diff --git a/src/storage/backend/sqlite/SQLite.cc b/src/storage/backend/sqlite/SQLite.cc index 6a6be32ba7..87e7a66652 100644 --- a/src/storage/backend/sqlite/SQLite.cc +++ b/src/storage/backend/sqlite/SQLite.cc @@ -152,7 +152,7 @@ OperationResult SQLite::DoOpen(OpenResultCallback* cb, RecordValPtr options) { 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]); @@ -171,6 +171,7 @@ OperationResult SQLite::DoClose(ResultCallback* cb) { OperationResult op_res{ReturnCode::SUCCESS}; if ( db ) { + // These will all call sqlite3_finalize as they're deleted. put_stmt.reset(); put_update_stmt.reset(); get_stmt.reset(); @@ -208,15 +209,14 @@ OperationResult SQLite::DoPut(ResultCallback* cb, ValPtr key, ValPtr value, bool if ( ! key_data ) return {ReturnCode::SERIALIZATION_FAILED, "Failed to serialize key"}; - sqlite3_stmt* stmt; + unique_stmt_ptr stmt; if ( ! overwrite ) - stmt = put_stmt.get(); + stmt = unique_stmt_ptr(put_stmt.get(), sqlite3_reset); 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 ) { - sqlite3_reset(stmt); return res; } @@ -224,26 +224,23 @@ OperationResult SQLite::DoPut(ResultCallback* cb, ValPtr key, ValPtr value, bool if ( ! val_data ) 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 ) { - sqlite3_reset(stmt); return res; } - if ( auto res = CheckError(sqlite3_bind_double(stmt, 3, expiration_time)); res.code != ReturnCode::SUCCESS ) { - sqlite3_reset(stmt); + if ( auto res = CheckError(sqlite3_bind_double(stmt.get(), 3, expiration_time)); res.code != ReturnCode::SUCCESS ) { return res; } 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 ) { - sqlite3_reset(stmt); 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 ) 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 ) { - sqlite3_reset(stmt); 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 ) 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 ) { - sqlite3_reset(stmt); return res; } - return Step(stmt, false); + return Step(stmt.get(), false); } /** @@ -295,20 +290,18 @@ OperationResult SQLite::DoErase(ResultCallback* cb, ValPtr key) { * derived classes. */ 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 ) { // TODO: do something with the error? - } - else { - status = sqlite3_step(stmt); - if ( status != SQLITE_ROW ) { - // TODO: should this return an error somehow? Reporter warning? - } + return; } - 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 @@ -330,7 +323,6 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) { size_t blob_size = sqlite3_column_bytes(stmt, 0); auto val = serializer->Unserialize({blob, blob_size}, val_type); - sqlite3_reset(stmt); if ( val ) ret = {ReturnCode::SUCCESS, "", val.value()}; @@ -355,8 +347,6 @@ OperationResult SQLite::Step(sqlite3_stmt* stmt, bool parse_value) { else ret = {ReturnCode::OPERATION_FAILED}; - sqlite3_reset(stmt); - return ret; } diff --git a/src/storage/backend/sqlite/SQLite.h b/src/storage/backend/sqlite/SQLite.h index a5db127fb7..29cae4fd89 100644 --- a/src/storage/backend/sqlite/SQLite.h +++ b/src/storage/backend/sqlite/SQLite.h @@ -54,8 +54,9 @@ private: sqlite3* db = nullptr; - using stmt_deleter = std::function; - using unique_stmt_ptr = std::unique_ptr; + using sqlite_stmt_func = std::function; + using unique_stmt_ptr = std::unique_ptr; + unique_stmt_ptr put_stmt; unique_stmt_ptr put_update_stmt; unique_stmt_ptr get_stmt;