about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/local-store.cc48
-rw-r--r--src/libstore/local-store.hh3
2 files changed, 19 insertions, 32 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 76911da67c..f1deb2eae2 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -167,6 +167,9 @@ LocalStore::LocalStore()
 
     if (sqlite3_busy_timeout(db, 60000) != SQLITE_OK)
         throw SQLiteError(db, "setting timeout");
+
+    /* !!! check whether sqlite has been built with foreign key
+       support */
     
     /* Check the current database schema and if necessary do an
        upgrade.  !!! Race condition: several processes could start
@@ -240,6 +243,8 @@ void LocalStore::prepareStatements()
         "select id, hash, registrationTime, deriver from ValidPaths where path = ?;");
     stmtQueryReferences.create(db,
         "select path from Refs join ValidPaths on reference = id where referrer = ?;");
+    stmtQueryReferrers.create(db,
+        "select path from Refs join ValidPaths on referrer = id where reference = (select id from ValidPaths where path = ?);");
 }
 
 
@@ -498,41 +503,24 @@ void LocalStore::queryReferences(const Path & path,
 }
 
 
-bool LocalStore::queryReferrersInternal(const Path & path, PathSet & referrers)
+void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
 {
-#if 0
-    bool allValid = true;
-    
-    if (!isValidPath(path))
-        throw Error(format("path `%1%' is not valid") % path);
-
-    /* No locking is necessary here: updates are only done by
-       appending or by atomically replacing the file.  When appending,
-       there is a possibility that we see a partial entry, but it will
-       just be filtered out below (the partially written path will not
-       be valid, so it will be ignored). */
-
-    Path referrersFile = referrersFileFor(path);
-    if (!pathExists(referrersFile)) return true;
-    
-    AutoCloseFD fd = open(referrersFile.c_str(), O_RDONLY);
-    if (fd == -1) throw SysError(format("opening file `%1%'") % referrersFile);
-
-    Paths refs = tokenizeString(readFile(fd), " ");
+    assertStorePath(path);
 
-    foreach (Paths::iterator, i, refs)
-        /* Referrers can be invalid (see registerValidPath() for the
-           invariant), so we only return one if it is valid. */
-        if (isStorePath(*i) && isValidPath(*i)) referrers.insert(*i); else allValid = false;
+    stmtQueryReferrers.reset();
 
-    return allValid;
-#endif
-}
+    if (sqlite3_bind_text(stmtQueryReferrers, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
+        throw SQLiteError(db, "binding argument");
 
+    int r;
+    while ((r = sqlite3_step(stmtQueryReferrers)) == SQLITE_ROW) {
+        const char * s = (const char *) sqlite3_column_text(stmtQueryReferrers, 0);
+        assert(s);
+        referrers.insert(s);
+    }
 
-void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
-{
-    queryReferrersInternal(path, referrers);
+    if (r != SQLITE_DONE)
+        throw Error(format("error getting references of `%1%'") % path);
 }
 
 
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index af1cd26a30..9eae443d12 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -190,6 +190,7 @@ private:
     SQLiteStmt stmtAddReference;
     SQLiteStmt stmtQueryPathInfo;
     SQLiteStmt stmtQueryReferences;
+    SQLiteStmt stmtQueryReferrers;
 
     int getSchema();
 
@@ -205,8 +206,6 @@ private:
     
     void rewriteReferrers(const Path & path, bool purge, PathSet referrers);
 
-    bool queryReferrersInternal(const Path & path, PathSet & referrers);
-    
     void invalidatePath(const Path & path);
 
     void upgradeStore6();