From 961cec5bc8ee7f8d2a295928b3b070708460bf64 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Thu, 14 Jan 2021 13:59:37 +0000 Subject: [PATCH] Implement swap/restore in SqliteDBStore --- .../bridge/db/sqlite/SqliteDBStore.java | 34 ++++++++++++--- .../db/sqlite/query/GetSwapCompression.java | 39 +++++++++++++++++ .../sqlite/query/RestoreTimeColumnExists.java | 26 ++++++++++++ .../query/SwapCompressionColumnExists.java | 27 ++++++++++++ .../db/sqlite/query/SwapTimeColumnExists.java | 27 ++++++++++++ .../update/alter/ProjectsAddRestoreTime.java | 14 +++++++ .../alter/ProjectsAddSwapCompression.java | 14 +++++++ .../update/alter/ProjectsAddSwapTime.java | 15 +++++++ .../create/CreateProjectsTableSQLUpdate.java | 3 ++ .../sqlite/update/insert/UpdateRestore.java | 40 ++++++++++++++++++ .../db/sqlite/update/insert/UpdateSwap.java | 42 +++++++++++++++++++ 11 files changed, 275 insertions(+), 6 deletions(-) create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/GetSwapCompression.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/RestoreTimeColumnExists.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapCompressionColumnExists.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapTimeColumnExists.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddRestoreTime.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapCompression.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapTime.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateRestore.java create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateSwap.java diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStore.java index 20bf412624..725347bc0d 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStore.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStore.java @@ -104,6 +104,21 @@ public class SqliteDBStore implements DBStore { update(new SetProjectLastAccessedTime(projectName, lastAccessed)); } + @Override + public void swap(String projectName, String compressionMethod) { + update(new UpdateSwap(projectName, compressionMethod)); + } + + @Override + public void restore(String projectName) { + update(new UpdateRestore(projectName)); + } + + @Override + public String getSwapCompression(String projectName) { + return query(new GetSwapCompression(projectName)); + } + private Connection openConnectionTo(File dbFile) { File parentDir = dbFile.getParentFile(); if (!parentDir.exists() && !parentDir.mkdirs()) { @@ -127,20 +142,27 @@ public class SqliteDBStore implements DBStore { } private void createTables() { - try { - doUpdate(new ProjectsAddLastAccessed()); - } catch (SQLException ignore) { - /* We need to eat exceptions from here */ - } + /* Migrations */ + /* We need to eat exceptions from here */ + try { doUpdate(new ProjectsAddLastAccessed()); } catch (SQLException ignore) {} + try { doUpdate(new ProjectsAddSwapTime()); } catch (SQLException ignore) {} + try { doUpdate(new ProjectsAddRestoreTime()); } catch (SQLException ignore) {} + try { doUpdate(new ProjectsAddSwapCompression()); } catch (SQLException ignore) {} + + /* Create tables (if they don't exist) */ Stream.of( new CreateProjectsTableSQLUpdate(), new CreateProjectsIndexLastAccessed(), new CreateURLIndexStoreSQLUpdate(), new CreateIndexURLIndexStore() ).forEach(this::update); + /* In the case of needing to change the schema, we need to check that - ProjectsAddLastAccessed didn't just fail */ + migrations didn't just fail */ Preconditions.checkState(query(new LastAccessedColumnExists())); + Preconditions.checkState(query(new SwapTimeColumnExists())); + Preconditions.checkState(query(new RestoreTimeColumnExists())); + Preconditions.checkState(query(new SwapCompressionColumnExists())); } private void update(SQLUpdate update) { diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/GetSwapCompression.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/GetSwapCompression.java new file mode 100644 index 0000000000..c7f4d5b510 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/GetSwapCompression.java @@ -0,0 +1,39 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.query; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLQuery; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GetSwapCompression implements SQLQuery { + private static final String GET_SWAP_COMPRESSION = + "SELECT `swap_compression` FROM `projects` WHERE `name` = ?"; + + private final String projectName; + + public GetSwapCompression(String projectName) { + this.projectName = projectName; + } + + @Override + public String processResultSet(ResultSet resultSet) throws SQLException { + String compression = null; + while (resultSet.next()) { + compression = resultSet.getString("swap_compression"); + } + return compression; + } + + @Override + public String getSQL() { + return GET_SWAP_COMPRESSION; + } + + @Override + public void addParametersToStatement( + PreparedStatement statement + ) throws SQLException { + statement.setString(1, projectName); + } +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/RestoreTimeColumnExists.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/RestoreTimeColumnExists.java new file mode 100644 index 0000000000..ed4d0567ae --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/RestoreTimeColumnExists.java @@ -0,0 +1,26 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.query; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLQuery; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RestoreTimeColumnExists implements SQLQuery { + private static final String RESTORE_TIME_COLUMN_EXISTS = + "PRAGMA table_info(`projects`)"; + + @Override + public String getSQL() { + return RESTORE_TIME_COLUMN_EXISTS; + } + + @Override + public Boolean processResultSet(ResultSet resultSet) throws SQLException { + while (resultSet.next()) { + if (resultSet.getString(2).equals("restore_time")) { + return true; + } + } + return false; + } +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapCompressionColumnExists.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapCompressionColumnExists.java new file mode 100644 index 0000000000..1b1754f26e --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapCompressionColumnExists.java @@ -0,0 +1,27 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.query; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLQuery; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SwapCompressionColumnExists implements SQLQuery { + private static final String SWAP_COMPRESSION_COLUMN_EXISTS = + "PRAGMA table_info(`projects`)"; + + @Override + public String getSQL() { + return SWAP_COMPRESSION_COLUMN_EXISTS; + } + + @Override + public Boolean processResultSet(ResultSet resultSet) throws SQLException { + while (resultSet.next()) { + if (resultSet.getString(2).equals("swap_compression")) { + return true; + } + } + return false; + } + +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapTimeColumnExists.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapTimeColumnExists.java new file mode 100644 index 0000000000..9426dedc5f --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/query/SwapTimeColumnExists.java @@ -0,0 +1,27 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.query; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLQuery; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SwapTimeColumnExists implements SQLQuery { + private static final String SWAP_TIME_COLUMN_EXISTS = + "PRAGMA table_info(`projects`)"; + + @Override + public String getSQL() { + return SWAP_TIME_COLUMN_EXISTS; + } + + @Override + public Boolean processResultSet(ResultSet resultSet) throws SQLException { + while (resultSet.next()) { + if (resultSet.getString(2).equals("swap_time")) { + return true; + } + } + return false; + } + +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddRestoreTime.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddRestoreTime.java new file mode 100644 index 0000000000..dd92efcab5 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddRestoreTime.java @@ -0,0 +1,14 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.alter; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLUpdate; + +public class ProjectsAddRestoreTime implements SQLUpdate { + private static final String PROJECTS_ADD_RESTORE_TIME = + "ALTER TABLE `projects`\n" + + "ADD COLUMN `restore_time` DATETIME NULL;\n"; + + @Override + public String getSQL() { + return PROJECTS_ADD_RESTORE_TIME; + } +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapCompression.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapCompression.java new file mode 100644 index 0000000000..c5599d9116 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapCompression.java @@ -0,0 +1,14 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.alter; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLUpdate; + +public class ProjectsAddSwapCompression implements SQLUpdate { + private static final String PROJECTS_ADD_SWAP_COMPRESSION = + "ALTER TABLE `projects`\n" + + "ADD COLUMN `swap_compression` VARCHAR NULL;\n"; + + @Override + public String getSQL() { + return PROJECTS_ADD_SWAP_COMPRESSION; + } +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapTime.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapTime.java new file mode 100644 index 0000000000..da89be8c25 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/alter/ProjectsAddSwapTime.java @@ -0,0 +1,15 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.alter; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLUpdate; + +public class ProjectsAddSwapTime implements SQLUpdate { + private static final String PROJECTS_ADD_SWAP_TIME = + "ALTER TABLE `projects`\n" + + "ADD COLUMN `swap_time` DATETIME NULL;\n"; + + @Override + public String getSQL() { + return PROJECTS_ADD_SWAP_TIME; + } + +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/create/CreateProjectsTableSQLUpdate.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/create/CreateProjectsTableSQLUpdate.java index c5f8d3f6e7..15042445ad 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/create/CreateProjectsTableSQLUpdate.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/create/CreateProjectsTableSQLUpdate.java @@ -12,6 +12,9 @@ public class CreateProjectsTableSQLUpdate implements SQLUpdate { " `name` VARCHAR NOT NULL DEFAULT '',\n" + " `version_id` INT NOT NULL DEFAULT 0,\n" + " `last_accessed` DATETIME NULL DEFAULT 0,\n" + + " `swap_time` DATETIME NULL,\n" + + " `restore_time` DATETIME NULL,\n" + + " `swap_compression` VARCHAR NULL,\n" + " PRIMARY KEY (`name`)\n" + ")"; diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateRestore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateRestore.java new file mode 100644 index 0000000000..91abc5f473 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateRestore.java @@ -0,0 +1,40 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLUpdate; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; + +public class UpdateRestore implements SQLUpdate { + private static final String UPDATE_RESTORE = + "UPDATE `projects`\n" + + "SET `last_accessed` = ?,\n" + + " `swap_time` = NULL,\n" + + " `restore_time` = ?,\n" + + " `swap_compression` = NULL\n" + + "WHERE `name` = ?;\n"; + + private final String projectName; + private final Timestamp now; + + public UpdateRestore(String projectName) { + this.projectName = projectName; + this.now = Timestamp.valueOf(LocalDateTime.now()); + } + + @Override + public String getSQL() { + return UPDATE_RESTORE; + } + + @Override + public void addParametersToStatement( + PreparedStatement statement + ) throws SQLException { + statement.setTimestamp(1, now); + statement.setTimestamp(2, now); + statement.setString(3, projectName); + } +} diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateSwap.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateSwap.java new file mode 100644 index 0000000000..24d7815279 --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/UpdateSwap.java @@ -0,0 +1,42 @@ +package uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert; + +import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLUpdate; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; + +public class UpdateSwap implements SQLUpdate { + private static final String UPDATE_SWAP = + "UPDATE `projects`\n" + + "SET `last_accessed` = NULL,\n" + + " `swap_time` = ?,\n" + + " `restore_time` = NULL,\n" + + " `swap_compression` = ?\n" + + "WHERE `name` = ?;\n"; + + private final String projectName; + private final String compression; + private final Timestamp now; + + public UpdateSwap(String projectName, String compression) { + this.projectName = projectName; + this.compression = compression; + this.now = Timestamp.valueOf(LocalDateTime.now()); + } + + @Override + public String getSQL() { + return UPDATE_SWAP; + } + + @Override + public void addParametersToStatement( + PreparedStatement statement + ) throws SQLException { + statement.setTimestamp(1, now); + statement.setString(2, compression); + statement.setString(3, projectName); + } +}