public static List <RqlNode> ExtractAggregates(RqlNode node) { if (node == null) { return(null); } var result = new List <RqlNode>(); if (node.NodeType == RqlNodeType.AND) { foreach (var child in node.Value <List <RqlNode> >()) { result.AddRange(ExtractAggregates(child)); } } else if (node.NodeType == RqlNodeType.OR) { foreach (var child in node.Value <List <RqlNode> >()) { result.AddRange(ExtractAggregates(child)); } } else if (node.NodeType == RqlNodeType.SUM) { return(new List <RqlNode>() { node }); } else if (node.NodeType == RqlNodeType.MIN) { return(new List <RqlNode>() { node }); } else if (node.NodeType == RqlNodeType.MAX) { return(new List <RqlNode>() { node }); } else if (node.NodeType == RqlNodeType.MEAN) { return(new List <RqlNode>() { node }); } return(result); }
/// <summary> /// Extract a Clause from the compiled RQL Query /// </summary> /// <param name="type"></param> /// <param name="node"></param> /// <returns></returns> public static RqlNode ExtractClause(RqlNodeType type, RqlNode node) { if (node == null) { return(null); } if (node.NodeType == RqlNodeType.AND) { foreach (var child in node.Value <List <RqlNode> >()) { var clause = ExtractClause(type, child); if (clause != null) { return(clause); } } } else if (node.NodeType == RqlNodeType.OR) { foreach (var child in node.Value <List <RqlNode> >()) { var clause = ExtractClause(type, child); if (clause != null) { return(clause); } } } else if (node.NodeType == type) { return(node); } return(null); }
/// <summary> /// Replaces a clause with a new one in place /// </summary> /// <param name="type"></param> /// <param name="node"></param> /// <param name="replacement"></param> /// <returns></returns> public static RqlNode ReplaceClause(RqlNodeType type, RqlNode node, RqlNode replacement) { if (node.NodeType == RqlNodeType.AND) { for (int i = 0; i < node.Value <List <RqlNode> >().Count; i++) { node.SetValue <RqlNode>(i, ReplaceClause(type, node.Value <RqlNode>(i), replacement)); } } else if (node.NodeType == RqlNodeType.OR) { for (int i = 0; i < node.Value <List <RqlNode> >().Count; i++) { node.SetValue <RqlNode>(i, ReplaceClause(type, node.Value <RqlNode>(i), replacement)); } } else if (node.NodeType == type) { return(replacement); } return(node); }
/// <summary> /// Gets a collection /// </summary> /// <param name="T">The type of items to retrieve</param> /// <param name="keys">The list of keys to further limit the results of the query.</param> /// <param name="node">The compiled RQL Query</param> /// <param name="NoPaging">Do not page results even if the result set exceeds the system defined limit. Default value = false.</param> /// <returns></returns> public async Task <object> GetCollectionAsync(Type T, IEnumerable <KeyValuePair <string, object> > keys, RqlNode node, bool NoPaging) { using (var ctc = new CancellationTokenSource()) { var task = Task.Run(async() => { var parameters = new List <SqlParameter>(); var pageFilter = RqlUtilities.ExtractClause(RqlNodeType.LIMIT, node); var options = ServiceProvider.GetService <IRepositoryOptions>(); var translationOptions = ServiceProvider.GetService <ITranslationOptions>(); var emitter = new Emitter(ServiceProvider); var rdgeneric = typeof(List <>); var rd = rdgeneric.MakeGenericType(T); var resultList = Activator.CreateInstance(rd); var rxgeneric = typeof(RqlCollection <>); var rx = rxgeneric.MakeGenericType(T); var results = Activator.CreateInstance(rx); var countProperty = results.GetType().GetProperty("count"); var itemsProperty = results.GetType().GetProperty("items"); var limitProperty = results.GetType().GetProperty("limit"); var hrefProperty = results.GetType().GetProperty("href"); var firstProperty = results.GetType().GetProperty("first"); var previousProperty = results.GetType().GetProperty("previous"); var nextProperty = results.GetType().GetProperty("next"); if (!NoPaging) { if (pageFilter != null && pageFilter.Value <int>(0) < 1) { pageFilter = new RqlNode(RqlNodeType.LIMIT, new List <int> { 1, options.BatchLimit }); } else { var sqlCount = emitter.BuildCollectionCountQuery(keys, node, parameters, T); Logger.BeginScope <string>(sqlCount.ToString()); Logger.LogTrace($"[REPOSITORY] ReadCollection<{T.Name}>"); // We now have an SQL query that needs to be executed in order to get our object. using (var command = new SqlCommand(sqlCount, _connection)) { foreach (var parameter in parameters) { command.Parameters.Add(parameter); } using (var reader = await command.ExecuteReaderAsync(ctc.Token)) { if (await reader.ReadAsync()) { countProperty.SetValue(results, await reader.ReadInt32Async("RecordCount", ctc.Token)); } } } } if (ctc.Token.IsCancellationRequested) { return(default);
/// <summary> /// Gets a collection /// </summary> /// <param name="T">The type of items to retrieve</param> /// <param name="node">The compiled RQL Query</param> /// <param name="NoPaging">Do not page results even if the result set exceeds the system defined limit. Default value = false.</param> /// <returns></returns> public async Task <object> GetCollectionAsync(Type T, RqlNode node, bool NoPaging) { return(await GetCollectionAsync(T, new List <KeyValuePair <string, object> >(), node, NoPaging)); }