* ObjectControllerTests.cs: chore: 增加根据条件更新 Object

* ObjectTest.cs:
* AVObject.cs:
* AVObjectController.cs:
oneRain 2019-08-28 12:10:59 +08:00
parent 9d3c9dc178
commit 862df7c6fa
4 changed files with 24 additions and 28 deletions

View File

@ -23,6 +23,16 @@ namespace LeanCloudTests {
Assert.NotNull(obj.UpdatedAt);
}
[Test]
public async Task SaveWithQuery() {
AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476");
AVQuery<AVObject> query = new AVQuery<AVObject>("Account");
query.WhereGreaterThan("balance", 80);
account["balance"] = 50;
await account.SaveAsync(query);
TestContext.Out.WriteLine($"balance: {account["balance"]}");
}
[Test]
public async Task Fetch() {
AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f");

View File

@ -8,13 +8,7 @@ namespace LeanCloudTests {
public class ObjectTests {
[SetUp]
public void SetUp() {
AVClient.Initialize(new AVClient.Configuration {
ApplicationId = "BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz",
ApplicationKey = "pbf6Nk5seyjilexdpyrPwjSp",
ApiServer = "https://avoscloud.com",
RTMServer = "https://router-g0-push.avoscloud.com",
});
AVClient.HttpLog(TestContext.Out.WriteLine);
Utils.InitNorthChina();
}
[Test]

View File

@ -35,14 +35,24 @@ namespace LeanCloud.Storage.Internal {
public Task<IObjectState> SaveAsync(IObjectState state,
IDictionary<string, IAVFieldOperation> operations,
AVQuery<AVObject> query,
string sessionToken,
CancellationToken cancellationToken) {
var objectJSON = AVObject.ToJSONObjectForSaving(operations);
var command = new AVCommand {
Path = state.ObjectId == null ? $"classes/{Uri.EscapeDataString(state.ClassName)}" : $"classes/{Uri.EscapeDataString(state.ClassName)}/{state.ObjectId}",
Method = state.ObjectId == null ? HttpMethod.Post : HttpMethod.Put,
Content = objectJSON
};
// 查询条件
if (query != null && query.where != null) {
Dictionary<string, object> where = new Dictionary<string, object> {
{ "where", PointerOrLocalIdEncoder.Instance.Encode(query.where) }
};
string encode = AVClient.BuildQueryString(where);
command.Path = $"{command.Path}?{encode}";
}
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken: cancellationToken).OnSuccess(t => {
var serverState = AVObjectCoder.Instance.Decode(t.Result.Item2, AVDecoder.Instance);
serverState = serverState.MutatedClone(mutableClone => {

View File

@ -557,13 +557,12 @@ string propertyName
}
}
protected virtual Task SaveAsync(Task toAwait,
CancellationToken cancellationToken) {
public virtual Task SaveAsync(AVQuery<AVObject> query = null, CancellationToken cancellationToken = default) {
IDictionary<string, IAVFieldOperation> currentOperations = null;
if (!IsDirty) {
return Task.FromResult(0);
}
Task deepSaveTask;
string sessionToken;
lock (mutex) {
@ -576,10 +575,9 @@ string propertyName
}
return deepSaveTask.OnSuccess(_ => {
return toAwait;
}).Unwrap().OnSuccess(_ => {
return ObjectController.SaveAsync(state,
currentOperations,
query,
sessionToken,
cancellationToken);
}).Unwrap().ContinueWith(t => {
@ -593,22 +591,6 @@ string propertyName
}).Unwrap();
}
/// <summary>
/// Saves this object to the server.
/// </summary>
public virtual Task SaveAsync() {
return SaveAsync(CancellationToken.None);
}
/// <summary>
/// Saves this object to the server.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
public virtual Task SaveAsync(CancellationToken cancellationToken) {
return taskQueue.Enqueue(toAwait => SaveAsync(toAwait, cancellationToken),
cancellationToken);
}
internal virtual Task<AVObject> FetchAsyncInternal(
Task toAwait,
IDictionary<string, object> queryString,