diff --git a/Storage/Storage.Test/ObjectControllerTests.cs b/Storage/Storage.Test/ObjectControllerTests.cs deleted file mode 100644 index 3dbe70b..0000000 --- a/Storage/Storage.Test/ObjectControllerTests.cs +++ /dev/null @@ -1,157 +0,0 @@ -using NUnit.Framework; -using System; -using System.Threading; -using System.Threading.Tasks; -using System.Collections.Generic; -using LeanCloud; - -namespace LeanCloud.Test { - public class ObjectControllerTests { - [SetUp] - public void SetUp() { - Utils.InitNorthChina(); - } - - [Test] - public async Task Save() { - AVObject obj = AVObject.Create("Foo"); - obj["content"] = "hello, world"; - obj["list"] = new List { 1, 1, 2, 3, 5, 8 }; - obj["dict"] = new Dictionary { - { "hello", 1 }, - { "world", 2 } - }; - await obj.SaveAsync(); - Assert.NotNull(obj.ObjectId); - Assert.NotNull(obj.CreatedAt); - Assert.NotNull(obj.UpdatedAt); - } - - [Test] - public async Task SaveWithOptions() { - AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476"); - account["balance"] = 100; - await account.SaveAsync(); - AVQuery query = new AVQuery("Account"); - query.WhereGreaterThan("balance", 80); - account["balance"] = 50; - await account.SaveAsync(true, query); - TestContext.Out.WriteLine($"balance: {account["balance"]}"); - } - - [Test] - public async Task SaveWithPointer() { - AVObject comment = new AVObject("Comment") { - { "content", "Hello, Comment" } - }; - - AVObject post = new AVObject("Post") { - { "name", "New Post" }, - { "category", new AVObject("Category") { - { "name", "new post category" } - } } - }; - comment["post"] = post; - - AVObject testPost = new AVObject("Post") { - { "name", "Test Post" }, - { "category", new AVObject("Category") { - { "name", "test post category" } - } } - }; - comment["test_post"] = testPost; - - await comment.SaveAsync(); - TestContext.Out.WriteLine(post); - TestContext.Out.WriteLine(testPost); - TestContext.Out.WriteLine(comment); - } - - [Test] - public async Task SaveBatch() { - List objList = new List(); - for (int i = 0; i < 5; i++) { - AVObject obj = AVObject.Create("Foo"); - obj["content"] = "batch object"; - objList.Add(obj); - } - try { - await objList.SaveAllAsync(); - objList.ForEach(obj => { - Assert.NotNull(obj.ObjectId); - }); - } catch (Exception e) { - TestContext.Out.WriteLine(e.Message); - } - } - - [Test] - public async Task Fetch() { - AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f"); - await obj.FetchAsync(); - Assert.NotNull(obj["title"]); - Assert.NotNull(obj["content"]); - TestContext.Out.WriteLine($"{obj["title"]}, {obj["content"]}"); - } - - [Test] - public async Task FetchWithKeys() { - AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326"); - await obj.FetchAsync(new List { "pubUser" }); - TestContext.Out.WriteLine($"{obj["pubUser"]}"); - } - - [Test] - public async Task FetchWithIncludes() { - AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326"); - await obj.FetchAsync(includes: new List { "tag" }); - AVObject tag = obj["tag"] as AVObject; - TestContext.Out.WriteLine($"{tag["name"]}"); - } - - [Test] - public async Task FetchAll() { - List objList = new List { - AVObject.CreateWithoutData("Tag", "5d64e5ebc05a8000730340ba"), - AVObject.CreateWithoutData("Tag", "5d64e5eb12215f0073db271c"), - AVObject.CreateWithoutData("Tag", "5d64e57f43e78c0068a14315") - }; - await objList.FetchAllAsync(); - objList.ForEach(obj => { - Assert.NotNull(obj.ObjectId); - TestContext.Out.WriteLine($"{obj.ObjectId}, {obj["name"]}"); - }); - } - - [Test] - public async Task Delete() { - AVObject obj = AVObject.Create("Foo"); - obj["content"] = "hello, world"; - await obj.SaveAsync(); - Assert.NotNull(obj); - await obj.DeleteAsync(); - } - - [Test] - public async Task DeleteAll() { - List objList = new List(); - for (int i = 0; i < 5; i++) { - AVObject obj = AVObject.Create("Foo"); - obj["content"] = "batch object"; - objList.Add(obj); - } - await objList.SaveAllAsync(); - await AVObject.DeleteAllAsync(objList); - } - - [Test] - public async Task Set() { - AVObject obj = AVObject.Create("Foo"); - obj["hello"] = "world"; - await obj.SaveAsync(); - obj["world"] = "aaa"; - obj.Revert(); - TestContext.Out.WriteAsync(obj["hello"] as string); - } - } -} diff --git a/Storage/Storage.Test/ObjectTest.cs b/Storage/Storage.Test/ObjectTest.cs index 5416e31..d1821b2 100644 --- a/Storage/Storage.Test/ObjectTest.cs +++ b/Storage/Storage.Test/ObjectTest.cs @@ -1,7 +1,8 @@ using NUnit.Framework; -using LeanCloud; +using System; using System.Threading; using System.Threading.Tasks; +using System.Collections.Generic; namespace LeanCloud.Test { public class ObjectTests { @@ -11,22 +12,166 @@ namespace LeanCloud.Test { } [Test] - public void TestAVObjectConstructor() { - AVObject obj = new AVObject("Foo"); - Assert.AreEqual("Foo", obj.ClassName); - Assert.Null(obj.CreatedAt); - Assert.True(obj.IsDataAvailable); - Assert.True(obj.IsDirty); + public async Task Save() { + AVObject obj = AVObject.Create("Foo"); + obj["content"] = "hello, world"; + obj["list"] = new List { 1, 1, 2, 3, 5, 8 }; + obj["dict"] = new Dictionary { + { "hello", 1 }, + { "world", 2 } + }; + await obj.SaveAsync(); + Assert.NotNull(obj.ObjectId); + Assert.NotNull(obj.CreatedAt); + Assert.NotNull(obj.UpdatedAt); } [Test] - public void TestAVObjectCreate() { - AVObject obj = AVObject.CreateWithoutData("Foo", "5d356b1cd5de2b00837162ca"); - Assert.AreEqual("Foo", obj.ClassName); - Assert.AreEqual("5d356b1cd5de2b00837162ca", obj.ObjectId); - Assert.Null(obj.CreatedAt); - Assert.False(obj.IsDataAvailable); - Assert.False(obj.IsDirty); + public async Task SaveWithOptions() { + AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476"); + account["balance"] = 100; + await account.SaveAsync(); + AVQuery query = new AVQuery("Account"); + query.WhereGreaterThan("balance", 80); + account["balance"] = 50; + await account.SaveAsync(true, query); + TestContext.Out.WriteLine($"balance: {account["balance"]}"); + } + + [Test] + public async Task SaveWithPointer() { + AVObject comment = new AVObject("Comment") { + { "content", "Hello, Comment" } + }; + + AVObject post = new AVObject("Post") { + { "name", "New Post" }, + { "category", new AVObject("Category") { + { "name", "new post category" } + } } + }; + comment["post"] = post; + + AVObject testPost = new AVObject("Post") { + { "name", "Test Post" }, + { "category", new AVObject("Category") { + { "name", "test post category" } + } } + }; + comment["test_post"] = testPost; + + await comment.SaveAsync(); + TestContext.Out.WriteLine(post); + TestContext.Out.WriteLine(testPost); + TestContext.Out.WriteLine(comment); + } + + [Test] + public async Task SaveBatch() { + List objList = new List(); + for (int i = 0; i < 5; i++) { + AVObject obj = AVObject.Create("Foo"); + obj["content"] = "batch object"; + objList.Add(obj); + } + try { + await objList.SaveAllAsync(); + objList.ForEach(obj => { + Assert.NotNull(obj.ObjectId); + }); + } catch (Exception e) { + TestContext.Out.WriteLine(e.Message); + } + } + + [Test] + public async Task Fetch() { + AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f"); + await obj.FetchAsync(); + Assert.NotNull(obj["title"]); + Assert.NotNull(obj["content"]); + TestContext.Out.WriteLine($"{obj["title"]}, {obj["content"]}"); + } + + [Test] + public async Task FetchWithKeys() { + AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326"); + await obj.FetchAsync(new List { "pubUser" }); + TestContext.Out.WriteLine($"{obj["pubUser"]}"); + } + + [Test] + public async Task FetchWithIncludes() { + AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326"); + await obj.FetchAsync(includes: new List { "tag" }); + AVObject tag = obj["tag"] as AVObject; + TestContext.Out.WriteLine($"{tag["name"]}"); + } + + [Test] + public async Task FetchAll() { + List objList = new List { + AVObject.CreateWithoutData("Tag", "5d64e5ebc05a8000730340ba"), + AVObject.CreateWithoutData("Tag", "5d64e5eb12215f0073db271c"), + AVObject.CreateWithoutData("Tag", "5d64e57f43e78c0068a14315") + }; + await objList.FetchAllAsync(); + objList.ForEach(obj => { + Assert.NotNull(obj.ObjectId); + TestContext.Out.WriteLine($"{obj.ObjectId}, {obj["name"]}"); + }); + } + + [Test] + public async Task Delete() { + AVObject obj = AVObject.Create("Foo"); + obj["content"] = "hello, world"; + await obj.SaveAsync(); + Assert.NotNull(obj); + await obj.DeleteAsync(); + } + + [Test] + public async Task DeleteWithCondition() { + AVObject account = new AVObject("Account") { + { "balance", 100 }, + }; + account.ACL = new AVACL { + PublicWriteAccess = true, + PublicReadAccess = true + }; + await account.SaveAsync(); + AVQuery condition = new AVQuery(); + condition.WhereGreaterThan("balance", 10); + await account.DeleteAsync(condition); + + account = new AVObject("Account") { + { "balance", 8 }, + }; + account.ACL = new AVACL { + PublicWriteAccess = true, + PublicReadAccess = true + }; + await account.SaveAsync(); + condition = new AVQuery(); + condition.WhereGreaterThan("balance", 10); + try { + await account.DeleteAsync(condition); + } catch (AVException e) { + Assert.AreEqual(e.Code, AVException.ErrorCode.NoEffectOnUpdatingOrDeleting); + } + } + + [Test] + public async Task DeleteAll() { + List objList = new List(); + for (int i = 0; i < 5; i++) { + AVObject obj = AVObject.Create("Foo"); + obj["content"] = "batch object"; + objList.Add(obj); + } + await objList.SaveAllAsync(); + await AVObject.DeleteAllAsync(objList); } [Test] diff --git a/Storage/Storage/Internal/Object/Controller/AVObjectController.cs b/Storage/Storage/Internal/Object/Controller/AVObjectController.cs index 865b2f3..0938207 100644 --- a/Storage/Storage/Internal/Object/Controller/AVObjectController.cs +++ b/Storage/Storage/Internal/Object/Controller/AVObjectController.cs @@ -74,12 +74,17 @@ namespace LeanCloud.Storage.Internal { return stateTasks; } - public async Task DeleteAsync(IObjectState state, - CancellationToken cancellationToken) { + public async Task DeleteAsync(IObjectState state, AVQuery query, CancellationToken cancellationToken) { var command = new AVCommand { Path = $"classes/{state.ClassName}/{state.ObjectId}", Method = HttpMethod.Delete }; + if (query != null) { + Dictionary where = new Dictionary { + { "where", query.BuildWhere() } + }; + command.Path = $"{command.Path}?{AVClient.BuildQueryString(where)}"; + } await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken); } diff --git a/Storage/Storage/Public/AVACL.cs b/Storage/Storage/Public/AVACL.cs index 22544c4..3d6d7f0 100644 --- a/Storage/Storage/Public/AVACL.cs +++ b/Storage/Storage/Public/AVACL.cs @@ -12,273 +12,273 @@ namespace LeanCloud { /// set of users could write to that object. /// public class AVACL : IJsonConvertible { - private enum AccessKind { - Read, - Write - } - private const string publicName = "*"; - private readonly ICollection readers = new HashSet(); - private readonly ICollection writers = new HashSet(); - - internal AVACL(IDictionary jsonObject) { - readers = new HashSet(from pair in jsonObject - where ((IDictionary)pair.Value).ContainsKey("read") - select pair.Key); - writers = new HashSet(from pair in jsonObject - where ((IDictionary)pair.Value).ContainsKey("write") - select pair.Key); - } - - /// - /// Creates an ACL with no permissions granted. - /// - public AVACL() { - } - - /// - /// Creates an ACL where only the provided user has access. - /// - /// The only user that can read or write objects governed by this ACL. - public AVACL(AVUser owner) { - SetReadAccess(owner, true); - SetWriteAccess(owner, true); - } - - IDictionary IJsonConvertible.ToJSON() { - var result = new Dictionary(); - foreach (var user in readers.Union(writers)) { - var userPermissions = new Dictionary(); - if (readers.Contains(user)) { - userPermissions["read"] = true; + private enum AccessKind { + Read, + Write } - if (writers.Contains(user)) { - userPermissions["write"] = true; + private const string publicName = "*"; + private readonly ICollection readers = new HashSet(); + private readonly ICollection writers = new HashSet(); + + internal AVACL(IDictionary jsonObject) { + readers = new HashSet(from pair in jsonObject + where ((IDictionary)pair.Value).ContainsKey("read") + select pair.Key); + writers = new HashSet(from pair in jsonObject + where ((IDictionary)pair.Value).ContainsKey("write") + select pair.Key); } - result[user] = userPermissions; - } - return result; - } - private void SetAccess(AccessKind kind, string userId, bool allowed) { - if (userId == null) { - throw new ArgumentException("Cannot set access for an unsaved user or role."); - } - ICollection target = null; - switch (kind) { - case AccessKind.Read: - target = readers; - break; - case AccessKind.Write: - target = writers; - break; - default: - throw new NotImplementedException("Unknown AccessKind"); - } - if (allowed) { - target.Add(userId); - } else { - target.Remove(userId); - } - } + /// + /// Creates an ACL with no permissions granted. + /// + public AVACL() { + } - private bool GetAccess(AccessKind kind, string userId) { - if (userId == null) { - throw new ArgumentException("Cannot get access for an unsaved user or role."); - } - switch (kind) { - case AccessKind.Read: - return readers.Contains(userId); - case AccessKind.Write: - return writers.Contains(userId); - default: - throw new NotImplementedException("Unknown AccessKind"); - } - } + /// + /// Creates an ACL where only the provided user has access. + /// + /// The only user that can read or write objects governed by this ACL. + public AVACL(AVUser owner) { + SetReadAccess(owner, true); + SetWriteAccess(owner, true); + } - /// - /// Gets or sets whether the public is allowed to read this object. - /// - public bool PublicReadAccess { - get { - return GetAccess(AccessKind.Read, publicName); - } - set { - SetAccess(AccessKind.Read, publicName, value); - } - } + IDictionary IJsonConvertible.ToJSON() { + var result = new Dictionary(); + foreach (var user in readers.Union(writers)) { + var userPermissions = new Dictionary(); + if (readers.Contains(user)) { + userPermissions["read"] = true; + } + if (writers.Contains(user)) { + userPermissions["write"] = true; + } + result[user] = userPermissions; + } + return result; + } - /// - /// Gets or sets whether the public is allowed to write this object. - /// - public bool PublicWriteAccess { - get { - return GetAccess(AccessKind.Write, publicName); - } - set { - SetAccess(AccessKind.Write, publicName, value); - } - } + private void SetAccess(AccessKind kind, string userId, bool allowed) { + if (userId == null) { + throw new ArgumentException("Cannot set access for an unsaved user or role."); + } + ICollection target = null; + switch (kind) { + case AccessKind.Read: + target = readers; + break; + case AccessKind.Write: + target = writers; + break; + default: + throw new NotImplementedException("Unknown AccessKind"); + } + if (allowed) { + target.Add(userId); + } else { + target.Remove(userId); + } + } - /// - /// Sets whether the given user id is allowed to read this object. - /// - /// The objectId of the user. - /// Whether the user has permission. - public void SetReadAccess(string userId, bool allowed) { - SetAccess(AccessKind.Read, userId, allowed); - } + private bool GetAccess(AccessKind kind, string userId) { + if (userId == null) { + throw new ArgumentException("Cannot get access for an unsaved user or role."); + } + switch (kind) { + case AccessKind.Read: + return readers.Contains(userId); + case AccessKind.Write: + return writers.Contains(userId); + default: + throw new NotImplementedException("Unknown AccessKind"); + } + } - /// - /// Sets whether the given user is allowed to read this object. - /// - /// The user. - /// Whether the user has permission. - public void SetReadAccess(AVUser user, bool allowed) { - SetReadAccess(user.ObjectId, allowed); - } + /// + /// Gets or sets whether the public is allowed to read this object. + /// + public bool PublicReadAccess { + get { + return GetAccess(AccessKind.Read, publicName); + } + set { + SetAccess(AccessKind.Read, publicName, value); + } + } - /// - /// Sets whether the given user id is allowed to write this object. - /// - /// The objectId of the user. - /// Whether the user has permission. - public void SetWriteAccess(string userId, bool allowed) { - SetAccess(AccessKind.Write, userId, allowed); - } + /// + /// Gets or sets whether the public is allowed to write this object. + /// + public bool PublicWriteAccess { + get { + return GetAccess(AccessKind.Write, publicName); + } + set { + SetAccess(AccessKind.Write, publicName, value); + } + } - /// - /// Sets whether the given user is allowed to write this object. - /// - /// The user. - /// Whether the user has permission. - public void SetWriteAccess(AVUser user, bool allowed) { - SetWriteAccess(user.ObjectId, allowed); - } + /// + /// Sets whether the given user id is allowed to read this object. + /// + /// The objectId of the user. + /// Whether the user has permission. + public void SetReadAccess(string userId, bool allowed) { + SetAccess(AccessKind.Read, userId, allowed); + } - /// - /// Gets whether the given user id is *explicitly* allowed to read this object. - /// Even if this returns false, the user may still be able to read it if - /// PublicReadAccess is true or a role that the user belongs to has read access. - /// - /// The user objectId to check. - /// Whether the user has access. - public bool GetReadAccess(string userId) { - return GetAccess(AccessKind.Read, userId); - } + /// + /// Sets whether the given user is allowed to read this object. + /// + /// The user. + /// Whether the user has permission. + public void SetReadAccess(AVUser user, bool allowed) { + SetReadAccess(user.ObjectId, allowed); + } - /// - /// Gets whether the given user is *explicitly* allowed to read this object. - /// Even if this returns false, the user may still be able to read it if - /// PublicReadAccess is true or a role that the user belongs to has read access. - /// - /// The user to check. - /// Whether the user has access. - public bool GetReadAccess(AVUser user) { - return GetReadAccess(user.ObjectId); - } + /// + /// Sets whether the given user id is allowed to write this object. + /// + /// The objectId of the user. + /// Whether the user has permission. + public void SetWriteAccess(string userId, bool allowed) { + SetAccess(AccessKind.Write, userId, allowed); + } - /// - /// Gets whether the given user id is *explicitly* allowed to write this object. - /// Even if this returns false, the user may still be able to write it if - /// PublicReadAccess is true or a role that the user belongs to has write access. - /// - /// The user objectId to check. - /// Whether the user has access. - public bool GetWriteAccess(string userId) { - return GetAccess(AccessKind.Write, userId); - } + /// + /// Sets whether the given user is allowed to write this object. + /// + /// The user. + /// Whether the user has permission. + public void SetWriteAccess(AVUser user, bool allowed) { + SetWriteAccess(user.ObjectId, allowed); + } - /// - /// Gets whether the given user is *explicitly* allowed to write this object. - /// Even if this returns false, the user may still be able to write it if - /// PublicReadAccess is true or a role that the user belongs to has write access. - /// - /// The user to check. - /// Whether the user has access. - public bool GetWriteAccess(AVUser user) { - return GetWriteAccess(user.ObjectId); - } + /// + /// Gets whether the given user id is *explicitly* allowed to read this object. + /// Even if this returns false, the user may still be able to read it if + /// PublicReadAccess is true or a role that the user belongs to has read access. + /// + /// The user objectId to check. + /// Whether the user has access. + public bool GetReadAccess(string userId) { + return GetAccess(AccessKind.Read, userId); + } - /// - /// Sets whether users belonging to the role with the given - /// are allowed to read this object. - /// - /// The name of the role. - /// Whether the role has access. - public void SetRoleReadAccess(string roleName, bool allowed) { - SetAccess(AccessKind.Read, "role:" + roleName, allowed); - } + /// + /// Gets whether the given user is *explicitly* allowed to read this object. + /// Even if this returns false, the user may still be able to read it if + /// PublicReadAccess is true or a role that the user belongs to has read access. + /// + /// The user to check. + /// Whether the user has access. + public bool GetReadAccess(AVUser user) { + return GetReadAccess(user.ObjectId); + } - /// - /// Sets whether users belonging to the given role are allowed to read this object. - /// - /// The role. - /// Whether the role has access. - public void SetRoleReadAccess(AVRole role, bool allowed) { - SetRoleReadAccess(role.Name, allowed); - } + /// + /// Gets whether the given user id is *explicitly* allowed to write this object. + /// Even if this returns false, the user may still be able to write it if + /// PublicReadAccess is true or a role that the user belongs to has write access. + /// + /// The user objectId to check. + /// Whether the user has access. + public bool GetWriteAccess(string userId) { + return GetAccess(AccessKind.Write, userId); + } - /// - /// Gets whether users belonging to the role with the given - /// are allowed to read this object. Even if this returns false, the role may still be - /// able to read it if a parent role has read access. - /// - /// The name of the role. - /// Whether the role has access. - public bool GetRoleReadAccess(string roleName) { - return GetAccess(AccessKind.Read, "role:" + roleName); - } + /// + /// Gets whether the given user is *explicitly* allowed to write this object. + /// Even if this returns false, the user may still be able to write it if + /// PublicReadAccess is true or a role that the user belongs to has write access. + /// + /// The user to check. + /// Whether the user has access. + public bool GetWriteAccess(AVUser user) { + return GetWriteAccess(user.ObjectId); + } - /// - /// Gets whether users belonging to the role are allowed to read this object. - /// Even if this returns false, the role may still be able to read it if a - /// parent role has read access. - /// - /// The name of the role. - /// Whether the role has access. - public bool GetRoleReadAccess(AVRole role) { - return GetRoleReadAccess(role.Name); - } + /// + /// Sets whether users belonging to the role with the given + /// are allowed to read this object. + /// + /// The name of the role. + /// Whether the role has access. + public void SetRoleReadAccess(string roleName, bool allowed) { + SetAccess(AccessKind.Read, "role:" + roleName, allowed); + } - /// - /// Sets whether users belonging to the role with the given - /// are allowed to write this object. - /// - /// The name of the role. - /// Whether the role has access. - public void SetRoleWriteAccess(string roleName, bool allowed) { - SetAccess(AccessKind.Write, "role:" + roleName, allowed); - } + /// + /// Sets whether users belonging to the given role are allowed to read this object. + /// + /// The role. + /// Whether the role has access. + public void SetRoleReadAccess(AVRole role, bool allowed) { + SetRoleReadAccess(role.Name, allowed); + } - /// - /// Sets whether users belonging to the given role are allowed to write this object. - /// - /// The role. - /// Whether the role has access. - public void SetRoleWriteAccess(AVRole role, bool allowed) { - SetRoleWriteAccess(role.Name, allowed); - } + /// + /// Gets whether users belonging to the role with the given + /// are allowed to read this object. Even if this returns false, the role may still be + /// able to read it if a parent role has read access. + /// + /// The name of the role. + /// Whether the role has access. + public bool GetRoleReadAccess(string roleName) { + return GetAccess(AccessKind.Read, "role:" + roleName); + } - /// - /// Gets whether users belonging to the role with the given - /// are allowed to write this object. Even if this returns false, the role may still be - /// able to write it if a parent role has write access. - /// - /// The name of the role. - /// Whether the role has access. - public bool GetRoleWriteAccess(string roleName) { - return GetAccess(AccessKind.Write, "role:" + roleName); - } + /// + /// Gets whether users belonging to the role are allowed to read this object. + /// Even if this returns false, the role may still be able to read it if a + /// parent role has read access. + /// + /// The name of the role. + /// Whether the role has access. + public bool GetRoleReadAccess(AVRole role) { + return GetRoleReadAccess(role.Name); + } - /// - /// Gets whether users belonging to the role are allowed to write this object. - /// Even if this returns false, the role may still be able to write it if a - /// parent role has write access. - /// - /// The name of the role. - /// Whether the role has access. - public bool GetRoleWriteAccess(AVRole role) { - return GetRoleWriteAccess(role.Name); + /// + /// Sets whether users belonging to the role with the given + /// are allowed to write this object. + /// + /// The name of the role. + /// Whether the role has access. + public void SetRoleWriteAccess(string roleName, bool allowed) { + SetAccess(AccessKind.Write, "role:" + roleName, allowed); + } + + /// + /// Sets whether users belonging to the given role are allowed to write this object. + /// + /// The role. + /// Whether the role has access. + public void SetRoleWriteAccess(AVRole role, bool allowed) { + SetRoleWriteAccess(role.Name, allowed); + } + + /// + /// Gets whether users belonging to the role with the given + /// are allowed to write this object. Even if this returns false, the role may still be + /// able to write it if a parent role has write access. + /// + /// The name of the role. + /// Whether the role has access. + public bool GetRoleWriteAccess(string roleName) { + return GetAccess(AccessKind.Write, "role:" + roleName); + } + + /// + /// Gets whether users belonging to the role are allowed to write this object. + /// Even if this returns false, the role may still be able to write it if a + /// parent role has write access. + /// + /// The name of the role. + /// Whether the role has access. + public bool GetRoleWriteAccess(AVRole role) { + return GetRoleWriteAccess(role.Name); + } } - } } diff --git a/Storage/Storage/Public/AVException.cs b/Storage/Storage/Public/AVException.cs index 4fedef0..641803b 100644 --- a/Storage/Storage/Public/AVException.cs +++ b/Storage/Storage/Public/AVException.cs @@ -258,7 +258,12 @@ namespace LeanCloud /// /// 手机号不合法 /// - MobilePhoneInvalid = 253 + MobilePhoneInvalid = 253, + + /// + /// 按条件更新/删除失败 + /// + NoEffectOnUpdatingOrDeleting = 305, } internal AVException(ErrorCode code, string message, Exception cause = null) diff --git a/Storage/Storage/Public/AVObject.cs b/Storage/Storage/Public/AVObject.cs index ad0cc18..4ce96a9 100644 --- a/Storage/Storage/Public/AVObject.cs +++ b/Storage/Storage/Public/AVObject.cs @@ -790,11 +790,11 @@ string propertyName /// Deletes this object on the server. /// /// The cancellation token. - public virtual async Task DeleteAsync(CancellationToken cancellationToken = default) { + public virtual async Task DeleteAsync(AVQuery query = null, CancellationToken cancellationToken = default) { if (ObjectId == null) { return; } - await ObjectController.DeleteAsync(State, cancellationToken); + await ObjectController.DeleteAsync(State, query, cancellationToken); IsDirty = true; }