Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/MongoDB.Driver/Core/Misc/Feature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class Feature
private static readonly Feature __convertOperatorStringToObjectOrArray = new Feature("ConvertOperatorStringToObjectOrArray", WireVersion.Server83);
private static readonly Feature __createIndexCommitQuorum = new Feature("CreateIndexCommitQuorum", WireVersion.Server44);
private static readonly Feature __createIndexesUsingInsertOperations = new Feature("CreateIndexesUsingInsertOperations", WireVersion.Zero, WireVersion.Server42);
private static readonly Feature __createObjectIdExpression = new Feature("CreateObjectIdExpression", WireVersion.Server83);
private static readonly Feature __csfleRangeAlgorithm = new Feature("CsfleRangeAlgorithm", WireVersion.Server62);
private static readonly Feature __csfle2Qev2Lookup = new Feature("csfle2Qev2Lookup", WireVersion.Server81);
private static readonly Feature __csfle2Qev2RangeAlgorithm = new Feature("csfle2Qev2RangeAlgorithm", WireVersion.Server80);
Expand Down Expand Up @@ -248,6 +249,11 @@ public class Feature
[Obsolete("This feature was removed in server version 4.2. As such, this property will be removed in a later release.")]
public static Feature CreateIndexesUsingInsertOperations => __createIndexesUsingInsertOperations;

/// <summary>
/// Represents support for the $createObjectId operator feature.
/// </summary>
public static Feature CreateObjectIdExpression => __createObjectIdExpression;

/// <summary>
/// Gets the csfle range algorithm feature.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ internal enum AstNodeType
ConstantExpression,
ConvertExpression,
CountStage,
CreateObjectIdExpression,
CurrentOpStage,
CustomAccumulatorExpression,
DateAddExpression,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using MongoDB.Bson;
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Visitors;

namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions;

internal sealed class AstCreateObjectIdExpression : AstExpression
{
public override AstNodeType NodeType => AstNodeType.CreateObjectIdExpression;

public override AstNode Accept(AstNodeVisitor visitor) =>
visitor.VisitCreateObjectIdExpression(this);

public override BsonValue Render() =>
new BsonDocument("$createObjectId", new BsonDocument());
}
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ public static AstExpression Floor(AstExpression arg)
return new AstUnaryExpression(AstUnaryOperator.Floor, arg);
}

public static AstCreateObjectIdExpression CreateObjectId()
=> new();

public static AstGetFieldExpression GetField(AstExpression input, AstExpression fieldName)
{
return new AstGetFieldExpression(input, fieldName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ public virtual AstNode VisitCustomAccumulatorExpression(AstCustomAccumulatorExpr
return node.Update(VisitAndConvert(node.InitArgs), VisitAndConvert(node.AccumulateArgs));
}

public virtual AstNode VisitCreateObjectIdExpression(AstCreateObjectIdExpression node)
=> node;

public virtual AstNode VisitDateAddExpression(AstDateAddExpression node)
{
return node.Update(VisitAndConvert(node.StartDate), VisitAndConvert(node.Unit), VisitAndConvert(node.Amount), VisitAndConvert(node.Timezone));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal static class MqlMethod
private static readonly MethodInfo __constantWithRepresentation;
private static readonly MethodInfo __constantWithSerializer;
private static readonly MethodInfo __convert;
private static readonly MethodInfo __createObjectId;
private static readonly MethodInfo __dateFromString;
private static readonly MethodInfo __dateFromStringWithFormat;
private static readonly MethodInfo __dateFromStringWithFormatAndTimezone;
Expand All @@ -53,6 +54,7 @@ static MqlMethod()
__constantWithRepresentation = ReflectionInfo.Method((object value, BsonType representation) => Mql.Constant(value, representation));
__constantWithSerializer = ReflectionInfo.Method((object value, IBsonSerializer<object> serializer) => Mql.Constant(value, serializer));
__convert = ReflectionInfo.Method((object value, ConvertOptions<object> options) => Mql.Convert(value, options));
__createObjectId = ReflectionInfo.Method(() => Mql.CreateObjectId());
__dateFromString = ReflectionInfo.Method((string dateStringl) => Mql.DateFromString(dateStringl));
__dateFromStringWithFormat = ReflectionInfo.Method((string dateString, string format) => Mql.DateFromString(dateString, format));
__dateFromStringWithFormatAndTimezone = ReflectionInfo.Method((string dateString, string format, string timezone) => Mql.DateFromString(dateString, format, timezone));
Expand Down Expand Up @@ -110,6 +112,7 @@ static MqlMethod()
public static MethodInfo ConstantWithRepresentation => __constantWithRepresentation;
public static MethodInfo ConstantWithSerializer => __constantWithSerializer;
public static MethodInfo Convert => __convert;
public static MethodInfo CreateObjectId => __createObjectId;
public static MethodInfo DateFromString => __dateFromString;
public static MethodInfo DateFromStringWithFormat => __dateFromStringWithFormat;
public static MethodInfo DateFromStringWithFormatAndTimezone => __dateFromStringWithFormatAndTimezone;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,106 +16,69 @@
using System;
using System.Linq.Expressions;
using System.Reflection;
using MongoDB.Driver.Linq.Linq3Implementation.Misc;

namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection
{
internal static class ReflectionInfo
{
public static ConstructorInfo Constructor<TObject>(Expression<Func<TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<TObject>(Expression<Func<TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, TObject>(Expression<Func<T1, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, TObject>(Expression<Func<T1, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, TObject>(Expression<Func<T1, T2, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, TObject>(Expression<Func<T1, T2, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, T3, TObject>(Expression<Func<T1, T2, T3, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, T3, TObject>(Expression<Func<T1, T2, T3, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, T3, T4, TObject>(Expression<Func<T1, T2, T3, T4, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, T3, T4, TObject>(Expression<Func<T1, T2, T3, T4, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, TObject>(Expression<Func<T1, T2, T3, T4, T5, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, TObject>(Expression<Func<T1, T2, T3, T4, T5, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, T6, TObject>(Expression<Func<T1, T2, T3, T4, T5, T6, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, T6, TObject>(Expression<Func<T1, T2, T3, T4, T5, T6, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, T6, T7, TObject>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TObject>> lambda)
{
return ExtractConstructorInfoFromLambda(lambda);
}
public static ConstructorInfo Constructor<T1, T2, T3, T4, T5, T6, T7, TObject>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TObject>> lambda) =>
ExtractConstructorInfoFromLambda(lambda);

public static MethodInfo Method<T1, TResult>(Expression<Func<T1, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<TResult>(Expression<Func<TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, TResult>(Expression<Func<T1, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, T4, TResult>(Expression<Func<T1, T2, T3, T4, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, T4, T5, TResult>(Expression<Func<T1, T2, T3, T4, T5, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, T4, TResult>(Expression<Func<T1, T2, T3, T4, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, T4, T5, T6, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, T4, T5, TResult>(Expression<Func<T1, T2, T3, T4, T5, TResult>> lambda) => ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, T4, T5, T6, T7, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, T4, T5, T6, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo Method<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, T4, T5, T6, T7, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static PropertyInfo Property<TObject, TProperty>(Expression<Func<TObject, TProperty>> lambda)
{
return ExtractPropertyInfoFromLambda(lambda);
}
public static MethodInfo Method<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo IndexerGet<TObject, TIndex, TValue>(Expression<Func<TObject, TIndex, TValue>> lambda)
{
return ExtractMethodInfoFromLambda(lambda);
}
public static PropertyInfo Property<TObject, TProperty>(Expression<Func<TObject, TProperty>> lambda) =>
ExtractPropertyInfoFromLambda(lambda);

public static MethodInfo IndexerSet<TObject, TIndex, TValue>(Expression<Func<TObject, TIndex, TValue>> lambda)
{
return ExtractIndexerSetMethodInfoFromLambda(lambda);
}
public static MethodInfo IndexerGet<TObject, TIndex, TValue>(Expression<Func<TObject, TIndex, TValue>> lambda) =>
ExtractMethodInfoFromLambda(lambda);

public static MethodInfo IndexerSet<TObject, TIndex, TValue>(Expression<Func<TObject, TIndex, TValue>> lambda) =>
ExtractIndexerSetMethodInfoFromLambda(lambda);

// private static methods
private static ConstructorInfo ExtractConstructorInfoFromLambda(LambdaExpression lambda)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void DeduceMethodCallSerializers()
case "ContainsValue": DeduceContainsValueMethodSerializers(); break;
case "Convert": DeduceConvertMethodSerializers(); break;
case "Create": DeduceCreateMethodSerializers(); break;
case "CreateObjectId": DeduceCreateObjectIdMethodSerializers(); break;
case "DateFromString": DeduceDateFromStringMethodSerializers(); break;
case "DefaultIfEmpty": DeduceDefaultIfEmptyMethodSerializers(); break;
case "DegreesToRadians": DeduceDegreesToRadiansMethodSerializers(); break;
Expand Down Expand Up @@ -1373,6 +1374,21 @@ void DeduceFieldMethodSerializers()
}
}

void DeduceCreateObjectIdMethodSerializers()
{
if (method.Is(MqlMethod.CreateObjectId))
{
if (IsNotKnown(node))
{
DeduceSerializer(node, ObjectIdSerializer.Instance);
}
}
else
{
DeduceUnknownMethodSerializer();
}
}

void DeduceFirstOrLastOrSingleMethodsSerializers()
{
if (method.IsOneOf(EnumerableOrQueryableMethod.FirstOrLastOrSingleOverloads))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public static TranslatedExpression Translate(TranslationContext context, MethodC
case "CovariancePopulation": return CovariancePopulationMethodToAggregationExpressionTranslator.Translate(context, expression);
case "CovarianceSample": return CovarianceSampleMethodToAggregationExpressionTranslator.Translate(context, expression);
case "Create": return CreateMethodToAggregationExpressionTranslator.Translate(context, expression);
case "CreateObjectId": return CreateObjectIdMethodToAggregationExpressionTranslator.Translate(context, expression);
case "DateFromString": return DateFromStringMethodToAggregationExpressionTranslator.Translate(context, expression);
case "DefaultIfEmpty": return DefaultIfEmptyMethodToAggregationExpressionTranslator.Translate(context, expression);
case "DenseRank": return DenseRankMethodToAggregationExpressionTranslator.Translate(context, expression);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System.Linq.Expressions;
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions;
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
using MongoDB.Driver.Linq.Linq3Implementation.Reflection;

namespace MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MethodTranslators;

internal static class CreateObjectIdMethodToAggregationExpressionTranslator
{
public static TranslatedExpression Translate(TranslationContext context, MethodCallExpression expression)
{
var method = expression.Method;

if (method.Is(MqlMethod.CreateObjectId))
{
var ast = AstExpression.CreateObjectId();
var serializer = context.GetSerializer(expression);
return new TranslatedExpression(expression, ast, serializer);
}

throw new ExpressionNotSupportedException(expression);
}
}
7 changes: 7 additions & 0 deletions src/MongoDB.Driver/Mql.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ public static TTo Convert<TFrom, TTo>(TFrom value, ConvertOptions<TTo> options)
throw CustomLinqExtensionMethodHelper.CreateNotSupportedException();
}

/// <summary>
/// Creates a new unique ObjectId using the $createObjectId aggregation operator.
/// </summary>
/// <returns>A ObjectId.</returns>
public static ObjectId CreateObjectId() =>
throw CustomLinqExtensionMethodHelper.CreateNotSupportedException();

/// <summary>
/// Converts a string to a DateTime using the $dateFromString aggregation operator.
/// </summary>
Expand Down
Loading