diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 3e7273d42..d3f0c4787 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -181,24 +181,20 @@ LocalStore::LocalStore(const Params & params) if (curSchema < 8) { SQLiteTxn txn(state->db); - if (sqlite3_exec(state->db, "alter table ValidPaths add column ultimate integer", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "upgrading database schema"); - if (sqlite3_exec(state->db, "alter table ValidPaths add column sigs text", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "upgrading database schema"); + state->db.exec("alter table ValidPaths add column ultimate integer"); + state->db.exec("alter table ValidPaths add column sigs text"); txn.commit(); } if (curSchema < 9) { SQLiteTxn txn(state->db); - if (sqlite3_exec(state->db, "drop table FailedPaths", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "upgrading database schema"); + state->db.exec("drop table FailedPaths"); txn.commit(); } if (curSchema < 10) { SQLiteTxn txn(state->db); - if (sqlite3_exec(state->db, "alter table ValidPaths add column ca text", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "upgrading database schema"); + state->db.exec("alter table ValidPaths add column ca text"); txn.commit(); } @@ -286,8 +282,7 @@ void LocalStore::openDB(State & state, bool create) if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK) throwSQLiteError(db, "setting timeout"); - if (sqlite3_exec(db, "pragma foreign_keys = 1;", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(db, "enabling foreign keys"); + db.exec("pragma foreign_keys = 1"); /* !!! check whether sqlite has been built with foreign key support */ @@ -297,8 +292,7 @@ void LocalStore::openDB(State & state, bool create) all. This can cause database corruption if the system crashes. */ string syncMode = settings.fsyncMetadata ? "normal" : "off"; - if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 0, 0, 0) != SQLITE_OK) - throwSQLiteError(db, "setting synchronous mode"); + db.exec("pragma synchronous = " + syncMode); /* Set the SQLite journal mode. WAL mode is fastest, so it's the default. */ @@ -326,8 +320,7 @@ void LocalStore::openDB(State & state, bool create) const char * schema = #include "schema.sql.hh" ; - if (sqlite3_exec(db, (const char *) schema, 0, 0, 0) != SQLITE_OK) - throwSQLiteError(db, "initialising database schema"); + db.exec(schema); } } @@ -1297,9 +1290,7 @@ void LocalStore::upgradeStore7() void LocalStore::vacuumDB() { auto state(_state.lock()); - - if (sqlite3_exec(state->db, "vacuum;", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "vacuuming SQLite database"); + state->db.exec("vacuum"); } diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index 172a918ff..d28ff42c7 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -78,21 +78,16 @@ public: Path dbPath = getCacheDir() + "/nix/binary-cache-v5.sqlite"; createDirs(dirOf(dbPath)); - if (sqlite3_open_v2(dbPath.c_str(), &state->db.db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK) - throw Error(format("cannot open store cache ‘%s’") % dbPath); + state->db = SQLite(dbPath); if (sqlite3_busy_timeout(state->db, 60 * 60 * 1000) != SQLITE_OK) throwSQLiteError(state->db, "setting timeout"); // We can always reproduce the cache. - if (sqlite3_exec(state->db, "pragma synchronous = off", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "making database asynchronous"); - if (sqlite3_exec(state->db, "pragma main.journal_mode = truncate", 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "setting journal mode"); + state->db.exec("pragma synchronous = off"); + state->db.exec("pragma main.journal_mode = truncate"); - if (sqlite3_exec(state->db, schema, 0, 0, 0) != SQLITE_OK) - throwSQLiteError(state->db, "initialising database schema"); + state->db.exec(schema); state->insertCache.create(state->db, "insert or replace into BinaryCaches(url, timestamp, storeDir, wantMassQuery, priority) values (?, ?, ?, ?, ?)"); diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 816f9984d..ea0b843f5 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -35,6 +35,13 @@ namespace nix { throw SQLiteError(format("%1%: %2%") % f.str() % sqlite3_errmsg(db)); } +SQLite::SQLite(const Path & path) +{ + if (sqlite3_open_v2(path.c_str(), &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK) + throw Error(format("cannot open SQLite database ‘%s’") % path); +} + SQLite::~SQLite() { try { @@ -45,6 +52,12 @@ SQLite::~SQLite() } } +void SQLite::exec(const std::string & stmt) +{ + if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK) + throwSQLiteError(db, format("executing SQLite statement ‘%s’") % stmt); +} + void SQLiteStmt::create(sqlite3 * db, const string & s) { checkInterrupt(); diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index d6b4a8d91..7c1ed5382 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -13,10 +13,16 @@ namespace nix { /* RAII wrapper to close a SQLite database automatically. */ struct SQLite { - sqlite3 * db; - SQLite() { db = 0; } + sqlite3 * db = 0; + SQLite() { } + SQLite(const Path & path); + SQLite(const SQLite & from) = delete; + SQLite& operator = (const SQLite & from) = delete; + SQLite& operator = (SQLite && from) { db = from.db; from.db = 0; return *this; } ~SQLite(); operator sqlite3 * () { return db; } + + void exec(const std::string & stmt); }; /* RAII wrapper to create and destroy SQLite prepared statements. */