From c8e98e6caab6c6bf40e36fdca639d1a8aa3b04cb Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 10 Jan 2019 14:11:26 +0200 Subject: [PATCH] DB Index Creation Task + test (Not used yet) --- .../databases/sql/CreateIndexTask.java | 81 +++++++++++++++++++ .../databases/sql/operation/Queries.java | 17 ++++ .../databases/sql/tables/UsersTable.java | 4 +- .../database/databases/sql/CommonDBTest.java | 5 ++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/CreateIndexTask.java diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/CreateIndexTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/CreateIndexTask.java new file mode 100644 index 000000000..b9a6dc224 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/CreateIndexTask.java @@ -0,0 +1,81 @@ +package com.djrapitops.plan.system.database.databases.sql; + +import com.djrapitops.plan.system.database.databases.DBType; +import com.djrapitops.plan.system.database.databases.sql.operation.Queries; +import com.djrapitops.plan.system.database.databases.sql.statements.Column; +import com.djrapitops.plan.system.database.databases.sql.tables.*; +import com.djrapitops.plugin.task.AbsRunnable; +import org.apache.commons.text.TextStringBuilder; + +public class CreateIndexTask extends AbsRunnable { + + private final SQLDB db; + + public CreateIndexTask(SQLDB db) { + this.db = db; + } + + @Override + public void run() { + createIndex(UsersTable.TABLE_NAME, "plan_users_uuid_index", + UsersTable.Col.UUID + ); + createIndex(UserInfoTable.TABLE_NAME, "plan_user_info_uuid_index", + UserInfoTable.Col.UUID, + UserInfoTable.Col.SERVER_UUID + ); + createIndex(SessionsTable.TABLE_NAME, "plan_sessions_uuid_index", + SessionsTable.Col.UUID, + SessionsTable.Col.SERVER_UUID + ); + createIndex(SessionsTable.TABLE_NAME, "plan_sessions_date_index", + SessionsTable.Col.SESSION_START + ); + createIndex(WorldTimesTable.TABLE_NAME, "plan_world_times_uuid_index", + WorldTimesTable.Col.UUID, + WorldTimesTable.Col.SERVER_UUID + ); + createIndex(KillsTable.TABLE_NAME, "plan_kills_uuid_index", + KillsTable.Col.KILLER_UUID, + KillsTable.Col.VICTIM_UUID, + KillsTable.Col.SERVER_UUID + ); + createIndex(KillsTable.TABLE_NAME, "plan_kills_date_index", + KillsTable.Col.DATE + ); + createIndex(PingTable.TABLE_NAME, "plan_ping_uuid_index", + PingTable.Col.UUID, + PingTable.Col.SERVER_UUID + ); + createIndex(PingTable.TABLE_NAME, "plan_ping_date_index", + PingTable.Col.DATE + ); + createIndex(TPSTable.TABLE_NAME, "plan_tps_date_index", + TPSTable.Col.DATE + ); + } + + private void createIndex(String tableName, String indexName, Column... indexedColumns) { + if (indexedColumns.length == 0) { + throw new IllegalArgumentException("Can not create index without columns"); + } + + boolean isMySQL = db.getType() == DBType.MYSQL; + if (isMySQL) { + boolean indexExists = db.query(Queries.doesIndexExist(indexName, tableName)); + if (indexExists) return; + } + + TextStringBuilder sql = new TextStringBuilder("CREATE INDEX "); + if (!isMySQL) { + sql.append("IF NOT EXISTS "); + } + sql.append(indexName).append(" ON ").append(tableName); + + sql.append(" ("); + sql.appendWithSeparators(indexedColumns, ","); + sql.append(")"); + + db.execute(sql.toString()); + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/Queries.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/Queries.java index 1c9d63208..ba0ca7f54 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/Queries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/Queries.java @@ -70,4 +70,21 @@ public class Queries { }; } + public static QueryStatement doesIndexExist(String indexName, String tableName) { + String sql = "SELECT COUNT(1) as IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS " + + "WHERE table_schema=DATABASE() AND table_name=? AND index_name=?"; + return new QueryStatement(sql) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setString(1, tableName); + statement.setString(2, indexName); + } + + @Override + public Boolean processResults(ResultSet set) throws SQLException { + return set.next() && set.getInt("IndexIsThere") > 0; + } + }; + } + } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java index 9cc8fc8e7..ee859373c 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java @@ -44,8 +44,10 @@ import java.util.*; */ public class UsersTable extends UserUUIDTable { + public static final String TABLE_NAME = "plan_users"; + public UsersTable(SQLDB db) { - super("plan_users", db); + super(TABLE_NAME, db); statementSelectID = "(" + Select.from(tableName, tableName + "." + Col.ID).where(Col.UUID + "=?").toString() + " LIMIT 1)"; insertStatement = Insert.values(tableName, Col.UUID, diff --git a/Plan/common/src/test/java/com/djrapitops/plan/system/database/databases/sql/CommonDBTest.java b/Plan/common/src/test/java/com/djrapitops/plan/system/database/databases/sql/CommonDBTest.java index 8b4b4c2ed..dec3ba5bc 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/system/database/databases/sql/CommonDBTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/system/database/databases/sql/CommonDBTest.java @@ -1059,4 +1059,9 @@ public abstract class CommonDBTest { assertFalse(settingsTable.fetchNewerConfig(savedMs, serverUUID).isPresent()); } + @Test + public void indexCreationWorksWithoutErrors() { + new CreateIndexTask(db).run(); + } + }