From e9eda2b0d0019890cd404e4af25b7adf349e288f Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Fri, 27 Feb 2015 02:24:07 -0500 Subject: [PATCH] Don't start a server for map migration --- src/main.cpp | 97 ++++++++++++++++++++++------------------------------ src/map.cpp | 41 ++++++++++++---------- src/map.h | 2 ++ 3 files changed, 65 insertions(+), 75 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4e5bf51f..a01ddec9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,22 +46,15 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "quicktune.h" #include "httpfetch.h" #include "guiEngine.h" +#include "map.h" #include "mapsector.h" #include "fontengine.h" #include "gameparams.h" +#include "database.h" #ifndef SERVER #include "client/clientlauncher.h" #endif -#include "database-sqlite3.h" -#ifdef USE_LEVELDB -#include "database-leveldb.h" -#endif - -#if USE_REDIS -#include "database-redis.h" -#endif - #ifdef HAVE_TOUCHSCREENGUI #include "touchscreengui.h" #endif @@ -140,8 +133,7 @@ static bool get_game_from_cmdline(GameParams *game_params, const Settings &cmd_a static bool determine_subgame(GameParams *game_params); static bool run_dedicated_server(const GameParams &game_params, const Settings &cmd_args); -static bool migrate_database(const GameParams &game_params, const Settings &cmd_args, - Server *server); +static bool migrate_database(const GameParams &game_params, const Settings &cmd_args); /**********************************************************************/ @@ -894,14 +886,14 @@ static bool run_dedicated_server(const GameParams &game_params, const Settings & return false; } + // Database migration + if (cmd_args.exists("migrate")) + return migrate_database(game_params, cmd_args); + // Create server Server server(game_params.world_path, game_params.game_spec, false, bind_addr.isIPv6()); - // Database migration - if (cmd_args.exists("migrate")) - return migrate_database(game_params, cmd_args, &server); - server.start(bind_addr); // Run server @@ -911,68 +903,58 @@ static bool run_dedicated_server(const GameParams &game_params, const Settings & return true; } -static bool migrate_database(const GameParams &game_params, const Settings &cmd_args, - Server *server) +static bool migrate_database(const GameParams &game_params, const Settings &cmd_args) { std::string migrate_to = cmd_args.get("migrate"); Settings world_mt; std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; - bool success = world_mt.readConfigFile(world_mt_path.c_str()); - if (!success) { - errorstream << "Cannot read world.mt" << std::endl; - return 1; + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt!" << std::endl; + return false; } if (!world_mt.exists("backend")) { errorstream << "Please specify your current backend in world.mt:" + << std::endl + << " backend = {sqlite3|leveldb|redis|dummy}" << std::endl; - errorstream << " backend = {sqlite3|leveldb|redis|dummy}" - << std::endl; - return 1; + return false; } 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(game_params.world_path); - #if USE_LEVELDB - else if (migrate_to == "leveldb") - new_db = new Database_LevelDB(game_params.world_path); - #endif - #if USE_REDIS - else if (migrate_to == "redis") - new_db = new Database_Redis(world_mt); - #endif - else { - errorstream << "Migration to " << migrate_to - << " is not supported" << std::endl; - return 1; + << " as the old one" << std::endl; + return false; } + Database *old_db = ServerMap::createDatabase(backend, game_params.world_path, world_mt), + *new_db = ServerMap::createDatabase(migrate_to, game_params.world_path, world_mt); + + u32 count = 0; + time_t last_update_time = 0; + bool &kill = *porting::signal_handler_killstatus(); std::vector blocks; - ServerMap &old_map = (ServerMap &) server->getMap(); - old_map.listAllLoadableBlocks(blocks); - int count = 0; + old_db->listAllLoadableBlocks(blocks); new_db->beginSave(); - for (std::vector::iterator i = blocks.begin(); i != blocks.end(); i++) { - MapBlock *block = old_map.loadBlock(*i); - if (!block) { - errorstream << "Failed to load block " << PP(*i) << ", skipping it."; + for (std::vector::const_iterator it = blocks.begin(); it != blocks.end(); ++it) { + if (kill) return false; + + const std::string &data = old_db->loadBlock(*it); + if (!data.empty()) { + new_db->saveBlock(*it, data); + } else { + errorstream << "Failed to load block " << PP(*it) << ", skipping it." << std::endl; } - else { - old_map.saveBlock(block, new_db); - MapSector *sector = old_map.getSectorNoGenerate(v2s16(i->X, i->Z)); - sector->deleteBlock(block); + if (++count % 0xFF == 0 && time(NULL) - last_update_time >= 1) { + std::cerr << " Migrated " << count << " blocks, " + << (100.0 * count / blocks.size()) << "% completed.\r"; + new_db->endSave(); + new_db->beginSave(); + last_update_time = time(NULL); } - ++count; - if (count % 500 == 0) - actionstream << "Migrated " << count << " blocks " - << (100.0 * count / blocks.size()) << "% completed" << std::endl; } + std::cerr << std::endl; new_db->endSave(); + delete old_db; delete new_db; actionstream << "Successfully migrated " << count << " blocks" << std::endl; @@ -984,3 +966,4 @@ static bool migrate_database(const GameParams &game_params, const Settings &cmd_ return true; } + diff --git a/src/map.cpp b/src/map.cpp index e58ae2cf..e80c8252 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2018,20 +2018,7 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer conf.set("backend", "sqlite3"); } std::string backend = conf.get("backend"); - if (backend == "dummy") - dbase = new Database_Dummy(); - else if (backend == "sqlite3") - dbase = new Database_SQLite3(savedir); - #if USE_LEVELDB - else if (backend == "leveldb") - dbase = new Database_LevelDB(savedir); - #endif - #if USE_REDIS - else if (backend == "redis") - dbase = new Database_Redis(conf); - #endif - else - throw BaseException("Unknown map backend"); + dbase = createDatabase(backend, savedir, conf); if (!conf.updateConfigFile(conf_path.c_str())) errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl; @@ -2813,7 +2800,7 @@ plan_b: } bool ServerMap::loadFromFolders() { - if(!dbase->initialized() && + if (!dbase->initialized() && !fs::PathExists(m_savedir + DIR_DELIM + "map.sqlite")) return true; return false; @@ -2989,9 +2976,9 @@ void ServerMap::save(ModifiedState save_level) void ServerMap::listAllLoadableBlocks(std::vector &dst) { - if(loadFromFolders()){ - errorstream<<"Map::listAllLoadableBlocks(): Result will be missing " - <<"all blocks that are stored in flat files"<listAllLoadableBlocks(dst); } @@ -3246,6 +3233,24 @@ bool ServerMap::loadSectorFull(v2s16 p2d) } #endif +Database *ServerMap::createDatabase(const std::string &name, const std::string &savedir, Settings &conf) +{ + if (name == "sqlite3") + return new Database_SQLite3(savedir); + if (name == "dummy") + return new Database_Dummy(); + #if USE_LEVELDB + else if (name == "leveldb") + return new Database_LevelDB(savedir); + #endif + #if USE_REDIS + else if (name == "redis") + return new Database_Redis(conf); + #endif + else + throw BaseException(std::string("Database backend ") + name + " not supported."); +} + void ServerMap::beginSave() { dbase->beginSave(); diff --git a/src/map.h b/src/map.h index 073f9314..a4fd8406 100644 --- a/src/map.h +++ b/src/map.h @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/container.h" #include "nodetimer.h" +class Settings; class Database; class ClientMap; class MapSector; @@ -445,6 +446,7 @@ public: /* Database functions */ + static Database *createDatabase(const std::string &name, const std::string &savedir, Settings &conf); // Verify we can read/write to the database void verifyDatabase();