Skip to content

Commit 169c616

Browse files
CSHARP-3980: Remove reliance on "$explain" modifier so FindOpcodeOperation can be removed.
1 parent c0f286b commit 169c616

File tree

12 files changed

+1006
-3973
lines changed

12 files changed

+1006
-3973
lines changed

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

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,34 @@
1919
using MongoDB.Bson;
2020
using MongoDB.Bson.Serialization.Serializers;
2121
using MongoDB.Driver.Core.Bindings;
22+
using MongoDB.Driver.Core.Connections;
2223
using MongoDB.Driver.Core.Misc;
2324
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
2425

2526
namespace MongoDB.Driver.Core.Operations
2627
{
28+
/// <summary>
29+
/// Represents an explainable operation.
30+
/// </summary>
31+
public interface IExplainableOperation
32+
{
33+
/// <summary>
34+
/// Creates the command to be explained.
35+
/// </summary>
36+
/// <param name="connectionDescription">The connection description.</param>
37+
/// <param name="session">The session.</param>
38+
/// <returns>The command.</returns>
39+
BsonDocument CreateCommand(ConnectionDescription connectionDescription, ICoreSession session);
40+
}
41+
2742
/// <summary>
2843
/// Represents an explain operation.
2944
/// </summary>
3045
public class ExplainOperation : IReadOperation<BsonDocument>, IWriteOperation<BsonDocument>
3146
{
3247
// fields
3348
private readonly DatabaseNamespace _databaseNamespace;
34-
private readonly BsonDocument _command;
49+
private readonly IExplainableOperation _explainableOperation;
3550
private readonly MessageEncoderSettings _messageEncoderSettings;
3651
private ExplainVerbosity _verbosity;
3752

@@ -40,12 +55,12 @@ public class ExplainOperation : IReadOperation<BsonDocument>, IWriteOperation<Bs
4055
/// Initializes a new instance of the <see cref="ExplainOperation"/> class.
4156
/// </summary>
4257
/// <param name="databaseNamespace">The database namespace.</param>
43-
/// <param name="command">The command.</param>
58+
/// <param name="explainableOperation">The explainable operation.</param>
4459
/// <param name="messageEncoderSettings">The message encoder settings.</param>
45-
public ExplainOperation(DatabaseNamespace databaseNamespace, BsonDocument command, MessageEncoderSettings messageEncoderSettings)
60+
public ExplainOperation(DatabaseNamespace databaseNamespace, IExplainableOperation explainableOperation, MessageEncoderSettings messageEncoderSettings)
4661
{
4762
_databaseNamespace = Ensure.IsNotNull(databaseNamespace, nameof(databaseNamespace));
48-
_command = Ensure.IsNotNull(command, nameof(command));
63+
_explainableOperation = Ensure.IsNotNull(explainableOperation, nameof(explainableOperation));
4964
_messageEncoderSettings = Ensure.IsNotNull(messageEncoderSettings, nameof(messageEncoderSettings));
5065
_verbosity = ExplainVerbosity.QueryPlanner;
5166
}
@@ -63,14 +78,14 @@ public DatabaseNamespace DatabaseNamespace
6378
}
6479

6580
/// <summary>
66-
/// Gets the command to be explained.
81+
/// Gets the operation to be explained.
6782
/// </summary>
6883
/// <value>
69-
/// The command to be explained.
84+
/// The operation to be explained.
7085
/// </value>
71-
public BsonDocument Command
86+
public IExplainableOperation ExplainableOperation
7287
{
73-
get { return _command; }
88+
get { return _explainableOperation; }
7489
}
7590

7691
/// <summary>
@@ -100,29 +115,49 @@ public ExplainVerbosity Verbosity
100115
/// <inheritdoc/>
101116
public BsonDocument Execute(IReadBinding binding, CancellationToken cancellationToken)
102117
{
103-
var operation = CreateReadOperation();
104-
return operation.Execute(binding, cancellationToken);
118+
using (var channelSource = binding.GetReadChannelSource(cancellationToken))
119+
using (var channel = channelSource.GetChannel(cancellationToken))
120+
using (var channelBinding = new ChannelReadBinding(channelSource.Server, channel, binding.ReadPreference, binding.Session))
121+
{
122+
var operation = CreateReadOperation(channel.ConnectionDescription, binding.Session);
123+
return operation.Execute(channelBinding, cancellationToken);
124+
}
105125
}
106126

107127
/// <inheritdoc/>
108128
public BsonDocument Execute(IWriteBinding binding, CancellationToken cancellationToken)
109129
{
110-
var operation = CreateWriteOperation();
111-
return operation.Execute(binding, cancellationToken);
130+
using (var channelSource = binding.GetWriteChannelSource(cancellationToken))
131+
using (var channel = channelSource.GetChannel(cancellationToken))
132+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel, binding.Session))
133+
{
134+
var operation = CreateWriteOperation(channel.ConnectionDescription, binding.Session);
135+
return operation.Execute(channelBinding, cancellationToken);
136+
}
112137
}
113138

114139
/// <inheritdoc/>
115-
public Task<BsonDocument> ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
140+
public async Task<BsonDocument> ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
116141
{
117-
var operation = CreateReadOperation();
118-
return operation.ExecuteAsync(binding, cancellationToken);
142+
using (var channelSource = await binding.GetReadChannelSourceAsync(cancellationToken).ConfigureAwait(false))
143+
using (var channel = await channelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false))
144+
using (var channelBinding = new ChannelReadBinding(channelSource.Server, channel, binding.ReadPreference, binding.Session))
145+
{
146+
var operation = CreateReadOperation(channel.ConnectionDescription, binding.Session);
147+
return await operation.ExecuteAsync(channelBinding, cancellationToken).ConfigureAwait(false);
148+
}
119149
}
120150

121151
/// <inheritdoc/>
122-
public Task<BsonDocument> ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
152+
public async Task<BsonDocument> ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
123153
{
124-
var operation = CreateWriteOperation();
125-
return operation.ExecuteAsync(binding, cancellationToken);
154+
using (var channelSource = await binding.GetWriteChannelSourceAsync(cancellationToken).ConfigureAwait(false))
155+
using (var channel = await channelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false))
156+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel, binding.Session))
157+
{
158+
var operation = CreateWriteOperation(channel.ConnectionDescription, binding.Session);
159+
return await operation.ExecuteAsync(channelBinding, cancellationToken).ConfigureAwait(false);
160+
}
126161
}
127162

128163
// private methods
@@ -142,34 +177,35 @@ private static string ConvertVerbosityToString(ExplainVerbosity verbosity)
142177
}
143178
}
144179

145-
internal BsonDocument CreateCommand()
180+
internal BsonDocument CreateExplainCommand(ConnectionDescription connectionDescription, ICoreSession session)
146181
{
182+
var explainableCommand = _explainableOperation.CreateCommand(connectionDescription, session);
147183
return new BsonDocument
148184
{
149-
{ "explain", _command },
185+
{ "explain", explainableCommand },
150186
{ "verbosity", ConvertVerbosityToString(_verbosity) }
151187
};
152188
}
153189

154-
private ReadCommandOperation<BsonDocument> CreateReadOperation()
190+
private ReadCommandOperation<BsonDocument> CreateReadOperation(ConnectionDescription connectionDescription, ICoreSession session)
155191
{
156-
var command = CreateCommand();
192+
var explainCommand = CreateExplainCommand(connectionDescription, session);
157193
return new ReadCommandOperation<BsonDocument>(
158194
_databaseNamespace,
159-
command,
195+
explainCommand,
160196
BsonDocumentSerializer.Instance,
161197
_messageEncoderSettings)
162198
{
163199
RetryRequested = false
164200
};
165201
}
166202

167-
private WriteCommandOperation<BsonDocument> CreateWriteOperation()
203+
private WriteCommandOperation<BsonDocument> CreateWriteOperation(ConnectionDescription connectionDescription, ICoreSession session)
168204
{
169-
var command = CreateCommand();
205+
var explainCommand = CreateExplainCommand(connectionDescription, session);
170206
return new WriteCommandOperation<BsonDocument>(
171207
_databaseNamespace,
172-
command,
208+
explainCommand,
173209
BsonDocumentSerializer.Instance,
174210
_messageEncoderSettings);
175211
}

0 commit comments

Comments
 (0)