mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-28 20:17:55 +01:00
Upgrade h2 database engine to v2 (#3458)
This commit is contained in:
parent
495d951556
commit
e35f46798b
@ -160,7 +160,7 @@ public enum Dependency {
|
||||
"IydH+gkk2Iom36QrgSi2+hFAgC2AQSWJFZboyl8pEyI=",
|
||||
Relocation.of("postgresql", "org{}postgresql")
|
||||
),
|
||||
H2_DRIVER(
|
||||
H2_DRIVER_LEGACY(
|
||||
"com.h2database",
|
||||
"h2",
|
||||
// seems to be a compat bug in 1.4.200 with older dbs
|
||||
@ -170,6 +170,14 @@ public enum Dependency {
|
||||
// we don't apply relocations to h2 - it gets loaded via
|
||||
// an isolated classloader
|
||||
),
|
||||
H2_DRIVER(
|
||||
"com.h2database",
|
||||
"h2",
|
||||
"2.1.214",
|
||||
"1iPNwPYdIYz1SajQnxw5H/kQlhFrIuJHVHX85PvnK9A="
|
||||
// we don't apply relocations to h2 - it gets loaded via
|
||||
// an isolated classloader
|
||||
),
|
||||
SQLITE_DRIVER(
|
||||
"org.xerial",
|
||||
"sqlite-jdbc",
|
||||
|
@ -128,6 +128,7 @@ public class DependencyRegistry {
|
||||
case ASM_COMMONS:
|
||||
case JAR_RELOCATOR:
|
||||
case H2_DRIVER:
|
||||
case H2_DRIVER_LEGACY:
|
||||
case SQLITE_DRIVER:
|
||||
return false;
|
||||
default:
|
||||
|
@ -114,7 +114,7 @@ public class StorageFactory {
|
||||
case H2:
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new H2ConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("luckperms-h2")),
|
||||
new H2ConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("luckperms-h2-v2")),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case POSTGRESQL:
|
||||
|
@ -30,9 +30,12 @@ import me.lucko.luckperms.common.dependencies.classloader.IsolatedClassLoader;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
@ -56,16 +59,22 @@ public class H2ConnectionFactory extends FlatfileConnectionFactory {
|
||||
IsolatedClassLoader classLoader = plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.H2_DRIVER));
|
||||
try {
|
||||
Class<?> connectionClass = classLoader.loadClass("org.h2.jdbc.JdbcConnection");
|
||||
this.connectionConstructor = connectionClass.getConstructor(String.class, Properties.class);
|
||||
this.connectionConstructor = connectionClass.getConstructor(String.class, Properties.class, String.class, Object.class, boolean.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
new MigrateH2ToVersion2(plugin, super.getWriteFile().getParent()).run(this);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warn("Something went wrong whilst upgrading the LuckPerms database. Please report this on GitHub.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Connection createConnection(Path file) throws SQLException {
|
||||
try {
|
||||
return (Connection) this.connectionConstructor.newInstance("jdbc:h2:" + file.toString(), new Properties());
|
||||
return (Connection) this.connectionConstructor.newInstance("jdbc:h2:" + file.toString(), new Properties(), null, null, false);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (e.getCause() instanceof SQLException) {
|
||||
throw (SQLException) e.getCause();
|
||||
@ -83,6 +92,79 @@ public class H2ConnectionFactory extends FlatfileConnectionFactory {
|
||||
|
||||
@Override
|
||||
public Function<String, String> getStatementProcessor() {
|
||||
return s -> s.replace('\'', '`').replace("LIKE", "ILIKE");
|
||||
return s -> s.replace('\'', '`')
|
||||
.replace("LIKE", "ILIKE")
|
||||
.replace("value", "`value`")
|
||||
.replace("``value``", "`value`");
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates the old (version 1) H2 database to version 2.
|
||||
*
|
||||
* See <a href="http://www.h2database.com/html/migration-to-v2.html">here</a> for more info.
|
||||
*/
|
||||
private static final class MigrateH2ToVersion2 {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Path directory;
|
||||
|
||||
MigrateH2ToVersion2(LuckPermsPlugin plugin, Path directory) {
|
||||
this.plugin = plugin;
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
public void run(H2ConnectionFactory newFactory) throws Exception {
|
||||
Path oldDatabase = this.directory.resolve("luckperms-h2");
|
||||
Path oldDatabaseWriteFile = this.directory.resolve("luckperms-h2.mv.db");
|
||||
|
||||
if (!Files.exists(oldDatabaseWriteFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path tempMigrationFile = this.directory.resolve("luckperms-h2-migration.sql");
|
||||
|
||||
this.plugin.getLogger().warn("[DB Upgrade] Found an old (v1) H2 database file. LuckPerms will now attempt to upgrade it to v2 (this is a one time operation).");
|
||||
|
||||
this.plugin.getLogger().info("[DB Upgrade] Stage 1: Exporting the old database to an intermediary file...");
|
||||
Constructor<?> constructor = getConnectionConstructor();
|
||||
try (Connection c = getConnection(constructor, oldDatabase)) {
|
||||
try (Statement stmt = c.createStatement()) {
|
||||
stmt.execute(String.format("SCRIPT TO '%s'", tempMigrationFile));
|
||||
}
|
||||
}
|
||||
|
||||
this.plugin.getLogger().info("[DB Upgrade] Stage 2: Importing the intermediary file into the new database...");
|
||||
try (Connection c = newFactory.getConnection()) {
|
||||
try (Statement stmt = c.createStatement()) {
|
||||
stmt.execute(String.format("RUNSCRIPT FROM '%s'", tempMigrationFile));
|
||||
}
|
||||
}
|
||||
|
||||
this.plugin.getLogger().info("[DB Upgrade] Stage 3: Tidying up...");
|
||||
Files.deleteIfExists(tempMigrationFile);
|
||||
Files.move(oldDatabaseWriteFile, this.directory.resolve("luckperms-h2-v1-backup.mv.db"));
|
||||
|
||||
this.plugin.getLogger().info("[DB Upgrade] All done!");
|
||||
}
|
||||
|
||||
private Constructor<?> getConnectionConstructor() {
|
||||
this.plugin.getDependencyManager().loadDependencies(Collections.singleton(Dependency.H2_DRIVER_LEGACY));
|
||||
IsolatedClassLoader classLoader = this.plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.H2_DRIVER_LEGACY));
|
||||
try {
|
||||
Class<?> connectionClass = classLoader.loadClass("org.h2.jdbc.JdbcConnection");
|
||||
return connectionClass.getConstructor(String.class, Properties.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection(Constructor<?> constructor, Path file) {
|
||||
try {
|
||||
return (Connection) constructor.newInstance("jdbc:h2:" + file.toString(), new Properties());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user