SQLite: handle existing keys when overwrite=F correctly

This commit is contained in:
Tim Wojtulewicz 2025-03-20 16:06:41 -07:00
parent ba9cf1e4db
commit 3d7fcfb428
3 changed files with 44 additions and 10 deletions

View file

@ -291,6 +291,8 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) {
else if ( step_status == SQLITE_BUSY ) else if ( step_status == SQLITE_BUSY )
// TODO: this could retry a number of times instead of just failing // TODO: this could retry a number of times instead of just failing
ret = {ReturnCode::TIMEOUT}; ret = {ReturnCode::TIMEOUT};
else if ( step_status == SQLITE_CONSTRAINT )
ret = {ReturnCode::KEY_EXISTS};
else else
ret = {ReturnCode::OPERATION_FAILED}; ret = {ReturnCode::OPERATION_FAILED};

View file

@ -3,3 +3,9 @@ open result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=<opaque of
put result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=<uninitialized>] put result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=<uninitialized>]
get result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=value7890] get result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=value7890]
get result same as inserted, T get result same as inserted, T
put result, [code=Storage::KEY_EXISTS, error_str=<uninitialized>, value=<uninitialized>]
get result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=value7890]
get result same as originally inserted, T
put result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=<uninitialized>]
get result, [code=Storage::SUCCESS, error_str=<uninitialized>, value=value2345]
get result same as overwritten, T

View file

@ -7,24 +7,50 @@
@load base/frameworks/storage/sync @load base/frameworks/storage/sync
@load policy/frameworks/storage/backend/sqlite @load policy/frameworks/storage/backend/sqlite
# Create a typename here that can be passed down into get().
type str: string;
event zeek_init() { event zeek_init() {
local opts : Storage::BackendOptions; local opts : Storage::BackendOptions;
opts$sqlite = [$database_path = "storage-test.sqlite", $table_name = "testing"]; opts$sqlite = [$database_path = "testing.sqlite", $table_name = "testing"];
local key = "key1234"; local key = "key1111";
local value = "value7890"; local value = "value7890";
local value2 = "value2345";
local open_res = Storage::Sync::open_backend(Storage::SQLITE, opts, string, string); local res = Storage::Sync::open_backend(Storage::SQLITE, opts, str, str);
print "open result", open_res; print "open result", res;
local b = open_res$value; local b = res$value;
local res = Storage::Sync::put(b, [$key=key, $value=value]); # Put a first value. This should return Storage::SUCCESS.
res = Storage::Sync::put(b, [$key=key, $value=value]);
print "put result", res; print "put result", res;
local res2 = Storage::Sync::get(b, key); # Get the first value, validate that it's what we inserted.
print "get result", res2; res = Storage::Sync::get(b, key);
if ( res2$code == Storage::SUCCESS && res2?$value ) print "get result", res;
print "get result same as inserted", value == (res2$value as string); if ( res$code == Storage::SUCCESS && res?$value )
print "get result same as inserted", value == (res$value as string);
# This will return a Storage::KEY_EXISTS since we don't want overwriting.
res = Storage::Sync::put(b, [$key=key, $value=value2, $overwrite=F]);
print "put result", res;
# Verify that the overwrite didn't actually happen.
res = Storage::Sync::get(b, key);
print "get result", res;
if ( res$code == Storage::SUCCESS && res?$value )
print "get result same as originally inserted", value == (res$value as string);
# This will return a Storage::SUCESSS since we're asking for an overwrite.
res = Storage::Sync::put(b, [$key=key, $value=value2, $overwrite=T]);
print "put result", res;
# Verify that the overwrite happened.
res = Storage::Sync::get(b, key);
print "get result", res;
if ( res$code == Storage::SUCCESS && res?$value )
print "get result same as overwritten", value2 == (res$value as string);
Storage::Sync::close_backend(b); Storage::Sync::close_backend(b);
} }