Skip to content

Commit

Permalink
Translate string Contains, StartsWith, and EndsWith
Browse files Browse the repository at this point in the history
Summary of changes
- Adds initial StringMethodTranslator for Cosmos provider.
- Translates Contains, StartsWith, and EndsWith

Addresses part of dotnet#16143
  • Loading branch information
jviau committed Jan 10, 2020
1 parent 3ae7e28 commit b58b093
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public CosmosMethodCallTranslatorProvider(
new IMethodCallTranslator[]
{
new EqualsTranslator(sqlExpressionFactory),
//new StringMethodTranslator(sqlExpressionFactory),
new StringMethodTranslator(sqlExpressionFactory),
new ContainsTranslator(sqlExpressionFactory)
//new LikeTranslator(sqlExpressionFactory),
//new EnumHasFlagTranslator(sqlExpressionFactory),
Expand Down
81 changes: 81 additions & 0 deletions src/EFCore.Cosmos/Query/Internal/StringMethodTranslator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
{
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public class StringMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _containsMethodInfo
= typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) });

private static readonly MethodInfo _startsWithMethodInfo
= typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });

private static readonly MethodInfo _endsWithMethodInfo
= typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });

private readonly ISqlExpressionFactory _sqlExpressionFactory;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public StringMethodTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList<SqlExpression> arguments)
{
Check.NotNull(method, nameof(method));
Check.NotNull(arguments, nameof(arguments));

if (_containsMethodInfo.Equals(method))
{
return TranslateSystemFunction("CONTAINS", instance, arguments[0], typeof(bool));
}

if (_startsWithMethodInfo.Equals(method))
{
return TranslateSystemFunction("STARTSWITH", instance, arguments[0], typeof(bool));
}

if (_endsWithMethodInfo.Equals(method))
{
return TranslateSystemFunction("ENDSWITH", instance, arguments[0], typeof(bool));
}

return null;
}

private SqlExpression TranslateSystemFunction(string function, SqlExpression instance, SqlExpression pattern, Type returnType)
{
Check.NotNull(instance, nameof(instance));
return _sqlExpressionFactory.Function(
function,
new[] { instance, pattern },
returnType,
ExpressionExtensions.InferTypeMapping(instance, pattern));
}
}
}

0 comments on commit b58b093

Please sign in to comment.