mirror of
https://github.com/GeorgH93/Minepacks.git
synced 2024-11-14 10:45:23 +01:00
Add MySQL to SQLite and SQLite to MySQL DB migration support
This commit is contained in:
parent
eef444d0bd
commit
f697c728c1
@ -18,9 +18,10 @@
|
||||
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
|
||||
|
||||
import at.pcgamingfreaks.ConsoleColor;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.*;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
|
||||
import at.pcgamingfreaks.PluginLib.Bukkit.PluginLib;
|
||||
import at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool;
|
||||
import at.pcgamingfreaks.Reflection;
|
||||
|
||||
import org.bukkit.event.HandlerList;
|
||||
@ -100,17 +101,38 @@ public void migrateDB(final String targetDatabaseType, final MigrationCallback c
|
||||
//endregion
|
||||
}
|
||||
|
||||
public Migration getMigrationPerformer(final String targetDatabaseType)
|
||||
public Migration getMigrationPerformer(String targetDatabaseType)
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean global = false;
|
||||
if(targetDatabaseType.toLowerCase().equals("external") ||targetDatabaseType.toLowerCase().equals("global") || targetDatabaseType.toLowerCase().equals("shared"))
|
||||
{
|
||||
DatabaseConnectionPool pool = PluginLib.getInstance().getDatabaseConnectionPool();
|
||||
if(pool == null)
|
||||
{
|
||||
plugin.getLogger().warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET);
|
||||
return null;
|
||||
}
|
||||
targetDatabaseType = pool.getDatabaseType().toLowerCase();
|
||||
global = true;
|
||||
}
|
||||
switch(targetDatabaseType.toLowerCase())
|
||||
{
|
||||
case "flat":
|
||||
case "file":
|
||||
case "files":
|
||||
if(plugin.getDatabase() instanceof Files) return null;
|
||||
return new SQLtoFilesMigration(plugin, plugin.getDatabase());
|
||||
if(!(plugin.getDatabase() instanceof SQL)) return null;
|
||||
return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase());
|
||||
case "mysql":
|
||||
if(global && plugin.getDatabase() instanceof MySQLShared || !global && plugin.getDatabase() instanceof MySQL) return null;
|
||||
if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "mysql", global);
|
||||
else {} //TODO Files to SQL
|
||||
case "sqlite":
|
||||
default:
|
||||
if(global && plugin.getDatabase() instanceof SQLiteShared || !global && plugin.getDatabase() instanceof SQLite) return null;
|
||||
if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "sqlite", global);
|
||||
else {} //TODO Files to SQL
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
|
||||
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
|
||||
@ -39,7 +38,7 @@ public class SQLtoFilesMigration extends Migration
|
||||
private final String sqlQuery;
|
||||
private final File saveFolder;
|
||||
|
||||
protected SQLtoFilesMigration(@NotNull Minepacks plugin, @NotNull Database oldDb) throws InvocationTargetException, IllegalAccessException
|
||||
protected SQLtoFilesMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb) throws InvocationTargetException, IllegalAccessException
|
||||
{
|
||||
super(plugin, oldDb);
|
||||
@Language("SQL") String query = "SELECT " + (plugin.getConfiguration().getUseUUIDs() ? "{FieldUUID}" : "{FieldName}") + ",{FieldBPITS},{FieldBPVersion} FROM {TablePlayers} INNER JOIN {TableBackpacks} ON {FieldPlayerID}={FieldBPOwner};";
|
||||
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2018 GeorgH93
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
|
||||
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Database.*;
|
||||
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
|
||||
import at.pcgamingfreaks.PluginLib.Bukkit.PluginLib;
|
||||
import at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool;
|
||||
import at.pcgamingfreaks.Reflection;
|
||||
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.*;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class SQLtoSQLMigration extends Migration
|
||||
{
|
||||
private static final Method METHOD_REPLACE_PLACEHOLDERS = Reflection.getMethod(SQL.class, "replacePlaceholders", String.class);
|
||||
private static final Field FIELD_PLAYER_ID = Reflection.getField(SQL.class, "fieldPlayerID");
|
||||
private static final Field FIELD_PLAYER_UUID = Reflection.getField(SQL.class, "fieldPlayerUUID");
|
||||
private static final Field FIELD_PLAYER_NAME = Reflection.getField(SQL.class, "fieldPlayerName");
|
||||
private static final Field FIELD_BP_OWNER = Reflection.getField(SQL.class, "fieldBpOwner");
|
||||
private static final Field FIELD_BP_ITS = Reflection.getField(SQL.class, "fieldBpIts");
|
||||
private static final Field FIELD_BP_VERSION = Reflection.getField(SQL.class, "fieldBpVersion");
|
||||
private static final Field FIELD_BP_LAST_UPDATE = Reflection.getField(SQL.class, "fieldBpLastUpdate");
|
||||
private static final DateFormat SQLITE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
private final SQL newDb;
|
||||
private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks;
|
||||
private final boolean uuid;
|
||||
private int autoIndex = 0;
|
||||
|
||||
protected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NonNls String dbType, boolean global) throws Exception
|
||||
{
|
||||
super(plugin, oldDb);
|
||||
if(global)
|
||||
{
|
||||
newDb = (SQL) Reflection.getConstructor((dbType.equals("mysql")) ? MySQLShared.class : SQLiteShared.class, Minepacks.class, DatabaseConnectionPool.class).newInstance(plugin, PluginLib.getInstance().getDatabaseConnectionPool());
|
||||
}
|
||||
else
|
||||
{
|
||||
newDb = (SQL) Reflection.getConstructor((dbType.equals("mysql")) ? MySQL.class : SQLite.class, Minepacks.class).newInstance(plugin);
|
||||
}
|
||||
uuid = plugin.getConfiguration().getUseUUIDs();
|
||||
//setup insert querys
|
||||
if(uuid)
|
||||
{
|
||||
queryInsertUsers = replacePlaceholders(newDb, "INSERT INTO {TablePlayers} ({FieldPlayerID},{FieldName},{FieldUUID}) VALUES (?,?,?);");
|
||||
}
|
||||
else
|
||||
{
|
||||
queryInsertUsers = replacePlaceholders(newDb, "INSERT INTO {TablePlayers} ({FieldPlayerID},{FieldName}) VALUES (?,?);");
|
||||
}
|
||||
queryInsertBackpacks = replacePlaceholders(newDb, "INSERT INTO {TableBackpacks} ({FieldBPOwner},{FieldBPITS},{FieldBPVersion},{FieldBPLastUpdate}) VALUES (?,?,?,?);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MigrationResult migrate() throws Exception
|
||||
{
|
||||
try(Connection readConnection = ((SQL) oldDb).getConnection(); Connection writeConnection = newDb.getConnection(); Statement readStatement = readConnection.createStatement())
|
||||
{
|
||||
int users = migrate("users", writeConnection, readStatement, "SELECT * FROM {TablePlayers};", queryInsertUsers);
|
||||
int backpacks = migrate("backpacks", writeConnection, readStatement, "SELECT * FROM {TableBackpacks};", queryInsertBackpacks);
|
||||
return new MigrationResult("Migrated " + users + " users and " + backpacks + " backpacks from " + oldDb.getClass().getSimpleName() + " to " + newDb.getClass().getSimpleName() + ".", MigrationResult.MigrationResultType.SUCCESS);
|
||||
}
|
||||
finally
|
||||
{
|
||||
newDb.close();
|
||||
}
|
||||
}
|
||||
|
||||
private int migrate(@NonNls String type, @NotNull Connection writeConnection, @NotNull Statement readStatement, @Language("SQL") String readQuery, @Language("SQL") String insertQuery) throws Exception
|
||||
{
|
||||
int count = 0;
|
||||
byte mode = (byte) ((type.equals("users")) ? 0 : 1);
|
||||
plugin.getLogger().info("Migrate " + type + " ...");
|
||||
try(ResultSet resultSet = readStatement.executeQuery(replacePlaceholders((SQL) oldDb, readQuery));
|
||||
PreparedStatement preparedStatement = writeConnection.prepareStatement(replacePlaceholders(newDb, insertQuery)))
|
||||
{
|
||||
while(resultSet.next())
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case 0: migrateUser(resultSet, preparedStatement);
|
||||
case 1: migrateBackpack(resultSet, preparedStatement);
|
||||
}
|
||||
preparedStatement.addBatch();
|
||||
count++;
|
||||
}
|
||||
preparedStatement.executeBatch();
|
||||
}
|
||||
plugin.getLogger().info("Migrated " + count + " " + type + ".");
|
||||
return count;
|
||||
}
|
||||
|
||||
private void migrateUser(@NotNull ResultSet usersResultSet, @NotNull PreparedStatement preparedStatement) throws Exception
|
||||
{
|
||||
int userId = usersResultSet.getInt((String) FIELD_PLAYER_ID.get(oldDb));
|
||||
preparedStatement.setInt(1, userId);
|
||||
preparedStatement.setString(2, usersResultSet.getString((String) FIELD_PLAYER_NAME.get(oldDb)));
|
||||
if(uuid) preparedStatement.setString(3, usersResultSet.getString((String) FIELD_PLAYER_UUID.get(oldDb)));
|
||||
if(userId > autoIndex) autoIndex = userId;
|
||||
}
|
||||
|
||||
private void migrateBackpack(@NotNull ResultSet backpacksResultSet, @NotNull PreparedStatement preparedStatement) throws Exception
|
||||
{
|
||||
preparedStatement.setInt(1, backpacksResultSet.getInt((String) FIELD_BP_OWNER.get(oldDb)));
|
||||
preparedStatement.setBytes(2, backpacksResultSet.getBytes((String) FIELD_BP_ITS.get(oldDb)));
|
||||
preparedStatement.setInt(3, backpacksResultSet.getInt((String) FIELD_BP_VERSION.get(oldDb)));
|
||||
if(oldDb instanceof SQLite)
|
||||
{
|
||||
preparedStatement.setTimestamp(4, new Timestamp(SQLITE_DATE_FORMAT.parse(backpacksResultSet.getString((String) FIELD_BP_LAST_UPDATE.get(oldDb))).getTime()));
|
||||
}
|
||||
else
|
||||
{
|
||||
preparedStatement.setString(4, SQLITE_DATE_FORMAT.format(new Date(backpacksResultSet.getTimestamp((String) FIELD_BP_LAST_UPDATE.get(oldDb)).getTime())));
|
||||
}
|
||||
}
|
||||
|
||||
private @Language("SQL") String replacePlaceholders(SQL database, @Language("SQL") String query) throws Exception
|
||||
{
|
||||
return (String) METHOD_REPLACE_PLACEHOLDERS.invoke(database, query);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user