* The database needs a trigger to get rid of self-references to

prevent a foreign key constraint violation on the Refs table when
  deleting a path.
This commit is contained in:
Eelco Dolstra 2010-02-22 14:18:55 +00:00
parent c4d388add4
commit 9cda616949
2 changed files with 20 additions and 2 deletions

View File

@ -109,7 +109,11 @@ struct SQLiteStmtUse
}
~SQLiteStmtUse()
{
stmt.reset();
try {
stmt.reset();
} catch (...) {
ignoreException();
}
}
};
@ -798,6 +802,8 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
void LocalStore::invalidatePath(const Path & path)
{
debug(format("invalidating path `%1%'") % path);
SQLiteTxn txn(db);
SQLiteStmtUse use(stmtInvalidatePath);
@ -807,7 +813,9 @@ void LocalStore::invalidatePath(const Path & path)
throw SQLiteError(db, format("invalidating path `%1%' in database") % path);
/* Note that the foreign key constraints on the Refs table take
care of deleting the references entries for `path'. */
care of deleting the references entries for `path'. */
txn.commit();
}

View File

@ -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);
-- Paths can refer to themselves, causing a tuple (N, N) in the Refs
-- table. This causes a deletion of the corresponding row in
-- ValidPaths to cause a foreign key constraint violation (due to `on
-- delete restrict' on the `reference' column). Therefore, explicitly
-- get rid of self-references.
create trigger DeleteSelfRefs before delete on ValidPaths
begin
delete from Refs where referrer = old.id and reference = old.id;
end;
create table if not exists DerivationOutputs (
drv integer not null,
id text not null, -- symbolic output id, usually "out"