diff --git a/bin/config/settings_zone.xml b/bin/config/settings_zone.xml
index 2b0a3a4a..fee76340 100644
--- a/bin/config/settings_zone.xml
+++ b/bin/config/settings_zone.xml
@@ -14,6 +14,8 @@
root
sapphire
+ 2
+ 2
diff --git a/src/libraries b/src/libraries
index 5512f4d4..5a9881ae 160000
--- a/src/libraries
+++ b/src/libraries
@@ -1 +1 @@
-Subproject commit 5512f4d48186cf0796449215a5b03d3229ec9b31
+Subproject commit 5a9881aee513b1daed1598755225fb2a5b59221b
diff --git a/src/servers/Server_Common/Database/CharaDbConnection.cpp b/src/servers/Server_Common/Database/CharaDbConnection.cpp
new file mode 100644
index 00000000..ede6b909
--- /dev/null
+++ b/src/servers/Server_Common/Database/CharaDbConnection.cpp
@@ -0,0 +1,24 @@
+#include "CharaDbConnection.h"
+#include
+
+Core::Db::CharaDbConnection::CharaDbConnection( ConnectionInfo& connInfo ) : DbConnection( connInfo )
+{
+}
+
+Core::Db::CharaDbConnection::CharaDbConnection( Core::LockedWaitQueue< Operation * >* q,
+ ConnectionInfo& connInfo) : DbConnection( q, connInfo )
+{
+}
+
+Core::Db::CharaDbConnection::~CharaDbConnection()
+{
+}
+
+void Core::Db::CharaDbConnection::doPrepareStatements()
+{
+ if( !m_reconnecting )
+ m_stmts.resize( MAX_STATEMENTS );
+
+ prepareStatement( CHAR_INS_TEST, "INSERT INTO zoneservers ( id, ip, port ) VALUES ( ?, ?, ?);", CONNECTION_BOTH );
+
+}
\ No newline at end of file
diff --git a/src/servers/Server_Common/Database/CharaDbConnection.h b/src/servers/Server_Common/Database/CharaDbConnection.h
new file mode 100644
index 00000000..847427f1
--- /dev/null
+++ b/src/servers/Server_Common/Database/CharaDbConnection.h
@@ -0,0 +1,36 @@
+#ifndef SAPPHIRE_CHARACONNECTION_H
+#define SAPPHIRE_CHARACONNECTION_H
+
+#include "DbConnection.h"
+
+namespace Core
+{
+namespace Db
+{
+class DbConnectionInfo;
+
+enum CharaDbStatements : uint32_t
+{
+ CHAR_INS_TEST,
+
+ MAX_STATEMENTS
+};
+
+class CharaDbConnection : public DbConnection
+{
+public:
+ typedef CharaDbStatements Statements;
+
+ CharaDbConnection( ConnectionInfo& connInfo );
+ CharaDbConnection( Core::LockedWaitQueue< Operation* >* q, ConnectionInfo &connInfo );
+
+ ~CharaDbConnection();
+
+ void doPrepareStatements() override;
+
+};
+
+}
+}
+
+#endif //SAPPHIRE_CHARACONNECTION_H
diff --git a/src/servers/Server_Common/Database/DbConnection.cpp b/src/servers/Server_Common/Database/DbConnection.cpp
new file mode 100644
index 00000000..f3045d3f
--- /dev/null
+++ b/src/servers/Server_Common/Database/DbConnection.cpp
@@ -0,0 +1,244 @@
+#include "DbConnection.h"
+#include "DbWorker.h"
+#include "src/libraries/sapphire/mysqlConnector/MySqlConnector.h"
+
+#include "src/servers/Server_Common/Logging/Logger.h"
+#include "PreparedStatement.h"
+
+
+extern Core::Logger g_log;
+
+Core::Db::DbConnection::DbConnection( ConnectionInfo &connInfo ) :
+ m_reconnecting( false ),
+ m_prepareError( false ),
+ m_queue( nullptr ),
+ m_pConnection( nullptr ),
+ m_connectionInfo( connInfo ),
+ m_connectionFlags( CONNECTION_SYNCH )
+{
+
+}
+
+Core::Db::DbConnection::DbConnection( Core::LockedWaitQueue* queue, Core::Db::ConnectionInfo& connInfo ) :
+ m_reconnecting( false ),
+ m_prepareError( false ),
+ m_queue( queue ),
+ m_pConnection( nullptr ),
+ m_connectionInfo( connInfo ),
+ m_connectionFlags( CONNECTION_ASYNC )
+{
+ m_worker = std::unique_ptr< DbWorker >( new DbWorker( m_queue, this ) );
+}
+
+Core::Db::DbConnection::~DbConnection()
+{
+ close();
+}
+
+void Core::Db::DbConnection::close()
+{
+ m_worker.reset();
+ m_stmts.clear();
+
+ if( m_pConnection )
+ {
+ m_pConnection->close();
+ m_pConnection.reset();
+ }
+
+
+}
+
+uint32_t Core::Db::DbConnection::open()
+{
+ Mysql::MySqlBase base;
+ Mysql::optionMap options;
+ options[ MYSQL_OPT_RECONNECT ] = "1";
+ options[ MYSQL_SET_CHARSET_NAME ] = "utf8";
+
+ try
+ {
+ m_pConnection = std::shared_ptr< Mysql::Connection >( base.connect( m_connectionInfo.host,
+ m_connectionInfo.user,
+ m_connectionInfo.password,
+ options,
+ m_connectionInfo.port ) );
+ m_pConnection->setSchema( m_connectionInfo.database );
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ return 1;
+ }
+
+ return 0;
+}
+
+uint32_t Core::Db::DbConnection::getLastError()
+{
+ return m_pConnection->getErrorNo();
+}
+
+void Core::Db::DbConnection::ping()
+{
+ m_pConnection->ping();
+}
+
+bool Core::Db::DbConnection::lockIfReady()
+{
+ return m_mutex.try_lock();
+}
+
+void Core::Db::DbConnection::unlock()
+{
+ m_mutex.unlock();
+}
+
+void Core::Db::DbConnection::beginTransaction()
+{
+ m_pConnection->beginTransaction();
+}
+
+void Core::Db::DbConnection::rollbackTransaction()
+{
+ m_pConnection->rollbackTransaction();
+}
+
+void Core::Db::DbConnection::commitTransaction()
+{
+ m_pConnection->commitTransaction();
+}
+
+bool Core::Db::DbConnection::execute( const std::string& sql )
+{
+ try
+ {
+ Mysql::Statement* stmt( m_pConnection->createStatement() );
+ bool result = stmt->execute( sql );
+ return result;
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ return false;
+ }
+}
+
+Mysql::ResultSet *Core::Db::DbConnection::query( const std::string& sql )
+{
+ try
+ {
+ Mysql::Statement* stmt( m_pConnection->createStatement() );
+ Mysql::ResultSet* result = stmt->executeQuery( sql );
+ return result;
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ return nullptr;
+ }
+}
+
+
+Mysql::ResultSet* Core::Db::DbConnection::query( Core::Db::PreparedStatement* stmt )
+{
+ Mysql::ResultSet* res = nullptr;
+ if( !stmt )
+ return nullptr;
+
+ uint32_t index = stmt->getIndex();
+
+ Mysql::PreparedStatement* pStmt = getPreparedStatement( index );
+
+ if( !pStmt )
+ return nullptr;
+
+ stmt->setMysqlPS( pStmt );
+ try
+ {
+ stmt->bindParameters();
+ return pStmt->executeQuery();
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ return nullptr;
+ }
+
+}
+
+bool Core::Db::DbConnection::execute( Core::Db::PreparedStatement* stmt )
+{
+ if( !stmt )
+ return false;
+
+ uint32_t index = stmt->getIndex();
+
+ Mysql::PreparedStatement* pStmt = getPreparedStatement( index );
+
+ if( !pStmt )
+ return false;
+
+ stmt->setMysqlPS( pStmt );
+ try
+ {
+ stmt->bindParameters();
+ return pStmt->execute();
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ return nullptr;
+ }
+}
+
+Mysql::PreparedStatement* Core::Db::DbConnection::getPreparedStatement( uint32_t index )
+{
+ assert( index < m_stmts.size() );
+ Mysql::PreparedStatement* ret = m_stmts[index].get();
+ if( !ret )
+ nullptr;
+
+ return ret;
+}
+
+void Core::Db::DbConnection::prepareStatement( uint32_t index, const std::string &sql, Core::Db::ConnectionFlags flags )
+{
+ m_queries.insert( PreparedStatementMap::value_type( index, std::make_pair( sql, flags ) ) );
+
+ // Check if specified query should be prepared on this connection
+ // i.e. don't prepare async statements on synchronous connections
+ // to save memory that will not be used.
+ if( !( m_connectionFlags & flags ) )
+ {
+ m_stmts[index].reset();
+ return;
+ }
+
+ Mysql::PreparedStatement* pStmt = nullptr;
+
+ try
+ {
+ pStmt = m_pConnection->prepareStatement( sql );
+ }
+ catch( std::runtime_error& e )
+ {
+ g_log.error( e.what() );
+ m_prepareError = true;
+ }
+
+ m_stmts[index] = std::unique_ptr< Mysql::PreparedStatement >( pStmt );
+
+}
+
+bool Core::Db::DbConnection::prepareStatements()
+{
+ doPrepareStatements();
+ return !m_prepareError;
+}
+
+
+
+
+
+
diff --git a/src/servers/Server_Common/Database/DbConnection.h b/src/servers/Server_Common/Database/DbConnection.h
new file mode 100644
index 00000000..0e623dd0
--- /dev/null
+++ b/src/servers/Server_Common/Database/DbConnection.h
@@ -0,0 +1,107 @@
+#ifndef _SAPPHIRE_DBCONNECTION_H
+#define _SAPPHIRE_DBCONNECTION_H
+
+#include