about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/gc.cc8
-rw-r--r--src/libstore/local-store.cc24
-rw-r--r--src/libstore/local-store.hh3
-rw-r--r--src/libstore/misc.cc8
-rw-r--r--src/libstore/remote-store.cc6
-rw-r--r--src/libstore/remote-store.hh2
-rw-r--r--src/libstore/store-api.hh3
7 files changed, 46 insertions, 8 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 659c636e3d19..cf073c5d9aca 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -467,10 +467,10 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path)
            then don't delete the derivation if any of the outputs are
            live. */
         if (state.gcKeepDerivations && isDerivation(path)) {
-            Derivation drv = derivationFromPath(path);
-            foreach (DerivationOutputs::iterator, i, drv.outputs)
-                if (!tryToDelete(state, i->second.path)) {
-                    printMsg(lvlDebug, format("cannot delete derivation `%1%' because its output is alive") % path);
+            PathSet outputs = queryDerivationOutputs(path);
+            foreach (PathSet::iterator, i, outputs)
+                if (!tryToDelete(state, *i)) {
+                    printMsg(lvlDebug, format("cannot delete derivation `%1%' because its output `%2%' is alive") % path % *i);
                     goto isLive;
                 }
         }
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 0590b294baed..0823e785bda2 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -299,6 +299,8 @@ void LocalStore::prepareStatements()
         "insert or replace into DerivationOutputs (drv, id, path) values (?, ?, ?);");
     stmtQueryValidDerivers.create(db,
         "select v.id, v.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where d.path = ?;");
+    stmtQueryDerivationOutputs.create(db,
+        "select id, path from DerivationOutputs where drv = ?;");
 }
 
 
@@ -623,6 +625,28 @@ PathSet LocalStore::queryValidDerivers(const Path & path)
 }
 
 
+PathSet LocalStore::queryDerivationOutputs(const Path & path)
+{
+    SQLiteTxn txn(db);
+    
+    SQLiteStmtUse use(stmtQueryDerivationOutputs);
+    stmtQueryDerivationOutputs.bind(queryPathInfo(path).id);
+    
+    PathSet outputs;
+    int r;
+    while ((r = sqlite3_step(stmtQueryDerivationOutputs)) == SQLITE_ROW) {
+        const char * s = (const char *) sqlite3_column_text(stmtQueryDerivationOutputs, 1);
+        assert(s);
+        outputs.insert(s);
+    }
+    
+    if (r != SQLITE_DONE)
+        throw SQLiteError(db, format("error getting outputs of `%1%'") % path);
+
+    return outputs;
+}
+
+
 void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run)
 {
     if (run.pid != -1) return;
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 6bd47b3055f7..1a4acbe0e4eb 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -109,6 +109,8 @@ public:
        derivation that was actually used to produce `path', which may
        not exist anymore.) */
     PathSet queryValidDerivers(const Path & path);
+
+    PathSet queryDerivationOutputs(const Path & path);
     
     PathSet querySubstitutablePaths();
     
@@ -206,6 +208,7 @@ private:
     SQLiteStmt stmtHasPathFailed;
     SQLiteStmt stmtAddDerivationOutput;
     SQLiteStmt stmtQueryValidDerivers;
+    SQLiteStmt stmtQueryDerivationOutputs;
 
     int getSchema();
 
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 2d7d13a0e7b4..f79cb11cc20b 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -31,10 +31,10 @@ void computeFSClosure(const Path & storePath,
         store->queryReferences(storePath, references);
 
     if (includeOutputs && isDerivation(storePath)) {
-        Derivation drv = derivationFromPath(storePath);
-        foreach (DerivationOutputs::iterator, i, drv.outputs)
-            if (store->isValidPath(i->second.path))
-                computeFSClosure(i->second.path, paths, flipDirection, true);
+        PathSet outputs = store->queryDerivationOutputs(storePath);
+        foreach (PathSet::iterator, i, outputs)
+            if (store->isValidPath(*i))
+                computeFSClosure(*i, paths, flipDirection, true);
     }
 
     foreach (PathSet::iterator, i, references)
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 5143143f57c3..07cb62dc80a4 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -294,6 +294,12 @@ Path RemoteStore::queryDeriver(const Path & path)
 }
 
 
+PathSet RemoteStore::queryDerivationOutputs(const Path & path)
+{
+    throw Error("not yet implemented");
+}
+
+
 Path RemoteStore::addToStore(const Path & _srcPath,
     bool recursive, HashType hashAlgo, PathFilter & filter)
 {
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 3d55d23d958e..8bab1d8c4857 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -37,6 +37,8 @@ public:
 
     Path queryDeriver(const Path & path);
     
+    PathSet queryDerivationOutputs(const Path & path);
+    
     bool hasSubstitutes(const Path & path);
     
     bool querySubstitutablePathInfo(const Path & path,
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index d85ae0c9a10a..b6a8ff40e511 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -139,6 +139,9 @@ public:
        no deriver has been set. */
     virtual Path queryDeriver(const Path & path) = 0;
 
+    /* Query the outputs of the derivation denoted by `path'. */
+    virtual PathSet queryDerivationOutputs(const Path & path) = 0;
+    
     /* Query whether a path has substitutes. */
     virtual bool hasSubstitutes(const Path & path) = 0;