Split database and database-backend

This commit is contained in:
GeorgH93 2020-08-07 23:53:59 +02:00
parent e5b1c86f63
commit 0b24b82663
No known key found for this signature in database
GPG Key ID: D1630D37F9E4B3C8
17 changed files with 382 additions and 193 deletions

View File

@ -148,7 +148,7 @@ private void listBackups(final @NotNull CommandSender sender, final @NotNull Str
return;
}
}
ArrayList<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups();
List<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups();
int pages = backups.size() / elementsPerPage + 1;
page = Math.min(page, pages - 1);
int offset = page * elementsPerPage, end = Math.min(offset + elementsPerPage, backups.size());

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2020 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.Backend;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.InventorySerializer;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import lombok.Getter;
import lombok.Setter;
public abstract class DatabaseBackend
{
protected static final String START_UUID_UPDATE = "Start updating database to UUIDs ...", UUIDS_UPDATED = "Updated %d accounts to UUIDs.";
protected final Minepacks plugin;
protected final boolean onlineUUIDs;
@Setter protected boolean asyncSave = true;
protected boolean useUUIDSeparators;
@Getter protected final InventorySerializer itsSerializer;
protected long maxAge;
protected DatabaseBackend(final @NotNull Minepacks plugin)
{
this.plugin = plugin;
useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators();
onlineUUIDs = plugin.getConfiguration().useOnlineUUIDs();
maxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays();
itsSerializer = new InventorySerializer(plugin.getLogger());
}
public @NotNull String getPlayerFormattedUUID(final @NotNull OfflinePlayer player)
{
return (useUUIDSeparators) ? player.getUniqueId().toString() : player.getUniqueId().toString().replace("-", "");
}
public void close() {}
//region DB Functions
public abstract void updatePlayer(final @NotNull Player player);
public abstract void saveBackpack(final @NotNull Backpack backpack);
public void syncCooldown(final @NotNull Player player, long time) {}
public void getCooldown(final @NotNull Player player, final @NotNull Callback<Long> callback) {}
public abstract void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback<Backpack> callback);
//endregion
}

View File

@ -15,10 +15,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package at.pcgamingfreaks.Minepacks.Bukkit.Database;
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.InventorySerializer;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.UUIDConverter;
@ -33,17 +34,17 @@
import java.io.FileOutputStream;
import java.util.logging.Logger;
public class Files extends Database
public class Files extends DatabaseBackend
{
public static final String EXT = ".backpack", EXT_REGEX = "\\.backpack", FOLDER_NAME = "backpacks";
private final File saveFolder;
public Files(Minepacks plugin)
public Files(final @NotNull Minepacks plugin)
{
super(plugin);
maxAge *= 24 * 3600000L;
saveFolder = new File(this.plugin.getDataFolder(), FOLDER_NAME);
saveFolder = new File(plugin.getDataFolder(), FOLDER_NAME);
if(!saveFolder.exists())
{
if(!saveFolder.mkdirs())
@ -58,9 +59,9 @@ public Files(Minepacks plugin)
}
@Override
public void updatePlayer(Player player)
public void updatePlayer(final @NotNull Player player)
{
// Files are stored with the users name or the uuid, there is no reason to update anything
// Files are stored with the users uuid, there is no reason to update anything
}
private void checkFiles()
@ -118,7 +119,7 @@ private String getFileName(OfflinePlayer player)
// DB Functions
@Override
public void saveBackpack(Backpack backpack)
public void saveBackpack(@NotNull Backpack backpack)
{
File save = new File(saveFolder, getFileName(backpack.getOwner()));
try(FileOutputStream fos = new FileOutputStream(save))
@ -134,7 +135,7 @@ public void saveBackpack(Backpack backpack)
}
@Override
protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)
public void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback<Backpack> callback)
{ //TODO this needs to be done async!
File save = new File(saveFolder, getFileName(player));
ItemStack[] itemStacks = readFile(itsSerializer, save, plugin.getLogger());
@ -148,7 +149,7 @@ protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack>
}
}
protected static @Nullable ItemStack[] readFile(@NotNull InventorySerializer itsSerializer, @NotNull File file, @NotNull Logger logger)
public static @Nullable ItemStack[] readFile(final @NotNull InventorySerializer itsSerializer, final @NotNull File file, final @NotNull Logger logger)
{
if(file.exists())
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 GeorgH93
* Copyright (C) 2020 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
@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package at.pcgamingfreaks.Minepacks.Bukkit.Database;
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend;
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Database.ConnectionProvider.MySQLConnectionProvider;

View File

@ -15,12 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package at.pcgamingfreaks.Minepacks.Bukkit.Database;
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend;
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Database.DBTools;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.BackupHandler;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.UUIDConverter;
import at.pcgamingfreaks.Utils;
@ -32,10 +33,12 @@
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import lombok.AllArgsConstructor;
import java.sql.*;
import java.util.*;
public abstract class SQL extends Database
public abstract class SQL extends DatabaseBackend
{
private final ConnectionProvider dataSource;
@ -104,23 +107,17 @@ protected void loadSettings()
@Override
public void close()
{
super.close();
Utils.blockThread(1); // Give the database some time to perform async operations
dataSource.close();
}
protected void checkUUIDs()
{
@AllArgsConstructor
class UpdateData // Helper class for fixing UUIDs
{
int id;
String uuid;
public UpdateData(String uuid, int id)
{
this.id = id;
this.uuid = uuid;
}
final int id;
}
try(Connection connection = getConnection())
{
@ -262,17 +259,17 @@ protected void runStatement(final String query, final Object... args)
// Plugin Functions
@Override
public void updatePlayer(final Player player)
public void updatePlayer(final @NotNull Player player)
{
runStatementAsync(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player), player.getName());
}
@Override
public void saveBackpack(final Backpack backpack)
public void saveBackpack(final @NotNull Backpack backpack)
{
final byte[] data = itsSerializer.serialize(backpack.getInventory());
final int id = backpack.getOwnerID(), usedSerializer = itsSerializer.getUsedSerializer();
final String nameOrUUID = getPlayerFormattedUUID(backpack.getOwner()), name = backpack.getOwner().getName();
final String uuid = getPlayerFormattedUUID(backpack.getOwner()), name = backpack.getOwner().getName();
Runnable runnable = () -> {
try(Connection connection = getConnection())
@ -281,7 +278,7 @@ public void saveBackpack(final Backpack backpack)
{
try(PreparedStatement ps = connection.prepareStatement(queryGetPlayerID))
{
ps.setString(1, nameOrUUID);
ps.setString(1, uuid);
try(ResultSet rs = ps.executeQuery())
{
if(rs.next())
@ -293,7 +290,7 @@ public void saveBackpack(final Backpack backpack)
else
{
plugin.getLogger().warning("Failed saving backpack for: " + name + " (Unable to get players ID from database)");
writeBackup(name, nameOrUUID, usedSerializer, data);
BackupHandler.getInstance().writeBackup(name, uuid, usedSerializer, data);
}
}
}
@ -307,14 +304,14 @@ public void saveBackpack(final Backpack backpack)
{
plugin.getLogger().warning("Failed to save backpack in database! Error: " + e.getMessage());
e.printStackTrace();
writeBackup(name, nameOrUUID, usedSerializer, data);
BackupHandler.getInstance().writeBackup(name, uuid, usedSerializer, data);
}
};
if(asyncSave) Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable); else runnable.run();
}
@Override
protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)
public void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback<Backpack> callback)
{
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetBP))
@ -360,14 +357,14 @@ protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack>
}
@Override
public void syncCooldown(Player player, long cooldownTime)
public void syncCooldown(final @NotNull Player player, final long cooldownTime)
{
Timestamp ts = new Timestamp(cooldownTime);
runStatementAsync(querySyncCooldown, ts, getPlayerFormattedUUID(player), ts);
}
@Override
public void getCooldown(final Player player, final Callback<Long> callback)
public void getCooldown(final @NotNull Player player, final @NotNull Callback<Long> callback)
{
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetCooldown))

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package at.pcgamingfreaks.Minepacks.Bukkit.Database;
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend;
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Database.ConnectionProvider.SQLiteConnectionProvider;
@ -107,7 +107,7 @@ protected void checkDB()
}
@Override
public void updatePlayer(final Player player)
public void updatePlayer(final @NotNull Player player)
{
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
runStatement(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player));

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2020 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;
import at.pcgamingfreaks.ConsoleColor;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
public final class BackupHandler
{
@Setter(AccessLevel.PRIVATE) @Getter private static BackupHandler instance;
private final Logger logger;
private final InventorySerializer itsSerializer;
private final boolean useUUIDSeparators;
private final File backupFolder;
public BackupHandler(final @NotNull Minepacks plugin)
{
logger = plugin.getLogger();
itsSerializer = new InventorySerializer(logger);
useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators();
backupFolder = new File(plugin.getDataFolder(), "backups");
if(!backupFolder.exists() && !backupFolder.mkdirs()) plugin.getLogger().info("Failed to create backups folder.");
setInstance(this);
}
public void backup(final @NotNull Backpack backpack)
{
final String formattedUUID = (useUUIDSeparators) ? backpack.getOwner().getUniqueId().toString() : backpack.getOwner().getUniqueId().toString().replace("-", "");
writeBackup(backpack.getOwner().getName(), formattedUUID, itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory()));
}
public @Nullable ItemStack[] loadBackup(final String backupName)
{
File backup = new File(backupFolder, backupName + Files.EXT);
return Files.readFile(itsSerializer, backup, logger);
}
public void writeBackup(@Nullable String userName, @NotNull String userIdentifier, final int usedSerializer, final @NotNull byte[] data)
{
if(userIdentifier.equalsIgnoreCase(userName)) userName = null;
if(userName != null) userIdentifier = userName + "_" + userIdentifier;
final File save = new File(backupFolder, userIdentifier + "_" + System.currentTimeMillis() + Files.EXT);
try(FileOutputStream fos = new FileOutputStream(save))
{
fos.write(usedSerializer);
fos.write(data);
logger.info("Backup of the backpack has been created: " + save.getAbsolutePath());
}
catch(Exception e)
{
logger.warning(ConsoleColor.RED + "Failed to write backup! Error: " + e.getMessage() + ConsoleColor.RESET);
}
}
public List<String> getBackups()
{
File[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT));
if(files != null)
{
ArrayList<String> backups = new ArrayList<>(files.length);
for(File file : files)
{
if(!file.isFile()) continue;
backups.add(file.getName().replaceAll(Files.EXT_REGEX, ""));
}
return backups;
}
return new ArrayList<>();
}
}

View File

@ -82,11 +82,16 @@ public int getAutoCleanupMaxInactiveDays()
return getConfigE().getInt("Database.AutoCleanup.MaxInactiveDays", -1);
}
public String getDatabaseType()
public @NotNull String getDatabaseTypeName()
{
return getConfigE().getString("Database.Type", "sqlite");
}
public @NotNull DatabaseType getDatabaseType()
{
return DatabaseType.fromName(getDatabaseTypeName());
}
public void setDatabaseType(String type)
{
getConfigE().set("Database.Type", type);

View File

@ -21,6 +21,10 @@
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.MySQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.OnDisconnect;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.UnCacheStrategie;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
@ -35,90 +39,85 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import lombok.Getter;
import java.util.Collection;
import java.util.Locale;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
public abstract class Database implements Listener
public final class Database implements Listener
{
protected static final String START_UUID_UPDATE = "Start updating database to UUIDs ...", UUIDS_UPDATED = "Updated %d accounts to UUIDs.";
public static final String MESSAGE_UNKNOWN_DB_TYPE = ConsoleColor.RED + "Unknown database type \"%s\"!" + ConsoleColor.RESET;
protected final Minepacks plugin;
protected final InventorySerializer itsSerializer;
protected final boolean onlineUUIDs, bungeeCordMode;
protected boolean useUUIDSeparators, asyncSave = true;
protected long maxAge;
private final boolean bungeeCordMode;
private final BackupHandler backupHandler;
@Getter private final DatabaseBackend backend;
private final Map<OfflinePlayer, Backpack> backpacks = new ConcurrentHashMap<>();
private final UnCacheStrategie unCacheStrategie;
private final File backupFolder;
public Database(Minepacks mp)
public Database(final @NotNull Minepacks plugin)
{
plugin = mp;
itsSerializer = new InventorySerializer(plugin.getLogger());
useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators();
onlineUUIDs = plugin.getConfiguration().useOnlineUUIDs();
this.plugin = plugin;
bungeeCordMode = plugin.getConfiguration().isBungeeCordModeEnabled();
maxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays();
unCacheStrategie = bungeeCordMode ? new OnDisconnect(this) : UnCacheStrategie.getUnCacheStrategie(this);
backupFolder = new File(this.plugin.getDataFolder(), "backups");
if(!backupFolder.exists() && !backupFolder.mkdirs()) mp.getLogger().info("Failed to create backups folder.");
}
backupHandler = new BackupHandler(plugin);
backend = getDatabaseBackend(plugin);
if(!available()) return;
public void init()
{
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public void close()
{
HandlerList.unregisterAll(this);
asyncSave = false;
backend.setAsyncSave(false);
backpacks.forEach((key, value) -> value.closeAll());
backpacks.clear();
unCacheStrategie.close();
backend.close();
}
public static @Nullable Database getDatabase(Minepacks plugin)
public boolean available()
{
return backend != null;
}
public static @Nullable ConnectionProvider getGlobalConnectionProvider(final @NotNull Logger logger)
{
/*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)
{
logger.warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET);
return null;
}
return pool.getConnectionProvider();
/*end[STANDALONE]*/
}
protected static @Nullable DatabaseBackend getDatabaseBackend(Minepacks plugin)
{
try
{
String dbType = plugin.getConfiguration().getDatabaseType().toLowerCase(Locale.ROOT);
ConnectionProvider connectionProvider = null;
if(dbType.equals("shared") || dbType.equals("external") || dbType.equals("global"))
{
/*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;
}
dbType = pool.getDatabaseType().toLowerCase(Locale.ROOT);
connectionProvider = pool.getConnectionProvider();
/*end[STANDALONE]*/
}
Database database;
DatabaseType dbType = plugin.getConfiguration().getDatabaseType();
ConnectionProvider connectionProvider = dbType == DatabaseType.SHARED ? getGlobalConnectionProvider(plugin.getLogger()) : null;
if(connectionProvider != null) dbType = DatabaseType.fromName(connectionProvider.getDatabaseType());
DatabaseBackend databaseBackend;
switch(dbType)
{
case "mysql": database = new MySQL(plugin, connectionProvider); break;
case "sqlite": database = new SQLite(plugin, connectionProvider); break;
case "flat":
case "file":
case "files":
database = new Files(plugin); break;
default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseType())); return null;
case MYSQL: databaseBackend = new MySQL(plugin, connectionProvider); break;
case SQLITE: databaseBackend = new SQLite(plugin, connectionProvider); break;
case FILES: databaseBackend = new Files(plugin); break;
default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseTypeName())); return null;
}
database.init();
return database;
//databaseBackend.init();
return databaseBackend;
}
catch(IllegalStateException ignored) {}
catch(Exception e)
@ -130,51 +129,17 @@ public void close()
public void backup(@NotNull Backpack backpack)
{
writeBackup(backpack.getOwner().getName(), getPlayerFormattedUUID(backpack.getOwner()), itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory()));
}
protected void writeBackup(@Nullable String userName, @NotNull String userIdentifier, final int usedSerializer, final @NotNull byte[] data)
{
if(userIdentifier.equalsIgnoreCase(userName)) userName = null;
if(userName != null) userIdentifier = userName + "_" + userIdentifier;
final File save = new File(backupFolder, userIdentifier + "_" + System.currentTimeMillis() + Files.EXT);
try(FileOutputStream fos = new FileOutputStream(save))
{
fos.write(usedSerializer);
fos.write(data);
plugin.getLogger().info("Backup of the backpack has been created: " + save.getAbsolutePath());
}
catch(Exception e)
{
plugin.getLogger().warning(ConsoleColor.RED + "Failed to write backup! Error: " + e.getMessage() + ConsoleColor.RESET);
}
backupHandler.backup(backpack);
}
public @Nullable ItemStack[] loadBackup(final String backupName)
{
File backup = new File(backupFolder, backupName + Files.EXT);
return Files.readFile(itsSerializer, backup, plugin.getLogger());
return backupHandler.loadBackup(backupName);
}
public ArrayList<String> getBackups()
public List<String> getBackups()
{
File[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT));
if(files != null)
{
ArrayList<String> backups = new ArrayList<>(files.length);
for(File file : files)
{
if(!file.isFile()) continue;
backups.add(file.getName().replaceAll(Files.EXT_REGEX, ""));
}
return backups;
}
return new ArrayList<>();
}
protected String getPlayerFormattedUUID(OfflinePlayer player)
{
return (useUUIDSeparators) ? player.getUniqueId().toString() : player.getUniqueId().toString().replace("-", "");
return backupHandler.getBackups();
}
public @NotNull Collection<Backpack> getLoadedBackpacks()
@ -270,20 +235,35 @@ public void onPlayerLoginEvent(PlayerJoinEvent event)
updatePlayerAndLoadBackpack(event.getPlayer());
}
// DB Functions
public void updatePlayerAndLoadBackpack(Player player)
{
updatePlayer(player);
if(!bungeeCordMode) asyncLoadBackpack(player);
}
public abstract void updatePlayer(Player player);
// DB Functions
public void updatePlayer(final @NotNull Player player)
{
backend.updatePlayer(player);
}
public abstract void saveBackpack(Backpack backpack);
public void saveBackpack(final @NotNull Backpack backpack)
{
backend.saveBackpack(backpack);
}
public void syncCooldown(Player player, long time) {}
public void syncCooldown(final @NotNull Player player, final long time)
{
backend.syncCooldown(player, time);
}
public void getCooldown(final Player player, final Callback<Long> callback) {}
public void getCooldown(final Player player, final Callback<Long> callback)
{
backend.getCooldown(player, callback);
}
protected abstract void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback);
protected void loadBackpack(final OfflinePlayer player, final Callback<Backpack> callback)
{
backend.loadBackpack(player, callback);
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2020 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;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
public enum DatabaseType
{
MYSQL,
SQLITE,
FILES,
SHARED,
UNKNOWN;
public static @NotNull DatabaseType fromName(@NotNull String typeName)
{
typeName = typeName.toLowerCase(Locale.ENGLISH);
switch(typeName)
{
case "mysql": return MYSQL;
case "sqlite": return SQLITE;
case "files": case "file": case "flat": return FILES;
case "shared": case "external": case "global": return SHARED;
}
return UNKNOWN;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 GeorgH93
* Copyright (C) 2020 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
@ -17,7 +17,8 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.intellij.lang.annotations.Language;
@ -35,7 +36,7 @@ public class FilesToSQLMigration extends ToSQLMigration
private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks;
private final File saveFolder;
protected FilesToSQLMigration(@NotNull Minepacks plugin, @NotNull Files oldDb, @NotNull String dbType, boolean global) throws Exception
protected FilesToSQLMigration(@NotNull Minepacks plugin, @NotNull Files oldDb, @NotNull DatabaseType dbType, boolean global) throws Exception
{
super(plugin, oldDb, dbType, global);
saveFolder = new File(this.plugin.getDataFolder(), Files.FOLDER_NAME);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 GeorgH93
* Copyright (C) 2020 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
@ -17,7 +17,7 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.jetbrains.annotations.NotNull;
@ -26,9 +26,9 @@
public abstract class Migration
{
protected final Minepacks plugin;
protected final Database oldDb;
protected final DatabaseBackend oldDb;
protected Migration(@NotNull Minepacks plugin, @NotNull Database oldDb)
protected Migration(@NotNull Minepacks plugin, @NotNull DatabaseBackend oldDb)
{
this.plugin = plugin;
this.oldDb = oldDb;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 GeorgH93
* Copyright (C) 2020 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
@ -18,14 +18,15 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.ConsoleColor;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.*;
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.*;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType;
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;
@ -107,39 +108,25 @@ 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"))
DatabaseType targetDbType = DatabaseType.fromName(targetDatabaseType);
ConnectionProvider cp = targetDbType == DatabaseType.SHARED ? Database.getGlobalConnectionProvider(plugin.getLogger()) : null;
boolean global = cp != null;
if(cp != null) targetDbType = DatabaseType.fromName(cp.getDatabaseType());
DatabaseBackend oldBackend = plugin.getDatabase().getBackend();
switch(targetDbType)
{
/*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;
case FILES:
if(!(oldBackend instanceof SQL)) return null;
return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase().getBackend());
case MYSQL:
if(oldBackend instanceof MySQL) return null;
if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.MYSQL, global);
else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.MYSQL, global);
case SQLITE:
if(oldBackend instanceof SQLite) return null;
if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.SQLITE, global);
else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.SQLITE, global);
default: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE, targetDatabaseType)); return null;
}
}
catch(Exception e)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 GeorgH93
* Copyright (C) 2020 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
@ -17,8 +17,8 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.Reflection;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 GeorgH93
* Copyright (C) 2020 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
@ -17,8 +17,9 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.intellij.lang.annotations.Language;
@ -33,7 +34,7 @@ public class SQLtoSQLMigration extends ToSQLMigration
{
private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks;
protected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NotNull String dbType, boolean global) throws Exception
protected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NotNull DatabaseType dbType, boolean global) throws Exception
{
super(plugin, oldDb, dbType, global);

View File

@ -18,10 +18,12 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.MySQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.MySQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.Reflection;
@ -49,18 +51,15 @@ public abstract class ToSQLMigration extends Migration
protected final SQL newDb;
protected ToSQLMigration(@NotNull Minepacks plugin, @NotNull Database oldDb, @NotNull String dbType, boolean global)
protected ToSQLMigration(@NotNull Minepacks plugin, @NotNull DatabaseBackend oldDb, @NotNull DatabaseType dbType, boolean global)
{
super(plugin, oldDb);
/*if[STANDALONE]
ConnectionProvider connectionProvider = null;
else[STANDALONE]*/
ConnectionProvider connectionProvider = (global) ? at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool().getConnectionProvider() : null;
/*end[STANDALONE]*/
ConnectionProvider connectionProvider = (global) ? Database.getGlobalConnectionProvider(plugin.getLogger()) : null;
switch(dbType)
{
case "mysql": newDb = new MySQL(plugin, connectionProvider); break;
case "sqlite":
case MYSQL: newDb = new MySQL(plugin, connectionProvider); break;
case SQLITE:
final File dbFile = new File(SQLite.getDbFile(plugin));
if(dbFile.exists()) dbFile.renameTo(new File(SQLite.getDbFile(plugin) + ".old_" + System.currentTimeMillis()));
newDb = new SQLite(plugin, connectionProvider);

View File

@ -186,8 +186,8 @@ private void load()
updater.setChannel(config.getUpdateChannel());
lang.load(config);
backpacksConfig.loadData();
database = Database.getDatabase(this);
if(database == null)
database = new Database(this);
if(!database.available())
{
new NoDatabaseWorker(this);
return;