* 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 LeanCloud;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Test {
|
||||
public class RelationTest {
|
||||
[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]
|
||||
public async Task CreateRelation() {
|
||||
AVObject tag1 = new AVObject("Tag") {
|
||||
["name"] = "hello"
|
||||
};
|
||||
await tag1.SaveAsync();
|
||||
AVObject tag2 = new AVObject("Tag") {
|
||||
{ "name", "world" }
|
||||
};
|
||||
await tag2.SaveAsync();
|
||||
AVObject todo = new AVObject("Todo");
|
||||
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
|
||||
relation.Add(tag1);
|
||||
relation.Add(tag2);
|
||||
await todo.SaveAsync();
|
||||
public async Task AddAndRemove() {
|
||||
LCObject parent = new LCObject("Parent");
|
||||
LCObject c1 = new LCObject("Child");
|
||||
parent.AddRelation("children", c1);
|
||||
LCObject c2 = new LCObject("Child");
|
||||
parent.AddRelation("children", c2);
|
||||
await parent.Save();
|
||||
|
||||
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
|
||||
LCQuery<LCObject> query = relation.Query;
|
||||
int count = await query.Count();
|
||||
|
||||
TestContext.WriteLine($"count: {count}");
|
||||
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]
|
||||
public async Task QueryRelation() {
|
||||
AVQuery<AVObject> query = new AVQuery<AVObject>("Todo");
|
||||
query.OrderByDescending("createdAt");
|
||||
AVObject todo = await query.FirstAsync();
|
||||
AVRelation<AVObject> relation = todo.GetRelation<AVObject>("tags");
|
||||
AVQuery<AVObject> tagQuery = relation.Query;
|
||||
IEnumerable<AVObject> tags = await tagQuery.FindAsync();
|
||||
Assert.Greater(tags.Count(), 0);
|
||||
TestContext.Out.WriteLine($"count: {tags.Count()}");
|
||||
foreach (AVObject tag in tags) {
|
||||
TestContext.Out.WriteLine($"{tag.ObjectId}, {tag["name"]}");
|
||||
}
|
||||
public async Task Query() {
|
||||
LCQuery<LCObject> query = new LCQuery<LCObject>("Parent");
|
||||
LCObject parent = await query.Get("5e13112021b47e0070ed0922");
|
||||
LCRelation<LCObject> relation = parent["children"] as LCRelation<LCObject>;
|
||||
|
||||
TestContext.WriteLine(relation.Key);
|
||||
TestContext.WriteLine(relation.Parent);
|
||||
TestContext.WriteLine(relation.TargetClass);
|
||||
|
||||
Assert.NotNull(relation.Key);
|
||||
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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LeanCloud;
|
||||
using System.Linq;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Test {
|
||||
[TestFixture]
|
||||
public class RoleTest {
|
||||
[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]
|
||||
public async Task GetUsersFromRole() {
|
||||
AVQuery<AVRole> query = new AVQuery<AVRole>();
|
||||
AVRole role = await query.FirstAsync();
|
||||
AVQuery<AVUser> userQuery = role.Users.Query;
|
||||
IEnumerable<AVUser> users = await userQuery.FindAsync();
|
||||
Assert.Greater(users.Count(), 0);
|
||||
TestContext.Out.WriteLine($"count: {users.Count()}");
|
||||
foreach (AVUser user in users) {
|
||||
TestContext.Out.WriteLine($"{user.ObjectId}, {user.Username}");
|
||||
public async Task NewRole() {
|
||||
LCUser currentUser = await LCUser.Login("game", "play");
|
||||
LCACL acl = new LCACL();
|
||||
acl.PublicReadAccess = true;
|
||||
acl.SetUserWriteAccess(currentUser, true);
|
||||
string name = $"role_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}";
|
||||
LCRole role = LCRole.Create(name, acl);
|
||||
role.AddRelation("users", currentUser);
|
||||
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) {
|
||||
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
||||
relation.targetClass = dict["className"].ToString();
|
||||
relation.TargetClass = dict["className"].ToString();
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace LeanCloud.Storage.Internal.Codec {
|
|||
static object EncodeRelation(LCRelation<LCObject> relation) {
|
||||
return new Dictionary<string, object> {
|
||||
{ "__type", "Relation" },
|
||||
{ "className", relation.targetClass }
|
||||
{ "className", relation.TargetClass }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace LeanCloud.Storage.Internal.Operation {
|
|||
|
||||
public object Apply(object oldValue, string key) {
|
||||
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
||||
relation.targetClass = valueList[0].ClassName;
|
||||
relation.TargetClass = valueList[0].ClassName;
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace LeanCloud.Storage.Internal.Operation {
|
|||
|
||||
public object Apply(object oldValue, string key) {
|
||||
LCRelation<LCObject> relation = new LCRelation<LCObject>();
|
||||
relation.targetClass = valueList[0].ClassName;
|
||||
relation.TargetClass = valueList[0].ClassName;
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,28 @@ namespace LeanCloud.Storage {
|
|||
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) {
|
||||
while (batches.Count > 0) {
|
||||
LCBatch batch = batches.Pop();
|
||||
|
|
|
@ -1,20 +1,41 @@
|
|||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// 关系类
|
||||
/// </summary>
|
||||
namespace LeanCloud.Storage {
|
||||
public class LCRelation<T> where T : LCObject {
|
||||
/// <summary>
|
||||
/// 字段名
|
||||
/// </summary>
|
||||
public string Key {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 父对象
|
||||
/// </summary>
|
||||
public LCObject Parent {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string targetClass {
|
||||
/// <summary>
|
||||
/// 关联类型名
|
||||
/// </summary>
|
||||
public string TargetClass {
|
||||
get; set;
|
||||
}
|
||||
|
||||
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 {
|
||||
namespace LeanCloud.Storage {
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public class LCRole : LCObject {
|
||||
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 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