Skip to content

Commit 3e65a36

Browse files
committed
CSHARP-1706: Support collations.
1 parent 8a7bedc commit 3e65a36

File tree

84 files changed

+1833
-268
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1833
-268
lines changed

src/MongoDB.Driver.Core/Collation.cs

Lines changed: 498 additions & 0 deletions
Large diffs are not rendered by default.

src/MongoDB.Driver.Core/Core/Misc/SupportedFeatures.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2015 MongoDB Inc.
1+
/* Copyright 2015-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ internal static class SupportedFeatures
2424
private static readonly SemanticVersion __versionSupportingAggregateCursorResult = new SemanticVersion(2, 6, 0);
2525
private static readonly SemanticVersion __versionSupportingAggregateOut = new SemanticVersion(2, 6, 0);
2626
private static readonly SemanticVersion __versionSupportingBypassDocumentValidation = new SemanticVersion(3, 1, 3);
27+
private static readonly SemanticVersion __versionSupportingCollation = new SemanticVersion(3, 3, 11);
2728
private static readonly SemanticVersion __versionSupportingCreateIndexesCommand = new SemanticVersion(2, 7, 6);
2829
private static readonly SemanticVersion __versionSupportingCurrentOpCommand = new SemanticVersion(3, 1, 2);
2930
private static readonly SemanticVersion __versionSupportingFailPoints = new SemanticVersion(2, 4, 0);
@@ -98,6 +99,16 @@ public static bool IsBypassDocumentValidationSupported(SemanticVersion serverVer
9899
return serverVersion >= __versionSupportingBypassDocumentValidation;
99100
}
100101

102+
/// <summary>
103+
/// Determines whether Collation is supported.
104+
/// </summary>
105+
/// <param name="serverVersion">The server version.</param>
106+
/// <returns>True if Collation is supported.</returns>
107+
public static bool IsCollationSupported(SemanticVersion serverVersion)
108+
{
109+
return serverVersion >= __versionSupportingCollation;
110+
}
111+
101112
/// <summary>
102113
/// Determines whether the CreateIndexes command is supported.
103114
/// </summary>

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

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2015 MongoDB Inc.
1+
/* Copyright 2013-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@ public class AggregateExplainOperation : IReadOperation<BsonDocument>
3333
{
3434
// fields
3535
private bool? _allowDiskUse;
36+
private Collation _collation;
3637
private CollectionNamespace _collectionNamespace;
3738
private TimeSpan? _maxTime;
3839
private MessageEncoderSettings _messageEncoderSettings;
@@ -65,6 +66,18 @@ public bool? AllowDiskUse
6566
set { _allowDiskUse = value; }
6667
}
6768

69+
/// <summary>
70+
/// Gets or sets the collation.
71+
/// </summary>
72+
/// <value>
73+
/// The collation.
74+
/// </value>
75+
public Collation Collation
76+
{
77+
get { return _collation; }
78+
set { _collation = value; }
79+
}
80+
6881
/// <summary>
6982
/// Gets the collection namespace.
7083
/// </summary>
@@ -111,35 +124,51 @@ public IReadOnlyList<BsonDocument> Pipeline
111124
}
112125

113126
// methods
114-
internal BsonDocument CreateCommand()
127+
internal BsonDocument CreateCommand(SemanticVersion serverVersion)
115128
{
129+
if (_collation != null && !SupportedFeatures.IsCollationSupported(serverVersion))
130+
{
131+
throw new NotSupportedException($"Server version {serverVersion} does not support collations.");
132+
}
133+
116134
return new BsonDocument
117135
{
118136
{ "aggregate", _collectionNamespace.CollectionName },
119137
{ "explain", true },
120138
{ "pipeline", new BsonArray(_pipeline) },
121139
{ "allowDiskUse", () => _allowDiskUse.Value, _allowDiskUse.HasValue },
122-
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue }
140+
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
141+
{ "collation", () => _collation.ToBsonDocument(), _collation != null }
123142
};
124143
}
125144

126145
/// <inheritdoc/>
127146
public BsonDocument Execute(IReadBinding binding, CancellationToken cancellationToken)
128147
{
129-
var operation = CreateOperation();
130-
return operation.Execute(binding, cancellationToken);
148+
using (var channelSource = binding.GetReadChannelSource(cancellationToken))
149+
using (var channel = channelSource.GetChannel(cancellationToken))
150+
using (var channelBinding = new ChannelReadBinding(channelSource.Server, channel, binding.ReadPreference))
151+
{
152+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
153+
return operation.Execute(channelBinding, cancellationToken);
154+
}
131155
}
132156

133157
/// <inheritdoc/>
134-
public Task<BsonDocument> ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
158+
public async Task<BsonDocument> ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
135159
{
136-
var operation = CreateOperation();
137-
return operation.ExecuteAsync(binding, cancellationToken);
160+
using (var channelSource = await binding.GetReadChannelSourceAsync(cancellationToken).ConfigureAwait(false))
161+
using (var channel = await channelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false))
162+
using (var channelBinding = new ChannelReadBinding(channelSource.Server, channel, binding.ReadPreference))
163+
{
164+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
165+
return await operation.ExecuteAsync(channelBinding, cancellationToken).ConfigureAwait(false);
166+
}
138167
}
139168

140-
private ReadCommandOperation<BsonDocument> CreateOperation()
169+
private ReadCommandOperation<BsonDocument> CreateOperation(SemanticVersion serverVersion)
141170
{
142-
var command = CreateCommand();
171+
var command = CreateCommand(serverVersion);
143172
return new ReadCommandOperation<BsonDocument>(
144173
_collectionNamespace.DatabaseNamespace,
145174
command,

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2015 MongoDB Inc.
1+
/* Copyright 2013-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ public class AggregateOperation<TResult> : IReadOperation<IAsyncCursor<TResult>>
3838
// fields
3939
private bool? _allowDiskUse;
4040
private int? _batchSize;
41+
private Collation _collation;
4142
private readonly CollectionNamespace _collectionNamespace;
4243
private TimeSpan? _maxTime;
4344
private readonly MessageEncoderSettings _messageEncoderSettings;
@@ -87,6 +88,15 @@ public int? BatchSize
8788
set { _batchSize = Ensure.IsNullOrGreaterThanOrEqualToZero(value, nameof(value)); }
8889
}
8990

91+
/// <summary>
92+
/// Gets or sets the collation.
93+
/// </summary>
94+
public Collation Collation
95+
{
96+
get { return _collation; }
97+
set { _collation = value; }
98+
}
99+
90100
/// <summary>
91101
/// Gets the collection namespace.
92102
/// </summary>
@@ -212,21 +222,27 @@ public IReadOperation<BsonDocument> ToExplainOperation(ExplainVerbosity verbosit
212222
return new AggregateExplainOperation(_collectionNamespace, _pipeline, _messageEncoderSettings)
213223
{
214224
AllowDiskUse = _allowDiskUse,
225+
Collation = _collation,
215226
MaxTime = _maxTime
216227
};
217228
}
218229

219230
internal BsonDocument CreateCommand(SemanticVersion serverVersion)
220231
{
221232
_readConcern.ThrowIfNotSupported(serverVersion);
233+
if (_collation != null && !SupportedFeatures.IsCollationSupported(serverVersion))
234+
{
235+
throw new NotSupportedException($"Server version {serverVersion} does not support collations.");
236+
}
222237

223238
var command = new BsonDocument
224239
{
225240
{ "aggregate", _collectionNamespace.CollectionName },
226241
{ "pipeline", new BsonArray(_pipeline) },
227242
{ "allowDiskUse", () => _allowDiskUse.Value, _allowDiskUse.HasValue },
228243
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
229-
{ "readConcern", () => _readConcern.ToBsonDocument(), !_readConcern.IsServerDefault }
244+
{ "readConcern", () => _readConcern.ToBsonDocument(), !_readConcern.IsServerDefault },
245+
{ "collation", () => _collation.ToBsonDocument(), _collation != null }
230246
};
231247

232248
if (SupportedFeatures.IsAggregateCursorResultSupported(serverVersion) && _useCursor.GetValueOrDefault(true))

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013-2015 MongoDB Inc.
1+
/* Copyright 2013-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ public class AggregateToCollectionOperation : IWriteOperation<BsonDocument>
3434
// fields
3535
private bool? _allowDiskUse;
3636
private bool? _bypassDocumentValidation;
37+
private Collation _collation;
3738
private readonly CollectionNamespace _collectionNamespace;
3839
private TimeSpan? _maxTime;
3940
private readonly MessageEncoderSettings _messageEncoderSettings;
@@ -80,6 +81,18 @@ public bool? BypassDocumentValidation
8081
set { _bypassDocumentValidation = value; }
8182
}
8283

84+
/// <summary>
85+
/// Gets or sets the collation.
86+
/// </summary>
87+
/// <value>
88+
/// The collation.
89+
/// </value>
90+
public Collation Collation
91+
{
92+
get { return _collation; }
93+
set { _collation = value; }
94+
}
95+
8396
/// <summary>
8497
/// Gets the collection namespace.
8598
/// </summary>
@@ -156,13 +169,19 @@ public async Task<BsonDocument> ExecuteAsync(IWriteBinding binding, Cancellation
156169

157170
internal BsonDocument CreateCommand(SemanticVersion serverVersion)
158171
{
172+
if (_collation != null && !SupportedFeatures.IsCollationSupported(serverVersion))
173+
{
174+
throw new NotSupportedException($"Server version {serverVersion} does not support collations.");
175+
}
176+
159177
return new BsonDocument
160178
{
161179
{ "aggregate", _collectionNamespace.CollectionName },
162180
{ "pipeline", new BsonArray(_pipeline) },
163181
{ "allowDiskUse", () => _allowDiskUse.Value, _allowDiskUse.HasValue },
164182
{ "bypassDocumentValidation", () => _bypassDocumentValidation.Value, _bypassDocumentValidation.HasValue && SupportedFeatures.IsBypassDocumentValidationSupported(serverVersion) },
165-
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue }
183+
{ "maxTimeMS", () => _maxTime.Value.TotalMilliseconds, _maxTime.HasValue },
184+
{ "collation", () => _collation.ToBsonDocument(), _collation != null }
166185
};
167186
}
168187

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-2014 MongoDB Inc.
1+
/* Copyright 2010-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -13,10 +13,14 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System;
1617
using System.Collections.Generic;
1718
using System.Linq;
1819
using MongoDB.Bson.IO;
1920
using MongoDB.Bson.Serialization;
21+
using MongoDB.Bson.Serialization.Serializers;
22+
using MongoDB.Driver.Core.Connections;
23+
using MongoDB.Driver.Core.Misc;
2024
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
2125

2226
namespace MongoDB.Driver.Core.Operations
@@ -49,9 +53,9 @@ protected override string RequestsElementName
4953
}
5054

5155
// methods
52-
protected override BatchSerializer CreateBatchSerializer(int maxBatchCount, int maxBatchLength, int maxDocumentSize, int maxWireDocumentSize)
56+
protected override BatchSerializer CreateBatchSerializer(ConnectionDescription connectionDescription, int maxBatchCount, int maxBatchLength)
5357
{
54-
return new DeleteBatchSerializer(maxBatchCount, maxBatchLength, maxDocumentSize, maxWireDocumentSize);
58+
return new DeleteBatchSerializer(connectionDescription, maxBatchCount, maxBatchLength);
5559
}
5660

5761
protected override BulkUnmixedWriteOperationEmulatorBase CreateEmulator()
@@ -69,21 +73,31 @@ protected override BulkUnmixedWriteOperationEmulatorBase CreateEmulator()
6973
private class DeleteBatchSerializer : BatchSerializer
7074
{
7175
// constructors
72-
public DeleteBatchSerializer(int maxBatchCount, int maxBatchLength, int maxDocumentSize, int maxWireDocumentSize)
73-
: base(maxBatchCount, maxBatchLength, maxDocumentSize, maxWireDocumentSize)
76+
public DeleteBatchSerializer(ConnectionDescription connectionDescription, int maxBatchCount, int maxBatchLength)
77+
: base(connectionDescription, maxBatchCount, maxBatchLength)
7478
{
7579
}
7680

7781
// methods
7882
protected override void SerializeRequest(BsonSerializationContext context, WriteRequest request)
7983
{
8084
var deleteRequest = (DeleteRequest)request;
85+
if (deleteRequest.Collation != null && !SupportedFeatures.IsCollationSupported(ConnectionDescription.ServerVersion))
86+
{
87+
throw new NotSupportedException($"Server version {ConnectionDescription.ServerVersion} does not support collations.");
88+
}
89+
8190
var bsonWriter = (BsonBinaryWriter)context.Writer;
82-
bsonWriter.PushMaxDocumentSize(MaxDocumentSize);
91+
bsonWriter.PushMaxDocumentSize(ConnectionDescription.MaxDocumentSize);
8392
bsonWriter.WriteStartDocument();
8493
bsonWriter.WriteName("q");
8594
BsonSerializer.Serialize(bsonWriter, deleteRequest.Filter);
8695
bsonWriter.WriteInt32("limit", deleteRequest.Limit);
96+
if (deleteRequest.Collation != null)
97+
{
98+
bsonWriter.WriteName("collation");
99+
BsonDocumentSerializer.Instance.Serialize(context, deleteRequest.Collation.ToBsonDocument());
100+
}
87101
bsonWriter.WriteEndDocument();
88102
bsonWriter.PopMaxDocumentSize();
89103
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-2014 MongoDB Inc.
1+
/* Copyright 2010-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System;
1617
using System.Collections.Generic;
1718
using System.Threading;
1819
using System.Threading.Tasks;
@@ -37,6 +38,10 @@ public BulkDeleteOperationEmulator(
3738
protected override WriteConcernResult ExecuteProtocol(IChannelHandle channel, WriteRequest request, CancellationToken cancellationToken)
3839
{
3940
var deleteRequest = (DeleteRequest)request;
41+
if (deleteRequest.Collation != null)
42+
{
43+
throw new NotSupportedException("OP_DELETE does not support collations.");
44+
}
4045
var isMulti = deleteRequest.Limit == 0;
4146

4247
return channel.Delete(
@@ -52,6 +57,10 @@ protected override Task<WriteConcernResult> ExecuteProtocolAsync(IChannelHandle
5257
{
5358
var deleteRequest = (DeleteRequest)request;
5459
var isMulti = deleteRequest.Limit == 0;
60+
if (deleteRequest.Collation != null)
61+
{
62+
throw new NotSupportedException("OP_DELETE does not support collations.");
63+
}
5564

5665
return channel.DeleteAsync(
5766
CollectionNamespace,

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-2014 MongoDB Inc.
1+
/* Copyright 2010-2016 MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
using MongoDB.Bson.Serialization.Options;
2626
using MongoDB.Bson.Serialization.Serializers;
2727
using MongoDB.Driver.Core.Bindings;
28+
using MongoDB.Driver.Core.Connections;
2829
using MongoDB.Driver.Core.Misc;
2930
using MongoDB.Driver.Core.Operations.ElementNameValidators;
3031
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
@@ -59,11 +60,11 @@ protected override string RequestsElementName
5960
}
6061

6162
// methods
62-
protected override BatchSerializer CreateBatchSerializer(int maxBatchCount, int maxBatchLength, int maxDocumentSize, int maxWireDocumentSize)
63+
protected override BatchSerializer CreateBatchSerializer(ConnectionDescription connectionDescription, int maxBatchCount, int maxBatchLength)
6364
{
6465
var isSystemIndexesCollection = CollectionNamespace.Equals(CollectionNamespace.DatabaseNamespace.SystemIndexesCollection);
6566
var elementNameValidator = isSystemIndexesCollection ? (IElementNameValidator)NoOpElementNameValidator.Instance : CollectionElementNameValidator.Instance;
66-
return new InsertBatchSerializer(maxBatchCount, maxBatchLength, maxDocumentSize, maxWireDocumentSize, elementNameValidator);
67+
return new InsertBatchSerializer(connectionDescription, maxBatchCount, maxBatchLength, elementNameValidator);
6768
}
6869

6970
protected override BulkUnmixedWriteOperationEmulatorBase CreateEmulator()
@@ -86,8 +87,8 @@ private class InsertBatchSerializer : BatchSerializer
8687
private IElementNameValidator _elementNameValidator;
8788

8889
// constructors
89-
public InsertBatchSerializer(int maxBatchCount, int maxBatchLength, int maxDocumentSize, int maxWireDocumentSize, IElementNameValidator elementNameValidator)
90-
: base(maxBatchCount, maxBatchLength, maxDocumentSize, maxWireDocumentSize)
90+
public InsertBatchSerializer(ConnectionDescription connectionDescription, int maxBatchCount, int maxBatchLength, IElementNameValidator elementNameValidator)
91+
: base(connectionDescription, maxBatchCount, maxBatchLength)
9192
{
9293
_elementNameValidator = elementNameValidator;
9394
}
@@ -108,7 +109,7 @@ protected override void SerializeRequest(BsonSerializationContext context, Write
108109
var serializer = _cachedSerializer;
109110

110111
var bsonWriter = (BsonBinaryWriter)context.Writer;
111-
bsonWriter.PushMaxDocumentSize(MaxDocumentSize);
112+
bsonWriter.PushMaxDocumentSize(ConnectionDescription.MaxDocumentSize);
112113
bsonWriter.PushElementNameValidator(_elementNameValidator);
113114
try
114115
{

0 commit comments

Comments
 (0)