Просмотр исходного кода

Added per-project synchronisation and massively refactored SQLiteWLDatabase.

Winston Li 12 лет назад
Родитель
Сommit
b5adf31774
22 измененных файлов с 736 добавлено и 252 удалено
  1. 12 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/util/Util.java
  2. 3 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java
  3. 0 250
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/SQLiteWLDatabase.java
  4. 3 2
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/WLGBPersistentStore.java
  5. 13 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLQuery.java
  6. 14 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLUpdate.java
  7. 128 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLiteWLDatabase.java
  8. 57 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetFileNodesForProjectNameSQLQuery.java
  9. 38 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetProjectNamesSQLQuery.java
  10. 48 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetURLIndexTableForProjectNameSQLQuery.java
  11. 43 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetVersionIDsForProjectNameSQLQuery.java
  12. 35 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateFileNodeTableSQLUpdate.java
  13. 28 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateProjectsTableSQLUpdate.java
  14. 31 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateSnapshotsTableSQLUpdate.java
  15. 32 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateURLIndexStoreSQLUpdate.java
  16. 32 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/delete/DeleteFileNodesForProjectNameSQLUpdate.java
  17. 32 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/delete/DeleteURLIndexesForProjectNameSQLUpdate.java
  18. 41 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddFileNodeBlobSQLUpdate.java
  19. 41 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddFileNodeExternalSQLUpdate.java
  20. 32 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddProjectSQLUpdate.java
  21. 35 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddSnapshotSQLUpdate.java
  22. 38 0
      services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddURLIndexSQLUpdate.java

+ 12 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/util/Util.java

@@ -13,4 +13,16 @@ public class Util {
         }
         }
     }
     }
 
 
+    public static int booleanToInt(boolean b) {
+        if (b) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    public static boolean intToBoolean(int i) {
+        return i != 0;
+    }
+
 }
 }

+ 3 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java

@@ -84,6 +84,7 @@ public class WriteLatexAPI implements WriteLatexDataSource {
 
 
     @Override
     @Override
     public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException {
     public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException {
+        lockForProject(projectName);
         System.out.println("Pushing project: " + projectName);
         System.out.println("Pushing project: " + projectName);
         CandidateSnapshot candidate = dataModel.createCandidateSnapshotFromProjectWithContents(projectName, directoryContents, hostname);
         CandidateSnapshot candidate = dataModel.createCandidateSnapshotFromProjectWithContents(projectName, directoryContents, hostname);
         SnapshotPushRequest snapshotPushRequest = new SnapshotPushRequest(candidate);
         SnapshotPushRequest snapshotPushRequest = new SnapshotPushRequest(candidate);
@@ -91,7 +92,9 @@ public class WriteLatexAPI implements WriteLatexDataSource {
         SnapshotPushRequestResult result = snapshotPushRequest.getResult();
         SnapshotPushRequestResult result = snapshotPushRequest.getResult();
         if (result.wasSuccessful()) {
         if (result.wasSuccessful()) {
             candidate.approveWithVersionID(postbackManager.getVersionID(projectName));
             candidate.approveWithVersionID(postbackManager.getVersionID(projectName));
+            unlockForProject(projectName);
         } else {
         } else {
+            unlockForProject(projectName);
             throw new OutOfDateException();
             throw new OutOfDateException();
         }
         }
     }
     }

+ 0 - 250
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/SQLiteWLDatabase.java

@@ -1,250 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.model.db;
-
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.BlobNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
-
-import java.io.File;
-import java.sql.*;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created by Winston on 17/11/14.
- */
-public class SQLiteWLDatabase {
-
-    private static final String[] CREATE_TABLE_STATEMENTS = {
-            "CREATE TABLE IF NOT EXISTS `projects` (\n" +
-            "  `name` varchar(10) NOT NULL DEFAULT '',\n" +
-            "  PRIMARY KEY (`name`)\n" +
-            ")",
-            "CREATE TABLE IF NOT EXISTS `snapshots` (\n" +
-            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n" +
-            "  `version_id` int(11) NOT NULL,\n" +
-            "  PRIMARY KEY (`project_name`,`version_id`),\n" +
-            "  CONSTRAINT `snapshots_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n" +
-            ")",
-            "CREATE TABLE IF NOT EXISTS `file_node_table` (\n" +
-            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n" +
-            "  `file_name` varchar(255) NOT NULL DEFAULT '',\n" +
-            "  `changed` tinyint(1) NOT NULL,\n" +
-            "  `is_blob` tinyint(1) NOT NULL,\n" +
-            "  `blob` blob,\n" +
-            "  `url` varchar(128) DEFAULT NULL,\n" +
-            "  PRIMARY KEY (`project_name`,`file_name`),\n" +
-            "  CONSTRAINT `file_node_table_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n" +
-            ")",
-            "CREATE TABLE IF NOT EXISTS `url_index_store` (\n"+
-            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n"+
-            "  `url` varchar(128) NOT NULL,\n"+
-            "  `blob` blob NOT NULL,\n"+
-            "  PRIMARY KEY (`project_name`,`url`),\n"+
-            "  CONSTRAINT `url_index_store_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n"+
-            ")"
-    };
-
-    private static final String ADD_PROJECT =
-            "INSERT INTO `projects` (`name`) VALUES (?);\n";
-    private static final String ADD_SNAPSHOT =
-            "INSERT INTO `snapshots` (`project_name`, `version_id`) VALUES (?, ?);\n";
-    private static final String ADD_FILE_NODE_BLOB =
-            "INSERT INTO `file_node_table` (`project_name`, `file_name`, `changed`, `is_blob`, `blob`, `url`) VALUES (?, ?, ?, '1', ?, NULL);\n";
-    private static final String ADD_FILE_NODE_EXTERNAL =
-            "INSERT INTO `file_node_table` (`project_name`, `file_name`, `changed`, `is_blob`, `blob`, `url`) VALUES (?, ?, ?, '0', NULL, ?);\n";
-    private static final String ADD_URL_INDEX =
-            "INSERT INTO `url_index_store` (`project_name`, `url`, `blob`) VALUES (?, ?, ?);\n";
-
-    private static final String GET_PROJECT_NAMES =
-            "SELECT * FROM `projects`;\n";
-    private static final String GET_VERSION_IDS_FOR_PROJECT_NAME =
-            "SELECT `version_id` FROM `snapshots` WHERE `project_name` = ?";
-    private static final String GET_FILE_NODES_FOR_PROJECT_NAME =
-            "SELECT `file_name`, `changed`, `is_blob`, `blob`, `url` FROM `file_node_table` WHERE `project_name` = ?";
-    private static final String GET_URL_INDEXES_FOR_PROJECT_NAME =
-            "SELECT `url`, `blob` FROM `url_index_store` WHERE `project_name` = ?";
-
-    private static final String DELETE_FILE_NODES_FOR_PROJECT_NAME =
-            "DELETE FROM `file_node_table` WHERE `project_name` = ?";
-    private static final String DELETE_URL_INDEXES_FOR_PROJECT_NAME =
-            "DELETE FROM `url_index_store` WHERE `project_name` = ?";
-
-    private final File rootGitDirectory;
-    private final Connection connection;
-
-    private PreparedStatement addProjectStatement;
-    private PreparedStatement addSnapshotStatement;
-    private PreparedStatement addFileNodeBlobStatement;
-    private PreparedStatement addFileNodeExternalStatement;
-    private PreparedStatement addURLIndexStatement;
-
-    private PreparedStatement getProjectNamesStatement;
-    private PreparedStatement getVersionIDsForProjectNameStatement;
-    private PreparedStatement getFileNodesForProjectNameStatement;
-    private PreparedStatement getURLIndexesForProjectNameStatement;
-
-    private PreparedStatement deleteFileNodesForProjectNameStatement;
-    private PreparedStatement deleteURLIndexesForProjectNameStatement;
-
-    public SQLiteWLDatabase(File rootGitDirectory) throws SQLException, ClassNotFoundException {
-        this.rootGitDirectory = rootGitDirectory;
-        File databaseFile = new File(rootGitDirectory, "/.wlgb/wlgb.db");
-        databaseFile.getParentFile().mkdirs();
-        System.out.println("Loading data...");
-        Class.forName("org.sqlite.JDBC");
-        connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
-        createTables();
-        prepareStatements();
-    }
-
-    private void createTables() throws SQLException {
-        for (String createTableStatement : CREATE_TABLE_STATEMENTS) {
-            PreparedStatement preparedStatement = connection.prepareStatement(createTableStatement);
-            preparedStatement.executeUpdate();
-        }
-    }
-
-    private void prepareStatements() throws SQLException {
-        addProjectStatement = connection.prepareStatement(ADD_PROJECT);
-        addSnapshotStatement = connection.prepareStatement(ADD_SNAPSHOT);
-        addFileNodeBlobStatement = connection.prepareStatement(ADD_FILE_NODE_BLOB);
-        addFileNodeExternalStatement = connection.prepareStatement(ADD_FILE_NODE_EXTERNAL);
-        addURLIndexStatement = connection.prepareStatement(ADD_URL_INDEX);
-
-        getProjectNamesStatement = connection.prepareStatement(GET_PROJECT_NAMES);
-        getVersionIDsForProjectNameStatement = connection.prepareStatement(GET_VERSION_IDS_FOR_PROJECT_NAME);
-        getFileNodesForProjectNameStatement = connection.prepareStatement(GET_FILE_NODES_FOR_PROJECT_NAME);
-        getURLIndexesForProjectNameStatement = connection.prepareStatement(GET_URL_INDEXES_FOR_PROJECT_NAME);
-
-        deleteFileNodesForProjectNameStatement = connection.prepareStatement(DELETE_FILE_NODES_FOR_PROJECT_NAME);
-        deleteURLIndexesForProjectNameStatement = connection.prepareStatement(DELETE_URL_INDEXES_FOR_PROJECT_NAME);
-    }
-
-    public void addProject(String name) throws SQLException {
-        addProjectStatement.clearParameters();
-        addProjectStatement.setString(1, name);
-        addProjectStatement.executeUpdate();
-    }
-
-    public void addSnapshot(String projectName, int versionID) throws SQLException {
-        addSnapshotStatement.clearParameters();
-        addSnapshotStatement.setString(1, projectName);
-        addSnapshotStatement.setInt(2, versionID);
-        addSnapshotStatement.executeUpdate();
-    }
-
-    public void addFileNodeBlob(String projectName, String fileName, int changed, byte[] blob) throws SQLException {
-        addFileNodeBlobStatement.clearParameters();
-        addFileNodeBlobStatement.setString(1, projectName);
-        addFileNodeBlobStatement.setString(2, fileName);
-        addFileNodeBlobStatement.setInt(3, changed);
-        addFileNodeBlobStatement.setBytes(4, blob);
-        addFileNodeBlobStatement.executeUpdate();
-    }
-
-    public void addFileNodeExternal(String projectName, String fileName, int changed, String url) throws SQLException {
-        addFileNodeExternalStatement.clearParameters();
-        addFileNodeExternalStatement.setString(1, projectName);
-        addFileNodeExternalStatement.setString(2, fileName);
-        addFileNodeExternalStatement.setInt(3, changed);
-        addFileNodeExternalStatement.setString(4, url);
-        addFileNodeExternalStatement.executeUpdate();
-    }
-
-    public void addURLIndex(String projectName, String url, byte[] blob) throws SQLException {
-        addURLIndexStatement.clearParameters();
-        addURLIndexStatement.setString(1, projectName);
-        addURLIndexStatement.setString(2, url);
-        addURLIndexStatement.setBytes(3, blob);
-        addURLIndexStatement.executeUpdate();
-    }
-
-    public List<String> getProjectNames() throws SQLException {
-        List<String> projectNames = new LinkedList<String>();
-        ResultSet results = getProjectNamesStatement.executeQuery();
-        while (results.next()) {
-            projectNames.add(results.getString("name"));
-        }
-        return projectNames;
-    }
-
-    public List<Integer> getVersionIDsForProjectName(String projectName) throws SQLException {
-        List<Integer> versionIDs = new LinkedList<Integer>();
-        getVersionIDsForProjectNameStatement.clearParameters();
-        getVersionIDsForProjectNameStatement.setString(1, projectName);
-        ResultSet results = getVersionIDsForProjectNameStatement.executeQuery();
-        while (results.next()) {
-            versionIDs.add(results.getInt("version_id"));
-        }
-        return versionIDs;
-    }
-
-    public List<FileNode> getFileNodesForProjectName(String projectName) throws SQLException {
-        List<FileNode> fileNodes = new LinkedList<FileNode>();
-        getFileNodesForProjectNameStatement.clearParameters();
-        getFileNodesForProjectNameStatement.setString(1, projectName);
-        ResultSet results = getFileNodesForProjectNameStatement.executeQuery();
-        while (results.next()) {
-            boolean isBlob = intToBoolean(results.getInt("is_blob"));
-            FileNode fileNode;
-            String fileName = results.getString("file_name");
-            boolean changed = intToBoolean(results.getInt("changed"));
-            if (isBlob) {
-                fileNode = new BlobNode(fileName, changed, results.getBytes("blob"));
-            } else {
-                fileNode = new AttachmentNode(fileName, changed, results.getString("url"));
-            }
-            fileNodes.add(fileNode);
-        }
-        return fileNodes;
-    }
-
-    public Map<String, FileNode> getURLIndexTableForProjectName(String projectName) throws SQLException {
-        Map<String, FileNode> urlIndexTable = new HashMap<String, FileNode>();
-        getURLIndexesForProjectNameStatement.clearParameters();
-        getURLIndexesForProjectNameStatement.setString(1, projectName);
-        ResultSet results = getURLIndexesForProjectNameStatement.executeQuery();
-        while (results.next()) {
-            String url = results.getString("url");
-            byte[] blob = results.getBytes("blob");
-            urlIndexTable.put(url, new AttachmentNode(url, blob));
-        }
-        return urlIndexTable;
-    }
-
-    public void deleteFileNodesForProjectName(String projectName) throws SQLException {
-        deleteFileNodesForProjectNameStatement.clearParameters();
-        deleteFileNodesForProjectNameStatement.setString(1, projectName);
-        deleteFileNodesForProjectNameStatement.executeUpdate();
-    }
-
-    public void deleteURLIndexesForProjectName(String projectName) throws SQLException {
-        deleteURLIndexesForProjectNameStatement.clearParameters();
-        deleteURLIndexesForProjectNameStatement.setString(1, projectName);
-        deleteURLIndexesForProjectNameStatement.executeUpdate();
-    }
-
-    private void test() throws SQLException {
-        addProject("testproj12");
-        addSnapshot("testproj12", 0);
-        addSnapshot("testproj12", 1);
-        addFileNodeBlob("testproj12", "filename.tex", 1, "hello".getBytes());
-        addFileNodeExternal("testproj12", "urlname.jpg", 1, "http://someurl.com/urlname.jpg");
-        addURLIndex("testproj12", "http://someurl.com/urlname.jpg", "thebytes".getBytes());
-    }
-
-    public static int booleanToInt(boolean b) {
-        if (b) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    public static boolean intToBoolean(int i) {
-        return i != 0;
-    }
-
-}

+ 3 - 2
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/WLGBPersistentStore.java

@@ -1,5 +1,6 @@
 package uk.ac.ic.wlgitbridge.writelatex.model.db;
 package uk.ac.ic.wlgitbridge.writelatex.model.db;
 
 
+import uk.ac.ic.wlgitbridge.util.Util;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.WLProjectStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.WLProjectStore;
@@ -59,7 +60,7 @@ public class WLGBPersistentStore implements PersistentStoreAPI {
     @Override
     @Override
     public void addFileNodeBlob(String projectName, String fileName, boolean changed, byte[] blob) {
     public void addFileNodeBlob(String projectName, String fileName, boolean changed, byte[] blob) {
         try {
         try {
-            database.addFileNodeBlob(projectName, fileName, SQLiteWLDatabase.booleanToInt(changed), blob);
+            database.addFileNodeBlob(projectName, fileName, Util.booleanToInt(changed), blob);
         } catch (SQLException e) {
         } catch (SQLException e) {
             throw new RuntimeException(e);
             throw new RuntimeException(e);
         }
         }
@@ -68,7 +69,7 @@ public class WLGBPersistentStore implements PersistentStoreAPI {
     @Override
     @Override
     public void addFileNodeExternal(String projectName, String fileName, boolean changed, String url) {
     public void addFileNodeExternal(String projectName, String fileName, boolean changed, String url) {
         try {
         try {
-            database.addFileNodeExternal(projectName, fileName, SQLiteWLDatabase.booleanToInt(changed), url);
+            database.addFileNodeExternal(projectName, fileName, Util.booleanToInt(changed), url);
         } catch (SQLException e) {
         } catch (SQLException e) {
             throw new RuntimeException(e);
             throw new RuntimeException(e);
         }
         }

+ 13 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLQuery.java

@@ -0,0 +1,13 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public interface SQLQuery<T> extends SQLUpdate {
+
+    public T processResultSet(ResultSet resultSet) throws SQLException;
+
+}

+ 14 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLUpdate.java

@@ -0,0 +1,14 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public interface SQLUpdate {
+
+    public String getSQL();
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException;
+
+}

+ 128 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLiteWLDatabase.java

@@ -0,0 +1,128 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
+
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetFileNodesForProjectNameSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetProjectNamesSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetURLIndexTableForProjectNameSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetVersionIDsForProjectNameSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateFileNodeTableSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateProjectsTableSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateSnapshotsTableSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateURLIndexStoreSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete.DeleteFileNodesForProjectNameSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete.DeleteURLIndexesForProjectNameSQLUpdate;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert.*;
+
+import java.io.File;
+import java.sql.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Winston on 17/11/14.
+ */
+public class SQLiteWLDatabase {
+
+    private final Connection connection;
+
+    public SQLiteWLDatabase(File rootGitDirectory) throws SQLException, ClassNotFoundException {
+        File databaseFile = new File(rootGitDirectory, "/.wlgb/wlgb.db");
+        databaseFile.getParentFile().mkdirs();
+        System.out.println("Loading data...");
+        Class.forName("org.sqlite.JDBC");
+        connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
+        createTables();
+    }
+
+    public void addProject(String projectName) throws SQLException {
+        update(new AddProjectSQLUpdate(projectName));
+    }
+
+    public void addSnapshot(String projectName, int versionID) throws SQLException {
+        update(new AddSnapshotSQLUpdate(projectName, versionID));
+    }
+
+    public void addFileNodeBlob(String projectName, String fileName, int changed, byte[] blob) throws SQLException {
+        update(new AddFileNodeBlobSQLUpdate(projectName, fileName, changed, blob));
+    }
+
+    public void addFileNodeExternal(String projectName, String fileName, int changed, String url) throws SQLException {
+        update(new AddFileNodeExternalSQLUpdate(projectName, fileName, changed, url));
+    }
+
+    public void addURLIndex(String projectName, String url, byte[] blob) throws SQLException {
+        update(new AddURLIndexSQLUpdate(projectName, url, blob));
+
+    }
+
+    public List<String> getProjectNames() throws SQLException {
+        return query(new GetProjectNamesSQLQuery());
+    }
+
+    public List<Integer> getVersionIDsForProjectName(String projectName) throws SQLException {
+        return query(new GetVersionIDsForProjectNameSQLQuery(projectName));
+    }
+
+    public List<FileNode> getFileNodesForProjectName(String projectName) throws SQLException {
+        return query(new GetFileNodesForProjectNameSQLQuery(projectName));
+    }
+
+    public Map<String, FileNode> getURLIndexTableForProjectName(String projectName) throws SQLException {
+        return query(new GetURLIndexTableForProjectNameSQLQuery(projectName));
+    }
+
+    public void deleteFileNodesForProjectName(String projectName) throws SQLException {
+        update(new DeleteFileNodesForProjectNameSQLUpdate(projectName));
+    }
+
+    public void deleteURLIndexesForProjectName(String projectName) throws SQLException {
+        update(new DeleteURLIndexesForProjectNameSQLUpdate(projectName));
+    }
+
+    private void createTables() throws SQLException {
+        final SQLUpdate[] createTableUpdates = {
+                new CreateProjectsTableSQLUpdate(),
+                new CreateSnapshotsTableSQLUpdate(),
+                new CreateFileNodeTableSQLUpdate(),
+                new CreateURLIndexStoreSQLUpdate()
+        };
+
+        for (SQLUpdate update : createTableUpdates) {
+            update(update);
+        }
+    }
+
+    private void update(SQLUpdate update) throws SQLException {
+        PreparedStatement statement = null;
+        try {
+            statement = connection.prepareStatement(update.getSQL());
+            update.addParametersToStatement(statement);
+            statement.executeUpdate();
+        } catch (SQLException e) {
+            throw e;
+        } finally {
+            statement.close();
+        }
+    }
+
+    private <T> T query(SQLQuery<T> query) throws SQLException {
+        PreparedStatement statement = null;
+        ResultSet results = null;
+        try {
+            statement = connection.prepareStatement(query.getSQL());
+            query.addParametersToStatement(statement);
+            results = statement.executeQuery();
+            return query.processResultSet(results);
+        } catch (SQLException e) {
+            throw e;
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+            if (results != null) {
+                results.close();
+            }
+        }
+    }
+
+}

+ 57 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetFileNodesForProjectNameSQLQuery.java

@@ -0,0 +1,57 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
+
+import uk.ac.ic.wlgitbridge.util.Util;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.BlobNode;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class GetFileNodesForProjectNameSQLQuery implements SQLQuery<List<FileNode>> {
+
+    private static final String GET_FILE_NODES_FOR_PROJECT_NAME =
+            "SELECT `file_name`, `changed`, `is_blob`, `blob`, `url` FROM `file_node_table` WHERE `project_name` = ?";
+
+    private final String projectName;
+
+    public GetFileNodesForProjectNameSQLQuery(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public List<FileNode> processResultSet(ResultSet resultSet) throws SQLException {
+        List<FileNode> fileNodes = new LinkedList<FileNode>();
+        while (resultSet.next()) {
+            boolean isBlob = Util.intToBoolean(resultSet.getInt("is_blob"));
+            FileNode fileNode;
+            String fileName = resultSet.getString("file_name");
+            boolean changed = Util.intToBoolean(resultSet.getInt("changed"));
+            if (isBlob) {
+                fileNode = new BlobNode(fileName, changed, resultSet.getBytes("blob"));
+            } else {
+                fileNode = new AttachmentNode(fileName, changed, resultSet.getString("url"));
+            }
+            fileNodes.add(fileNode);
+        }
+        return fileNodes;
+    }
+
+    @Override
+    public String getSQL() {
+        return GET_FILE_NODES_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+
+}

+ 38 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetProjectNamesSQLQuery.java

@@ -0,0 +1,38 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class GetProjectNamesSQLQuery implements SQLQuery<List<String>> {
+
+    private static final String GET_PROJECT_NAMES =
+            "SELECT * FROM `projects`;\n";
+
+    @Override
+    public List<String> processResultSet(ResultSet resultSet) throws SQLException {
+        List<String> projectNames = new LinkedList<String>();
+        while (resultSet.next()) {
+            projectNames.add(resultSet.getString("name"));
+        }
+        return projectNames;
+    }
+
+    @Override
+    public String getSQL() {
+        return GET_PROJECT_NAMES;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 48 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetURLIndexTableForProjectNameSQLQuery.java

@@ -0,0 +1,48 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
+
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class GetURLIndexTableForProjectNameSQLQuery implements SQLQuery<Map<String, FileNode>> {
+
+    private static final String GET_URL_INDEXES_FOR_PROJECT_NAME =
+            "SELECT `url`, `blob` FROM `url_index_store` WHERE `project_name` = ?";
+
+    private final String projectName;
+
+    public GetURLIndexTableForProjectNameSQLQuery(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public Map<String, FileNode> processResultSet(ResultSet resultSet) throws SQLException {
+        Map<String, FileNode> urlIndexTable = new HashMap<String, FileNode>();
+        while (resultSet.next()) {
+            String url = resultSet.getString("url");
+            byte[] blob = resultSet.getBytes("blob");
+            urlIndexTable.put(url, new AttachmentNode(url, blob));
+        }
+        return urlIndexTable;
+    }
+
+    @Override
+    public String getSQL() {
+        return GET_URL_INDEXES_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+
+}

+ 43 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetVersionIDsForProjectNameSQLQuery.java

@@ -0,0 +1,43 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class GetVersionIDsForProjectNameSQLQuery implements SQLQuery<List<Integer>> {
+
+    private static final String GET_VERSION_IDS_FOR_PROJECT_NAME =
+            "SELECT `version_id` FROM `snapshots` WHERE `project_name` = ?";
+
+    private final String projectName;
+
+    public GetVersionIDsForProjectNameSQLQuery(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public List<Integer> processResultSet(ResultSet resultSet) throws SQLException {
+        List<Integer> versionIDs = new LinkedList<Integer>();
+        while (resultSet.next()) {
+            versionIDs.add(resultSet.getInt("version_id"));
+        }
+        return versionIDs;
+    }
+
+    @Override
+    public String getSQL() {
+        return GET_VERSION_IDS_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+}

+ 35 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateFileNodeTableSQLUpdate.java

@@ -0,0 +1,35 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class CreateFileNodeTableSQLUpdate implements SQLUpdate {
+
+    private static final String CREATE_FILE_NODE_TABLE =
+            "CREATE TABLE IF NOT EXISTS `file_node_table` (\n" +
+            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n" +
+            "  `file_name` varchar(255) NOT NULL DEFAULT '',\n" +
+            "  `changed` tinyint(1) NOT NULL,\n" +
+            "  `is_blob` tinyint(1) NOT NULL,\n" +
+            "  `blob` blob,\n" +
+            "  `url` varchar(128) DEFAULT NULL,\n" +
+            "  PRIMARY KEY (`project_name`,`file_name`),\n" +
+            "  CONSTRAINT `file_node_table_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n" +
+            ")";
+
+    @Override
+    public String getSQL() {
+        return CREATE_FILE_NODE_TABLE;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 28 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateProjectsTableSQLUpdate.java

@@ -0,0 +1,28 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class CreateProjectsTableSQLUpdate implements SQLUpdate {
+
+    private static final String CREATE_PROJECTS_TABLE =
+            "CREATE TABLE IF NOT EXISTS `projects` (\n" +
+            "  `name` varchar(10) NOT NULL DEFAULT '',\n" +
+            "  PRIMARY KEY (`name`)\n" +
+            ")";
+    @Override
+    public String getSQL() {
+        return CREATE_PROJECTS_TABLE;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 31 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateSnapshotsTableSQLUpdate.java

@@ -0,0 +1,31 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class CreateSnapshotsTableSQLUpdate implements SQLUpdate {
+
+    private static final String CREATE_SNAPSHOTS_TABLE =
+            "CREATE TABLE IF NOT EXISTS `snapshots` (\n" +
+            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n" +
+            "  `version_id` int(11) NOT NULL,\n" +
+            "  PRIMARY KEY (`project_name`,`version_id`),\n" +
+            "  CONSTRAINT `snapshots_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n" +
+            ")";
+
+    @Override
+    public String getSQL() {
+        return CREATE_SNAPSHOTS_TABLE;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 32 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateURLIndexStoreSQLUpdate.java

@@ -0,0 +1,32 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class CreateURLIndexStoreSQLUpdate implements SQLUpdate {
+
+    private static final String CREATE_URL_INDEX_STORE =
+            "CREATE TABLE IF NOT EXISTS `url_index_store` (\n"+
+            "  `project_name` varchar(10) NOT NULL DEFAULT '',\n"+
+            "  `url` varchar(128) NOT NULL,\n"+
+            "  `blob` blob NOT NULL,\n"+
+            "  PRIMARY KEY (`project_name`,`url`),\n"+
+            "  CONSTRAINT `url_index_store_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n"+
+            ")";
+
+    @Override
+    public String getSQL() {
+        return CREATE_URL_INDEX_STORE;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 32 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/delete/DeleteFileNodesForProjectNameSQLUpdate.java

@@ -0,0 +1,32 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class DeleteFileNodesForProjectNameSQLUpdate implements SQLUpdate {
+
+    private static final String DELETE_FILE_NODES_FOR_PROJECT_NAME =
+            "DELETE FROM `file_node_table` WHERE `project_name` = ?";
+
+    private final String projectName;
+
+    public DeleteFileNodesForProjectNameSQLUpdate(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public String getSQL() {
+        return DELETE_FILE_NODES_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+
+}

+ 32 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/delete/DeleteURLIndexesForProjectNameSQLUpdate.java

@@ -0,0 +1,32 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class DeleteURLIndexesForProjectNameSQLUpdate implements SQLUpdate {
+
+    private static final String DELETE_URL_INDEXES_FOR_PROJECT_NAME =
+            "DELETE FROM `url_index_store` WHERE `project_name` = ?";
+
+    private final String projectName;
+
+    public DeleteURLIndexesForProjectNameSQLUpdate(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public String getSQL() {
+        return DELETE_URL_INDEXES_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+
+}

+ 41 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddFileNodeBlobSQLUpdate.java

@@ -0,0 +1,41 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class AddFileNodeBlobSQLUpdate implements SQLUpdate {
+
+    private static final String ADD_FILE_NODE_BLOB =
+            "INSERT INTO `file_node_table` (`project_name`, `file_name`, `changed`, `is_blob`, `blob`, `url`) VALUES (?, ?, ?, '1', ?, NULL);\n";
+
+    private final String projectName;
+    private final String fileName;
+    private final int changed;
+    private final byte[] blob;
+
+    public AddFileNodeBlobSQLUpdate(String projectName, String fileName, int changed, byte[] blob) {
+        this.projectName = projectName;
+        this.fileName = fileName;
+        this.changed = changed;
+        this.blob = blob;
+    }
+
+    @Override
+    public String getSQL() {
+        return ADD_FILE_NODE_BLOB;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+        statement.setString(2, fileName);
+        statement.setInt(3, changed);
+        statement.setBytes(4, blob);
+    }
+
+}

+ 41 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddFileNodeExternalSQLUpdate.java

@@ -0,0 +1,41 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class AddFileNodeExternalSQLUpdate implements SQLUpdate {
+
+    private static final String ADD_FILE_NODE_EXTERNAL =
+            "INSERT INTO `file_node_table` (`project_name`, `file_name`, `changed`, `is_blob`, `blob`, `url`) VALUES (?, ?, ?, '0', NULL, ?);\n";
+
+    private final String projectName;
+    private final String fileName;
+    private final int changed;
+    private final String url;
+
+    public AddFileNodeExternalSQLUpdate(String projectName, String fileName, int changed, String url) {
+        this.projectName = projectName;
+        this.fileName = fileName;
+        this.changed = changed;
+        this.url = url;
+    }
+
+    @Override
+    public String getSQL() {
+        return ADD_FILE_NODE_EXTERNAL;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+        statement.setString(2, fileName);
+        statement.setInt(3, changed);
+        statement.setString(4, url);
+    }
+
+}

+ 32 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddProjectSQLUpdate.java

@@ -0,0 +1,32 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class AddProjectSQLUpdate implements SQLUpdate {
+
+    private static final String ADD_PROJECT =
+            "INSERT INTO `projects` (`name`) VALUES (?);\n";
+
+    private final String projectName;
+
+    public AddProjectSQLUpdate(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public String getSQL() {
+        return ADD_PROJECT;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+    }
+
+}

+ 35 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddSnapshotSQLUpdate.java

@@ -0,0 +1,35 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class AddSnapshotSQLUpdate implements SQLUpdate {
+
+    private static final String ADD_SNAPSHOT =
+            "INSERT INTO `snapshots` (`project_name`, `version_id`) VALUES (?, ?);\n";
+
+    private final String projectName;
+    private final int versionID;
+
+    public AddSnapshotSQLUpdate(String projectName, int versionID) {
+        this.projectName = projectName;
+        this.versionID = versionID;
+    }
+
+    @Override
+    public String getSQL() {
+        return ADD_SNAPSHOT;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+        statement.setInt(2, versionID);
+    }
+
+}

+ 38 - 0
services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/insert/AddURLIndexSQLUpdate.java

@@ -0,0 +1,38 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 20/11/14.
+ */
+public class AddURLIndexSQLUpdate implements SQLUpdate {
+
+    private static final String ADD_URL_INDEX =
+            "INSERT INTO `url_index_store` (`project_name`, `url`, `blob`) VALUES (?, ?, ?);\n";
+
+    private final String projectName;
+    private final String url;
+    private final byte[] blob;
+
+    public AddURLIndexSQLUpdate(String projectName, String url, byte[] blob) {
+        this.projectName = projectName;
+        this.url = url;
+        this.blob = blob;
+    }
+
+    @Override
+    public String getSQL() {
+        return ADD_URL_INDEX;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+        statement.setString(1, projectName);
+        statement.setString(2, url);
+        statement.setBytes(3, blob);
+    }
+
+}