From 71403e93af96ab9c86826a4cd01fd24c9e21d410 Mon Sep 17 00:00:00 2001 From: Kavin <20838718+FireMasterK@users.noreply.github.com> Date: Sun, 13 Aug 2023 23:20:30 +0100 Subject: [PATCH] Add liquibase to perform database migrations --- build.gradle | 1 + src/main/java/me/kavin/piped/Main.java | 8 ++- .../me/kavin/piped/utils/LiquibaseHelper.java | 51 +++++++++++++++++++ .../changelog/db.changelog-master.xml | 9 ++++ .../changelog/version/0-1-init-crdb.sql | 3 ++ .../changelog/version/0-1-init-pg.sql | 3 ++ .../resources/changelog/version/0-1-init.sql | 11 ++++ .../resources/changelog/version/0-init.xml | 13 +++++ src/main/resources/hibernate.cfg.xml | 4 +- 9 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/kavin/piped/utils/LiquibaseHelper.java create mode 100644 src/main/resources/changelog/db.changelog-master.xml create mode 100644 src/main/resources/changelog/version/0-1-init-crdb.sql create mode 100644 src/main/resources/changelog/version/0-1-init-pg.sql create mode 100644 src/main/resources/changelog/version/0-1-init.sql create mode 100644 src/main/resources/changelog/version/0-init.xml diff --git a/build.gradle b/build.gradle index cb9a478..332d724 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,7 @@ dependencies { implementation 'org.postgresql:postgresql:42.6.0' implementation 'org.hibernate:hibernate-core:6.2.7.Final' implementation 'org.hibernate:hibernate-hikaricp:6.2.7.Final' + implementation 'org.liquibase:liquibase-core:4.23.1' implementation 'com.zaxxer:HikariCP:5.0.1' implementation 'org.springframework.security:spring-security-crypto:6.1.2' implementation 'commons-logging:commons-logging:1.2' diff --git a/src/main/java/me/kavin/piped/Main.java b/src/main/java/me/kavin/piped/Main.java index 067f229..15e982c 100644 --- a/src/main/java/me/kavin/piped/Main.java +++ b/src/main/java/me/kavin/piped/Main.java @@ -20,7 +20,6 @@ import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.services.youtube.YoutubeThrottlingDecrypter; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; -import rocks.kavin.reqwest4j.ReqwestUtils; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -70,6 +69,13 @@ public class Main { } }).start(); + try { + LiquibaseHelper.init(); + } catch (Exception e) { + ExceptionHandler.handle(e); + System.exit(1); + } + try (Session ignored = DatabaseSessionFactory.createSession()) { System.out.println("Database connection is ready!"); } catch (Throwable t) { diff --git a/src/main/java/me/kavin/piped/utils/LiquibaseHelper.java b/src/main/java/me/kavin/piped/utils/LiquibaseHelper.java new file mode 100644 index 0000000..e585799 --- /dev/null +++ b/src/main/java/me/kavin/piped/utils/LiquibaseHelper.java @@ -0,0 +1,51 @@ +package me.kavin.piped.utils; + +import liquibase.Contexts; +import liquibase.Liquibase; +import liquibase.Scope; +import liquibase.command.CommandScope; +import liquibase.command.core.UpdateCommandStep; +import liquibase.command.core.helpers.ChangeExecListenerCommandStep; +import liquibase.command.core.helpers.DatabaseChangelogCommandStep; +import liquibase.command.core.helpers.DbUrlConnectionCommandStep; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.LiquibaseException; +import liquibase.resource.ClassLoaderResourceAccessor; +import me.kavin.piped.consts.Constants; + +import java.io.FileWriter; +import java.io.IOException; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +public class LiquibaseHelper { + + public static void init() throws Exception { + + String url = Constants.hibernateProperties.get("hibernate.connection.url"); + String username = Constants.hibernateProperties.get("hibernate.connection.username"); + String password = Constants.hibernateProperties.get("hibernate.connection.password"); + + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(DriverManager.getConnection(url, username, password))); + + try (Liquibase liquibase = new Liquibase("changelog/db.changelog-master.xml", new ClassLoaderResourceAccessor(), database)) { + + Map scopeObjects = new HashMap<>(); + scopeObjects.put(Scope.Attr.database.name(), liquibase.getDatabase()); + scopeObjects.put(Scope.Attr.resourceAccessor.name(), liquibase.getResourceAccessor()); + + Scope.child(scopeObjects, () -> { + CommandScope updateCommand = new CommandScope(UpdateCommandStep.COMMAND_NAME); + updateCommand.addArgumentValue(DbUrlConnectionCommandStep.DATABASE_ARG, liquibase.getDatabase()); + updateCommand.addArgumentValue(UpdateCommandStep.CHANGELOG_FILE_ARG, liquibase.getChangeLogFile()); + updateCommand.execute(); + }); + + } + } + +} diff --git a/src/main/resources/changelog/db.changelog-master.xml b/src/main/resources/changelog/db.changelog-master.xml new file mode 100644 index 0000000..4478527 --- /dev/null +++ b/src/main/resources/changelog/db.changelog-master.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/main/resources/changelog/version/0-1-init-crdb.sql b/src/main/resources/changelog/version/0-1-init-crdb.sql new file mode 100644 index 0000000..ec15eae --- /dev/null +++ b/src/main/resources/changelog/version/0-1-init-crdb.sql @@ -0,0 +1,3 @@ +CREATE INDEX IF NOT EXISTS users_session_id_idx ON users (session_id ASC) STORING (password, username); + +--rollback DROP INDEX IF EXISTS users_session_id_idx; diff --git a/src/main/resources/changelog/version/0-1-init-pg.sql b/src/main/resources/changelog/version/0-1-init-pg.sql new file mode 100644 index 0000000..610e4c2 --- /dev/null +++ b/src/main/resources/changelog/version/0-1-init-pg.sql @@ -0,0 +1,3 @@ +CREATE INDEX IF NOT EXISTS users_session_id_idx ON users (session_id ASC); + +--rollback DROP INDEX IF EXISTS users_session_id_idx; diff --git a/src/main/resources/changelog/version/0-1-init.sql b/src/main/resources/changelog/version/0-1-init.sql new file mode 100644 index 0000000..d01cfee --- /dev/null +++ b/src/main/resources/changelog/version/0-1-init.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS users ( + id SERIAL NOT NULL, + password STRING NULL, + session_id STRING(36) NULL, + username STRING(24) NULL UNIQUE, + CONSTRAINT users_pkey PRIMARY KEY (id ASC), + INDEX users_id_idx (id ASC), + INDEX username_idx (username ASC) +); + +--rollback DROP TABLE IF EXISTS users; diff --git a/src/main/resources/changelog/version/0-init.xml b/src/main/resources/changelog/version/0-init.xml new file mode 100644 index 0000000..fc0fe76 --- /dev/null +++ b/src/main/resources/changelog/version/0-init.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index a0953d0..6374737 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -4,11 +4,11 @@ "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - update + validate false true - + org.hibernate.hikaricp.internal.HikariCPConnectionProvider DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT 50