aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/local-store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/local-store.cc')
-rw-r--r--src/libstore/local-store.cc117
1 files changed, 61 insertions, 56 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index bfb253bc1..7e205a9bf 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -205,52 +205,43 @@ LocalStore::LocalStore()
lockFile(globalLock, ltRead, true);
}
- /* Open the Nix database. */
- if (sqlite3_open_v2((nixDBPath + "/db.sqlite").c_str(), &db.db,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
- throw Error("cannot open SQLite database");
-
- 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 */
-
- /* Whether SQLite should fsync(). "Normal" synchronous mode
- should be safe enough. If the user asks for it, don't sync at
- all. This can cause database corruption if the system
- crashes. */
- string syncMode = queryBoolSetting("fsync-metadata", true) ? "normal" : "off";
- if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 0, 0, 0) != SQLITE_OK)
- throw SQLiteError(db, "setting synchronous mode");
-
- /* Use `truncate' journal mode, which should be a bit faster. */
- if (sqlite3_exec(db, "pragma main.journal_mode = truncate;", 0, 0, 0) != SQLITE_OK)
- throw SQLiteError(db, "setting journal mode");
-
/* Check the current database schema and if necessary do an
- upgrade. !!! Race condition: several processes could start
- the upgrade at the same time. */
+ upgrade. */
int curSchema = getSchema();
if (curSchema > nixSchemaVersion)
throw Error(format("current Nix store schema is version %1%, but I only support %2%")
% curSchema % nixSchemaVersion);
- if (curSchema == 0) { /* new store */
+
+ else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
- initSchema();
+ openDB(true);
+ writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
+ }
+
+ else if (curSchema < nixSchemaVersion) {
+ if (curSchema < 5)
+ throw Error(
+ "Your Nix store has a database in Berkeley DB format,\n"
+ "which is no longer supported. To convert to the new format,\n"
+ "please upgrade Nix to version 0.12 first.");
+
+ if (!lockFile(globalLock, ltWrite, false)) {
+ printMsg(lvlError, "waiting for exclusive access to the Nix store...");
+ lockFile(globalLock, ltWrite, true);
+ }
+
+ /* Get the schema version again, because another process may
+ have performed the upgrade already. */
+ curSchema = getSchema();
+
+ if (curSchema < 6) upgradeStore6();
+
writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
+
+ lockFile(globalLock, ltRead, true);
}
- else if (curSchema == 1) throw Error("your Nix store is no longer supported");
- else if (curSchema < 5)
- throw Error(
- "Your Nix store has a database in Berkeley DB format,\n"
- "which is no longer supported. To convert to the new format,\n"
- "please upgrade Nix to version 0.12 first.");
- else if (curSchema < 6) upgradeStore6();
- else prepareStatements();
+
+ else openDB(false);
}
@@ -280,19 +271,42 @@ int LocalStore::getSchema()
}
-void LocalStore::initSchema()
+void LocalStore::openDB(bool create)
{
-#include "schema.sql.hh"
+ /* Open the Nix database. */
+ if (sqlite3_open_v2((nixDBPath + "/db.sqlite").c_str(), &db.db,
+ SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
+ throw Error("cannot open SQLite database");
- if (sqlite3_exec(db, (const char *) schema, 0, 0, 0) != SQLITE_OK)
- throw SQLiteError(db, "initialising database schema");
+ if (sqlite3_busy_timeout(db, 60000) != SQLITE_OK)
+ throw SQLiteError(db, "setting timeout");
- prepareStatements();
-}
+ 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 */
+
+ /* Whether SQLite should fsync(). "Normal" synchronous mode
+ should be safe enough. If the user asks for it, don't sync at
+ all. This can cause database corruption if the system
+ crashes. */
+ string syncMode = queryBoolSetting("fsync-metadata", true) ? "normal" : "off";
+ if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 0, 0, 0) != SQLITE_OK)
+ throw SQLiteError(db, "setting synchronous mode");
+ /* Use `truncate' journal mode, which should be a bit faster. */
+ if (sqlite3_exec(db, "pragma main.journal_mode = truncate;", 0, 0, 0) != SQLITE_OK)
+ throw SQLiteError(db, "setting journal mode");
-void LocalStore::prepareStatements()
-{
+ /* Initialise the database schema, if necessary. */
+ if (create) {
+#include "schema.sql.hh"
+ if (sqlite3_exec(db, (const char *) schema, 0, 0, 0) != SQLITE_OK)
+ throw SQLiteError(db, "initialising database schema");
+ }
+
+ /* Prepare SQL statements. */
stmtRegisterValidPath.create(db,
"insert or replace into ValidPaths (path, hash, registrationTime, deriver) values (?, ?, ?, ?);");
stmtAddReference.create(db,
@@ -1225,14 +1239,9 @@ ValidPathInfo LocalStore::queryPathInfoOld(const Path & path)
/* Upgrade from schema 5 (Nix 0.12) to schema 6 (Nix >= 0.15). */
void LocalStore::upgradeStore6()
{
- if (!lockFile(globalLock, ltWrite, false)) {
- printMsg(lvlError, "waiting for exclusive access to the Nix store...");
- lockFile(globalLock, ltWrite, true);
- }
-
printMsg(lvlError, "upgrading Nix store to new schema (this may take a while)...");
- initSchema();
+ openDB(true);
PathSet validPaths = queryValidPathsOld();
@@ -1256,10 +1265,6 @@ void LocalStore::upgradeStore6()
std::cerr << "\n";
txn.commit();
-
- writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
-
- lockFile(globalLock, ltRead, true);
}