From bbd91a5bec1648dcd6cd9c44c39a5823b8e08e35 Mon Sep 17 00:00:00 2001 From: mordred Date: Sun, 25 Nov 2018 16:45:48 +0100 Subject: [PATCH] Begin of db manager tool --- src/dbm/CMakeLists.txt | 31 +++++++ src/dbm/DbManager.cpp | 69 +++++++++++++++ src/dbm/DbManager.h | 49 +++++++++++ src/dbm/main.cpp | 189 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 338 insertions(+) create mode 100644 src/dbm/CMakeLists.txt create mode 100644 src/dbm/DbManager.cpp create mode 100644 src/dbm/DbManager.h create mode 100644 src/dbm/main.cpp diff --git a/src/dbm/CMakeLists.txt b/src/dbm/CMakeLists.txt new file mode 100644 index 00000000..0736265e --- /dev/null +++ b/src/dbm/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.0) +cmake_policy(SET CMP0015 NEW) +project(sapphire_dbm) + +file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*" ) +file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") + +add_executable(sapphire_dbm ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) + +set_target_properties(sapphire_dbm PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS ON + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/" + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/" + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/" +) + +target_include_directories( sapphire_dbm + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/" + PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/../" ) + target_link_libraries( sapphire_dbm PRIVATE mysqlConnector common xivdat ) +if (UNIX) + target_link_libraries( sapphire_dbm PRIVATE stdc++fs ) +else() + target_link_libraries( sapphire_dbm PRIVATE mysql ) +endif() + diff --git a/src/dbm/DbManager.cpp b/src/dbm/DbManager.cpp new file mode 100644 index 00000000..7035e29f --- /dev/null +++ b/src/dbm/DbManager.cpp @@ -0,0 +1,69 @@ +#include "DbManager.h" +#include +DbManager::DbManager( const std::string& host, const std::string& database, const std::string& user, const std::string& pw, uint16_t port ) : + m_host( host ), + m_database( database ), + m_user( user ), + m_password( pw ), + m_port( port ) +{ +} + +DbManager::~DbManager() +{ + +} + +bool DbManager::connect() +{ + std::shared_ptr< Mysql::MySqlBase > base( new Mysql::MySqlBase() ); + Mysql::optionMap options; + options[ Mysql::MYSQL_OPT_RECONNECT ] = "1"; + options[ Mysql::MYSQL_SET_CHARSET_NAME ] = "utf8"; + + try + { + m_pConnection = base->connect( m_host, m_user, m_password, options, m_port ); + } + catch( std::runtime_error& e ) + { + m_lastError = e.what(); + return false; + } + return true; +} + +bool DbManager::selectSchema() +{ + if( !m_pConnection ) + { + m_lastError = "No valid db connection!"; + return false; + } + + try + { + m_pConnection->setSchema( m_database ); + } + catch( std::runtime_error& e ) + { + m_lastError = e.what(); + return false; + } + return true; +} + +const std::string& DbManager::getLastError() +{ + return m_lastError; +} + +void DbManager::setMode( Mode mode ) +{ + m_mode = mode; +} + +Mode DbManager::getMode() const +{ + return m_mode; +} diff --git a/src/dbm/DbManager.h b/src/dbm/DbManager.h new file mode 100644 index 00000000..7c6cd2eb --- /dev/null +++ b/src/dbm/DbManager.h @@ -0,0 +1,49 @@ +#ifndef SAPPHIRE_DBMANAGER +#define SAPPHIRE_DBMANAGER +#include +#include +#include + +namespace Mysql +{ + class Connection; +} + +enum class Mode +{ + INIT, + LIQUIDATE, + UPDATE, + CHECK, + CLEAN_CHARS +}; + +class DbManager +{ + public: + DbManager( const std::string& host, const std::string& database, const std::string& user, const std::string& pw, uint16_t port ); + + void setMode( Mode mode ); + Mode getMode() const; + + bool connect(); + bool selectSchema(); + + virtual ~DbManager(); + + const std::string& getLastError(); + + private: + std::string m_host; + std::string m_database; + std::string m_user; + std::string m_password; + uint16_t m_port; + std::shared_ptr< Mysql::Connection > m_pConnection; + std::string m_lastError; + Mode m_mode; +}; + + + +#endif diff --git a/src/dbm/main.cpp b/src/dbm/main.cpp new file mode 100644 index 00000000..d7e337c9 --- /dev/null +++ b/src/dbm/main.cpp @@ -0,0 +1,189 @@ + +#include +#include +#include +#include +#include +#include + + +namespace filesys = std::experimental::filesystem; + +#include +#include +#include +#include + +#include "DbManager.h" + +Core::Logger g_log; + +std::vector< std::string > getAllFilesInDir( const std::string& dirPath, + const std::vector< std::string > dirSkipList = {} ) +{ + + // Create a vector of string + std::vector< std::string > listOfFiles; + try + { + // Check if given path exists and points to a directory + if( filesys::exists( dirPath ) && filesys::is_directory( dirPath ) ) + { + // Create a Recursive Directory Iterator object and points to the starting of directory + filesys::recursive_directory_iterator iter( dirPath ); + + // Create a Recursive Directory Iterator object pointing to end. + filesys::recursive_directory_iterator end; + + // Iterate till end + while( iter != end ) + { + // Check if current entry is a directory and if exists in skip list + if( filesys::is_directory( iter->path() ) && + ( std::find( dirSkipList.begin(), dirSkipList.end(), iter->path().filename() ) != dirSkipList.end() ) ) + { + // Skip the iteration of current directory pointed by iterator +#ifdef USING_BOOST + // Boost Fileystsem API to skip current directory iteration + iter.no_push(); +#else + // c++17 Filesystem API to skip current directory iteration + iter.disable_recursion_pending(); +#endif + } + else + { + // Add the name in vector + listOfFiles.push_back( iter->path().string() ); + } + + std::error_code ec; + // Increment the iterator to point to next entry in recursive iteration + iter.increment( ec ); + if( ec ) + { + std::cerr << "Error While Accessing : " << iter->path().string() << " :: " << ec.message() << '\n'; + } + } + } + } + catch( std::system_error& e ) + { + std::cerr << "Exception :: " << e.what(); + } + return listOfFiles; +} + +std::string delChar( std::string &str, char del ) +{ + str.erase( std::remove( str.begin(), str.end(), del ), str.end() ); + return str; +} + +void printUsage() +{ + g_log.info( " Usage: sapphire_dbm " ); + g_log.info( "\t --mode" ); + g_log.info( "\t\t initialize -> Creates DB if not present and inserts default tables/data" ); + g_log.info( "\t\t check -> Checks if Sapphire DB-Version matches your DB-Version" ); + g_log.info( "\t\t update -> Updates your DB-Version to Sapphire DB-Version" ); + g_log.info( "\t\t clearchars -> Removes all character data from DB. Accounts will stay untouched" ); + g_log.info( "\t\t liquidate -> Removes all tables and deletes the DB" ); + g_log.info( "\t --user " ); + g_log.info( "\t --pass ( default empty )" ); + g_log.info( "\t --host ( default 127.0.0.1 )" ); + g_log.info( "\t --port ( default 3306 )" ); + g_log.info( "\t --database " ); + +} + +int main( int32_t argc, char* argv[] ) +{ + std::string arg( "" ); + std::string val( "" ); + + std::string mode; + std::string user; + std::string host; + std::string database; + + g_log.setLogPath( "log/SapphireDbm" ); + g_log.init(); + + + std::vector< std::string > args( argv + 1, argv + argc ); + for( uint32_t i = 0; i + 1 < args.size(); i += 2 ) + { + arg = std::string( args[ i ] ); + val = std::string( args[ i + 1 ] ); + + // trim '-' from start of arg + arg = arg.erase( 0, arg.find_first_not_of( '-' ) ); + if( arg == "mode" ) + mode = val; + else if( arg == "user" ) + user = val; + else if( arg == "host" ) + host = val; + else if( arg == "database" ) + database = val; + } + + if( host.empty() ) + host = "127.0.0.1"; + + if( mode.empty() || user.empty() || database.empty() ) + { + printUsage(); + return 0; + } + + auto dbm = DbManager( host, database, user, "", 3306 ); + + //initialize|check|update|clearchars|liquidate + if( mode.find( "initialize" ) != std::string::npos ) + { + dbm.setMode( Mode::INIT ); + } + else if( mode.find( "check" ) != std::string::npos ) + { + dbm.setMode( Mode::CHECK ); + } + else if( mode.find( "update" ) != std::string::npos ) + { + dbm.setMode( Mode::UPDATE ); + } + else if( mode.find( "clearchars" ) != std::string::npos ) + { + dbm.setMode( Mode::CLEAN_CHARS ); + } + else if( mode.find( "liquidate" ) != std::string::npos ) + { + dbm.setMode( Mode::LIQUIDATE ); + } + else + { + g_log.fatal( "Not a valid mode: " + mode + " !" ); + return 0; + } + + g_log.info( "Launching in " + mode + " mode..." ); + + if( !dbm.connect() ) + { + g_log.fatal( "Could not connect to server!" ); + g_log.fatal( dbm.getLastError() ); + return 0; + } + + if( !dbm.selectSchema() ) + { + g_log.fatal( "Could not set schema!" ); + g_log.fatal( dbm.getLastError() ); + return 0; + } + + + + return 0; +}