private async Task TransformObject(object item, IGraphRequestContext context, MutationActions mutationAction) { await TransformObjects(new List <object> { item }, context, mutationAction); }
public async Task DeleteAsync <T>(T item, IGraphRequestContext graphRequestContext) where T : class { var info = Get <T>(graphRequestContext); await info.Table.ExecuteAsync(TableOperation.Delete(Convert(item, info.PartitionKeyMemberName))); }
public async Task <IEnumerable <T> > QueryAsync <T>(string queryName, IEnumerable <QueryParameter> queryParameters, Dictionary <string, object> stepBagItems, IGraphRequestContext graphRequestContext) where T : class { var parameters = queryParameters.ToList(); Dictionary <string, string> items = parameters.ToDictionary(x => x.MemberModel.Name, x => { if (!x.ContextValue.IsSingleValue()) { // TODO: Investigate the impact as we need to support multiple values. throw new NotImplementedException("Multiple values not supported."); } return(x.ContextValue.GetFirstValue().ToString()); }); // ReSharper disable once AssignNullToNotNullAttribute var resourceQueries = _queryTransforms[typeof(T).FullName]; var resourceQuery = resourceQueries[queryName](items); var httpClient = GetHttpClient <T>(); HttpResponseMessage response; switch (resourceQuery.QueryType) { case HttpQueryTypes.AppendToUrl: response = await httpClient.GetAsync(resourceQuery.AppendUrl); break; default: throw new NotImplementedException(); } response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); return(resourceQuery.IsListResult ? JsonConvert.DeserializeObject <List <T> >(result) : new List <T> { JsonConvert.DeserializeObject <T>(result) }); }
public async Task <SearchResult> QueryAsync <T>(IEnumerable <QueryParameter> queryParameters, Type type, bool enableAggregate, IGraphRequestContext graphRequestContext) where T : class { var searchResult = new SearchResult { Values = new List <SearchResultModel>(), Aggregates = new List <SearchAggregateModel>() }; var searchResultModels = new List <SearchResultModel>(); var client = InternalGetInfo(type.Name, graphRequestContext).SearchIndexClient; var searchParameters = new SearchParameters(); TypeAccessor accessor = TypeAccessor.Create(type); var members = accessor.GetMembers(); if (enableAggregate) { searchParameters.Facets = members.Where(x => x.GetAttribute(typeof(IsFacetableAttribute), false) != null).Select(x => x.Name).ToList(); } var searchTextParam = queryParameters.Single(x => x.MemberModel.Name == "searchtext"); if (enableAggregate) { searchParameters.Filter = _searchFilterProvider.GenerateStringFilter(queryParameters, members); } var results = await client.Documents.SearchAsync((string)searchTextParam.ContextValue.GetFirstValue(), searchParameters); searchResult.AddValues(accessor, results); searchResult.AddFacets(results); return(searchResult); }
public async Task <IEnumerable <TSource> > ExecuteAsync(string queryName, IEnumerable <QueryStep> querySteps, IGraphRequestContext graphRequestContext, List <ConnectionEdgeDestinationFilter> connectionEdgeDestinationFilters) { var ctx = new QueryExecutionContext(graphRequestContext); foreach (var queryStep in querySteps) { queryStep.Started = DateTime.UtcNow; // If there are any runtime mappers, run them first. queryStep.QueryParameters.ForEach(qp => { if (qp.Mapper != null) { var values = qp.Mapper(new MapperQueryExecutionContext(ctx, queryStep)); if (values.Count > 0) { qp.ContextValue = new ContextValue { Values = values, Comparison = Comparisons.Equal }; } } }); var nextQueryResults = new List <object>(); if (queryStep.StepMapper != null) { var queryValues = queryStep.StepMapper(new MapperQueryExecutionContext(ctx, queryStep)); if (queryValues.Count > 0) { var first = queryStep.QueryParameters.FirstOrDefault(x => x.Rule != null && x.Rule.PopulateWithQueryValues); if (first == null) { first = queryStep.QueryParameters.First(); } first.ContextValue = new ContextValue { Values = queryValues, Comparison = Comparisons.Equal, SelectValues = first.ContextValue != null && first.ContextValue.SelectValues != null ? first.ContextValue.SelectValues : null }; try { nextQueryResults.AddRange(await QueryAsync(queryName, queryStep, graphRequestContext, ctx, connectionEdgeDestinationFilters)); } catch (Exception e) { _logger.LogError(e, "An error has occured while executing query on repository."); throw; } } else { _logger.LogWarning($"No values detected for queryStep @ {queryName}"); } } else { if (!IsInvalidForNextQuery(queryStep)) { nextQueryResults.AddRange(await QueryAsync(queryName, queryStep, graphRequestContext, ctx, connectionEdgeDestinationFilters)); } else { _logger.LogWarning($"Invalid values detected for queryStep @ {queryName}"); } } ctx.SetQueryResult(nextQueryResults); queryStep.ContextAction?.Invoke(ctx); queryStep.Ended = DateTime.UtcNow; } return(ctx.GetResults <TSource>()); }
public bool CanHandle(string typeName, IGraphRequestContext graphRequestContext) { return(InternalGetInfo(typeName.ToLower(), graphRequestContext) != null); }
public async Task BatchCreateAsync <T>(IEnumerable <T> items, IGraphRequestContext graphRequestContext) where T : class { var client = Get <T>(graphRequestContext); var list = items.Select(IndexAction.Upload).ToList(); await client.Documents.IndexAsync(IndexBatch.New(list)); }
public async Task UpdateAsync <T>(T item, IGraphRequestContext graphRequestContext) where T : class { var info = Get <T>(graphRequestContext); var partitionKey = item.GetMemberStringValue(info.PartitionKeyMemberName); await info.Table.ExecuteAsync(TableOperation.Replace(Convert(item, partitionKey))); }
private SearchClientProvider GetProvider <T>(IGraphRequestContext graphRequestContext) where T : class { return(_providers.Single(x => x.CanHandle <T>(graphRequestContext))); }
public async Task <IEnumerable <TSource> > ExecuteAsync(string queryName, IEnumerable <QueryStep> querySteps, IGraphRequestContext graphRequestContext) { var ctx = new QueryExecutionContext(); foreach (var queryStep in querySteps) { queryStep.Started = DateTime.UtcNow; if (queryStep.Mapper != null) { // We may have to make several queries. var nextQueryResults = new List <object>(); var queryValues = queryStep.Mapper(ctx); if (queryValues.Count > 0) { var first = queryStep.QueryParameters.First(); first.ContextValue = new ContextValue { Values = queryValues, Comparison = Comparisons.Equal }; try { var results = await QueryAsync(queryName, queryStep, graphRequestContext); nextQueryResults.AddRange(results); } catch (Exception e) { _logger.LogError(e, "An error has occured while executing query on repository."); throw; } } else { _logger.LogWarning($"No values detected for queryStep @ {queryName}"); } ctx.SetQueryResult(nextQueryResults); } else { ctx.SetQueryResult(await QueryAsync(queryName, queryStep, graphRequestContext)); } queryStep.ContextAction?.Invoke(ctx); queryStep.Ended = DateTime.UtcNow; } return(ctx.GetResults <TSource>()); }
private async Task <List <object> > QueryAsync(string queryName, QueryStep queryStep, IGraphRequestContext graphRequestContext) { var results = (await _graphQlRepositoryProvider.QueryAsync(queryName, queryStep, graphRequestContext)).ToList(); if (results.Count > 0) { if (results.First().GetType() == typeof(SearchResultModel)) { return(results); } await _connectionEdgeHandler.QueryAsync(results, queryStep, graphRequestContext); } return(results); }
public async Task <IEnumerable <object> > QueryAsync(string queryName, QueryStep queryStep, IGraphRequestContext graphRequestContext) { var list = queryStep.QueryParameters.ToList(); // ReSharper disable once AssignNullToNotNullAttribute var repo = _repositories[list.First().MemberModel.SourceType.FullName]; MethodInfo method = repo.GetType().GetMethod("QueryAsync"); // ReSharper disable once PossibleNullReferenceException var sourceType = list.First().MemberModel.SourceType; if (queryStep.OverrideRepositoryWithType != null) { sourceType = queryStep.OverrideRepositoryWithType; } MethodInfo generic = method.MakeGenericMethod(sourceType); var task = (Task)generic.Invoke(repo, new object[] { queryName, list, queryStep.Items, graphRequestContext }); await task.ConfigureAwait(false); var resultProperty = task.GetType().GetProperty("Result"); // ReSharper disable once PossibleNullReferenceException return((IEnumerable <object>)resultProperty.GetValue(task)); }
private async Task ProcessListAsync(List <object> items, MutationActions action, IGraphRequestContext context, bool forceHandle) { var typeAccessor = TypeAccessor.Create(items.First().GetType()); var listMembers = typeAccessor.GetMembers().Where(x => x.IsList()); var connectionEdgeMembers = typeAccessor.GetMembers().Where(x => x.GetAttribute(typeof(ConnectionEdgeDestinationAttribute), false) != null); foreach (var x in _modelTransformers) { if (forceHandle || x.CanHandle(action)) { foreach (var item in items) { await x.TransformAsync(item, typeAccessor, context); foreach (var member in listMembers) { var value = typeAccessor[item, member.Name]; if (value != null) { List <object> memberItems = new List <object>(); var list = (IList)value; foreach (var item1 in list) { memberItems.Add(item1); } if (memberItems.Count > 0) { await ProcessListAsync(memberItems, action, context, true); } } } foreach (var member in connectionEdgeMembers) { var value = typeAccessor[item, member.Name]; if (value != null) { await ProcessListAsync(new List <object> { value }, action, context, true); } } } } } }
private async Task QueryAndPopulateEdgeConnections( List <SelectValue> selections, List <object> results, IGraphRequestContext graphRequestContext, List <ConnectionEdgeDestinationFilter> connectionEdgeDestinationFilters, QueryExecutionContext queryExecutionContext) { var edgeQueryParameters = _connectionEdgeResolver.ListConnectionEdgeQueryParameter(results) .Where(x => selections.Any(y => y.FieldName.ToLower() == x.SourceFieldName.ToLower())).ToList(); if (edgeQueryParameters.Count > 0) { var connectionEdges = (await GetConnectionEdgeRepository().QueryAsync <ConnectionEdge>( ConnectionEdgeQueryName, edgeQueryParameters.ToQueryParameters(), null, graphRequestContext)).ToList(); if (connectionEdges.Count > 0) { var accessor = TypeAccessor.Create(results.First().GetType()); var dictionary = new Dictionary <string, object>(); results.ForEach(item => dictionary.Add(accessor.GetKey(item), item)); foreach (var connectionEdge in connectionEdges) { if (!dictionary.ContainsKey(connectionEdge.SourceId)) { throw new InvalidOperationException($"{connectionEdge.SourceId} is invalid."); } var sourceObject = dictionary[connectionEdge.SourceId]; var edgeObject = DeserializeObject(connectionEdge.MetaValue, connectionEdge.MetaType); var member = accessor.GetMembers().Single(x => x.Name == connectionEdge.SourceFieldName); if (member.IsList()) { member.CreateNewListIfNullThenAddItemToList(accessor, sourceObject, edgeObject); } else { accessor[sourceObject, connectionEdge.SourceFieldName] = edgeObject; } var selection = selections.SingleOrDefault(s => s.FieldName.ToLower() == connectionEdge.SourceFieldName.ToLower()); if (selection != null) { var edgeObjectType = edgeObject.GetType(); var edgeObjectTypeAccessor = TypeAccessor.Create(edgeObjectType); var entity = await GetValue(edgeObjectTypeAccessor, connectionEdge, graphRequestContext, connectionEdgeDestinationFilters, queryExecutionContext); if (entity == null) { _logger.LogWarning($"The following connection edge did not yield a record: {JsonConvert.SerializeObject(connectionEdge)}"); continue; } edgeObjectTypeAccessor[edgeObject, connectionEdge.MetaFieldName] = entity; var matchingFieldName = connectionEdge.MetaFieldName.ToLower(); var matchingSelections = selections.Where(x => x.SelectValues.Any(y => y.FieldName.ToLower() == matchingFieldName)); foreach (var matchingSelection in matchingSelections) { var selectionWithSelects = matchingSelection.SelectValues.Single(x => x.FieldName.ToLower() == matchingFieldName) .SelectValues.Where(x => x.SelectValues.Count > 0).ToList(); if (selectionWithSelects.Count > 0) { await QueryAndPopulateEdgeConnections(selectionWithSelects, new List <object> { entity }, graphRequestContext, connectionEdgeDestinationFilters, queryExecutionContext); } } } } } } }
public async Task BatchAddOrUpdateAsync <T>(IEnumerable <T> items, IGraphRequestContext graphRequestContext) where T : class { await GetProvider <T>(graphRequestContext).BatchAddOrUpdateAsync(items, graphRequestContext); }
public async Task <IEnumerable <T> > QueryAsync <T>(string queryName, IEnumerable <QueryParameter> queryParameters, Dictionary <string, object> stepBagItems, IGraphRequestContext graphRequestContext) where T : class { var searchResult = new List <SearchResult>(); var searchTypes = (Type[])stepBagItems[SearchConstants.QueryTypes]; var queryParametersList = queryParameters.ToList(); var enableAggregate = stepBagItems.ContainsKey(SearchConstants.EnableAggregate); foreach (var searchType in searchTypes) { var provider = _providers.Single(x => x.CanHandle(searchType.Name, graphRequestContext)); var result = await provider.QueryAsync <SearchResultModel>( queryParametersList, searchType, enableAggregate, graphRequestContext); searchResult.Add(result); } return(searchResult.Select(x => x as T).ToList()); }
public bool CanHandle <T>(IGraphRequestContext graphRequestContext) { return(GetInfo <T>(graphRequestContext) != null); }
public QueryExecutionContext(IGraphRequestContext graphRequestContext) { RequestContext = graphRequestContext; }
private SearchClientProviderInfo GetInfo <T>(IGraphRequestContext graphRequestContext) { var indexName = typeof(T).Name; return(InternalGetInfo(indexName, graphRequestContext)); }
public async Task CreateAsync <T>(T item, IGraphRequestContext graphRequestContext) where T : class { await BatchCreateAsync(new List <T> { item }, graphRequestContext); }
public Task BatchCreateOrUpdateAsync <T>(IEnumerable <T> items, IGraphRequestContext graphRequestContext) where T : class { throw new NotImplementedException(); }
public async Task <IEnumerable <T> > QueryAsync <T>(string queryName, IEnumerable <QueryParameter> queryParameters, Dictionary <string, object> stepBagItems, IGraphRequestContext graphRequestContext) where T : class { return(await GetProvider <T>(graphRequestContext).QueryAsync <T>(queryParameters, graphRequestContext)); }
private async Task <List <object> > QueryAsync(string queryName, QueryStep queryStep, IGraphRequestContext graphRequestContext, QueryExecutionContext queryExecutionContext, List <ConnectionEdgeDestinationFilter> connectionEdgeDestinationFilters) { var results = (await _graphQlRepositoryProvider.QueryAsync(queryName, queryStep, graphRequestContext)).ToList(); if (!queryStep.SkipConnectionEdgeCheck && results.Count > 0) { await _connectionEdgeHandler.QueryAsync(results, queryStep, graphRequestContext, queryExecutionContext, connectionEdgeDestinationFilters); } return(results); }
public async Task DeleteAllAsync <T>(IGraphRequestContext graphRequestContext) where T : class { await GetProvider <T>(graphRequestContext).DeleteAllAsync <T>(graphRequestContext); }
public bool CanHandle <T>(IGraphRequestContext graphRequestContext) { return(InternalGet <T>(graphRequestContext) != null); }
private TableStorageClientProvider GetProvider <T>(IGraphRequestContext graphRequestContext) { return(_providers.Single(x => x.CanHandle <T>(graphRequestContext))); }
public async Task BatchAddAsync <T>(IEnumerable <T> items, IGraphRequestContext graphRequestContext) where T : class { await InternalBatchAsync(items, graphRequestContext, true); }
public async Task AddOrUpdateAsync <T>(T item, IGraphRequestContext graphRequestContext) where T : class { await GetProvider <T>(graphRequestContext).AddOrUpdateAsync(item, graphRequestContext); }
public Task AddOrUpdateAsync <T>(T item, IGraphRequestContext graphRequestContext) where T : class { throw new NotImplementedException(); }
public async Task <IEnumerable <T> > QueryAsync <T>(IEnumerable <QueryParameter> queryParameters, IGraphRequestContext graphRequestContext) { var collection = new SqlParameterCollection(); var queryParametersList = queryParameters.ToList(); string sql; if (queryParametersList.Count == 1 && (queryParametersList.Single().ContextValue == null || queryParametersList.Single().ContextValue.Values == null)) { sql = $"SELECT {All} FROM x"; } else { sql = $"SELECT {All} FROM x WHERE "; const string and = " AND "; queryParametersList.ForEach(x => { var documentDbSqlParameter = TranslateQueryParameter(x); documentDbSqlParameter.SqlParameters.ToList().ForEach(collection.Add); sql += documentDbSqlParameter.Comparison + and; }); if (sql.EndsWith(and)) { sql = sql.Substring(0, sql.LastIndexOf("AND ", StringComparison.Ordinal)); } } var sqlQuery = new SqlQuerySpec(sql, collection); var options = new FeedOptions { EnableCrossPartitionQuery = true, // See: https://docs.microsoft.com/en-us/azure/cosmos-db/index-policy EnableScanInQuery = queryParametersList.Any( x => x.ContextValue != null && ( x.ContextValue.Comparison == Comparisons.StringContains || x.ContextValue.Comparison == Comparisons.StringEndsWith || x.ContextValue.Comparison == Comparisons.StringStartsWith || x.ContextValue.Comparison == Comparisons.GreaterEqualThan || x.ContextValue.Comparison == Comparisons.GreaterThan || x.ContextValue.Comparison == Comparisons.LessThan || x.ContextValue.Comparison == Comparisons.LessEqualThan)) }; _logger.LogInformation($"Generated SQL query in DocumentDb provider: {sql}"); var query = _documentClient.CreateDocumentQuery <T>( GetDocumentCollectionUri <T>(graphRequestContext), sqlQuery, options).AsDocumentQuery(); var results = await query.ExecuteNextAsync <T>(); return(results.ToList()); }