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.
This commit is contained in:
Amaan Qureshi
2026-01-22 11:34:13 -05:00
parent b7ddbb8e2d
commit 751a0f40bc
7 changed files with 17 additions and 10 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -2,6 +2,7 @@
#include <gtest/gtest.h>
#include <rapidcheck/gtest.h>
#include "nix/store/globals.hh"
#include "nix/store/sqlite.hh"
#include <sqlite3.h>
@@ -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'");
{

View File

@@ -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;

View File

@@ -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

View File

@@ -92,7 +92,7 @@ public:
createDirs(dirOf(dbPath));
state->db = SQLite(dbPath);
state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL});
state->db.isCache();

View File

@@ -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);