mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Make PUT on SQLite backend implicitly overwrite expired entries
The backend does not serve expired but still present entries so to a user they do not exist. When they put new data over such an entry their expecation is that the value is overwritten, even if not explicitly requested.
This commit is contained in:
parent
56f5cafa98
commit
fc007b674a
3 changed files with 39 additions and 0 deletions
|
@ -295,6 +295,33 @@ OperationResult SQLite::DoPut(ResultCallback* cb, ValPtr key, ValPtr value, bool
|
||||||
if ( ! key_data )
|
if ( ! key_data )
|
||||||
return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"};
|
return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"};
|
||||||
|
|
||||||
|
// If we are not already in overwrite mode check if an expired entry exists
|
||||||
|
// in the database. Such entries would not be visible to the user, but even
|
||||||
|
// outside of overwrite mode would need to be overwritten.
|
||||||
|
if ( ! overwrite ) {
|
||||||
|
auto stmt = unique_stmt_ptr(get_stmt.get(), sqlite3_reset);
|
||||||
|
|
||||||
|
if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 1, key_data->data(), key_data->size(), SQLITE_STATIC));
|
||||||
|
res.code != ReturnCode::SUCCESS ) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int step_status = sqlite3_step(stmt.get());
|
||||||
|
if ( step_status == SQLITE_ROW ) {
|
||||||
|
// If an expired entry exists, switch to overwrite mode.
|
||||||
|
overwrite =
|
||||||
|
sqlite3_column_type(stmt.get(), 1) != SQLITE_NULL && is_expired(sqlite3_column_double(stmt.get(), 0));
|
||||||
|
}
|
||||||
|
else if ( step_status == SQLITE_DONE ) {
|
||||||
|
// Nothing currently exists.
|
||||||
|
}
|
||||||
|
else if ( step_status == SQLITE_BUSY || step_status == SQLITE_LOCKED )
|
||||||
|
// TODO: this could retry a number of times instead of just failing
|
||||||
|
return {ReturnCode::TIMEOUT};
|
||||||
|
else
|
||||||
|
return {ReturnCode::OPERATION_FAILED};
|
||||||
|
}
|
||||||
|
|
||||||
unique_stmt_ptr stmt;
|
unique_stmt_ptr stmt;
|
||||||
if ( ! overwrite )
|
if ( ! overwrite )
|
||||||
stmt = unique_stmt_ptr(put_stmt.get(), sqlite3_reset);
|
stmt = unique_stmt_ptr(put_stmt.get(), sqlite3_reset);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
BEFORE, [code=Storage::SUCCESS, error_str=<uninitialized>, value=v]
|
BEFORE, [code=Storage::SUCCESS, error_str=<uninitialized>, value=v]
|
||||||
AFTER, [code=Storage::KEY_NOT_FOUND, error_str=<uninitialized>, value=<uninitialized>]
|
AFTER, [code=Storage::KEY_NOT_FOUND, error_str=<uninitialized>, value=<uninitialized>]
|
||||||
|
OVERWRITE, [code=Storage::SUCCESS, error_str=<uninitialized>, value=vv]
|
||||||
|
|
|
@ -47,4 +47,15 @@ event zeek_init()
|
||||||
# An expired value does not exist.
|
# An expired value does not exist.
|
||||||
get = Storage::Sync::get(h, key);
|
get = Storage::Sync::get(h, key);
|
||||||
print "AFTER", get;
|
print "AFTER", get;
|
||||||
|
|
||||||
|
# Even though the entry still exists in the backend we can put a
|
||||||
|
# new value in its place without specifying overwrite.
|
||||||
|
Storage::Sync::put(
|
||||||
|
h,
|
||||||
|
Storage::PutArgs(
|
||||||
|
$key=key,
|
||||||
|
$value=value+value));
|
||||||
|
|
||||||
|
get = Storage::Sync::get(h, key);
|
||||||
|
print "OVERWRITE", get;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue