From 751a0f40bc1cf697d73c24d4d3f540988cbb159b Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Thu, 22 Jan 2026 11:34:13 -0500 Subject: [PATCH] libstore: add SQLite::Settings struct for explicit configuration Progress on #5638 Replace the SQLite constructor's mode parameter with a Settings struct that includes both the open mode and useWAL flag. This makes the dependency on useSQLiteWAL explicit at call sites rather than having it read from the global settings inside the constructor. All call sites now explicitly pass settings.useSQLiteWAL, preparing for downstream work where stores can pass their own settings instead of relying on the global. --- src/libexpr/eval-cache.cc | 2 +- src/libfetchers/cache.cc | 2 +- src/libstore-tests/nar-info-disk-cache.cc | 3 ++- src/libstore/include/nix/store/sqlite.hh | 8 +++++++- src/libstore/local-store.cc | 2 +- src/libstore/nar-info-disk-cache.cc | 2 +- src/libstore/sqlite.cc | 8 ++++---- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 90de4b69d..4f6c5fe8e 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -75,7 +75,7 @@ struct AttrDb auto dbPath = cacheDir / (fingerprint.to_string(HashFormat::Base16, false) + ".sqlite"); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); state->db.isCache(); state->db.exec(schema); diff --git a/src/libfetchers/cache.cc b/src/libfetchers/cache.cc index 183f106a5..a302d77e1 100644 --- a/src/libfetchers/cache.cc +++ b/src/libfetchers/cache.cc @@ -41,7 +41,7 @@ struct CacheImpl : Cache auto dbPath = (getCacheDir() / "fetcher-cache-v4.sqlite").string(); createDirs(dirOf(dbPath)); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); state->db.isCache(); state->db.exec(schema); diff --git a/src/libstore-tests/nar-info-disk-cache.cc b/src/libstore-tests/nar-info-disk-cache.cc index b925a4a1e..eb1d04b5e 100644 --- a/src/libstore-tests/nar-info-disk-cache.cc +++ b/src/libstore-tests/nar-info-disk-cache.cc @@ -2,6 +2,7 @@ #include #include +#include "nix/store/globals.hh" #include "nix/store/sqlite.hh" #include @@ -48,7 +49,7 @@ TEST(NarInfoDiskCacheImpl, create_and_read) // We're going to pay special attention to the id field because we had a bug // that changed it. - db = SQLite(dbPath); + db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); getIds.create(db, "select id from BinaryCaches where url = 'http://foo'"); { diff --git a/src/libstore/include/nix/store/sqlite.hh b/src/libstore/include/nix/store/sqlite.hh index 3495c0bd1..9de569a37 100644 --- a/src/libstore/include/nix/store/sqlite.hh +++ b/src/libstore/include/nix/store/sqlite.hh @@ -42,7 +42,13 @@ struct SQLite SQLite() {} - SQLite(const std::filesystem::path & path, SQLiteOpenMode mode = SQLiteOpenMode::Normal); + struct Settings + { + SQLiteOpenMode mode = SQLiteOpenMode::Normal; + bool useWAL; + }; + + SQLite(const std::filesystem::path & path, Settings && settings); SQLite(const SQLite & from) = delete; SQLite & operator=(const SQLite & from) = delete; diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index fff9adee1..17f0216b5 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -481,7 +481,7 @@ void LocalStore::openDB(State & state, bool create) auto openMode = config->readOnly ? SQLiteOpenMode::Immutable : create ? SQLiteOpenMode::Normal : SQLiteOpenMode::NoCreate; - state.db = SQLite(std::filesystem::path(dbDir) / "db.sqlite", openMode); + state.db = SQLite(std::filesystem::path(dbDir) / "db.sqlite", {.mode = openMode, .useWAL = settings.useSQLiteWAL}); #ifdef __CYGWIN__ /* The cygwin version of sqlite3 has a patch which calls diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index bf7ab4bf9..fb78a0739 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -92,7 +92,7 @@ public: createDirs(dirOf(dbPath)); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); state->db.isCache(); diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 9ce833368..498e2deda 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -62,7 +62,7 @@ static void traceSQL(void * x, const char * sql) notice("SQL<[%1%]>", sql); }; -SQLite::SQLite(const std::filesystem::path & path, SQLiteOpenMode mode) +SQLite::SQLite(const std::filesystem::path & path, Settings && settings) { // Work around a ZFS issue where SQLite's truncate() call on // db.sqlite-shm can randomly take up to a few seconds. See @@ -89,10 +89,10 @@ SQLite::SQLite(const std::filesystem::path & path, SQLiteOpenMode mode) // useSQLiteWAL also indicates what virtual file system we need. Using // `unix-dotfile` is needed on NFS file systems and on Windows' Subsystem // for Linux (WSL) where useSQLiteWAL should be false by default. - const char * vfs = settings.useSQLiteWAL ? 0 : "unix-dotfile"; - bool immutable = mode == SQLiteOpenMode::Immutable; + const char * vfs = settings.useWAL ? 0 : "unix-dotfile"; + bool immutable = settings.mode == SQLiteOpenMode::Immutable; int flags = immutable ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE; - if (mode == SQLiteOpenMode::Normal) + if (settings.mode == SQLiteOpenMode::Normal) flags |= SQLITE_OPEN_CREATE; auto uri = "file:" + percentEncode(path.string()) + "?immutable=" + (immutable ? "1" : "0"); int ret = sqlite3_open_v2(uri.c_str(), &db, SQLITE_OPEN_URI | flags, vfs);