150 lines
5.9 KiB
Java
150 lines
5.9 KiB
Java
/*
|
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
|
|
|
|
import at.pcgamingfreaks.ConsoleColor;
|
|
import at.pcgamingfreaks.Minepacks.Bukkit.Database.*;
|
|
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
|
|
import at.pcgamingfreaks.Reflection;
|
|
import org.bukkit.event.HandlerList;
|
|
|
|
import java.util.Locale;
|
|
|
|
public class MigrationManager
|
|
{
|
|
private final Minepacks plugin;
|
|
|
|
public MigrationManager(final Minepacks plugin)
|
|
{
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
public void migrateDB(final String targetDatabaseType, final MigrationCallback callback)
|
|
{
|
|
final Migration migration = getMigrationPerformer(targetDatabaseType);
|
|
if(migration == null)
|
|
{
|
|
callback.onResult(new MigrationResult("There is no need to migrate the database.", MigrationResult.MigrationResultType.NOT_NEEDED));
|
|
return;
|
|
}
|
|
final Database db = plugin.getDatabase();
|
|
|
|
//region Disable the plugin except for the database
|
|
try
|
|
{
|
|
plugin.getLogger().info("Unloading plugin for migration");
|
|
Reflection.setValue(plugin, "database", null); // Hack to prevent the unload of the database
|
|
//noinspection ConstantConditions
|
|
Reflection.getMethod(Minepacks.class, "unload").invoke(plugin); // Unload plugin
|
|
HandlerList.unregisterAll(db); // Disable events for database
|
|
Reflection.setValue(plugin, "database", db);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
plugin.getLogger().warning(ConsoleColor.RED + "Failed to unload plugin! Please restart your server!" + ConsoleColor.RESET);
|
|
e.printStackTrace();
|
|
callback.onResult(new MigrationResult("Failed to unload plugin! Please restart your server!", MigrationResult.MigrationResultType.ERROR));
|
|
return;
|
|
}
|
|
//endregion
|
|
//region Migrate data
|
|
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
|
|
MigrationResult migrationResult = null;
|
|
try
|
|
{
|
|
plugin.getLogger().info("Start migrating data to new database");
|
|
migrationResult = migration.migrate();
|
|
plugin.getConfiguration().setDatabaseType(targetDatabaseType);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
e.printStackTrace();
|
|
plugin.getLogger().warning(ConsoleColor.RED + "There was a problem migrating from " + db.getClass().getName() + " to " + targetDatabaseType + ConsoleColor.RESET);
|
|
callback.onResult(new MigrationResult("There was a problem migrating from " + db.getClass().getName() + " to " + targetDatabaseType + ". Please check the console for details.", MigrationResult.MigrationResultType.ERROR));
|
|
}
|
|
|
|
//region Start the plugin again
|
|
final MigrationResult migrationResultFinal = migrationResult;
|
|
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
|
db.close();
|
|
// No need to reload the config
|
|
try
|
|
{
|
|
plugin.getLogger().info("Migration is done, loading the plugin again.");
|
|
//noinspection ConstantConditions
|
|
Reflection.getMethod(Minepacks.class, "load").invoke(plugin); // load the plugin again
|
|
plugin.getLogger().info(ConsoleColor.GREEN + "Plugin loaded successful and is ready to use again." + ConsoleColor.RESET);
|
|
if(migrationResultFinal != null) callback.onResult(migrationResultFinal);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
plugin.getLogger().warning(ConsoleColor.RED + "Failed to start plugin again!" + ConsoleColor.RESET);
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
//endregion
|
|
});
|
|
//endregion
|
|
}
|
|
|
|
public Migration getMigrationPerformer(String targetDatabaseType)
|
|
{
|
|
try
|
|
{
|
|
boolean global = false;
|
|
if(targetDatabaseType.toLowerCase(Locale.ROOT).equals("external") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("global") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("shared"))
|
|
{
|
|
/*if[STANDALONE]
|
|
plugin.getLogger().warning(ConsoleColor.RED + "The shared database connection option is not available in standalone mode!" + ConsoleColor.RESET);
|
|
return null;
|
|
else[STANDALONE]*/
|
|
at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.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(Locale.ROOT);
|
|
global = true;
|
|
/*end[STANDALONE]*/
|
|
}
|
|
switch(targetDatabaseType.toLowerCase(Locale.ROOT))
|
|
{
|
|
case "flat":
|
|
case "file":
|
|
case "files":
|
|
if(!(plugin.getDatabase() instanceof SQL)) return null;
|
|
return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase());
|
|
case "mysql":
|
|
if(plugin.getDatabase() instanceof MySQL) return null;
|
|
if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "mysql", global);
|
|
else return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), "mysql", global);
|
|
case "sqlite":
|
|
if(plugin.getDatabase() instanceof SQLite) return null;
|
|
if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "sqlite", global);
|
|
else return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), "sqlite", global);
|
|
default: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseType())); return null;
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
} |