diff --git a/scripts/policy/frameworks/storage/backend/sqlite/main.zeek b/scripts/policy/frameworks/storage/backend/sqlite/main.zeek index 100d97239e..6cab5911f2 100644 --- a/scripts/policy/frameworks/storage/backend/sqlite/main.zeek +++ b/scripts/policy/frameworks/storage/backend/sqlite/main.zeek @@ -18,5 +18,14 @@ export { ## Name of the table used for storing data. table_name: string; + + ## Key/value table for passing tuning parameters when opening + ## the database. These must be pairs that can be passed to the + ## ``pragma`` command in sqlite. + tuning_params: table[string] of string &default=table( + ["journal_mode"] = "WAL", + ["synchronous"] = "normal", + ["temp_store"] = "memory" + ); }; } diff --git a/src/storage/backend/sqlite/SQLite.cc b/src/storage/backend/sqlite/SQLite.cc index e4fc4afd9b..e166e861c8 100644 --- a/src/storage/backend/sqlite/SQLite.cc +++ b/src/storage/backend/sqlite/SQLite.cc @@ -53,6 +53,21 @@ ErrorResult SQLite::DoOpen(RecordValPtr options) { return err; } + auto tuning_params = options->GetField("tuning_params")->ToMap(); + for ( const auto& [k, v] : tuning_params ) { + auto ks = k->AsListVal()->Idx(0)->AsStringVal(); + auto vs = v->AsStringVal(); + std::string cmd = util::fmt("pragma %s = %s", ks->ToStdStringView().data(), vs->ToStdStringView().data()); + + if ( int res = sqlite3_exec(db, cmd.c_str(), NULL, NULL, &errorMsg); res != SQLITE_OK ) { + std::string err = util::fmt("Error executing tuning pragma statement: %s", errorMsg); + Error(err.c_str()); + sqlite3_free(errorMsg); + Close(); + return err; + } + } + static std::map statements = {{"put", util::fmt("insert into %s (key_str, value_str, expire_time) values(?, ?, ?)", table_name.c_str())}, {"put_update", @@ -89,6 +104,12 @@ void SQLite::Close() { prepared_stmts.clear(); + char* errmsg; + if ( int res = sqlite3_exec(db, "pragma optimize", NULL, NULL, &errmsg); res != SQLITE_OK ) { + Error(util::fmt("Sqlite failed to optimize at shutdown: %s", errmsg)); + sqlite3_free(&errmsg); + } + if ( int res = sqlite3_close_v2(db); res != SQLITE_OK ) Error("Sqlite could not close connection");