* AVIMConversationQuery.cs: chore: 抽象 QueryCondition
* AVQuery.cs: * AVRelation.cs: * AVQueryExtensions.cs: * AVQueryExtensions.cs: * QueryCompositionalCondition.cs:
parent
6252a06b72
commit
06707f75fe
|
@ -12,7 +12,7 @@ namespace LeanCloud.Realtime
|
|||
/// <summary>
|
||||
/// 对话查询类
|
||||
/// </summary>
|
||||
public class AVIMConversationQuery : AVQuery<AVObject>
|
||||
public class AVIMConversationQuery
|
||||
{
|
||||
internal AVIMClient CurrentClient { get; set; }
|
||||
internal AVIMConversationQuery(AVIMClient _currentClient)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace LeanCloud.Storage.Internal {
|
||||
internal class QueryCompositionalCondition : IQueryCondition {
|
||||
|
@ -8,9 +11,18 @@ namespace LeanCloud.Storage.Internal {
|
|||
readonly List<IQueryCondition> conditions;
|
||||
readonly string composition;
|
||||
|
||||
internal ReadOnlyCollection<string> orderBy;
|
||||
internal HashSet<string> includes;
|
||||
internal HashSet<string> selectedKeys;
|
||||
internal string redirectClassNameForKey;
|
||||
internal int skip;
|
||||
internal int limit;
|
||||
|
||||
internal QueryCompositionalCondition(string composition = AND) {
|
||||
conditions = new List<IQueryCondition>();
|
||||
this.composition = composition;
|
||||
skip = 0;
|
||||
limit = 30;
|
||||
}
|
||||
|
||||
public bool Equals(IQueryCondition other) {
|
||||
|
@ -33,6 +45,73 @@ namespace LeanCloud.Storage.Internal {
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建查询字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDictionary<string, object> BuildParameters(string className) {
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
if (conditions != null) {
|
||||
result["where"] = ToJSON();
|
||||
}
|
||||
if (orderBy != null) {
|
||||
result["order"] = string.Join(",", orderBy.ToArray());
|
||||
}
|
||||
if (includes != null) {
|
||||
result["include"] = string.Join(",", includes.ToArray());
|
||||
}
|
||||
if (selectedKeys != null) {
|
||||
result["keys"] = string.Join(",", selectedKeys.ToArray());
|
||||
}
|
||||
if (!string.IsNullOrEmpty(className)) {
|
||||
result["className"] = className;
|
||||
}
|
||||
if (redirectClassNameForKey != null) {
|
||||
result["redirectClassNameForKey"] = redirectClassNameForKey;
|
||||
}
|
||||
result["skip"] = skip;
|
||||
result["limit"] = limit;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void OrderBy(string key) {
|
||||
orderBy = new ReadOnlyCollection<string>(new List<string> { key });
|
||||
}
|
||||
|
||||
internal void OrderByDescending(string key) {
|
||||
orderBy = new ReadOnlyCollection<string>(new List<string> { "-" + key });
|
||||
}
|
||||
|
||||
internal void Include(string key) {
|
||||
if (includes == null) {
|
||||
includes = new HashSet<string>();
|
||||
}
|
||||
try {
|
||||
includes.Add(key);
|
||||
} catch (Exception e) {
|
||||
AVClient.PrintLog(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Select(string key) {
|
||||
if (selectedKeys == null) {
|
||||
selectedKeys = new HashSet<string>();
|
||||
}
|
||||
try {
|
||||
selectedKeys.Add(key);
|
||||
} catch (Exception e) {
|
||||
AVClient.PrintLog(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Skip(int count) {
|
||||
skip = count;
|
||||
}
|
||||
|
||||
internal void Limit(int count) {
|
||||
limit = count;
|
||||
}
|
||||
|
||||
internal void AddCondition(IQueryCondition condition) {
|
||||
if (condition == null) {
|
||||
return;
|
||||
|
|
|
@ -17,10 +17,6 @@ namespace LeanCloud.Storage.Internal {
|
|||
return query.ClassName;
|
||||
}
|
||||
|
||||
public static IDictionary<string, object> BuildParameters<T>(this AVQuery<T> query) where T: AVObject {
|
||||
return query.BuildParameters(false);
|
||||
}
|
||||
|
||||
public static object GetConstraint<T>(this AVQuery<T> query, string key) where T : AVObject {
|
||||
return query.GetConstraint(key);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
@ -31,13 +30,6 @@ namespace LeanCloud {
|
|||
|
||||
internal QueryCompositionalCondition condition;
|
||||
|
||||
internal ReadOnlyCollection<string> orderBy;
|
||||
internal ReadOnlyCollection<string> includes;
|
||||
internal ReadOnlyCollection<string> selectedKeys;
|
||||
internal string redirectClassNameForKey;
|
||||
internal int? skip;
|
||||
internal int? limit;
|
||||
|
||||
internal static AVQueryController QueryController {
|
||||
get {
|
||||
return AVPlugins.Instance.QueryController;
|
||||
|
@ -121,12 +113,9 @@ namespace LeanCloud {
|
|||
}
|
||||
|
||||
public virtual async Task<T> GetAsync(string objectId, CancellationToken cancellationToken) {
|
||||
AVQuery<T> singleItemQuery = new AVQuery<T>(ClassName)
|
||||
.WhereEqualTo("objectId", objectId);
|
||||
singleItemQuery.includes = includes;
|
||||
singleItemQuery.selectedKeys = selectedKeys;
|
||||
singleItemQuery.limit = 1;
|
||||
var result = await singleItemQuery.FindAsync(cancellationToken);
|
||||
WhereEqualTo("objectId", objectId);
|
||||
Limit(1);
|
||||
var result = await FindAsync(cancellationToken);
|
||||
var first = result.FirstOrDefault();
|
||||
if (first == null) {
|
||||
throw new AVException(AVException.ErrorCode.ObjectNotFound,
|
||||
|
@ -179,40 +168,6 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 构建查询字符串
|
||||
/// </summary>
|
||||
/// <param name="includeClassName">是否包含 ClassName </param>
|
||||
/// <returns></returns>
|
||||
public IDictionary<string, object> BuildParameters(bool includeClassName = false) {
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
if (condition != null) {
|
||||
result["where"] = condition.ToJSON();
|
||||
}
|
||||
if (orderBy != null) {
|
||||
result["order"] = string.Join(",", orderBy.ToArray());
|
||||
}
|
||||
if (skip != null) {
|
||||
result["skip"] = skip.Value;
|
||||
}
|
||||
if (limit != null) {
|
||||
result["limit"] = limit.Value;
|
||||
}
|
||||
if (includes != null) {
|
||||
result["include"] = string.Join(",", includes.ToArray());
|
||||
}
|
||||
if (selectedKeys != null) {
|
||||
result["keys"] = string.Join(",", selectedKeys.ToArray());
|
||||
}
|
||||
if (includeClassName) {
|
||||
result["className"] = ClassName;
|
||||
}
|
||||
if (redirectClassNameForKey != null) {
|
||||
result["redirectClassNameForKey"] = redirectClassNameForKey;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object is equal to the current object.
|
||||
/// </summary>
|
||||
|
@ -225,12 +180,7 @@ namespace LeanCloud {
|
|||
|
||||
var other = obj as AVQuery<T>;
|
||||
return ClassName.Equals(other.ClassName) &&
|
||||
condition.Equals(other.condition) &&
|
||||
orderBy.CollectionsEqual(other.orderBy) &&
|
||||
includes.CollectionsEqual(other.includes) &&
|
||||
selectedKeys.CollectionsEqual(other.selectedKeys) &&
|
||||
Equals(skip, other.skip) &&
|
||||
Equals(limit, other.limit);
|
||||
condition.Equals(other.condition);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
|
@ -240,59 +190,34 @@ namespace LeanCloud {
|
|||
#region Order By
|
||||
|
||||
public AVQuery<T> OrderBy(string key) {
|
||||
orderBy = new ReadOnlyCollection<string>(new List<string> { key });
|
||||
condition.OrderBy(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> OrderByDescending(string key) {
|
||||
orderBy = new ReadOnlyCollection<string>(new List<string> { "-" + key });
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> ThenBy(string key) {
|
||||
if (orderBy == null) {
|
||||
throw new ArgumentException("You must call OrderBy before calling ThenBy");
|
||||
}
|
||||
List<string> newOrderBy = orderBy.ToList();
|
||||
newOrderBy.Add(key);
|
||||
orderBy = new ReadOnlyCollection<string>(newOrderBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> ThenByDescending(string key) {
|
||||
if (orderBy == null) {
|
||||
throw new ArgumentException("You must call OrderBy before calling ThenBy");
|
||||
}
|
||||
List<string> newOrderBy = orderBy.ToList();
|
||||
newOrderBy.Add($"-{key}");
|
||||
orderBy = new ReadOnlyCollection<string>(newOrderBy);
|
||||
condition.OrderByDescending(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public AVQuery<T> Include(string key) {
|
||||
includes = new ReadOnlyCollection<string>(new List<string> { key });
|
||||
condition.Include(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> Select(string key) {
|
||||
selectedKeys = new ReadOnlyCollection<string>(new List<string> { key });
|
||||
condition.Select(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> Skip(int count) {
|
||||
skip = count;
|
||||
condition.Skip(count);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AVQuery<T> Limit(int count) {
|
||||
limit = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal AVQuery<T> RedirectClassName(string key) {
|
||||
redirectClassNameForKey = key;
|
||||
condition.Limit(count);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -320,7 +245,7 @@ namespace LeanCloud {
|
|||
|
||||
public AVQuery<T> WhereDoesNotMatchQuery<TOther>(string key, AVQuery<TOther> query)
|
||||
where TOther : AVObject {
|
||||
AddCondition(key, "$notInQuery", query.BuildParameters(true));
|
||||
AddCondition(key, "$notInQuery", query.BuildParameters(query.ClassName));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -389,7 +314,7 @@ namespace LeanCloud {
|
|||
public AVQuery<T> WhereMatchesKeyInQuery<TOther>(string key, string keyInQuery, AVQuery<TOther> query)
|
||||
where TOther : AVObject {
|
||||
var parameters = new Dictionary<string, object> {
|
||||
{ "query", query.BuildParameters(true)},
|
||||
{ "query", query.BuildParameters(query.ClassName)},
|
||||
{ "key", keyInQuery}
|
||||
};
|
||||
AddCondition(key, "$select", parameters);
|
||||
|
@ -399,7 +324,7 @@ namespace LeanCloud {
|
|||
public AVQuery<T> WhereDoesNotMatchesKeyInQuery<TOther>(string key, string keyInQuery, AVQuery<TOther> query)
|
||||
where TOther : AVObject {
|
||||
var parameters = new Dictionary<string, object> {
|
||||
{ "query", query.BuildParameters(true)},
|
||||
{ "query", query.BuildParameters(query.ClassName)},
|
||||
{ "key", keyInQuery}
|
||||
};
|
||||
AddCondition(key, "$dontSelect", parameters);
|
||||
|
@ -408,7 +333,7 @@ namespace LeanCloud {
|
|||
|
||||
public AVQuery<T> WhereMatchesQuery<TOther>(string key, AVQuery<TOther> query)
|
||||
where TOther : AVObject {
|
||||
AddCondition(key, "$inQuery", query.BuildParameters(true));
|
||||
AddCondition(key, "$inQuery", query.BuildParameters(query.ClassName));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -453,6 +378,10 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
internal IDictionary<string, object> BuildParameters(string className = null) {
|
||||
return condition.BuildParameters(className);
|
||||
}
|
||||
|
||||
private string RegexQuote(string input) {
|
||||
return "\\Q" + input.Replace("\\E", "\\E\\\\E\\Q") + "\\E";
|
||||
}
|
||||
|
|
|
@ -703,38 +703,6 @@ namespace LeanCloud
|
|||
return source.OrderByDescending(GetOrderByPath(keySelector));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a subsequent ordering of a query based upon the key selector provided.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of AVObject being queried for.</typeparam>
|
||||
/// <typeparam name="TSelector">The type of key returned by keySelector.</typeparam>
|
||||
/// <param name="source">The query to order.</param>
|
||||
/// <param name="keySelector">A function to extract a key from the AVObject.</param>
|
||||
/// <returns>A new AVQuery based on Source whose results will be ordered by
|
||||
/// the key specified in the keySelector.</returns>
|
||||
public static AVQuery<TSource> ThenBy<TSource, TSelector>(
|
||||
this AVQuery<TSource> source, Expression<Func<TSource, TSelector>> keySelector)
|
||||
where TSource : AVObject
|
||||
{
|
||||
return source.ThenBy(GetOrderByPath(keySelector));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a subsequent ordering of a query based upon the key selector provided.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of AVObject being queried for.</typeparam>
|
||||
/// <typeparam name="TSelector">The type of key returned by keySelector.</typeparam>
|
||||
/// <param name="source">The query to order.</param>
|
||||
/// <param name="keySelector">A function to extract a key from the AVObject.</param>
|
||||
/// <returns>A new AVQuery based on Source whose results will be ordered by
|
||||
/// the key specified in the keySelector.</returns>
|
||||
public static AVQuery<TSource> ThenByDescending<TSource, TSelector>(
|
||||
this AVQuery<TSource> source, Expression<Func<TSource, TSelector>> keySelector)
|
||||
where TSource : AVObject
|
||||
{
|
||||
return source.ThenByDescending(GetOrderByPath(keySelector));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Correlates the elements of two queries based on matching keys.
|
||||
/// </summary>
|
||||
|
|
|
@ -63,7 +63,6 @@ namespace LeanCloud {
|
|||
}
|
||||
|
||||
return new AVQuery<T>(parent.ClassName)
|
||||
.RedirectClassName(key)
|
||||
.WhereRelatedTo(parent, key);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue