diff --git a/src/servers/Server_Common/Database/Connection.cpp b/src/servers/Server_Common/Database/Connection.cpp new file mode 100644 index 00000000..3e2ec2ee --- /dev/null +++ b/src/servers/Server_Common/Database/Connection.cpp @@ -0,0 +1,173 @@ +#include "Connection.h" +#include "MySqlBase.h" + +Core::Db::Connection::Connection( MySqlBase * pBase, + const std::string& hostName, + const std::string& userName, + const std::string& password ) : + m_pBase( pBase ), + m_bConnected( false ) +{ + m_pRawCon = mysql_init( nullptr ); + if( mysql_real_connect( m_pRawCon, hostName.c_str(), userName.c_str(), password.c_str(), + nullptr, 3306, nullptr, 0) == nullptr ) + { + throw std::runtime_error( mysql_error( m_pRawCon ) ); + } + m_bConnected = true; + +} + +Core::Db::Connection::Connection( MySqlBase * pBase, + const std::string& hostName, + const std::string& userName, + const std::string& password, + const optionMap& options ) : + m_pBase( pBase ) +{ + m_pRawCon = mysql_init( nullptr ); + for( auto entry : options ) + { + switch( entry.first ) + { + // integer based options + case MYSQL_OPT_CONNECT_TIMEOUT: + case MYSQL_OPT_PROTOCOL: + case MYSQL_OPT_READ_TIMEOUT: + // case MYSQL_OPT_SSL_MODE: + // case MYSQL_OPT_RETRY_COUNT: + case MYSQL_OPT_WRITE_TIMEOUT: + // case MYSQL_OPT_MAX_ALLOWED_PACKET: + // case MYSQL_OPT_NET_BUFFER_LENGTH: + { + uint32_t optVal = std::stoi( entry.second, nullptr, 10 ); + setOption( entry.first, optVal ); + } + break; + + // bool based options + //case MYSQL_ENABLE_CLEARTEXT_PLUGIN: + // case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS: + case MYSQL_OPT_COMPRESS: + case MYSQL_OPT_GUESS_CONNECTION: + case MYSQL_OPT_LOCAL_INFILE: + case MYSQL_OPT_RECONNECT: + // case MYSQL_OPT_SSL_ENFORCE: + // case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: + case MYSQL_OPT_USE_EMBEDDED_CONNECTION: + case MYSQL_OPT_USE_REMOTE_CONNECTION: + case MYSQL_REPORT_DATA_TRUNCATION: + case MYSQL_SECURE_AUTH: + { + my_bool optVal = entry.second == "0" ? 0 : 1; + setOption( entry.first, &optVal ); + } + break; + + // string based options + //case MYSQL_DEFAULT_AUTH: + // case MYSQL_OPT_BIND: + // case MYSQL_OPT_SSL_CA: + // case MYSQL_OPT_SSL_CAPATH: + // case MYSQL_OPT_SSL_CERT: + // case MYSQL_OPT_SSL_CIPHER: + // case MYSQL_OPT_SSL_CRL: + // case MYSQL_OPT_SSL_CRLPATH: + // case MYSQL_OPT_SSL_KEY: + // case MYSQL_OPT_TLS_VERSION: + //case MYSQL_PLUGIN_DIR: + case MYSQL_READ_DEFAULT_FILE: + case MYSQL_READ_DEFAULT_GROUP: + // case MYSQL_SERVER_PUBLIC_KEY: + case MYSQL_SET_CHARSET_DIR: + case MYSQL_SET_CHARSET_NAME: + case MYSQL_SET_CLIENT_IP: + case MYSQL_SHARED_MEMORY_BASE_NAME: + { + setOption( entry.first, entry.second.c_str() ); + } + break; + + default: + throw std::runtime_error( "Unknown option: " + std::to_string( entry.first ) ); + } + + } + + + if( mysql_real_connect( m_pRawCon, hostName.c_str(), userName.c_str(), password.c_str(), + nullptr, 3306, nullptr, 0) == nullptr ) + { + throw std::runtime_error( mysql_error( m_pRawCon ) ); + } + +} + + +Core::Db::Connection::~Connection() +{ +} + +void Core::Db::Connection::setOption( enum mysql_option option, const void *arg ) +{ + + if( mysql_options( m_pRawCon, option, arg ) != 0 ) + throw std::runtime_error( "Connection::setOption failed!" ); + +} + +void Core::Db::Connection::setOption( enum mysql_option option, uint32_t arg ) +{ + + if( mysql_options( m_pRawCon, option, &arg ) != 0 ) + throw std::runtime_error( "Connection::setOption failed!" ); + +} + +void Core::Db::Connection::setOption( enum mysql_option option, const std::string& arg ) +{ + + if( mysql_options( m_pRawCon, option, arg.c_str() ) != 0 ) + throw std::runtime_error( "Connection::setOption failed!" ); + +} + +void Core::Db::Connection::close() +{ + mysql_close( m_pRawCon ); + m_bConnected = false; +} + +bool Core::Db::Connection::isClosed() +{ + return !m_bConnected; +} + +Core::Db::MySqlBase* Core::Db::Connection::getMySqlBase() +{ + return m_pBase; +} + +void Core::Db::Connection::setAutoCommit( bool autoCommit ) +{ + my_bool b = autoCommit == true ? 1 : 0; + if( mysql_autocommit( m_pRawCon, b ) != 0 ) + throw std::runtime_error( "Connection::setAutoCommit failed!" ); +} + +bool Core::Db::Connection::getAutoCommit() +{ + std::string query("SELECT @@autocommit"); + auto res = mysql_real_query( m_pRawCon, query.c_str(), query.length() ); + + if( res != 0 ) + throw std::runtime_error( "Query failed!" ); + + auto pRes = mysql_store_result( m_pRawCon ); + auto row = mysql_fetch_row( pRes ); + + uint32_t ac = atoi( row[0] ); + + return ac == 0 ? false : true; +} + diff --git a/src/servers/Server_Common/Database/Connection.h b/src/servers/Server_Common/Database/Connection.h new file mode 100644 index 00000000..b0610f13 --- /dev/null +++ b/src/servers/Server_Common/Database/Connection.h @@ -0,0 +1,109 @@ +#ifndef SAPPHIRE_CONNECTION_H +#define SAPPHIRE_CONNECTION_H + +#include +#include +#include +#include + +namespace Core +{ +namespace Db +{ + + typedef std::map< enum mysql_option, std::string > optionMap; + class MySqlBase; + + class Connection + { + //Statement * createServiceStmt(); + + public: + + Connection( MySqlBase * pBase, + const std::string& hostName, + const std::string& userName, + const std::string& password ); + + Connection( MySqlBase * pBase, + const std::string& hostName, + const std::string& userName, + const std::string& password, + const optionMap& options ); + + virtual ~Connection(); + + void close(); + bool isClosed(); + + void setOption( enum mysql_option option, const void *arg ); + void setOption( enum mysql_option option, uint32_t arg ); + void setOption( enum mysql_option option, const std::string& arg ); + + MySqlBase *getMySqlBase(); + + void setAutoCommit( bool autoCommit ); + + //// implemented up to this point + + bool getAutoCommit(); + + + void beginTransaction(); + void commitTransaction(); + void rollbackTransaction(); + + //Statement * createStatement(); + + std::string escapeString( const std::string& ); + + + + std::string getSchema(); + void setSchema( const std::string& catalog ); + + void getOption( enum mysql_option option, void * optionValue ); + + std::string getOption( enum mysql_option option ); + + //DatabaseMetaData * getMetaData(); + + //enum_transaction_isolation getTransactionIsolation(); + + //const SQLWarning * getWarnings(); + + bool isReadOnly(); + void setReadOnly( bool readOnly ); + + bool isValid(); + + bool reconnect(); + + //sql::PreparedStatement * prepareStatement(const sql::SQLString& sql); + + //sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys); + + //sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]); + + //sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency); + + //sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]); + + //void setTransactionIsolation(enum_transaction_isolation level); + + std::string getLastStatementInfo(); + + private: + MySqlBase * m_pBase; + MYSQL * m_pRawCon; + bool m_bConnected; + + Connection( const Connection& ); + void operator=( Connection& ); + }; + + +} +} + +#endif //SAPPHIRE_CONNECTION_H diff --git a/src/servers/Server_Common/Database/MySqlBase.cpp b/src/servers/Server_Common/Database/MySqlBase.cpp new file mode 100644 index 00000000..3035ece8 --- /dev/null +++ b/src/servers/Server_Common/Database/MySqlBase.cpp @@ -0,0 +1,26 @@ +#include "MySqlBase.h" +#include "Connection.h" + +Core::Db::MySqlBase::MySqlBase() +{ +} + +Core::Db::MySqlBase::~MySqlBase() +{ + +} + +std::string Core::Db::MySqlBase::getVersionInfo() +{ + return std::string( mysql_get_client_info() ); +} + +Core::Db::Connection * Core::Db::MySqlBase::connect( const std::string& hostName, const std::string& userName, const std::string& password ) +{ + return new Connection( this, hostName, userName, password ); +} + +Core::Db::Connection * Core::Db::MySqlBase::connect( const std::string& hostName, const std::string& userName, const std::string& password, const optionMap& options ) +{ + return new Connection( this, hostName, userName, password, options ); +} diff --git a/src/servers/Server_Common/Database/MySqlBase.h b/src/servers/Server_Common/Database/MySqlBase.h new file mode 100644 index 00000000..f759a014 --- /dev/null +++ b/src/servers/Server_Common/Database/MySqlBase.h @@ -0,0 +1,38 @@ +#ifndef SAPPHIRE_MYSQLBASE_H +#define SAPPHIRE_MYSQLBASE_H + +#include +#include +#include +#include + +namespace Core +{ +namespace Db +{ + +typedef std::map< enum mysql_option, std::string > optionMap; + +class Connection; + +class MySqlBase +{ +public: + MySqlBase(); + + ~MySqlBase(); + + Connection * connect( const std::string& hostName, const std::string& userName, const std::string& password ); + Connection * connect( const std::string& hostName, const std::string& userName, const std::string& password, const optionMap& map ); + + std::string getVersionInfo(); + +private: + MySqlBase(const MySqlBase &); + void operator=(MySqlBase &); +}; + +} +} + +#endif //SAPPHIRE_MYSQLBASE_H diff --git a/src/servers/Server_Zone/ServerZone.cpp b/src/servers/Server_Zone/ServerZone.cpp index 8d5bb5dc..0c5bb3df 100644 --- a/src/servers/Server_Zone/ServerZone.cpp +++ b/src/servers/Server_Zone/ServerZone.cpp @@ -8,6 +8,9 @@ #include #include +#include +#include + #include #include #include @@ -155,6 +158,37 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] ) return false; } + try + { + Core::Db::MySqlBase base; + g_log.info( base.getVersionInfo() ); + + Core::Db::optionMap options; + options[ MYSQL_OPT_RECONNECT ] = "1"; + + auto con = base.connect( "127.0.0.1", "root", "", options ); + + if( con->getAutoCommit() ) + g_log.info( "autocommit active" ); + + con->setAutoCommit( false ); + + if( !con->getAutoCommit() ) + g_log.info( "autocommit inactive" ); + + con->setAutoCommit( true ); + + if( con->getAutoCommit() ) + g_log.info( "autocommit active" ); + + + } + catch( std::runtime_error e ) + { + g_log.error( e.what() ); + } + + Db::DatabaseParams params; params.bufferSize = 16384; params.connectionCount = 3;