private async Task <IEnumerable <IDictionary <string, object> >?> IterateEntriesAsync(
        ResolvedCommand command, bool resultRequired,
        Func <string, IDictionary <string, object>, IDictionary <string, object>, bool, Task <IDictionary <string, object> > > funcAsync, CancellationToken cancellationToken)
    {
        var collectionName = command.QualifiedEntityCollectionName;
        var entryData      = command.CommandData;

        IEnumerable <IDictionary <string, object> >?result = null;
        var client  = new ODataClient(this);
        var entries = await client.FindEntriesAsync(command.Format(), cancellationToken).ConfigureAwait(false);

        if (entries != null)
        {
            var entryList  = entries.ToList();
            var resultList = new List <IDictionary <string, object> >();
            foreach (var entry in entryList)
            {
                resultList.Add(await funcAsync(collectionName, entry, entryData, resultRequired).ConfigureAwait(false));
                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }

            result = resultList;
        }

        return(result);
    }
        /// <summary>
        /// Activates the resolved command
        /// </summary>
        /// <param name="resCmd">The resolved command</param>
        /// <returns>An activation result</returns>
        public ActivationResult Activate(ResolvedCommand resCmd)
        {
            // check for errors

            if (!resCmd.IsValid)
            {
                throw new CommandActivationException(resCmd, "Cannot activate command with resolution errors");
            }

            // create command instance

            var cmd = _container.CreateScope().Get(resCmd.CommandInfo.Type);

            // inject property values

            foreach (var info in resCmd.CommandInfo.Arguments)
            {
                if (info.PropertyInfo.PropertyType == typeof(Option))
                {
                    info.PropertyInfo.SetValue(cmd, new Option(resCmd.InputMap.ContainsKey(info)));
                }
                else if (resCmd.InputMap.ContainsKey(info))
                {
                    info.PropertyInfo.SetValue(cmd, StringParsing.Parse(info.DataType, resCmd.InputMap[info].IsPairedWith?.Value));
                }
            }

            // return result

            return(new ActivationResult(cmd, resCmd));
        }
Пример #3
0
 private void AssertHasKey(ResolvedCommand command)
 {
     if (!command.Details.HasKey && command.FilterAsKey == null)
     {
         throw new InvalidOperationException("No entry key specified.");
     }
 }
Пример #4
0
 internal ActivationResult(
     CommandBase command,
     ResolvedCommand resolvedCommand)
 {
     Command         = command;
     ResolvedCommand = resolvedCommand;
 }
    private async Task <int> IterateEntriesAsync(ResolvedCommand command,
                                                 Func <string, IDictionary <string, object>, Task> funcAsync, CancellationToken cancellationToken)
    {
        var collectionName = command.QualifiedEntityCollectionName;

        var result  = 0;
        var client  = new ODataClient(this);
        var entries = await client.FindEntriesAsync(command.Format(), cancellationToken).ConfigureAwait(false);

        if (entries != null)
        {
            var entryList = entries.ToList();
            foreach (var entry in entryList)
            {
                await funcAsync(collectionName, entry).ConfigureAwait(false);

                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }

                ++result;
            }
        }

        return(result);
    }
Пример #6
0
    private string FormatEntryKey(ResolvedCommand command)
    {
        var entryIdent = command.Details.HasKey
                        ? command.Format()
                        : new FluentCommand(command).Key(command.FilterAsKey).Resolve(_session).Format();

        return(entryIdent);
    }
Пример #7
0
 public RequestBuilder(
     ResolvedCommand command,
     Session session,
     Lazy <IBatchWriter> batchWriter)
 {
     _command         = command;
     _session         = session;
     _lazyBatchWriter = batchWriter;
 }
    private async Task <IDictionary <string, object> > GetUpdatedResult(ResolvedCommand command, CancellationToken cancellationToken)
    {
        var entryKey  = command.Details.HasKey ? command.KeyValues : command.FilterAsKey;
        var entryData = command.CommandData;

        var updatedKey = entryKey.Where(x => !entryData.ContainsKey(x.Key)).ToIDictionary();

        foreach (var item in entryData.Where(x => entryKey.ContainsKey(x.Key)))
        {
            updatedKey.Add(item);
        }

        var updatedCommand = new FluentCommand(command).Key(updatedKey);

        return(await FindEntryAsync(updatedCommand.Resolve(Session).Format(), cancellationToken).ConfigureAwait(false));
    }
Пример #9
0
        internal string Build(ResolvedCommand command, ISession session)
        {
            var context     = new ExpressionContext(session, null, null, command.DynamicPropertiesContainerName);
            var commandText = string.Empty;

            foreach (var applyClause in DataAggregationClauses)
            {
                var formattedApplyClause = applyClause.Format(context);
                if (string.IsNullOrEmpty(formattedApplyClause))
                {
                    continue;
                }
                if (commandText.Length > 0)
                {
                    commandText += "/";
                }
                commandText += formattedApplyClause;
            }

            return(AddNextCommand(commandText, command, session));
        }
Пример #10
0
        private string AddNextCommand(string commandText, ResolvedCommand command, ISession session)
        {
            if (_nextDataAggregationBuilder == null)
            {
                return(commandText);
            }

            var nestedCommand = _nextDataAggregationBuilder.Build(command, session);

            if (string.IsNullOrEmpty(nestedCommand))
            {
                return(commandText);
            }

            if (commandText.Length > 0)
            {
                commandText += "/";
            }
            commandText += nestedCommand;

            return(commandText);
        }
        protected override void FormatExtensions(IList <string> commandClauses, ResolvedCommand command)
        {
            if (command.Details.Extensions.TryGetValue(ODataLiteral.Apply, out var applyCommandObject))
            {
                var formattedApplyCommand = string.Empty;
                switch (applyCommandObject)
                {
                case DataAggregationBuilder applyCommandBuilder:
                    formattedApplyCommand = applyCommandBuilder.Build(command, _session);
                    break;

                case string applyCommand:
                    formattedApplyCommand = applyCommand;
                    break;
                }

                if (!string.IsNullOrEmpty(formattedApplyCommand))
                {
                    commandClauses.Add($"{ODataLiteral.Apply}={EscapeUnescapedString(formattedApplyCommand)}");
                }
            }
        }
    private async Task EnrichWithMediaPropertiesAsync(IEnumerable <AnnotatedEntry> entries, ResolvedCommand command, CancellationToken cancellationToken)
    {
        if (entries != null)
        {
            foreach (var entry in entries)
            {
                await EnrichWithMediaPropertiesAsync(entry, command.Details.MediaProperties, cancellationToken).ConfigureAwait(false);

                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }
    }
        private string FormatExpansionSegment(ODataExpandAssociation association, EntityCollection entityCollection,
                                              ODataExpandOptions expandOptions, ResolvedCommand command, bool rootLevel = true)
        {
            if (rootLevel)
            {
                association = command.Details.SelectColumns.Aggregate(association, MergeExpandAssociations);
                association = command.Details.OrderbyColumns.Aggregate(association, MergeOrderByColumns);
            }

            var associationName     = association.Name;
            var expandsToCollection = false;

            if (_session.Metadata.HasNavigationProperty(entityCollection.Name, associationName))
            {
                associationName     = _session.Metadata.GetNavigationPropertyExactName(entityCollection.Name, associationName);
                expandsToCollection = _session.Metadata.IsNavigationPropertyCollection(entityCollection.Name, associationName);
            }

            var clauses = new List <string>();
            var text    = associationName;

            if (expandOptions.ExpandMode == ODataExpandMode.ByReference)
            {
                text += "/" + ODataLiteral.Ref;
            }

            if (expandOptions.Levels > 1)
            {
                clauses.Add($"{ODataLiteral.Levels}={expandOptions.Levels}");
            }
            else if (expandOptions.Levels == 0)
            {
                clauses.Add($"{ODataLiteral.Levels}={ODataLiteral.Max}");
            }

            if (associationName != StarString)
            {
                if (expandsToCollection && !ReferenceEquals(association.FilterExpression, null))
                {
                    var associatedEntityCollection = _session.Metadata.GetEntityCollection(
                        _session.Metadata.GetNavigationPropertyPartnerTypeName(entityCollection.Name, associationName));
                    clauses.Add(
                        $"{ODataLiteral.Filter}={EscapeUnescapedString(association.FilterExpression.Format(new ExpressionContext(_session, associatedEntityCollection, null, command.DynamicPropertiesContainerName)))}");
                }

                if (association.ExpandAssociations.Any())
                {
                    var associatedEntityCollection = _session.Metadata.GetEntityCollection(
                        _session.Metadata.GetNavigationPropertyPartnerTypeName(entityCollection.Name, associationName));
                    var expandAll = association.ExpandAssociations.FirstOrDefault(a => a.Name == StarString);
                    if (expandAll != null)
                    {
                        clauses.Add($"{ODataLiteral.Expand}=*");
                    }
                    else
                    {
                        var expandedProperties = string.Join(",", association.ExpandAssociations
                                                             .Where(
                                                                 a => _session.Metadata.HasNavigationProperty(associatedEntityCollection.Name, a.Name))
                                                             .Select(a =>
                                                                     FormatExpansionSegment(a, associatedEntityCollection, ODataExpandOptions.ByValue(),
                                                                                            command,
                                                                                            false)));
                        if (!string.IsNullOrEmpty(expandedProperties))
                        {
                            clauses.Add($"{ODataLiteral.Expand}={expandedProperties}");
                        }
                    }

                    var selectColumns = string.Join(",", association.ExpandAssociations
                                                    .Where(a => a.Name != StarString &&
                                                           !_session.Metadata.HasNavigationProperty(associatedEntityCollection.Name, a.Name))
                                                    .Select(a => a.Name));
                    if (!string.IsNullOrEmpty(selectColumns))
                    {
                        clauses.Add($"{ODataLiteral.Select}={selectColumns}");
                    }
                }

                if (expandsToCollection && association.OrderByColumns.Any())
                {
                    var columns = string.Join(",", association.OrderByColumns
                                              .Select(o => o.Name + (o.Descending ? " desc" : string.Empty)));
                    if (!string.IsNullOrEmpty(columns))
                    {
                        clauses.Add($"{ODataLiteral.OrderBy}={columns}");
                    }
                }
            }

            if (clauses.Any())
            {
                text += $"({string.Join(";", clauses)})";
            }

            return(text);
        }
        protected override void FormatExpandSelectOrderby(IList <string> commandClauses, EntityCollection resultCollection, ResolvedCommand command)
        {
            if (command.Details.ExpandAssociations.Any())
            {
                var groupedExpandAssociations = command.Details.ExpandAssociations
                                                .GroupBy(x => (x.Key, x.Value), x => x.Key);
                var mergedExpandAssociations = groupedExpandAssociations
                                               .Select(x =>
                {
                    var mainAssociation = x.Key.Key;
                    foreach (var association in x.Where(a => a != mainAssociation))
                    {
                        mainAssociation = MergeExpandAssociations(mainAssociation, association).First();
                    }
                    return(new KeyValuePair <ODataExpandAssociation, ODataExpandOptions>(mainAssociation, x.Key.Value));
                });

                var formattedExpand = string.Join(",", mergedExpandAssociations.Select(x =>
                                                                                       FormatExpansionSegment(x.Key, resultCollection, x.Value, command)));
                commandClauses.Add($"{ODataLiteral.Expand}={formattedExpand}");
            }

            FormatClause(commandClauses, resultCollection,
                         SelectPathSegmentColumns(command.Details.SelectColumns, resultCollection,
                                                  command.Details.ExpandAssociations.Select(x => FormatFirstSegment(x.Key.Name)).ToList()),
                         ODataLiteral.Select, FormatSelectItem);

            FormatClause(commandClauses, resultCollection,
                         command.Details.OrderbyColumns
                         .Where(o => !command.Details.ExpandAssociations.Select(ea => ea.Key)
                                .Any(ea => IsInnerCollectionOrderBy(ea.Name, resultCollection, o.Key))).ToList(),
                         ODataLiteral.OrderBy, FormatOrderByItem);
        }
    protected override void FormatExpandSelectOrderby(IList <string> commandClauses, EntityCollection resultCollection, ResolvedCommand command)
    {
        var expandAssociations = FlatExpandAssociations(command.Details.ExpandAssociations).ToList();

        FormatClause(commandClauses, resultCollection, expandAssociations, ODataLiteral.Expand, FormatExpandItem);
        FormatClause(commandClauses, resultCollection, command.Details.SelectColumns, ODataLiteral.Select, FormatSelectItem);
        FormatClause(commandClauses, resultCollection, command.Details.OrderbyColumns, ODataLiteral.OrderBy, FormatOrderByItem);
    }
 protected override void FormatExtensions(IList <string> commandClauses, ResolvedCommand command)
 {
 }
Пример #17
0
    private string FormatClauses(ResolvedCommand command, IList <string>?queryClauses = null)
    {
        var text = string.Empty;

        queryClauses ??= new List <string>();
        var aggregateClauses = new List <string>();

        if (command.CommandData.Any() && !string.IsNullOrEmpty(command.Details.FunctionName) &&
            FunctionFormat == FunctionFormat.Query)
        {
            queryClauses.Add(string.Join("&", command.CommandData.Select(x => $"{x.Key}={ConvertValueToUriLiteral(x.Value, true)}")));
        }

        if (command.Details.Filter != null)
        {
            queryClauses.Add($"{ODataLiteral.Filter}={EscapeUnescapedString(command.Details.Filter)}");
        }

        if (command.Details.Search != null)
        {
            queryClauses.Add($"{ODataLiteral.Search}={EscapeUnescapedString(command.Details.Search)}");
        }

        if (command.Details.QueryOptions != null)
        {
            queryClauses.Add(command.Details.QueryOptions);
        }

        var details = command.Details;

        if (details.QueryOptionsExpression is not null)
        {
            queryClauses.Add(details.QueryOptionsExpression.Format(new ExpressionContext(_session, true)));
        }

        if (command.Details.QueryOptionsKeyValues != null)
        {
            foreach (var kv in command.Details.QueryOptionsKeyValues)
            {
                queryClauses.Add($"{kv.Key}={ODataExpression.FromValue(kv.Value).Format(new ExpressionContext(_session))}");
            }
        }

        if (command.Details.SkipCount >= 0)
        {
            queryClauses.Add($"{ODataLiteral.Skip}={command.Details.SkipCount}");
        }

        if (command.Details.TopCount >= 0)
        {
            queryClauses.Add($"{ODataLiteral.Top}={command.Details.TopCount}");
        }

        if (command.Details.Extensions.Any())
        {
            FormatExtensions(queryClauses, command);
        }

        EntityCollection resultCollection;

        if (command.Details.HasFunction)
        {
            resultCollection = _session.Adapter.GetMetadata().GetFunctionReturnCollection(command.Details.FunctionName);
        }
        else
        {
            resultCollection = command.Details.HasAction
                                ? _session.Adapter.GetMetadata().GetActionReturnCollection(command.Details.ActionName)
                                : command.EntityCollection;
        }

        if (resultCollection != null)
        {
            FormatExpandSelectOrderby(queryClauses, resultCollection, command);
        }

        if (command.Details.IncludeCount)
        {
            FormatInlineCount(queryClauses);
        }

        if (command.Details.ComputeCount)
        {
            aggregateClauses.Add(ODataLiteral.Count);
        }

        if (aggregateClauses.Any())
        {
            text += "/" + string.Join("/", aggregateClauses);
        }

        if (queryClauses.Any())
        {
            text += "?" + string.Join("&", queryClauses);
        }

        return(text);
    }
Пример #18
0
    public string FormatCommand(ResolvedCommand command)
    {
        if (command.Details.HasFunction && command.Details.HasAction)
        {
            throw new InvalidOperationException("OData function and action may not be combined.");
        }

        var commandText = string.Empty;

        if (!string.IsNullOrEmpty(command.Details.CollectionName))
        {
            commandText += _session.Metadata.GetEntityCollectionExactName(command.Details.CollectionName);
        }
        else if (!string.IsNullOrEmpty(command.Details.LinkName))
        {
            var parent = new FluentCommand(command.Details.Parent).Resolve(_session);
            commandText += $"{FormatCommand(parent)}/{_session.Metadata.GetNavigationPropertyExactName(parent.EntityCollection.Name, command.Details.LinkName)}";
        }

        if (command.Details.HasKey)
        {
            commandText += ConvertKeyValuesToUriLiteral(command.KeyValues, !command.Details.IsAlternateKey);
        }

        var collectionValues = new List <string>();

        if (!string.IsNullOrEmpty(command.Details.MediaName))
        {
            commandText += "/" + (command.Details.MediaName == FluentCommand.MediaEntityLiteral
                                ? ODataLiteral.Value
                                : command.Details.MediaName);
        }
        else
        {
            if (!string.IsNullOrEmpty(command.Details.FunctionName) || !string.IsNullOrEmpty(command.Details.ActionName))
            {
                if (!string.IsNullOrEmpty(command.Details.CollectionName) || !string.IsNullOrEmpty(command.Details.LinkName))
                {
                    commandText += "/";
                }

                if (!string.IsNullOrEmpty(command.Details.FunctionName))
                {
                    commandText += _session.Metadata.GetFunctionFullName(command.Details.FunctionName);
                }
                else
                {
                    commandText += _session.Metadata.GetActionFullName(command.Details.ActionName);
                }
            }

            if (!string.IsNullOrEmpty(command.Details.FunctionName) && FunctionFormat == FunctionFormat.Key)
            {
                commandText += ConvertKeyValuesToUriLiteralExtractCollections(command.CommandData, collectionValues, false);
            }

            if (!string.IsNullOrEmpty(command.Details.DerivedCollectionName))
            {
                commandText += "/" + _session.Metadata.GetQualifiedTypeName(command.Details.DerivedCollectionName);
            }
        }

        commandText += FormatClauses(command, collectionValues);
        return(commandText);
    }
Пример #19
0
 protected abstract void FormatExtensions(IList <string> commandClauses, ResolvedCommand command);
Пример #20
0
 protected abstract void FormatExpandSelectOrderby(IList <string> commandClauses, EntityCollection resultCollection, ResolvedCommand command);
Пример #21
0
        public CommandHandler(CommandRequest commandRequest)
        {
            ResolvedCommand resolvedCommand = this.ResolveCommandType(commandRequest.Text);

            this.Command = CommandFactory.Create(resolvedCommand.Type, resolvedCommand.Parameters, commandRequest);
        }
 public CommandActivationException(ResolvedCommand command, string message) : base(message)
 {
     Command = command;
 }
 public CommandActivationException(ResolvedCommand command, string message, Exception innerException) : base(message, innerException)
 {
     Command = command;
 }
    private async Task <IEnumerable <IDictionary <string, object> > > ExecuteFunctionAsync(ResolvedCommand command, CancellationToken cancellationToken)
    {
        var request = await Session.Adapter.GetRequestWriter(BatchWriter)
                      .CreateFunctionRequestAsync(command.Format(), command.Details.FunctionName, command.Details.Headers).ConfigureAwait(false);

        return(await ExecuteRequestWithResultAsync(request, cancellationToken,
                                                   x => x.AsEntries(Session.Settings.IncludeAnnotationsInResults),
                                                   () => Array.Empty <IDictionary <string, object> >()).ConfigureAwait(false));
    }
    private async Task <IEnumerable <IDictionary <string, object> > > ExecuteActionAsync(ResolvedCommand command, CancellationToken cancellationToken)
    {
        var entityTypeName = command.EntityCollection != null
                        ? Session.Metadata.GetQualifiedTypeName(command.EntityCollection.Name)
                        : null;

        var request = await Session.Adapter.GetRequestWriter(BatchWriter)
                      .CreateActionRequestAsync(command.Format(), command.Details.ActionName, entityTypeName, command.CommandData, true, command.Details.Headers).ConfigureAwait(false);

        return(await ExecuteRequestWithResultAsync(request, cancellationToken,
                                                   x => x.AsEntries(Session.Settings.IncludeAnnotationsInResults),
                                                   () => Array.Empty <IDictionary <string, object> >()).ConfigureAwait(false));
    }
Пример #26
0
 internal FluentCommand(ResolvedCommand command)
 {
     Details = new FluentCommandDetails(command.Details);
 }
Пример #27
0
        protected override void FormatExpandSelectOrderby(IList <string> commandClauses, EntityCollection resultCollection, ResolvedCommand command)
        {
            if (command.Details.ExpandAssociations.Any())
            {
                var formattedExpand = string.Join(",", command.Details.ExpandAssociations.Select(x =>
                                                                                                 FormatExpansionSegment(x.Key, resultCollection,
                                                                                                                        x.Value,
                                                                                                                        SelectPathSegmentColumns(command.Details.SelectColumns, x.Key, resultCollection),
                                                                                                                        SelectPathSegmentColumns(command.Details.OrderbyColumns, x.Key, resultCollection))));
                commandClauses.Add($"{ODataLiteral.Expand}={formattedExpand}");
            }

            FormatClause(commandClauses, resultCollection,
                         SelectPathSegmentColumns(command.Details.SelectColumns, null, resultCollection,
                                                  command.Details.ExpandAssociations.Select(FormatFirstSegment).ToList()),
                         ODataLiteral.Select, FormatSelectItem);

            FormatClause(commandClauses, resultCollection,
                         command.Details.OrderbyColumns
                         .Where(o => !command.Details.ExpandAssociations.Select(ea => ea.Key)
                                .Any(ea => IsInnerCollectionOrderBy(ea, resultCollection, o.Key))).ToList(),
                         ODataLiteral.OrderBy, FormatOrderByItem);
        }