Skip to content

Commit cd88629

Browse files
committed
CSHARP-1749: Support creating views.
1 parent 29b13b0 commit cd88629

19 files changed

+1417
-0
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class Feature
3030
private static readonly Feature __aggregateOut = new Feature("Aggregate", new SemanticVersion(2, 6, 0));
3131
private static readonly Feature __bypassDocumentValidation = new Feature("BypassDocumentValidation", new SemanticVersion(3, 2, 0));
3232
private static readonly CollationFeature __collation = new CollationFeature("Collation", new SemanticVersion(3, 3, 11));
33+
private static readonly Feature __commandsWriteConcern = new CollationFeature("CommandsWriteConcern", new SemanticVersion(3, 3, 11));
3334
private static readonly Feature __createIndexesCommand = new Feature("CreateIndexesCommand", new SemanticVersion(3, 0, 0));
3435
private static readonly Feature __currentOpCommand = new Feature("CurrentOpCommand", new SemanticVersion(3, 2, 0));
3536
private static readonly Feature __documentValidation = new Feature("DocumentValidation", new SemanticVersion(3, 2, 0));
@@ -46,6 +47,7 @@ public class Feature
4647
private static readonly ReadConcernFeature __readConcern = new ReadConcernFeature("ReadConcern", new SemanticVersion(3, 2, 0));
4748
private static readonly Feature __scramSha1Authentication = new Feature("ScramSha1Authentication", new SemanticVersion(3, 0, 0));
4849
private static readonly Feature __userManagementCommands = new Feature("UserManagementCommands", new SemanticVersion(2, 6, 0));
50+
private static readonly Feature __views = new Feature("Views", new SemanticVersion(3, 3, 11));
4951
private static readonly Feature __writeCommands = new Feature("WriteCommands", new SemanticVersion(2, 6, 0));
5052

5153
/// <summary>
@@ -83,6 +85,11 @@ public class Feature
8385
/// </summary>
8486
public static CollationFeature Collation => __collation;
8587

88+
/// <summary>
89+
/// Gets the commands write concern feature.
90+
/// </summary>
91+
public static Feature CommandsWriteConcern => __commandsWriteConcern;
92+
8693
/// <summary>
8794
/// Gets the create indexes command feature.
8895
/// </summary>
@@ -163,6 +170,11 @@ public class Feature
163170
/// </summary>
164171
public static Feature UserManagementCommands => __userManagementCommands;
165172

173+
/// <summary>
174+
/// Gets the views feature.
175+
/// </summary>
176+
public static Feature Views => __views;
177+
166178
/// <summary>
167179
/// Gets the write commands feature.
168180
/// </summary>
@@ -218,6 +230,18 @@ public SemanticVersion SupportedOrNotSupportedVersion(bool isSupported)
218230
return isSupported ? _firstSupportedVersion : VersionBefore(_firstSupportedVersion);
219231
}
220232

233+
/// <summary>
234+
/// Throws if the feature is not supported by a version of the server.
235+
/// </summary>
236+
/// <param name="serverVersion">The server version.</param>
237+
public void ThrowIfNotSupported(SemanticVersion serverVersion)
238+
{
239+
if (!IsSupported(serverVersion))
240+
{
241+
throw new NotSupportedException($"Server version {serverVersion} does not support the {_name} feature.");
242+
}
243+
}
244+
221245
private SemanticVersion VersionBefore(SemanticVersion version)
222246
{
223247
if (version.Patch > 0)
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/* Copyright 2016 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Threading;
19+
using System.Threading.Tasks;
20+
using MongoDB.Bson;
21+
using MongoDB.Bson.Serialization.Serializers;
22+
using MongoDB.Driver.Core.Bindings;
23+
using MongoDB.Driver.Core.Misc;
24+
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
25+
26+
namespace MongoDB.Driver.Core.Operations
27+
{
28+
/// <summary>
29+
/// Represents a create view operation.
30+
/// </summary>
31+
public class CreateViewOperation : IWriteOperation<BsonDocument>
32+
{
33+
// private fields
34+
private Collation _collation;
35+
private readonly DatabaseNamespace _databaseNamespace;
36+
private readonly MessageEncoderSettings _messageEncoderSettings;
37+
private readonly IReadOnlyList<BsonDocument> _pipeline;
38+
private readonly string _viewName;
39+
private readonly string _viewOn;
40+
private WriteConcern _writeConcern;
41+
42+
// constructors
43+
/// <summary>
44+
/// Initializes a new instance of the <see cref="CreateCollectionOperation" /> class.
45+
/// </summary>
46+
/// <param name="databaseNamespace">Name of the database.</param>
47+
/// <param name="viewName">Name of the view.</param>
48+
/// <param name="viewOn">The view on.</param>
49+
/// <param name="pipeline">The pipeline.</param>
50+
/// <param name="messageEncoderSettings">The message encoder settings.</param>
51+
public CreateViewOperation(
52+
DatabaseNamespace databaseNamespace,
53+
string viewName,
54+
string viewOn,
55+
IEnumerable<BsonDocument> pipeline,
56+
MessageEncoderSettings messageEncoderSettings)
57+
{
58+
_databaseNamespace = Ensure.IsNotNull(databaseNamespace, nameof(databaseNamespace));
59+
_viewName = Ensure.IsNotNull(viewName, nameof(viewName));
60+
_viewOn = Ensure.IsNotNull(viewOn, nameof(viewOn));
61+
_pipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)).ToList();
62+
_messageEncoderSettings = Ensure.IsNotNull(messageEncoderSettings, nameof(messageEncoderSettings));
63+
}
64+
65+
// public properties
66+
/// <summary>
67+
/// Gets or sets the collation.
68+
/// </summary>
69+
/// <value>
70+
/// The collation.
71+
/// </value>
72+
public Collation Collation
73+
{
74+
get { return _collation; }
75+
set { _collation = value; }
76+
}
77+
78+
/// <summary>
79+
/// Gets the namespace of the database.
80+
/// </summary>
81+
/// <value>
82+
/// The namespace of the database.
83+
/// </value>
84+
public DatabaseNamespace DatabaseNamespace
85+
{
86+
get { return _databaseNamespace; }
87+
}
88+
89+
/// <summary>
90+
/// Gets the message encoder settings.
91+
/// </summary>
92+
/// <value>
93+
/// The message encoder settings.
94+
/// </value>
95+
public MessageEncoderSettings MessageEncoderSettings
96+
{
97+
get { return _messageEncoderSettings; }
98+
}
99+
100+
/// <summary>
101+
/// Gets the pipeline.
102+
/// </summary>
103+
/// <value>
104+
/// The pipeline.
105+
/// </value>
106+
public IReadOnlyList<BsonDocument> Pipeline
107+
{
108+
get { return _pipeline; }
109+
}
110+
111+
/// <summary>
112+
/// Gets the name of the view.
113+
/// </summary>
114+
/// <value>
115+
/// The name of the view.
116+
/// </value>
117+
public string ViewName
118+
{
119+
get { return _viewName; }
120+
}
121+
122+
/// <summary>
123+
/// Gets the collection namespace.
124+
/// </summary>
125+
/// <value>
126+
/// The collection namespace.
127+
/// </value>
128+
public string ViewOn
129+
{
130+
get { return _viewOn; }
131+
}
132+
133+
/// <summary>
134+
/// Gets or sets the write concern.
135+
/// </summary>
136+
/// <value>
137+
/// The write concern.
138+
/// </value>
139+
public WriteConcern WriteConcern
140+
{
141+
get { return _writeConcern; }
142+
set { _writeConcern = value; }
143+
}
144+
145+
// public methods
146+
/// <inheritdoc/>
147+
public BsonDocument Execute(IWriteBinding binding, CancellationToken cancellationToken)
148+
{
149+
Ensure.IsNotNull(binding, nameof(binding));
150+
151+
using (var channelSource = binding.GetWriteChannelSource(cancellationToken))
152+
using (var channel = channelSource.GetChannel(cancellationToken))
153+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel))
154+
{
155+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
156+
return operation.Execute(channelBinding, cancellationToken);
157+
}
158+
}
159+
160+
/// <inheritdoc/>
161+
public async Task<BsonDocument> ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
162+
{
163+
Ensure.IsNotNull(binding, nameof(binding));
164+
165+
using (var channelSource = await binding.GetWriteChannelSourceAsync(cancellationToken).ConfigureAwait(false))
166+
using (var channel = await channelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false))
167+
using (var channelBinding = new ChannelReadWriteBinding(channelSource.Server, channel))
168+
{
169+
var operation = CreateOperation(channel.ConnectionDescription.ServerVersion);
170+
return await operation.ExecuteAsync(channelBinding, cancellationToken).ConfigureAwait(false);
171+
}
172+
}
173+
174+
// private methods
175+
internal BsonDocument CreateCommand(SemanticVersion serverVersion)
176+
{
177+
Feature.Views.ThrowIfNotSupported(serverVersion);
178+
Feature.Collation.ThrowIfNotSupported(serverVersion, _collation);
179+
180+
return new BsonDocument
181+
{
182+
{ "create", _viewName },
183+
{ "viewOn", _viewOn },
184+
{ "pipeline", new BsonArray(_pipeline) },
185+
{ "collation", () => _collation.ToBsonDocument(), _collation != null },
186+
{ "writeConcern", () => _writeConcern.ToBsonDocument(), _writeConcern != null && !_writeConcern.IsServerDefault && Feature.CommandsWriteConcern.IsSupported(serverVersion) }
187+
};
188+
}
189+
190+
private WriteCommandOperation<BsonDocument> CreateOperation(SemanticVersion serverVersion)
191+
{
192+
var command = CreateCommand(serverVersion);
193+
return new WriteCommandOperation<BsonDocument>(_databaseNamespace, command, BsonDocumentSerializer.Instance, _messageEncoderSettings);
194+
}
195+
}
196+
}

src/MongoDB.Driver.Core/MongoDB.Driver.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="Core\Misc\ReadAheadEnumerable.cs" />
7777
<Compile Include="Core\Misc\ReadConcernFeature.cs" />
7878
<Compile Include="Core\Misc\TaskExtensions.cs" />
79+
<Compile Include="Core\Operations\CreateViewOperation.cs" />
7980
<Compile Include="Core\Servers\IServerMonitor.cs" />
8081
<Compile Include="Core\Servers\IServerMonitorFactory.cs" />
8182
<Compile Include="Core\Servers\ServerMonitorFactory.cs" />
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* Copyright 2016 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using System.Text;
20+
using System.Threading.Tasks;
21+
using MongoDB.Bson;
22+
using MongoDB.Bson.Serialization;
23+
using MongoDB.Bson.Serialization.Attributes;
24+
using MongoDB.Bson.Serialization.Serializers;
25+
26+
namespace MongoDB.Driver.Builders
27+
{
28+
/// <summary>
29+
/// A builder for the options used when creating a view.
30+
/// </summary>
31+
public static class CreateViewOptions
32+
{
33+
/// <summary>
34+
/// Sets the collation.
35+
/// </summary>
36+
/// <param name="collation">The collation.</param>
37+
/// <returns>The builder (so method calls can be chained).</returns>
38+
public static CreateViewOptionsBuilder SetCollation(Collation collation)
39+
{
40+
return new CreateViewOptionsBuilder().SetCollation(collation);
41+
}
42+
}
43+
44+
/// <summary>
45+
/// A builder for the options used when creating a view.
46+
/// </summary>
47+
[BsonSerializer(typeof(CreateViewOptionsBuilder.Serializer))]
48+
public class CreateViewOptionsBuilder : BuilderBase, IMongoCreateViewOptions
49+
{
50+
private BsonDocument _document;
51+
52+
/// <summary>
53+
/// Initializes a new instance of the <see cref="CreateViewOptionsBuilder"/> class.
54+
/// </summary>
55+
public CreateViewOptionsBuilder()
56+
{
57+
_document = new BsonDocument();
58+
}
59+
60+
/// <summary>
61+
/// Sets the collation.
62+
/// </summary>
63+
/// <param name="collation">The collation.</param>
64+
/// <returns>The builder (so method calls can be chained).</returns>
65+
public CreateViewOptionsBuilder SetCollation(Collation collation)
66+
{
67+
if (collation == null)
68+
{
69+
_document.Remove("collation");
70+
}
71+
else
72+
{
73+
_document["collation"] = collation.ToBsonDocument();
74+
}
75+
76+
return this;
77+
}
78+
79+
/// <inheritdoc/>
80+
public override BsonDocument ToBsonDocument()
81+
{
82+
return _document;
83+
}
84+
85+
// nested classes
86+
new internal class Serializer : SerializerBase<CreateViewOptionsBuilder>
87+
{
88+
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, CreateViewOptionsBuilder value)
89+
{
90+
BsonDocumentSerializer.Instance.Serialize(context, value._document);
91+
}
92+
}
93+
}
94+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* Copyright 2016 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using MongoDB.Bson.Serialization.Attributes;
17+
using MongoDB.Bson.Serialization.Serializers;
18+
19+
namespace MongoDB.Driver
20+
{
21+
/// <summary>
22+
/// A marker interface that represents options for creating a view (see CreateViewOptionsDocument and the CreateViewOptions builder).
23+
/// </summary>
24+
[BsonSerializer(typeof(UndiscriminatedActualTypeSerializer<IMongoCreateViewOptions>))]
25+
public interface IMongoCreateViewOptions
26+
{
27+
}
28+
}

0 commit comments

Comments
 (0)