Skip to content

Commit fb88c67

Browse files
committed
CSHARP-5656: Support Aggregation Operator to generate random object ids
1 parent 457c80e commit fb88c67

14 files changed

Lines changed: 379 additions & 2 deletions

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class Feature
4848
private static readonly Feature __convertOperatorBinDataToFromString= new Feature("ConvertOperatorBinDataToFromString", WireVersion.Server80);
4949
private static readonly Feature __createIndexCommitQuorum = new Feature("CreateIndexCommitQuorum", WireVersion.Server44);
5050
private static readonly Feature __createIndexesUsingInsertOperations = new Feature("CreateIndexesUsingInsertOperations", WireVersion.Zero, WireVersion.Server42);
51+
private static readonly Feature __createObjectIdExpression = new Feature("CreateObjectIdExpression", WireVersion.Server83);
5152
private static readonly Feature __csfleRangeAlgorithm = new Feature("CsfleRangeAlgorithm", WireVersion.Server62);
5253
private static readonly Feature __csfle2Qev2Lookup = new Feature("csfle2Qev2Lookup", WireVersion.Server81);
5354
private static readonly Feature __csfle2Qev2RangeAlgorithm = new Feature("csfle2Qev2RangeAlgorithm", WireVersion.Server80);
@@ -223,6 +224,11 @@ public class Feature
223224
[Obsolete("This feature was removed in server version 4.2. As such, this property will be removed in a later release.")]
224225
public static Feature CreateIndexesUsingInsertOperations => __createIndexesUsingInsertOperations;
225226

227+
/// <summary>
228+
/// Represents support for the $createObjectId operator feature.
229+
/// </summary>
230+
public static Feature CreateObjectIdExpression => __createObjectIdExpression;
231+
226232
/// <summary>
227233
/// Gets the csfle range algorithm feature.
228234
/// </summary>

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/AstNodeType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ internal enum AstNodeType
3838
ConstantExpression,
3939
ConvertExpression,
4040
CountStage,
41+
CreateObjectIdExpression,
4142
CurrentOpStage,
4243
CustomAccumulatorExpression,
4344
DateAddExpression,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Copyright 2010-present 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;
17+
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Visitors;
18+
19+
namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions
20+
{
21+
internal sealed class AstCreateObjectIdExpression : AstExpression
22+
{
23+
public override AstNodeType NodeType => AstNodeType.CreateObjectIdExpression;
24+
25+
public override AstNode Accept(AstNodeVisitor visitor)
26+
{
27+
return visitor.VisitCreateObjectIdExpression(this);
28+
}
29+
30+
public override BsonValue Render()
31+
{
32+
return new BsonDocument
33+
{
34+
{ "$createObjectId", new BsonDocument() }
35+
};
36+
}
37+
}
38+
}

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstExpression.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ public static AstExpression Floor(AstExpression arg)
439439
return new AstUnaryExpression(AstUnaryOperator.Floor, arg);
440440
}
441441

442+
public static AstCreateObjectIdExpression CreateObjectId()
443+
=> new();
444+
442445
public static AstGetFieldExpression GetField(AstExpression input, AstExpression fieldName)
443446
{
444447
return new AstGetFieldExpression(input, fieldName);

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Visitors/AstNodeVisitor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ public virtual AstNode VisitCustomAccumulatorExpression(AstCustomAccumulatorExpr
244244
return node.Update(VisitAndConvert(node.InitArgs), VisitAndConvert(node.AccumulateArgs));
245245
}
246246

247+
public virtual AstNode VisitCreateObjectIdExpression(AstCreateObjectIdExpression node)
248+
=> node;
249+
247250
public virtual AstNode VisitDateAddExpression(AstDateAddExpression node)
248251
{
249252
return node.Update(VisitAndConvert(node.StartDate), VisitAndConvert(node.Unit), VisitAndConvert(node.Amount), VisitAndConvert(node.Timezone));

src/MongoDB.Driver/Linq/Linq3Implementation/Misc/PartialEvaluator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
325325

326326
var method = node.Method;
327327
if (IsCustomLinqExtensionMethod(method) ||
328-
method.Is(QueryableMethod.AsQueryable))
328+
method.Is(QueryableMethod.AsQueryable) ||
329+
method.Is(ObjectIdMethod.GenerateNewIdMethod))
329330
{
330331
_cannotBeEvaluated = true;
331332
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Copyright 2010-present 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.Reflection;
17+
using MongoDB.Bson;
18+
19+
namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection;
20+
21+
internal static class ObjectIdMethod
22+
{
23+
public static MethodInfo GenerateNewIdMethod => ReflectionInfo.Method(() => ObjectId.GenerateNewId());
24+
}
25+

src/MongoDB.Driver/Linq/Linq3Implementation/Reflection/ReflectionInfo.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using System;
1717
using System.Linq.Expressions;
1818
using System.Reflection;
19-
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
2019

2120
namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection
2221
{
@@ -62,6 +61,11 @@ public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, T6, T7, TObject>(E
6261
return ExtractConstructorInfoFromLambda(lambda);
6362
}
6463

64+
public static MethodInfo Method<TResult>(Expression<Func<TResult>> lambda)
65+
{
66+
return ExtractMethodInfoFromLambda(lambda);
67+
}
68+
6569
public static MethodInfo Method<T1, TResult>(Expression<Func<T1, TResult>> lambda)
6670
{
6771
return ExtractMethodInfoFromLambda(lambda);

src/MongoDB.Driver/Linq/Linq3Implementation/SerializerFinders/SerializerFinderVisitMethodCall.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ void DeduceMethodCallSerializers()
113113
case "Exp": DeduceExpMethodSerializers(); break;
114114
case "ExponentialMovingAverage": DeduceExponentialMovingAverageMethodSerializers(); break;
115115
case "Field": DeduceFieldMethodSerializers(); break;
116+
case "GenerateNewId": DeduceGenerateNewIdMethodSerializers(); break;
116117
case "get_Item": DeduceGetItemMethodSerializers(); break;
117118
case "get_Chars": DeduceGetCharsMethodSerializers(); break;
118119
case "GroupBy": DeduceGroupByMethodSerializers(); break;
@@ -1369,6 +1370,21 @@ void DeduceFieldMethodSerializers()
13691370
}
13701371
}
13711372

1373+
void DeduceGenerateNewIdMethodSerializers()
1374+
{
1375+
if (method.Is(ObjectIdMethod.GenerateNewIdMethod))
1376+
{
1377+
if (IsNotKnown(node))
1378+
{
1379+
DeduceSerializer(node, ObjectIdSerializer.Instance);
1380+
}
1381+
}
1382+
else
1383+
{
1384+
DeduceUnknownMethodSerializer();
1385+
}
1386+
}
1387+
13721388
void DeduceFirstOrLastOrSingleMethodsSerializers()
13731389
{
13741390
if (method.IsOneOf(EnumerableOrQueryableMethod.FirstOrLastOrSingleOverloads))

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MethodCallExpressionToAggregationExpressionTranslator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public static TranslatedExpression Translate(TranslationContext context, MethodC
5555
case "ExponentialMovingAverage": return ExponentialMovingAverageMethodToAggregationExpressionTranslator.Translate(context, expression);
5656
case "Field": return FieldMethodToAggregationExpressionTranslator.Translate(context, expression);
5757
case "Floor": return FloorMethodToAggregationExpressionTranslator.Translate(context, expression);
58+
case "GenerateNewId": return GenerateNewIdMethodToAggregationExpressionTranslator.Translate(context, expression);
5859
case "get_Item": return GetItemMethodToAggregationExpressionTranslator.Translate(context, expression);
5960
case "Integral": return IntegralMethodToAggregationExpressionTranslator.Translate(context, expression);
6061
case "Intersect": return IntersectMethodToAggregationExpressionTranslator.Translate(context, expression);

0 commit comments

Comments
 (0)