Example #1
0
        public async Task WriteBody_Repeats_Safely()
        {
            var bytes = new byte[]
            {
                129, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 16, 21, 240,
                165, 234, 46, 107, 0, 0, 3, 0, 0, 0, 0, 0, 2, 49, 48, 4, 0, 0,
                0, 0, 0, 2, 45, 53
            };

            var builder = new MutateInSpecBuilder();

            for (int i = 0; i < 10; i++)
            {
                builder.Upsert("upsert_" + i, i);
            }

            var op = new MultiMutation <byte[]>("thekey", builder.Specs)
            {
                Transcoder = new JsonTranscoder()
            };

            op.OperationBuilderPool = new DefaultObjectPool <OperationBuilder>(new OperationBuilderPoolPolicy());

            await op.SendAsync(new Mock <IConnection>().Object).ConfigureAwait(false);

            op.Read(new FakeMemoryOwner <byte>(bytes));
            Assert.Equal(10, op.GetCommandValues().Count);
            op.Reset();
            await op.SendAsync(new Mock <IConnection>().Object).ConfigureAwait(false);

            op.Read(new FakeMemoryOwner <byte>(bytes));
            Assert.Equal(10, op.GetCommandValues().Count);

            var result = new MutateInResult(op.GetCommandValues(), 0, MutationToken.Empty, new DefaultSerializer());
        }
        public async Task Can_MutateIn_Parse_Flexible_Header_Args()
        {
            var responsePacket = new byte[]
            {
                0x18, 0xd1, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x44, 0x15, 0xfa,
                0xc3, 0x29, 0x58, 0x19, 0x00, 0x00, 0x02, 0x00, 0x12,
                0x00, 0x00, 0xad, 0x17, 0x52, 0xf2, 0x38, 0x3e, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x30, 0x04, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x35
            };

            var specs = new MutateInSpecBuilder().
                        Upsert("name", "mike").
                        Replace("bar", "bar").
                        Insert("bah", 0).
                        Increment("zzz", 10, true).
                        Decrement("xxx", 5, true).Specs;

            var op = new MultiMutation <byte[]>
            {
                Builder = new MutateInBuilder <byte[]>(null, null, "thekey", specs)
            };
            await op.SendAsync(new Mock <IConnection>().Object).ConfigureAwait(false);

            op.Read(new FakeMemoryOwner <byte>(responsePacket));

            var result = new MutateInResult(op.GetCommandValues(), 0, MutationToken.Empty, new DefaultSerializer());

            Assert.Equal(10, result.ContentAs <int>(3));
            Assert.Equal(-5, result.ContentAs <int>(4));
        }
Example #3
0
        public async Task When_Result_Contains_Values_AllowRead()
        {
            var bytes = new byte[]
            {
                129, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 16, 21, 240,
                165, 234, 46, 107, 0, 0, 3, 0, 0, 0, 0, 0, 2, 49, 48, 4, 0, 0,
                0, 0, 0, 2, 45, 53
            };

            var specs = new MutateInSpecBuilder().
                        Upsert("name", "mike").
                        Replace("bar", "bar").
                        Insert("bah", 0).
                        Increment("zzz", 10, true).
                        Decrement("xxx", 5, true).Specs;

            var op = new MultiMutation <byte[]>
            {
                Builder = new MutateInBuilder <byte[]>(null, null, "thekey", specs)
            };
            await op.SendAsync(new Mock <IConnection>().Object).ConfigureAwait(false);

            await op.ReadAsync(new FakeMemoryOwner <byte>(bytes), null).ConfigureAwait(false);

            var result = new MutateInResult(op.GetCommandValues(), 0, MutationToken.Empty, new DefaultSerializer());

            Assert.Equal(0, result.ContentAs <int>(0));
            Assert.Equal(0, result.ContentAs <int>(1));
            Assert.Equal(0, result.ContentAs <int>(2));
            Assert.Equal(10, result.ContentAs <int>(3));
            Assert.Equal(-5, result.ContentAs <int>(4));
        }
        public async Task When_Index_Invalid_IndexNotFoundException_Thrown(int index)
        {
            var bytes = new byte[]
            {
                129, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 16, 21, 240,
                165, 234, 46, 107, 0, 0, 3, 0, 0, 0, 0, 0, 2, 49, 48, 4, 0, 0,
                0, 0, 0, 2, 45, 53
            };

            var specs = new MutateInSpecBuilder().Upsert("name", "mike").Replace("bar", "bar").Insert("bah", 0)
                        .Increment("zzz", 10, true).Decrement("xxx", 5, true).Specs;

            var op = new MultiMutation <byte[]>
            {
                Builder    = new MutateInBuilder <byte[]>(null, null, "thekey", specs),
                Transcoder = new JsonTranscoder()
            };

            op.OperationBuilderPool = new DefaultObjectPool <OperationBuilder>(new OperationBuilderPoolPolicy());
            await op.SendAsync(new Mock <IConnection>().Object).ConfigureAwait(false);

            op.Read(new FakeMemoryOwner <byte>(bytes));

            var result = new MutateInResult(op.GetCommandValues(), 0, MutationToken.Empty, new DefaultSerializer());

            Assert.Throws <InvalidIndexException>(() => result.ContentAs <string>(index));
        }
        public async Task <IMutateInResult> MutateInAsync(string id, IEnumerable <MutateInSpec> specs, MutateInOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            options ??= new MutateInOptions();
            // convert new style specs into old style builder
            var builder = new MutateInBuilder <byte[]>(null, null, id, specs);

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemanticsValue)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            case StoreSemantics.AccessDeleted:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            using var rootSpan = RootSpan(OperationNames.MultiMutationSubdocMutate);
            using var mutation = new MultiMutation <byte[]>
                  {
                      Key             = id,
                      BucketName      = _bucket.Name,
                      Builder         = builder,
                      Cid             = Cid,
                      CName           = Name,
                      Expires         = options.ExpiryValue.ToTtl(),
                      DurabilityLevel = options.DurabilityLevel,
                      Transcoder      = _transcoder,
                      DocFlags        = docFlags,
                      Span            = rootSpan
                  };

            await RetryUntilTimeoutOrSuccessAsync(options.TokenValue, options.TimeoutValue, mutation).ConfigureAwait(false);

            return(new MutateInResult(mutation.GetCommandValues(), mutation.Cas, mutation.MutationToken,
                                      options.SerializerValue ?? _transcoder.Serializer));
        }
        public void MultiMutation_WillRetry_IfHasCas()
        {
            var mockedInvoker = new Mock <ISubdocInvoker>();
            var builder       = new MutateInBuilder <dynamic>(mockedInvoker.Object, () => new DefaultSerializer(), "thekey");

            builder.Remove("somepath");
            var op = new MultiMutation <dynamic>("thekey", builder, new Mock <IVBucket>().Object,
                                                 new Mock <ITypeTranscoder>().Object, 10)
            {
                Cas = 100
            };

            Assert.IsTrue(op.CanRetry());
        }
        public void MultiMutate_Clone()
        {
            var mockedInvoker = new Mock <ISubdocInvoker>();
            var builder       = new MutateInBuilder <dynamic>(mockedInvoker.Object, () => new DefaultSerializer(), "thekey");

            builder.Remove("somepath");
            builder.ArrayPrepend("pathone", 10);
            var op = new MultiMutation <dynamic>("thekey", builder, new Mock <IVBucket>().Object,
                                                 new Mock <ITypeTranscoder>().Object, 10)
            {
                Cas = 100
            };

            var cloned = (MultiMutation <dynamic>)op.Clone();

            Assert.AreEqual(op, cloned);
        }
Example #8
0
        public async Task <IMutationResult> MutateIn(string id, IEnumerable <OperationSpec> specs, MutateInOptions options)
        {
            // convert new style specs into old style builder
            var builder = new MutateInBuilder <byte[]>(null, null, id, specs);

            var mutation = new MultiMutation <byte[]>
            {
                Key             = id,
                Builder         = builder,
                Cid             = Cid,
                DurabilityLevel = options._DurabilityLevel
            };

            await ExecuteOp(mutation, options._Token, options._Timeout);

            return(new MutationResult(mutation.Cas, null, mutation.MutationToken));
        }
Example #9
0
        public async Task <IMutateInResult> MutateInAsync(string id, IEnumerable <MutateInSpec> specs, MutateInOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            options ??= new MutateInOptions();
            // convert new style specs into old style builder
            var builder = new MutateInBuilder <byte[]>(null, null, id, specs);

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemanticsValue)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            case StoreSemantics.AccessDeleted:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            using var mutation = new MultiMutation <byte[]>
                  {
                      Key             = id,
                      Builder         = builder,
                      Cid             = Cid,
                      DurabilityLevel = options.DurabilityLevel,
                      Transcoder      = _transcoder,
                      DocFlags        = docFlags
                  };
            await _bucket.SendAsync(mutation, options.TokenValue, options.TimeoutValue);

            return(new MutateInResult(mutation.Cas, mutation.MutationToken, mutation.GetCommandValues()));
        }
        public async Task <IMutationResult> MutateInAsync(string id, IEnumerable <OperationSpec> specs, MutateInOptions options = null)
        {
            options = options ?? new MutateInOptions();
            // convert new style specs into old style builder
            var builder = new MutateInBuilder <byte[]>(null, null, id, specs);

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemantics)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            using (var mutation = new MultiMutation <byte[]>
            {
                Key = id,
                Builder = builder,
                Cid = Cid,
                DurabilityLevel = options.DurabilityLevel,
                Transcoder = _transcoder,
                DocFlags = docFlags
            })
            {
                await _bucket.SendAsync(mutation, options.Token, options.Timeout);

                return(new MutationResult(mutation.Cas, null, mutation.MutationToken));
            }
        }
Example #11
0
        public async Task <IMutateInResult> MutateInAsync(string id, IEnumerable <MutateInSpec> specs,
                                                          MutateInOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

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

            options ??= MutateInOptions.Default;

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemanticsValue)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            case StoreSemantics.AccessDeleted:
                docFlags |= SubdocDocFlags.AccessDeleted;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (options.CreateAsDeletedValue)
            {
                if (!_bucket.BucketConfig?.BucketCapabilities.Contains(BucketCapabilities.CREATE_AS_DELETED) == true)
                {
                    throw new FeatureNotAvailableException(nameof(BucketCapabilities.CREATE_AS_DELETED));
                }

                docFlags |= SubdocDocFlags.CreateAsDeleted;
            }

            if (options.AccessDeletedValue)
            {
                docFlags |= SubdocDocFlags.AccessDeleted;
            }

            using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.Kv.MutateIn);
            using var mutation = new MultiMutation <byte[]>(id, specs)
                  {
                      BucketName      = _bucket.Name,
                      Cas             = options.CasValue,
                      Cid             = Cid,
                      CName           = Name,
                      SName           = ScopeName,
                      Expires         = options.ExpiryValue.ToTtl(),
                      DurabilityLevel = options.DurabilityLevel,
                      DocFlags        = docFlags,
                      Span            = rootSpan
                  };
            _operationConfigurator.Configure(mutation, options);

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

#pragma warning disable 618 // MutateInResult is marked obsolete until it is made internal
            return(new MutateInResult(mutation.GetCommandValues(), mutation.Cas, mutation.MutationToken,
                                      options.SerializerValue ?? mutation.Transcoder.Serializer));

#pragma warning restore 618
        }
Example #12
0
        public async Task <IMutateInResult> MutateInAsync(string id, IEnumerable <MutateInSpec> specs, MutateInOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            options ??= MutateInOptions.Default;
            // convert new style specs into old style builder
            var builder = new MutateInBuilder <byte[]>(null, null, id, specs);

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemanticsValue)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            case StoreSemantics.AccessDeleted:
                docFlags |= SubdocDocFlags.AccessDeleted;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (options.CreateAsDeletedValue)
            {
                if (!_bucket.BucketConfig?.BucketCapabilities.Contains(BucketCapabilities.CREATE_AS_DELETED) == true)
                {
                    throw new FeatureNotAvailableException(nameof(BucketCapabilities.CREATE_AS_DELETED));
                }

                docFlags |= SubdocDocFlags.CreateAsDeleted;
            }

            if (options.AccessDeletedValue)
            {
                docFlags |= SubdocDocFlags.AccessDeleted;
            }

            using var rootSpan = RootSpan(OperationNames.MultiMutationSubdocMutate);
            using var mutation = new MultiMutation <byte[]>
                  {
                      Key             = id,
                      BucketName      = _bucket.Name,
                      Builder         = builder,
                      Cas             = options.CasValue,
                      Cid             = Cid,
                      CName           = Name,
                      Expires         = options.ExpiryValue.ToTtl(),
                      DurabilityLevel = options.DurabilityLevel,
                      DocFlags        = docFlags,
                      Span            = rootSpan
                  };
            _operationConfigurator.Configure(mutation, options);

            using var cts = CreateRetryTimeoutCancellationTokenSource(options, mutation);
            await _bucket.RetryAsync(mutation, cts.Token).ConfigureAwait(false);

            return(new MutateInResult(mutation.GetCommandValues(), mutation.Cas, mutation.MutationToken,
                                      options.SerializerValue ?? mutation.Transcoder.Serializer));
        }
        public void MultiMutation_WillNotRetry_IfCasIsZero()
        {
            var mockedInvoker = new Mock<ISubdocInvoker>();
            var builder = new MutateInBuilder<dynamic>(mockedInvoker.Object, () => new DefaultSerializer(), "thekey");

            builder.Remove("somepath");
            var op = new MultiMutation<dynamic>("thekey", builder, new Mock<IVBucket>().Object,
                new Mock<ITypeTranscoder>().Object, 10)
            { Cas = 0 };

            Assert.IsFalse(op.CanRetry());
        }
        public void MultiMutate_Clone()
        {
            var mockedInvoker = new Mock<ISubdocInvoker>();
            var builder = new MutateInBuilder<dynamic>(mockedInvoker.Object, () => new DefaultSerializer(), "thekey");

            builder.Remove("somepath");
            builder.ArrayPrepend("pathone", 10);
            var op = new MultiMutation<dynamic>("thekey", builder, new Mock<IVBucket>().Object,
                new Mock<ITypeTranscoder>().Object, 10)
            { Cas = 100 };

            var cloned = (MultiMutation<dynamic>) op.Clone();
            Assert.AreEqual(op, cloned);
        }
Example #15
0
        public async Task <IMutateInResult> MutateInAsync(string id, IEnumerable <MutateInSpec> specs,
                                                          MutateInOptions?options = null)
        {
            //sanity check for deferred bootstrapping errors
            _bucket.ThrowIfBootStrapFailed();

            //Check to see if the CID is needed
            if (RequiresCid())
            {
                //Get the collection ID
                await PopulateCidAsync().ConfigureAwait(false);
            }

            options ??= MutateInOptions.Default;

            //Reality check for preserveTtl server support
            if (!_bucket.Context.SupportsPreserveTtl && options.PreserveTtlValue)
            {
                throw new FeatureNotAvailableException(
                          "This version of Couchbase Server does not support preserving expiry when modifying documents.");
            }

            //resolve StoreSemantics to SubdocDocFlags
            var docFlags = SubdocDocFlags.None;

            switch (options.StoreSemanticsValue)
            {
            case StoreSemantics.Replace:
                break;

            case StoreSemantics.Upsert:
                docFlags |= SubdocDocFlags.UpsertDocument;
                break;

            case StoreSemantics.Insert:
                docFlags |= SubdocDocFlags.InsertDocument;
                break;

            case StoreSemantics.AccessDeleted:
                docFlags |= SubdocDocFlags.AccessDeleted;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (options.CreateAsDeletedValue)
            {
                if (!_bucket.CurrentConfig?.BucketCapabilities.Contains(BucketCapabilities.CREATE_AS_DELETED) == true)
                {
                    throw new FeatureNotAvailableException(nameof(BucketCapabilities.CREATE_AS_DELETED));
                }

                docFlags |= SubdocDocFlags.CreateAsDeleted;
            }

            if (options.AccessDeletedValue)
            {
                docFlags |= SubdocDocFlags.AccessDeleted;
            }

            using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.Kv.MutateIn, options.RequestSpanValue);
            using var mutation = new MultiMutation <byte[]>(id, specs)
                  {
                      BucketName      = _bucket.Name,
                      Cas             = options.CasValue,
                      Cid             = Cid,
                      CName           = Name,
                      SName           = ScopeName,
                      Expires         = options.ExpiryValue.ToTtl(),
                      DurabilityLevel = options.DurabilityLevel,
                      DocFlags        = docFlags,
                      Span            = rootSpan,
                      PreserveTtl     = options.PreserveTtlValue
                  };
            _operationConfigurator.Configure(mutation, options);
            if (mutation.Transcoder != null && options.SerializerValue != null)
            {
                mutation.Transcoder.Serializer = options.SerializerValue !;
            }

            using var ctp = CreateRetryTimeoutCancellationTokenSource(options, mutation);
            await _bucket.RetryAsync(mutation, ctp.TokenPair).ConfigureAwait(false);

#pragma warning disable 618 // MutateInResult is marked obsolete until it is made internal
            return(new MutateInResult(mutation.GetCommandValues(), mutation.Cas, mutation.MutationToken,
                                      options.SerializerValue ?? mutation.Transcoder?.Serializer ?? Core.IO.Serializers.DefaultSerializer.Instance));

#pragma warning restore 618
        }