Skip to content

Commit 96821c8

Browse files
committed
CSHARP-1437: Add support for WriteConcern to FindAndModify operations.
1 parent e9355df commit 96821c8

11 files changed

+109
-29
lines changed

src/MongoDB.Driver.Core.Tests/Core/Operations/FindOneAndDeleteOperationTests.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using FluentAssertions;
1919
using MongoDB.Bson;
2020
using MongoDB.Bson.Serialization.Serializers;
21+
using MongoDB.Driver.Core.Misc;
2122
using NUnit.Framework;
2223

2324
namespace MongoDB.Driver.Core.Operations
@@ -81,15 +82,20 @@ public void Constructor_should_initialize_object()
8182
public void CreateCommand_should_create_the_correct_command(
8283
[Values(null, 10)] int? maxTimeMS,
8384
[Values(null, "{a: 1}")] string projection,
84-
[Values(null, "{b: 1}")] string sort)
85+
[Values(null, "{b: 1}")] string sort,
86+
[Values(null, "{ w : 2 }")] string writeConcernString,
87+
[Values("3.0.0", "3.1.1")] string serverVersionString)
8588
{
8689
var projectionDoc = projection == null ? (BsonDocument)null : BsonDocument.Parse(projection);
8790
var sortDoc = sort == null ? (BsonDocument)null : BsonDocument.Parse(sort);
91+
var writeConcern = writeConcernString == null ? null : WriteConcern.FromBsonDocument(BsonDocument.Parse(writeConcernString));
92+
var serverVersion = SemanticVersion.Parse(serverVersionString);
8893
var subject = new FindOneAndDeleteOperation<BsonDocument>(_collectionNamespace, _filter, BsonDocumentSerializer.Instance, _messageEncoderSettings)
8994
{
9095
MaxTime = maxTimeMS.HasValue ? TimeSpan.FromMilliseconds(maxTimeMS.Value) : (TimeSpan?)null,
9196
Projection = projectionDoc,
92-
Sort = sortDoc
97+
Sort = sortDoc,
98+
WriteConcern = writeConcern
9399
};
94100

95101
var expectedResult = new BsonDocument
@@ -99,10 +105,12 @@ public void CreateCommand_should_create_the_correct_command(
99105
{ "sort", sortDoc, sortDoc != null },
100106
{ "remove", true },
101107
{ "fields", projectionDoc, projectionDoc != null },
102-
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue }
108+
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue },
109+
{ "writeConcern", () => writeConcern.ToBsonDocument(), writeConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
110+
103111
};
104112

105-
var result = subject.CreateCommand();
113+
var result = subject.CreateCommand(serverVersion);
106114

107115
result.Should().Be(expectedResult);
108116
}

src/MongoDB.Driver.Core.Tests/Core/Operations/FindOneAndReplaceOperationTests.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using FluentAssertions;
1919
using MongoDB.Bson;
2020
using MongoDB.Bson.Serialization.Serializers;
21+
using MongoDB.Driver.Core.Misc;
2122
using NUnit.Framework;
2223

2324
namespace MongoDB.Driver.Core.Operations
@@ -94,17 +95,22 @@ public void CreateCommand_should_create_the_correct_command(
9495
[Values(null, 10)] int? maxTimeMS,
9596
[Values(null, "{a: 1}")] string projection,
9697
[Values(ReturnDocument.Before, ReturnDocument.After)] ReturnDocument returnDocument,
97-
[Values(null, "{b: 1}")] string sort)
98+
[Values(null, "{b: 1}")] string sort,
99+
[Values(null, "{ w : 2 }")] string writeConcernString,
100+
[Values("3.0.0", "3.1.1")] string serverVersionString)
98101
{
99102
var projectionDoc = projection == null ? (BsonDocument)null : BsonDocument.Parse(projection);
100103
var sortDoc = sort == null ? (BsonDocument)null : BsonDocument.Parse(sort);
104+
var writeConcern = writeConcernString == null ? null : WriteConcern.FromBsonDocument(BsonDocument.Parse(writeConcernString));
105+
var serverVersion = SemanticVersion.Parse(serverVersionString);
101106
var subject = new FindOneAndReplaceOperation<BsonDocument>(_collectionNamespace, _filter, _replacement, BsonDocumentSerializer.Instance, _messageEncoderSettings)
102107
{
103108
IsUpsert = isUpsert,
104109
MaxTime = maxTimeMS.HasValue ? TimeSpan.FromMilliseconds(maxTimeMS.Value) : (TimeSpan?)null,
105110
Projection = projectionDoc,
106111
ReturnDocument = returnDocument,
107-
Sort = sortDoc
112+
Sort = sortDoc,
113+
WriteConcern = writeConcern
108114
};
109115

110116
var expectedResult = new BsonDocument
@@ -116,10 +122,11 @@ public void CreateCommand_should_create_the_correct_command(
116122
{ "new", returnDocument == ReturnDocument.After },
117123
{ "fields", projectionDoc, projectionDoc != null },
118124
{ "upsert", isUpsert },
119-
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue }
125+
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue },
126+
{ "writeConcern", () => writeConcern.ToBsonDocument(), writeConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
120127
};
121128

122-
var result = subject.CreateCommand();
129+
var result = subject.CreateCommand(serverVersion);
123130

124131
result.Should().Be(expectedResult);
125132
}

src/MongoDB.Driver.Core.Tests/Core/Operations/FindOneAndUpdateOperationTests.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using FluentAssertions;
1919
using MongoDB.Bson;
2020
using MongoDB.Bson.Serialization.Serializers;
21+
using MongoDB.Driver.Core.Misc;
2122
using NUnit.Framework;
2223

2324
namespace MongoDB.Driver.Core.Operations
@@ -94,17 +95,22 @@ public void CreateCommand_should_create_the_correct_command(
9495
[Values(null, 10)] int? maxTimeMS,
9596
[Values(null, "{a: 1}")] string projection,
9697
[Values(ReturnDocument.Before, ReturnDocument.After)] ReturnDocument returnDocument,
97-
[Values(null, "{b: 1}")] string sort)
98+
[Values(null, "{b: 1}")] string sort,
99+
[Values(null, "{ w : 2 }")] string writeConcernString,
100+
[Values("3.0.0", "3.1.1")] string serverVersionString)
98101
{
99102
var projectionDoc = projection == null ? (BsonDocument)null : BsonDocument.Parse(projection);
100103
var sortDoc = sort == null ? (BsonDocument)null : BsonDocument.Parse(sort);
104+
var writeConcern = writeConcernString == null ? null : WriteConcern.FromBsonDocument(BsonDocument.Parse(writeConcernString));
105+
var serverVersion = SemanticVersion.Parse(serverVersionString);
101106
var subject = new FindOneAndUpdateOperation<BsonDocument>(_collectionNamespace, _filter, _update, BsonDocumentSerializer.Instance, _messageEncoderSettings)
102107
{
103108
IsUpsert = isUpsert,
104109
MaxTime = maxTimeMS.HasValue ? TimeSpan.FromMilliseconds(maxTimeMS.Value) : (TimeSpan?)null,
105110
Projection = projectionDoc,
106111
ReturnDocument = returnDocument,
107-
Sort = sortDoc
112+
Sort = sortDoc,
113+
WriteConcern = writeConcern
108114
};
109115

110116
var expectedResult = new BsonDocument
@@ -116,10 +122,11 @@ public void CreateCommand_should_create_the_correct_command(
116122
{ "new", returnDocument == ReturnDocument.After },
117123
{ "fields", projectionDoc, projectionDoc != null },
118124
{ "upsert", isUpsert },
119-
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue }
125+
{ "maxTimeMS", () => maxTimeMS.Value, maxTimeMS.HasValue },
126+
{ "writeConcern", () => writeConcern.ToBsonDocument(), writeConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
120127
};
121128

122-
var result = subject.CreateCommand();
129+
var result = subject.CreateCommand(serverVersion);
123130

124131
result.Should().Be(expectedResult);
125132
}

src/MongoDB.Driver.Core/Core/Operations/FindAndModifyOperationBase.cs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public abstract class FindAndModifyOperationBase<TResult> : IWriteOperation<TRes
3939
private readonly CollectionNamespace _collectionNamespace;
4040
private readonly MessageEncoderSettings _messageEncoderSettings;
4141
private readonly IBsonSerializer<TResult> _resultSerializer;
42+
private WriteConcern _writeConcern;
4243

4344
// constructors
4445
/// <summary>
@@ -88,29 +89,50 @@ public IBsonSerializer<TResult> ResultSerializer
8889
get { return _resultSerializer; }
8990
}
9091

92+
/// <summary>
93+
/// Gets or sets the write concern.
94+
/// </summary>
95+
public WriteConcern WriteConcern
96+
{
97+
get { return _writeConcern; }
98+
set { _writeConcern = value; }
99+
}
100+
91101
// public methods
92102
/// <inheritdoc/>
93103
public TResult Execute(IWriteBinding binding, CancellationToken cancellationToken)
94104
{
95105
Ensure.IsNotNull(binding, nameof(binding));
96-
var operation = CreateOperation();
97-
return operation.Execute(binding, cancellationToken);
106+
107+
using (var channelSource = binding.GetWriteChannelSource(cancellationToken))
108+
using (var channel = channelSource.GetChannel(cancellationToken))
109+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel))
110+
{
111+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
112+
return operation.Execute(channelBinding, cancellationToken);
113+
}
98114
}
99115

100116
/// <inheritdoc/>
101-
public Task<TResult> ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
117+
public async Task<TResult> ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
102118
{
103119
Ensure.IsNotNull(binding, nameof(binding));
104-
var operation = CreateOperation();
105-
return operation.ExecuteAsync(binding, cancellationToken);
120+
121+
using (var channelSource = await binding.GetWriteChannelSourceAsync(cancellationToken).ConfigureAwait(false))
122+
using (var channel = await channelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false))
123+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel))
124+
{
125+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
126+
return await operation.ExecuteAsync(channelBinding, cancellationToken).ConfigureAwait(false);
127+
}
106128
}
107129

108130
// private methods
109-
internal abstract BsonDocument CreateCommand();
131+
internal abstract BsonDocument CreateCommand(SemanticVersion serverVersion);
110132

111-
private WriteCommandOperation<TResult> CreateOperation()
133+
private WriteCommandOperation<TResult> CreateOperation(SemanticVersion serverVersion)
112134
{
113-
var command = CreateCommand();
135+
var command = CreateCommand(serverVersion);
114136
return new WriteCommandOperation<TResult>(_collectionNamespace.DatabaseNamespace, command, _resultSerializer, _messageEncoderSettings)
115137
{
116138
CommandValidator = GetCommandValidator()

src/MongoDB.Driver.Core/Core/Operations/FindOneAndDeleteOperation.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public BsonDocument Sort
102102
}
103103

104104
// methods
105-
internal override BsonDocument CreateCommand()
105+
internal override BsonDocument CreateCommand(SemanticVersion serverVersion)
106106
{
107107
return new BsonDocument
108108
{
@@ -111,7 +111,8 @@ internal override BsonDocument CreateCommand()
111111
{ "sort", _sort, _sort != null },
112112
{ "remove", true },
113113
{ "fields", _projection, _projection != null },
114-
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue }
114+
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
115+
{ "writeConcern", () => WriteConcern.ToBsonDocument(), WriteConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
115116
};
116117
}
117118

src/MongoDB.Driver.Core/Core/Operations/FindOneAndReplaceOperation.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public BsonDocument Sort
144144
}
145145

146146
// methods
147-
internal override BsonDocument CreateCommand()
147+
internal override BsonDocument CreateCommand(SemanticVersion serverVersion)
148148
{
149149
return new BsonDocument
150150
{
@@ -155,7 +155,8 @@ internal override BsonDocument CreateCommand()
155155
{ "new", _returnDocument == ReturnDocument.After },
156156
{ "fields", _projection, _projection != null },
157157
{ "upsert", _isUpsert },
158-
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue }
158+
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
159+
{ "writeConcern", () => WriteConcern.ToBsonDocument(), WriteConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
159160
};
160161
}
161162

src/MongoDB.Driver.Core/Core/Operations/FindOneAndUpdateOperation.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public BsonDocument Update
144144
}
145145

146146
// methods
147-
internal override BsonDocument CreateCommand()
147+
internal override BsonDocument CreateCommand(SemanticVersion serverVersion)
148148
{
149149
return new BsonDocument
150150
{
@@ -155,7 +155,8 @@ internal override BsonDocument CreateCommand()
155155
{ "new", _returnDocument == ReturnDocument.After },
156156
{ "fields", _projection, _projection != null },
157157
{ "upsert", _isUpsert },
158-
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue }
158+
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
159+
{ "writeConcern", () => WriteConcern.ToBsonDocument(), WriteConcern != null && serverVersion >= new SemanticVersion(3, 1, 1) }
159160
};
160161
}
161162

src/MongoDB.Driver/FindOneAndDeleteOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class FindOneAndDeleteOptions<TDocument, TProjection>
3333
private TimeSpan? _maxTime;
3434
private ProjectionDefinition<TDocument, TProjection> _projection;
3535
private SortDefinition<TDocument> _sort;
36+
private WriteConcern _writeConcern;
3637

3738
// properties
3839
/// <summary>
@@ -61,6 +62,15 @@ public SortDefinition<TDocument> Sort
6162
get { return _sort; }
6263
set { _sort = value; }
6364
}
65+
66+
/// <summary>
67+
/// Gets or sets the write concern.
68+
/// </summary>
69+
public WriteConcern WriteConcern
70+
{
71+
get { return _writeConcern; }
72+
set { _writeConcern = value; }
73+
}
6474
}
6575

6676
/// <summary>

src/MongoDB.Driver/FindOneAndReplaceOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class FindOneAndReplaceOptions<TDocument, TProjection>
3535
private ProjectionDefinition<TDocument, TProjection> _projection;
3636
private ReturnDocument _returnDocument;
3737
private SortDefinition<TDocument> _sort;
38+
private WriteConcern _writeConcern;
3839

3940
// constructors
4041
/// <summary>
@@ -90,6 +91,15 @@ public SortDefinition<TDocument> Sort
9091
get { return _sort; }
9192
set { _sort = value; }
9293
}
94+
95+
/// <summary>
96+
/// Gets or sets the write concern.
97+
/// </summary>
98+
public WriteConcern WriteConcern
99+
{
100+
get { return _writeConcern; }
101+
set { _writeConcern = value; }
102+
}
93103
}
94104

95105
/// <summary>

src/MongoDB.Driver/FindOneAndUpdateOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class FindOneAndUpdateOptions<TDocument, TProjection>
3535
private ProjectionDefinition<TDocument, TProjection> _projection;
3636
private ReturnDocument _returnDocument;
3737
private SortDefinition<TDocument> _sort;
38+
private WriteConcern _writeConcern;
3839

3940
// constructors
4041
/// <summary>
@@ -90,6 +91,15 @@ public SortDefinition<TDocument> Sort
9091
get { return _sort; }
9192
set { _sort = value; }
9293
}
94+
95+
/// <summary>
96+
/// Gets or sets the write concern.
97+
/// </summary>
98+
public WriteConcern WriteConcern
99+
{
100+
get { return _writeConcern; }
101+
set { _writeConcern = value; }
102+
}
93103
}
94104

95105
/// <summary>

0 commit comments

Comments
 (0)