From c9ad7b6194e20b0cff1ac8f7800684b1c33537cc Mon Sep 17 00:00:00 2001 From: opejanovic Date: Sat, 21 Dec 2024 18:42:13 +0100 Subject: [PATCH 01/12] Enriching OracleParameterInfo with flag for PII data Added a new flag, MaskValueWhenLogging, to the OracleParameterInfo class. This flag is used to identify Oracle parameters containing Personally Identifiable Information (PII). When set to true, the parameter values can be masked in logs to enhance data security and compliance with privacy standards. --- src/Dapper.Oracle/OracleDynamicParameters.cs | 27 ++++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Dapper.Oracle/OracleDynamicParameters.cs b/src/Dapper.Oracle/OracleDynamicParameters.cs index cfb6bc5..10c7029 100644 --- a/src/Dapper.Oracle/OracleDynamicParameters.cs +++ b/src/Dapper.Oracle/OracleDynamicParameters.cs @@ -1,4 +1,4 @@ -//// Based on Gist found here: https://gist.github.com/vijaysg/3096151 +//// Based on Gist found here: https://gist.github.com/vijaysg/3096151 using System; using System.Collections; @@ -109,6 +109,7 @@ public void AddDynamicParams(dynamic param) /// /// /// + /// a flag that this param contains sensitive data and it must be masked in case of logging values public void Add( string name, object value = null, @@ -121,7 +122,8 @@ public void Add( string sourceColumn = null, DataRowVersion? sourceVersion = null, OracleMappingCollectionType? collectionType = null, - int[] arrayBindSize = null) + int[] arrayBindSize = null, + bool maskValueWhenLogging = false) { Parameters[Clean(name)] = new OracleParameterInfo() { @@ -136,7 +138,8 @@ public void Add( SourceColumn = sourceColumn, SourceVersion = sourceVersion ?? DataRowVersion.Current, CollectionType = collectionType ?? OracleMappingCollectionType.None, - ArrayBindSize = arrayBindSize + ArrayBindSize = arrayBindSize, + MaskValueWhenLogging = maskValueWhenLogging }; } @@ -167,7 +170,7 @@ public T Get(string name) } return default(T); } - + return OracleValueConverter.Convert(val); } @@ -239,10 +242,10 @@ protected virtual void AddParameters(IDbCommand command, SqlMapper.Identity iden } OracleMethodHelper.SetOracleParameters(p, param); - + p.Direction = param.ParameterDirection; - - var val = param.Value; + + var val = param.Value; if (val != null && OracleTypeMapper.HasTypeHandler(val.GetType(), out var handler)) { @@ -251,7 +254,7 @@ protected virtual void AddParameters(IDbCommand command, SqlMapper.Identity iden else { p.Value = val ?? DBNull.Value; - + var s = val as string; if (s?.Length <= 4000) { @@ -262,8 +265,8 @@ protected virtual void AddParameters(IDbCommand command, SqlMapper.Identity iden { p.Size = param.Size.Value; } - } - + } + if (add) { command.Parameters.Add(p); @@ -320,6 +323,8 @@ public class OracleParameterInfo public OracleParameterMappingStatus Status { get; set; } public IDbDataParameter AttachedParam { get; set; } + + public bool MaskValueWhenLogging { get; set; } } /// @@ -328,4 +333,4 @@ public class OracleParameterInfo /// public IEnumerator GetEnumerator() => Parameters.GetEnumerator(); } -} \ No newline at end of file +} From bcdf52748bcafd37942fa3e60ce3b71af45cc45b Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:19:35 +0200 Subject: [PATCH 02/12] Create OracleDecimalConversion.cs --- src/Dapper.Oracle/OracleDecimalConversion.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/Dapper.Oracle/OracleDecimalConversion.cs diff --git a/src/Dapper.Oracle/OracleDecimalConversion.cs b/src/Dapper.Oracle/OracleDecimalConversion.cs new file mode 100644 index 0000000..10c1226 --- /dev/null +++ b/src/Dapper.Oracle/OracleDecimalConversion.cs @@ -0,0 +1,17 @@ +namespace Dapper.Oracle +{ + /// + /// Maps Oracle native numeric values (especially OracleDecimal) to , + /// using OracleDecimal.SetPrecision(..., 28) before reading System.Decimal (same idea as legacy ADO.NET). + /// + /// + /// Used internally by (for example from ). + /// Dapper's default Query<decimal> / ExecuteScalar<decimal> does not call this; for result sets use this helper on raw values, SQL CAST, or a custom TypeHandler. + /// + public static class OracleDecimalConversion + { + public static decimal ToDecimal(object value) => OracleValueConverter.Convert(value); + + public static decimal? ToDecimalNullable(object value) => OracleValueConverter.Convert(value); + } +} From 1ce1844e914b6a978942b1f1e227905d97cf5075 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:20:24 +0200 Subject: [PATCH 03/12] Update OracleValueConverter.cs Converts OracleDecimal to .NET Decimal --- src/Dapper.Oracle/OracleValueConverter.cs | 54 ++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Dapper.Oracle/OracleValueConverter.cs b/src/Dapper.Oracle/OracleValueConverter.cs index fe1f579..8aa9719 100644 --- a/src/Dapper.Oracle/OracleValueConverter.cs +++ b/src/Dapper.Oracle/OracleValueConverter.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Linq; +using System.Reflection; using System.Reflection.Emit; using System.Text.RegularExpressions; @@ -126,7 +127,10 @@ private static T ConvertArray(object value) var decimalArray = new decimal[arr.Length]; for (int i = 0; i < arr.Length; i++) { - decimalArray[i] = decimal.Parse(arr.GetValue(i)?.ToString()); + var raw = arr.GetValue(i); + decimalArray[i] = TryReduceOracleDecimalToSystemDecimal(raw, out var systemDecimal) + ? systemDecimal + : decimal.Parse(raw?.ToString() ?? "0"); } return (T)System.Convert.ChangeType(decimalArray, nullableType ?? typeof(T)); case "System.Boolean[]": @@ -187,6 +191,12 @@ private static object GetValue(object value) return null; } + // Legacy ADO.NET: OracleDecimal.SetPrecision(..., 28).Value — no compile-time reference to Oracle.ManagedDataAccess. + if (TryReduceOracleDecimalToSystemDecimal(value, out var asDecimal)) + { + return asDecimal; + } + var val = valueType.GetProperty("Value")?.GetValue(value); if (val != null) { @@ -208,5 +218,45 @@ private static bool IsOracleDataStructure(Type valueType) // See: https://docs.oracle.com/en/database/oracle/oracle-database/19/odpnt/intro003.html#GUID-425C9EBA-CFFC-47FE-B490-604251714ACA return Regex.IsMatch(valueType.FullName, @"Oracle\.\w+\.Types\.Oracle\w+"); } + + private const string OracleDecimalTypeFullName = "Oracle.ManagedDataAccess.Types.OracleDecimal"; + + private static bool IsOracleDecimal(Type type) => + type != null && type.FullName == OracleDecimalTypeFullName; + + /// + /// Calls OracleDecimal.SetPrecision(instance, 28).Value via reflection when ODP.NET is loaded at runtime. + /// + private static bool TryReduceOracleDecimalToSystemDecimal(object value, out decimal systemDecimal) + { + systemDecimal = default; + if (value == null || !IsOracleDecimal(value.GetType())) + { + return false; + } + + var t = value.GetType(); + var setPrecision = t.GetMethod( + "SetPrecision", + BindingFlags.Public | BindingFlags.Static, + binder: null, + types: new[] { t, typeof(int) }, + modifiers: null); + if (setPrecision == null) + { + return false; + } + + var reduced = setPrecision.Invoke(null, new object[] { value, 28 }); + var valueProp = t.GetProperty("Value"); + var boxed = valueProp?.GetValue(reduced); + if (boxed is decimal d) + { + systemDecimal = d; + return true; + } + + return false; + } } } From 02e6a48ece2f0b5f6fb8dd595557e2df01df8dd5 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:21:14 +0200 Subject: [PATCH 04/12] Update OracleValueConverterTests.cs --- .../OracleValueConverterTests.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Tests.Dapper.Oracle/OracleValueConverterTests.cs b/src/Tests.Dapper.Oracle/OracleValueConverterTests.cs index dcc0ef5..b3ba639 100644 --- a/src/Tests.Dapper.Oracle/OracleValueConverterTests.cs +++ b/src/Tests.Dapper.Oracle/OracleValueConverterTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Dapper.Oracle; using FluentAssertions; @@ -249,6 +249,22 @@ public void GetOracleDecimalReturnsDecimal() result.Should().Be(expected); } + [Fact] + public void GetOracleDecimalMatchesExplicitSetPrecision28() + { + foreach (var d in new[] + { + 0m, + 1m, + 0.4690679611650485436893203883m, + }) + { + var od = new OracleDecimal(d); + var expected = OracleDecimal.SetPrecision(od, 28).Value; + OracleValueConverter.Convert(od).Should().Be(expected); + } + } + [Fact] public void GetOracleDecimalReturnsNullableDecimal() { From 19cbd12f2f618914c8ed07ebb6d69bf5e1577ec9 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:42:10 +0200 Subject: [PATCH 05/12] Update Dapper.Oracle.csproj --- src/Dapper.Oracle/Dapper.Oracle.csproj | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Dapper.Oracle/Dapper.Oracle.csproj b/src/Dapper.Oracle/Dapper.Oracle.csproj index 305e81d..e6fcf11 100644 --- a/src/Dapper.Oracle/Dapper.Oracle.csproj +++ b/src/Dapper.Oracle/Dapper.Oracle.csproj @@ -1,26 +1,28 @@ - + false - net7.0 + net10.0 -Version 2.0.4: - - Updated to use .net 7.0. - - Dependency switched to most recent version of Dapper: 2.0.123. - - Dependencies updated also for test project. - + Version 2.1.0: + - Updated to use .net 10.0. + - Dependency switched to most recent version of Dapper: 2.1.66. + - Dependencies updated also for test project. + - Fix OracleDecimal to System.Decimal conversion overflow handling + - Enriching OracleParameterInfo with flag for PII data + - + - \ No newline at end of file + From c00d2ffc1855218ed0c64d1706c7c09eacf40a68 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:43:14 +0200 Subject: [PATCH 06/12] Update Dapper.Oracle.StrongName.csproj --- .../Dapper.Oracle.StrongName.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj b/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj index 3bdda7a..46985a1 100644 --- a/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj +++ b/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj @@ -1,9 +1,9 @@ - + false - net7.0 + net10.0 true key.snk @@ -19,4 +19,4 @@ - \ No newline at end of file + From ab7abeab2fbf19c9f67d46a208143a1ce0c16778 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:44:45 +0200 Subject: [PATCH 07/12] Update Tests.Dapper.Oracle.csproj --- src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj b/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj index af10b18..6dbab6d 100644 --- a/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj +++ b/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj @@ -1,22 +1,22 @@ - + true - net7.0 + net10.0 false - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -39,4 +39,4 @@ - \ No newline at end of file + From aa21785a6cf1304fda568c2500941ab251719b97 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 09:45:18 +0200 Subject: [PATCH 08/12] Update build.ps1 --- build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.ps1 b/build.ps1 index add4cf0..a013173 100644 --- a/build.ps1 +++ b/build.ps1 @@ -11,4 +11,4 @@ if ($connectionstring) dotnet restore .\src\Dapper.Oracle.sln dotnet build .\src\Dapper.Oracle.sln dotnet test .\src\Dapper.Oracle.sln -dotnet pack .\src\Dapper.Oracle.sln -p:PackageVersion=2.0.4 \ No newline at end of file +dotnet pack .\src\Dapper.Oracle.sln -p:PackageVersion=2.1.0 From 3062401bba9244993badf3270c2ad4db705307d1 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 12:05:12 +0200 Subject: [PATCH 09/12] Update Dapper.Oracle.csproj --- src/Dapper.Oracle/Dapper.Oracle.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Dapper.Oracle/Dapper.Oracle.csproj b/src/Dapper.Oracle/Dapper.Oracle.csproj index e6fcf11..0289057 100644 --- a/src/Dapper.Oracle/Dapper.Oracle.csproj +++ b/src/Dapper.Oracle/Dapper.Oracle.csproj @@ -10,7 +10,7 @@ Version 2.1.0: - Updated to use .net 10.0. - - Dependency switched to most recent version of Dapper: 2.1.66. + - Dependency switched to most recent version of Dapper: 2.1.72. - Dependencies updated also for test project. - Fix OracleDecimal to System.Decimal conversion overflow handling - Enriching OracleParameterInfo with flag for PII data @@ -19,10 +19,10 @@ - + - + From 73a1087875b81a742d2a2964377e498501fad01a Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 12:05:45 +0200 Subject: [PATCH 10/12] Update Dapper.Oracle.StrongName.csproj --- src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj b/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj index 46985a1..ee76527 100644 --- a/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj +++ b/src/Dapper.Oracle.StrongName/Dapper.Oracle.StrongName.csproj @@ -13,10 +13,10 @@ - + - + From 95f9c97ecdece97095c935e18c95127c420bed4a Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 12:06:20 +0200 Subject: [PATCH 11/12] Update DatabaseFixture.cs --- src/Tests.Dapper.Oracle/IntegrationTests/DatabaseFixture.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Tests.Dapper.Oracle/IntegrationTests/DatabaseFixture.cs b/src/Tests.Dapper.Oracle/IntegrationTests/DatabaseFixture.cs index 80c64c6..f3477ce 100644 --- a/src/Tests.Dapper.Oracle/IntegrationTests/DatabaseFixture.cs +++ b/src/Tests.Dapper.Oracle/IntegrationTests/DatabaseFixture.cs @@ -35,10 +35,9 @@ public void Dispose() public async Task InitializeAsync() { + // Prefer DA_OR_CONNECTION (CI / local Oracle). Do not overwrite it — a hardcoded default used to break env-based runs. var connectionString = Environment.GetEnvironmentVariable("DA_OR_CONNECTION"); - connectionString = "Data Source=localhost/dips;User Id=system;Password=oracle"; - if (string.IsNullOrEmpty(connectionString)) { var si = new ProcessStartInfo("powershell", @".\LocalOracleDockerDb.ps1"); @@ -100,4 +99,4 @@ private static string GetBootstrapFolder() } } -} \ No newline at end of file +} From a4faa272de00c6444aba366df22c56ec127580a1 Mon Sep 17 00:00:00 2001 From: opejanovic Date: Thu, 14 May 2026 12:06:44 +0200 Subject: [PATCH 12/12] Update Tests.Dapper.Oracle.csproj --- .../Tests.Dapper.Oracle.csproj | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj b/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj index 6dbab6d..bf51727 100644 --- a/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj +++ b/src/Tests.Dapper.Oracle/Tests.Dapper.Oracle.csproj @@ -5,18 +5,23 @@ true net10.0 false + + false + + + Category!=Integration&Category!=IntegrationTest - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -36,7 +41,7 @@ - +