* RelationTest.cs: chore: 完善 Relation 和 Role 的功能和测试
* LCRole.cs: * LCObject.cs: * LCRelation.cs: * RoleTest.cs: * LCDecoder.cs: * LCEncoder.cs: * LCAddRelationOperation.cs: * LCRemoveRelationOperation.cs:
parent
6576cbd47f
commit
83ad15a8ec
|
@ -1,46 +1,66 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using LeanCloud;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using LeanCloud.Storage;
|
||||||
|
|
||||||
namespace LeanCloud.Test {
|
namespace LeanCloud.Test {
|
||||||
public class RelationTest {
|
public class RelationTest {
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() {
|
public void SetUp() {
|
||||||
Utils.InitNorthChina();
|
Logger.LogDelegate += Utils.Print;
|
||||||
|
LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() {
|
||||||
|
Logger.LogDelegate -= Utils.Print;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task CreateRelation() {
|
public async Task AddAndRemove() {
|
||||||
AVObject tag1 = new AVObject("Tag") {
|
LCObject parent = new LCObject("Parent");
|
||||||
["name"] = "hello"
|
LCObject c1 = new LCObject("Child");
|
||||||
};
|
parent.AddRelation("children", c1);
|
||||||
await tag1.SaveAsync();
|
LCObject c2 = new LCObject("Child");
|
||||||
AVObject tag2 = new AVObject("Tag") {
|
parent.AddRelation("children", c2);
|
||||||
{ "name", "world" }
|
await parent.Save();
|
||||||
};
|
|
||||||
await tag2.SaveAsync();
|
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
|
||||||
AVObject todo = new AVObject("Todo");
|
LCQuery<LCObject> query = relation.Query;
|
||||||
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
|
int count = await query.Count();
|
||||||
relation.Add(tag1);
|
|
||||||
relation.Add(tag2);
|
TestContext.WriteLine($"count: {count}");
|
||||||
await todo.SaveAsync();
|
Assert.AreEqual(count, 2);
|
||||||
|
|
||||||
|
parent.RemoveRelation("children", c2);
|
||||||
|
await parent.Save();
|
||||||
|
|
||||||
|
int count2 = await query.Count();
|
||||||
|
TestContext.WriteLine($"count: {count2}");
|
||||||
|
Assert.AreEqual(count2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task QueryRelation() {
|
public async Task Query() {
|
||||||
AVQuery<AVObject> query = new AVQuery<AVObject>("Todo");
|
LCQuery<LCObject> query = new LCQuery<LCObject>("Parent");
|
||||||
query.OrderByDescending("createdAt");
|
LCObject parent = await query.Get("5e13112021b47e0070ed0922");
|
||||||
AVObject todo = await query.FirstAsync();
|
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
|
||||||
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
|
|
||||||
AVQuery<AVObject> tagQuery = relation.Query;
|
TestContext.WriteLine(relation.Key);
|
||||||
IEnumerable<AVObject> tags = await tagQuery.FindAsync();
|
TestContext.WriteLine(relation.Parent);
|
||||||
Assert.Greater(tags.Count(), 0);
|
TestContext.WriteLine(relation.TargetClass);
|
||||||
TestContext.Out.WriteLine($"count: {tags.Count()}");
|
|
||||||
foreach (AVObject tag in tags) {
|
Assert.NotNull(relation.Key);
|
||||||
TestContext.Out.WriteLine($"{tag.ObjectId}, {tag["name"]}");
|
Assert.NotNull(relation.Parent);
|
||||||
}
|
Assert.NotNull(relation.TargetClass);
|
||||||
|
|
||||||
|
LCQuery<LCObject> relationQuery = relation.Query;
|
||||||
|
List<LCObject> list = await relationQuery.Find();
|
||||||
|
list.ForEach(item => {
|
||||||
|
TestContext.WriteLine(item.ObjectId);
|
||||||
|
Assert.NotNull(item.ObjectId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,49 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using LeanCloud;
|
using System.Linq;
|
||||||
|
using LeanCloud.Storage;
|
||||||
|
|
||||||
namespace LeanCloud.Test {
|
namespace LeanCloud.Test {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class RoleTest {
|
public class RoleTest {
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() {
|
public void SetUp() {
|
||||||
Utils.InitNorthChina(true);
|
Logger.LogDelegate += Utils.Print;
|
||||||
|
LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() {
|
||||||
|
Logger.LogDelegate -= Utils.Print;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task GetUsersFromRole() {
|
public async Task NewRole() {
|
||||||
AVQuery<AVRole> query = new AVQuery<AVRole>();
|
LCUser currentUser = await LCUser.Login("game", "play");
|
||||||
AVRole role = await query.FirstAsync();
|
LCACL acl = new LCACL();
|
||||||
AVQuery<AVUser> userQuery = role.Users.Query;
|
acl.PublicReadAccess = true;
|
||||||
IEnumerable<AVUser> users = await userQuery.FindAsync();
|
acl.SetUserWriteAccess(currentUser, true);
|
||||||
Assert.Greater(users.Count(), 0);
|
string name = $"role_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}";
|
||||||
TestContext.Out.WriteLine($"count: {users.Count()}");
|
LCRole role = LCRole.Create(name, acl);
|
||||||
foreach (AVUser user in users) {
|
role.AddRelation("users", currentUser);
|
||||||
TestContext.Out.WriteLine($"{user.ObjectId}, {user.Username}");
|
await role.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Query() {
|
||||||
|
LCQuery<LCRole> query = LCRole.GetQuery();
|
||||||
|
List<LCRole> list = await query.Find();
|
||||||
|
list.ForEach(item => {
|
||||||
|
TestContext.WriteLine($"{item.ObjectId} : {item.Name}");
|
||||||
|
Assert.NotNull(item.ObjectId);
|
||||||
|
Assert.NotNull(item.Name);
|
||||||
|
TestContext.WriteLine(item.Roles.GetType());
|
||||||
|
TestContext.WriteLine(item.Users.GetType());
|
||||||
|
Assert.IsTrue(item.Roles is LCRelation<LCRole>);
|
||||||
|
Assert.IsTrue(item.Users is LCRelation<LCUser>);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace LeanCloud.Storage.Internal.Codec {
|
||||||
|
|
||||||
static LCRelation<LCObject> DecodeRelation(IDictionary dict) {
|
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();
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace LeanCloud.Storage.Internal.Codec {
|
||||||
static object EncodeRelation(LCRelation<LCObject> relation) {
|
static object EncodeRelation(LCRelation<LCObject> relation) {
|
||||||
return new Dictionary<string, object> {
|
return new Dictionary<string, object> {
|
||||||
{ "__type", "Relation" },
|
{ "__type", "Relation" },
|
||||||
{ "className", relation.targetClass }
|
{ "className", relation.TargetClass }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace LeanCloud.Storage.Internal.Operation {
|
||||||
|
|
||||||
public object Apply(object oldValue, string key) {
|
public object Apply(object oldValue, string key) {
|
||||||
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
||||||
relation.targetClass = valueList[0].ClassName;
|
relation.TargetClass = valueList[0].ClassName;
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace LeanCloud.Storage.Internal.Operation {
|
||||||
|
|
||||||
public object Apply(object oldValue, string key) {
|
public object Apply(object oldValue, string key) {
|
||||||
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
||||||
relation.targetClass = valueList[0].ClassName;
|
relation.TargetClass = valueList[0].ClassName;
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,28 @@ namespace LeanCloud.Storage {
|
||||||
ApplyOperation(key, deleteOp);
|
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<LCObject> { 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);
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
|
@ -1,20 +1,41 @@
|
||||||
using System;
|
/// <summary>
|
||||||
|
/// 关系类
|
||||||
|
/// </summary>
|
||||||
namespace LeanCloud.Storage {
|
namespace LeanCloud.Storage {
|
||||||
public class LCRelation<T> where T : LCObject {
|
public class LCRelation<T> where T : LCObject {
|
||||||
|
/// <summary>
|
||||||
|
/// 字段名
|
||||||
|
/// </summary>
|
||||||
public string Key {
|
public string Key {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 父对象
|
||||||
|
/// </summary>
|
||||||
public LCObject Parent {
|
public LCObject Parent {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string targetClass {
|
/// <summary>
|
||||||
|
/// 关联类型名
|
||||||
|
/// </summary>
|
||||||
|
public string TargetClass {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LCRelation() {
|
public LCRelation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 Relation 的查询对象
|
||||||
|
/// </summary>
|
||||||
|
public LCQuery<T> Query {
|
||||||
|
get {
|
||||||
|
LCQuery<T> query = new LCQuery<T>(TargetClass);
|
||||||
|
query.WhereRelatedTo(Parent, Key);
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,64 @@
|
||||||
using System;
|
namespace LeanCloud.Storage {
|
||||||
|
/// <summary>
|
||||||
namespace LeanCloud.Storage {
|
/// 角色
|
||||||
|
/// </summary>
|
||||||
public class LCRole : LCObject {
|
public class LCRole : LCObject {
|
||||||
public const string CLASS_NAME = "_Role";
|
public const string CLASS_NAME = "_Role";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名字
|
||||||
|
/// </summary>
|
||||||
|
public string Name {
|
||||||
|
get {
|
||||||
|
return this["name"] as string;
|
||||||
|
} set {
|
||||||
|
this["name"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关联角色
|
||||||
|
/// </summary>
|
||||||
|
public LCRelation<LCRole> Roles {
|
||||||
|
get {
|
||||||
|
LCRelation<LCObject> roles = this["roles"] as LCRelation<LCObject>;
|
||||||
|
return new LCRelation<LCRole> {
|
||||||
|
Parent = roles.Parent,
|
||||||
|
Key = "roles"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关联用户
|
||||||
|
/// </summary>
|
||||||
|
public LCRelation<LCUser> Users {
|
||||||
|
get {
|
||||||
|
LCRelation<LCObject> users = this["users"] as LCRelation<LCObject>;
|
||||||
|
return new LCRelation<LCUser> {
|
||||||
|
Parent = users.Parent,
|
||||||
|
Key = "users"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public LCRole() : base(CLASS_NAME) {
|
public LCRole() : base(CLASS_NAME) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LCRole Create(string name, LCACL acl) {
|
||||||
|
LCRole role = new LCRole() {
|
||||||
|
Name = name,
|
||||||
|
ACL = acl
|
||||||
|
};
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取角色查询对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static LCQuery<LCRole> GetQuery() {
|
||||||
|
return new LCQuery<LCRole>(CLASS_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue