From 8fdcb9c313e929aa6793417664df6dcd316bb225 Mon Sep 17 00:00:00 2001 From: Heliosares Date: Fri, 18 Aug 2023 10:32:19 -0400 Subject: [PATCH] Fix encoding issues --- pom.xml | 2 +- .../auxprotect/database/MigrationManager.java | 25 ++- .../auxprotect/database/SQLManager.java | 169 ++++++++++-------- .../heliosares/auxprotect/database/Table.java | 9 +- 4 files changed, 121 insertions(+), 84 deletions(-) diff --git a/pom.xml b/pom.xml index 7bde3d3..f4224f0 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 AuxProtect AuxProtect - 1.2.8-pre1 + 1.2.8-pre2 AuxProtect ${project.artifactId}-${project.version} diff --git a/src/main/java/dev/heliosares/auxprotect/database/MigrationManager.java b/src/main/java/dev/heliosares/auxprotect/database/MigrationManager.java index 7b5ffd5..f8f5fa2 100644 --- a/src/main/java/dev/heliosares/auxprotect/database/MigrationManager.java +++ b/src/main/java/dev/heliosares/auxprotect/database/MigrationManager.java @@ -11,7 +11,7 @@ import java.sql.*; import java.util.*; public class MigrationManager { - public static final int TARGET_DB_VERSION = 13; + public static final int TARGET_DB_VERSION = 14; private final SQLManager sql; private final Connection connection; private final IAuxProtect plugin; @@ -434,6 +434,19 @@ public class MigrationManager { } })); + + // + // 14 + // + + migrationActions.put(14, new MigrationAction(sql.isMySQL(), () -> { + }, () -> { + for (Table table : Table.values()) { + if (!table.hasStringTarget() && !table.hasData()) continue; + sql.execute("ALTER TABLE " + table + " CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;", connection); + } + })); + // // Finalizing // @@ -513,7 +526,15 @@ public class MigrationManager { + "..."); plugin.info("This may take a while. Please do not interrupt."); isMigrating = true; - if (!sql.isMySQL()) { + boolean needBackup = false; + for (int i = sql.getVersion() + 1; i <= TARGET_DB_VERSION; i++) { + MigrationAction action = migrationActions.get(i); + if (action.necessary) { + needBackup = true; + break; + } + } + if (!sql.isMySQL() && needBackup) { String path = sql.backup(connection); if (path != null) plugin.info("Pre-migration database backup created: " + path); } diff --git a/src/main/java/dev/heliosares/auxprotect/database/SQLManager.java b/src/main/java/dev/heliosares/auxprotect/database/SQLManager.java index 3c22c18..9c1b214 100644 --- a/src/main/java/dev/heliosares/auxprotect/database/SQLManager.java +++ b/src/main/java/dev/heliosares/auxprotect/database/SQLManager.java @@ -116,7 +116,7 @@ public class SQLManager extends ConnectionPool { try { super.init(this::init); } catch (SQLException e) { - if (migrationmanager.isMigrating()) { + if (migrationmanager != null && migrationmanager.isMigrating()) { plugin.warning( "Error while migrating database. This database will likely not work with the current version. You will need to restore a backup (plugins/AuxProtect/database/backups) and try again. Please contact the plugin developer if you are unable to complete migration."); } @@ -203,101 +203,112 @@ public class SQLManager extends ConnectionPool { } private void init(Connection connection) throws SQLException, BusyException { - this.migrationmanager = new MigrationManager(this, connection, plugin); - migrationmanager.preTables(); + startTransaction(connection); + try { + this.migrationmanager = new MigrationManager(this, connection, plugin); + migrationmanager.preTables(); - if (invdiffmanager != null) { - invdiffmanager.createTable(connection); - } - - if (invblobmanager != null) { - invblobmanager.createTable(connection); - } - - for (Table table : Table.values()) { - if (table.hasAPEntries()) { - execute(table.getSQLCreateString(plugin), connection); + if (invdiffmanager != null) { + invdiffmanager.createTable(connection); } - } - String stmt; - if (plugin.getPlatform() == PlatformType.SPIGOT) { - stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_INVDIFF; - stmt += " (time BIGINT, uid INT, slot INT, qty INT, blobid BIGINT, damage INT);"; - execute(stmt, connection); - stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_WORLDS; - stmt += " (name varchar(255), wid SMALLINT);"; - execute(stmt, connection); + if (invblobmanager != null) { + invblobmanager.createTable(connection); + } - stmt = "SELECT * FROM " + Table.AUXPROTECT_WORLDS + ";"; - debugSQLStatement(stmt); - try (Statement statement = connection.createStatement()) { - try (ResultSet results = statement.executeQuery(stmt)) { - while (results.next()) { - String world = results.getString("name"); - int wid = results.getInt("wid"); - worlds.put(world, wid); - if (wid >= nextWid) { - nextWid = wid + 1; + for (Table table : Table.values()) { + if (table.hasAPEntries()) { + execute(table.getSQLCreateString(plugin), connection); + } + } + String stmt; + if (plugin.getPlatform() == PlatformType.SPIGOT) { + stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_INVDIFF; + stmt += " (time BIGINT, uid INT, slot INT, qty INT, blobid BIGINT, damage INT);"; + execute(stmt, connection); + + stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_WORLDS; + stmt += " (name varchar(255), wid SMALLINT);"; + execute(stmt, connection); + + stmt = "SELECT * FROM " + Table.AUXPROTECT_WORLDS + ";"; + debugSQLStatement(stmt); + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(stmt)) { + while (results.next()) { + String world = results.getString("name"); + int wid = results.getInt("wid"); + worlds.put(world, wid); + if (wid >= nextWid) { + nextWid = wid + 1; + } } } } } - } - stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_LASTS; - stmt += " (name SMALLINT PRIMARY KEY, value BIGINT);"; - execute(stmt, connection); - for (LastKeys key : LastKeys.values()) { - try { - execute("INSERT INTO " + Table.AUXPROTECT_LASTS + " (name, value) VALUES (?,?)", connection, key.id); - } catch (SQLException ignored) { - // Ensures each LastKeys has a value, so we can just UPDATE later - } - } - - stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_API_ACTIONS - + " (name varchar(255), nid SMALLINT, pid SMALLINT, ntext varchar(255), ptext varchar(255));"; - execute(stmt, connection); - - stmt = "SELECT * FROM " + Table.AUXPROTECT_API_ACTIONS + ";"; - debugSQLStatement(stmt); - try (Statement statement = connection.createStatement()) { - try (ResultSet results = statement.executeQuery(stmt)) { - while (results.next()) { - String key = results.getString("name"); - int nid = results.getInt("nid"); - int pid = results.getInt("pid"); - String ntext = results.getString("ntext"); - String ptext = results.getString("ptext"); - nextActionId = Math.max(nextActionId, Math.max(nid, pid) + 1); - new EntryAction(key, nid, pid, ntext, ptext); + stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_LASTS; + stmt += " (name SMALLINT PRIMARY KEY, value BIGINT);"; + execute(stmt, connection); + for (LastKeys key : LastKeys.values()) { + try { + execute("INSERT INTO " + Table.AUXPROTECT_LASTS + " (name, value) VALUES (?,?)", connection, key.id); + } catch (SQLException ignored) { + // Ensures each LastKeys has a value, so we can just UPDATE later } } + + stmt = "CREATE TABLE IF NOT EXISTS " + Table.AUXPROTECT_API_ACTIONS + + " (name varchar(255), nid SMALLINT, pid SMALLINT, ntext varchar(255), ptext varchar(255));"; + execute(stmt, connection); + + stmt = "SELECT * FROM " + Table.AUXPROTECT_API_ACTIONS + ";"; + debugSQLStatement(stmt); + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(stmt)) { + while (results.next()) { + String key = results.getString("name"); + int nid = results.getInt("nid"); + int pid = results.getInt("pid"); + String ntext = results.getString("ntext"); + String ptext = results.getString("ptext"); + nextActionId = Math.max(nextActionId, Math.max(nid, pid) + 1); + new EntryAction(key, nid, pid, ntext, ptext); + } + } + } + + usermanager.init(connection); + + migrationmanager.postTables(); + + if (invdiffmanager != null) { + invdiffmanager.init(connection); + } + + if (invblobmanager != null) { + invblobmanager.init(connection); + } + + if (getLast(LastKeys.LEGACY_POSITIONS, connection) == 0) + setLast(LastKeys.LEGACY_POSITIONS, System.currentTimeMillis(), connection); + + execute("COMMIT", connection); + plugin.debug("init done."); + } catch (Throwable t) { + plugin.warning("An error occurred during initialization. Rolling back changes."); + execute("ROLLBACK", connection); + throw t; } + } - usermanager.init(connection); - - migrationmanager.postTables(); - - if (invdiffmanager != null) { - invdiffmanager.init(connection); - } - - if (invblobmanager != null) { - invblobmanager.init(connection); - } - - if (getLast(LastKeys.LEGACY_POSITIONS, connection) == 0) - setLast(LastKeys.LEGACY_POSITIONS, System.currentTimeMillis(), connection); - - plugin.debug("init done."); - + private void startTransaction(Connection connection) throws SQLException { + execute((isMySQL() ? "START" : "BEGIN") + " TRANSACTION", connection); } public int purgeUIDs() throws SQLException, BusyException { int count = executeReturn(connection -> { - execute((isMySQL() ? "START" : "BEGIN") + " TRANSACTION", connection); + startTransaction(connection); try { // Step 1: Create a Temporary Table execute("CREATE TEMP" + (isMySQL() ? "ORARY" : "") + " TABLE temp_uids (uid INT PRIMARY KEY)", connection); diff --git a/src/main/java/dev/heliosares/auxprotect/database/Table.java b/src/main/java/dev/heliosares/auxprotect/database/Table.java index 9464375..0536395 100644 --- a/src/main/java/dev/heliosares/auxprotect/database/Table.java +++ b/src/main/java/dev/heliosares/auxprotect/database/Table.java @@ -187,7 +187,7 @@ public enum Table { } else { stmt += "varchar(255)"; } - if(this==AUXPROTECT_LONGTERM) { + if (this == AUXPROTECT_LONGTERM) { stmt += ",\n target_hash INT"; } } else { @@ -207,7 +207,12 @@ public enum Table { stmt += ",\n qty INTEGER"; stmt += ",\n damage INTEGER"; } - stmt += "\n);"; + stmt += "\n)"; + + if (plugin.getSqlManager().isMySQL() && (hasStringTarget() || hasData())) { + stmt += " CHARACTER SET utf8mb4"; + stmt += " COLLATE utf8mb4_general_ci;"; + } return stmt; }