starting work on sql unit tests

This commit is contained in:
nossr50 2023-12-27 21:14:14 -08:00
parent dadc295431
commit b0efd46584
4 changed files with 271 additions and 79 deletions

13
pom.xml
View File

@ -14,9 +14,9 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<java.version>16</java.version> <java.version>17</java.version>
</properties> </properties>
<issueManagement> <issueManagement>
@ -257,6 +257,13 @@
<!-- ... --> <!-- ... -->
</repositories> </repositories>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>me.clip</groupId> <groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>

View File

@ -10,6 +10,7 @@ import java.util.logging.Logger;
public class DatabaseManagerFactory { public class DatabaseManagerFactory {
private static Class<? extends DatabaseManager> customManager = null; private static Class<? extends DatabaseManager> customManager = null;
public static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
public static DatabaseManager getDatabaseManager(@NotNull String userFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) { public static DatabaseManager getDatabaseManager(@NotNull String userFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
if (customManager != null) { if (customManager != null) {
@ -27,7 +28,7 @@ public class DatabaseManagerFactory {
LogUtils.debug(mcMMO.p.getLogger(), "Falling back on " + (mcMMO.p.getGeneralConfig().getUseMySQL() ? "SQL" : "Flatfile") + " database"); LogUtils.debug(mcMMO.p.getLogger(), "Falling back on " + (mcMMO.p.getGeneralConfig().getUseMySQL() ? "SQL" : "Flatfile") + " database");
} }
return mcMMO.p.getGeneralConfig().getUseMySQL() ? new SQLDatabaseManager() : new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel); return mcMMO.p.getGeneralConfig().getUseMySQL() ? new SQLDatabaseManager(logger, MYSQL_DRIVER) : new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
} }
/** /**
@ -68,7 +69,7 @@ public class DatabaseManagerFactory {
case SQL: case SQL:
LogUtils.debug(mcMMO.p.getLogger(), "Using SQL Database"); LogUtils.debug(mcMMO.p.getLogger(), "Using SQL Database");
return new SQLDatabaseManager(); return new SQLDatabaseManager(logger, "com.mysql.cj.jdbc.Driver");
case CUSTOM: case CUSTOM:
try { try {

View File

@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
public final class SQLDatabaseManager implements DatabaseManager { public final class SQLDatabaseManager implements DatabaseManager {
private static final String ALL_QUERY_VERSION = "total"; private static final String ALL_QUERY_VERSION = "total";
@ -45,23 +46,19 @@ public final class SQLDatabaseManager implements DatabaseManager {
private final ReentrantLock massUpdateLock = new ReentrantLock(); private final ReentrantLock massUpdateLock = new ReentrantLock();
private final String CHARSET_SQL = "utf8mb4"; //This is compliant with UTF-8 while "utf8" is not, confusing but this is how it is. private final String CHARSET_SQL = "utf8mb4"; //This is compliant with UTF-8 while "utf8" is not, confusing but this is how it is.
private String driverPath = "com.mysql.cj.jdbc.Driver"; //modern driver private final Logger logger;
private final boolean h2;
protected SQLDatabaseManager() { SQLDatabaseManager(Logger logger, String driverPath) {
String connectionString = "jdbc:mysql://" + mcMMO.p.getGeneralConfig().getMySQLServerName() this(logger, driverPath, false);
+ ":" + mcMMO.p.getGeneralConfig().getMySQLServerPort() + "/" + mcMMO.p.getGeneralConfig().getMySQLDatabaseName(); }
if(!mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 17, 0) //Temporary hack for SQL and 1.17 support SQLDatabaseManager(Logger logger, String driverPath, boolean h2) {
&& mcMMO.p.getGeneralConfig().getMySQLSSL()) this.logger = logger;
connectionString += this.h2 = h2;
"?verifyServerCertificate=false"+ String connectionString = getConnectionString(h2);
"&useSSL=true"+
"&requireSSL=true";
else
connectionString+=
"?useSSL=false";
if(mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()) { if(!h2 && mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()) {
connectionString+= connectionString+=
"&allowPublicKeyRetrieval=true"; "&allowPublicKeyRetrieval=true";
} }
@ -76,7 +73,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
e.printStackTrace(); e.printStackTrace();
ex.printStackTrace(); ex.printStackTrace();
mcMMO.p.getLogger().severe("Neither driver found"); logger.severe("Neither driver found");
return; return;
} }
//throw e; // aborts onEnable() Riking if you want to do this, fully implement it. //throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
@ -133,9 +130,30 @@ public final class SQLDatabaseManager implements DatabaseManager {
checkStructure(); checkStructure();
} }
@NotNull
private static String getConnectionString(boolean h2) {
if (h2) {
return "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL";
}
String connectionString = "jdbc:mysql://" + mcMMO.p.getGeneralConfig().getMySQLServerName()
+ ":" + mcMMO.p.getGeneralConfig().getMySQLServerPort() + "/" + mcMMO.p.getGeneralConfig().getMySQLDatabaseName();
if(!mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 17, 0) //Temporary hack for SQL and 1.17 support
&& mcMMO.p.getGeneralConfig().getMySQLSSL())
connectionString +=
"?verifyServerCertificate=false"+
"&useSSL=true"+
"&requireSSL=true";
else
connectionString+=
"?useSSL=false";
return connectionString;
}
public int purgePowerlessUsers() { public int purgePowerlessUsers() {
massUpdateLock.lock(); massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging powerless users..."); logger.info("Purging powerless users...");
Connection connection = null; Connection connection = null;
Statement statement = null; Statement statement = null;
@ -165,13 +183,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
massUpdateLock.unlock(); massUpdateLock.unlock();
} }
mcMMO.p.getLogger().info("Purged " + purged + " users from the database."); logger.info("Purged " + purged + " users from the database.");
return purged; return purged;
} }
public void purgeOldUsers() { public void purgeOldUsers() {
massUpdateLock.lock(); massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging inactive users older than " + (mcMMO.p.getPurgeTime() / 2630000000L) + " months..."); logger.info("Purging inactive users older than " + (mcMMO.p.getPurgeTime() / 2630000000L) + " months...");
Connection connection = null; Connection connection = null;
Statement statement = null; Statement statement = null;
@ -196,7 +214,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
massUpdateLock.unlock(); massUpdateLock.unlock();
} }
mcMMO.p.getLogger().info("Purged " + purged + " users from the database."); logger.info("Purged " + purged + " users from the database.");
} }
public boolean removeUser(String playerName, UUID uuid) { public boolean removeUser(String playerName, UUID uuid) {
@ -253,7 +271,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
if (id == -1) { if (id == -1) {
id = newUser(connection, profile.getPlayerName(), profile.getUniqueId()); id = newUser(connection, profile.getPlayerName(), profile.getUniqueId());
if (id == -1) { if (id == -1) {
mcMMO.p.getLogger().severe("Failed to create new account for " + profile.getPlayerName()); logger.severe("Failed to create new account for " + profile.getPlayerName());
return false; return false;
} }
} }
@ -263,7 +281,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success &= (statement.executeUpdate() != 0); success &= (statement.executeUpdate() != 0);
statement.close(); statement.close();
if (!success) { if (!success) {
mcMMO.p.getLogger().severe("Failed to update last login for " + profile.getPlayerName()); logger.severe("Failed to update last login for " + profile.getPlayerName());
return false; return false;
} }
@ -293,7 +311,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success &= (statement.executeUpdate() != 0); success &= (statement.executeUpdate() != 0);
statement.close(); statement.close();
if (!success) { if (!success) {
mcMMO.p.getLogger().severe("Failed to update skills for " + profile.getPlayerName()); logger.severe("Failed to update skills for " + profile.getPlayerName());
return false; return false;
} }
@ -319,7 +337,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success &= (statement.executeUpdate() != 0); success &= (statement.executeUpdate() != 0);
statement.close(); statement.close();
if (!success) { if (!success) {
mcMMO.p.getLogger().severe("Failed to update experience for " + profile.getPlayerName()); logger.severe("Failed to update experience for " + profile.getPlayerName());
return false; return false;
} }
@ -340,7 +358,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success = (statement.executeUpdate() != 0); success = (statement.executeUpdate() != 0);
statement.close(); statement.close();
if (!success) { if (!success) {
mcMMO.p.getLogger().severe("Failed to update cooldowns for " + profile.getPlayerName()); logger.severe("Failed to update cooldowns for " + profile.getPlayerName());
return false; return false;
} }
@ -351,7 +369,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success = (statement.executeUpdate() != 0); success = (statement.executeUpdate() != 0);
statement.close(); statement.close();
if (!success) { if (!success) {
mcMMO.p.getLogger().severe("Failed to update hud settings for " + profile.getPlayerName()); logger.severe("Failed to update hud settings for " + profile.getPlayerName());
return false; return false;
} }
} }
@ -371,7 +389,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
//Fix for a plugin that people are using that is throwing SQL errors //Fix for a plugin that people are using that is throwing SQL errors
if(skill != null && SkillTools.isChildSkill(skill)) { if(skill != null && SkillTools.isChildSkill(skill)) {
mcMMO.p.getLogger().severe("A plugin hooking into mcMMO is being naughty with our database commands, update all plugins that hook into mcMMO and contact their devs!"); logger.severe("A plugin hooking into mcMMO is being naughty with our database commands, update all plugins that hook into mcMMO and contact their devs!");
throw new InvalidSkillException("A plugin hooking into mcMMO that you are using is attempting to read leaderboard skills for child skills, child skills do not have leaderboards! This is NOT an mcMMO error!"); throw new InvalidSkillException("A plugin hooking into mcMMO that you are using is attempting to read leaderboard skills for child skills, child skills do not have leaderboards! This is NOT an mcMMO error!");
} }
@ -560,7 +578,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet = statement.getGeneratedKeys(); resultSet = statement.getGeneratedKeys();
if (!resultSet.next()) { if (!resultSet.next()) {
mcMMO.p.getLogger().severe("Unable to create new user account in DB"); logger.severe("Unable to create new user account in DB");
return -1; return -1;
} }
@ -840,27 +858,30 @@ public final class SQLDatabaseManager implements DatabaseManager {
try { try {
connection = getConnection(PoolIdentifier.MISC); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES" String schemaQuery = this.h2 ? "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name = ?"
+ " WHERE table_schema = ?" : "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?";
+ " AND table_name = ?");
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName()); statement = connection.prepareStatement(schemaQuery);
statement.setString(2, tablePrefix + "users");
setStatementQuery(statement, "users");
resultSet = statement.executeQuery(); resultSet = statement.executeQuery();
if (!resultSet.next()) { if (!resultSet.next()) {
createStatement = connection.createStatement(); createStatement = connection.createStatement();
createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` (" String sql = "CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` (" +
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT," "`id` int AUTO_INCREMENT," +
+ "`user` varchar(40) NOT NULL," "`user` varchar(40) NOT NULL," +
+ "`uuid` varchar(36) NULL DEFAULT NULL," "`uuid` varchar(36)," +
+ "`lastlogin` int(32) unsigned NOT NULL," "`lastlogin` bigint NOT NULL," +
+ "PRIMARY KEY (`id`)," "PRIMARY KEY (`id`)," +
+ "INDEX(`user`(20) ASC)," "INDEX `user_index`(`user`)," +
+ "UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=" + CHARSET_SQL + " AUTO_INCREMENT=1;"); "UNIQUE(`uuid`))";
createStatement.executeUpdate(sql);
tryClose(createStatement); tryClose(createStatement);
} }
tryClose(resultSet); tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName()); setStatementQuery(statement, "huds");
statement.setString(2, tablePrefix + "huds");
resultSet = statement.executeQuery(); resultSet = statement.executeQuery();
if (!resultSet.next()) { if (!resultSet.next()) {
createStatement = connection.createStatement(); createStatement = connection.createStatement();
@ -873,8 +894,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(createStatement); tryClose(createStatement);
} }
tryClose(resultSet); tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName()); setStatementQuery(statement, "cooldowns");
statement.setString(2, tablePrefix + "cooldowns");
resultSet = statement.executeQuery(); resultSet = statement.executeQuery();
if (!resultSet.next()) { if (!resultSet.next()) {
createStatement = connection.createStatement(); createStatement = connection.createStatement();
@ -898,8 +918,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(createStatement); tryClose(createStatement);
} }
tryClose(resultSet); tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName()); setStatementQuery(statement, "skills");
statement.setString(2, tablePrefix + "skills");
resultSet = statement.executeQuery(); resultSet = statement.executeQuery();
if (!resultSet.next()) { if (!resultSet.next()) {
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'"; String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
@ -926,8 +945,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(createStatement); tryClose(createStatement);
} }
tryClose(resultSet); tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName()); setStatementQuery(statement, "experience");
statement.setString(2, tablePrefix + "experience");
resultSet = statement.executeQuery(); resultSet = statement.executeQuery();
if (!resultSet.next()) { if (!resultSet.next()) {
createStatement = connection.createStatement(); createStatement = connection.createStatement();
@ -968,7 +986,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
} }
mcMMO.p.getLogger().info("Killing orphans"); logger.info("Killing orphans");
createStatement = connection.createStatement(); createStatement = connection.createStatement();
createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "experience`.`user_id` = `u`.`id`)"); createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "experience`.`user_id` = `u`.`id`)");
createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "huds`.`user_id` = `u`.`id`)"); createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "huds`.`user_id` = `u`.`id`)");
@ -987,7 +1005,18 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
private Connection getConnection(PoolIdentifier identifier) throws SQLException { private void setStatementQuery(PreparedStatement statement, String tableName) throws SQLException {
if (!this.h2) {
// Set schema name for MySQL
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + tableName);
} else {
// For H2, the schema parameter is not needed
statement.setString(1, tablePrefix + tableName);
}
}
Connection getConnection(PoolIdentifier identifier) throws SQLException {
Connection connection = null; Connection connection = null;
switch (identifier) { switch (identifier) {
case LOAD: case LOAD:
@ -1013,7 +1042,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
*/ */
private void checkDatabaseStructure(Connection connection, UpgradeType upgrade) { private void checkDatabaseStructure(Connection connection, UpgradeType upgrade) {
if (!mcMMO.getUpgradeManager().shouldUpgrade(upgrade)) { if (!mcMMO.getUpgradeManager().shouldUpgrade(upgrade)) {
LogUtils.debug(mcMMO.p.getLogger(), "Skipping " + upgrade.name() + " upgrade (unneeded)"); LogUtils.debug(logger, "Skipping " + upgrade.name() + " upgrade (unneeded)");
return; return;
} }
@ -1196,16 +1225,26 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
private void printErrors(SQLException ex) { private void printErrors(SQLException ex) {
if (debug) { if (debug || h2) {
ex.printStackTrace(); ex.printStackTrace();
} else {
for (StackTraceElement element : ex.getStackTrace()) {
logger.severe("Location: " + element.getClassName() + " " + element.getMethodName() + " " + element.getLineNumber());
}
} }
StackTraceElement element = ex.getStackTrace()[0]; // logger.severe("SQLException: " + ex.getMessage());
mcMMO.p.getLogger().severe("Location: " + element.getClassName() + " " + element.getMethodName() + " " + element.getLineNumber()); logger.severe("SQLState: " + ex.getSQLState());
mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage()); logger.severe("VendorError: " + ex.getErrorCode());
mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode()); // Handling SQLException chain
SQLException nextException = ex.getNextException();
while (nextException != null) {
logger.severe("Caused by: " + nextException.getMessage());
nextException = nextException.getNextException();
} }
}
public DatabaseType getDatabaseType() { public DatabaseType getDatabaseType() {
return DatabaseType.SQL; return DatabaseType.SQL;
@ -1222,7 +1261,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
return; return;
} }
resultSet.close(); resultSet.close();
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables to drop name uniqueness..."); logger.info("Updating mcMMO MySQL tables to drop name uniqueness...");
statement.execute("ALTER TABLE `" + tablePrefix + "users` " statement.execute("ALTER TABLE `" + tablePrefix + "users` "
+ "DROP INDEX `user`," + "DROP INDEX `user`,"
+ "ADD INDEX `user` (`user`(20) ASC)"); + "ADD INDEX `user` (`user`(20) ASC)");
@ -1240,7 +1279,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_ALCHEMY); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_ALCHEMY);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Alchemy..."); logger.info("Updating mcMMO MySQL tables for Alchemy...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `alchemy` int(10) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `alchemy` int(10) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
} }
@ -1252,7 +1291,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_BLAST_MINING_COOLDOWN); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_BLAST_MINING_COOLDOWN);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining..."); logger.info("Updating mcMMO MySQL tables for Blast Mining...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0'");
} }
} }
@ -1263,7 +1302,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UNIQUE_PLAYER_DATA); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UNIQUE_PLAYER_DATA);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Chimaera Wing..."); logger.info("Updating mcMMO MySQL tables for Chimaera Wing...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `chimaera_wing` int(32) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `chimaera_wing` int(32) NOT NULL DEFAULT '0'");
} }
} }
@ -1274,7 +1313,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_FISHING); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_FISHING);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing..."); logger.info("Updating mcMMO MySQL tables for Fishing...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
} }
@ -1286,7 +1325,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_MOB_HEALTHBARS); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_MOB_HEALTHBARS);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars..."); logger.info("Updating mcMMO MySQL tables for mob healthbars...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + mcMMO.p.getGeneralConfig().getMobHealthbarDefault() + "'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + mcMMO.p.getGeneralConfig().getMobHealthbarDefault() + "'");
} }
} }
@ -1297,7 +1336,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SCOREBOARD_TIPS); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SCOREBOARD_TIPS);
} }
catch (SQLException ex) { catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for scoreboard tips..."); logger.info("Updating mcMMO MySQL tables for scoreboard tips...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `scoreboardtips` int(10) NOT NULL DEFAULT '0' ;"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `scoreboardtips` int(10) NOT NULL DEFAULT '0' ;");
} }
} }
@ -1310,7 +1349,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet.last(); resultSet.last();
if (resultSet.getRow() != SkillTools.NON_CHILD_SKILLS.size()) { if (resultSet.getRow() != SkillTools.NON_CHILD_SKILLS.size()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases"); logger.info("Indexing tables, this may take a while on larger databases");
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) { for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
String skill_name = skill.name().toLowerCase(Locale.ENGLISH); String skill_name = skill.name().toLowerCase(Locale.ENGLISH);
@ -1351,7 +1390,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
if (!column_exists) { if (!column_exists) {
mcMMO.p.getLogger().info("Adding UUIDs to mcMMO MySQL user table..."); logger.info("Adding UUIDs to mcMMO MySQL user table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(36) NULL DEFAULT NULL"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(36) NULL DEFAULT NULL");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD UNIQUE INDEX `uuid` (`uuid`) USING BTREE"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD UNIQUE INDEX `uuid` (`uuid`) USING BTREE");
@ -1420,7 +1459,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
if (column_exists) { if (column_exists) {
mcMMO.p.getLogger().info("Removing party name from users table..."); logger.info("Removing party name from users table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party`"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party`");
} }
@ -1454,7 +1493,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
if (!column_exists) { if (!column_exists) {
mcMMO.p.getLogger().info("Adding skill total column to skills table..."); logger.info("Adding skill total column to skills table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD COLUMN `total` int NOT NULL DEFAULT '0'"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD COLUMN `total` int NOT NULL DEFAULT '0'");
statement.executeUpdate("UPDATE `" + tablePrefix + "skills` SET `total` = (taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy)"); statement.executeUpdate("UPDATE `" + tablePrefix + "skills` SET `total` = (taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy)");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_total` (`total`) USING BTREE"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_total` (`total`) USING BTREE");
@ -1490,7 +1529,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
if (column_exists) { if (column_exists) {
mcMMO.p.getLogger().info("Removing Spout HUD type from huds table..."); logger.info("Removing Spout HUD type from huds table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` DROP COLUMN `hudtype`"); statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` DROP COLUMN `hudtype`");
} }
@ -1577,7 +1616,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
@Override @Override
public void onDisable() { public void onDisable() {
LogUtils.debug(mcMMO.p.getLogger(), "Releasing connection pool resource..."); LogUtils.debug(logger, "Releasing connection pool resource...");
miscPool.close(); miscPool.close();
loadPool.close(); loadPool.close();
savePool.close(); savePool.close();
@ -1619,19 +1658,19 @@ public final class SQLDatabaseManager implements DatabaseManager {
*/ */
//Alter users table //Alter users table
mcMMO.p.getLogger().info("SQL Converting tables from latin1 to utf8mb4"); logger.info("SQL Converting tables from latin1 to utf8mb4");
//Update "user" column //Update "user" column
try { try {
mcMMO.p.getLogger().info("Updating user column to new encoding"); logger.info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUserInUsersTableSQLQuery()); statement.executeUpdate(getUpdateUserInUsersTableSQLQuery());
//Update "uuid" column //Update "uuid" column
mcMMO.p.getLogger().info("Updating user column to new encoding"); logger.info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUUIDInUsersTableSQLQuery()); statement.executeUpdate(getUpdateUUIDInUsersTableSQLQuery());
//Update "mobhealthbar" column //Update "mobhealthbar" column
mcMMO.p.getLogger().info("Updating mobhealthbar column to new encoding"); logger.info("Updating mobhealthbar column to new encoding");
statement.executeUpdate(getUpdateMobHealthBarInHudsTableSQLQuery()); statement.executeUpdate(getUpdateMobHealthBarInHudsTableSQLQuery());
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.SQL_CHARSET_UTF8MB4); mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.SQL_CHARSET_UTF8MB4);

View File

@ -0,0 +1,145 @@
package com.gmail.nossr50.database;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.GeneralConfig;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.compat.CompatibilityManager;
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import com.gmail.nossr50.util.platform.version.SimpleNumericVersion;
import com.gmail.nossr50.util.upgrade.UpgradeManager;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
class SQLDatabaseManagerTest {
private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
static MockedStatic<mcMMO> mockedMcMMO;
SQLDatabaseManager sqlDatabaseManager;
static GeneralConfig generalConfig;
static AdvancedConfig advancedConfig;
static UpgradeManager upgradeManager;
static CompatibilityManager compatibilityManager;
@BeforeAll
static void setUpAll() {
// stub mcMMO.p
mockedMcMMO = Mockito.mockStatic(mcMMO.class);
mcMMO.p = Mockito.mock(mcMMO.class);
when(mcMMO.p.getLogger()).thenReturn(logger);
// general config mock
mockGeneralConfig();
// advanced config mock
advancedConfig = Mockito.mock(AdvancedConfig.class);
when(mcMMO.p.getAdvancedConfig()).thenReturn(advancedConfig);
// starting level
when(mcMMO.p.getAdvancedConfig().getStartingLevel()).thenReturn(0);
// compatibility manager mock
compatibilityManager = Mockito.mock(CompatibilityManager.class);
when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
when(compatibilityManager.getMinecraftGameVersion()).thenReturn(new MinecraftGameVersion(1, 20, 4));
// upgrade manager mock
upgradeManager = Mockito.mock(UpgradeManager.class);
when(mcMMO.getUpgradeManager()).thenReturn(upgradeManager);
// don't trigger upgrades
when(mcMMO.getUpgradeManager().shouldUpgrade(any())).thenReturn(false);
}
private static void mockGeneralConfig() {
generalConfig = Mockito.mock(GeneralConfig.class);
when(generalConfig.getLocale()).thenReturn("en_US");
when(mcMMO.p.getGeneralConfig()).thenReturn(generalConfig);
// max pool size
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.MISC))
.thenReturn(10);
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.LOAD))
.thenReturn(20);
when(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier.SAVE))
.thenReturn(20);
// max connections
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.MISC))
.thenReturn(30);
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.LOAD))
.thenReturn(30);
when(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier.SAVE))
.thenReturn(30);
// table prefix
when(mcMMO.p.getGeneralConfig().getMySQLTablePrefix()).thenReturn("mcmmo_");
// public key retrieval
when(mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()).thenReturn(true);
// debug
when(mcMMO.p.getGeneralConfig().getMySQLDebug()).thenReturn(true);
// use mysql
when(mcMMO.p.getGeneralConfig().getUseMySQL()).thenReturn(true);
// use ssl
when(mcMMO.p.getGeneralConfig().getMySQLSSL()).thenReturn(true);
// username
when(mcMMO.p.getGeneralConfig().getMySQLUserName()).thenReturn("sa");
// password
when(mcMMO.p.getGeneralConfig().getMySQLUserPassword()).thenReturn("");
// host
when(mcMMO.p.getGeneralConfig().getMySQLServerName()).thenReturn("localhost");
}
@BeforeEach
void setUp() {
assertNull(sqlDatabaseManager);
sqlDatabaseManager = new SQLDatabaseManager(logger, "org.h2.Driver", true);
}
@AfterEach
void tearDown() {
sqlDatabaseManager = null;
}
@Test
void testGetConnectionMisc() throws Exception {
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.MISC));
}
@Test
void testGetConnectionLoad() throws Exception {
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.LOAD));
}
@Test
void testGetConnectionSave() throws Exception {
assertNotNull(sqlDatabaseManager.getConnection(SQLDatabaseManager.PoolIdentifier.SAVE));
}
@Test
void testNewUser() {
Player player = Mockito.mock(Player.class);
when(player.getUniqueId()).thenReturn(java.util.UUID.randomUUID());
when(player.getName()).thenReturn("nossr50");
sqlDatabaseManager.newUser(player);
}
}