diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/content/mods.cpp | 7 | ||||
-rw-r--r-- | src/content/mods.h | 2 | ||||
-rw-r--r-- | src/database/database-dummy.cpp | 11 | ||||
-rw-r--r-- | src/database/database-dummy.h | 1 | ||||
-rw-r--r-- | src/database/database-files.cpp | 15 | ||||
-rw-r--r-- | src/database/database-files.h | 1 | ||||
-rw-r--r-- | src/database/database-sqlite3.cpp | 20 | ||||
-rw-r--r-- | src/database/database-sqlite3.h | 2 | ||||
-rw-r--r-- | src/database/database.h | 1 | ||||
-rw-r--r-- | src/metadata.cpp | 9 | ||||
-rw-r--r-- | src/metadata.h | 5 | ||||
-rw-r--r-- | src/script/lua_api/l_itemstackmeta.cpp | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_metadata.cpp | 26 | ||||
-rw-r--r-- | src/script/lua_api/l_metadata.h | 3 | ||||
-rw-r--r-- | src/script/lua_api/l_nodemeta.cpp | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_playermeta.cpp | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_storage.cpp | 1 | ||||
-rw-r--r-- | src/unittest/test_modmetadatadatabase.cpp | 7 |
18 files changed, 115 insertions, 0 deletions
diff --git a/src/content/mods.cpp b/src/content/mods.cpp index ef268055f..57ccaaf2e 100644 --- a/src/content/mods.cpp +++ b/src/content/mods.cpp @@ -247,6 +247,13 @@ const StringMap &ModMetadata::getStrings(StringMap *place) const return *place; } +const std::vector<std::string> &ModMetadata::getKeys(std::vector<std::string> *place) const +{ + place->clear(); + m_database->getModKeys(m_mod_name, place); + return *place; +} + const std::string *ModMetadata::getStringRaw(const std::string &name, std::string *place) const { return m_database->getModEntry(m_mod_name, name, place) ? place : nullptr; diff --git a/src/content/mods.h b/src/content/mods.h index 0b0e26b50..a45081f57 100644 --- a/src/content/mods.h +++ b/src/content/mods.h @@ -127,6 +127,8 @@ public: const StringMap &getStrings(StringMap *place) const override; + const std::vector<std::string> &getKeys(std::vector<std::string> *place) const override; + protected: const std::string *getStringRaw(const std::string &name, std::string *place) const override; diff --git a/src/database/database-dummy.cpp b/src/database/database-dummy.cpp index ee88c6684..a8daaca88 100644 --- a/src/database/database-dummy.cpp +++ b/src/database/database-dummy.cpp @@ -92,6 +92,17 @@ bool Database_Dummy::getModEntries(const std::string &modname, StringMap *storag return true; } +bool Database_Dummy::getModKeys(const std::string &modname, std::vector<std::string> *storage) +{ + const auto mod_pair = m_mod_meta_database.find(modname); + if (mod_pair != m_mod_meta_database.cend()) { + storage->reserve(storage->size() + mod_pair->second.size()); + for (const auto &pair : mod_pair->second) + storage->push_back(pair.first); + } + return true; +} + bool Database_Dummy::getModEntry(const std::string &modname, const std::string &key, std::string *value) { diff --git a/src/database/database-dummy.h b/src/database/database-dummy.h index 86c680ef1..b77911d55 100644 --- a/src/database/database-dummy.h +++ b/src/database/database-dummy.h @@ -38,6 +38,7 @@ public: void listPlayers(std::vector<std::string> &res); bool getModEntries(const std::string &modname, StringMap *storage); + bool getModKeys(const std::string &modname, std::vector<std::string> *storage); bool getModEntry(const std::string &modname, const std::string &key, std::string *value); bool hasModEntry(const std::string &modname, const std::string &key); diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index eff08de12..0b94b28f2 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -396,6 +396,21 @@ bool ModMetadataDatabaseFiles::getModEntries(const std::string &modname, StringM return true; } +bool ModMetadataDatabaseFiles::getModKeys(const std::string &modname, + std::vector<std::string> *storage) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + std::vector<std::string> keys = meta->getMemberNames(); + storage->reserve(storage->size() + keys.size()); + for (std::string &key : keys) + storage->push_back(std::move(key)); + + return true; +} + bool ModMetadataDatabaseFiles::getModEntry(const std::string &modname, const std::string &key, std::string *value) { diff --git a/src/database/database-files.h b/src/database/database-files.h index 089e071fe..2f74cc2e1 100644 --- a/src/database/database-files.h +++ b/src/database/database-files.h @@ -79,6 +79,7 @@ public: virtual ~ModMetadataDatabaseFiles() = default; virtual bool getModEntries(const std::string &modname, StringMap *storage); + virtual bool getModKeys(const std::string &modname, std::vector<std::string> *storage); virtual bool getModEntry(const std::string &modname, const std::string &key, std::string *value); virtual bool hasModEntry(const std::string &modname, const std::string &key); diff --git a/src/database/database-sqlite3.cpp b/src/database/database-sqlite3.cpp index 0406fadc8..5511a46de 100644 --- a/src/database/database-sqlite3.cpp +++ b/src/database/database-sqlite3.cpp @@ -775,6 +775,7 @@ ModMetadataDatabaseSQLite3::~ModMetadataDatabaseSQLite3() FINALIZE_STATEMENT(m_stmt_set) FINALIZE_STATEMENT(m_stmt_has) FINALIZE_STATEMENT(m_stmt_get) + FINALIZE_STATEMENT(m_stmt_get_keys) FINALIZE_STATEMENT(m_stmt_get_all) } @@ -796,6 +797,7 @@ void ModMetadataDatabaseSQLite3::createDatabase() void ModMetadataDatabaseSQLite3::initStatements() { PREPARE_STATEMENT(get_all, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?"); + PREPARE_STATEMENT(get_keys, "SELECT `key` FROM `entries` WHERE `modname` = ?"); PREPARE_STATEMENT(get, "SELECT `value` FROM `entries` WHERE `modname` = ? AND `key` = ? LIMIT 1"); PREPARE_STATEMENT(has, @@ -825,6 +827,24 @@ bool ModMetadataDatabaseSQLite3::getModEntries(const std::string &modname, Strin return true; } +bool ModMetadataDatabaseSQLite3::getModKeys(const std::string &modname, + std::vector<std::string> *storage) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_get_keys, 1, modname); + while (sqlite3_step(m_stmt_get_keys) == SQLITE_ROW) { + const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get_keys, 0); + size_t key_len = sqlite3_column_bytes(m_stmt_get_keys, 0); + storage->emplace_back(key_data, key_len); + } + sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE); + + sqlite3_reset(m_stmt_get_keys); + + return true; +} + bool ModMetadataDatabaseSQLite3::getModEntry(const std::string &modname, const std::string &key, std::string *value) { diff --git a/src/database/database-sqlite3.h b/src/database/database-sqlite3.h index 566f6cebb..20488f0f0 100644 --- a/src/database/database-sqlite3.h +++ b/src/database/database-sqlite3.h @@ -240,6 +240,7 @@ public: virtual ~ModMetadataDatabaseSQLite3(); virtual bool getModEntries(const std::string &modname, StringMap *storage); + virtual bool getModKeys(const std::string &modname, std::vector<std::string> *storage); virtual bool getModEntry(const std::string &modname, const std::string &key, std::string *value); virtual bool hasModEntry(const std::string &modname, const std::string &key); @@ -258,6 +259,7 @@ protected: private: sqlite3_stmt *m_stmt_get_all = nullptr; + sqlite3_stmt *m_stmt_get_keys = nullptr; sqlite3_stmt *m_stmt_get = nullptr; sqlite3_stmt *m_stmt_has = nullptr; sqlite3_stmt *m_stmt_set = nullptr; diff --git a/src/database/database.h b/src/database/database.h index 0f22deebc..bf5a3da2b 100644 --- a/src/database/database.h +++ b/src/database/database.h @@ -92,6 +92,7 @@ public: virtual ~ModMetadataDatabase() = default; virtual bool getModEntries(const std::string &modname, StringMap *storage) = 0; + virtual bool getModKeys(const std::string &modname, std::vector<std::string> *storage) = 0; virtual bool hasModEntry(const std::string &modname, const std::string &key) = 0; virtual bool getModEntry(const std::string &modname, const std::string &key, std::string *value) = 0; diff --git a/src/metadata.cpp b/src/metadata.cpp index c0ae9a404..d8a41218d 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -108,6 +108,15 @@ const StringMap &SimpleMetadata::getStrings(StringMap *) const return m_stringvars; } +const std::vector<std::string> &SimpleMetadata::getKeys(std::vector<std::string> *place) const +{ + place->clear(); + place->reserve(m_stringvars.size()); + for (const auto &pair : m_stringvars) + place->push_back(pair.first); + return *place; +} + const std::string *SimpleMetadata::getStringRaw(const std::string &name, std::string *) const { const auto found = m_stringvars.find(name); diff --git a/src/metadata.h b/src/metadata.h index df61b3f7a..45a3774d2 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -60,6 +60,9 @@ public: // May (not must!) put strings in `place` and return a reference to these strings. virtual const StringMap &getStrings(StringMap *place) const = 0; + // May (not must!) put keys in `place` and return a reference to these keys. + virtual const std::vector<std::string> &getKeys(std::vector<std::string> *place) const = 0; + // Add support for variable names in values. Uses place like getString. const std::string &resolveString(const std::string &str, std::string *place, u16 recursion = 0) const; @@ -88,6 +91,8 @@ public: bool contains(const std::string &name) const override; virtual bool setString(const std::string &name, const std::string &var) override; const StringMap &getStrings(StringMap *) const override final; + const std::vector<std::string> &getKeys(std::vector<std::string> *place) + const override final; // Simple version of getters, possible due to in-memory storage: diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp index 3c0f68406..8ce9673db 100644 --- a/src/script/lua_api/l_itemstackmeta.cpp +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -97,6 +97,7 @@ const luaL_Reg ItemStackMetaRef::methods[] = { luamethod(MetaDataRef, set_int), luamethod(MetaDataRef, get_float), luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, get_keys), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(MetaDataRef, equals), diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp index 8388bc089..68b79331b 100644 --- a/src/script/lua_api/l_metadata.cpp +++ b/src/script/lua_api/l_metadata.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverenvironment.h" #include "map.h" #include "server.h" +#include "util/basic_macros.h" MetaDataRef *MetaDataRef::checkAnyMetadata(lua_State *L, int narg) { @@ -196,6 +197,31 @@ int MetaDataRef::l_set_float(lua_State *L) return 0; } +// get_keys(self) +int MetaDataRef::l_get_keys(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkAnyMetadata(L, 1); + + IMetadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_newtable(L); + return 1; + } + + std::vector<std::string> keys_; + const std::vector<std::string> &keys = meta->getKeys(&keys_); + + int i = 0; + lua_createtable(L, keys.size(), 0); + for (const std::string &key : keys) { + lua_pushlstring(L, key.c_str(), key.size()); + lua_rawseti(L, -2, ++i); + } + return 1; +} + // to_table(self) int MetaDataRef::l_to_table(lua_State *L) { diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h index 084b06c83..cae15e232 100644 --- a/src/script/lua_api/l_metadata.h +++ b/src/script/lua_api/l_metadata.h @@ -74,6 +74,9 @@ protected: // set_float(self, name, var) static int l_set_float(lua_State *L); + // get_keys(self) + static int l_get_keys(lua_State *L); + // to_table(self) static int l_to_table(lua_State *L); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 3cfb25883..f4edc1790 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -209,6 +209,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, set_int), luamethod(MetaDataRef, get_float), luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, get_keys), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(NodeMetaRef, get_inventory), @@ -230,6 +231,7 @@ const luaL_Reg NodeMetaRef::methodsClient[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, get_int), luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, get_keys), luamethod(MetaDataRef, to_table), {0,0} }; diff --git a/src/script/lua_api/l_playermeta.cpp b/src/script/lua_api/l_playermeta.cpp index 6ccb53e1c..def65a1cc 100644 --- a/src/script/lua_api/l_playermeta.cpp +++ b/src/script/lua_api/l_playermeta.cpp @@ -70,6 +70,7 @@ const luaL_Reg PlayerMetaRef::methods[] = { luamethod(MetaDataRef, set_int), luamethod(MetaDataRef, get_float), luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, get_keys), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(MetaDataRef, equals), diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp index 4b3863ca9..e1d47ba72 100644 --- a/src/script/lua_api/l_storage.cpp +++ b/src/script/lua_api/l_storage.cpp @@ -74,6 +74,7 @@ const luaL_Reg StorageRef::methods[] = { luamethod(MetaDataRef, set_int), luamethod(MetaDataRef, get_float), luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, get_keys), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(MetaDataRef, equals), diff --git a/src/unittest/test_modmetadatadatabase.cpp b/src/unittest/test_modmetadatadatabase.cpp index b46feb884..1a443e51b 100644 --- a/src/unittest/test_modmetadatadatabase.cpp +++ b/src/unittest/test_modmetadatadatabase.cpp @@ -286,8 +286,11 @@ void TestModMetadataDatabase::testRecallFail() { ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); StringMap recalled; + std::vector<std::string> recalled_keys; mod_meta_db->getModEntries("mod1", &recalled); + mod_meta_db->getModKeys("mod1", &recalled_keys); UASSERT(recalled.empty()); + UASSERT(recalled_keys.empty()); std::string key1_value; UASSERT(!mod_meta_db->getModEntry("mod1", "key1", &key1_value)); UASSERT(!mod_meta_db->hasModEntry("mod1", "key1")); @@ -303,9 +306,13 @@ void TestModMetadataDatabase::testRecall() { ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); StringMap recalled; + std::vector<std::string> recalled_keys; mod_meta_db->getModEntries("mod1", &recalled); + mod_meta_db->getModKeys("mod1", &recalled_keys); UASSERTCMP(std::size_t, ==, recalled.size(), 1); + UASSERTCMP(std::size_t, ==, recalled_keys.size(), 1); UASSERTCMP(std::string, ==, recalled["key1"], "value1"); + UASSERTCMP(std::string, ==, recalled_keys[0], "key1"); std::string key1_value; UASSERT(mod_meta_db->getModEntry("mod1", "key1", &key1_value)); UASSERTCMP(std::string, ==, key1_value, "value1"); |