aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-02-22 11:15:50 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-02-22 11:15:50 +0000
commit299ff64812ce166d230f1b630f794be226c7a178 (patch)
treee09c23e7c49837c09701255bcd8fc09e51a964a8
parent1930570ad96e47de9e8557a7734c7bfd9f36f942 (diff)
* Put the derivation outputs in the database. This is useful for the
garbage collector.
-rw-r--r--src/libstore/local-store.cc26
-rw-r--r--src/libstore/local-store.hh1
-rw-r--r--src/libstore/schema.sql10
3 files changed, 35 insertions, 2 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 4c1bbb708..2f12256db 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -3,9 +3,9 @@
#include "globals.hh"
#include "archive.hh"
#include "pathlocks.hh"
-#include "aterm.hh"
#include "derivations-ast.hh"
#include "worker-protocol.hh"
+#include "derivations.hh"
#include <iostream>
#include <algorithm>
@@ -295,6 +295,8 @@ void LocalStore::prepareStatements()
"insert into FailedPaths (path, time) values (?, ?);");
stmtHasPathFailed.create(db,
"select time from FailedPaths where path = ?;");
+ stmtAddDerivationOutput.create(db,
+ "insert or replace into DerivationOutputs (drv, id, path) values (?, ?, ?);");
}
@@ -397,7 +399,27 @@ unsigned long long LocalStore::addValidPath(const ValidPathInfo & info)
stmtRegisterValidPath.bind(); // null
if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE)
throw SQLiteError(db, format("registering valid path `%1%' in database") % info.path);
- return sqlite3_last_insert_rowid(db);
+ unsigned long long id = sqlite3_last_insert_rowid(db);
+
+ /* If this is a derivation, then store the derivation outputs in
+ the database. This is useful for the garbage collector: it can
+ efficiently query whether a path is an output of some
+ derivation. */
+ if (isDerivation(info.path)) {
+ ATerm t = ATreadFromNamedFile(info.path.c_str());
+ if (!t) throw Error(format("cannot read derivation `%1%'") % info.path);
+ Derivation drv = parseDerivation(t);
+ foreach (DerivationOutputs::iterator, i, drv.outputs) {
+ SQLiteStmtUse use(stmtAddDerivationOutput);
+ stmtAddDerivationOutput.bind(id);
+ stmtAddDerivationOutput.bind(i->first);
+ stmtAddDerivationOutput.bind(i->second.path);
+ if (sqlite3_step(stmtAddDerivationOutput) != SQLITE_DONE)
+ throw SQLiteError(db, format("adding derivation output for `%1%' in database") % info.path);
+ }
+ }
+
+ return id;
}
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index e1859e68e..f10ba18d5 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -198,6 +198,7 @@ private:
SQLiteStmt stmtInvalidatePath;
SQLiteStmt stmtRegisterFailedPath;
SQLiteStmt stmtHasPathFailed;
+ SQLiteStmt stmtAddDerivationOutput;
int getSchema();
diff --git a/src/libstore/schema.sql b/src/libstore/schema.sql
index 1e707ce1f..682ce5ed7 100644
--- a/src/libstore/schema.sql
+++ b/src/libstore/schema.sql
@@ -17,6 +17,16 @@ create table if not exists Refs (
create index if not exists IndexReferrer on Refs(referrer);
create index if not exists IndexReference on Refs(reference);
+create table if not exists DerivationOutputs (
+ drv integer not null,
+ id text not null, -- symbolic output id, usually "out"
+ path text not null,
+ primary key (drv, id),
+ foreign key (drv) references ValidPaths(id) on delete cascade
+);
+
+create index if not exists IndexDerivationOutputs on DerivationOutputs(path);
+
create table if not exists FailedPaths (
path text primary key not null,
time integer not null