public async Task <IGetResult> GetAsync(string id, GetOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            options ??= new GetOptions();
            var specs = new List <LookupInSpec>();

            if (options.IncludeExpiryValue)
            {
                specs.Add(new LookupInSpec
                {
                    OpCode    = OpCode.SubGet,
                    Path      = VirtualXttrs.DocExpiryTime,
                    PathFlags = SubdocPathFlags.Xattr
                });
            }

            var projectList = options.ProjectListValue;

            if (projectList.Any())
            {
                //we have succeeded the max #fields returnable by sub-doc so fetch the whole doc
                if (projectList.Count + specs.Count > 16)
                {
                    specs.Add(new LookupInSpec
                    {
                        Path     = "",
                        OpCode   = OpCode.Get,
                        DocFlags = SubdocDocFlags.None
                    });
                }
                else
                {
                    //Add the projections for fetching
                    projectList.ForEach(path => specs.Add(new LookupInSpec
                    {
                        OpCode = OpCode.SubGet,
                        Path   = path
                    }));
                }
            }
            else
            {
                //Project list is empty so fetch the whole doc
                specs.Add(new LookupInSpec
                {
                    Path     = "",
                    OpCode   = OpCode.Get,
                    DocFlags = SubdocDocFlags.None
                });
            }

            var lookupOp = await ExecuteLookupIn(id,
                                                 specs, new LookupInOptions().Timeout(options.TimeoutValue))
                           .ConfigureAwait(false);

            var transcoder = options.TranscoderValue ?? _transcoder;

            return(new GetResult(lookupOp.ExtractData(), transcoder, _getLogger, specs, projectList)
            {
                Id = lookupOp.Key,
                Cas = lookupOp.Cas,
                OpCode = lookupOp.OpCode,
                Flags = lookupOp.Flags,
                Header = lookupOp.Header,
                Opaque = lookupOp.Opaque
            });
        }
Example #2
0
        public async Task <IGetResult> GetAsync(string id, GetOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            //Get the collection ID
            await PopulateCidAsync().ConfigureAwait(false);

            // TODO: Since we're actually using LookupIn for Get requests, which operation name should we use?
            using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.Kv.Get);
            options ??= GetOptions.Default;

            var projectList = options.ProjectListValue;

            var specCount = projectList.Count;

            if (options.IncludeExpiryValue)
            {
                specCount++;
            }

            if (specCount == 0)
            {
                // We aren't including the expiry value and we have no projections so fetch the whole doc using a Get operation
                var getOp = new Get <byte[]>
                {
                    Key   = id,
                    Cid   = Cid,
                    CName = Name,
                    SName = ScopeName,
                    Span  = rootSpan
                };
                _operationConfigurator.Configure(getOp, options);

                using var cts = CreateRetryTimeoutCancellationTokenSource(options, getOp, out var tokenPair);
                await _bucket.RetryAsync(getOp, tokenPair).ConfigureAwait(false);

                return(new GetResult(getOp.ExtractBody(), getOp.Transcoder, _getLogger)
                {
                    Id = getOp.Key,
                    Cas = getOp.Cas,
                    OpCode = getOp.OpCode,
                    Flags = getOp.Flags,
                    Header = getOp.Header,
                    Opaque = getOp.Opaque
                });
            }

            var specs = new List <LookupInSpec>();

            if (options.IncludeExpiryValue)
            {
                specs.Add(new LookupInSpec
                {
                    OpCode    = OpCode.SubGet,
                    Path      = VirtualXttrs.DocExpiryTime,
                    PathFlags = SubdocPathFlags.Xattr
                });
            }

            if (projectList.Count == 0 || specCount > 16)
            {
                // No projections or we have exceeded the max #fields returnable by sub-doc so fetch the whole doc
                specs.Add(new LookupInSpec
                {
                    Path     = "",
                    OpCode   = OpCode.Get,
                    DocFlags = SubdocDocFlags.None
                });
            }
            else
            {
                //Add the projections for fetching
                foreach (var path in projectList)
                {
                    specs.Add(new LookupInSpec
                    {
                        OpCode = OpCode.SubGet,
                        Path   = path
                    });
                }
            }

            var lookupInOptions = !ReferenceEquals(options, GetOptions.Default)
                ? new LookupInOptions()
                                  .Timeout(options.TimeoutValue)
                                  .Transcoder(options.TranscoderValue)
                : LookupInOptions.Default;

            var lookupOp = await ExecuteLookupIn(id,
                                                 specs, lookupInOptions, rootSpan)
                           .ConfigureAwait(false);

            rootSpan.WithOperationId(lookupOp);
            rootSpan.Dispose();
            return(new GetResult(lookupOp.ExtractBody(), lookupOp.Transcoder, _getLogger, specs, projectList)
            {
                Id = lookupOp.Key,
                Cas = lookupOp.Cas,
                OpCode = lookupOp.OpCode,
                Flags = lookupOp.Flags,
                Header = lookupOp.Header,
                Opaque = lookupOp.Opaque
            });
        }
Example #3
0
        public async Task <IGetResult> GetAsync(string id, GetOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            // TODO: Since we're actually using LookupIn for Get requests, which operation name should we use?
            using var rootSpan = RootSpan(OperationNames.Get);
            options ??= new GetOptions();
            var specs = new List <LookupInSpec>();

            if (options.IncludeExpiryValue)
            {
                specs.Add(new LookupInSpec
                {
                    OpCode    = OpCode.SubGet,
                    Path      = VirtualXttrs.DocExpiryTime,
                    PathFlags = SubdocPathFlags.Xattr
                });
            }

            var projectList = options.ProjectListValue;

            if (projectList.Any())
            {
                //we have succeeded the max #fields returnable by sub-doc so fetch the whole doc
                if (projectList.Count + specs.Count > 16)
                {
                    specs.Add(new LookupInSpec
                    {
                        Path     = "",
                        OpCode   = OpCode.Get,
                        DocFlags = SubdocDocFlags.None
                    });
                }
                else
                {
                    //Add the projections for fetching
                    projectList.ForEach(path => specs.Add(new LookupInSpec
                    {
                        OpCode = OpCode.SubGet,
                        Path   = path
                    }));
                }
            }
            else
            {
                //Project list is empty so fetch the whole doc
                specs.Add(new LookupInSpec
                {
                    Path     = "",
                    OpCode   = OpCode.Get,
                    DocFlags = SubdocDocFlags.None
                });
            }

            var lookupOp = await ExecuteLookupIn(id,
                                                 specs, new LookupInOptions().Timeout(options.TimeoutValue), rootSpan)
                           .ConfigureAwait(false);

            rootSpan.OperationId(lookupOp);
            _operationConfigurator.Configure(lookupOp, options);

            return(new GetResult(lookupOp.ExtractBody(), lookupOp.Transcoder, _getLogger, specs, projectList)
            {
                Id = lookupOp.Key,
                Cas = lookupOp.Cas,
                OpCode = lookupOp.OpCode,
                Flags = lookupOp.Flags,
                Header = lookupOp.Header,
                Opaque = lookupOp.Opaque
            });
        }