Compute checksums of segments and store them in the local database.
[cumulus.git] / localdb.cc
index 1388881..5c1f7e5 100644 (file)
@@ -38,7 +38,8 @@ sqlite3_stmt *LocalDb::Prepare(const char *sql)
     return stmt;
 }
 
-void LocalDb::Open(const char *path, const char *snapshot_name)
+void LocalDb::Open(const char *path, const char *snapshot_name,
+                   const char *snapshot_scheme)
 {
     int rc;
 
@@ -58,10 +59,16 @@ void LocalDb::Open(const char *path, const char *snapshot_name)
 
     /* Insert this snapshot into the database, and determine the integer key
      * which will be used to identify it. */
-    sqlite3_stmt *stmt = Prepare("insert into snapshots(name, timestamp) "
-                                 "values (?, julianday('now'))");
+    sqlite3_stmt *stmt = Prepare("insert into "
+                                 "snapshots(name, scheme, timestamp) "
+                                 "values (?, ?, julianday('now'))");
     sqlite3_bind_text(stmt, 1, snapshot_name, strlen(snapshot_name),
                       SQLITE_TRANSIENT);
+    if (snapshot_scheme == NULL)
+        sqlite3_bind_null(stmt, 2);
+    else
+        sqlite3_bind_text(stmt, 2, snapshot_scheme, strlen(snapshot_scheme),
+                          SQLITE_TRANSIENT);
 
     rc = sqlite3_step(stmt);
     if (rc != SQLITE_DONE) {
@@ -230,6 +237,34 @@ bool LocalDb::IsOldObject(const string &checksum, int64_t size, double *age)
     return found;
 }
 
+/* Does this object still exist in the database (and not expired)? */
+bool LocalDb::IsAvailable(const ObjectReference &ref)
+{
+    int rc;
+    sqlite3_stmt *stmt;
+    bool found = false;
+
+    stmt = Prepare("select count(*) from block_index "
+                   "where segmentid = ? and object = ? and expired is null");
+    sqlite3_bind_int64(stmt, 1, SegmentToId(ref.get_segment()));
+    sqlite3_bind_text(stmt, 2, ref.get_sequence().c_str(),
+                      ref.get_sequence().size(), SQLITE_TRANSIENT);
+
+    rc = sqlite3_step(stmt);
+    if (rc == SQLITE_DONE) {
+        found = false;
+    } else if (rc == SQLITE_ROW) {
+        if (sqlite3_column_int(stmt, 0) > 0)
+            found = true;
+    } else {
+        fprintf(stderr, "Could not execute SELECT statement!\n");
+    }
+
+    sqlite3_finalize(stmt);
+
+    return found;
+}
+
 void LocalDb::UseObject(const ObjectReference& ref)
 {
     int rc;
@@ -250,3 +285,26 @@ void LocalDb::UseObject(const ObjectReference& ref)
 
     sqlite3_finalize(stmt);
 }
+
+void LocalDb::SetSegmentChecksum(const std::string &segment,
+                                 const std::string &path,
+                                 const std::string &checksum)
+{
+    int rc;
+    sqlite3_stmt *stmt;
+
+    stmt = Prepare("update segments set path = ?, checksum = ? "
+                   "where segmentid = ?");
+    sqlite3_bind_text(stmt, 1, path.c_str(), path.size(),
+                      SQLITE_TRANSIENT);
+    sqlite3_bind_text(stmt, 2, checksum.c_str(), checksum.size(),
+                      SQLITE_TRANSIENT);
+    sqlite3_bind_int64(stmt, 3, SegmentToId(segment));
+
+    rc = sqlite3_step(stmt);
+    if (rc != SQLITE_DONE) {
+        fprintf(stderr, "Could not update segment checksum in database!\n");
+    }
+
+    sqlite3_finalize(stmt);
+}