1
0
Fork 0
mirror of https://github.com/xHyroM/lighteco.git synced 2024-11-14 03:18:07 +01:00

feat: auto dependency download

This commit is contained in:
Jozef Steinhübl 2023-08-28 20:40:47 +02:00
parent 341bc3eb44
commit 66bb95559c
24 changed files with 461 additions and 46 deletions

View file

@ -50,8 +50,8 @@ public class BukkitLightEcoBootstrap implements LightEcoBootstrap, LoaderBootstr
} }
@Override @Override
public File getDataFolder() { public Path getDataDirectory() {
return this.loader.getDataFolder(); return this.loader.getDataFolder().toPath();
} }
@Override @Override

View file

@ -10,8 +10,7 @@ dependencies {
exclude(module = "annotations") exclude(module = "annotations")
} }
api("net.kyori:adventure-text-minimessage:4.14.0") api("net.kyori:adventure-text-minimessage:4.14.0")
api("com.google.guava:guava:32.1.2-jre")
api("org.xerial:sqlite-jdbc:3.40.0.0")
implementation("eu.okaeri:okaeri-configs-yaml-snakeyaml:5.0.0-beta.5") implementation("eu.okaeri:okaeri-configs-yaml-snakeyaml:5.0.0-beta.5")
implementation("eu.okaeri:okaeri-configs-validator-okaeri:5.0.0-beta.5") implementation("eu.okaeri:okaeri-configs-validator-okaeri:5.0.0-beta.5")

View file

@ -6,10 +6,11 @@ import eu.okaeri.configs.annotation.Variable;
public class StorageConfig extends OkaeriConfig { public class StorageConfig extends OkaeriConfig {
@Comment("Storage provider.") @Comment("Storage provider.")
@Comment("Available providers: memory") @Comment("Available providers: h2, sqlite")
public String provider = "memory"; public String provider = "h2";
@Comment("Data storage settings.") @Comment("Data storage settings.")
@Comment("You don't need to worry about this if you're using local database.")
public StorageDataConfig data = new StorageDataConfig(); public StorageDataConfig data = new StorageDataConfig();
@Variable("table-prefix") @Variable("table-prefix")

View file

@ -0,0 +1,44 @@
package dev.xhyrom.lighteco.common.dependencies;
import lombok.Getter;
public enum Dependency {
H2_DRIVER(
"com.h2database",
"h2",
"2.1.214"
),
SQLITE_DRIVER(
"org.xerial",
"sqlite-jdbc",
"3.28.0"
);
@Getter
private final String fullPath;
private final String groupId;
private final String artifactId;
private final String version;
private static final String MAVEN_FORMAT = "%s/%s/%s/%s-%s.jar";
Dependency(String groupId, String artifactId, String version) {
this.fullPath = String.format(MAVEN_FORMAT,
groupId.replace('.', '/'),
artifactId,
version,
artifactId,
version
);
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
}
public String getFileName() {
String name = name().toLowerCase().replace('_', '-');
return String.format("%s-%s.jar", name, this.version);
}
}

View file

@ -0,0 +1,16 @@
package dev.xhyrom.lighteco.common.dependencies;
import dev.xhyrom.lighteco.common.storage.StorageType;
import java.util.Set;
public interface DependencyManager extends AutoCloseable {
void loadDependencies(Set<Dependency> dependencies);
void loadStorageDependencies(Set<StorageType> types);
ClassLoader obtainClassLoaderWith(Set<Dependency> dependencies);
@Override
void close() throws Exception;
}

View file

@ -0,0 +1,157 @@
package dev.xhyrom.lighteco.common.dependencies;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.MoreFiles;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.StorageType;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
public class DependencyManagerImpl implements DependencyManager {
private final EnumMap<Dependency, Path> loaded = new EnumMap<>(Dependency.class);
private final Map<ImmutableSet<Dependency>, IsolatedClassLoader> loaders = new HashMap<>();
private final DependencyRegistry registry;
private final Path cacheDirectory;
public DependencyManagerImpl(LightEcoPlugin plugin) {
this.registry = new DependencyRegistry();
this.cacheDirectory = setupCacheDirectory(plugin);
}
@Override
public void loadDependencies(Set<Dependency> dependencies) {
CountDownLatch latch = new CountDownLatch(dependencies.size());
for (Dependency dependency : dependencies) {
if (this.loaded.containsKey(dependency)) {
latch.countDown();
continue;
}
CompletableFuture.runAsync(() -> {
try {
loadDependency(dependency);
} catch (Exception e) {
new RuntimeException("Failed to load dependency " + dependency, e);
} finally {
latch.countDown();
}
});
}
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private void loadDependency(Dependency dependency) {
if (this.loaded.containsKey(dependency)) {
return;
}
try {
Path file = downloadDependency(dependency);
this.loaded.put(dependency, file);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Path downloadDependency(Dependency dependency) throws Exception {
Path file = this.cacheDirectory.resolve(dependency.getFileName());
if (Files.exists(file)) {
return file;
}
Files.createDirectories(file.getParent());
DependencyRepository.MAVEN_CENTRAL.download(dependency, file);
return file;
}
@Override
public void loadStorageDependencies(Set<StorageType> types) {
loadDependencies(this.registry.resolveStorageDependencies(types));
}
@Override
public ClassLoader obtainClassLoaderWith(Set<Dependency> dependencies) {
ImmutableSet<Dependency> set = ImmutableSet.copyOf(dependencies);
for (Dependency dependency : dependencies) {
if (!this.loaded.containsKey(dependency)) {
throw new IllegalStateException("Dependency " + dependency + " is not loaded");
}
}
synchronized (this.loaders) {
IsolatedClassLoader classLoader = this.loaders.get(set);
if (classLoader != null) {
return classLoader;
}
URL[] urls = set.stream()
.map(this.loaded::get)
.map(file -> {
try {
return file.toUri().toURL();
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.toArray(URL[]::new);
classLoader = new IsolatedClassLoader(urls);
this.loaders.put(set, classLoader);
return classLoader;
}
}
private static Path setupCacheDirectory(LightEcoPlugin plugin) {
Path cacheDirectory = plugin.getBootstrap().getDataDirectory().resolve("libraries");
try {
MoreFiles.createParentDirectories(cacheDirectory);
} catch (IOException e) {
throw new RuntimeException("Unable to create libraries (cache) directory", e);
}
return cacheDirectory;
}
@Override
public void close() {
IOException exception = null;
for (IsolatedClassLoader loader : this.loaders.values()) {
try {
loader.close();
} catch (Exception e) {
if (exception == null) {
exception = new IOException("Failed to close class loader", e);
} else {
exception.addSuppressed(e);
}
}
}
if (exception != null) {
throw new RuntimeException(exception);
}
}
}

View file

@ -0,0 +1,25 @@
package dev.xhyrom.lighteco.common.dependencies;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
import dev.xhyrom.lighteco.common.storage.StorageType;
import java.util.LinkedHashSet;
import java.util.Set;
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)
.build();
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
Set<Dependency> dependencies = new LinkedHashSet<>();
for (StorageType type : types) {
dependencies.addAll(STORAGE_DEPENDENCIES.get(type));
}
return dependencies;
}
}

View file

@ -0,0 +1,33 @@
package dev.xhyrom.lighteco.common.dependencies;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
public enum DependencyRepository {
MAVEN_CENTRAL("https://repo1.maven.org/maven2/");
private final String url;
DependencyRepository(String url) {
this.url = url;
}
private URLConnection openConnection(Dependency dependency) throws IOException {
URL dependencyUrl = new URL(this.url + dependency.getFullPath());
return dependencyUrl.openConnection();
}
private byte[] download(Dependency dependency) throws IOException {
URLConnection connection = this.openConnection(dependency);
connection.connect();
return connection.getInputStream().readAllBytes();
}
public void download(Dependency dependency, Path file) throws IOException {
Files.write(file, this.download(dependency));
}
}

View file

@ -0,0 +1,15 @@
package dev.xhyrom.lighteco.common.dependencies;
import java.net.URL;
import java.net.URLClassLoader;
public class IsolatedClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
public IsolatedClassLoader(URL[] urls) {
super(urls, ClassLoader.getSystemClassLoader().getParent());
}
}

View file

@ -0,0 +1,7 @@
// Lot of implementation is from LuckPerms
// https://github.com/LuckPerms/LuckPerms/tree/71416baff214802a52f7d26521e6575f71c97fe4/common/src/main/java/me/lucko/luckperms/common/dependencies
// Copyright (c) lucko (Luck) <lucko@lucko.me>
// Copyright (c) contributors
// Under MIT License
package dev.xhyrom.lighteco.common.dependencies;

View file

@ -4,6 +4,8 @@ import dev.xhyrom.lighteco.api.LightEco;
import dev.xhyrom.lighteco.api.LightEcoProvider; import dev.xhyrom.lighteco.api.LightEcoProvider;
import dev.xhyrom.lighteco.common.api.LightEcoApi; import dev.xhyrom.lighteco.common.api.LightEcoApi;
import dev.xhyrom.lighteco.common.config.Config; import dev.xhyrom.lighteco.common.config.Config;
import dev.xhyrom.lighteco.common.dependencies.DependencyManager;
import dev.xhyrom.lighteco.common.dependencies.DependencyManagerImpl;
import dev.xhyrom.lighteco.common.storage.Storage; import dev.xhyrom.lighteco.common.storage.Storage;
import dev.xhyrom.lighteco.common.storage.StorageFactory; import dev.xhyrom.lighteco.common.storage.StorageFactory;
import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.ConfigManager;
@ -14,18 +16,20 @@ import java.io.File;
public abstract class AbstractLightEcoPlugin implements LightEcoPlugin { public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
@Getter @Getter
private Storage storage; private DependencyManager dependencyManager;
private LightEcoApi api;
@Getter @Getter
private Config config; private Config config;
public final void load() { @Getter
this.config = ConfigManager.create(Config.class, (it) -> { private Storage storage;
File path = new File(this.getBootstrap().getDataFolder(), "config.yml"); private LightEcoApi api;
path.mkdir();
public final void load() {
this.dependencyManager = new DependencyManagerImpl(this);
this.config = ConfigManager.create(Config.class, (it) -> {
it.withConfigurer(new YamlSnakeYamlConfigurer()); it.withConfigurer(new YamlSnakeYamlConfigurer());
it.withBindFile(path); it.withBindFile(this.getBootstrap().getDataDirectory().resolve("config.yml"));
it.withRemoveOrphans(true); it.withRemoveOrphans(true);
it.saveDefaults(); it.saveDefaults();
it.load(true); it.load(true);
@ -35,6 +39,8 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
public final void enable() { public final void enable() {
// setup storage // setup storage
StorageFactory factory = new StorageFactory(this); StorageFactory factory = new StorageFactory(this);
this.dependencyManager.loadStorageDependencies(factory.getRequiredTypes());
this.storage = factory.get(); this.storage = factory.get();
// register listeners // register listeners

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.plugin;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.common.config.Config; import dev.xhyrom.lighteco.common.config.Config;
import dev.xhyrom.lighteco.common.dependencies.DependencyManager;
import dev.xhyrom.lighteco.common.manager.command.CommandManager; import dev.xhyrom.lighteco.common.manager.command.CommandManager;
import dev.xhyrom.lighteco.common.manager.currency.CurrencyManager; import dev.xhyrom.lighteco.common.manager.currency.CurrencyManager;
import dev.xhyrom.lighteco.common.manager.user.UserManager; import dev.xhyrom.lighteco.common.manager.user.UserManager;
@ -21,5 +22,7 @@ public interface LightEcoPlugin {
@NonNull CommandManager getCommandManager(); @NonNull CommandManager getCommandManager();
@NonNull ContextManager<?> getContextManager(); @NonNull ContextManager<?> getContextManager();
@NonNull DependencyManager getDependencyManager();
@NonNull Storage getStorage(); @NonNull Storage getStorage();
} }

View file

@ -2,7 +2,6 @@ package dev.xhyrom.lighteco.common.plugin.bootstrap;
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger; import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
@ -11,7 +10,7 @@ import java.util.UUID;
public interface LightEcoBootstrap { public interface LightEcoBootstrap {
Object getLoader(); Object getLoader();
PluginLogger getLogger(); PluginLogger getLogger();
File getDataFolder(); Path getDataDirectory();
List<UUID> getOnlinePlayers(); List<UUID> getOnlinePlayers();
InputStream getResourceStream(String filename); InputStream getResourceStream(String filename);
} }

View file

@ -1,11 +1,15 @@
package dev.xhyrom.lighteco.common.storage; package dev.xhyrom.lighteco.common.storage;
import com.google.common.collect.ImmutableSet;
import dev.xhyrom.lighteco.api.storage.StorageProvider; import dev.xhyrom.lighteco.api.storage.StorageProvider;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.provider.memory.MemoryStorageProvider; 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.SqliteConnectionFactory; import dev.xhyrom.lighteco.common.storage.provider.sql.connection.file.SqliteConnectionFactory;
import java.util.Set;
public class StorageFactory { public class StorageFactory {
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
@ -13,6 +17,10 @@ public class StorageFactory {
this.plugin = plugin; this.plugin = plugin;
} }
public Set<StorageType> getRequiredTypes() {
return ImmutableSet.of(StorageType.parse(this.plugin.getConfig().storage.provider));
}
public Storage get() { public Storage get() {
// todo: use config // todo: use config
String provider = this.plugin.getConfig().storage.provider; String provider = this.plugin.getConfig().storage.provider;
@ -27,10 +35,15 @@ public class StorageFactory {
switch (provider.toLowerCase()) { switch (provider.toLowerCase()) {
case "memory": case "memory":
return new MemoryStorageProvider(this.plugin); return new MemoryStorageProvider(this.plugin);
case "h2":
return new SqlStorageProvider(
this.plugin,
new H2ConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-h2").toAbsolutePath())
);
case "sqlite": case "sqlite":
return new SqlStorageProvider( return new SqlStorageProvider(
this.plugin, this.plugin,
new SqliteConnectionFactory(this.plugin.getBootstrap().getDataFolder().toPath().resolve("data.db")) new SqliteConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-sqlite.db"))
); );
default: default:
throw new IllegalArgumentException("Unknown storage provider: " + provider); throw new IllegalArgumentException("Unknown storage provider: " + provider);

View file

@ -0,0 +1,27 @@
package dev.xhyrom.lighteco.common.storage;
import java.util.List;
import java.util.stream.Stream;
public enum StorageType {
MARIADB("MariaDB", "mariadb"),
MYSQL("MySQL", "mysql"),
SQLITE("SQLite", "sqlite"),
H2("H2", "h2");
private final String name;
private final List<String> identifiers;
StorageType(String name, String... identifiers) {
this.name = name;
this.identifiers = List.of(identifiers);
}
public static StorageType parse(String name) {
return Stream.of(values())
.filter(type -> type.identifiers.contains(name.toLowerCase()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown storage type: " + name));
}
}

View file

@ -0,0 +1,7 @@
// Lot of implementation is from LuckPerms
// https://github.com/LuckPerms/LuckPerms/tree/71416baff214802a52f7d26521e6575f71c97fe4/common/src/main/java/me/lucko/luckperms/common/storage
// Copyright (c) lucko (Luck) <lucko@lucko.me>
// Copyright (c) contributors
// Under MIT License
package dev.xhyrom.lighteco.common.storage.provider;

View file

@ -1,7 +0,0 @@
package dev.xhyrom.lighteco.common.storage.provider.sql;
public enum SqlImplementation {
H2,
SQLITE,
MYSQL;
}

View file

@ -1,9 +1,11 @@
package dev.xhyrom.lighteco.common.storage.provider.sql; package dev.xhyrom.lighteco.common.storage.provider.sql;
import dev.xhyrom.lighteco.common.storage.StorageType;
public enum SqlStatements { public enum SqlStatements {
SAVE_USER_LOCAL_CURRENCY( SAVE_USER_LOCAL_CURRENCY(
"INSERT INTO {prefix}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON CONFLICT (uuid, currency_identifier) DO UPDATE SET balance=?3;", "INSERT INTO {prefix}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON CONFLICT (uuid, currency_identifier) DO UPDATE SET balance=?3;",
"INSERT INTO {prefix}_{context}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON DUPLICATE KEY UPDATE balance=?3;" "INSERT INTO {prefix}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON DUPLICATE KEY UPDATE balance=?3;"
), ),
SAVE_USER_GLOBAL_CURRENCY( SAVE_USER_GLOBAL_CURRENCY(
"INSERT INTO {prefix}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON CONFLICT (uuid, currency_identifier) DO UPDATE SET balance=?3;", "INSERT INTO {prefix}_users (uuid, currency_identifier, balance) VALUES (?1, ?2, ?3) ON CONFLICT (uuid, currency_identifier) DO UPDATE SET balance=?3;",
@ -18,12 +20,12 @@ public enum SqlStatements {
this.mysql = mysql; this.mysql = mysql;
} }
public String get(SqlImplementation implementationName) { public String get(StorageType implementationName) {
switch (implementationName) { switch (implementationName) {
case SQLITE -> { case SQLITE -> {
return this.sqlite; return this.sqlite;
} }
case MYSQL -> { case H2, MYSQL -> {
return this.mysql; return this.mysql;
} }
} }

View file

@ -4,6 +4,7 @@ import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.api.storage.StorageProvider; import dev.xhyrom.lighteco.api.storage.StorageProvider;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
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 org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -46,7 +47,7 @@ public class SqlStorageProvider implements StorageProvider {
.replace("{context}", plugin.getConfig().server) .replace("{context}", plugin.getConfig().server)
); );
final SqlImplementation implementationName = this.connectionFactory.getImplementationName(); final StorageType implementationName = this.connectionFactory.getImplementationName();
this.SAVE_USER_LOCAL_CURRENCY = SqlStatements.SAVE_USER_LOCAL_CURRENCY.get(implementationName); this.SAVE_USER_LOCAL_CURRENCY = SqlStatements.SAVE_USER_LOCAL_CURRENCY.get(implementationName);
this.SAVE_USER_GLOBAL_CURRENCY = SqlStatements.SAVE_USER_GLOBAL_CURRENCY.get(implementationName); this.SAVE_USER_GLOBAL_CURRENCY = SqlStatements.SAVE_USER_GLOBAL_CURRENCY.get(implementationName);
} }

View file

@ -1,13 +1,13 @@
package dev.xhyrom.lighteco.common.storage.provider.sql.connection; package dev.xhyrom.lighteco.common.storage.provider.sql.connection;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.provider.sql.SqlImplementation; import dev.xhyrom.lighteco.common.storage.StorageType;
import java.sql.Connection; import java.sql.Connection;
import java.util.function.Function; import java.util.function.Function;
public interface ConnectionFactory { public interface ConnectionFactory {
SqlImplementation getImplementationName(); StorageType getImplementationName();
void init(LightEcoPlugin plugin); void init(LightEcoPlugin plugin);
void shutdown() throws Exception; void shutdown() throws Exception;

View file

@ -1,13 +1,14 @@
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.file; package dev.xhyrom.lighteco.common.storage.provider.sql.connection.file;
import dev.xhyrom.lighteco.common.dependencies.Dependency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.provider.sql.SqlImplementation; import dev.xhyrom.lighteco.common.storage.StorageType;
import java.io.File;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.nio.file.Path; import java.nio.file.Path;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.EnumSet;
import java.util.Properties; import java.util.Properties;
import java.util.function.Function; import java.util.function.Function;
@ -19,21 +20,27 @@ public class H2ConnectionFactory extends FileConnectionFactory {
} }
@Override @Override
public SqlImplementation getImplementationName() { public StorageType getImplementationName() {
return SqlImplementation.H2; return StorageType.H2;
} }
@Override @Override
public void init(LightEcoPlugin plugin) { public void init(LightEcoPlugin plugin) {
// TODO: implement ClassLoader classLoader = plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.H2_DRIVER));
//ClassLoader classLoader = plugin
try {
Class<?> connectionClass = classLoader.loadClass("org.h2.jdbc.JdbcConnection");
this.connectionConstructor = connectionClass.getConstructor(String.class, Properties.class, String.class, Object.class, boolean.class);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
} }
@Override @Override
protected Connection createConnection(Path file) throws SQLException { protected Connection createConnection(Path file) throws SQLException {
try { try {
return (Connection) this.connectionConstructor.newInstance( return (Connection) this.connectionConstructor.newInstance(
"jdbc:h2:" + file, "jdbc:h2:" + file.toString() + ";MODE=MySQL;DATABASE_TO_LOWER=TRUE",
new Properties(), new Properties(),
null, null, false null, null, false
); );
@ -45,4 +52,13 @@ public class H2ConnectionFactory extends FileConnectionFactory {
throw new SQLException("Failed to create connection", e); throw new SQLException("Failed to create connection", e);
} }
} }
@Override
public Function<String, String> getStatementProcessor() {
return s -> s
.replace('\'', '`')
.replace("LIKE", "ILIKE")
.replace("value", "`value`")
.replace("``value``", "`value`");
}
} }

View file

@ -1,13 +1,16 @@
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.file; package dev.xhyrom.lighteco.common.storage.provider.sql.connection.file;
import dev.xhyrom.lighteco.common.dependencies.Dependency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.provider.sql.SqlImplementation; import dev.xhyrom.lighteco.common.storage.StorageType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.nio.file.Path; import java.nio.file.Path;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.EnumSet;
import java.util.Properties;
public class SqliteConnectionFactory extends FileConnectionFactory { public class SqliteConnectionFactory extends FileConnectionFactory {
private Constructor<?> connectionConstructor; private Constructor<?> connectionConstructor;
@ -17,31 +20,30 @@ public class SqliteConnectionFactory extends FileConnectionFactory {
} }
@Override @Override
public SqlImplementation getImplementationName() { public StorageType getImplementationName() {
return SqlImplementation.SQLITE; return StorageType.SQLITE;
} }
@Override @Override
public void init(LightEcoPlugin plugin) { public void init(LightEcoPlugin plugin) {
/*ClassLoader classLoader = ClassLoader.getSystemClassLoader(); ClassLoader classLoader = plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.SQLITE_DRIVER));
try { try {
Class<?> connectionClass = classLoader.loadClass("org.sqlite.jdbc4.JDBC4Connection"); Class<?> connectionClass = classLoader.loadClass("org.sqlite.jdbc4.JDBC4Connection");
this.connectionConstructor = connectionClass.getConstructor(String.class, String.class, Properties.class); this.connectionConstructor = connectionClass.getConstructor(String.class, String.class, Properties.class);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
}*/ }
} }
@Override @Override
protected Connection createConnection(Path file) throws SQLException { protected Connection createConnection(Path file) throws SQLException {
try { try {
/*return (Connection) this.connectionConstructor.newInstance( return (Connection) this.connectionConstructor.newInstance(
"jdbc:sqlite:" + file, "jdbc:sqlite:" + file,
new Properties(), file.toString(),
null, null, false new Properties()
);*/ );
return DriverManager.getConnection("jdbc:sqlite:" + file);
} catch (Exception e) { } catch (Exception e) {
if (e.getCause() instanceof SQLException) { if (e.getCause() instanceof SQLException) {
throw (SQLException) e.getCause(); throw (SQLException) e.getCause();

View file

@ -0,0 +1,36 @@
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
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.util.function.Function;
public class HikariConnectionFactory implements ConnectionFactory {
@Override
public StorageType getImplementationName() {
return null;
}
@Override
public void init(LightEcoPlugin plugin) {
}
@Override
public void shutdown() throws Exception {
}
@Override
public Function<String, String> getStatementProcessor() {
return null;
}
@Override
public Connection getConnection() throws Exception {
return null;
}
}

View 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`)
);