getForName(String name) {
+ for (DBType dbType : DBType.values()) {
+ if (dbType.getName().equalsIgnoreCase(name)) {
+ return Optional.of(dbType);
+ }
+ }
+
+ return Optional.empty();
+ }
+
+ /**
+ * Checks if the name of a {@code DBType} corresponds to {@code name}.
+ * This method is case-insensitive.
+ *
+ * @param name the name of the {@code DBType}
+ * @return if the {@code DBType} exists
+ * @see DBType#getForName(String)
+ */
+ public static boolean exists(String name) {
+ for (DBType dbType : DBType.values()) {
+ if (dbType.getName().equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java
index 541fa2731..ee08804fc 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java
@@ -29,7 +29,7 @@ import com.djrapitops.plan.system.database.databases.operation.*;
*/
public abstract class Database {
- protected boolean open = false;
+ protected volatile boolean open = false;
public abstract void init() throws DBInitException;
@@ -47,18 +47,13 @@ public abstract class Database {
public abstract SaveOperations save();
- public abstract String getName();
-
/**
- * Used to get the config name of the database type.
- *
- * Thread safe.
+ * Used to get the {@code DBType} of the Database
*
- * @return sqlite/mysql
+ * @return the {@code DBType}
+ * @see DBType
*/
- public String getConfigName() {
- return getName().toLowerCase().trim();
- }
+ public abstract DBType getType();
public abstract void close() throws DBException;
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/H2DB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/H2DB.java
new file mode 100644
index 000000000..44891f394
--- /dev/null
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/H2DB.java
@@ -0,0 +1,240 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the LGNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan 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
+ * LGNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.system.database.databases.sql;
+
+import com.djrapitops.plan.api.exceptions.database.DBInitException;
+import com.djrapitops.plan.data.store.containers.NetworkContainer;
+import com.djrapitops.plan.system.database.databases.DBType;
+import com.djrapitops.plan.system.file.PlanFiles;
+import com.djrapitops.plan.system.info.server.ServerInfo;
+import com.djrapitops.plan.system.locale.Locale;
+import com.djrapitops.plan.system.settings.Settings;
+import com.djrapitops.plan.system.settings.config.PlanConfig;
+import com.djrapitops.plan.utilities.MiscUtils;
+import com.djrapitops.plugin.benchmarking.Timings;
+import com.djrapitops.plugin.logging.L;
+import com.djrapitops.plugin.logging.console.PluginLogger;
+import com.djrapitops.plugin.logging.error.ErrorHandler;
+import com.djrapitops.plugin.task.PluginTask;
+import com.djrapitops.plugin.task.RunnableFactory;
+import dagger.Lazy;
+import org.h2.jdbcx.JdbcDataSource;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Objects;
+
+/**
+ * Implementation of the H2 database
+ *
+ * @author Fuzzlemann
+ * @since 4.5.1
+ */
+public class H2DB extends SQLDB {
+
+ private final File databaseFile;
+ private final String dbName;
+ private Connection connection;
+ private PluginTask connectionPingTask;
+
+ private H2DB(
+ File databaseFile,
+ Locale locale,
+ PlanConfig config,
+ Lazy serverInfo,
+ NetworkContainer.Factory networkContainerFactory,
+ RunnableFactory runnableFactory,
+ PluginLogger logger,
+ Timings timings,
+ ErrorHandler errorHandler
+ ) {
+ super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, logger, timings, errorHandler);
+ dbName = databaseFile.getName();
+ this.databaseFile = databaseFile;
+ }
+
+ @Override
+ public void setupDataSource() throws DBInitException {
+ try {
+ Class.forName("org.h2.Driver");
+ } catch (ClassNotFoundException e) {
+ errorHandler.log(L.CRITICAL, this.getClass(), e);
+ }
+
+ try {
+ connection = getNewConnection(databaseFile);
+ } catch (SQLException e) {
+ throw new DBInitException(e);
+ }
+
+ execute("SET REFERENTIAL_INTEGRITY FALSE");
+ startConnectionPingTask();
+ }
+
+ public Connection getNewConnection(File dbFile) throws SQLException {
+ String dbFilePath = dbFile.getAbsolutePath();
+
+ Connection newConnection = getConnectionFor(dbFilePath);
+ logger.debug("H2 " + dbName + ": Opened a new Connection");
+ newConnection.setAutoCommit(false);
+ return newConnection;
+ }
+
+ private Connection getConnectionFor(String dbFilePath) throws SQLException {
+ String username = config.getString(Settings.DB_USER);
+ String password = config.getString(Settings.DB_PASS);
+
+ JdbcDataSource jdbcDataSource = new JdbcDataSource();
+ jdbcDataSource.setURL("jdbc:h2:file:" + dbFilePath + ";mode=MySQL");
+ jdbcDataSource.setUser(username);
+ jdbcDataSource.setPassword(password);
+
+ return jdbcDataSource.getConnection();
+ }
+
+ private void startConnectionPingTask() {
+ stopConnectionPingTask();
+ try {
+ // Maintains Connection.
+ connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(),
+ new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler)
+ ).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
+ } catch (Exception ignored) {
+ }
+ }
+
+ private void stopConnectionPingTask() {
+ if (connectionPingTask != null) {
+ try {
+ connectionPingTask.cancel();
+ } catch (Exception ignored) {
+ }
+ }
+ }
+
+ @Override
+ public DBType getType() {
+ return DBType.H2;
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ if (connection == null) {
+ connection = getNewConnection(databaseFile);
+ }
+
+ return connection;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ stopConnectionPingTask();
+
+ if (connection != null) {
+ logger.debug("H2DB " + dbName + ": Closed Connection");
+ MiscUtils.close(connection);
+ }
+ }
+
+ @Override
+ public void commit(Connection connection) {
+ try {
+ connection.commit();
+ } catch (SQLException e) {
+ if (!e.getMessage().contains("cannot commit")) {
+ errorHandler.log(L.ERROR, this.getClass(), e);
+ }
+ }
+ }
+
+ @Override
+ public void returnToPool(Connection connection) {
+ // Connection pool not in use, no action required.
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+ H2DB h2DB = (H2DB) o;
+ return Objects.equals(dbName, h2DB.dbName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), dbName);
+ }
+
+ @Singleton
+ public static class Factory {
+
+ private final Locale locale;
+ private final PlanConfig config;
+ private final Lazy serverInfo;
+ private final NetworkContainer.Factory networkContainerFactory;
+ private final RunnableFactory runnableFactory;
+ private final PluginLogger logger;
+ private final Timings timings;
+ private final ErrorHandler errorHandler;
+ private PlanFiles files;
+
+ @Inject
+ public Factory(
+ Locale locale,
+ PlanConfig config,
+ PlanFiles files,
+ Lazy serverInfo,
+ NetworkContainer.Factory networkContainerFactory,
+ RunnableFactory runnableFactory,
+ PluginLogger logger,
+ Timings timings,
+ ErrorHandler errorHandler
+ ) {
+ this.locale = locale;
+ this.config = config;
+ this.files = files;
+ this.serverInfo = serverInfo;
+ this.networkContainerFactory = networkContainerFactory;
+ this.runnableFactory = runnableFactory;
+ this.logger = logger;
+ this.timings = timings;
+ this.errorHandler = errorHandler;
+ }
+
+ public H2DB usingDefaultFile() {
+ return usingFileCalled("h2database");
+ }
+
+ public H2DB usingFileCalled(String fileName) {
+ return usingFile(files.getFileFromPluginFolder(fileName));
+ }
+
+ public H2DB usingFile(File databaseFile) {
+ return new H2DB(databaseFile,
+ locale, config, serverInfo,
+ networkContainerFactory,
+ runnableFactory, logger, timings, errorHandler
+ );
+ }
+
+ }
+}
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/KeepAliveTask.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/KeepAliveTask.java
new file mode 100644
index 000000000..fd74885bc
--- /dev/null
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/KeepAliveTask.java
@@ -0,0 +1,59 @@
+package com.djrapitops.plan.system.database.databases.sql;
+
+import com.djrapitops.plan.utilities.MiscUtils;
+import com.djrapitops.plugin.logging.L;
+import com.djrapitops.plugin.logging.console.PluginLogger;
+import com.djrapitops.plugin.logging.error.ErrorHandler;
+import com.djrapitops.plugin.task.AbsRunnable;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * The task which handles the upkeep of the {@code Connection}
+ *
+ * @author Fuzzlemann
+ * @since 4.5.1
+ */
+public class KeepAliveTask extends AbsRunnable {
+ private Connection connection;
+ private final IReconnect iReconnect;
+ private final PluginLogger logger;
+ private final ErrorHandler errorHandler;
+
+ public KeepAliveTask(Connection connection, IReconnect iReconnect, PluginLogger logger, ErrorHandler errorHandler) {
+ this.connection = connection;
+ this.iReconnect = iReconnect;
+ this.logger = logger;
+ this.errorHandler = errorHandler;
+ }
+
+ @Override
+ public void run() {
+ Statement statement = null;
+ ResultSet resultSet = null;
+ try {
+ if (connection != null && !connection.isClosed()) {
+ statement = connection.createStatement();
+ resultSet = statement.executeQuery("/* ping */ SELECT 1");
+ }
+ } catch (SQLException e) {
+ logger.debug("Something went wrong during SQL Connection upkeep task.");
+ try {
+ connection = iReconnect.reconnect();
+ } catch (SQLException e1) {
+ errorHandler.log(L.ERROR, this.getClass(), e1);
+ logger.error("SQL connection maintaining task had to be closed due to exception.");
+ this.cancel();
+ }
+ } finally {
+ MiscUtils.close(statement, resultSet);
+ }
+ }
+
+ public interface IReconnect {
+ Connection reconnect() throws SQLException;
+ }
+}
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java
index 4447f6f02..b87b86978 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java
@@ -19,6 +19,7 @@ package com.djrapitops.plan.system.database.databases.sql;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.api.exceptions.database.DBOpException;
import com.djrapitops.plan.data.store.containers.NetworkContainer;
+import com.djrapitops.plan.system.database.databases.DBType;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.locale.lang.PluginLang;
@@ -67,12 +68,9 @@ public class MySQLDB extends SQLDB {
increment++;
}
- /**
- * @return the name of the Database
- */
@Override
- public String getName() {
- return "MySQL";
+ public DBType getType() {
+ return DBType.MySQL;
}
/**
@@ -136,10 +134,11 @@ public class MySQLDB extends SQLDB {
@Override
public void close() {
+ super.close();
+
if (dataSource instanceof HikariDataSource) {
((HikariDataSource) dataSource).close();
}
- super.close();
}
@Override
@@ -158,11 +157,6 @@ public class MySQLDB extends SQLDB {
returnToPool(connection);
}
- @Override
- public boolean isUsingMySQL() {
- return true;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java
index b326913e2..3206cf3fa 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java
@@ -288,6 +288,10 @@ public abstract class SQLDB extends Database {
public abstract void returnToPool(Connection connection);
public boolean execute(ExecStatement statement) {
+ if (!isOpen()) {
+ throw new DBOpException("SQL Statement tried to execute while connection closed");
+ }
+
Connection connection = null;
try {
connection = getConnection();
@@ -328,6 +332,10 @@ public abstract class SQLDB extends Database {
}
public void executeBatch(ExecStatement statement) {
+ if (!isOpen()) {
+ throw new DBOpException("SQL Batch tried to execute while connection closed");
+ }
+
Connection connection = null;
try {
connection = getConnection();
@@ -346,6 +354,10 @@ public abstract class SQLDB extends Database {
}
public T query(QueryStatement statement) {
+ if (!isOpen()) {
+ throw new DBOpException("SQL Query tried to execute while connection closed");
+ }
+
Connection connection = null;
try {
connection = getConnection();
@@ -419,10 +431,6 @@ public abstract class SQLDB extends Database {
return pingTable;
}
- public boolean isUsingMySQL() {
- return false;
- }
-
@Override
public BackupOperations backup() {
return backupOps;
@@ -468,12 +476,12 @@ public abstract class SQLDB extends Database {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SQLDB sqldb = (SQLDB) o;
- return getName().equals(sqldb.getName());
+ return getType() == sqldb.getType();
}
@Override
public int hashCode() {
- return Objects.hash(getName());
+ return Objects.hash(getType().getName());
}
public Supplier getServerUUIDSupplier() {
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java
index 640afedd3..7b722c39f 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java
@@ -18,6 +18,7 @@ package com.djrapitops.plan.system.database.databases.sql;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.data.store.containers.NetworkContainer;
+import com.djrapitops.plan.system.database.databases.DBType;
import com.djrapitops.plan.system.file.PlanFiles;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.locale.Locale;
@@ -28,7 +29,6 @@ import com.djrapitops.plugin.benchmarking.Timings;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.console.PluginLogger;
import com.djrapitops.plugin.logging.error.ErrorHandler;
-import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.PluginTask;
import com.djrapitops.plugin.task.RunnableFactory;
import dagger.Lazy;
@@ -36,7 +36,9 @@ import dagger.Lazy;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
import java.util.Objects;
/**
@@ -104,30 +106,9 @@ public class SQLiteDB extends SQLDB {
stopConnectionPingTask();
try {
// Maintains Connection.
- connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getName(), new AbsRunnable() {
- @Override
- public void run() {
- Statement statement = null;
- ResultSet resultSet = null;
- try {
- if (connection != null && !connection.isClosed()) {
- statement = connection.createStatement();
- resultSet = statement.executeQuery("/* ping */ SELECT 1");
- }
- } catch (SQLException e) {
- logger.debug("Something went wrong during SQLite Connection upkeep task.");
- try {
- connection = getNewConnection(databaseFile);
- } catch (SQLException e1) {
- errorHandler.log(L.ERROR, this.getClass(), e1);
- logger.error("SQLite connection maintaining task had to be closed due to exception.");
- this.cancel();
- }
- } finally {
- MiscUtils.close(statement, resultSet);
- }
- }
- }).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
+ connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(),
+ new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler)
+ ).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
} catch (Exception ignored) {
}
}
@@ -141,12 +122,9 @@ public class SQLiteDB extends SQLDB {
}
}
- /**
- * @return the name of the Database
- */
@Override
- public String getName() {
- return "SQLite";
+ public DBType getType() {
+ return DBType.SQLite;
}
@Override
@@ -159,12 +137,13 @@ public class SQLiteDB extends SQLDB {
@Override
public void close() {
+ super.close();
stopConnectionPingTask();
+
if (connection != null) {
logger.debug("SQLite " + dbName + ": Closed Connection");
MiscUtils.close(connection);
}
- super.close();
}
@Override
@@ -250,4 +229,5 @@ public class SQLiteDB extends SQLDB {
}
}
+
}
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java
index ef1f614f8..071e22c85 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java
@@ -24,6 +24,7 @@ import com.djrapitops.plan.data.store.mutators.PerServerMutator;
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.data.store.objects.DateObj;
+import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
@@ -123,6 +124,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
Map timesKicked = usersTable.getAllTimesKicked();
Map> geoInfo = geoInfoTable.getAllGeoInfo();
Map> allPings = pingTable.getAllPings();
+ Map> allNicknames = nicknamesTable.getAllNicknamesUnmapped();
Map> sessions = sessionsTable.getSessionInfoOfServer(serverUUID);
Map>> map = new HashMap<>();
@@ -144,7 +146,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
- container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
+ container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid));
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
@@ -187,6 +189,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
Map timesKicked = usersTable.getAllTimesKicked();
Map> geoInfo = geoInfoTable.getAllGeoInfo();
Map> allPings = pingTable.getAllPings();
+ Map> allNicknames = nicknamesTable.getAllNicknamesUnmapped();
Map>> sessions = sessionsTable.getAllSessions(false);
Map> allUserInfo = userInfoTable.getAllUserInfo();
@@ -202,7 +205,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
- container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
+ container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid));
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java
index 70ef3d07b..35cfa9fcf 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java
@@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.system.database.databases.sql.patches;
+import com.djrapitops.plan.system.database.databases.DBType;
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
@@ -30,11 +31,11 @@ import java.util.UUID;
public abstract class Patch {
protected final SQLDB db;
- protected final boolean usingMySQL;
+ protected final DBType dbType;
public Patch(SQLDB db) {
this.db = db;
- usingMySQL = db.isUsingMySQL();
+ this.dbType = db.getType();
}
public abstract boolean hasBeenApplied();
@@ -46,15 +47,25 @@ public abstract class Patch {
}
public boolean hasTable(String tableName) {
- String sql = usingMySQL ?
- "SELECT * FROM information_schema.TABLES WHERE table_name=? AND TABLE_SCHEMA=? LIMIT 1" :
- "SELECT tbl_name FROM sqlite_master WHERE tbl_name=?";
+ boolean secondParameter;
+
+ String sql;
+ if (dbType == DBType.H2) {
+ sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=?";
+ secondParameter = false;
+ } else if (dbType.supportsMySQLQueries()) {
+ sql = "SELECT * FROM information_schema.TABLES WHERE table_name=? AND TABLE_SCHEMA=? LIMIT 1";
+ secondParameter = true;
+ } else {
+ sql = "SELECT tbl_name FROM sqlite_master WHERE tbl_name=?";
+ secondParameter = false;
+ }
return query(new QueryStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, tableName);
- if (usingMySQL) {
+ if (secondParameter) {
statement.setString(2, db.getConfig().getString(Settings.DB_DATABASE));
}
}
@@ -67,36 +78,49 @@ public abstract class Patch {
}
protected boolean hasColumn(String tableName, String columnName) {
- return usingMySQL ?
- query(new QueryStatement("SELECT * FROM information_schema.COLUMNS" +
- " WHERE TABLE_NAME=? AND COLUMN_NAME=? AND TABLE_SCHEMA=?") {
- @Override
- public void prepare(PreparedStatement statement) throws SQLException {
- statement.setString(1, tableName);
- statement.setString(2, columnName);
+ if (dbType.supportsMySQLQueries()) {
+ String query;
+
+ if (dbType == DBType.H2) {
+ query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS" +
+ " WHERE TABLE_NAME=? AND COLUMN_NAME=?";
+ } else {
+ query = "SELECT * FROM information_schema.COLUMNS" +
+ " WHERE TABLE_NAME=? AND COLUMN_NAME=? AND TABLE_SCHEMA=?";
+ }
+
+ return query(new QueryStatement(query) {
+ @Override
+ public void prepare(PreparedStatement statement) throws SQLException {
+ statement.setString(1, tableName);
+ statement.setString(2, columnName);
+ if (dbType != DBType.H2) {
statement.setString(3, db.getConfig().getString(Settings.DB_DATABASE));
}
+ }
- @Override
- public Boolean processResults(ResultSet set) throws SQLException {
- return set.next();
- }
- }) :
- query(new QueryAllStatement("PRAGMA table_info(" + tableName + ")") {
- @Override
- public Boolean processResults(ResultSet set) throws SQLException {
- while (set.next()) {
- if (columnName.equals(set.getString("name"))) {
- return true;
- }
+ @Override
+ public Boolean processResults(ResultSet set) throws SQLException {
+ return set.next();
+ }
+ });
+ } else {
+ return query(new QueryAllStatement("PRAGMA table_info(" + tableName + ")") {
+ @Override
+ public Boolean processResults(ResultSet set) throws SQLException {
+ while (set.next()) {
+ if (columnName.equals(set.getString("name"))) {
+ return true;
}
- return false;
}
- });
+ return false;
+ }
+ });
+ }
}
protected void addColumn(String tableName, String columnInfo) {
- db.executeUnsafe("ALTER TABLE " + tableName + " ADD " + (usingMySQL ? "" : "COLUMN ") + columnInfo);
+ db.executeUnsafe("ALTER TABLE " + tableName + " ADD " + (dbType.supportsMySQLQueries() ? "" : "COLUMN ") + columnInfo);
}
protected void dropTable(String name) {
@@ -104,7 +128,7 @@ public abstract class Patch {
}
protected void renameTable(String from, String to) {
- String sql = usingMySQL ?
+ String sql = dbType.supportsMySQLQueries() ?
"RENAME TABLE " + from + " TO " + to :
"ALTER TABLE " + from + " RENAME TO " + to;
db.execute(sql);
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java
index 95b7bcf85..c62e86dc9 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java
@@ -109,7 +109,7 @@ public class Version10Patch extends Patch {
" FROM " + tempNickTableName;
db.execute(statement);
try {
- if (usingMySQL) {
+ if (dbType.supportsMySQLQueries()) {
db.execute("SET foreign_key_checks = 0");
}
statement = "INSERT INTO plan_kills " +
@@ -118,7 +118,7 @@ public class Version10Patch extends Patch {
" FROM " + tempKillsTableName;
db.execute(statement);
} finally {
- if (usingMySQL) {
+ if (dbType.supportsMySQLQueries()) {
db.execute("SET foreign_key_checks = 1");
}
}
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java
index d84f3f734..6089e880f 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java
@@ -62,11 +62,11 @@ public class CommandUseTable extends Table {
public void createTable() throws DBInitException {
ServerTable serverTable = db.getServerTable();
createTable(TableSqlParser.createTable(tableName)
- .primaryKeyIDColumn(usingMySQL, Col.COMMAND_ID)
+ .primaryKeyIDColumn(supportsMySQLQueries, Col.COMMAND_ID)
.column(Col.COMMAND, Sql.varchar(20)).notNull()
.column(Col.TIMES_USED, Sql.INT).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
- .primaryKey(usingMySQL, Col.COMMAND_ID)
+ .primaryKey(supportsMySQLQueries, Col.COMMAND_ID)
.foreignKey(Col.SERVER_ID, serverTable.toString(), ServerTable.Col.SERVER_ID)
.toString()
);
diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java
index 33fcd2f0d..ca8eafae3 100644
--- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java
+++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java
@@ -81,8 +81,6 @@ public class NicknamesTable extends UserIDTable {
/**
* Get nicknames of the user on a server.
- *
- * Get's nicknames from other servers as well.
*
* @param uuid UUID of the Player
* @param serverUUID UUID of the server
@@ -119,8 +117,6 @@ public class NicknamesTable extends UserIDTable {
/**
* Get nicknames of the user on THIS server.
- *
- * Get's nicknames from other servers as well.
*
* @param uuid UUID of the Player
* @return The nicknames of the User
@@ -166,6 +162,42 @@ public class NicknamesTable extends UserIDTable {
});
}
+ /**
+ * Get nicknames of all users but doesn't map them by Server
+ *
+ * @return a {@code Map} with all nicknames of all users
+ * @see NicknamesTable#getAllNicknames();
+ */
+ public Map> getAllNicknamesUnmapped() {
+ String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
+ String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
+ String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
+ String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
+ String sql = "SELECT " +
+ Col.NICKNAME + ", " +
+ Col.LAST_USED + ", " +
+ usersUUIDColumn + ", " +
+ serverUUIDColumn +
+ " FROM " + tableName +
+ " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID +
+ " INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID;
+ return query(new QueryAllStatement