chore: 支持 and 查询

oneRain 2019-08-07 14:58:24 +08:00
parent a3d477075a
commit 905cc943bf
2 changed files with 66 additions and 22 deletions

View File

@ -1,6 +1,7 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using LeanCloud;
namespace LeanCloudTests {
@ -16,7 +17,7 @@ namespace LeanCloudTests {
}
[Test]
public async Task TestQuery() {
public async Task BasicQuery() {
var query = new AVQuery<AVObject>("Foo");
query.WhereEqualTo("content", "hello");
var results = await query.FindAsync();
@ -26,11 +27,38 @@ namespace LeanCloudTests {
}
[Test]
public async Task TestQueryCount() {
public async Task Count() {
var query = new AVQuery<AVObject>("Foo");
query.WhereEqualTo("content", "hello, world");
var count = await query.CountAsync();
Assert.Greater(count, 8);
}
[Test]
public async Task Or() {
AVQuery<AVObject> q1 = new AVQuery<AVObject>("Foo");
q1.WhereEqualTo("content", "hello");
AVQuery<AVObject> q2 = new AVQuery<AVObject>("Foo");
q2.WhereEqualTo("content", "world");
AVQuery<AVObject> query = AVQuery<AVObject>.Or(new List<AVQuery<AVObject>> { q1, q2 });
IEnumerable<AVObject> results = await query.FindAsync();
foreach (AVObject result in results) {
TestContext.Out.WriteLine(result.ObjectId);
}
}
[Test]
public async Task And() {
AVQuery<AVObject> q1 = new AVQuery<AVObject>("Foo");
q1.WhereContains("content", "hello");
AVQuery<AVObject> q2 = new AVQuery<AVObject>("Foo");
q2.WhereContains("content", "world");
AVQuery<AVObject> query = AVQuery<AVObject>.And(new List<AVQuery<AVObject>> { q1, q2 });
IEnumerable<AVObject> results = await query.FindAsync();
TestContext.Out.WriteLine($"Count: {results.Count()}");
foreach (AVObject result in results) {
TestContext.Out.WriteLine(result.ObjectId);
}
}
}
}

View File

@ -152,40 +152,56 @@ namespace LeanCloud
return newSelectedKeys;
}
public static AVQuery<T> Or(IEnumerable<AVQuery<T>> queries)
{
public static AVQuery<T> Or(IEnumerable<AVQuery<T>> queries) {
string className = null;
var orValue = new List<IDictionary<string, object>>();
// We need to cast it to non-generic IEnumerable because of AOT-limitation
var nonGenericQueries = (IEnumerable)queries;
foreach (var obj in nonGenericQueries)
{
foreach (var obj in nonGenericQueries) {
var q = (AVQuery<T>)obj;
if (className != null && q.ClassName != className)
{
throw new ArgumentException(
"All of the queries in an or query must be on the same class.");
if (className != null && q.ClassName != className) {
throw new ArgumentException("All of the queries in an or query must be on the same class.");
}
className = q.ClassName;
var parameters = q.BuildParameters();
if (parameters.Count == 0)
{
if (parameters.Count == 0) {
continue;
}
object where;
if (!parameters.TryGetValue("where", out where) || parameters.Count > 1)
{
throw new ArgumentException(
"None of the queries in an or query can have non-filtering clauses");
if (!parameters.TryGetValue("where", out object where) || parameters.Count > 1) {
throw new ArgumentException("None of the queries in an or query can have non-filtering clauses");
}
orValue.Add(where as IDictionary<string, object>);
}
return new AVQuery<T>(new AVQuery<T>(className),
where: new Dictionary<string, object> {
return new AVQuery<T>(new AVQuery<T>(className), new Dictionary<string, object> {
{ "$or", orValue }
});
}
public static AVQuery<T> And(IEnumerable<AVQuery<T>> queries) {
string className = null;
var andValue = new List<IDictionary<string, object>>();
// We need to cast it to non-generic IEnumerable because of AOT-limitation
var nonGenericQueries = (IEnumerable)queries;
foreach (var obj in nonGenericQueries) {
var q = (AVQuery<T>)obj;
if (className != null && q.ClassName != className) {
throw new ArgumentException("All of the queries in an or query must be on the same class.");
}
className = q.ClassName;
var parameters = q.BuildParameters();
if (parameters.Count == 0) {
continue;
}
if (!parameters.TryGetValue("where", out object where) || parameters.Count > 1) {
throw new ArgumentException("None of the queries in an or query can have non-filtering clauses");
}
andValue.Add(where as IDictionary<string, object>);
}
return new AVQuery<T>(new AVQuery<T>(className), new Dictionary<string, object> {
{ "$and", andValue }
});
}
public Task<IEnumerable<T>> FindAsync(CancellationToken cancellationToken = default)
{
return AVUser.GetCurrentUserAsync().OnSuccess(t =>