Use unique_ptr to avoid needing to call sqlite3_reset manually

This commit is contained in:
Tim Wojtulewicz 2025-05-22 14:25:22 -07:00
parent 850b20e12b
commit 97a2ec379e
2 changed files with 26 additions and 35 deletions

View file

@ -152,7 +152,7 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) {
return prep_res; return prep_res;
} }
stmt_ptrs[i++] = unique_stmt_ptr(ps, [](sqlite3_stmt* stmt) { sqlite3_finalize(stmt); }); stmt_ptrs[i++] = unique_stmt_ptr(ps, sqlite3_finalize);
} }
put_stmt = std::move(stmt_ptrs[0]); put_stmt = std::move(stmt_ptrs[0]);
@ -171,6 +171,7 @@ OperationResult SQLite::DoClose(ResultCallback* cb) {
OperationResult op_res{ReturnCode::SUCCESS}; OperationResult op_res{ReturnCode::SUCCESS};
if ( db ) { if ( db ) {
// These will all call sqlite3_finalize as they're deleted.
put_stmt.reset(); put_stmt.reset();
put_update_stmt.reset(); put_update_stmt.reset();
get_stmt.reset(); get_stmt.reset();
@ -208,15 +209,14 @@ 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"};
sqlite3_stmt* stmt; unique_stmt_ptr stmt;
if ( ! overwrite ) if ( ! overwrite )
stmt = put_stmt.get(); stmt = unique_stmt_ptr(put_stmt.get(), sqlite3_reset);
else else
stmt = put_update_stmt.get(); stmt = unique_stmt_ptr(put_update_stmt.get(), sqlite3_reset);
if ( auto res = CheckError(sqlite3_bind_blob(stmt, 1, key_data->data(), key_data->size(), SQLITE_STATIC)); if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 1, key_data->data(), key_data->size(), SQLITE_STATIC));
res.code != ReturnCode::SUCCESS ) { res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
@ -224,26 +224,23 @@ OperationResult SQLite::DoPut(ResultCallback* cb, ValPtr key, ValPtr value, bool
if ( ! val_data ) if ( ! val_data )
return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize value"}; return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize value"};
if ( auto res = CheckError(sqlite3_bind_blob(stmt, 2, val_data->data(), val_data->size(), SQLITE_STATIC)); if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 2, val_data->data(), val_data->size(), SQLITE_STATIC));
res.code != ReturnCode::SUCCESS ) { res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
if ( auto res = CheckError(sqlite3_bind_double(stmt, 3, expiration_time)); res.code != ReturnCode::SUCCESS ) { if ( auto res = CheckError(sqlite3_bind_double(stmt.get(), 3, expiration_time)); res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
if ( overwrite ) { if ( overwrite ) {
if ( auto res = CheckError(sqlite3_bind_blob(stmt, 4, val_data->data(), val_data->size(), SQLITE_STATIC)); if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 4, val_data->data(), val_data->size(), SQLITE_STATIC));
res.code != ReturnCode::SUCCESS ) { res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
} }
return Step(stmt, false); return Step(stmt.get(), false);
} }
/** /**
@ -257,15 +254,14 @@ OperationResult SQLite::DoGet(ResultCallback* cb, ValPtr key) {
if ( ! key_data ) if ( ! key_data )
return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"}; return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"};
auto stmt = get_stmt.get(); auto stmt = unique_stmt_ptr(get_stmt.get(), sqlite3_reset);
if ( auto res = CheckError(sqlite3_bind_blob(stmt, 1, key_data->data(), key_data->size(), SQLITE_STATIC)); if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 1, key_data->data(), key_data->size(), SQLITE_STATIC));
res.code != ReturnCode::SUCCESS ) { res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
return Step(stmt, true); return Step(stmt.get(), true);
} }
/** /**
@ -279,15 +275,14 @@ OperationResult SQLite::DoErase(ResultCallback* cb, ValPtr key) {
if ( ! key_data ) if ( ! key_data )
return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"}; return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"};
auto stmt = erase_stmt.get(); auto stmt = unique_stmt_ptr(erase_stmt.get(), sqlite3_reset);
if ( auto res = CheckError(sqlite3_bind_blob(stmt, 1, key_data->data(), key_data->size(), SQLITE_STATIC)); if ( auto res = CheckError(sqlite3_bind_blob(stmt.get(), 1, key_data->data(), key_data->size(), SQLITE_STATIC));
res.code != ReturnCode::SUCCESS ) { res.code != ReturnCode::SUCCESS ) {
sqlite3_reset(stmt);
return res; return res;
} }
return Step(stmt, false); return Step(stmt.get(), false);
} }
/** /**
@ -295,20 +290,18 @@ OperationResult SQLite::DoErase(ResultCallback* cb, ValPtr key) {
* derived classes. * derived classes.
*/ */
void SQLite::DoExpire(double current_network_time) { void SQLite::DoExpire(double current_network_time) {
auto stmt = expire_stmt.get(); auto stmt = unique_stmt_ptr(expire_stmt.get(), sqlite3_reset);
int status = sqlite3_bind_double(stmt, 1, current_network_time); int status = sqlite3_bind_double(stmt.get(), 1, current_network_time);
if ( status != SQLITE_OK ) { if ( status != SQLITE_OK ) {
// TODO: do something with the error? // TODO: do something with the error?
} return;
else {
status = sqlite3_step(stmt);
if ( status != SQLITE_ROW ) {
// TODO: should this return an error somehow? Reporter warning?
}
} }
sqlite3_reset(stmt); status = sqlite3_step(stmt.get());
if ( status != SQLITE_ROW ) {
// TODO: should this return an error somehow? Reporter warning?
}
} }
// returns true in case of error // returns true in case of error
@ -330,7 +323,6 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) {
size_t blob_size = sqlite3_column_bytes(stmt, 0); size_t blob_size = sqlite3_column_bytes(stmt, 0);
auto val = serializer->Unserialize({blob, blob_size}, val_type); auto val = serializer->Unserialize({blob, blob_size}, val_type);
sqlite3_reset(stmt);
if ( val ) if ( val )
ret = {ReturnCode::SUCCESS, "", val.value()}; ret = {ReturnCode::SUCCESS, "", val.value()};
@ -355,8 +347,6 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) {
else else
ret = {ReturnCode::OPERATION_FAILED}; ret = {ReturnCode::OPERATION_FAILED};
sqlite3_reset(stmt);
return ret; return ret;
} }

View file

@ -54,8 +54,9 @@ private:
sqlite3* db = nullptr; sqlite3* db = nullptr;
using stmt_deleter = std::function<void(sqlite3_stmt*)>; using sqlite_stmt_func = std::function<void(sqlite3_stmt*)>;
using unique_stmt_ptr = std::unique_ptr<sqlite3_stmt, stmt_deleter>; using unique_stmt_ptr = std::unique_ptr<sqlite3_stmt, sqlite_stmt_func>;
unique_stmt_ptr put_stmt; unique_stmt_ptr put_stmt;
unique_stmt_ptr put_update_stmt; unique_stmt_ptr put_update_stmt;
unique_stmt_ptr get_stmt; unique_stmt_ptr get_stmt;