Skip to content

Commit b252bcc

Browse files
author
rstam
committed
Merge Craig and Robert's work around CommandResults.
1 parent b46c8db commit b252bcc

File tree

5 files changed

+128
-40
lines changed

5 files changed

+128
-40
lines changed

MongoDB.Driver/CommandResults/DistinctCommandResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace MongoDB.Driver
2828
public class DistinctCommandResult<TValue> : CommandResult
2929
{
3030
// private fields
31-
private IEnumerable<TValue> _values;
31+
private readonly IEnumerable<TValue> _values;
3232

3333
// constructors
3434
/// <summary>

MongoDB.Driver/CommandResults/DistinctCommandResultSerializer.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,30 @@ namespace MongoDB.Driver
2929
/// <typeparam name="TValue">The type of the value.</typeparam>
3030
public class DistinctCommandResultSerializer<TValue> : BsonBaseSerializer
3131
{
32+
// private fields
33+
private readonly IBsonSerializer _valueSerializer;
34+
private readonly IBsonSerializationOptions _valueSerializationOptions;
35+
36+
// constructors
37+
/// <summary>
38+
/// Initializes a new instance of the <see cref="DistinctCommandResultSerializer{TValue}"/> class.
39+
/// </summary>
40+
public DistinctCommandResultSerializer()
41+
: this(BsonSerializer.LookupSerializer(typeof(TValue)), null)
42+
{
43+
}
44+
45+
/// <summary>
46+
/// Initializes a new instance of the <see cref="DistinctCommandResultSerializer{TValue}"/> class.
47+
/// </summary>
48+
/// <param name="valueSerializer">The value serializer.</param>
49+
/// <param name="valueSerializationOptions">The value serialization options.</param>
50+
public DistinctCommandResultSerializer(IBsonSerializer valueSerializer, IBsonSerializationOptions valueSerializationOptions)
51+
{
52+
_valueSerializer = valueSerializer;
53+
_valueSerializationOptions = valueSerializationOptions;
54+
}
55+
3256
/// <summary>
3357
/// Deserializes an object from a BsonReader.
3458
/// </summary>
@@ -50,8 +74,7 @@ public override object Deserialize(BsonReader bsonReader, Type nominalType, Type
5074
var name = bsonReader.ReadName();
5175
if (name == "values")
5276
{
53-
var enumerableSerializer = new EnumerableSerializer<TValue>();
54-
values = (IEnumerable<TValue>)enumerableSerializer.Deserialize(bsonReader, typeof(List<TValue>), null);
77+
values = ReadValues(bsonReader);
5578
}
5679
else
5780
{
@@ -63,5 +86,20 @@ public override object Deserialize(BsonReader bsonReader, Type nominalType, Type
6386

6487
return new DistinctCommandResult<TValue>(response, values);
6588
}
89+
90+
// private methods
91+
private IEnumerable<TValue> ReadValues(BsonReader bsonReader)
92+
{
93+
var values = new List<TValue>();
94+
95+
bsonReader.ReadStartArray();
96+
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
97+
{
98+
values.Add((TValue)_valueSerializer.Deserialize(bsonReader, typeof(TValue), _valueSerializationOptions));
99+
}
100+
bsonReader.ReadEndArray();
101+
102+
return values;
103+
}
66104
}
67105
}

MongoDB.Driver/Communication/MongoConnection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ internal TCommandResult RunCommandAs<TCommandResult>(
287287
var message = string.Format("Command '{0}' failed. No response returned.", commandName);
288288
throw new MongoCommandException(message);
289289
}
290+
290291
var commandResult = reply.Documents[0];
291292
commandResult.Command = command;
292293

@@ -390,8 +391,7 @@ internal WriteConcernResult SendMessage(BsonBuffer buffer, MongoRequestMessage m
390391
MaxDocumentSize = _serverInstance.MaxDocumentSize
391392
};
392393
var writeConcernResultSerializer = BsonSerializer.LookupSerializer(typeof(WriteConcernResult));
393-
IBsonSerializationOptions writeConcernSerializationOptions = null;
394-
var replyMessage = ReceiveMessage<WriteConcernResult>(readerSettings, writeConcernResultSerializer, writeConcernSerializationOptions);
394+
var replyMessage = ReceiveMessage<WriteConcernResult>(readerSettings, writeConcernResultSerializer, null);
395395
writeConcernResult = replyMessage.Documents[0];
396396
writeConcernResult.Command = getLastErrorCommand;
397397
if (!writeConcernResult.Ok)

MongoDB.Driver/MongoCollection.cs

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using MongoDB.Driver.Builders;
2525
using MongoDB.Driver.Internal;
2626
using MongoDB.Driver.Wrappers;
27+
using MongoDB.Bson.Serialization.Serializers;
2728

2829
namespace MongoDB.Driver
2930
{
@@ -246,14 +247,7 @@ public virtual IEnumerable<BsonValue> Distinct(string key)
246247
/// <returns>The distint values of the field.</returns>
247248
public virtual IEnumerable<BsonValue> Distinct(string key, IMongoQuery query)
248249
{
249-
var command = new CommandDocument
250-
{
251-
{ "distinct", _name },
252-
{ "key", key },
253-
{ "query", BsonDocumentWrapper.Create(query), query != null } // query is optional
254-
};
255-
var result = RunCommand(command);
256-
return result.Response["values"].AsBsonArray;
250+
return Distinct<BsonValue>(key, query, BsonValueSerializer.Instance, null);
257251
}
258252

259253
/// <summary>
@@ -276,14 +270,8 @@ public virtual IEnumerable<TValue> Distinct<TValue>(string key)
276270
/// <returns>The distint values of the field.</returns>
277271
public virtual IEnumerable<TValue> Distinct<TValue>(string key, IMongoQuery query)
278272
{
279-
var command = new CommandDocument
280-
{
281-
{ "distinct", _name },
282-
{ "key", key },
283-
{ "query", BsonDocumentWrapper.Create(query), query != null } // query is optional
284-
};
285-
var result = RunCommandAs<DistinctCommandResult<TValue>>(command);
286-
return result.Values;
273+
var valueSerializer = BsonSerializer.LookupSerializer(typeof(TValue));
274+
return Distinct<TValue>(key, query, valueSerializer, null);
287275
}
288276

289277
/// <summary>
@@ -570,7 +558,7 @@ public virtual FindAndModifyResult FindAndRemove(IMongoQuery query, IMongoSortBy
570558
public virtual MongoCursor<TDocument> FindAs<TDocument>(IMongoQuery query)
571559
{
572560
var serializer = BsonSerializer.LookupSerializer(typeof(TDocument));
573-
return new MongoCursor<TDocument>(this, query, _settings.ReadPreference, serializer);
561+
return FindAs<TDocument>(query, serializer, null);
574562
}
575563

576564
/// <summary>
@@ -582,7 +570,7 @@ public virtual MongoCursor<TDocument> FindAs<TDocument>(IMongoQuery query)
582570
public virtual MongoCursor FindAs(Type documentType, IMongoQuery query)
583571
{
584572
var serializer = BsonSerializer.LookupSerializer(documentType);
585-
return MongoCursor.Create(documentType, this, query, _settings.ReadPreference, serializer);
573+
return FindAs(documentType, query, serializer, null);
586574
}
587575

588576
/// <summary>
@@ -1702,12 +1690,24 @@ internal TCommandResult RunCommandAs<TCommandResult>(IMongoCommand command)
17021690
return (TCommandResult)RunCommandAs(typeof(TCommandResult), command);
17031691
}
17041692

1693+
internal TCommandResult RunCommandAs<TCommandResult>(IMongoCommand command, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
1694+
where TCommandResult : CommandResult
1695+
{
1696+
return (TCommandResult)RunCommandAs(typeof(TCommandResult), command, serializer, serializationOptions);
1697+
}
1698+
17051699
internal CommandResult RunCommandAs(Type commandResultType, IMongoCommand command)
1700+
{
1701+
var commandResultSerializer = BsonSerializer.LookupSerializer(commandResultType);
1702+
return RunCommandAs(commandResultType, command, commandResultSerializer, null);
1703+
}
1704+
1705+
internal CommandResult RunCommandAs(Type commandResultType, IMongoCommand command, IBsonSerializer commandResultSerializer, IBsonSerializationOptions commandResultSerializationOptions)
17061706
{
17071707
// if necessary delegate running the command to the _commandCollection
17081708
if (_name == "$cmd")
17091709
{
1710-
var commandResult = (CommandResult)FindOneAs(commandResultType, command);
1710+
var commandResult = (CommandResult)FindOneAs(commandResultType, command, commandResultSerializer, commandResultSerializationOptions);
17111711
if (commandResult == null)
17121712
{
17131713
var commandName = command.ToBsonDocument().GetElement(0).Name;
@@ -1729,11 +1729,48 @@ internal CommandResult RunCommandAs(Type commandResultType, IMongoCommand comman
17291729
}
17301730
else
17311731
{
1732-
return _commandCollection.RunCommandAs(commandResultType, command);
1732+
return _commandCollection.RunCommandAs(commandResultType, command, commandResultSerializer, commandResultSerializationOptions);
17331733
}
17341734
}
17351735

17361736
// private methods
1737+
private IEnumerable<TValue> Distinct<TValue>(
1738+
string key,
1739+
IMongoQuery query,
1740+
IBsonSerializer valueSerializer,
1741+
IBsonSerializationOptions valueSerializationOptions)
1742+
{
1743+
var command = new CommandDocument
1744+
{
1745+
{ "distinct", _name },
1746+
{ "key", key },
1747+
{ "query", BsonDocumentWrapper.Create(query), query != null } // query is optional
1748+
};
1749+
var resultSerializer = new DistinctCommandResultSerializer<TValue>(valueSerializer, valueSerializationOptions);
1750+
var result = RunCommandAs<DistinctCommandResult<TValue>>(command, resultSerializer, null);
1751+
return result.Values;
1752+
}
1753+
1754+
private MongoCursor FindAs(Type documentType, IMongoQuery query, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
1755+
{
1756+
return MongoCursor.Create(documentType, this, query, _settings.ReadPreference, serializer, serializationOptions);
1757+
}
1758+
1759+
private MongoCursor<TDocument> FindAs<TDocument>(IMongoQuery query, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
1760+
{
1761+
return new MongoCursor<TDocument>(this, query, _settings.ReadPreference, serializer, serializationOptions);
1762+
}
1763+
1764+
private CommandResult FindOneAs(Type documentType, IMongoQuery query, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
1765+
{
1766+
return FindAs(documentType, query, serializer, serializationOptions).SetLimit(1).Cast<CommandResult>().FirstOrDefault();
1767+
}
1768+
1769+
private TDocument FindOneAs<TDocument>(IMongoQuery query, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
1770+
{
1771+
return FindAs<TDocument>(query, serializer, serializationOptions).SetLimit(1).FirstOrDefault();
1772+
}
1773+
17371774
private string GetIndexName(BsonDocument keys, BsonDocument options)
17381775
{
17391776
if (options != null)

MongoDB.Driver/MongoCursor.cs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ public abstract class MongoCursor : IEnumerable
5454
/// <param name="query">The query.</param>
5555
/// <param name="readPreference">The read preference.</param>
5656
/// <param name="serializer">The serializer.</param>
57-
protected MongoCursor(MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer)
57+
/// <param name="serializationOptions">The serialization options.</param>
58+
protected MongoCursor(MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
5859
{
5960
_collection = collection;
6061
_database = collection.Database;
6162
_server = collection.Database.Server;
6263
_query = query;
6364
_serializer = serializer;
65+
_serializationOptions = serializationOptions;
6466
_readPreference = readPreference;
6567
}
6668

@@ -254,13 +256,16 @@ public virtual bool IsFrozen
254256
/// <param name="query">A query.</param>
255257
/// <param name="readPreference">The read preference.</param>
256258
/// <param name="serializer">The serializer.</param>
257-
/// <returns>A cursor.</returns>
258-
public static MongoCursor Create(Type documentType, MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer)
259+
/// <param name="serializationOptions">The serialization options.</param>
260+
/// <returns>
261+
/// A cursor.
262+
/// </returns>
263+
public static MongoCursor Create(Type documentType, MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
259264
{
260265
var cursorDefinition = typeof(MongoCursor<>);
261266
var cursorType = cursorDefinition.MakeGenericType(documentType);
262-
var constructorInfo = cursorType.GetConstructor(new Type[] { typeof(MongoCollection), typeof(IMongoQuery), typeof(ReadPreference), typeof(IBsonSerializer)});
263-
return (MongoCursor)constructorInfo.Invoke(new object[] { collection, query, readPreference, serializer });
267+
var constructorInfo = cursorType.GetConstructor(new Type[] { typeof(MongoCollection), typeof(IMongoQuery), typeof(ReadPreference), typeof(IBsonSerializer), typeof(IBsonSerializationOptions)});
268+
return (MongoCursor)constructorInfo.Invoke(new object[] { collection, query, readPreference, serializer, serializationOptions });
264269
}
265270

266271
// public methods
@@ -279,10 +284,13 @@ public virtual MongoCursor<TDocument> Clone<TDocument>()
279284
/// </summary>
280285
/// <typeparam name="TDocument">The type of the documents returned.</typeparam>
281286
/// <param name="serializer">The serializer to use.</param>
282-
/// <returns>A clone of the cursor.</returns>
283-
public virtual MongoCursor<TDocument> Clone<TDocument>(IBsonSerializer serializer)
287+
/// <param name="serializationOptions">The serialization options.</param>
288+
/// <returns>
289+
/// A clone of the cursor.
290+
/// </returns>
291+
public virtual MongoCursor<TDocument> Clone<TDocument>(IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
284292
{
285-
return (MongoCursor<TDocument>)Clone(typeof(TDocument), serializer);
293+
return (MongoCursor<TDocument>)Clone(typeof(TDocument), serializer, serializationOptions);
286294
}
287295

288296
/// <summary>
@@ -292,18 +300,22 @@ public virtual MongoCursor<TDocument> Clone<TDocument>(IBsonSerializer serialize
292300
/// <returns>A clone of the cursor.</returns>
293301
public virtual MongoCursor Clone(Type documentType)
294302
{
295-
return Clone(documentType, _serializer);
303+
var serializer = BsonSerializer.LookupSerializer(documentType);
304+
return Clone(documentType, serializer, null);
296305
}
297306

298307
/// <summary>
299308
/// Creates a clone of the cursor.
300309
/// </summary>
301310
/// <param name="documentType">The type of the documents returned.</param>
302311
/// <param name="serializer">The serializer to use.</param>
303-
/// <returns>A clone of the cursor.</returns>
304-
public virtual MongoCursor Clone(Type documentType, IBsonSerializer serializer)
312+
/// <param name="serializationOptions">The serialization options.</param>
313+
/// <returns>
314+
/// A clone of the cursor.
315+
/// </returns>
316+
public virtual MongoCursor Clone(Type documentType, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
305317
{
306-
var clone = Create(documentType, _collection, _query, _readPreference, serializer);
318+
var clone = Create(documentType, _collection, _query, _readPreference, serializer, serializationOptions);
307319
clone._options = _options == null ? null : (BsonDocument)_options.Clone();
308320
clone._flags = _flags;
309321
clone._skip = _skip;
@@ -347,7 +359,7 @@ public virtual BsonDocument Explain()
347359
public virtual BsonDocument Explain(bool verbose)
348360
{
349361
_isFrozen = true;
350-
var clone = Clone<BsonDocument>(BsonDocumentSerializer.Instance);
362+
var clone = Clone<BsonDocument>(BsonDocumentSerializer.Instance, null);
351363
clone.SetOption("$explain", true);
352364
clone._limit = -clone._limit; // TODO: should this be -1?
353365
var explanation = clone.FirstOrDefault();
@@ -683,8 +695,9 @@ public class MongoCursor<TDocument> : MongoCursor, IEnumerable<TDocument>
683695
/// <param name="query">The query.</param>
684696
/// <param name="readPreference">The read preference.</param>
685697
/// <param name="serializer">The serializer.</param>
686-
public MongoCursor(MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer)
687-
: base(collection, query, readPreference, serializer)
698+
/// <param name="serializationOptions">The serialization options.</param>
699+
public MongoCursor(MongoCollection collection, IMongoQuery query, ReadPreference readPreference, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
700+
: base(collection, query, readPreference, serializer, serializationOptions)
688701
{
689702
}
690703

0 commit comments

Comments
 (0)