* Implement queryPathInfo().

This commit is contained in:
Eelco Dolstra 2010-02-18 15:52:57 +00:00
parent 885e22b16e
commit 77cb9e3fb1
2 changed files with 49 additions and 51 deletions

View file

@ -236,7 +236,10 @@ void LocalStore::prepareStatements()
"insert into ValidPaths (path, hash, registrationTime, deriver) values (?, ?, ?, ?);"); "insert into ValidPaths (path, hash, registrationTime, deriver) values (?, ?, ?, ?);");
stmtAddReference.create(db, stmtAddReference.create(db,
"insert into Refs (referrer, reference) values (?, ?);"); "insert into Refs (referrer, reference) values (?, ?);");
stmtIsValidPath.create(db, "select 1 from ValidPaths where path = ?;"); stmtQueryPathInfo.create(db,
"select id, hash, registrationTime, deriver from ValidPaths where path = ?;");
stmtQueryReferences.create(db,
"select path from Refs join ValidPaths on reference = id where referrer = ?;");
} }
@ -418,65 +421,59 @@ Hash parseHashField(const Path & path, const string & s)
} }
ValidPathInfo LocalStore::queryPathInfo(const Path & path, bool ignoreErrors) ValidPathInfo LocalStore::queryPathInfo(const Path & path)
{ {
#if 0
ValidPathInfo res; ValidPathInfo res;
res.path = path; res.path = path;
assertStorePath(path); assertStorePath(path);
if (!isValidPath(path)) /* Get the path info. */
throw Error(format("path `%1%' is not valid") % path); stmtQueryPathInfo.reset();
/* Read the info file. */ if (sqlite3_bind_text(stmtQueryPathInfo, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
Path infoFile = infoFileFor(path); throw SQLiteError(db, "binding argument");
if (!pathExists(infoFile))
throw Error(format("path `%1%' is not valid") % path);
string info = readFile(infoFile);
/* Parse it. */ int r = sqlite3_step(stmtQueryPathInfo);
Strings lines = tokenizeString(info, "\n"); if (r == SQLITE_DONE) throw Error(format("path `%1%' is not valid") % path);
if (r != SQLITE_ROW) throw SQLiteError(db, "querying path in database");
foreach (Strings::iterator, i, lines) { unsigned int id = sqlite3_column_int(stmtQueryPathInfo, 0);
string::size_type p = i->find(':');
if (p == string::npos) { const char * s = (const char *) sqlite3_column_text(stmtQueryPathInfo, 1);
if (!ignoreErrors) assert(s);
throw Error(format("corrupt line in `%1%': %2%") % infoFile % *i); res.hash = parseHashField(path, s);
continue; /* bad line */
} res.registrationTime = sqlite3_column_int(stmtQueryPathInfo, 2);
string name(*i, 0, p);
string value(*i, p + 2); s = (const char *) sqlite3_column_text(stmtQueryPathInfo, 3);
if (name == "References") { if (s) res.deriver = s;
Strings refs = tokenizeString(value, " ");
res.references = PathSet(refs.begin(), refs.end()); /* Get the references. */
} else if (name == "Deriver") { stmtQueryReferences.reset();
res.deriver = value;
} else if (name == "Hash") { if (sqlite3_bind_int(stmtQueryReferences, 1, id) != SQLITE_OK)
try { throw SQLiteError(db, "binding argument");
res.hash = parseHashField(path, value);
} catch (Error & e) { while ((r = sqlite3_step(stmtQueryReferences)) == SQLITE_ROW) {
if (!ignoreErrors) throw; s = (const char *) sqlite3_column_text(stmtQueryReferences, 0);
printMsg(lvlError, format("cannot parse hash field in `%1%': %2%") % infoFile % e.msg()); assert(s);
} res.references.insert(s);
} else if (name == "Registered-At") {
int n = 0;
string2Int(value, n);
res.registrationTime = n;
}
} }
if (r != SQLITE_DONE)
throw Error(format("error getting references of `%1%'") % path);
return res; return res;
#endif
} }
bool LocalStore::isValidPath(const Path & path) bool LocalStore::isValidPath(const Path & path)
{ {
stmtIsValidPath.reset(); stmtQueryPathInfo.reset();
if (sqlite3_bind_text(stmtIsValidPath, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) if (sqlite3_bind_text(stmtQueryPathInfo, 1, path.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument"); throw SQLiteError(db, "binding argument");
int res = sqlite3_step(stmtIsValidPath); 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");
return res == SQLITE_ROW; return res == SQLITE_ROW;
@ -1253,18 +1250,18 @@ void LocalStore::upgradeStore6()
stmtRegisterValidPath.reset(); stmtRegisterValidPath.reset();
if (sqlite3_bind_text(stmtRegisterValidPath, 1, i->c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) if (sqlite3_bind_text(stmtRegisterValidPath, 1, i->c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument 1"); throw SQLiteError(db, "binding argument");
string h = "sha256:" + printHash(info.hash); string h = "sha256:" + printHash(info.hash);
if (sqlite3_bind_text(stmtRegisterValidPath, 2, h.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) if (sqlite3_bind_text(stmtRegisterValidPath, 2, h.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument 2"); throw SQLiteError(db, "binding argument");
if (sqlite3_bind_int(stmtRegisterValidPath, 3, info.registrationTime) != SQLITE_OK) if (sqlite3_bind_int(stmtRegisterValidPath, 3, info.registrationTime) != SQLITE_OK)
throw SQLiteError(db, "binding argument 3"); throw SQLiteError(db, "binding argument");
if (info.deriver != "") { if (info.deriver != "") {
if (sqlite3_bind_text(stmtRegisterValidPath, 4, info.deriver.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK) if (sqlite3_bind_text(stmtRegisterValidPath, 4, info.deriver.c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
throw SQLiteError(db, "binding argument 4"); throw SQLiteError(db, "binding argument");
} else { } else {
if (sqlite3_bind_null(stmtRegisterValidPath, 4) != SQLITE_OK) if (sqlite3_bind_null(stmtRegisterValidPath, 4) != SQLITE_OK)
throw SQLiteError(db, "binding argument 4"); throw SQLiteError(db, "binding argument");
} }
if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE) if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE)
throw SQLiteError(db, "registering valid path in database"); throw SQLiteError(db, "registering valid path in database");
@ -1282,11 +1279,11 @@ void LocalStore::upgradeStore6()
foreach (PathSet::iterator, j, info.references) { foreach (PathSet::iterator, j, info.references) {
stmtAddReference.reset(); stmtAddReference.reset();
if (sqlite3_bind_int(stmtAddReference, 1, pathToId[*i]) != SQLITE_OK) if (sqlite3_bind_int(stmtAddReference, 1, pathToId[*i]) != SQLITE_OK)
throw SQLiteError(db, "binding argument 1"); throw SQLiteError(db, "binding argument");
if (pathToId.find(*j) == pathToId.end()) if (pathToId.find(*j) == pathToId.end())
throw Error(format("path `%1%' referenced by `%2%' is invalid") % *j % *i); throw Error(format("path `%1%' referenced by `%2%' is invalid") % *j % *i);
if (sqlite3_bind_int(stmtAddReference, 2, pathToId[*j]) != SQLITE_OK) if (sqlite3_bind_int(stmtAddReference, 2, pathToId[*j]) != SQLITE_OK)
throw SQLiteError(db, "binding argument 2"); 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");
} }

View file

@ -188,7 +188,8 @@ private:
/* Some precompiled SQLite statements. */ /* Some precompiled SQLite statements. */
SQLiteStmt stmtRegisterValidPath; SQLiteStmt stmtRegisterValidPath;
SQLiteStmt stmtAddReference; SQLiteStmt stmtAddReference;
SQLiteStmt stmtIsValidPath; SQLiteStmt stmtQueryPathInfo;
SQLiteStmt stmtQueryReferences;
int getSchema(); int getSchema();
@ -198,7 +199,7 @@ private:
void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false); void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false);
ValidPathInfo queryPathInfo(const Path & path, bool ignoreErrors = false); ValidPathInfo queryPathInfo(const Path & path);
void appendReferrer(const Path & from, const Path & to, bool lock); void appendReferrer(const Path & from, const Path & to, bool lock);