about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-02-19T17·15+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-02-19T17·15+0000
commit1930570ad96e47de9e8557a7734c7bfd9f36f942 (patch)
treeed4eb236f6e7935a955659105821f1e9beadef65
parent9c9a88e9e25bdc4456368a40691e61acf5d3b330 (diff)
* Foreign key support in SQLite is not a persistent setting, so enable
  it at startup.
* Implement negative caching.  Now `make check' passes.

-rw-r--r--src/libstore/local-store.cc21
-rw-r--r--src/libstore/local-store.hh2
-rw-r--r--src/libstore/schema.sql4
-rw-r--r--tests/referrers.sh27
4 files changed, 25 insertions, 29 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index cd25ded72b..4c1bbb708e 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -209,6 +209,9 @@ LocalStore::LocalStore()
     if (sqlite3_busy_timeout(db, 60000) != SQLITE_OK)
         throw SQLiteError(db, "setting timeout");
 
+    if (sqlite3_exec(db, "pragma foreign_keys = 1;", 0, 0, 0) != SQLITE_OK)
+        throw SQLiteError(db, "enabling foreign keys");
+
     /* !!! check whether sqlite has been built with foreign key
        support */
     
@@ -288,6 +291,10 @@ void LocalStore::prepareStatements()
         "select path from Refs join ValidPaths on referrer = id where reference = (select id from ValidPaths where path = ?);");
     stmtInvalidatePath.create(db,
         "delete from ValidPaths where path = ?;");
+    stmtRegisterFailedPath.create(db,
+        "insert into FailedPaths (path, time) values (?, ?);");
+    stmtHasPathFailed.create(db,
+        "select time from FailedPaths where path = ?;");
 }
 
 
@@ -425,13 +432,23 @@ void LocalStore::registerValidPath(const ValidPathInfo & info)
 
 void LocalStore::registerFailedPath(const Path & path)
 {
-    throw Error("not implemented");
+    if (hasPathFailed(path)) return;
+    SQLiteStmtUse use(stmtRegisterFailedPath);
+    stmtRegisterFailedPath.bind(path);
+    stmtRegisterFailedPath.bind(time(0));
+    if (sqlite3_step(stmtRegisterFailedPath) != SQLITE_DONE)
+        throw SQLiteError(db, format("registering failed path `%1%'") % path);
 }
 
 
 bool LocalStore::hasPathFailed(const Path & path)
 {
-    throw Error("not implemented");
+    SQLiteStmtUse use(stmtHasPathFailed);
+    stmtHasPathFailed.bind(path);
+    int res = sqlite3_step(stmtHasPathFailed);
+    if (res != SQLITE_DONE && res != SQLITE_ROW)
+        throw SQLiteError(db, "querying whether path failed");
+    return res == SQLITE_ROW;
 }
 
 
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 34aa55fc8f..e1859e68ed 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -196,6 +196,8 @@ private:
     SQLiteStmt stmtQueryReferences;
     SQLiteStmt stmtQueryReferrers;
     SQLiteStmt stmtInvalidatePath;
+    SQLiteStmt stmtRegisterFailedPath;
+    SQLiteStmt stmtHasPathFailed;
 
     int getSchema();
 
diff --git a/src/libstore/schema.sql b/src/libstore/schema.sql
index dc53f452c2..1e707ce1f4 100644
--- a/src/libstore/schema.sql
+++ b/src/libstore/schema.sql
@@ -1,5 +1,3 @@
-pragma foreign_keys = on;
-
 create table if not exists ValidPaths (
     id               integer primary key autoincrement not null,
     path             text unique not null,
@@ -19,7 +17,7 @@ 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 FailedDerivations (
+create table if not exists FailedPaths (
     path text primary key not null,
     time integer not null
 );
diff --git a/tests/referrers.sh b/tests/referrers.sh
index e3f8e07bc1..752f05c3d5 100644
--- a/tests/referrers.sh
+++ b/tests/referrers.sh
@@ -3,6 +3,8 @@ source common.sh
 # This takes way to long on Cygwin (because process creation is so slow...).
 if test "$system" = i686-cygwin; then exit 0; fi
 
+clearStore
+
 max=2500
 
 reference=$NIX_STORE_DIR/abcdef
@@ -25,34 +27,11 @@ echo "registering..."
 
 time $nixstore --register-validity < $TEST_ROOT/reg_info
 
-oldTime=$(cat test-tmp/db/info/1 | grep Registered-At)
-
-echo "sleeping..."
-
-sleep 2
-
-echo "reregistering..."
-
-time $nixstore --register-validity --reregister < $TEST_ROOT/reg_info
-
-newTime=$(cat test-tmp/db/info/1 | grep Registered-At)
-
-if test "$newTime" != "$oldTime"; then
-    echo "reregistration changed original registration time"
-    exit 1
-fi
-
-if test "$(cat test-tmp/db/referrer/1 | wc -w)" -ne 1; then
-    echo "reregistration duplicated referrers"
-    exit 1
-fi
-
 echo "collecting garbage..."
 ln -sfn $reference "$NIX_STATE_DIR"/gcroots/ref
 time $nixstore --gc
 
-if test "$(cat test-tmp/db/referrer/abcdef | wc -w)" -ne 0; then
+if test "$(sqlite3 ./test-tmp/db/db.sqlite 'select count(*) from Refs')" -ne 0; then
     echo "referrers not cleaned up"
     exit 1
 fi
-