From 58841ef12f6cba1bb622353c1fcaa0e3c6fb46c9 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 23 Oct 2012 01:18:44 +0400 Subject: Add dummy and LevelDB database backends --- src/main.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index fafb3c8ef..c49829592 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,6 +78,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverlist.h" #include "guiEngine.h" +#ifdef USE_LEVELDB +#include "database-sqlite3.h" +#include "database-leveldb.h" +#endif + /* Settings. These are loaded from the config file. @@ -789,6 +794,10 @@ int main(int argc, char *argv[]) _("Set logfile path ('' = no logging)")))); allowed_options.insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING, _("Set gameid (\"--gameid list\" prints available ones)")))); + #if USE_LEVELDB + allowed_options.insert("migrate", ValueSpec(VALUETYPE_STRING, + _("Migrate from current map backend to another"))); + #endif #ifndef SERVER allowed_options.insert(std::make_pair("videomodes", ValueSpec(VALUETYPE_FLAG, _("Show available video modes")))); @@ -1085,6 +1094,7 @@ int main(int argc, char *argv[]) } } + /* Run dedicated server if asked to or no other option */ @@ -1207,6 +1217,61 @@ int main(int argc, char *argv[]) // Create server Server server(world_path, gamespec, false); + + #if USE_LEVELDB + // Database migration + if (cmd_args.exists("migrate")) { + std::string migrate_to = cmd_args.get("migrate"); + Settings world_mt; + bool success = world_mt.readConfigFile((world_path + DIR_DELIM + "world.mt").c_str()); + if (!success) { + errorstream << "Cannot read world.mt" << std::endl; + return 1; + } + if (!world_mt.exists("backend")) { + errorstream << "Please specify your current backend in world.mt file:" + << std::endl << " backend = {sqlite3|leveldb|dummy}" << std::endl; + return 1; + } + std::string backend = world_mt.get("backend"); + Database *new_db; + if (backend == migrate_to) { + errorstream << "Cannot migrate: new backend is same as the old one" << std::endl; + return 1; + } + if (migrate_to == "sqlite3") + new_db = new Database_SQLite3(&(ServerMap&)server.getMap(), world_path); + else if (migrate_to == "leveldb") + new_db = new Database_LevelDB(&(ServerMap&)server.getMap(), world_path); + else { + errorstream << "Migration to " << migrate_to << " is not supported" << std::endl; + return 1; + } + + core::list blocks; + ServerMap &old_map = ((ServerMap&)server.getMap()); + old_map.listAllLoadableBlocks(blocks); + int count = 0; + new_db->beginSave(); + for (core::list::Iterator i = blocks.begin(); i != blocks.end(); ++i) { + MapBlock *block = old_map.loadBlock(*i); + new_db->saveBlock(block); + MapSector *sector = old_map.getSectorNoGenerate(v2s16(i->X, i->Z)); + sector->deleteBlock(block); + ++count; + if (count % 500 == 0) + actionstream << "Migrated " << count << " blocks " + << (100.0 * count / blocks.size()) << "\% completed" << std::endl; + } + new_db->endSave(); + + actionstream << "Successfully migrated " << count << " blocks" << std::endl; + actionstream << "Don't forget to update your world.mt backend setting!" << std::endl; + + return 0; + } + #endif + server.start(port); // Run server -- cgit v1.2.3