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; return;
} }
} }
ArrayList<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups(); List<String> backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups();
int pages = backups.size() / elementsPerPage + 1; int pages = backups.size() / elementsPerPage + 1;
page = Math.min(page, pages - 1); page = Math.min(page, pages - 1);
int offset = page * elementsPerPage, end = Math.min(offset + elementsPerPage, backups.size()); 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/>. * 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.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; import at.pcgamingfreaks.Minepacks.Bukkit.Backpack;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.InventorySerializer;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.UUIDConverter; import at.pcgamingfreaks.UUIDConverter;
@ -33,17 +34,17 @@
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.util.logging.Logger; 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"; public static final String EXT = ".backpack", EXT_REGEX = "\\.backpack", FOLDER_NAME = "backpacks";
private final File saveFolder; private final File saveFolder;
public Files(Minepacks plugin) public Files(final @NotNull Minepacks plugin)
{ {
super(plugin); super(plugin);
maxAge *= 24 * 3600000L; maxAge *= 24 * 3600000L;
saveFolder = new File(this.plugin.getDataFolder(), FOLDER_NAME); saveFolder = new File(plugin.getDataFolder(), FOLDER_NAME);
if(!saveFolder.exists()) if(!saveFolder.exists())
{ {
if(!saveFolder.mkdirs()) if(!saveFolder.mkdirs())
@ -58,9 +59,9 @@ public Files(Minepacks plugin)
} }
@Override @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() private void checkFiles()
@ -118,7 +119,7 @@ private String getFileName(OfflinePlayer player)
// DB Functions // DB Functions
@Override @Override
public void saveBackpack(Backpack backpack) public void saveBackpack(@NotNull Backpack backpack)
{ {
File save = new File(saveFolder, getFileName(backpack.getOwner())); File save = new File(saveFolder, getFileName(backpack.getOwner()));
try(FileOutputStream fos = new FileOutputStream(save)) try(FileOutputStream fos = new FileOutputStream(save))
@ -134,7 +135,7 @@ public void saveBackpack(Backpack backpack)
} }
@Override @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! { //TODO this needs to be done async!
File save = new File(saveFolder, getFileName(player)); File save = new File(saveFolder, getFileName(player));
ItemStack[] itemStacks = readFile(itsSerializer, save, plugin.getLogger()); 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()) 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 * 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 * 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/>. * 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.ConnectionProvider;
import at.pcgamingfreaks.Database.ConnectionProvider.MySQLConnectionProvider; import at.pcgamingfreaks.Database.ConnectionProvider.MySQLConnectionProvider;

View File

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

View File

@ -21,6 +21,10 @@
import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider;
import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback; import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback;
import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; 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.OnDisconnect;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.UnCacheStrategie; import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.UnCacheStrategie;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
@ -35,90 +39,85 @@
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File; import lombok.Getter;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; 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; public static final String MESSAGE_UNKNOWN_DB_TYPE = ConsoleColor.RED + "Unknown database type \"%s\"!" + ConsoleColor.RESET;
protected final Minepacks plugin; protected final Minepacks plugin;
protected final InventorySerializer itsSerializer; private final boolean bungeeCordMode;
protected final boolean onlineUUIDs, bungeeCordMode; private final BackupHandler backupHandler;
protected boolean useUUIDSeparators, asyncSave = true; @Getter private final DatabaseBackend backend;
protected long maxAge;
private final Map<OfflinePlayer, Backpack> backpacks = new ConcurrentHashMap<>(); private final Map<OfflinePlayer, Backpack> backpacks = new ConcurrentHashMap<>();
private final UnCacheStrategie unCacheStrategie; private final UnCacheStrategie unCacheStrategie;
private final File backupFolder;
public Database(Minepacks mp) public Database(final @NotNull Minepacks plugin)
{ {
plugin = mp; this.plugin = plugin;
itsSerializer = new InventorySerializer(plugin.getLogger());
useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators();
onlineUUIDs = plugin.getConfiguration().useOnlineUUIDs();
bungeeCordMode = plugin.getConfiguration().isBungeeCordModeEnabled(); bungeeCordMode = plugin.getConfiguration().isBungeeCordModeEnabled();
maxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays();
unCacheStrategie = bungeeCordMode ? new OnDisconnect(this) : UnCacheStrategie.getUnCacheStrategie(this); unCacheStrategie = bungeeCordMode ? new OnDisconnect(this) : UnCacheStrategie.getUnCacheStrategie(this);
backupFolder = new File(this.plugin.getDataFolder(), "backups"); backupHandler = new BackupHandler(plugin);
if(!backupFolder.exists() && !backupFolder.mkdirs()) mp.getLogger().info("Failed to create backups folder."); backend = getDatabaseBackend(plugin);
} if(!available()) return;
public void init()
{
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
} }
public void close() public void close()
{ {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
asyncSave = false; backend.setAsyncSave(false);
backpacks.forEach((key, value) -> value.closeAll()); backpacks.forEach((key, value) -> value.closeAll());
backpacks.clear(); backpacks.clear();
unCacheStrategie.close(); 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 try
{ {
String dbType = plugin.getConfiguration().getDatabaseType().toLowerCase(Locale.ROOT); DatabaseType dbType = plugin.getConfiguration().getDatabaseType();
ConnectionProvider connectionProvider = null; ConnectionProvider connectionProvider = dbType == DatabaseType.SHARED ? getGlobalConnectionProvider(plugin.getLogger()) : null;
if(dbType.equals("shared") || dbType.equals("external") || dbType.equals("global")) if(connectionProvider != null) dbType = DatabaseType.fromName(connectionProvider.getDatabaseType());
{ DatabaseBackend databaseBackend;
/*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;
switch(dbType) switch(dbType)
{ {
case "mysql": database = new MySQL(plugin, connectionProvider); break; case MYSQL: databaseBackend = new MySQL(plugin, connectionProvider); break;
case "sqlite": database = new SQLite(plugin, connectionProvider); break; case SQLITE: databaseBackend = new SQLite(plugin, connectionProvider); break;
case "flat": case FILES: databaseBackend = new Files(plugin); break;
case "file": default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseTypeName())); return null;
case "files":
database = new Files(plugin); break;
default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseType())); return null;
} }
database.init(); //databaseBackend.init();
return database; return databaseBackend;
} }
catch(IllegalStateException ignored) {} catch(IllegalStateException ignored) {}
catch(Exception e) catch(Exception e)
@ -130,51 +129,17 @@ public void close()
public void backup(@NotNull Backpack backpack) public void backup(@NotNull Backpack backpack)
{ {
writeBackup(backpack.getOwner().getName(), getPlayerFormattedUUID(backpack.getOwner()), itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory())); backupHandler.backup(backpack);
}
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);
}
} }
public @Nullable ItemStack[] loadBackup(final String backupName) public @Nullable ItemStack[] loadBackup(final String backupName)
{ {
File backup = new File(backupFolder, backupName + Files.EXT); return backupHandler.loadBackup(backupName);
return Files.readFile(itsSerializer, backup, plugin.getLogger());
} }
public ArrayList<String> getBackups() public List<String> getBackups()
{ {
File[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT)); return backupHandler.getBackups();
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("-", "");
} }
public @NotNull Collection<Backpack> getLoadedBackpacks() public @NotNull Collection<Backpack> getLoadedBackpacks()
@ -270,20 +235,35 @@ public void onPlayerLoginEvent(PlayerJoinEvent event)
updatePlayerAndLoadBackpack(event.getPlayer()); updatePlayerAndLoadBackpack(event.getPlayer());
} }
// DB Functions
public void updatePlayerAndLoadBackpack(Player player) public void updatePlayerAndLoadBackpack(Player player)
{ {
updatePlayer(player); updatePlayer(player);
if(!bungeeCordMode) asyncLoadBackpack(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 * 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 * it under the terms of the GNU General Public License as published by
@ -17,7 +17,8 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; 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 at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.intellij.lang.annotations.Language; import org.intellij.lang.annotations.Language;
@ -35,7 +36,7 @@ public class FilesToSQLMigration extends ToSQLMigration
private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks; private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks;
private final File saveFolder; 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); super(plugin, oldDb, dbType, global);
saveFolder = new File(this.plugin.getDataFolder(), Files.FOLDER_NAME); 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 * 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 * it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; 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 at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -26,9 +26,9 @@
public abstract class Migration public abstract class Migration
{ {
protected final Minepacks plugin; 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.plugin = plugin;
this.oldDb = oldDb; 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 * 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 * it under the terms of the GNU General Public License as published by
@ -18,14 +18,15 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.ConsoleColor; 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.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.Reflection; import at.pcgamingfreaks.Reflection;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import java.util.Locale;
public class MigrationManager public class MigrationManager
{ {
private final Minepacks plugin; private final Minepacks plugin;
@ -107,39 +108,25 @@ public Migration getMigrationPerformer(String targetDatabaseType)
{ {
try try
{ {
boolean global = false; DatabaseType targetDbType = DatabaseType.fromName(targetDatabaseType);
if(targetDatabaseType.toLowerCase(Locale.ROOT).equals("external") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("global") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("shared")) 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] case FILES:
plugin.getLogger().warning(ConsoleColor.RED + "The shared database connection option is not available in standalone mode!" + ConsoleColor.RESET); if(!(oldBackend instanceof SQL)) return null;
return null; return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase().getBackend());
else[STANDALONE]*/ case MYSQL:
at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool(); if(oldBackend instanceof MySQL) return null;
if(pool == null) if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.MYSQL, global);
{ else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.MYSQL, global);
plugin.getLogger().warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET); case SQLITE:
return null; if(oldBackend instanceof SQLite) return null;
} if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.SQLITE, global);
targetDatabaseType = pool.getDatabaseType().toLowerCase(Locale.ROOT); else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.SQLITE, global);
global = true; default: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE, targetDatabaseType)); return null;
/*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) 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 * 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 * it under the terms of the GNU General Public License as published by
@ -17,8 +17,8 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; 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.SQL; import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import at.pcgamingfreaks.Reflection; 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 * 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 * it under the terms of the GNU General Public License as published by
@ -17,8 +17,9 @@
package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL; import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite; import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite;
import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType;
import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks;
import org.intellij.lang.annotations.Language; import org.intellij.lang.annotations.Language;
@ -33,7 +34,7 @@ public class SQLtoSQLMigration extends ToSQLMigration
{ {
private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks; 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); super(plugin, oldDb, dbType, global);

View File

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

View File

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