Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
add interface
  • Loading branch information
Maya-Painter committed Nov 1, 2023
commit 9a1f18cf5b718d5d35017d50f588be3003e89a17
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private SqlScalarExpression VisitIN(Expression expression, ConstantExpression co
List<SqlScalarExpression> items = new List<SqlScalarExpression>();
foreach (object item in (IEnumerable)constantExpressionList.Value)
{
items.Add(CosmosLinqSerializer.VisitConstant(Expression.Constant(item), context));
items.Add(context.CosmosLinqSerializer.VisitConstant(Expression.Constant(item), context));
}

// if the items list empty, then just return false expression
Expand Down
14 changes: 7 additions & 7 deletions Microsoft.Azure.Cosmos/src/Linq/CosmosLinqSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ namespace Microsoft.Azure.Cosmos.Linq
using Microsoft.Azure.Documents;
using Newtonsoft.Json;

internal static class CosmosLinqSerializer
internal class CosmosLinqSerializer : ICosmosLinqSerializer
{
public static SqlScalarExpression ApplyCustomConverters(Expression left, SqlLiteralScalarExpression right)
public SqlScalarExpression ApplyCustomConverters(Expression left, SqlLiteralScalarExpression right)
{
MemberExpression memberExpression;
if (left is UnaryExpression unaryExpression)
Expand Down Expand Up @@ -115,7 +115,7 @@ public static SqlScalarExpression ApplyCustomConverters(Expression left, SqlLite
return right;
}

public static SqlScalarExpression VisitConstant(ConstantExpression inputExpression, TranslationContext context)
public SqlScalarExpression VisitConstant(ConstantExpression inputExpression, TranslationContext context)
{
if (inputExpression.Value == null)
{
Expand All @@ -124,10 +124,10 @@ public static SqlScalarExpression VisitConstant(ConstantExpression inputExpressi

if (inputExpression.Type.IsNullable())
{
return CosmosLinqSerializer.VisitConstant(Expression.Constant(inputExpression.Value, Nullable.GetUnderlyingType(inputExpression.Type)), context);
return this.VisitConstant(Expression.Constant(inputExpression.Value, Nullable.GetUnderlyingType(inputExpression.Type)), context);
}

if (context.parameters != null && context.parameters.TryGetValue(inputExpression.Value, out string paramName))
if (context.Parameters != null && context.Parameters.TryGetValue(inputExpression.Value, out string paramName))
{
SqlParameter sqlParameter = SqlParameter.Create(paramName);
return SqlParameterRefScalarExpression.Create(sqlParameter);
Expand Down Expand Up @@ -171,7 +171,7 @@ public static SqlScalarExpression VisitConstant(ConstantExpression inputExpressi

foreach (object item in enumerable)
{
arrayItems.Add(CosmosLinqSerializer.VisitConstant(Expression.Constant(item), context));
arrayItems.Add(this.VisitConstant(Expression.Constant(item), context));
}

return SqlArrayCreateScalarExpression.Create(arrayItems.ToImmutableArray());
Expand All @@ -180,7 +180,7 @@ public static SqlScalarExpression VisitConstant(ConstantExpression inputExpressi
return CosmosElement.Parse(JsonConvert.SerializeObject(inputExpression.Value)).Accept(CosmosElementToSqlScalarExpressionVisitor.Singleton);
}

public static string GetMemberName(this MemberInfo memberInfo, CosmosLinqSerializerOptions linqSerializerOptions = null)
public string GetMemberName(MemberInfo memberInfo, CosmosLinqSerializerOptions linqSerializerOptions = null)
{
string memberName = null;

Expand Down
80 changes: 40 additions & 40 deletions Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions Microsoft.Azure.Cosmos/src/Linq/ICosmosLinqSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos.Linq
{
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.Azure.Cosmos.SqlObjects;

internal interface ICosmosLinqSerializer
{
SqlScalarExpression ApplyCustomConverters(Expression left, SqlLiteralScalarExpression right);

string GetMemberName(MemberInfo memberInfo, CosmosLinqSerializerOptions linqSerializerOptions = null);

SqlScalarExpression VisitConstant(ConstantExpression inputExpression, TranslationContext context);
}
}
8 changes: 4 additions & 4 deletions Microsoft.Azure.Cosmos/src/Linq/QueryUnderConstruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -583,13 +583,13 @@ public QueryUnderConstruction AddOrderByClause(SqlOrderByClause orderBy, Transla

public QueryUnderConstruction UpdateOrderByClause(SqlOrderByClause thenBy, TranslationContext context)
{
List<SqlOrderByItem> items = new List<SqlOrderByItem>(context.currentQuery.orderByClause.OrderByItems);
List<SqlOrderByItem> items = new List<SqlOrderByItem>(context.CurrentQuery.orderByClause.OrderByItems);
items.AddRange(thenBy.OrderByItems);
context.currentQuery.orderByClause = SqlOrderByClause.Create(items.ToImmutableArray());
context.CurrentQuery.orderByClause = SqlOrderByClause.Create(items.ToImmutableArray());

foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings()) context.currentQuery.AddBinding(binding);
foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings()) context.CurrentQuery.AddBinding(binding);

return context.currentQuery;
return context.CurrentQuery;
}

public QueryUnderConstruction AddOffsetSpec(SqlOffsetSpec offsetSpec, TranslationContext context)
Expand Down
35 changes: 22 additions & 13 deletions Microsoft.Azure.Cosmos/src/Linq/TranslationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace Microsoft.Azure.Cosmos.Linq
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.Azure.Cosmos.Serializer;
using Microsoft.Azure.Cosmos.SqlObjects;
using static Microsoft.Azure.Cosmos.Linq.ExpressionToSql;
using static Microsoft.Azure.Cosmos.Linq.FromParameterBindings;
Expand All @@ -29,30 +28,39 @@ internal sealed class TranslationContext
/// <summary>
/// Query that is being assembled.
/// </summary>
public QueryUnderConstruction currentQuery;
public QueryUnderConstruction CurrentQuery;

/// <summary>
/// Dictionary for parameter name and value
/// </summary>
public IDictionary<object, string> parameters;
public IDictionary<object, string> Parameters;

/// <summary>
/// The LINQ serializer
/// </summary>
public ICosmosLinqSerializer CosmosLinqSerializer;

/// <summary>
/// If the FROM clause uses a parameter name, it will be substituted for the parameter used in
/// the lambda expressions for the WHERE and SELECT clauses.
/// </summary>
private ParameterSubstitution substitutions;

/// <summary>
/// We are currently visiting these methods.
/// </summary>
private List<MethodCallExpression> methodStack;

/// <summary>
/// Stack of parameters from lambdas currently in scope.
/// </summary>
private List<ParameterExpression> lambdaParametersStack;

/// <summary>
/// Stack of collection-valued inputs.
/// </summary>
private List<Collection> collectionStack;

/// <summary>
/// The stack of subquery binding information.
/// </summary>
Expand All @@ -65,14 +73,15 @@ public TranslationContext(CosmosLinqSerializerOptions linqSerializerOptions, IDi
this.methodStack = new List<MethodCallExpression>();
this.lambdaParametersStack = new List<ParameterExpression>();
this.collectionStack = new List<Collection>();
this.currentQuery = new QueryUnderConstruction(this.GetGenFreshParameterFunc());
this.CurrentQuery = new QueryUnderConstruction(this.GetGenFreshParameterFunc());
this.subqueryBindingStack = new Stack<SubqueryBinding>();
this.linqSerializerOptions = linqSerializerOptions;
this.parameters = parameters;
this.LinqSerializerOptions = linqSerializerOptions;
this.Parameters = parameters;
this.memberNames = new MemberNames(linqSerializerOptions);
this.CosmosLinqSerializer = new CosmosLinqSerializer();
}

public CosmosLinqSerializerOptions linqSerializerOptions;
public CosmosLinqSerializerOptions LinqSerializerOptions;

public Expression LookupSubstitution(ParameterExpression parameter)
{
Expand Down Expand Up @@ -103,12 +112,12 @@ public void PushParameter(ParameterExpression parameter, bool shouldBeOnNewQuery
if (last.isOuter)
{
// substitute
ParameterExpression inputParam = this.currentQuery.GetInputParameterInContext(shouldBeOnNewQuery);
ParameterExpression inputParam = this.CurrentQuery.GetInputParameterInContext(shouldBeOnNewQuery);
this.substitutions.AddSubstitution(parameter, inputParam);
}
else
{
this.currentQuery.Bind(parameter, last.inner);
this.CurrentQuery.Bind(parameter, last.inner);
}
}

Expand Down Expand Up @@ -182,7 +191,7 @@ public void PopCollection()
/// <param name="name">Suggested name for the input parameter.</param>
public ParameterExpression SetInputParameter(Type type, string name)
{
return this.currentQuery.fromParameters.SetInputParameter(type, name, this.InScope);
return this.CurrentQuery.fromParameters.SetInputParameter(type, name, this.InScope);
}

/// <summary>
Expand All @@ -193,7 +202,7 @@ public ParameterExpression SetInputParameter(Type type, string name)
public void SetFromParameter(ParameterExpression parameter, SqlCollection collection)
{
Binding binding = new Binding(parameter, collection, isInCollection: true);
this.currentQuery.fromParameters.Add(binding);
this.CurrentQuery.fromParameters.Add(binding);
}

/// <summary>
Expand Down Expand Up @@ -258,11 +267,11 @@ public QueryUnderConstruction PackageCurrentQueryIfNeccessary()
{
if (this.CurrentSubqueryBinding.ShouldBeOnNewQuery)
{
this.currentQuery = this.currentQuery.PackageQuery(this.InScope);
this.CurrentQuery = this.CurrentQuery.PackageQuery(this.InScope);
this.CurrentSubqueryBinding.ShouldBeOnNewQuery = false;
}

return this.currentQuery;
return this.CurrentQuery;
}

public class SubqueryBinding
Expand Down
5 changes: 5 additions & 0 deletions Microsoft.Azure.Cosmos/src/Linq/TypeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public static Type GetElementType(Type type)
return GetElementType(type, new HashSet<Type>());
}

public static string GetMemberName(this MemberInfo memberInfo, ICosmosLinqSerializer serializer, CosmosLinqSerializerOptions linqSerializerOptions = null)
{
return serializer.GetMemberName(memberInfo, linqSerializerOptions);
}

private static Type GetElementType(Type type, HashSet<Type> visitedSet)
{
Debug.Assert(type != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,11 @@ public Datum2(string jsonProperty, string dataMember, string defaultMember, stri
[TestMethod]
public void TestAttributePriority()
{
Assert.AreEqual("jsonProperty", CosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("JsonProperty").First()));
Assert.AreEqual("dataMember", CosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("DataMember").First()));
Assert.AreEqual("Default", CosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("Default").First()));
Assert.AreEqual("jsonPropertyHasHigherPriority", CosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("JsonPropertyAndDataMember").First()));
ICosmosLinqSerializer cosmosLinqSerializer = new CosmosLinqSerializer();
Assert.AreEqual("jsonProperty", cosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("JsonProperty").First()));
Assert.AreEqual("dataMember", cosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("DataMember").First()));
Assert.AreEqual("Default", cosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("Default").First()));
Assert.AreEqual("jsonPropertyHasHigherPriority", cosmosLinqSerializer.GetMemberName(typeof(Datum).GetMember("JsonPropertyAndDataMember").First()));
}

/// <summary>
Expand Down