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)); }
private void AssertHasKey(ResolvedCommand command) { if (!command.Details.HasKey && command.FilterAsKey == null) { throw new InvalidOperationException("No entry key specified."); } }
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); }
private string FormatEntryKey(ResolvedCommand command) { var entryIdent = command.Details.HasKey ? command.Format() : new FluentCommand(command).Key(command.FilterAsKey).Resolve(_session).Format(); return(entryIdent); }
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)); }
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)); }
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) { }
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); }
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); }
protected abstract void FormatExtensions(IList <string> commandClauses, ResolvedCommand command);
protected abstract void FormatExpandSelectOrderby(IList <string> commandClauses, EntityCollection resultCollection, ResolvedCommand command);
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)); }
internal FluentCommand(ResolvedCommand command) { Details = new FluentCommandDetails(command.Details); }
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); }