mirror of
https://github.com/xHyroM/lighteco.git
synced 2024-11-21 22:41:06 +01:00
feat: mysql [wip]
This commit is contained in:
parent
66bb95559c
commit
818ffe28cf
9 changed files with 262 additions and 20 deletions
|
@ -4,14 +4,29 @@ import lombok.Getter;
|
||||||
|
|
||||||
public enum Dependency {
|
public enum Dependency {
|
||||||
H2_DRIVER(
|
H2_DRIVER(
|
||||||
"com.h2database",
|
"com.h2database",
|
||||||
"h2",
|
"h2",
|
||||||
"2.1.214"
|
"2.1.214"
|
||||||
),
|
),
|
||||||
SQLITE_DRIVER(
|
SQLITE_DRIVER(
|
||||||
"org.xerial",
|
"org.xerial",
|
||||||
"sqlite-jdbc",
|
"sqlite-jdbc",
|
||||||
"3.28.0"
|
"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
|
@Getter
|
||||||
|
|
|
@ -11,6 +11,8 @@ public class DependencyRegistry {
|
||||||
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder()
|
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder()
|
||||||
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
|
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
|
||||||
.putAll(StorageType.H2, Dependency.H2_DRIVER)
|
.putAll(StorageType.H2, Dependency.H2_DRIVER)
|
||||||
|
.putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER)
|
||||||
|
.putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
|
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.SqlStorageProvider;
|
||||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.file.H2ConnectionFactory;
|
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.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;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -45,6 +47,16 @@ public class StorageFactory {
|
||||||
this.plugin,
|
this.plugin,
|
||||||
new SqliteConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-sqlite.db"))
|
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:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown storage provider: " + provider);
|
throw new IllegalArgumentException("Unknown storage provider: " + provider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public enum SqlStatements {
|
||||||
case SQLITE -> {
|
case SQLITE -> {
|
||||||
return this.sqlite;
|
return this.sqlite;
|
||||||
}
|
}
|
||||||
case H2, MYSQL -> {
|
case H2, MYSQL, MARIADB -> {
|
||||||
return this.mysql;
|
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;
|
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.plugin.LightEcoPlugin;
|
||||||
import dev.xhyrom.lighteco.common.storage.StorageType;
|
|
||||||
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory;
|
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory;
|
||||||
|
|
||||||
import java.sql.Connection;
|
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;
|
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
|
@Override
|
||||||
public void init(LightEcoPlugin plugin) {
|
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
|
@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
|
@Override
|
||||||
public Function<String, String> getStatementProcessor() {
|
public Function<String, String> getStatementProcessor() {
|
||||||
return null;
|
return s -> s.replace('\'', '`');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Connection getConnection() throws Exception {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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