Skip to content

Commit 7b44597

Browse files
committed
NCBC-9383 Add ReplaceBodyWithXattr to MutateInSpec
Motivation ========== This capability was added in 7.1. Also, transactions has an extension that uses it to gain a bit of efficiency. Modification ============ Added the BucketCapability, then updated the MutateInSpec and corresponding builder to support adding the new op code. Results ======= Added a new integration test, it passes. Change-Id: Ie130c31bb632f8454774dd73f6fd792872d29cdc Reviewed-on: https://review.couchbase.org/c/couchbase-net-client/+/225199 Reviewed-by: Jeffry Morris <jeffrymorris@gmail.com> Tested-by: Build Bot <build@couchbase.com>
1 parent ba56d87 commit 7b44597

File tree

6 files changed

+41
-1
lines changed

6 files changed

+41
-1
lines changed

src/Couchbase/Core/Configuration/Server/BucketCapabilities.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static class BucketCapabilities
1717
public const string RANGE_SCAN = "rangeScan";
1818
public const string SUBDOC_REPLICA_READ = "subdoc.ReplicaRead";
1919
public const string NON_DEDUPED_HISTORY = "nonDedupedHistory";
20+
public const string SUBDOC_REPLACE_BODY_WITH_XATTR = "subdoc.ReplaceBodyWithXattr";
2021
}
2122
}
2223

src/Couchbase/Core/IO/Operations/OpCode.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public enum OpCode : byte
8484
MultiLookup = 0xd0,
8585
SubMultiMutation = 0xd1,
8686
SubGetCount = 0xd2,
87+
SubReplaceBodyWithXattr = 0xd3,
8788

8889
//the collections manifest
8990
GetCollectionsManifest = 0xBA,

src/Couchbase/Core/IO/Operations/SubDocument/MultiMutation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ protected override void WriteBody(OperationBuilder builder)
109109
var pathLength = ByteConverter.FromString(mutate.Path, bufferSpan);
110110
builder.Write(buffer, 0, pathLength);
111111

112-
if (mutate.OpCode is not OpCode.SubDelete and not OpCode.Delete)
112+
if (mutate.OpCode is not OpCode.SubDelete and not OpCode.Delete and not OpCode.SubReplaceBodyWithXattr)
113113
{
114114
builder.AdvanceToSegment(OperationSegment.OperationSpecFragment);
115115
mutate.WriteSpecValue(builder, Transcoder);

src/Couchbase/KeyValue/MutateInSpec.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ public static MutateInSpec Decrement(string path, ulong delta, bool createPath =
156156
return CreateSpec(OpCode.SubCounter, path, -(long)delta, createPath, isXattr, removeBrackets);
157157
}
158158

159+
public static MutateInSpec ReplaceBodyWithXattr(string path)
160+
{
161+
return CreateSpec(OpCode.SubReplaceBodyWithXattr, path, false, true, false);
162+
}
163+
159164
/// <summary>
160165
/// Serializes the <see cref="OperationSpec.Value" /> to the <see cref="OperationBuilder"/> using the <see cref="ITypeTranscoder"/>.
161166
/// </summary>

src/Couchbase/KeyValue/MutateInSpecBuilder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ public MutateInSpecBuilder SetDoc<T>(T value)
243243
Specs.Add(MutateInSpec.Decrement(path, delta, createPath, isXattr));
244244
return this;
245245
}
246+
247+
public MutateInSpecBuilder ReplaceBodyWithXattr(string path)
248+
{
249+
Specs.Add(MutateInSpec.ReplaceBodyWithXattr(path));
250+
return this;
251+
}
246252
}
247253
}
248254

tests/Couchbase.IntegrationTests/SubdocTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,33 @@ public async Task MutateIn_SetDoc_UsesTranscoder()
542542
//Assert.Equal("foo", result.ContentAs<string>(1));
543543
}
544544

545+
[Fact]
546+
public async Task MutateIn_ReplaceBodyWithXattr_Succeeds()
547+
{
548+
var collection = await _fixture.GetDefaultCollectionAsync().ConfigureAwait(false);
549+
var documentKey = nameof(MutateIn_ReplaceBodyWithXattr_Succeeds);
550+
await collection.UpsertAsync(documentKey, new { foo = "bar", bar = "foo", xxx = 0 }).ConfigureAwait(false);
551+
var newDocBody = new { bar = "foo2", foo = "bar2", xxx = 3 };
552+
553+
// put the newDocBody in test_attr xattr...
554+
using (await collection.MutateInAsync(documentKey, builder =>
555+
{
556+
builder.Upsert("test_attr", newDocBody, isXattr: true, createPath: true);
557+
}));
558+
559+
using (await collection.MutateInAsync(documentKey, builder =>
560+
{
561+
builder.ReplaceBodyWithXattr("test_attr");
562+
}));
563+
564+
// verify the document body changed. NOTE: by comparing as strings, we run the risk
565+
// of having the order change though the key/value pairs are all equal. If you change
566+
// the newDocBody (or the old one), you may need to adjust the order of one or the
567+
// other to match.
568+
var getResult = await collection.GetAsync(documentKey, options => options.Transcoder(new LegacyTranscoder())).ConfigureAwait(false);
569+
Assert.Equal(getResult.ContentAs<string>(), JsonConvert.SerializeObject(newDocBody));
570+
}
571+
545572
#region Helpers
546573

547574
private class TestDoc

0 commit comments

Comments
 (0)