private async Task TransformObject(object item, IGraphRequestContext context, MutationActions mutationAction)
 {
     await TransformObjects(new List <object> {
         item
     }, context, mutationAction);
 }
Esempio n. 2
0
        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));
        }
Esempio n. 13
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 15
0
 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);
 }
Esempio n. 18
0
 public QueryExecutionContext(IGraphRequestContext graphRequestContext)
 {
     RequestContext = graphRequestContext;
 }
        private SearchClientProviderInfo GetInfo <T>(IGraphRequestContext graphRequestContext)
        {
            var indexName = typeof(T).Name;

            return(InternalGetInfo(indexName, graphRequestContext));
        }
Esempio n. 20
0
 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();
 }
Esempio n. 22
0
 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);
        }
Esempio n. 24
0
 public async Task DeleteAllAsync <T>(IGraphRequestContext graphRequestContext) where T : class
 {
     await GetProvider <T>(graphRequestContext).DeleteAllAsync <T>(graphRequestContext);
 }
Esempio n. 25
0
 public bool CanHandle <T>(IGraphRequestContext graphRequestContext)
 {
     return(InternalGet <T>(graphRequestContext) != null);
 }
Esempio n. 26
0
 private TableStorageClientProvider GetProvider <T>(IGraphRequestContext graphRequestContext)
 {
     return(_providers.Single(x => x.CanHandle <T>(graphRequestContext)));
 }
Esempio n. 27
0
 public async Task BatchAddAsync <T>(IEnumerable <T> items, IGraphRequestContext graphRequestContext) where T : class
 {
     await InternalBatchAsync(items, graphRequestContext, true);
 }
Esempio n. 28
0
 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());
        }