mirror of
https://github.com/xHyroM/lighteco.git
synced 2024-11-25 00:01:05 +01:00
feat: mysql [wip]
This commit is contained in:
parent
66bb95559c
commit
818ffe28cf
9 changed files with 262 additions and 20 deletions
|
@ -12,6 +12,21 @@ public enum Dependency {
|
|||
"org.xerial",
|
||||
"sqlite-jdbc",
|
||||
"3.28.0"
|
||||
),
|
||||
MARIADB_DRIVER(
|
||||
"org.mariadb.jdbc",
|
||||
"mariadb-java-client",
|
||||
"3.1.3"
|
||||
),
|
||||
MYSQL_DRIVER(
|
||||
"mysql",
|
||||
"mysql-connector-java",
|
||||
"8.0.23"
|
||||
),
|
||||
POSTGRESQL_DRIVER(
|
||||
"org.postgresql",
|
||||
"postgresql",
|
||||
"42.6.0"
|
||||
);
|
||||
|
||||
@Getter
|
||||
|
|
|
@ -11,6 +11,8 @@ public class DependencyRegistry {
|
|||
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder()
|
||||
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
|
||||
.putAll(StorageType.H2, Dependency.H2_DRIVER)
|
||||
.putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER)
|
||||
.putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER)
|
||||
.build();
|
||||
|
||||
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
|
||||
|
|
|
@ -7,6 +7,8 @@ import dev.xhyrom.lighteco.common.storage.provider.memory.MemoryStorageProvider;
|
|||
import dev.xhyrom.lighteco.common.storage.provider.sql.SqlStorageProvider;
|
||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.file.H2ConnectionFactory;
|
||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.file.SqliteConnectionFactory;
|
||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari.MariaDBConnectionFactory;
|
||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari.MySQLConnectionFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -45,6 +47,16 @@ public class StorageFactory {
|
|||
this.plugin,
|
||||
new SqliteConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-sqlite.db"))
|
||||
);
|
||||
case "mysql":
|
||||
return new SqlStorageProvider(
|
||||
this.plugin,
|
||||
new MySQLConnectionFactory(this.plugin.getConfig().storage.data)
|
||||
);
|
||||
case "mariadb":
|
||||
return new SqlStorageProvider(
|
||||
this.plugin,
|
||||
new MariaDBConnectionFactory(this.plugin.getConfig().storage.data)
|
||||
);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown storage provider: " + provider);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public enum SqlStatements {
|
|||
case SQLITE -> {
|
||||
return this.sqlite;
|
||||
}
|
||||
case H2, MYSQL -> {
|
||||
case H2, MYSQL, MARIADB -> {
|
||||
return this.mysql;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
|
||||
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public abstract class DriverBasedHikariConnectionFactory extends HikariConnectionFactory {
|
||||
protected DriverBasedHikariConnectionFactory(StorageDataConfig configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
protected abstract String driverClassName();
|
||||
|
||||
protected abstract String driverJdbcIdentifier();
|
||||
|
||||
@Override
|
||||
protected void configureDatabase(HikariConfig config, String address, String port, String databaseName, String username, String password) {
|
||||
config.setDriverClassName(driverClassName());
|
||||
config.setJdbcUrl(String.format("jdbc:%s://%s:%s/%s", driverJdbcIdentifier(), address, port, databaseName));
|
||||
config.setUsername(username);
|
||||
config.setPassword(password);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postInitialize() {
|
||||
super.postInitialize();
|
||||
|
||||
deregisterDriver(driverClassName());
|
||||
}
|
||||
|
||||
private static void deregisterDriver(String driverClassName) {
|
||||
Enumeration<Driver> drivers = DriverManager.getDrivers();
|
||||
while (drivers.hasMoreElements()) {
|
||||
Driver driver = drivers.nextElement();
|
||||
if (driver.getClass().getName().equals(driverClassName)) {
|
||||
try {
|
||||
DriverManager.deregisterDriver(driver);
|
||||
} catch (SQLException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,104 @@
|
|||
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
|
||||
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
|
||||
import dev.xhyrom.lighteco.common.storage.StorageType;
|
||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class HikariConnectionFactory implements ConnectionFactory {
|
||||
public abstract class HikariConnectionFactory implements ConnectionFactory {
|
||||
private final StorageDataConfig configuration;
|
||||
private HikariDataSource hikari;
|
||||
|
||||
public HikariConnectionFactory(StorageDataConfig configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
protected abstract String defaultPort();
|
||||
|
||||
protected abstract void configureDatabase(HikariConfig config, String address, String port, String databaseName, String username, String password);
|
||||
|
||||
protected void overrideProperties(Map<String, Object> properties) {
|
||||
// https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery
|
||||
properties.putIfAbsent("socketTimeout", String.valueOf(TimeUnit.SECONDS.toMillis(30)));
|
||||
}
|
||||
|
||||
protected void setProperties(HikariConfig config, Map<String, Object> properties) {
|
||||
for (Map.Entry<String, Object> property : properties.entrySet()) {
|
||||
config.addDataSourceProperty(property.getKey(), property.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the Hikari pool has been initialised
|
||||
*/
|
||||
protected void postInitialize() {
|
||||
|
||||
@Override
|
||||
public StorageType getImplementationName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LightEcoPlugin plugin) {
|
||||
HikariConfig config = new HikariConfig();
|
||||
|
||||
// set pool name so the logging output can be linked back to us
|
||||
config.setPoolName("lighteco-hikari");
|
||||
|
||||
// get the database info/credentials from the config file
|
||||
String[] addressSplit = this.configuration.address.split(":");
|
||||
String address = addressSplit[0];
|
||||
String port = addressSplit.length > 1 ? addressSplit[1] : defaultPort();
|
||||
|
||||
// allow the implementation to configure the HikariConfig appropriately with these values
|
||||
configureDatabase(config, address, port, this.configuration.database, this.configuration.username, this.configuration.password);
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
|
||||
this.overrideProperties(properties);
|
||||
this.setProperties(config, properties);
|
||||
|
||||
// configure the connection pool
|
||||
// config.setMaximumPoolSize(1);
|
||||
// config.setMinimumIdle(10);
|
||||
// config.setMaxLifetime(1800000);
|
||||
// config.setKeepaliveTime(0);
|
||||
// config.setConnectionTimeout(5000);
|
||||
// config.setInitializationFailTimeout(-1);
|
||||
|
||||
this.hikari = new HikariDataSource(config);
|
||||
|
||||
postInitialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws Exception {
|
||||
public void shutdown() {
|
||||
if (this.hikari != null) {
|
||||
this.hikari.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
if (this.hikari == null) {
|
||||
throw new SQLException("Unable to get a connection from the pool. (hikari is null)");
|
||||
}
|
||||
|
||||
Connection connection = this.hikari.getConnection();
|
||||
if (connection == null) {
|
||||
throw new SQLException("Unable to get a connection from the pool. (getConnection returned null)");
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<String, String> getStatementProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws Exception {
|
||||
return null;
|
||||
return s -> s.replace('\'', '`');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
|
||||
|
||||
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
|
||||
import dev.xhyrom.lighteco.common.storage.StorageType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MariaDBConnectionFactory extends DriverBasedHikariConnectionFactory {
|
||||
public MariaDBConnectionFactory(StorageDataConfig configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageType getImplementationName() {
|
||||
return StorageType.MARIADB;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String defaultPort() {
|
||||
return "3306";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String driverClassName() {
|
||||
return "org.mariadb.jdbc.Driver";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String driverJdbcIdentifier() {
|
||||
return "mariadb";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
|
||||
|
||||
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
|
||||
import dev.xhyrom.lighteco.common.storage.StorageType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MySQLConnectionFactory extends DriverBasedHikariConnectionFactory {
|
||||
public MySQLConnectionFactory(StorageDataConfig configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageType getImplementationName() {
|
||||
return StorageType.MYSQL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String defaultPort() {
|
||||
return "3306";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String driverClassName() {
|
||||
return "com.mysql.cj.jdbc.Driver";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String driverJdbcIdentifier() {
|
||||
return "mysql";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void overrideProperties(Map<String, Object> properties) {
|
||||
// https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
|
||||
properties.putIfAbsent("cachePrepStmts", "true");
|
||||
properties.putIfAbsent("prepStmtCacheSize", "250");
|
||||
properties.putIfAbsent("prepStmtCacheSqlLimit", "2048");
|
||||
properties.putIfAbsent("useServerPrepStmts", "true");
|
||||
properties.putIfAbsent("useLocalSessionState", "true");
|
||||
properties.putIfAbsent("rewriteBatchedStatements", "true");
|
||||
properties.putIfAbsent("cacheResultSetMetadata", "true");
|
||||
properties.putIfAbsent("cacheServerConfiguration", "true");
|
||||
properties.putIfAbsent("elideSetAutoCommits", "true");
|
||||
properties.putIfAbsent("maintainTimeStats", "false");
|
||||
properties.putIfAbsent("alwaysSendSetIsolation", "false");
|
||||
properties.putIfAbsent("cacheCallableStmts", "true");
|
||||
|
||||
// https://stackoverflow.com/a/54256150
|
||||
// It's not super important which timezone we pick, because we don't use time-based
|
||||
// data types in any of our schemas/queries.
|
||||
properties.putIfAbsent("serverTimezone", "UTC");
|
||||
}
|
||||
}
|
13
common/src/main/resources/schema/mariadb.sql
Normal file
13
common/src/main/resources/schema/mariadb.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE IF NOT EXISTS `{prefix}_users` (
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`currency_identifier` VARCHAR(255) NOT NULL,
|
||||
`balance` DECIMAL(10, 2) NOT NULL,
|
||||
PRIMARY KEY (`uuid`, `currency_identifier`)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `{prefix}_{context}_users` (
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`currency_identifier` VARCHAR(255) NOT NULL,
|
||||
`balance` DECIMAL(10, 2) NOT NULL,
|
||||
PRIMARY KEY (`uuid`, `currency_identifier`)
|
||||
);
|
Loading…
Reference in a new issue