diff --git a/scripts/policy/frameworks/storage/backend/sqlite/main.zeek b/scripts/policy/frameworks/storage/backend/sqlite/main.zeek index 5dba77b20a..c8c5f6ca87 100644 --- a/scripts/policy/frameworks/storage/backend/sqlite/main.zeek +++ b/scripts/policy/frameworks/storage/backend/sqlite/main.zeek @@ -25,7 +25,8 @@ export { ## sqlite. The ``integrity_check`` pragma is run automatically and does ## not need to be included here. For pragmas without a second argument, ## set the value to an empty string. - pragma_commands: table[string] of string &default=table( + pragma_commands: table[string] of string &ordered &default=table( + ["integrity_check"] = "", ["busy_timeout"] = "5000", ["journal_mode"] = "WAL", ["synchronous"] = "normal", diff --git a/src/storage/backend/sqlite/SQLite.cc b/src/storage/backend/sqlite/SQLite.cc index 4d007fa5c4..d0773530ef 100644 --- a/src/storage/backend/sqlite/SQLite.cc +++ b/src/storage/backend/sqlite/SQLite.cc @@ -5,6 +5,7 @@ #include #include "zeek/3rdparty/sqlite3.h" +#include "zeek/DebugLogger.h" #include "zeek/Func.h" #include "zeek/Val.h" #include "zeek/storage/ReturnCode.h" @@ -21,6 +22,8 @@ OperationResult SQLite::RunPragma(std::string_view name, std::optionalempty() ) cmd += util::fmt(" = %.*s", static_cast(value->size()), value->data()); + DBG_LOG(DBG_STORAGE, "Executing pragma %s on %s", cmd.c_str(), full_path.c_str()); + while ( pragma_timeout == 0ms || time_spent < pragma_timeout ) { int res = sqlite3_exec(db, cmd.c_str(), NULL, NULL, &errorMsg); if ( res == SQLITE_OK ) { @@ -89,14 +92,6 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) { return open_res; } - char* errorMsg = nullptr; - - OperationResult pragma_res = RunPragma("integrity_check"); - if ( pragma_res.code != ReturnCode::SUCCESS ) { - Error(pragma_res.err_str.c_str()); - return pragma_res; - } - auto pragmas = backend_options->GetField("pragma_commands")->ToMap(); for ( const auto& [k, v] : pragmas ) { auto ks = k->AsListVal()->Idx(0)->AsStringVal(); @@ -104,7 +99,7 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) { auto vs = v->AsStringVal(); auto vs_sv = vs->ToStdStringView(); - pragma_res = RunPragma(ks_sv, vs_sv); + auto pragma_res = RunPragma(ks_sv, vs_sv); if ( pragma_res.code != ReturnCode::SUCCESS ) { Error(pragma_res.err_str.c_str()); return pragma_res; @@ -114,6 +109,7 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) { std::string create = "create table if not exists " + table_name + " ("; create.append("key_str blob primary key, value_str blob not null, expire_time real);"); + char* errorMsg = nullptr; if ( int res = sqlite3_exec(db, create.c_str(), NULL, NULL, &errorMsg); res != SQLITE_OK ) { std::string err = util::fmt("Error executing table creation statement: (%d) %s", res, errorMsg); Error(err.c_str()); diff --git a/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-basic/out b/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-basic/out index 3052fe3a40..e683770c8e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-basic/out +++ b/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-basic/out @@ -2,8 +2,9 @@ Storage::backend_opened, Storage::STORAGE_BACKEND_SQLITE, [serializer=Storage::STORAGE_SERIALIZER_JSON, sqlite=[database_path=test.sqlite, table_name=testing, pragma_commands={ [synchronous] = normal, [journal_mode] = WAL, -[temp_store] = memory, -[busy_timeout] = 5000 +[busy_timeout] = 5000, +[integrity_check] = , +[temp_store] = memory }, pragma_timeout=500.0 msecs, pragma_wait_on_failure=5.0 msecs]] open result, [code=Storage::SUCCESS, error_str=, value=] put result, [code=Storage::SUCCESS, error_str=, value=]