diff options
author | Jude Melton-Houghton <jwmhjwmh@gmail.com> | 2022-09-26 17:03:43 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-26 17:03:43 -0400 |
commit | f4a01f3a5dc0d8fe2f4f6d804d790da91d1bc30c (patch) | |
tree | 089ddc309e22ae8549ec3b86765ee272f57a33df /src/database/database-sqlite3.cpp | |
parent | 03428d9825cfdf2cfaed6ac9410dafccac0d4f3a (diff) | |
download | minetest-f4a01f3a5dc0d8fe2f4f6d804d790da91d1bc30c.tar.xz |
Avoid duplication of mod metadata in memory (#12562)
Co-authored-by: sfan5 <sfan5@live.de>
Diffstat (limited to 'src/database/database-sqlite3.cpp')
-rw-r--r-- | src/database/database-sqlite3.cpp | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/src/database/database-sqlite3.cpp b/src/database/database-sqlite3.cpp index 5e565be55..0406fadc8 100644 --- a/src/database/database-sqlite3.cpp +++ b/src/database/database-sqlite3.cpp @@ -770,9 +770,12 @@ ModMetadataDatabaseSQLite3::ModMetadataDatabaseSQLite3(const std::string &savedi ModMetadataDatabaseSQLite3::~ModMetadataDatabaseSQLite3() { + FINALIZE_STATEMENT(m_stmt_remove_all) FINALIZE_STATEMENT(m_stmt_remove) FINALIZE_STATEMENT(m_stmt_set) + FINALIZE_STATEMENT(m_stmt_has) FINALIZE_STATEMENT(m_stmt_get) + FINALIZE_STATEMENT(m_stmt_get_all) } void ModMetadataDatabaseSQLite3::createDatabase() @@ -792,31 +795,74 @@ void ModMetadataDatabaseSQLite3::createDatabase() void ModMetadataDatabaseSQLite3::initStatements() { - PREPARE_STATEMENT(get, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?"); + PREPARE_STATEMENT(get_all, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?"); + PREPARE_STATEMENT(get, + "SELECT `value` FROM `entries` WHERE `modname` = ? AND `key` = ? LIMIT 1"); + PREPARE_STATEMENT(has, + "SELECT 1 FROM `entries` WHERE `modname` = ? AND `key` = ? LIMIT 1"); PREPARE_STATEMENT(set, "REPLACE INTO `entries` (`modname`, `key`, `value`) VALUES (?, ?, ?)"); PREPARE_STATEMENT(remove, "DELETE FROM `entries` WHERE `modname` = ? AND `key` = ?"); + PREPARE_STATEMENT(remove_all, "DELETE FROM `entries` WHERE `modname` = ?"); } bool ModMetadataDatabaseSQLite3::getModEntries(const std::string &modname, StringMap *storage) { verifyDatabase(); - str_to_sqlite(m_stmt_get, 1, modname); - while (sqlite3_step(m_stmt_get) == SQLITE_ROW) { - const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get, 0); - size_t key_len = sqlite3_column_bytes(m_stmt_get, 0); - const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 1); - size_t value_len = sqlite3_column_bytes(m_stmt_get, 1); + str_to_sqlite(m_stmt_get_all, 1, modname); + while (sqlite3_step(m_stmt_get_all) == SQLITE_ROW) { + const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 0); + size_t key_len = sqlite3_column_bytes(m_stmt_get_all, 0); + const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 1); + size_t value_len = sqlite3_column_bytes(m_stmt_get_all, 1); (*storage)[std::string(key_data, key_len)] = std::string(value_data, value_len); } sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE); - sqlite3_reset(m_stmt_get); + sqlite3_reset(m_stmt_get_all); return true; } +bool ModMetadataDatabaseSQLite3::getModEntry(const std::string &modname, + const std::string &key, std::string *value) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_get, 1, modname); + SQLOK(sqlite3_bind_blob(m_stmt_get, 2, key.data(), key.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + bool found = sqlite3_step(m_stmt_get) == SQLITE_ROW; + if (found) { + const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 0); + size_t value_len = sqlite3_column_bytes(m_stmt_get, 0); + value->assign(value_data, value_len); + sqlite3_step(m_stmt_get); + } + + sqlite3_reset(m_stmt_get); + + return found; +} + +bool ModMetadataDatabaseSQLite3::hasModEntry(const std::string &modname, + const std::string &key) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_has, 1, modname); + SQLOK(sqlite3_bind_blob(m_stmt_has, 2, key.data(), key.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + bool found = sqlite3_step(m_stmt_has) == SQLITE_ROW; + if (found) + sqlite3_step(m_stmt_has); + + sqlite3_reset(m_stmt_has); + + return found; +} + bool ModMetadataDatabaseSQLite3::setModEntry(const std::string &modname, const std::string &key, const std::string &value) { @@ -850,6 +896,19 @@ bool ModMetadataDatabaseSQLite3::removeModEntry(const std::string &modname, return changes > 0; } +bool ModMetadataDatabaseSQLite3::removeModEntries(const std::string &modname) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_remove_all, 1, modname); + sqlite3_vrfy(sqlite3_step(m_stmt_remove_all), SQLITE_DONE); + int changes = sqlite3_changes(m_database); + + sqlite3_reset(m_stmt_remove_all); + + return changes > 0; +} + void ModMetadataDatabaseSQLite3::listMods(std::vector<std::string> *res) { verifyDatabase(); |