Ejemplo n.º 1
0
        public override async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            var body = await _deserializer.DeserializeAsync <QueryResultData>(ResponseStream, cancellationToken);

            MetaData = new QueryMetaData
            {
                RequestId       = body.requestID.ToString(),
                ClientContextId = body.clientContextID,
                Signature       = body.signature,
                Profile         = body.profile,
                Metrics         = body.metrics?.ToMetrics()
            };

            if (Enum.TryParse(body.status, true, out QueryStatus status))
            {
                MetaData.Status = status;
                Success         = status == QueryStatus.Success;
            }

            PreparedPlanName = body.prepared;

            if (body.warnings != null)
            {
                MetaData.Warnings.AddRange(body.warnings.Select(p => p.ToWarning()));
            }
            if (body.errors != null)
            {
                Errors.AddRange(body.errors.Select(p => p.ToError()));
            }

            _rows = body.results ?? Enumerable.Empty <T>();
        }
        internal async Task ReadResponseAttributes(CancellationToken cancellationToken)
        {
            if (_reader == null)
            {
                // Should not be possible
                throw new InvalidOperationException("_reader is null");
            }

            if (MetaData == null)
            {
                MetaData = new QueryMetaData();
            }

            _hasReadToResult = false;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var path = await _reader !.ReadToNextAttributeAsync(cancellationToken).ConfigureAwait(false);
                if (path == null)
                {
                    // Reached the end
                    break;
                }

                switch (path)
                {
                case "requestID" when _reader.ValueType == typeof(string):
                    MetaData.RequestId = _reader.Value?.ToString();
                    break;

                case "status" when _reader.ValueType == typeof(string):
                    if (Enum.TryParse(_reader.Value?.ToString(), true, out QueryStatus status))
                    {
                        MetaData.Status = status;
                        Success         = status == QueryStatus.Success;
                    }

                    break;

                case "clientContextID" when _reader.ValueType == typeof(string):
                    MetaData.ClientContextId = _reader.Value?.ToString();
                    break;

                case "signature":
                    MetaData.Signature = (await _reader.ReadTokenAsync(cancellationToken).ConfigureAwait(false))
                                         .ToDynamic();
                    break;

                case "prepared" when _reader.ValueType == typeof(string):
                    PreparedPlanName = _reader.Value?.ToString();;
                    break;

                case "profile":
                    MetaData.Profile = (await _reader.ReadTokenAsync(cancellationToken).ConfigureAwait(false))
                                       .ToDynamic();
                    break;

                case "metrics":
                    MetaData.Metrics =
                        (await _reader.ReadObjectAsync <MetricsData>(cancellationToken).ConfigureAwait(false))
                        .ToMetrics();
                    break;

                case "results":
                    // We've reached the result rows, return now
                    _hasReadToResult = true;

                    return;

                case "warnings":
                    await foreach (var warning in _reader.ReadObjectsAsync <QueryWarning>(cancellationToken)
                                   .ConfigureAwait(false))
                    {
                        MetaData.Warnings.Add(warning);
                    }

                    break;

                case "errors":
                    await foreach (var error in _reader.ReadObjectsAsync <Error>(cancellationToken)
                                   .ConfigureAwait(false))
                    {
                        Errors.Add(error);
                    }

                    break;
                }
            }

            // We've reached the end of the object, mark that entire read is complete
            _hasFinishedReading = true;
        }
        internal async Task ReadResponseAttributes(CancellationToken cancellationToken)
        {
            if (_reader == null)
            {
                // Should not be possible
                throw new InvalidOperationException("_reader is null");
            }

            if (MetaData == null)
            {
                MetaData = new QueryMetaData();
            }

            _resultEnumerator = null;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var path = await _reader !.ReadToNextAttributeAsync(cancellationToken).ConfigureAwait(false);
                if (path == null)
                {
                    // Reached the end
                    break;
                }

                switch (path)
                {
                case "requestID" when _reader.ValueType == typeof(string):
                    MetaData.RequestId = _reader.Value?.ToString();
                    break;

                case "status" when _reader.ValueType == typeof(string):
                    if (Enum.TryParse(_reader.Value?.ToString(), true, out QueryStatus status))
                    {
                        MetaData.Status = status;
                        Success         = status == QueryStatus.Success;
                    }

                    break;

                case "clientContextID" when _reader.ValueType == typeof(string):
                    MetaData.ClientContextId = _reader.Value?.ToString();
                    break;

                case "signature":
                    MetaData.Signature = (await _reader.ReadTokenAsync(cancellationToken).ConfigureAwait(false))
                                         .ToDynamic();
                    break;

                case "prepared" when _reader.ValueType == typeof(string):
                    PreparedPlanName = _reader.Value?.ToString();;
                    break;

                case "profile":
                    MetaData.Profile = (await _reader.ReadTokenAsync(cancellationToken).ConfigureAwait(false))
                                       .ToDynamic();
                    break;

                case "metrics":
                    MetaData.Metrics =
                        (await _reader.ReadObjectAsync <MetricsData>(cancellationToken).ConfigureAwait(false))
                        .ToMetrics();
                    break;

                case "results":
                    if (this.Success)
                    {
                        _resultEnumerator = _reader.ReadObjectsAsync <T>(cancellationToken).GetAsyncEnumerator(cancellationToken);

                        if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
                        {
                            // We've reached the result rows, and there is at least one item in the results, return now
                            return;
                        }

                        // Result set was empty, cleanup
                        await _resultEnumerator.DisposeAsync().ConfigureAwait(false);

                        _resultEnumerator = null;
                    }

                    // In non-success situations or when the result set is empty, we want to populate all the error and warning fields.
                    break;

                case "warnings":
                    await foreach (var warning in _reader.ReadObjectsAsync <QueryWarning>(cancellationToken)
                                   .ConfigureAwait(false))
                    {
                        MetaData.Warnings.Add(warning);
                    }

                    break;

                case "errors":
                    await foreach (var error in _reader.ReadObjectsAsync <Error>(cancellationToken)
                                   .ConfigureAwait(false))
                    {
                        Errors.Add(error);
                    }

                    break;
                }
            }

            // We've reached the end of the object, mark that entire read is complete
            _hasFinishedReading = true;
        }