* AVIMConversationQuery.cs: chore: AVIMConversation 使用

QueryCondition

* AVQuery.cs:
* QueryOperation.cs:
* IQueryCondition.cs:
* QueryEqualCondition.cs:
* QueryRelatedCondition.cs:
* QueryOperationCondition.cs:
* QueryCompositionalCondition.cs:
oneRain 2019-09-17 14:28:44 +08:00
parent 0aab4b959b
commit bd47c2e44e
8 changed files with 258 additions and 149 deletions

View File

@ -3,110 +3,80 @@ using LeanCloud.Storage.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace LeanCloud.Realtime namespace LeanCloud.Realtime {
{
/// <summary> /// <summary>
/// 对话查询类 /// 对话查询类
/// </summary> /// </summary>
public class AVIMConversationQuery public class AVIMConversationQuery {
{
internal AVIMClient CurrentClient { get; set; } internal AVIMClient CurrentClient { get; set; }
internal AVIMConversationQuery(AVIMClient _currentClient)
: base()
{
CurrentClient = _currentClient;
}
bool compact;
bool withLastMessageRefreshed;
QueryCombinedCondition condition;
/// <summary> public AVIMConversationQuery() {
/// Creates the instance. condition = new QueryCombinedCondition();
/// </summary>
/// <returns>The instance.</returns>
/// <param name="where">Where.</param>
/// <param name="replacementOrderBy">Replacement order by.</param>
/// <param name="thenBy">Then by.</param>
/// <param name="skip">Skip.</param>
/// <param name="limit">Limit.</param>
/// <param name="includes">Includes.</param>
/// <param name="selectedKeys">Selected keys.</param>
/// <param name="redirectClassNameForKey">Redirect class name for key.</param>
public AVIMConversationQuery CreateInstance(
IDictionary<string, object> where = null,
IEnumerable<string> replacementOrderBy = null,
IEnumerable<string> thenBy = null,
int? skip = null,
int? limit = null,
IEnumerable<string> includes = null,
IEnumerable<string> selectedKeys = null,
String redirectClassNameForKey = null)
{
var rtn = new AVIMConversationQuery(this, where, replacementOrderBy, thenBy, skip, limit, includes);
rtn.CurrentClient = this.CurrentClient;
rtn.compact = this.compact;
rtn.withLastMessageRefreshed = this.withLastMessageRefreshed;
return rtn;
} }
/// <summary> internal ConversationCommand GenerateQueryCommand() {
/// Withs the last message refreshed.
/// </summary>
/// <returns>The last message refreshed.</returns>
/// <param name="enabled">If set to <c>true</c> enabled.</param>
public AVIMConversationQuery WithLastMessageRefreshed(bool enabled)
{
this.withLastMessageRefreshed = enabled;
return this;
}
public AVIMConversationQuery Compact(bool enabled)
{
this.compact = enabled;
return this;
}
internal ConversationCommand GenerateQueryCommand()
{
var cmd = new ConversationCommand(); var cmd = new ConversationCommand();
var queryParameters = this.BuildParameters(false);
if (queryParameters != null)
{
if (queryParameters.Keys.Contains("where"))
cmd.Where(queryParameters["where"]);
if (queryParameters.Keys.Contains("skip")) var queryParameters = BuildParameters();
cmd.Skip(int.Parse(queryParameters["skip"].ToString())); if (queryParameters != null) {
if (queryParameters.TryGetValue("where", out object where)) {
if (queryParameters.Keys.Contains("limit")) cmd.Where(where);
cmd.Limit(int.Parse(queryParameters["limit"].ToString())); }
if (queryParameters.TryGetValue("skip", out object skip)) {
if (queryParameters.Keys.Contains("sort")) cmd.Skip((int)skip);
cmd.Sort(queryParameters["order"].ToString()); }
if (queryParameters.TryGetValue("limit", out object limit)) {
cmd.Limit((int)limit);
}
if (queryParameters.TryGetValue("order", out object order)) {
cmd.Sort(order.ToString());
}
} }
return cmd; return cmd;
} }
public Task<int> CountAsync(CancellationToken cancellationToken = default) { #region Combined Query
public static AVIMConversationQuery And(IEnumerable<AVIMConversationQuery> queries) {
AVIMConversationQuery composition = new AVIMConversationQuery();
if (queries != null) {
foreach (AVIMConversationQuery query in queries) {
composition.condition.AddCondition(query.condition);
}
}
return composition;
}
public static AVIMConversationQuery Or(IEnumerable<AVIMConversationQuery> queries) {
AVIMConversationQuery composition = new AVIMConversationQuery {
condition = new QueryCombinedCondition(QueryCombinedCondition.OR)
};
if (queries != null) {
foreach (AVIMConversationQuery query in queries) {
composition.condition.AddCondition(query.condition);
}
}
return composition;
}
#endregion
public Task<int> CountAsync() {
var convCmd = GenerateQueryCommand(); var convCmd = GenerateQueryCommand();
convCmd.Count(); convCmd.Count();
convCmd.Limit(0); convCmd.Limit(0);
var cmd = convCmd.Option("query"); var cmd = convCmd.Option("query");
return CurrentClient.RunCommandAsync(convCmd).OnSuccess(t => return CurrentClient.RunCommandAsync(convCmd).OnSuccess(t => {
{
var result = t.Result.Item2; var result = t.Result.Item2;
if (result.ContainsKey("count")) if (result.ContainsKey("count")) {
{
return int.Parse(result["count"].ToString()); return int.Parse(result["count"].ToString());
} }
return 0; return 0;
@ -117,24 +87,16 @@ namespace LeanCloud.Realtime
/// <summary> /// <summary>
/// 查找符合条件的对话 /// 查找符合条件的对话
/// </summary> /// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
public Task<IEnumerable<AVIMConversation>> FindAsync(CancellationToken cancellationToken = default) public Task<IEnumerable<AVIMConversation>> FindAsync() {
{ var convCmd = GenerateQueryCommand().Option("query");
var convCmd = this.GenerateQueryCommand().Option("query"); return CurrentClient.RunCommandAsync(convCmd).OnSuccess(t => {
return CurrentClient.RunCommandAsync(convCmd).OnSuccess(t =>
{
var result = t.Result.Item2; var result = t.Result.Item2;
IList<AVIMConversation> rtn = new List<AVIMConversation>(); IList<AVIMConversation> rtn = new List<AVIMConversation>();
var conList = result["results"] as IList<object>; if (result["results"] is IList<object> conList) {
if (conList != null) foreach (var c in conList) {
{ if (c is IDictionary<string, object> cData) {
foreach (var c in conList)
{
var cData = c as IDictionary<string, object>;
if (cData != null)
{
var con = AVIMConversation.CreateWithData(cData, CurrentClient); var con = AVIMConversation.CreateWithData(cData, CurrentClient);
rtn.Add(con); rtn.Add(con);
} }
@ -144,25 +106,194 @@ namespace LeanCloud.Realtime
}); });
} }
public Task<AVIMConversation> FirstAsync(CancellationToken cancellationToken = default) public Task<AVIMConversation> FirstAsync() {
{ return FirstOrDefaultAsync();
return this.FirstOrDefaultAsync();
} }
public Task<AVIMConversation> FirstOrDefaultAsync(CancellationToken cancellationToken = default) public Task<AVIMConversation> FirstOrDefaultAsync() {
{ var firstQuery = Limit(1);
var firstQuery = this.Limit(1); return firstQuery.FindAsync().OnSuccess(t => {
return firstQuery.FindAsync().OnSuccess(t =>
{
return t.Result.FirstOrDefault(); return t.Result.FirstOrDefault();
}); });
} }
public Task<AVIMConversation> GetAsync(string objectId, CancellationToken cancellationToken = default) public Task<AVIMConversation> GetAsync(string objectId) {
{ var idQuery = WhereEqualTo("objectId", objectId);
var idQuery = this.WhereEqualTo("objectId", objectId);
return idQuery.FirstAsync(); return idQuery.FirstAsync();
} }
}
public AVIMConversationQuery OrderBy(string key) {
condition.OrderBy(key);
return this;
}
public AVIMConversationQuery OrderByDescending(string key) {
condition.OrderByDescending(key);
return this;
}
public AVIMConversationQuery Include(string key) {
condition.Include(key);
return this;
}
public AVIMConversationQuery Select(string key) {
condition.Select(key);
return this;
}
public AVIMConversationQuery Skip(int count) {
condition.Skip(count);
return this;
}
public AVIMConversationQuery Limit(int count) {
condition.Limit(count);
return this;
}
#region Where
public AVIMConversationQuery WhereContainedIn<TIn>(string key, IEnumerable<TIn> values) {
condition.WhereContainedIn(key, values);
return this;
}
public AVIMConversationQuery WhereContainsAll<TIn>(string key, IEnumerable<TIn> values) {
condition.WhereContainsAll(key, values);
return this;
}
public AVIMConversationQuery WhereContains(string key, string substring) {
condition.WhereContains(key, substring);
return this;
}
public AVIMConversationQuery WhereDoesNotExist(string key) {
condition.WhereDoesNotExist(key);
return this;
}
public AVIMConversationQuery WhereDoesNotMatchQuery<TOther>(string key, AVQuery<TOther> query) where TOther : AVObject {
condition.WhereDoesNotMatchQuery(key, query);
return this;
}
public AVIMConversationQuery WhereEndsWith(string key, string suffix) {
condition.WhereEndsWith(key, suffix);
return this;
}
public AVIMConversationQuery WhereEqualTo(string key, object value) {
condition.WhereEqualTo(key, value);
return this;
}
public AVIMConversationQuery WhereSizeEqualTo(string key, uint size) {
condition.WhereSizeEqualTo(key, size);
return this;
}
public AVIMConversationQuery WhereExists(string key) {
condition.WhereExists(key);
return this;
}
public AVIMConversationQuery WhereGreaterThan(string key, object value) {
condition.WhereGreaterThan(key, value);
return this;
}
public AVIMConversationQuery WhereGreaterThanOrEqualTo(string key, object value) {
condition.WhereGreaterThanOrEqualTo(key, value);
return this;
}
public AVIMConversationQuery WhereLessThan(string key, object value) {
condition.WhereLessThan(key, value);
return this;
}
public AVIMConversationQuery WhereLessThanOrEqualTo(string key, object value) {
condition.WhereLessThanOrEqualTo(key, value);
return this;
}
public AVIMConversationQuery WhereMatches(string key, Regex regex, string modifiers) {
condition.WhereMatches(key, regex, modifiers);
return this;
}
public AVIMConversationQuery WhereMatches(string key, Regex regex) {
return WhereMatches(key, regex, null);
}
public AVIMConversationQuery WhereMatches(string key, string pattern, string modifiers) {
return WhereMatches(key, new Regex(pattern, RegexOptions.ECMAScript), modifiers);
}
public AVIMConversationQuery WhereMatches(string key, string pattern) {
return WhereMatches(key, pattern, null);
}
public AVIMConversationQuery WhereMatchesKeyInQuery<TOther>(string key, string keyInQuery, AVQuery<TOther> query) where TOther : AVObject {
condition.WhereMatchesKeyInQuery(key, keyInQuery, query);
return this;
}
public AVIMConversationQuery WhereDoesNotMatchesKeyInQuery<TOther>(string key, string keyInQuery, AVQuery<TOther> query) where TOther : AVObject {
condition.WhereDoesNotMatchesKeyInQuery(key, keyInQuery, query);
return this;
}
public AVIMConversationQuery WhereMatchesQuery<TOther>(string key, AVQuery<TOther> query) where TOther : AVObject {
condition.WhereMatchesQuery(key, query);
return this;
}
public AVIMConversationQuery WhereNear(string key, AVGeoPoint point) {
condition.WhereNear(key, point);
return this;
}
public AVIMConversationQuery WhereNotContainedIn<TIn>(string key, IEnumerable<TIn> values) {
condition.WhereNotContainedIn(key, values);
return this;
}
public AVIMConversationQuery WhereNotEqualTo(string key, object value) {
condition.WhereNotEqualTo(key, value);
return this;
}
public AVIMConversationQuery WhereStartsWith(string key, string suffix) {
condition.WhereStartsWith(key, suffix);
return this;
}
public AVIMConversationQuery WhereWithinGeoBox(string key, AVGeoPoint southwest, AVGeoPoint northeast) {
condition.WhereWithinGeoBox(key, southwest, northeast);
return this;
}
public AVIMConversationQuery WhereWithinDistance(string key, AVGeoPoint point, AVGeoDistance maxDistance) {
condition.WhereWithinDistance(key, point, maxDistance);
return this;
}
public AVIMConversationQuery WhereRelatedTo(AVObject parent, string key) {
condition.WhereRelatedTo(parent, key);
return this;
}
#endregion
public IDictionary<string, object> BuildParameters(string className = null) {
return condition.BuildParameters(className);
}
public IDictionary<string, object> BuildWhere() {
return condition.ToJSON();
}
}
} }

View File

@ -5,6 +5,6 @@ namespace LeanCloud.Storage.Internal {
/// IEquatable<IQueryCondition> 用于比对(替换)相同的查询条件 /// IEquatable<IQueryCondition> 用于比对(替换)相同的查询条件
/// IJsonConvertible 用于生成序列化 Dictionary /// IJsonConvertible 用于生成序列化 Dictionary
/// </summary> /// </summary>
internal interface IQueryCondition : IEquatable<IQueryCondition>, IJsonConvertible { public interface IQueryCondition : IEquatable<IQueryCondition>, IJsonConvertible {
} }
} }

View File

@ -4,9 +4,9 @@ using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace LeanCloud.Storage.Internal { namespace LeanCloud.Storage.Internal {
internal class QueryCompositionalCondition : IQueryCondition { public class QueryCombinedCondition : IQueryCondition {
internal const string AND = "$and"; public const string AND = "$and";
internal const string OR = "$or"; public const string OR = "$or";
readonly List<IQueryCondition> conditions; readonly List<IQueryCondition> conditions;
readonly string composition; readonly string composition;
@ -17,7 +17,7 @@ namespace LeanCloud.Storage.Internal {
internal int skip; internal int skip;
internal int limit; internal int limit;
internal QueryCompositionalCondition(string composition = AND) { public QueryCombinedCondition(string composition = AND) {
conditions = new List<IQueryCondition>(); conditions = new List<IQueryCondition>();
this.composition = composition; this.composition = composition;
skip = 0; skip = 0;
@ -177,21 +177,21 @@ namespace LeanCloud.Storage.Internal {
#endregion #endregion
internal void OrderBy(string key) { public void OrderBy(string key) {
if (orderBy == null) { if (orderBy == null) {
orderBy = new List<string>(); orderBy = new List<string>();
} }
orderBy.Add(key); orderBy.Add(key);
} }
internal void OrderByDescending(string key) { public void OrderByDescending(string key) {
if (orderBy == null) { if (orderBy == null) {
orderBy = new List<string>(); orderBy = new List<string>();
} }
orderBy.Add($"-{key}"); orderBy.Add($"-{key}");
} }
internal void Include(string key) { public void Include(string key) {
if (includes == null) { if (includes == null) {
includes = new HashSet<string>(); includes = new HashSet<string>();
} }
@ -202,7 +202,7 @@ namespace LeanCloud.Storage.Internal {
} }
} }
internal void Select(string key) { public void Select(string key) {
if (selectedKeys == null) { if (selectedKeys == null) {
selectedKeys = new HashSet<string>(); selectedKeys = new HashSet<string>();
} }
@ -213,15 +213,15 @@ namespace LeanCloud.Storage.Internal {
} }
} }
internal void Skip(int count) { public void Skip(int count) {
skip = count; skip = count;
} }
internal void Limit(int count) { public void Limit(int count) {
limit = count; limit = count;
} }
internal void AddCondition(string key, string op, object value) { public void AddCondition(string key, string op, object value) {
QueryOperationCondition cond = new QueryOperationCondition { QueryOperationCondition cond = new QueryOperationCondition {
Key = key, Key = key,
Op = op, Op = op,
@ -230,7 +230,7 @@ namespace LeanCloud.Storage.Internal {
AddCondition(cond); AddCondition(cond);
} }
internal void AddCondition(IQueryCondition condition) { public void AddCondition(IQueryCondition condition) {
if (condition == null) { if (condition == null) {
return; return;
} }
@ -245,7 +245,7 @@ namespace LeanCloud.Storage.Internal {
/// 构建查询字符串 /// 构建查询字符串
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal IDictionary<string, object> BuildParameters(string className) { public IDictionary<string, object> BuildParameters(string className) {
Dictionary<string, object> result = new Dictionary<string, object>(); Dictionary<string, object> result = new Dictionary<string, object>();
if (conditions != null) { if (conditions != null) {
result["where"] = ToJSON(); result["where"] = ToJSON();

View File

@ -11,8 +11,7 @@ namespace LeanCloud.Storage.Internal {
} }
public bool Equals(IQueryCondition other) { public bool Equals(IQueryCondition other) {
if (other is QueryEqualCondition) { if (other is QueryEqualCondition otherCond) {
QueryEqualCondition otherCond = other as QueryEqualCondition;
return key == otherCond.key; return key == otherCond.key;
} }
return false; return false;

View File

@ -1,19 +0,0 @@
using System;
namespace LeanCloud.Storage.Internal {
public class QueryOperation {
public string Key {
get; set;
}
public string Op {
get; set;
}
public object Value {
get; set;
}
}
}

View File

@ -15,8 +15,7 @@ namespace LeanCloud.Storage.Internal {
} }
public bool Equals(IQueryCondition other) { public bool Equals(IQueryCondition other) {
if (other is QueryOperationCondition) { if (other is QueryOperationCondition otherCond) {
QueryOperationCondition otherCond = other as QueryOperationCondition;
return Key == otherCond.Key && Op == otherCond.Op; return Key == otherCond.Key && Op == otherCond.Op;
} }
return false; return false;

View File

@ -11,8 +11,7 @@ namespace LeanCloud.Storage.Internal {
} }
public bool Equals(IQueryCondition other) { public bool Equals(IQueryCondition other) {
if (other is QueryRelatedCondition) { if (other is QueryRelatedCondition otherCond) {
QueryRelatedCondition otherCond = other as QueryRelatedCondition;
return key == otherCond.key; return key == otherCond.key;
} }
return false; return false;

View File

@ -31,7 +31,7 @@ namespace LeanCloud {
/// <summary> /// <summary>
/// 根查询条件,默认是 and 查询,可以设置为 or 查询 /// 根查询条件,默认是 and 查询,可以设置为 or 查询
/// </summary> /// </summary>
QueryCompositionalCondition condition; QueryCombinedCondition condition;
static AVQueryController QueryController { static AVQueryController QueryController {
get { get {
@ -48,10 +48,10 @@ namespace LeanCloud {
throw new ArgumentNullException(nameof(className)); throw new ArgumentNullException(nameof(className));
} }
ClassName = className; ClassName = className;
condition = new QueryCompositionalCondition(); condition = new QueryCombinedCondition();
} }
#region Compositional Query #region Combined Query
public static AVQuery<T> And(IEnumerable<AVQuery<T>> queries) { public static AVQuery<T> And(IEnumerable<AVQuery<T>> queries) {
AVQuery<T> composition = new AVQuery<T>(); AVQuery<T> composition = new AVQuery<T>();
@ -71,7 +71,7 @@ namespace LeanCloud {
public static AVQuery<T> Or(IEnumerable<AVQuery<T>> queries) { public static AVQuery<T> Or(IEnumerable<AVQuery<T>> queries) {
AVQuery<T> composition = new AVQuery<T> { AVQuery<T> composition = new AVQuery<T> {
condition = new QueryCompositionalCondition(QueryCompositionalCondition.OR) condition = new QueryCombinedCondition(QueryCombinedCondition.OR)
}; };
string className = null; string className = null;
if (queries != null) { if (queries != null) {