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)); }
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); }
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)); }
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)); } }
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 }
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); }
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 }