From 7a7e5cd7af5fdaaf575acfd656768b3668e239df Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Thu, 29 Feb 2024 17:06:25 +0100 Subject: [PATCH 1/3] Fallback to PassParametersByName when BindByName is not available to support DevArt. --- src/SqlPersistence/Config/SqlDialect_Oracle.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/SqlPersistence/Config/SqlDialect_Oracle.cs b/src/SqlPersistence/Config/SqlDialect_Oracle.cs index 4eed1145a..8bd9175e6 100644 --- a/src/SqlPersistence/Config/SqlDialect_Oracle.cs +++ b/src/SqlPersistence/Config/SqlDialect_Oracle.cs @@ -13,7 +13,7 @@ public abstract partial class SqlDialect /// public partial class Oracle : SqlDialect { - volatile PropertyInfo bindByName; + volatile PropertyInfo parametersByNameProperty; internal override void SetJsonParameterValue(DbParameter parameter, object value) { @@ -42,16 +42,19 @@ internal override CommandWrapper CreateCommand(DbConnection connection) { var command = connection.CreateCommand(); - if (bindByName == null) + if (parametersByNameProperty == null) { var type = command.GetType(); - bindByName = type.GetProperty("BindByName"); - if (bindByName == null) + parametersByNameProperty = type.GetProperty("BindByName") ?? + // someone might be using DevArt Oracle provider which uses PassParametersByName + type.GetProperty("PassParametersByName"); + if (parametersByNameProperty == null) { - throw new Exception($"Could not extract field 'BindByName' from '{type.AssemblyQualifiedName}'."); + throw new Exception($"Could not extract property 'BindByName' nor 'PassParametersByName' from '{type.AssemblyQualifiedName}'. The property is required to make sure the parameters passed to the commands can be passed by name and do not depend on the order they are added to the command."); } } - bindByName.SetValue(command, true); + + parametersByNameProperty.SetValue(command, true); return new CommandWrapper(command, this); } From ace4fbe719cb42edc8e23fc1474c4ccc7b6c2f2a Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Fri, 1 Mar 2024 12:03:03 +0100 Subject: [PATCH 2/3] Bump vulnerable dependencies for tests --- src/TestHelper/TestHelper.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestHelper/TestHelper.csproj b/src/TestHelper/TestHelper.csproj index bd2d55639..649f6ec18 100644 --- a/src/TestHelper/TestHelper.csproj +++ b/src/TestHelper/TestHelper.csproj @@ -12,7 +12,7 @@ - + From af1de5335263ed6fb6e78b1d1f4a942e838b2ccf Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Fri, 8 Mar 2024 18:25:54 +0100 Subject: [PATCH 3/3] Read boolean as int if necessary --- src/SqlPersistence/Extensions.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/SqlPersistence/Extensions.cs b/src/SqlPersistence/Extensions.cs index 61cdcf9fb..7e0bdd98c 100644 --- a/src/SqlPersistence/Extensions.cs +++ b/src/SqlPersistence/Extensions.cs @@ -72,16 +72,21 @@ public static void AddParameter(this DbCommand command, string name, Version val public static async Task GetBoolAsync(this DbDataReader reader, int position, CancellationToken cancellationToken = default) { var type = reader.GetFieldType(position); - // MySql stores bools as ints + // MySql stores bools as longs (ulong) if (type == typeof(ulong)) { return Convert.ToBoolean(await reader.GetFieldValueAsync(position, cancellationToken).ConfigureAwait(false)); } - // In Oracle we store bools as NUMBER(1,0) (short). + // In Oracle default driver store bools as NUMBER(1,0) (short). if (type == typeof(short)) { return Convert.ToBoolean(await reader.GetFieldValueAsync(position, cancellationToken).ConfigureAwait(false)); } + // or it might be stored as ints. + if (type == typeof(int)) + { + return Convert.ToBoolean(await reader.GetFieldValueAsync(position, cancellationToken).ConfigureAwait(false)); + } return await reader.GetFieldValueAsync(position, cancellationToken).ConfigureAwait(false); }