diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fb3babab25c..bd394346aca 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,58 +1,58 @@ - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 - + https://github.com/dotnet/runtime - f8c110b8003d68cc635add4ca791d6cf2e645561 + 4122c63a13cfe40e97ac1f9ef01d8110a66943f4 diff --git a/eng/Versions.props b/eng/Versions.props index 939fcafb103..dbae7877301 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -16,19 +16,19 @@ False - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 - 8.0.0-rc.1.23421.3 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 + 8.0.0-rc.2.23426.4 8.0.0-beta.23425.2 diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteDbFunctionsExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteDbFunctionsExtensions.cs index 585a0936030..f52da2ec8f4 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteDbFunctionsExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteDbFunctionsExtensions.cs @@ -43,6 +43,33 @@ public static bool Glob(this DbFunctions _, string matchExpression, string patte public static string Hex(this DbFunctions _, byte[] bytes) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Hex))); + /// + /// Maps to the SQLite unhex function which returns a BLOB representing decoding of the hexadecimal string. + /// + /// + /// See Database functions, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The instance. + /// The hexadecimal string. + /// Decoded hexadecimal string as binary value. + public static byte[] Unhex(this DbFunctions _, string value) + => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Unhex))); + + /// + /// Maps to the SQLite unhex function which returns a BLOB representing decoding of the hexadecimal string. + /// + /// + /// See Database functions, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The instance. + /// The hexadecimal string. + /// Characters that are ignored in . + /// Decoded hexadecimal string as binary value. + public static byte[] Unhex(this DbFunctions _, string value, string ignoreChars) + => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Unhex))); + /// /// Maps to the SQLite substr function which returns a subarray of the specified value. The subarray starts /// at and continues to the end of the value. diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteHexMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteHexMethodTranslator.cs index 68e759f7a85..ede730114ed 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteHexMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteHexMethodTranslator.cs @@ -13,9 +13,15 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal; /// public class SqliteHexMethodTranslator : IMethodCallTranslator { - private static readonly MethodInfo MethodInfo = typeof(SqliteDbFunctionsExtensions) + private static readonly MethodInfo HexMethodInfo = typeof(SqliteDbFunctionsExtensions) .GetMethod(nameof(SqliteDbFunctionsExtensions.Hex), new[] { typeof(DbFunctions), typeof(byte[]) })!; + private static readonly MethodInfo UnhexMethodInfo = typeof(SqliteDbFunctionsExtensions) + .GetMethod(nameof(SqliteDbFunctionsExtensions.Unhex), new[] { typeof(DbFunctions), typeof(string) })!; + + private static readonly MethodInfo UnhexWithIgnoreCharsMethodInfo = typeof(SqliteDbFunctionsExtensions) + .GetMethod(nameof(SqliteDbFunctionsExtensions.Unhex), new[] { typeof(DbFunctions), typeof(string), typeof(string) })!; + private readonly ISqlExpressionFactory _sqlExpressionFactory; /// @@ -41,7 +47,7 @@ public SqliteHexMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) IReadOnlyList arguments, IDiagnosticsLogger logger) { - if (method.Equals(MethodInfo)) + if (method.Equals(HexMethodInfo)) { return _sqlExpressionFactory.Function( "hex", @@ -51,6 +57,17 @@ public SqliteHexMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) typeof(string)); } + if (method.Equals(UnhexMethodInfo) + || method.Equals(UnhexWithIgnoreCharsMethodInfo)) + { + return _sqlExpressionFactory.Function( + "unhex", + arguments.Skip(1), + nullable: true, + arguments.Skip(1).Select(_ => true).ToArray(), + typeof(byte[])); + } + return null; } } diff --git a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs index 08fc4c6e23a..c1a73c88ac5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs @@ -1546,6 +1546,46 @@ SELECT hex("o"."Bytes") Assert.Equal(expectedResults, results); } + [ConditionalFact] + public virtual void Can_query_using_unhex_function() + { + using var context = CreateContext(); + + var results = context.Set() + .Select(e => EF.Functions.Unhex(EF.Functions.Hex(e.Bytes))).ToList(); + + AssertSql( +""" +SELECT unhex(hex("o"."Bytes")) +FROM "ObjectBackedDataTypes" AS "o" +"""); + + var expectedResults = context.Set().AsEnumerable() + .Select(e => e.Bytes).ToList(); + + Assert.Equal(expectedResults, results); + } + + [ConditionalFact] + public virtual void Can_query_using_unhex_function_with_ignore_chars() + { + using var context = CreateContext(); + + var results = context.Set() + .Select(e => EF.Functions.Unhex(EF.Functions.Hex(e.Bytes) + "!?", "!?")).ToList(); + + AssertSql( +""" +SELECT unhex(COALESCE(hex("o"."Bytes"), '') || '!?', '!?') +FROM "ObjectBackedDataTypes" AS "o" +"""); + + var expectedResults = context.Set().AsEnumerable() + .Select(e => e.Bytes).ToList(); + + Assert.Equal(expectedResults, results); + } + [ConditionalFact] public virtual void Can_query_using_substr_function() {