Пример #1
0
        private void GetTimeSeriesQueryString(DocumentDatabase database, DocumentsOperationContext context, out IncludeTimeSeriesCommand includeTimeSeries)
        {
            includeTimeSeries = null;

            var timeSeriesNames = GetStringValuesQueryString("timeseries", required: false);

            if (timeSeriesNames.Count == 0)
            {
                return;
            }

            var fromList = GetStringValuesQueryString("from", required: false);
            var toList   = GetStringValuesQueryString("to", required: false);

            if (timeSeriesNames.Count != fromList.Count || fromList.Count != toList.Count)
            {
                throw new InvalidOperationException("Parameters 'timeseriesNames', 'fromList' and 'toList' must be of equal length. " +
                                                    $"Got : timeseriesNames.Count = {timeSeriesNames.Count}, fromList.Count = {fromList.Count}, toList.Count = {toList.Count}.");
            }

            var hs = new HashSet <TimeSeriesRange>(TimeSeriesRangeComparer.Instance);

            for (int i = 0; i < timeSeriesNames.Count; i++)
            {
                hs.Add(new TimeSeriesRange
                {
                    Name = timeSeriesNames[i],
                    From = string.IsNullOrEmpty(fromList[i])
                        ? DateTime.MinValue
                        : TimeSeriesHandler.ParseDate(fromList[i], "from"),
                    To = string.IsNullOrEmpty(toList[i])
                        ? DateTime.MaxValue
                        : TimeSeriesHandler.ParseDate(toList[i], "to")
                });
            }

            includeTimeSeries = new IncludeTimeSeriesCommand(context,
                                                             new Dictionary <string, HashSet <TimeSeriesRange> > {
                { string.Empty, hs }
            });
        }
Пример #2
0
 public override void AddTimeSeriesIncludes(IncludeTimeSeriesCommand includeTimeSeriesCommand)
 {
     throw new NotSupportedException();
 }
Пример #3
0
        private void GetTimeSeriesQueryString(DocumentDatabase database, DocumentsOperationContext context, out IncludeTimeSeriesCommand includeTimeSeries)
        {
            includeTimeSeries = null;

            var timeSeriesNames      = GetStringValuesQueryString("timeseries", required: false);
            var timeSeriesTimeNames  = GetStringValuesQueryString("timeseriestime", required: false);
            var timeSeriesCountNames = GetStringValuesQueryString("timeseriescount", required: false);

            if (timeSeriesNames.Count == 0 && timeSeriesTimeNames.Count == 0 && timeSeriesCountNames.Count == 0)
            {
                return;
            }

            if (timeSeriesNames.Count > 1 && timeSeriesNames.Contains(Constants.TimeSeries.All))
            {
                throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'.");
            }
            if (timeSeriesTimeNames.Count > 1 && timeSeriesTimeNames.Contains(Constants.TimeSeries.All))
            {
                throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'.");
            }
            if (timeSeriesCountNames.Count > 1 && timeSeriesCountNames.Contains(Constants.TimeSeries.All))
            {
                throw new InvalidOperationException($"Cannot have more than one include on '{Constants.TimeSeries.All}'.");
            }

            var fromList = GetStringValuesQueryString("from", required: false);
            var toList   = GetStringValuesQueryString("to", required: false);

            if (timeSeriesNames.Count != fromList.Count || fromList.Count != toList.Count)
            {
                throw new InvalidOperationException("Parameters 'timeseriesNames', 'fromList' and 'toList' must be of equal length. " +
                                                    $"Got : timeseriesNames.Count = {timeSeriesNames.Count}, fromList.Count = {fromList.Count}, toList.Count = {toList.Count}.");
            }

            var timeTypeList  = GetStringValuesQueryString("timeType", required: false);
            var timeValueList = GetStringValuesQueryString("timeValue", required: false);
            var timeUnitList  = GetStringValuesQueryString("timeUnit", required: false);

            if (timeSeriesTimeNames.Count != timeTypeList.Count || timeTypeList.Count != timeValueList.Count || timeValueList.Count != timeUnitList.Count)
            {
                throw new InvalidOperationException($"Parameters '{nameof(timeSeriesTimeNames)}', '{nameof(timeTypeList)}', '{nameof(timeValueList)}' and '{nameof(timeUnitList)}' must be of equal length. " +
                                                    $"Got : {nameof(timeSeriesTimeNames)}.Count = {timeSeriesTimeNames.Count}, {nameof(timeTypeList)}.Count = {timeTypeList.Count}, {nameof(timeValueList)}.Count = {timeValueList.Count}, {nameof(timeUnitList)}.Count = {timeUnitList.Count}.");
            }

            var countTypeList  = GetStringValuesQueryString("countType", required: false);
            var countValueList = GetStringValuesQueryString("countValue", required: false);

            if (timeSeriesCountNames.Count != countTypeList.Count || countTypeList.Count != countValueList.Count)
            {
                throw new InvalidOperationException($"Parameters '{nameof(timeSeriesCountNames)}', '{nameof(countTypeList)}', '{nameof(countValueList)}' must be of equal length. " +
                                                    $"Got : {nameof(timeSeriesCountNames)}.Count = {timeSeriesCountNames.Count}, {nameof(countTypeList)}.Count = {countTypeList.Count}, {nameof(countValueList)}.Count = {countValueList.Count}.");
            }

            var hs = new HashSet <AbstractTimeSeriesRange>(AbstractTimeSeriesRangeComparer.Instance);

            for (int i = 0; i < timeSeriesNames.Count; i++)
            {
                hs.Add(new TimeSeriesRange
                {
                    Name = timeSeriesNames[i],
                    From = string.IsNullOrEmpty(fromList[i])
                        ? DateTime.MinValue
                        : TimeSeriesHandler.ParseDate(fromList[i], "from"),
                    To = string.IsNullOrEmpty(toList[i])
                        ? DateTime.MaxValue
                        : TimeSeriesHandler.ParseDate(toList[i], "to")
                });
            }

            for (int i = 0; i < timeSeriesTimeNames.Count; i++)
            {
                var timeValueUnit = (TimeValueUnit)Enum.Parse(typeof(TimeValueUnit), timeUnitList[i]);
                if (timeValueUnit == TimeValueUnit.None)
                {
                    throw new InvalidOperationException($"Got unexpected {nameof(TimeValueUnit)} '{nameof(TimeValueUnit.None)}'. Only the following are supported: '{nameof(TimeValueUnit.Second)}' or '{nameof(TimeValueUnit.Month)}'.");
                }

                if (int.TryParse(timeValueList[i], out int res) == false)
                {
                    throw new InvalidOperationException($"Could not parse timeseries time range value.");
                }

                hs.Add(new TimeSeriesTimeRange
                {
                    Name = timeSeriesTimeNames[i],
                    Type = (TimeSeriesRangeType)Enum.Parse(typeof(TimeSeriesRangeType), timeTypeList[i]),
                    Time = timeValueUnit == TimeValueUnit.Second ? TimeValue.FromSeconds(res) : TimeValue.FromMonths(res)
                });
            }

            for (int i = 0; i < timeSeriesCountNames.Count; i++)
            {
                if (int.TryParse(countValueList[i], out int res) == false)
                {
                    throw new InvalidOperationException($"Could not parse timeseries count value.");
                }

                hs.Add(new TimeSeriesCountRange
                {
                    Name  = timeSeriesCountNames[i],
                    Type  = (TimeSeriesRangeType)Enum.Parse(typeof(TimeSeriesRangeType), countTypeList[i]),
                    Count = res
                });
            }

            includeTimeSeries = new IncludeTimeSeriesCommand(context, new Dictionary <string, HashSet <AbstractTimeSeriesRange> > {
                { string.Empty, hs }
            });
        }
Пример #4
0
 public override void AddTimeSeriesIncludes(IncludeTimeSeriesCommand includeTimeSeriesCommand)
 {
     _timeSeriesIncludes = includeTimeSeriesCommand.Results;
 }
Пример #5
0
 public abstract void AddTimeSeriesIncludes(IncludeTimeSeriesCommand command);
Пример #6
0
        private void ExecuteCollectionQuery(QueryResultServerSide <Document> resultToFill, IndexQueryServerSide query, string collection, QueryOperationContext context, bool pulseReadingTransaction, CancellationToken cancellationToken)
        {
            using (var queryScope = query.Timings?.For(nameof(QueryTimingsScope.Names.Query)))
            {
                QueryTimingsScope gatherScope = null;
                QueryTimingsScope fillScope   = null;

                if (queryScope != null && query.Metadata.Includes?.Length > 0)
                {
                    var includesScope = queryScope.For(nameof(QueryTimingsScope.Names.Includes), start: false);
                    gatherScope = includesScope.For(nameof(QueryTimingsScope.Names.Gather), start: false);
                    fillScope   = includesScope.For(nameof(QueryTimingsScope.Names.Fill), start: false);
                }

                // we optimize for empty queries without sorting options, appending CollectionIndexPrefix to be able to distinguish index for collection vs. physical index
                resultToFill.IsStale        = false;
                resultToFill.LastQueryTime  = DateTime.MinValue;
                resultToFill.IndexTimestamp = DateTime.MinValue;
                resultToFill.IncludedPaths  = query.Metadata.Includes;

                var fieldsToFetch                       = new FieldsToFetch(query, null);
                var includeDocumentsCommand             = new IncludeDocumentsCommand(Database.DocumentsStorage, context.Documents, query.Metadata.Includes, fieldsToFetch.IsProjection);
                var includeCompareExchangeValuesCommand = IncludeCompareExchangeValuesCommand.ExternalScope(context, query.Metadata.CompareExchangeValueIncludes);

                var totalResults = new Reference <int>();

                IEnumerator <Document> enumerator;

                if (pulseReadingTransaction == false)
                {
                    var documents = new CollectionQueryEnumerable(Database, Database.DocumentsStorage, fieldsToFetch, collection, query, queryScope, context.Documents, includeDocumentsCommand, includeCompareExchangeValuesCommand, totalResults);

                    enumerator = documents.GetEnumerator();
                }
                else
                {
                    enumerator = new PulsedTransactionEnumerator <Document, CollectionQueryResultsIterationState>(context.Documents,
                                                                                                                  state =>
                    {
                        query.Start    = state.Start;
                        query.PageSize = state.Take;

                        var documents = new CollectionQueryEnumerable(Database, Database.DocumentsStorage, fieldsToFetch, collection, query, queryScope, context.Documents, includeDocumentsCommand, includeCompareExchangeValuesCommand, totalResults);

                        return(documents);
                    },
                                                                                                                  new CollectionQueryResultsIterationState(context.Documents, Database.Configuration.Databases.PulseReadTransactionLimit)
                    {
                        Start = query.Start,
                        Take  = query.PageSize
                    });
                }

                IncludeCountersCommand   includeCountersCommand   = null;
                IncludeTimeSeriesCommand includeTimeSeriesCommand = null;

                if (query.Metadata.CounterIncludes != null)
                {
                    includeCountersCommand = new IncludeCountersCommand(
                        Database,
                        context.Documents,
                        query.Metadata.CounterIncludes.Counters);
                }

                if (query.Metadata.TimeSeriesIncludes != null)
                {
                    includeTimeSeriesCommand = new IncludeTimeSeriesCommand(
                        context.Documents,
                        query.Metadata.TimeSeriesIncludes.TimeSeries);
                }

                try
                {
                    using (enumerator)
                    {
                        while (enumerator.MoveNext())
                        {
                            var document = enumerator.Current;

                            cancellationToken.ThrowIfCancellationRequested();

                            resultToFill.AddResult(document);

                            using (gatherScope?.Start())
                            {
                                includeDocumentsCommand.Gather(document);
                                includeCompareExchangeValuesCommand?.Gather(document);
                            }

                            includeCountersCommand?.Fill(document);

                            includeTimeSeriesCommand?.Fill(document);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (resultToFill.SupportsExceptionHandling == false)
                    {
                        throw;
                    }

                    resultToFill.HandleException(e);
                }

                using (fillScope?.Start())
                {
                    includeDocumentsCommand.Fill(resultToFill.Includes);

                    includeCompareExchangeValuesCommand.Materialize();
                }

                if (includeCompareExchangeValuesCommand != null)
                {
                    resultToFill.AddCompareExchangeValueIncludes(includeCompareExchangeValuesCommand);
                }

                if (includeCountersCommand != null)
                {
                    resultToFill.AddCounterIncludes(includeCountersCommand);
                }

                if (includeTimeSeriesCommand != null)
                {
                    resultToFill.AddTimeSeriesIncludes(includeTimeSeriesCommand);
                }

                resultToFill.RegisterTimeSeriesFields(query, fieldsToFetch);

                resultToFill.TotalResults = (totalResults.Value == 0 && resultToFill.Results.Count != 0) ? -1 : totalResults.Value;

                if (query.Offset != null || query.Limit != null)
                {
                    if (resultToFill.TotalResults == -1)
                    {
                        resultToFill.CappedMaxResults = query.Limit ?? -1;
                    }
                    else
                    {
                        resultToFill.CappedMaxResults = Math.Min(
                            query.Limit ?? int.MaxValue,
                            resultToFill.TotalResults - (query.Offset ?? 0)
                            );
                    }
                }
            }
        }