* Implement more stuff.

This commit is contained in:
Eelco Dolstra 2010-02-19 16:43:25 +00:00
parent 762cee72cc
commit 9c9a88e9e2
2 changed files with 50 additions and 52 deletions

View File

@ -60,6 +60,7 @@ void SQLiteStmt::reset()
assert(stmt); assert(stmt);
if (sqlite3_reset(stmt) != SQLITE_OK) if (sqlite3_reset(stmt) != SQLITE_OK)
throw SQLiteError(db, "resetting statement"); throw SQLiteError(db, "resetting statement");
curArg = 1;
} }
@ -74,6 +75,27 @@ SQLiteStmt::~SQLiteStmt()
} }
void SQLiteStmt::bind(const string & value)
{
if (sqlite3_bind_text(stmt, curArg++, value.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
}
void SQLiteStmt::bind(int value)
{
if (sqlite3_bind_int(stmt, curArg++, value) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
}
void SQLiteStmt::bind()
{
if (sqlite3_bind_null(stmt, curArg++) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
}
/* Helper class to ensure that prepared statements are reset when /* Helper class to ensure that prepared statements are reset when
leaving the scope that uses them. Unfinished prepared statements leaving the scope that uses them. Unfinished prepared statements
prevent transactions from being aborted, and can cause locks to be prevent transactions from being aborted, and can cause locks to be
@ -264,6 +286,8 @@ void LocalStore::prepareStatements()
"select path from Refs join ValidPaths on reference = id where referrer = ?;"); "select path from Refs join ValidPaths on reference = id where referrer = ?;");
stmtQueryReferrers.create(db, stmtQueryReferrers.create(db,
"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,
"delete from ValidPaths where path = ?;");
} }
@ -357,20 +381,13 @@ void LocalStore::registerValidPath(const Path & path,
unsigned long long LocalStore::addValidPath(const ValidPathInfo & info) unsigned long long LocalStore::addValidPath(const ValidPathInfo & info)
{ {
SQLiteStmtUse use(stmtRegisterValidPath); SQLiteStmtUse use(stmtRegisterValidPath);
if (sqlite3_bind_text(stmtRegisterValidPath, 1, info.path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) stmtRegisterValidPath.bind(info.path);
throw SQLiteError(db, "binding argument"); stmtRegisterValidPath.bind("sha256:" + printHash(info.hash));
string h = "sha256:" + printHash(info.hash); stmtRegisterValidPath.bind(info.registrationTime);
if (sqlite3_bind_text(stmtRegisterValidPath, 2, h.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) if (info.deriver != "")
throw SQLiteError(db, "binding argument"); stmtRegisterValidPath.bind(info.deriver);
if (sqlite3_bind_int(stmtRegisterValidPath, 3, info.registrationTime) != SQLITE_OK) else
throw SQLiteError(db, "binding argument"); stmtRegisterValidPath.bind(); // null
if (info.deriver != "") {
if (sqlite3_bind_text(stmtRegisterValidPath, 4, info.deriver.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
} else {
if (sqlite3_bind_null(stmtRegisterValidPath, 4) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
}
if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE) if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE)
throw SQLiteError(db, format("registering valid path `%1%' in database") % info.path); throw SQLiteError(db, format("registering valid path `%1%' in database") % info.path);
return sqlite3_last_insert_rowid(db); return sqlite3_last_insert_rowid(db);
@ -380,10 +397,8 @@ unsigned long long LocalStore::addValidPath(const ValidPathInfo & info)
void LocalStore::addReference(unsigned long long referrer, unsigned long long reference) void LocalStore::addReference(unsigned long long referrer, unsigned long long reference)
{ {
SQLiteStmtUse use(stmtAddReference); SQLiteStmtUse use(stmtAddReference);
if (sqlite3_bind_int(stmtAddReference, 1, referrer) != SQLITE_OK) stmtAddReference.bind(referrer);
throw SQLiteError(db, "binding argument"); stmtAddReference.bind(reference);
if (sqlite3_bind_int(stmtAddReference, 2, reference) != SQLITE_OK)
throw SQLiteError(db, "binding argument");
if (sqlite3_step(stmtAddReference) != SQLITE_DONE) if (sqlite3_step(stmtAddReference) != SQLITE_DONE)
throw SQLiteError(db, "adding reference to database"); throw SQLiteError(db, "adding reference to database");
} }
@ -443,9 +458,8 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
/* Get the path info. */ /* Get the path info. */
SQLiteStmtUse use1(stmtQueryPathInfo); SQLiteStmtUse use1(stmtQueryPathInfo);
if (sqlite3_bind_text(stmtQueryPathInfo, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) stmtQueryPathInfo.bind(path);
throw SQLiteError(db, "binding argument");
int r = sqlite3_step(stmtQueryPathInfo); int r = sqlite3_step(stmtQueryPathInfo);
if (r == SQLITE_DONE) throw Error(format("path `%1%' is not valid") % path); if (r == SQLITE_DONE) throw Error(format("path `%1%' is not valid") % path);
@ -465,8 +479,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
/* Get the references. */ /* Get the references. */
SQLiteStmtUse use2(stmtQueryReferences); SQLiteStmtUse use2(stmtQueryReferences);
if (sqlite3_bind_int(stmtQueryReferences, 1, info.id) != SQLITE_OK) stmtQueryReferences.bind(info.id);
throw SQLiteError(db, "binding argument");
while ((r = sqlite3_step(stmtQueryReferences)) == SQLITE_ROW) { while ((r = sqlite3_step(stmtQueryReferences)) == SQLITE_ROW) {
s = (const char *) sqlite3_column_text(stmtQueryReferences, 0); s = (const char *) sqlite3_column_text(stmtQueryReferences, 0);
@ -484,8 +497,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
bool LocalStore::isValidPath(const Path & path) bool LocalStore::isValidPath(const Path & path)
{ {
SQLiteStmtUse use(stmtQueryPathInfo); SQLiteStmtUse use(stmtQueryPathInfo);
if (sqlite3_bind_text(stmtQueryPathInfo, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) stmtQueryPathInfo.bind(path);
throw SQLiteError(db, "binding argument");
int res = sqlite3_step(stmtQueryPathInfo); int res = sqlite3_step(stmtQueryPathInfo);
if (res != SQLITE_DONE && res != SQLITE_ROW) if (res != SQLITE_DONE && res != SQLITE_ROW)
throw SQLiteError(db, "querying path in database"); throw SQLiteError(db, "querying path in database");
@ -528,8 +540,7 @@ void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
SQLiteStmtUse use(stmtQueryReferrers); SQLiteStmtUse use(stmtQueryReferrers);
if (sqlite3_bind_text(stmtQueryReferrers, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) stmtQueryReferrers.bind(path);
throw SQLiteError(db, "binding argument");
int r; int r;
while ((r = sqlite3_step(stmtQueryReferrers)) == SQLITE_ROW) { while ((r = sqlite3_step(stmtQueryReferrers)) == SQLITE_ROW) {
@ -699,26 +710,17 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
there are no referrers. */ there are no referrers. */
void LocalStore::invalidatePath(const Path & path) void LocalStore::invalidatePath(const Path & path)
{ {
throw Error("not implemented");
#if 0
debug(format("invalidating path `%1%'") % path); debug(format("invalidating path `%1%'") % path);
SQLiteStmtUse use(stmtInvalidatePath);
ValidPathInfo info; stmtInvalidatePath.bind(path);
if (pathExists(infoFileFor(path))) { if (sqlite3_step(stmtInvalidatePath) != SQLITE_DONE)
info = queryPathInfo(path); throw SQLiteError(db, format("invalidating path `%1%' in database") % path);
/* Remove the info file. */ /* Note that the foreign key constraints on the Refs table take
Path p = infoFileFor(path); care of deleting the references entries for `path'. */
if (unlink(p.c_str()) == -1)
throw SysError(format("unlinking `%1%'") % p);
}
/* Remove the referrers file for `path'. */
Path p = referrersFileFor(path);
if (pathExists(p) && unlink(p.c_str()) == -1)
throw SysError(format("unlinking `%1%'") % p);
#endif
} }
@ -1022,19 +1024,11 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
void LocalStore::deleteFromStore(const Path & path, unsigned long long & bytesFreed, void LocalStore::deleteFromStore(const Path & path, unsigned long long & bytesFreed,
unsigned long long & blocksFreed) unsigned long long & blocksFreed)
{ {
throw Error("not implemented");
#if 0
bytesFreed = 0; bytesFreed = 0;
assertStorePath(path); assertStorePath(path);
if (isValidPath(path)) { if (isValidPath(path)) {
/* Acquire a lock on the referrers file to prevent new
referrers to this path from appearing while we're deleting
it. */
PathLocks referrersLock(singleton<PathSet, Path>(referrersFileFor(path)));
referrersLock.setDeletion(true);
PathSet referrers; queryReferrers(path, referrers); PathSet referrers; queryReferrers(path, referrers);
referrers.erase(path); /* ignore self-references */ referrers.erase(path); /* ignore self-references */
if (!referrers.empty()) if (!referrers.empty())
@ -1044,7 +1038,6 @@ void LocalStore::deleteFromStore(const Path & path, unsigned long long & bytesFr
} }
deletePathWrapped(path, bytesFreed, blocksFreed); deletePathWrapped(path, bytesFreed, blocksFreed);
#endif
} }

View File

@ -61,11 +61,15 @@ struct SQLiteStmt
{ {
sqlite3 * db; sqlite3 * db;
sqlite3_stmt * stmt; sqlite3_stmt * stmt;
unsigned int curArg;
SQLiteStmt() { stmt = 0; } SQLiteStmt() { stmt = 0; }
void create(sqlite3 * db, const string & s); void create(sqlite3 * db, const string & s);
void reset(); void reset();
~SQLiteStmt(); ~SQLiteStmt();
operator sqlite3_stmt * () { return stmt; } operator sqlite3_stmt * () { return stmt; }
void bind(const string & value);
void bind(int value);
void bind();
}; };
@ -191,6 +195,7 @@ private:
SQLiteStmt stmtQueryPathInfo; SQLiteStmt stmtQueryPathInfo;
SQLiteStmt stmtQueryReferences; SQLiteStmt stmtQueryReferences;
SQLiteStmt stmtQueryReferrers; SQLiteStmt stmtQueryReferrers;
SQLiteStmt stmtInvalidatePath;
int getSchema(); int getSchema();