Bläddra i källkod

Add and test an SQL update for only setting a project's last_accessed if it's missing

Winston Li 10 år sedan
förälder
incheckning
f036ff2c8b

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/DBStore.java

@@ -29,4 +29,21 @@ public interface DBStore {
      */
     void setLastAccessedTime(String projectName, Timestamp time);
 
+    /**
+     * Sets the last accessed time for the given project name,
+     * ONLY if it is not already in the database.
+     *
+     * This is useful if the server crashed while uploading to S3, because
+     * the files will still be on disk.
+     *
+     * It's also useful for the initial upgrade, where none of the projects
+     * are in the DB.
+     * @param projectName
+     * @param lastAccessed
+     */
+    void setProjectLastAccessedTimeIfMissing(
+            String projectName,
+            Timestamp lastAccessed
+    );
+
 }

+ 14 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStore.java

@@ -9,6 +9,7 @@ import uk.ac.ic.wlgitbridge.bridge.db.sqlite.query.GetProjectNamesSQLQuery;
 import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.create.*;
 import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.delete.DeleteFilesForProjectSQLUpdate;
 import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert.AddURLIndexSQLUpdate;
+import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert.SetProjectLastAccessedTimeIfMissing;
 import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert.SetProjectSQLUpdate;
 import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.insert.SetProjectLastAccessedTime;
 
@@ -91,6 +92,19 @@ public class SqliteDBStore implements DBStore {
         update(new SetProjectLastAccessedTime(projectName, lastAccessed));
     }
 
+    @Override
+    public void setProjectLastAccessedTimeIfMissing(
+            String projectName,
+            Timestamp lastAccessed
+    ) {
+        update(
+                new SetProjectLastAccessedTimeIfMissing(
+                        projectName,
+                        lastAccessed
+                )
+        );
+    }
+
     private Connection openConnectionTo(File dbFile) {
         File parentDir = dbFile.getParentFile();
         if (!parentDir.exists() && !parentDir.mkdirs()) {

+ 47 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/update/insert/SetProjectLastAccessedTimeIfMissing.java

@@ -0,0 +1,47 @@
+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;
+
+/**
+ * Created by winston on 23/08/2016.
+ */
+public class SetProjectLastAccessedTimeIfMissing implements SQLUpdate {
+
+    private static final String SET_IF_MISSING_PROJECT_LAST_ACCESSED_TIME =
+            "INSERT OR IGNORE INTO `swap_table`(\n" +
+            "        `project_name`,\n" +
+            "        `last_accessed`\n" +
+            ") VALUES (\n" +
+            "        ?,\n" +
+            "        ?\n" +
+            ")";
+
+    private final String projectName;
+    private final Timestamp lastAccessed;
+
+    public SetProjectLastAccessedTimeIfMissing(
+            String projectName,
+            Timestamp lastAccessed
+    ) {
+        this.projectName = projectName;
+        this.lastAccessed = lastAccessed;
+    }
+
+    @Override
+    public String getSQL() {
+        return SET_IF_MISSING_PROJECT_LAST_ACCESSED_TIME;
+    }
+
+    @Override
+    public void addParametersToStatement(
+            PreparedStatement statement
+    ) throws SQLException {
+        statement.setString(1, projectName);
+        statement.setTimestamp(2, lastAccessed);
+    }
+
+}

+ 36 - 0
services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/bridge/db/sqlite/SqliteDBStoreTest.java

@@ -85,4 +85,40 @@ public class SqliteDBStoreTest {
         assertEquals("newer", dbStore.getOldestUnswappedProject());
     }
 
+    @Test
+    public void missingProjectLastAccessedTimeCanBeSet() {
+        dbStore.setLatestVersionForProject("asdf", 1);
+        dbStore.setLastAccessedTime(
+                "asdf",
+                Timestamp.valueOf(LocalDateTime.now())
+        );
+        assertEquals("asdf", dbStore.getOldestUnswappedProject());
+    }
+
+    @Test
+    public void ifMissingDoesNotSetIfProjectIsNotMissing() {
+        dbStore.setLatestVersionForProject("older", 1);
+        dbStore.setProjectLastAccessedTimeIfMissing(
+                "older",
+                Timestamp.valueOf(
+                        LocalDateTime.now().minus(2, ChronoUnit.SECONDS)
+                )
+        );
+        dbStore.setLatestVersionForProject("asdf", 2);
+        dbStore.setProjectLastAccessedTimeIfMissing(
+                "asdf",
+                Timestamp.valueOf(
+                        LocalDateTime.now().minus(1, ChronoUnit.SECONDS)
+                )
+        );
+        assertEquals("older", dbStore.getOldestUnswappedProject());
+        dbStore.setProjectLastAccessedTimeIfMissing(
+                "older",
+                Timestamp.valueOf(
+                        LocalDateTime.now()
+                )
+        );
+        assertEquals("older", dbStore.getOldestUnswappedProject());
+    }
+
 }