using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LeanCloud.Storage.Internal.Object;
using LeanCloud.Storage.Internal.Operation;
using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage {
///
/// 对象类
///
public class LCObject {
///
/// 最近一次与服务端同步的数据
///
LCObjectData data;
///
/// 预算数据
///
internal Dictionary estimatedData;
///
/// 操作字典
///
internal Dictionary operationDict;
static readonly Dictionary subclassTypeDict = new Dictionary();
static readonly Dictionary subclassNameDict = new Dictionary();
public string ClassName {
get {
return data.ClassName;
}
}
public string ObjectId {
get {
return data.ObjectId;
}
}
public DateTime CreatedAt {
get {
return data.CreatedAt;
}
}
public DateTime UpdatedAt {
get {
return data.UpdatedAt;
}
}
public LCACL ACL {
get {
return this["ACL"] as LCACL ;
} set {
this["ACL"] = value;
}
}
bool isNew;
bool IsDirty {
get {
return isNew || estimatedData.Count > 0;
}
}
public LCObject(string className) {
if (string.IsNullOrEmpty(className)) {
throw new ArgumentNullException(nameof(className));
}
data = new LCObjectData();
estimatedData = new Dictionary();
operationDict = new Dictionary();
data.ClassName = className;
isNew = true;
}
public static LCObject CreateWithoutData(string className, string objectId) {
if (string.IsNullOrEmpty(objectId)) {
throw new ArgumentNullException(nameof(objectId));
}
LCObject obj = new LCObject(className);
obj.data.ObjectId = objectId;
obj.isNew = false;
return obj;
}
internal static LCObject Create(string className) {
if (subclassNameDict.TryGetValue(className, out LCSubclassInfo subclassInfo)) {
return subclassInfo.Constructor.Invoke();
}
return new LCObject(className);
}
internal static LCObject Create(Type type) {
if (subclassTypeDict.TryGetValue(type, out LCSubclassInfo subclassInfo)) {
return subclassInfo.Constructor.Invoke();
}
return null;
}
public object this[string key] {
get {
if (estimatedData.TryGetValue(key, out object value)) {
if (value is LCRelation relation) {
relation.Key = key;
relation.Parent = this;
}
return value;
}
return null;
}
set {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (key.StartsWith("_")) {
throw new ArgumentException("key should not start with '_'");
}
if (key == "objectId" || key == "createdAt" || key == "updatedAt") {
throw new ArgumentException($"{key} is reserved by LeanCloud");
}
LCSetOperation setOp = new LCSetOperation(value);
ApplyOperation(key, setOp);
}
}
///
/// 删除字段
///
///
public void Unset(string key) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
LCDeleteOperation deleteOp = new LCDeleteOperation();
ApplyOperation(key, deleteOp);
}
///
/// 增加关联
///
///
///
public void AddRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCAddRelationOperation op = new LCAddRelationOperation(new List { value });
ApplyOperation(key, op);
}
///
/// 删除关联
///
///
///
public void RemoveRelation(string key, LCObject value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCRemoveRelationOperation op = new LCRemoveRelationOperation(value);
ApplyOperation(key, op);
}
///
/// 增加数字属性值
///
///
///
public void Increment(string key, object value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCNumberOperation op = new LCNumberOperation(value);
ApplyOperation(key, op);
}
///
/// 在数组属性中增加一个元素
///
///
///
public void Add(string key, object value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentNullException(nameof(key));
}
if (value == null) {
throw new ArgumentNullException(nameof(value));
}
LCAddOperation op = new LCAddOperation(new List