diff --git a/src/storage/backend/sqlite/SQLite.cc b/src/storage/backend/sqlite/SQLite.cc index 785bdafbb5..aa8422fa86 100644 --- a/src/storage/backend/sqlite/SQLite.cc +++ b/src/storage/backend/sqlite/SQLite.cc @@ -186,7 +186,7 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) { db), std::make_pair(util:: fmt("insert into %s (key_str, value_str, expire_time) values(?, ?, ?) ON CONFLICT(key_str) " - "DO UPDATE SET value_str=?", + "DO UPDATE SET value_str=?, expire_time=?", table_name.c_str()), db), std::make_pair(util::fmt("select value_str from %s where key_str=?", table_name.c_str()), db), @@ -318,6 +318,12 @@ OperationResult SQLite::DoPut(ResultCallback* cb, ValPtr key, ValPtr value, bool res.code != ReturnCode::SUCCESS ) { return res; } + + // This duplicates the above binding, but it's to overwrite the expiration time on the entry. + if ( auto res = CheckError(sqlite3_bind_double(stmt.get(), 5, expiration_time)); + res.code != ReturnCode::SUCCESS ) { + return res; + } } return Step(stmt.get(), false); diff --git a/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-expiration/out b/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-expiration/out index 428580958a..7a353a836f 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-expiration/out +++ b/testing/btest/Baseline/scripts.base.frameworks.storage.sqlite-expiration/out @@ -2,9 +2,14 @@ open result, [code=Storage::SUCCESS, error_str=, value=] put result 1, [code=Storage::SUCCESS, error_str=, value=] put result 2, [code=Storage::SUCCESS, error_str=, value=] +put result 3.1, [code=Storage::SUCCESS, error_str=, value=] +put result 3.2, [code=Storage::SUCCESS, error_str=, value=] get result, [code=Storage::SUCCESS, error_str=, value=value1234] get result same as inserted, T get result 2, [code=Storage::SUCCESS, error_str=, value=value2345] get result 2 same as inserted, T +get result 3, [code=Storage::SUCCESS, error_str=, value=value3456] +get result 3 same as inserted, T get result 1 after expiration, [code=Storage::KEY_NOT_FOUND, error_str=, value=] get result 2 after expiration, [code=Storage::SUCCESS, error_str=, value=value2345] +get result 3 after expiration, [code=Storage::SUCCESS, error_str=, value=value3456] diff --git a/testing/btest/scripts/base/frameworks/storage/sqlite-expiration.zeek b/testing/btest/scripts/base/frameworks/storage/sqlite-expiration.zeek index 621859db11..0f6515b728 100644 --- a/testing/btest/scripts/base/frameworks/storage/sqlite-expiration.zeek +++ b/testing/btest/scripts/base/frameworks/storage/sqlite-expiration.zeek @@ -16,6 +16,9 @@ global value1: string = "value1234"; global key2: string = "key2345"; global value2: string = "value2345"; +global key3: string = "key3456"; +global value3: string = "value3456"; + event check_removed() { local res = Storage::Sync::get(b, key1); @@ -24,6 +27,9 @@ event check_removed() res = Storage::Sync::get(b, key2); print "get result 2 after expiration", res; + res = Storage::Sync::get(b, key3); + print "get result 3 after expiration", res; + Storage::Sync::close_backend(b); terminate(); } @@ -46,6 +52,14 @@ event setup_test() res = Storage::Sync::put(b, [ $key=key2, $value=value2, $expire_time=20secs ]); print "put result 2", res; + # Insert a key that should expire and then overwrite it with a new expiration time to + # set it to something that won't expire to verify that expiration gets reset. + res = Storage::Sync::put(b, [ $key=key3, $value=value3, $expire_time=2secs ]); + print "put result 3.1", res; + + res = Storage::Sync::put(b, [ $key=key3, $value=value3, $expire_time=25secs, $overwrite=T ]); + print "put result 3.2", res; + res = Storage::Sync::get(b, key1); print "get result", res; if ( res$code == Storage::SUCCESS && res?$value ) @@ -56,6 +70,11 @@ event setup_test() if ( res$code == Storage::SUCCESS && res?$value ) print "get result 2 same as inserted", value2 == ( res$value as string ); + res = Storage::Sync::get(b, key3); + print "get result 3", res; + if ( res$code == Storage::SUCCESS && res?$value ) + print "get result 3 same as inserted", value3 == ( res$value as string ); + schedule 5secs { check_removed() }; }