Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>${project.name}</finalName>
<resources>
Expand All @@ -36,6 +48,51 @@
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>module-info.class</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.MF</exclude>
</excludes>
</filter>
</filters>
<artifactSet>
<excludes>
<exclude>org.spigotmc:1.12.2-R0.1-SNAPSHOT</exclude>
<exclude>org.junit.jupiter:junit-jupiter</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

Expand All @@ -55,6 +112,7 @@
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
Expand All @@ -66,5 +124,26 @@
<artifactId>jsonmessage</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
31 changes: 22 additions & 9 deletions src/main/java/jp/azisaba/lgw/kdstatus/KDStatusReloaded.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package jp.azisaba.lgw.kdstatus;

import java.io.File;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;

import jp.azisaba.lgw.kdstatus.sql.*;
import jp.azisaba.lgw.kdstatus.task.DBConnectionCheckTask;
Expand Down Expand Up @@ -31,7 +33,7 @@ public class KDStatusReloaded extends JavaPlugin {

private SQLHandler sqlHandler = null;

public MySQLHandler sql;
public HikariMySQLDatabase sql;

private PlayerDataMySQLController kdData;

Expand All @@ -55,22 +57,33 @@ public void onEnable() {
sqlHandler = new SQLHandler(new File(getDataFolder(), "playerData.db"));
kdDataContainer = new KillDeathDataContainer(new PlayerDataSQLController(sqlHandler).init());

sql = new MySQLHandler();

this.kdData = new PlayerDataMySQLController(this);

try {
sql.connect();
} catch (SQLException throwables) {
throwables.printStackTrace();
getLogger().warning("Failed to connect SQLDatabase.");
}
DBAuthConfig.loadAuthConfig();
sql = DBAuthConfig.getDatabase(getLogger(), 10);

sql.connect();

if(sql.isConnected()){
getLogger().info("SQL Testing...");
try(PreparedStatement pstmt = sql.getConnection().prepareStatement("SELECT 1")) {
if(pstmt.executeQuery().next()) {
getLogger().info("SQL Test was success!");
} else {
getLogger().warning("Failed to test SQL Connection");
}
} catch (SQLException e) {
getLogger().log(Level.SEVERE, "Error on SQL Testing", e);
}
getLogger().info("SQL Test is finished!");

getLogger().info("Connected SQLDatabase!");

//ここでテーブル作るぞ
this.kdData.createTable();

getLogger().info("Table was created!");

}

saveTask = new SavePlayerDataTask(this);
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/jp/azisaba/lgw/kdstatus/sql/DBAuthConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package jp.azisaba.lgw.kdstatus.sql;

import jp.azisaba.lgw.kdstatus.KDStatusReloaded;
import lombok.AccessLevel;
import lombok.Getter;

import java.util.logging.Logger;

/**
* Safe auth config loader
*/
public class DBAuthConfig {
@Getter(AccessLevel.PROTECTED)
private static String host;
@Getter(AccessLevel.PROTECTED)
private static String port;
@Getter(AccessLevel.PROTECTED)
private static String database;
@Getter(AccessLevel.PROTECTED)
private static String user;
@Getter(AccessLevel.PROTECTED)
private static String password;

public static void loadAuthConfig() {
host = getConfigAsString("host");
port = getConfigAsString("port");
database = getConfigAsString("database");
user = getConfigAsString("username");
password = getConfigAsString("password");
}

public static HikariMySQLDatabase getDatabase(Logger logger, int maxPoolSize) {
return new HikariMySQLDatabase(
logger,
maxPoolSize,
host,
port,
database,
user,
password
);
}

private static String getConfigAsString(String path) {
return KDStatusReloaded.getPlugin().getConfig().getString(path);
}
}
167 changes: 167 additions & 0 deletions src/main/java/jp/azisaba/lgw/kdstatus/sql/HikariMySQLDatabase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package jp.azisaba.lgw.kdstatus.sql;


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Wrapper class of HikariDataSource for MySQL
*/
@RequiredArgsConstructor
public class HikariMySQLDatabase {
private final Logger logger;
private final int maxPoolSize;
private final String host, port, databaseName, user, password;

@Getter
private boolean initialized;
private HikariDataSource hikari;

public boolean isConnected() {
if(hikari == null) return false;
return hikari.isRunning();
}

/**
* connect to database.
*/
public void connect() {
if (initialized) {
logger.warning("Database is already initialized!");
return;
}
String jdbcUrl = String.format(
"jdbc:mysql://%s:%s/%s?useSSL=false",
host,
port,
databaseName
);

HikariConfig config = new HikariConfig();
config.setUsername(user);
config.setPassword(password);
config.setJdbcUrl(jdbcUrl);
config.setMaximumPoolSize(maxPoolSize);
// config.setConnectionInitSql("SELECT 1");
config.setAutoCommit(true);
config.setConnectionTimeout(1500); // TODO change this
hikari = new HikariDataSource(config);
}

/**
* close database connection
*/
public void close() {
hikari.close();
initialized = false;
}

/**
* reconnect database
*/
public void reconnect() {
close();
connect();
}

/**
* CAUTION: this method throws {@link SQLException} so need to catch it
*
* @return a connection of database
* @throws SQLException from {@link HikariDataSource#getConnection()}
*/
public Connection getConnection() throws SQLException {
return hikari.getConnection();
}

/**
* get a connection (Safer than {@link #getConnection()})
*
* @return database connection. If failed, return null.
*/

public Connection getConnectionOrNull() {
try {
return hikari.getConnection();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to get connection", e);
return null;
}
}


public PreparedStatement preparedStatement(@NonNull String sql) {
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.log(Level.SEVERE, "Failed to create preparedStatement: connection is null");
return null;
}
try {
return conn.prepareStatement(sql);
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to create preparedStatement", e);
return null;
}
}

/**
* execute a SQL statement
*
* @param sql SQL statement
* @param pstmtConsumer to process PreparedStatement (ex. {@link PreparedStatement#setString(int, String)})
* @return result of execution. If failed, return null
*/

public ResultSet executeQuery(@NonNull String sql, Consumer<PreparedStatement> pstmtConsumer) {
// get a connection
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.warning("Failed to execute query: connection is null");
return null;
}

// execute query
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
if (pstmtConsumer != null) {
pstmtConsumer.accept(pstmt);
}
return pstmt.executeQuery();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to execute query", e);
return null;
}
}

/**
* @param sql SQL statement
* @return is succeeded
*/
public boolean executeUpdate(String sql) {
Connection conn = getConnectionOrNull();
if (conn == null) {
logger.severe("Failed to execute update: connection is null");
return false;
}

try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
return true;
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to execute update", e);
return false;
}
}
}
Loading