1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 14:37:44 +00:00

First iteration of new mysql wrapper

This commit is contained in:
Mordred 2017-09-19 00:02:14 +02:00
parent 522dc15c39
commit 40bc05cf71
12 changed files with 843 additions and 12 deletions

View file

@ -1,5 +1,9 @@
#include "Connection.h"
#include "MySqlBase.h"
#include "Statement.h"
#include <vector>
#include <boost/scoped_array.hpp>
Core::Db::Connection::Connection( MySqlBase * pBase,
const std::string& hostName,
@ -174,3 +178,52 @@ bool Core::Db::Connection::getAutoCommit()
return ac != 0;
}
void Core::Db::Connection::beginTransaction()
{
}
void Core::Db::Connection::commitTransaction()
{
}
void Core::Db::Connection::rollbackTransaction()
{
}
std::string Core::Db::Connection::escapeString( const std::string &inData )
{
boost::scoped_array< char > buffer( new char[inData.length() * 2 + 1] );
if( !buffer.get() )
return "";
unsigned long return_len = mysql_real_escape_string( m_pRawCon, buffer.get(),
inData.c_str(), static_cast< unsigned long > ( inData.length() ) );
return std::string( buffer.get(), return_len );
}
void Core::Db::Connection::setSchema( const std::string &schema )
{
if( mysql_select_db( m_pRawCon, schema.c_str() ) != 0 )
throw std::runtime_error( "Current database could not be changed to " + schema );
}
Core::Db::Statement *Core::Db::Connection::createStatement()
{
return new Statement( this );
}
MYSQL *Core::Db::Connection::getRawCon()
{
return m_pRawCon;
}
std::string Core::Db::Connection::getError()
{
auto mysqlError = mysql_error( m_pRawCon );
if( mysqlError )
return std::string( mysqlError );
return "";
}

View file

@ -6,6 +6,7 @@
#include <mysql.h>
#include <map>
namespace Core
{
namespace Db
@ -13,6 +14,7 @@ namespace Db
typedef std::map< enum mysql_option, std::string > optionMap;
class MySqlBase;
class Statement;
class Connection
{
@ -45,28 +47,27 @@ namespace Db
void setAutoCommit( bool autoCommit );
bool getAutoCommit();
std::string escapeString( const std::string& inData );
void setSchema( const std::string& catalog );
Statement * createStatement();
//// implemented up to this point
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();
std::string getError();
bool isReadOnly();
void setReadOnly( bool readOnly );
@ -89,7 +90,9 @@ namespace Db
std::string getLastStatementInfo();
private:
MYSQL * getRawCon();
private:
MySqlBase * m_pBase;
MYSQL * m_pRawCon;
bool m_bConnected;

View file

@ -28,8 +28,8 @@ public:
std::string getVersionInfo();
private:
MySqlBase(const MySqlBase &);
void operator=(MySqlBase &);
MySqlBase( const MySqlBase& );
void operator=( MySqlBase& );
};
}

View file

@ -0,0 +1,274 @@
#include "ResultSet.h"
#include "Connection.h"
#include "Statement.h"
#include "mysql_util.h"
#include <cctype>
#include <clocale>
#include <vector>
Core::Db::ResultSet::ResultSet( MYSQL_RES *res, Core::Db::Statement *par )
{
m_pRes = res;
m_numRows = mysql_num_rows( res );
m_numFields = mysql_num_fields( res );
m_pStmt = par;
m_rowPosition = 1;
for (unsigned int i = 0; i < m_numFields; ++i)
{
std::string fieldName( getFieldMeta(i + 1)->name );
std::transform( fieldName.begin(), fieldName.end(), fieldName.begin(),
[](unsigned char c){ return std::toupper(c); } );
m_fieldNameToIndex[fieldName] = i;
}
}
Core::Db::ResultSet::~ResultSet()
{
mysql_free_result( m_pRes );
}
MYSQL_FIELD* Core::Db::ResultSet::getFieldMeta( unsigned int columnIndex ) const
{
return mysql_fetch_field_direct( m_pRes, columnIndex - 1 );
}
uint32_t Core::Db::ResultSet::findColumn( const std::string &columnLabel ) const
{
std::string searchColumn = columnLabel;
std::transform( searchColumn.begin(), searchColumn.end(), searchColumn.begin(),
[](unsigned char c){ return std::toupper(c); } );
auto iter = m_fieldNameToIndex.find( searchColumn );
if( iter == m_fieldNameToIndex.end() )
return 0;
return iter->second + 1;
}
size_t Core::Db::ResultSet::getRow() const
{
return static_cast< size_t >( m_rowPosition );
}
bool Core::Db::ResultSet::isLast() const
{
return ( m_rowPosition == m_numRows );
}
bool Core::Db::ResultSet::isFirst() const
{
return ( m_rowPosition == 1 );
}
bool Core::Db::ResultSet::next()
{
bool ret = false;
m_lastQueriedColumn = -1;
m_row = mysql_fetch_row( m_pRes );
if( m_row == nullptr )
{
if( m_pStmt->errNo() == 2013 || m_pStmt->errNo() == 2000 )
throw std::runtime_error( "Error fetching next row " + std::to_string( m_pStmt->errNo() ) +
": " + m_pStmt->getConnection()->getError() );
}
if( ( ret = ( m_row != nullptr ) ) )
++m_rowPosition;
else
m_rowPosition = 0;
return ret;
}
size_t Core::Db::ResultSet::rowsCount() const
{
return static_cast< uint32_t >( m_numRows );
}
const Core::Db::Statement *Core::Db::ResultSet::getStatement() const
{
return m_pStmt;
}
int64_t Core::Db::ResultSet::getInt64( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getInt64: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( m_row[columnIndex - 1] == nullptr )
{
m_wasNull = true;
return 0;
}
m_wasNull = false;
if( getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT &&
getFieldMeta(columnIndex)->flags != ( BINARY_FLAG | UNSIGNED_FLAG ) )
{
uint64_t uval = 0;
std::div_t length = std::div( getFieldMeta( columnIndex )->length, 8 );
if( length.rem != 0 )
++length.quot;
switch( length.quot )
{
case 8:uval = (uint64_t) bit_uint8korr( m_row[columnIndex - 1] );break;
case 7:uval = (uint64_t) bit_uint7korr( m_row[columnIndex - 1] );break;
case 6:uval = (uint64_t) bit_uint6korr( m_row[columnIndex - 1] );break;
case 5:uval = (uint64_t) bit_uint5korr( m_row[columnIndex - 1] );break;
case 4:uval = (uint64_t) bit_uint4korr( m_row[columnIndex - 1] );break;
case 3:uval = (uint64_t) bit_uint3korr( m_row[columnIndex - 1] );break;
case 2:uval = (uint64_t) bit_uint2korr( m_row[columnIndex - 1] );break;
case 1:uval = (uint64_t) bit_uint1korr( m_row[columnIndex - 1] );break;
}
return uval;
}
if( getFieldMeta( columnIndex)->flags & UNSIGNED_FLAG )
return strtoull( m_row[columnIndex - 1], nullptr, 10 );
return strtoll( m_row[columnIndex - 1], nullptr, 10 );
}
int64_t Core::Db::ResultSet::getInt64( const std::string &columnLabel ) const
{
return getInt64( findColumn( columnLabel ) );
}
uint64_t Core::Db::ResultSet::getUInt64( uint32_t columnIndex ) const
{
return static_cast< uint64_t >( getInt64( columnIndex ) );
}
uint64_t Core::Db::ResultSet::getUInt64( const std::string &columnLabel ) const
{
return getUInt64( findColumn( columnLabel ) );
}
int32_t Core::Db::ResultSet::getInt( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getInt: invalid value of 'columnIndex'" );
if( ( getFieldMeta( columnIndex )->flags & UNSIGNED_FLAG ) != 0 )
return static_cast< uint32_t >( getInt64( columnIndex ) );
return static_cast< int32_t >( getInt64( columnIndex ) );
}
int32_t Core::Db::ResultSet::getInt( const std::string &columnLabel ) const
{
return getInt( findColumn( columnLabel ) );
}
uint32_t Core::Db::ResultSet::getUInt( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getUInt: invalid value of 'columnIndex'" );
return static_cast< uint32_t >( getUInt64( columnIndex ) );
}
uint32_t Core::Db::ResultSet::getUInt( const std::string &columnLabel ) const
{
return getUInt( findColumn( columnLabel ) );
}
long double Core::Db::ResultSet::getDouble( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getDouble: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( m_row[columnIndex - 1] == nullptr )
{
m_wasNull = true;
return 0.0;
}
m_wasNull = false;
if( getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT )
return static_cast< long double >( getInt64( columnIndex ) );
return strtonum( m_row[columnIndex - 1] );
}
long double Core::Db::ResultSet::getDouble( const std::string &columnLabel ) const
{
return getDouble( findColumn( columnLabel ) );
}
bool Core::Db::ResultSet::getBoolean( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getBoolean: invalid value of 'columnIndex'" );
return getInt( columnIndex ) ? true : false;
}
bool Core::Db::ResultSet::getBoolean( const std::string &columnLabel ) const
{
return getInt( columnLabel ) ? true : false;
}
std::string Core::Db::ResultSet::getString( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getString: invalid value of 'columnIndex'" );
if( m_row == nullptr || m_row[columnIndex - 1] == nullptr )
{
m_wasNull = true;
return "";
}
if( getFieldMeta( columnIndex )->type == MYSQL_TYPE_BIT )
{
char buf[30];
snprintf( buf, sizeof( buf ) - 1, "%llu", ( unsigned long long ) getUInt64( columnIndex ) );
return std::string( buf );
}
size_t len = mysql_fetch_lengths( m_pRes )[columnIndex - 1];
m_wasNull = false;
return std::string( m_row[columnIndex - 1], len );
}
std::string Core::Db::ResultSet::getString( const std::string &columnLabel ) const
{
return getString( findColumn( columnLabel ) );
}
bool Core::Db::ResultSet::isNull( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::isNull: invalid value of 'columnIndex'" );
return ( m_row[columnIndex - 1] == nullptr );
}
bool Core::Db::ResultSet::isNull( const std::string &columnLabel ) const
{
return isNull( findColumn( columnLabel ) );
}
std::istream* Core::Db::ResultSet::getBlob( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getBlob: invalid value of 'columnIndex'" );
return new std::istringstream( getString( columnIndex ) );
}
std::istream* Core::Db::ResultSet::getBlob( const std::string& columnLabel ) const
{
return new std::istringstream( getString( columnLabel ) );
}

View file

@ -0,0 +1,102 @@
#ifndef SAPPHIRE_RESULTSET_H
#define SAPPHIRE_RESULTSET_H
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "ResultSetBase.h"
#include <mysql.h>
namespace Core
{
namespace Db
{
class Statement;
//class ResultSetMetaData;
class ResultSet : public ResultSetBase
{
MYSQL_ROW m_row;
uint32_t m_numFields;
uint64_t m_numRows;
uint64_t m_rowPosition;
typedef std::map< std::string, uint32_t > FieldNameIndexMap;
FieldNameIndexMap m_fieldNameToIndex;
mutable bool m_wasNull;
mutable uint32_t m_lastQueriedColumn;
Statement* m_pStmt;
MYSQL_RES* m_pRes;
//boost::scoped_ptr< MySQL_ResultSetMetaData > rs_meta;
protected:
MYSQL_FIELD* getFieldMeta( unsigned int columnIndex ) const;
public:
ResultSet( MYSQL_RES* res, Statement* par );
virtual ~ResultSet();
uint32_t findColumn( const std::string& columnLabel ) const;
std::istream * getBlob( uint32_t columnIndex ) const;
std::istream * getBlob( const std::string& columnLabel ) const;
bool getBoolean( uint32_t columnIndex ) const;
bool getBoolean( const std::string& columnLabel ) const;
long double getDouble( uint32_t columnIndex ) const;
long double getDouble( const std::string& columnLabel ) const;
int32_t getInt( uint32_t columnIndex ) const;
int32_t getInt( const std::string& columnLabel ) const;
uint32_t getUInt( uint32_t columnIndex ) const;
uint32_t getUInt( const std::string& columnLabel ) const;
int64_t getInt64( uint32_t columnIndex ) const;
int64_t getInt64( const std::string& columnLabel ) const;
uint64_t getUInt64( uint32_t columnIndex ) const;
uint64_t getUInt64( const std::string& columnLabel ) const;
//sql::ResultSetMetaData * getMetaData() const;
size_t getRow() const;
const Statement * getStatement() const;
std::string getString( uint32_t columnIndex ) const;
std::string getString( const std::string& columnLabel ) const;
bool isFirst() const;
bool isLast() const;
bool isNull( uint32_t columnIndex ) const;
bool isNull( const std::string& columnLabel ) const;
bool next();
size_t rowsCount() const;
private:
ResultSet( const ResultSet& );
void operator=( ResultSet& );
};
}
}
#endif //SAPPHIRE_RESULTSET_H

View file

@ -0,0 +1,70 @@
#ifndef SAPPHIRE_RESULTSETBASE_H
#define SAPPHIRE_RESULTSETBASE_H
#include <list>
#include <map>
#include <iostream>
namespace Core
{
namespace Db
{
class Statement;
class ResultSetBase
{
public:
virtual ~ResultSetBase() {}
virtual uint32_t findColumn( const std::string &columnLabel ) const = 0;
virtual std::istream *getBlob( uint32_t columnIndex ) const = 0;
virtual std::istream *getBlob( const std::string &columnLabel ) const = 0;
virtual bool getBoolean( uint32_t columnIndex ) const = 0;
virtual bool getBoolean( const std::string &columnLabel ) const = 0;
virtual long double getDouble( uint32_t columnIndex ) const = 0;
virtual long double getDouble( const std::string &columnLabel ) const = 0;
virtual int32_t getInt( uint32_t columnIndex ) const = 0;
virtual int32_t getInt( const std::string &columnLabel ) const = 0;
virtual uint32_t getUInt( uint32_t columnIndex ) const = 0;
virtual uint32_t getUInt( const std::string &columnLabel ) const = 0;
virtual int64_t getInt64( uint32_t columnIndex ) const = 0;
virtual int64_t getInt64( const std::string &columnLabel ) const = 0;
virtual uint64_t getUInt64( uint32_t columnIndex ) const = 0;
virtual uint64_t getUInt64( const std::string &columnLabel ) const = 0;
//virtual ResultSetMetaData *getMetaData() const = 0;
virtual size_t getRow() const = 0;
virtual const Statement *getStatement() const = 0;
virtual std::string getString( uint32_t columnIndex ) const = 0;
virtual std::string getString( const std::string &columnLabel ) const = 0;
virtual bool isFirst() const = 0;
virtual bool isLast() const = 0;
virtual bool isNull( uint32_t columnIndex ) const = 0;
virtual bool isNull( const std::string &columnLabel ) const = 0;
virtual bool next() = 0;
virtual size_t rowsCount() const = 0;
};
}
}
#endif //SAPPHIRE_RESULTSETBASE_H

View file

@ -0,0 +1,66 @@
#include "Statement.h"
#include "Connection.h"
#include "ResultSet.h"
#include "mysql_util.h"
Core::Db::Connection* Core::Db::Statement::getConnection()
{
return m_pConnection;
}
Core::Db::Statement::Statement( Core::Db::Connection *conn ) :
m_pConnection( conn )
{
}
void Core::Db::Statement::doQuery( const std::string &q )
{
mysql_real_query( m_pConnection->getRawCon(), q.c_str(), q.length() );
if( errNo() )
throw std::runtime_error( m_pConnection->getError() );
m_warningsCount = getWarningCount();
}
bool Core::Db::Statement::execute( const std::string &sql )
{
doQuery( sql );
bool ret = mysql_field_count( m_pConnection->getRawCon() ) == 0;
m_lastUpdateCount = mysql_affected_rows( m_pConnection->getRawCon() );
return ret;
}
uint64_t Core::Db::Statement::getUpdateCount()
{
return m_lastUpdateCount;
}
uint32_t Core::Db::Statement::getWarningCount()
{
return mysql_warning_count( m_pConnection->getRawCon() );
}
uint32_t Core::Db::Statement::errNo()
{
return mysql_errno( m_pConnection->getRawCon() );
}
Core::Db::ResultSet* Core::Db::Statement::executeQuery( const std::string &sql )
{
m_lastUpdateCount = UL64(~0);
doQuery( sql );
return new ResultSet( mysql_store_result( m_pConnection->getRawCon() ), this );
}
Core::Db::ResultSet *Core::Db::Statement::getResultSet()
{
if( errNo() != 0 )
throw std::runtime_error( "Error during getResultSet() : " + std::to_string( errNo() ) + ": " +
m_pConnection->getError() );
return new ResultSet( mysql_store_result( m_pConnection->getRawCon() ), this );
}

View file

@ -0,0 +1,56 @@
#ifndef SAPPHIRE_STATEMENT_H
#define SAPPHIRE_STATEMENT_H
#include <stdint.h>
#include <string>
#include "StatementBase.h"
namespace Core
{
namespace Db
{
class Connection;
class ResultSet;
class Statement : public StatementBase
{
protected:
Connection * m_pConnection;
void doQuery( const std::string& q );
uint64_t m_lastUpdateCount;
unsigned int m_warningsCount;
public:
Statement( Connection* conn );
virtual ~Statement() {};
Connection * getConnection() override;
bool execute( const std::string& sql ) override;
ResultSet * executeQuery( const std::string& sql ) override;
ResultSet * getResultSet() override;
uint64_t getUpdateCount() override;
uint32_t getWarningCount() override;
uint32_t errNo() override;
private:
/* Prevent use of these */
Statement( const Statement& );
void operator=( Statement& );
};
}
}
#endif //SAPPHIRE_STATEMENT_H

View file

@ -0,0 +1,36 @@
#ifndef SAPPHIRE_STATEMENTBASE_H
#define SAPPHIRE_STATEMENTBASE_H
#include <string>
namespace Core
{
namespace Db
{
class Connection;
class ResultSet;
class StatementBase
{
public:
virtual ~StatementBase() {};
virtual Connection* getConnection() = 0;
virtual bool execute( const std::string& sql ) = 0;
virtual ResultSet* executeQuery( const std::string& sql ) = 0;
virtual ResultSet* getResultSet() = 0;
virtual uint64_t getUpdateCount() = 0;
virtual uint32_t getWarningCount() = 0;
virtual uint32_t errNo() = 0;
};
}
}
#endif //SAPPHIRE_STATEMENTBASE_H

View file

@ -0,0 +1,30 @@
#include "mysql_util.h"
long double strtonum( const std::string &str, int radix )
{
typedef std::istreambuf_iterator< char > iter_t;
static std::locale c_locale( "C" );
static const std::num_get< char > &cvt = std::use_facet< std::num_get< char > >( c_locale );
std::istringstream inp( str );
long double val = 0.0L;
inp.imbue( c_locale );
switch( radix )
{
case 10: inp.setf( std::ios_base::dec, std::ios_base::basefield ); break;
case 16: inp.setf( std::ios_base::hex, std::ios_base::basefield ); break;
case 8: inp.setf( std::ios_base::oct, std::ios_base::basefield ); break;
default:
inp.setf( std::ios_base::fmtflags( 0 ), std::ios_base::basefield );
break;
}
iter_t beg( inp ), end;
std::ios::iostate err = std::ios_base::goodbit;
cvt.get( beg, end, inp, err, val );
return val;
}

View file

@ -0,0 +1,110 @@
/*
Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SAPPHIRE_MYSQL_UTIL_H
#define SAPPHIRE_MYSQL_UTIL_H
#include <iostream>
#include <sstream>
#ifndef UL64
#ifdef _WIN32
#define UL64(x) x##ui64
#else
#define UL64(x) x##ULL
#endif
#endif
#ifndef L64
#ifdef _WIN32
#define L64(x) x##i64
#else
#define L64(x) x##LL
#endif
#endif
#define NULLCSTR static_cast<char *>(0)
#ifndef _WIN32
# ifndef HAVE_FUNCTION_STRTOLL
# define strtoll(__a, __b, __c) static_cast<long long>(sql::mysql::util::strtold((__a), NULL))
# define HAVE_FUNCTION_STRTOLL 1
# endif
# ifndef HAVE_FUNCTION_STRTOULL
# define strtoull(__a, __b, __c) static_cast<unsigned long long>(sql::mysql::util::strtold((__a), NULL))
# define HAVE_FUNCTION_STRTOULL 1
# endif
#else
# ifndef strtoll
# define strtoll(x, e, b) _strtoi64((x), (e), (b))
# endif
# ifndef strtoull
# define strtoull(x, e, b) _strtoui64((x), (e), (b))
# endif
#endif // _WIN32
#define bit_uint1korr(A) (*(((uint8_t*)(A))))
#define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\
((uint16_t) (((unsigned char*) (A))[0]) << 8)))
#define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
(((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[0])) << 16)))
#define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
(((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[0])) << 24)))
#define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\
(((uint32_t) (((unsigned char*) (A))[3])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[2])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\
(((uint64_t) (((unsigned char*) (A))[0])) << 32))
#define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\
(((uint32_t) (((unsigned char*) (A))[4])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[3])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\
(((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\
(((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\
32))
#define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\
(((uint32_t) (((unsigned char*) (A))[5])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[4])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\
(((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
(((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\
32))
#define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\
(((uint32_t) (((unsigned char*) (A))[6])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[5])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\
(((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
(((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
(((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
(((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\
32))
long double strtonum( const std::string &str, int radix = 10);
#endif //SAPPHIRE_MYSQL_UTIL_H

View file

@ -10,6 +10,8 @@
#include <src/servers/Server_Common/Database/MySqlBase.h>
#include <src/servers/Server_Common/Database/Connection.h>
#include <src/servers/Server_Common/Database/Statement.h>
#include <src/servers/Server_Common/Database/ResultSet.h>
#include <src/servers/Server_Common/Network/Connection.h>
#include <src/servers/Server_Common/Network/Hive.h>
@ -160,13 +162,14 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
try
{
// bunch of test cases for db wrapper
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 );
boost::scoped_ptr< Core::Db::Connection > con( base.connect( "127.0.0.1", "root", "", options ) );
if( con->getAutoCommit() )
g_log.info( "autocommit active" );
@ -181,6 +184,34 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
if( con->getAutoCommit() )
g_log.info( "autocommit active" );
con->setSchema( "sapphire" );
boost::scoped_ptr< Core::Db::Statement > stmt( con->createStatement() );
bool t1 = stmt->execute( "DELETE FROM zoneservers WHERE id = 101" );
t1 = stmt->execute( "INSERT INTO zoneservers ( id, ip, port ) VALUES ( 101, '127.0.0.1', 54555);" );
// t1 = stmt->execute( "INSERT INTO zoneservers ( id, ip, port ) VALUES ( 101, '127.0.0.1', 54555);" ); // throws duplicate entry
t1 = stmt->execute( "DELETE FROM zoneservers WHERE id = 101" );
t1 = stmt->execute( "INSERT INTO zoneservers ( id, ip, port ) VALUES ( 101, '127.0.0.1', 54555);" );
//t1 = stmt->execute( "DELETE FROM zoneservers WHERE id = 101" );
//boost::scoped_ptr< Core::Db::Statement > stmt1( con->createStatement() );
//bool t2 = stmt1->execute( "INSERT INTO BLARGH!" ); // throws error
boost::scoped_ptr< Core::Db::Statement > stmt2( con->createStatement() );
boost::scoped_ptr< Core::Db::ResultSet > res( stmt2->executeQuery( "SELECT id,ip,port FROM zoneservers" ) );
while( res->next() )
{
g_log.info( "id: " + std::to_string( res->getUInt( "id" ) ) );
g_log.info( "ip: " + res->getString( "ip" ) );
g_log.info( "port: " + std::to_string( res->getUInt( "port" ) ) );
// alternatively ( slightly faster )
// g_log.info( "id: " + std::to_string( res->getUInt( 1 ) ) );
// g_log.info( "ip: " + res->getString( 2 ) );
// g_log.info( "port: " + std::to_string( res->getUInt( 3 ) ) );
}
}
catch( std::runtime_error e )