From b9fc03244a1d4e6a1e0486eb0960292839d8c0b2 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Tue, 12 Nov 2024 18:19:44 -0500 Subject: [PATCH 1/5] Add commandinterceptors to remove DBnull errors --- src/Libraries/Interceptor.cs | 27 ++++++++++++++++++++ src/Libraries/MySql.cs | 5 +++- src/Libraries/Utf8mb3.cs | 48 ++++++++++++++++++++++++++++++++++++ src/Oxide.MySql.csproj | 3 +++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/Libraries/Interceptor.cs create mode 100644 src/Libraries/Utf8mb3.cs diff --git a/src/Libraries/Interceptor.cs b/src/Libraries/Interceptor.cs new file mode 100644 index 0000000..5316c3a --- /dev/null +++ b/src/Libraries/Interceptor.cs @@ -0,0 +1,27 @@ +using System; +using System.Data; +using MySql.Data.MySqlClient; + +namespace CommandApp +{ + /// + /// Filters out collations with NULL id (e.g. UCA-14.0.0) from SHOW COLLATION command + /// Credit to Jeffraska + /// https://github.com/jeffraska/Jf.MySql.Data.Collations + /// + public sealed class Interceptor : BaseCommandInterceptor + { + public override bool ExecuteReader(string sql, CommandBehavior behavior, ref MySqlDataReader returnValue) + { + if (!sql.Equals("SHOW COLLATION", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + using var command = ActiveConnection.CreateCommand(); + command.CommandText = "SHOW COLLATION WHERE id IS NOT NULL"; + returnValue = command.ExecuteReader(behavior); + return true; + } + } +} diff --git a/src/Libraries/MySql.cs b/src/Libraries/MySql.cs index 0ab8f56..8492e8f 100644 --- a/src/Libraries/MySql.cs +++ b/src/Libraries/MySql.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Threading; +using CommandApp; namespace Oxide.Core.MySql.Libraries { @@ -220,7 +221,9 @@ private void Worker() [LibraryFunction("OpenDb")] public Connection OpenDb(string host, int port, string database, string user, string password, Plugin plugin, bool persistent = false) { - return OpenDb($"Server={host};Port={port};Database={database};User={user};Password={password};Pooling=false;default command timeout=120;Allow Zero Datetime=true;", plugin, persistent); + string interceptor = "CommandApp.Interceptor," + typeof(CommandApp.Interceptor).Assembly.FullName; + Utf8mb3.Enable(); + return OpenDb($"Server={host};Port={port};Database={database};User={user};Password={password};Pooling=false;default command timeout=120;Allow Zero Datetime=true;commandinterceptors={interceptor};", plugin, persistent); } public Connection OpenDb(string conStr, Plugin plugin, bool persistent = false) diff --git a/src/Libraries/Utf8mb3.cs b/src/Libraries/Utf8mb3.cs new file mode 100644 index 0000000..d6248f1 --- /dev/null +++ b/src/Libraries/Utf8mb3.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections; +using MySql.Data.MySqlClient; + +namespace CommandApp +{ + // ReSharper disable once InconsistentNaming + /// Credit to Jeffraska + /// https://github.com/jeffraska/Jf.MySql.Data.Collations + /// + public static class Utf8mb3 + { + private static readonly Version NewFieldNamingVersion = new Version(6, 10, 0); + + public static void Enable() + { + // Add internal mapping of database utf8mb3 charset to .NET framework's UTF-8 encoding + var assembly = System.Reflection.Assembly.GetAssembly(typeof(MySqlConnection)); + var connectorVersion = assembly.GetName().Version; + + var mappingFieldName = connectorVersion >= NewFieldNamingVersion ? "_mapping" : "mapping"; + + var mappingField = assembly + .GetType("MySql.Data.MySqlClient.CharSetMap").GetField(mappingFieldName, + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | + System.Reflection.BindingFlags.Static); + + if (mappingField != null) + { + var mappingDictionary = (IDictionary)mappingField.GetValue(null); + var utf8Mapping = mappingDictionary["utf8"]; + + if (utf8Mapping != null) + { + try + { + mappingDictionary.Add("utf8mb3", utf8Mapping); + mappingDictionary.Add("utf8mb4", utf8Mapping); + } + catch (ArgumentException) + { + // Item already exist + } + } + } + } + } +} diff --git a/src/Oxide.MySql.csproj b/src/Oxide.MySql.csproj index 6fa230b..472066b 100644 --- a/src/Oxide.MySql.csproj +++ b/src/Oxide.MySql.csproj @@ -16,6 +16,9 @@ True NU1701 + + 9.0 + From 610f0387731f7a43584a21e0b8a3b57b83abd301 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Tue, 12 Nov 2024 22:14:10 -0500 Subject: [PATCH 2/5] . --- src/Libraries/Utf8mb3.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Libraries/Utf8mb3.cs b/src/Libraries/Utf8mb3.cs index d6248f1..926e7bf 100644 --- a/src/Libraries/Utf8mb3.cs +++ b/src/Libraries/Utf8mb3.cs @@ -35,7 +35,6 @@ public static void Enable() try { mappingDictionary.Add("utf8mb3", utf8Mapping); - mappingDictionary.Add("utf8mb4", utf8Mapping); } catch (ArgumentException) { From 601914de67f7f611eaf9e367f8c1ce3858f4956c Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Wed, 13 Nov 2024 10:31:03 -0500 Subject: [PATCH 3/5] charsetmap change + more test validation --- src/Libraries/Utf8mb3.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Libraries/Utf8mb3.cs b/src/Libraries/Utf8mb3.cs index 926e7bf..341ce2e 100644 --- a/src/Libraries/Utf8mb3.cs +++ b/src/Libraries/Utf8mb3.cs @@ -10,7 +10,9 @@ namespace CommandApp /// public static class Utf8mb3 { - private static readonly Version NewFieldNamingVersion = new Version(6, 10, 0); + // verified that starting version 6.10.0, CharSetMap.mapping was changed to CharSetMap._mapping + // code will still work if MySql.Data.dll is upgraded + private static readonly Version NewFieldNamingVersion = new Version(6, 10, 0); public static void Enable() { @@ -35,6 +37,7 @@ public static void Enable() try { mappingDictionary.Add("utf8mb3", utf8Mapping); + mappingDictionary.Add("utf8mb4", utf8Mapping); } catch (ArgumentException) { From d3693da505d0f907a114c8f055701a0359056a26 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Wed, 13 Nov 2024 11:00:59 -0500 Subject: [PATCH 4/5] move patch to second opendb function --- src/Libraries/MySql.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Libraries/MySql.cs b/src/Libraries/MySql.cs index 8492e8f..52fe4eb 100644 --- a/src/Libraries/MySql.cs +++ b/src/Libraries/MySql.cs @@ -221,13 +221,13 @@ private void Worker() [LibraryFunction("OpenDb")] public Connection OpenDb(string host, int port, string database, string user, string password, Plugin plugin, bool persistent = false) { - string interceptor = "CommandApp.Interceptor," + typeof(CommandApp.Interceptor).Assembly.FullName; - Utf8mb3.Enable(); - return OpenDb($"Server={host};Port={port};Database={database};User={user};Password={password};Pooling=false;default command timeout=120;Allow Zero Datetime=true;commandinterceptors={interceptor};", plugin, persistent); + return OpenDb($"Server={host};Port={port};Database={database};User={user};Password={password};Pooling=false;default command timeout=120;Allow Zero Datetime=true;", plugin, persistent); } public Connection OpenDb(string conStr, Plugin plugin, bool persistent = false) { + Utf8mb3.Enable(); + conStr += ";commandinterceptors=CommandApp.Interceptor," + typeof(CommandApp.Interceptor).Assembly.FullName; Dictionary connections; if (!_connections.TryGetValue(plugin?.Name ?? "null", out connections)) { From d7927c0ffb87fd04f5c6f296391624c4e9a61ad8 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Wed, 13 Nov 2024 13:57:47 -0500 Subject: [PATCH 5/5] remove utf8mb4 mapping because its already there in all version --- src/Libraries/Utf8mb3.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Libraries/Utf8mb3.cs b/src/Libraries/Utf8mb3.cs index 341ce2e..e106751 100644 --- a/src/Libraries/Utf8mb3.cs +++ b/src/Libraries/Utf8mb3.cs @@ -37,7 +37,6 @@ public static void Enable() try { mappingDictionary.Add("utf8mb3", utf8Mapping); - mappingDictionary.Add("utf8mb4", utf8Mapping); } catch (ArgumentException) {