fix: object with file encode/decode

oneRain 2021-05-21 14:48:53 +08:00
parent b9ea3a0784
commit 9182650b29
4 changed files with 65 additions and 10 deletions

View File

@ -43,6 +43,24 @@ namespace Storage.Test {
internal Account() : base("Account") { } internal Account() : base("Account") { }
} }
internal class ObjectWithFile : LCObject {
internal LCFile File {
get => this["file"] as LCFile;
set {
this["file"] = value;
}
}
internal LCUser Owner {
get => this["owner"] as LCUser;
set {
this["owner"] = value;
}
}
internal ObjectWithFile() : base("ObjectWithFile") {}
}
public class BaseTest { public class BaseTest {
internal const string AppId = "ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz"; internal const string AppId = "ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz";
internal const string AppKey = "NUKmuRbdAhg1vrb2wexYo1jo"; internal const string AppKey = "NUKmuRbdAhg1vrb2wexYo1jo";
@ -59,6 +77,7 @@ namespace Storage.Test {
LCObject.RegisterSubclass("Account", () => new Account()); LCObject.RegisterSubclass("Account", () => new Account());
LCObject.RegisterSubclass("Hello", () => new Hello()); LCObject.RegisterSubclass("Hello", () => new Hello());
LCObject.RegisterSubclass("World", () => new World()); LCObject.RegisterSubclass("World", () => new World());
LCObject.RegisterSubclass("ObjectWithFile", () => new ObjectWithFile());
} }
[TearDown] [TearDown]

View File

@ -34,5 +34,24 @@ namespace Storage.Test {
await account.Save(); await account.Save();
await account.Delete(); await account.Delete();
} }
[Test]
public async Task ObjectWithFile() {
LCUser user = await LCUser.Login("hello", "world");
ObjectWithFile obj = new ObjectWithFile() {
File = new LCFile("avatar", "../../../../../assets/hello.png"),
Owner = user
};
await obj.Save();
LCQuery<ObjectWithFile> query = new LCQuery<ObjectWithFile>("ObjectWithFile");
ObjectWithFile obj2 = await query.Get(obj.ObjectId);
TestContext.WriteLine(obj2.File.Url);
TestContext.WriteLine(obj2.Owner.ObjectId);
Assert.IsNotNull(obj2.File.Url);
Assert.IsNotNull(obj2.Owner.ObjectId);
}
} }
} }

View File

@ -13,14 +13,16 @@ namespace LeanCloud.Storage.Internal.Codec {
return DecodeDate(dict); return DecodeDate(dict);
} else if (type == "Bytes") { } else if (type == "Bytes") {
return DecodeBytes(dict); return DecodeBytes(dict);
} else if (type == "Object") { } else if (type == "Pointer") {
return DecodeObject(dict); return DecodeObject(dict);
} else if (type == "Pointer" || type == "Object") { } else if (type == "Object") {
return DecodeObject(dict); return DecodeObject(dict);
} else if (type == "Relation") { } else if (type == "Relation") {
return DecodeRelation(dict); return DecodeRelation(dict);
} else if (type == "GeoPoint") { } else if (type == "GeoPoint") {
return DecodeGeoPoint(dict); return DecodeGeoPoint(dict);
} else if (type == "File") {
return DecodeFile(dict);
} }
} }
Dictionary<string, object> d = new Dictionary<string, object>(); Dictionary<string, object> d = new Dictionary<string, object>();
@ -61,6 +63,13 @@ namespace LeanCloud.Storage.Internal.Codec {
return obj; return obj;
} }
public static LCFile DecodeFile(IDictionary dict) {
LCFile file = new LCFile();
LCObjectData objectData = LCObjectData.Decode(dict as Dictionary<string, object>);
file.Merge(objectData);
return file;
}
public static LCRelation<LCObject> DecodeRelation(IDictionary dict) { public static LCRelation<LCObject> DecodeRelation(IDictionary dict) {
LCRelation<LCObject> relation = new LCRelation<LCObject>(); LCRelation<LCObject> relation = new LCRelation<LCObject>();
relation.TargetClass = dict["className"].ToString(); relation.TargetClass = dict["className"].ToString();

View File

@ -73,12 +73,8 @@ namespace LeanCloud.Storage {
} }
} }
bool isNew;
bool IsDirty { bool IsDirty {
get { get; set;
return isNew || estimatedData.Count > 0;
}
} }
/// <summary> /// <summary>
@ -96,7 +92,7 @@ namespace LeanCloud.Storage {
operationDict = new Dictionary<string, ILCOperation>(); operationDict = new Dictionary<string, ILCOperation>();
data.ClassName = className; data.ClassName = className;
isNew = true; IsDirty = true;
} }
/// <summary> /// <summary>
@ -111,7 +107,7 @@ namespace LeanCloud.Storage {
} }
LCObject obj = Create(className); LCObject obj = Create(className);
obj.data.ObjectId = objectId; obj.data.ObjectId = objectId;
obj.isNew = false; obj.IsDirty = false;
return obj; return obj;
} }
@ -327,8 +323,19 @@ namespace LeanCloud.Storage {
static async Task SaveBatches(Stack<LCBatch> batches) { static async Task SaveBatches(Stack<LCBatch> batches) {
while (batches.Count > 0) { while (batches.Count > 0) {
LCBatch batch = batches.Pop(); LCBatch batch = batches.Pop();
// 特殊处理 File 依赖
IEnumerable<LCFile> dirtyFiles = batch.objects.Where(item => (item is LCFile) && item.IsDirty)
.Cast<LCFile>();
foreach (LCFile file in dirtyFiles) {
await file.Save();
}
List<LCObject> dirtyObjects = batch.objects.Where(item => item.IsDirty) List<LCObject> dirtyObjects = batch.objects.Where(item => item.IsDirty)
.ToList(); .ToList();
if (dirtyObjects.Count == 0) {
continue;
}
List<Dictionary<string, object>> requestList = dirtyObjects.Select(item => { List<Dictionary<string, object>> requestList = dirtyObjects.Select(item => {
string path = item.ObjectId == null ? string path = item.ObjectId == null ?
@ -567,6 +574,7 @@ namespace LeanCloud.Storage {
} else { } else {
operationDict[key] = op; operationDict[key] = op;
} }
IsDirty = true;
} }
public void Merge(LCObjectData objectData) { public void Merge(LCObjectData objectData) {
@ -587,7 +595,7 @@ namespace LeanCloud.Storage {
RebuildEstimatedData(); RebuildEstimatedData();
// 清空操作 // 清空操作
operationDict.Clear(); operationDict.Clear();
isNew = false; IsDirty = false;
} }
void RebuildEstimatedData() { void RebuildEstimatedData() {