| 372 | } |
| 373 | |
| 374 | bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value) |
| 375 | { |
| 376 | if (!m_database.m_db) return false; |
| 377 | assert(m_read_stmt); |
| 378 | |
| 379 | // Bind: leftmost parameter in statement is index 1 |
| 380 | int res = sqlite3_bind_blob(m_read_stmt, 1, key.data(), key.size(), SQLITE_STATIC); |
| 381 | if (res != SQLITE_OK) { |
| 382 | LogPrintf("%s: Unable to bind statement: %s\n", __func__, sqlite3_errstr(res)); |
| 383 | sqlite3_clear_bindings(m_read_stmt); |
| 384 | sqlite3_reset(m_read_stmt); |
| 385 | return false; |
| 386 | } |
| 387 | res = sqlite3_step(m_read_stmt); |
| 388 | if (res != SQLITE_ROW) { |
| 389 | if (res != SQLITE_DONE) { |
| 390 | // SQLITE_DONE means "not found", don't log an error in that case. |
| 391 | LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res)); |
| 392 | } |
| 393 | sqlite3_clear_bindings(m_read_stmt); |
| 394 | sqlite3_reset(m_read_stmt); |
| 395 | return false; |
| 396 | } |
| 397 | // Leftmost column in result is index 0 |
| 398 | const std::byte* data{BytePtr(sqlite3_column_blob(m_read_stmt, 0))}; |
| 399 | size_t data_size(sqlite3_column_bytes(m_read_stmt, 0)); |
| 400 | value.write({data, data_size}); |
| 401 | |
| 402 | sqlite3_clear_bindings(m_read_stmt); |
| 403 | sqlite3_reset(m_read_stmt); |
| 404 | return true; |
| 405 | } |
| 406 | |
| 407 | bool SQLiteBatch::WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite) |
| 408 | { |