* Foreign key support in SQLite is not a persistent setting, so enable
it at startup. * Implement negative caching. Now `make check' passes.
This commit is contained in:
parent
9c9a88e9e2
commit
1930570ad9
4 changed files with 25 additions and 29 deletions
|
@ -209,6 +209,9 @@ LocalStore::LocalStore()
|
||||||
if (sqlite3_busy_timeout(db, 60000) != SQLITE_OK)
|
if (sqlite3_busy_timeout(db, 60000) != SQLITE_OK)
|
||||||
throw SQLiteError(db, "setting timeout");
|
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
|
/* !!! check whether sqlite has been built with foreign key
|
||||||
support */
|
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 = ?);");
|
"select path from Refs join ValidPaths on referrer = id where reference = (select id from ValidPaths where path = ?);");
|
||||||
stmtInvalidatePath.create(db,
|
stmtInvalidatePath.create(db,
|
||||||
"delete from ValidPaths where path = ?;");
|
"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)
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,8 @@ private:
|
||||||
SQLiteStmt stmtQueryReferences;
|
SQLiteStmt stmtQueryReferences;
|
||||||
SQLiteStmt stmtQueryReferrers;
|
SQLiteStmt stmtQueryReferrers;
|
||||||
SQLiteStmt stmtInvalidatePath;
|
SQLiteStmt stmtInvalidatePath;
|
||||||
|
SQLiteStmt stmtRegisterFailedPath;
|
||||||
|
SQLiteStmt stmtHasPathFailed;
|
||||||
|
|
||||||
int getSchema();
|
int getSchema();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
pragma foreign_keys = on;
|
|
||||||
|
|
||||||
create table if not exists ValidPaths (
|
create table if not exists ValidPaths (
|
||||||
id integer primary key autoincrement not null,
|
id integer primary key autoincrement not null,
|
||||||
path text unique 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 IndexReferrer on Refs(referrer);
|
||||||
create index if not exists IndexReference on Refs(reference);
|
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,
|
path text primary key not null,
|
||||||
time integer not null
|
time integer not null
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,8 @@ source common.sh
|
||||||
# This takes way to long on Cygwin (because process creation is so slow...).
|
# This takes way to long on Cygwin (because process creation is so slow...).
|
||||||
if test "$system" = i686-cygwin; then exit 0; fi
|
if test "$system" = i686-cygwin; then exit 0; fi
|
||||||
|
|
||||||
|
clearStore
|
||||||
|
|
||||||
max=2500
|
max=2500
|
||||||
|
|
||||||
reference=$NIX_STORE_DIR/abcdef
|
reference=$NIX_STORE_DIR/abcdef
|
||||||
|
@ -25,34 +27,11 @@ echo "registering..."
|
||||||
|
|
||||||
time $nixstore --register-validity < $TEST_ROOT/reg_info
|
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..."
|
echo "collecting garbage..."
|
||||||
ln -sfn $reference "$NIX_STATE_DIR"/gcroots/ref
|
ln -sfn $reference "$NIX_STATE_DIR"/gcroots/ref
|
||||||
time $nixstore --gc
|
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"
|
echo "referrers not cleaned up"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue