1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-06-07 16:47:44 +00:00

Moved mysqlConnector to libraries

This commit is contained in:
Mordred Admin 2017-09-25 14:44:15 +02:00
parent bfd3cbac3c
commit 2cd801c7cf
25 changed files with 17 additions and 3389 deletions

View file

@ -35,6 +35,7 @@ include( "cmake/compiler.cmake" )
# Common include folders
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/external/ChaiScript-6.0.0/include/")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader/")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/mysqlConnector/")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src")
include_directories("${PROJECT_INCLUDE_DIR}")
@ -48,3 +49,4 @@ link_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader)
add_subdirectory("src/servers")
add_subdirectory("src/libraries/sapphire/datReader")
add_subdirectory("src/libraries/sapphire/mysqlConnector")

View file

@ -29,7 +29,7 @@ set_target_properties(Common PROPERTIES
)
if (UNIX)
target_link_libraries( Common xivdat mysqlclient )
target_link_libraries( Common xivdat mysqlclient mysqlConnector )
else()
target_link_libraries( Common xivdat libmysql )
target_link_libraries( Common xivdat mysqlConnector libmysql )
endif()

View file

@ -1,244 +0,0 @@
#include "Connection.h"
#include "MySqlBase.h"
#include "Statement.h"
#include "PreparedStatement.h"
#include <vector>
#include <boost/scoped_array.hpp>
Core::Db::Connection::Connection( MySqlBase * pBase,
const std::string& hostName,
const std::string& userName,
const std::string& password,
uint16_t port ) :
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, port, 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,
uint16_t port ) :
m_pBase( pBase )
{
m_pRawCon = mysql_init( nullptr );
// Different mysql versions support different options, for now whatever was unsupporter here was commented out
// but left there.
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, port, 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() const
{
return !m_bConnected;
}
Core::Db::MySqlBase* Core::Db::Connection::getMySqlBase() const
{
return m_pBase;
}
void Core::Db::Connection::setAutoCommit( bool autoCommit )
{
auto b = static_cast< my_bool >( autoCommit == true ? 1 : 0 );
if( mysql_autocommit( m_pRawCon, b ) != 0 )
throw std::runtime_error( "Connection::setAutoCommit failed!" );
}
bool Core::Db::Connection::getAutoCommit()
{
// TODO: should be replaced with wrapped sql query function once available
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;
}
void Core::Db::Connection::beginTransaction()
{
boost::scoped_ptr< Statement > stmt( createStatement() );
stmt->execute( "START TRANSACTION;" );
}
void Core::Db::Connection::commitTransaction()
{
boost::scoped_ptr< Statement > stmt( createStatement() );
stmt->execute( "COMMIT" );
}
void Core::Db::Connection::rollbackTransaction()
{
boost::scoped_ptr< Statement > stmt( createStatement() );
stmt->execute( "ROLLBACK" );
}
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 "";
}
Core::Db::PreparedStatement* Core::Db::Connection::prepareStatement( const std::string &sql )
{
MYSQL_STMT* stmt = mysql_stmt_init( getRawCon() );
if( !stmt )
throw std::runtime_error( "Could not init prepared statement: " + this->getError() );
if( mysql_stmt_prepare( stmt, sql.c_str(), sql.size() ) )
throw std::runtime_error( "Could not prepare statement: " + this->getError() );
return new PreparedStatement( stmt, this );
}

View file

@ -1,102 +0,0 @@
#ifndef SAPPHIRE_CONNECTION_H
#define SAPPHIRE_CONNECTION_H
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <mysql.h>
#include <map>
namespace Core
{
namespace Db
{
typedef std::map< enum mysql_option, std::string > optionMap;
class MySqlBase;
class Statement;
class PreparedStatement;
class Connection
{
public:
Connection( MySqlBase * pBase,
const std::string& hostName,
const std::string& userName,
const std::string& password,
uint16_t port = 3306);
Connection( MySqlBase * pBase,
const std::string& hostName,
const std::string& userName,
const std::string& password,
const optionMap& options,
uint16_t port = 3306 );
virtual ~Connection();
void close();
bool isClosed() const;
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() const;
void setAutoCommit( bool autoCommit );
bool getAutoCommit();
std::string escapeString( const std::string& inData );
void setSchema( const std::string& catalog );
Statement * createStatement();
void beginTransaction();
void commitTransaction();
void rollbackTransaction();
std::string getSchema();
//DatabaseMetaData * getMetaData();
std::string getError();
bool isReadOnly();
void setReadOnly( bool readOnly );
bool isValid();
bool reconnect();
PreparedStatement* prepareStatement( const std::string& 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();
MYSQL* getRawCon();
private:
MySqlBase* m_pBase;
MYSQL* m_pRawCon;
bool m_bConnected;
Connection( const Connection& );
void operator=( Connection& );
};
}
}
#endif //SAPPHIRE_CONNECTION_H

View file

@ -1,44 +0,0 @@
#ifndef SAPPHIRE_DATATYPE_H
#define SAPPHIRE_DATATYPE_H
namespace Core
{
namespace Db
{
class DataType
{
DataType();
public:
enum
{
UNKNOWN = 0,
BIT,
TINYINT,
SMALLINT,
MEDIUMINT,
INTEGER,
BIGINT,
REAL,
DOUBLE,
DECIMAL,
NUMERIC,
CHAR,
BINARY,
VARCHAR,
VARBINARY,
LONGVARCHAR,
LONGVARBINARY,
TIMESTAMP,
DATE,
TIME,
YEAR,
GEOMETRY,
ENUM,
SET,
SQLNULL,
JSON
};
};
}
}
#endif //SAPPHIRE_DATATYPE_H

View file

@ -1,26 +0,0 @@
#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 );
}

View file

@ -1,38 +0,0 @@
#ifndef SAPPHIRE_MYSQLBASE_H
#define SAPPHIRE_MYSQLBASE_H
#include <boost/shared_ptr.hpp>
#include <mysql.h>
#include <string>
#include <map>
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

View file

@ -1,624 +0,0 @@
#include "PreparedResultSet.h"
#include "ResultBind.h"
#include "DataType.h"
#include <string>
#include <cctype>
#include <clocale>
#include <string.h>
namespace
{
static inline char * my_l_to_a(char * buf, size_t buf_size, int64_t a)
{
snprintf(buf, buf_size, "%lld", (long long) a);
return buf;
}
static inline char * my_ul_to_a(char * buf, size_t buf_size, uint64_t a)
{
snprintf(buf, buf_size, "%llu", (unsigned long long) a);
return buf;
}
static inline char * my_f_to_a(char * buf, size_t buf_size, double a)
{
snprintf(buf, buf_size, "%f", a);
return buf;
}
}
uint32_t Core::Db::PreparedResultSet::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;
}
Core::Db::PreparedResultSet::PreparedResultSet( boost::shared_ptr< ResultBind >& pBind,
Core::Db::PreparedStatement* par ) :
ResultSet( nullptr, par ),
m_pResultBind( pBind )
{
}
bool Core::Db::PreparedResultSet::isBeforeFirstOrAfterLast() const
{
return ( m_rowPosition == 0 );
}
Core::Db::PreparedResultSet::~PreparedResultSet()
{
}
uint32_t Core::Db::PreparedResultSet::getUInt( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getUInt: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getUInt: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if (*m_pResultBind->m_pBind[columnIndex - 1].is_null) {
return 0;
}
return static_cast< uint32_t >( getUInt64_intern( columnIndex, true ) );
}
uint32_t Core::Db::PreparedResultSet::getUInt( const std::string& columnLabel ) const
{
return getUInt( findColumn( columnLabel ) );
}
int64_t Core::Db::PreparedResultSet::getInt64( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getInt64: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getInt64: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( *m_pResultBind->m_pBind[columnIndex - 1].is_null )
return 0;
return getInt64_intern( columnIndex, true );
}
int64_t Core::Db::PreparedResultSet::getInt64( const std::string& columnLabel ) const
{
return getInt64( findColumn( columnLabel ) );
}
uint64_t Core::Db::PreparedResultSet::getUInt64_intern( const uint32_t columnIndex, bool ) const
{
MYSQL_RES* res = mysql_stmt_result_metadata( m_pStmt->getRawStmt() );
MYSQL_FIELD* field = mysql_fetch_field_direct( res, columnIndex );
switch( Util::mysql_type_to_datatype( field ) )
{
case DataType::REAL:
case DataType::DOUBLE:
return static_cast< uint64_t >( getDouble( columnIndex ) );
case DataType::NUMERIC:
case DataType::DECIMAL:
case DataType::TIMESTAMP:
case DataType::DATE:
case DataType::TIME:
case DataType::CHAR:
case DataType::BINARY:
case DataType::VARCHAR:
case DataType::VARBINARY:
case DataType::LONGVARCHAR:
case DataType::LONGVARBINARY:
case DataType::SET:
case DataType::ENUM:
case DataType::JSON:
return strtoull( getString(columnIndex).c_str(), nullptr, 10 );
case DataType::BIT:
{
uint64_t uval = 0;
/* This length is in bytes, on the contrary to what can be seen in mysql_resultset.cpp where the Meta is used */
switch( *m_pResultBind->m_pBind[columnIndex - 1].length )
{
case 8:uval = (uint64_t) bit_uint8korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 7:uval = (uint64_t) bit_uint7korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 6:uval = (uint64_t) bit_uint6korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 5:uval = (uint64_t) bit_uint5korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 4:uval = (uint64_t) bit_uint4korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 3:uval = (uint64_t) bit_uint3korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 2:uval = (uint64_t) bit_uint2korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 1:uval = (uint64_t) bit_uint1korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
}
return uval;
}
case DataType::YEAR:
case DataType::TINYINT:
case DataType::SMALLINT:
case DataType::MEDIUMINT:
case DataType::INTEGER:
case DataType::BIGINT:
{
uint64_t ret;
bool is_it_null = *m_pResultBind->m_pBind[columnIndex - 1].is_null != 0;
bool is_it_unsigned = m_pResultBind->m_pBind[columnIndex - 1].is_unsigned != 0;
switch( m_pResultBind->m_pBind[columnIndex - 1].buffer_length )
{
case 1:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint8_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int8_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
case 2:
if(is_it_unsigned)
ret = !is_it_null ? *reinterpret_cast< uint16_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int16_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
case 4:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint32_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int32_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
case 8:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint64_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int64_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
default:
throw std::runtime_error( "PreparedResultSet::getInt64_intern: invalid type" );
}
return ret;
}
default:
break;
}
throw std::runtime_error( "MySQL_Prepared_ResultSet::getUInt64_intern: unhandled type. Please, report" );
return 0;
}
int64_t Core::Db::PreparedResultSet::getInt64_intern( const uint32_t columnIndex, bool ) const
{
MYSQL_RES* res = mysql_stmt_result_metadata( m_pStmt->getRawStmt() );
MYSQL_FIELD* field = mysql_fetch_field_direct( res, columnIndex );
switch( Util::mysql_type_to_datatype( field ) )
{
case DataType::REAL:
case DataType::DOUBLE:
return static_cast< int64_t >( getDouble( columnIndex ) );
case DataType::NUMERIC:
case DataType::DECIMAL:
case DataType::TIMESTAMP:
case DataType::DATE:
case DataType::TIME:
case DataType::CHAR:
case DataType::BINARY:
case DataType::VARCHAR:
case DataType::VARBINARY:
case DataType::LONGVARCHAR:
case DataType::LONGVARBINARY:
case DataType::SET:
case DataType::ENUM:
case DataType::JSON:
return strtoll( getString( columnIndex ).c_str(), nullptr, 10 );
case DataType::BIT:
{
int64_t uval = 0;
switch( *m_pResultBind->m_pBind[columnIndex - 1].length )
{
case 8:uval = ( int64_t ) bit_uint8korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 7:uval = ( int64_t ) bit_uint7korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 6:uval = ( int64_t ) bit_uint6korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 5:uval = ( int64_t ) bit_uint5korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 4:uval = ( int64_t ) bit_uint4korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 3:uval = ( int64_t ) bit_uint3korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 2:uval = ( int64_t ) bit_uint2korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
case 1:uval = ( int64_t ) bit_uint1korr( m_pResultBind->m_pBind[columnIndex - 1].buffer );break;
}
return uval;
}
case DataType::YEAR:
case DataType::TINYINT:
case DataType::SMALLINT:
case DataType::MEDIUMINT:
case DataType::INTEGER:
case DataType::BIGINT:
{
int64_t ret;
bool is_it_null = *m_pResultBind->m_pBind[columnIndex - 1].is_null != 0;
bool is_it_unsigned = m_pResultBind->m_pBind[columnIndex - 1].is_unsigned != 0;
switch( m_pResultBind->m_pBind[columnIndex - 1].buffer_length )
{
case 1:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint8_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int8_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
case 2:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint16_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int16_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
case 4:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint32_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int32_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer) : 0;
break;
case 8:
if( is_it_unsigned )
ret = !is_it_null ? *reinterpret_cast< uint64_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
else
ret = !is_it_null ? *reinterpret_cast< int64_t* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0;
break;
default:
throw std::runtime_error( "PreparedResultSet::getInt64_intern: invalid type" );
}
return ret;
}
default:
break;
}
throw std::runtime_error( "PreparedResultSet::getInt64_intern: unhandled type. Please, report" );
return 0;
}
uint64_t Core::Db::PreparedResultSet::getUInt64( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getUInt64: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getUInt64: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( *m_pResultBind->m_pBind[columnIndex - 1].is_null )
return 0;
return getUInt64_intern( columnIndex, true );
}
uint64_t Core::Db::PreparedResultSet::getUInt64( const std::string& columnLabel ) const
{
return getUInt64( findColumn( columnLabel ) );
}
std::string Core::Db::PreparedResultSet::getString( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getString: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getString: invalid 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( *m_pResultBind->m_pBind[columnIndex - 1].is_null )
return std::string("");
MYSQL_RES* res = mysql_stmt_result_metadata( m_pStmt->getRawStmt() );
MYSQL_FIELD* field = mysql_fetch_field_direct( res, columnIndex );
switch( Util::mysql_type_to_datatype( field ) )
{
case DataType::TIMESTAMP:
{
char buf[28];
MYSQL_TIME * t = static_cast< MYSQL_TIME* >( m_pResultBind->m_pBind[columnIndex - 1].buffer );
if( t->second_part )
snprintf( buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d.%06lu",
t->year, t->month, t->day, t->hour, t->minute, t->second, t->second_part );
else
snprintf( buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d",
t->year, t->month, t->day, t->hour, t->minute, t->second );
return std::string( buf );
}
case DataType::DATE:
{
char buf[12];
MYSQL_TIME* t = static_cast< MYSQL_TIME* >( m_pResultBind->m_pBind[columnIndex - 1].buffer );
snprintf( buf, sizeof( buf ) - 1, "%02d-%02d-%02d", t->year, t->month, t->day );
return std::string( buf );
}
case DataType::TIME:
{
char buf[18];
MYSQL_TIME* t = static_cast<MYSQL_TIME*>( m_pResultBind->m_pBind[columnIndex - 1].buffer );
if( t->second_part )
snprintf( buf, sizeof( buf ), "%s%02d:%02d:%02d.%06lu", t->neg ? "-" : "", t->hour, t->minute, t->second, t->second_part );
else
snprintf( buf, sizeof( buf ), "%s%02d:%02d:%02d", t->neg ? "-" : "", t->hour, t->minute, t->second );
return std::string( buf );
}
case DataType::BIT:
case DataType::YEAR: // fetched as a SMALLINT
case DataType::TINYINT:
case DataType::SMALLINT:
case DataType::MEDIUMINT:
case DataType::INTEGER:
case DataType::BIGINT:
{
char buf[30];
if( m_pResultBind->m_pBind[columnIndex - 1].is_unsigned )
my_ul_to_a( buf, sizeof( buf ) - 1, getUInt64_intern( columnIndex, false ) );
else
my_l_to_a( buf, sizeof( buf ) - 1, getInt64_intern( columnIndex, false ) );
return std::string( buf );
}
case DataType::REAL:
case DataType::DOUBLE:
{
char buf[50];
my_f_to_a( buf, sizeof( buf ) - 1, getDouble( columnIndex ) );
return std::string( buf );
}
case DataType::NUMERIC:
case DataType::DECIMAL:
case DataType::CHAR:
case DataType::BINARY:
case DataType::VARCHAR:
case DataType::VARBINARY:
case DataType::LONGVARCHAR:
case DataType::LONGVARBINARY:
case DataType::SET:
case DataType::ENUM:
case DataType::JSON:
return std::string( static_cast< char* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ),
*m_pResultBind->m_pBind[columnIndex - 1].length );
default:
break;
}
throw std::runtime_error( " PreparedResultSet::getString: unhandled type. Please, report" );
return 0;
}
std::string Core::Db::PreparedResultSet::getString( const std::string& columnLabel) const
{
return getString( findColumn( columnLabel ) );
}
int32_t Core::Db::PreparedResultSet::getInt( uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getInt: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getInt: invalid value of 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( *m_pResultBind->m_pBind[columnIndex - 1].is_null )
return 0;
return static_cast< int32_t >( getInt64_intern( columnIndex, true ) );
}
int32_t Core::Db::PreparedResultSet::getInt( const std::string& columnLabel ) const
{
return getInt( findColumn( columnLabel ) );
}
long double Core::Db::PreparedResultSet::getDouble(const uint32_t columnIndex) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getDouble: can't fetch because not on result set" );
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getDouble: invalid 'columnIndex'" );
m_lastQueriedColumn = columnIndex;
if( *m_pResultBind->m_pBind[columnIndex - 1].is_null)
return 0.0;
MYSQL_RES* res = mysql_stmt_result_metadata( m_pStmt->getRawStmt() );
MYSQL_FIELD* field = mysql_fetch_field_direct( res, columnIndex );
switch( Util::mysql_type_to_datatype( field ) )
{
case DataType::BIT:
case DataType::YEAR:
case DataType::TINYINT:
case DataType::SMALLINT:
case DataType::MEDIUMINT:
case DataType::INTEGER:
case DataType::BIGINT:
{
long double ret;
bool is_it_unsigned = m_pResultBind->m_pBind[columnIndex - 1].is_unsigned != 0;
if( is_it_unsigned )
{
uint64_t ival = getUInt64_intern( columnIndex, false );
ret = static_cast< long double >( ival );
}
else
{
int64_t ival = getInt64_intern( columnIndex, false );
ret = static_cast< long double >( ival );
}
return ret;
}
case DataType::NUMERIC:
case DataType::DECIMAL:
case DataType::TIMESTAMP:
case DataType::DATE:
case DataType::TIME:
case DataType::CHAR:
case DataType::BINARY:
case DataType::VARCHAR:
case DataType::VARBINARY:
case DataType::LONGVARCHAR:
case DataType::LONGVARBINARY:
case DataType::SET:
case DataType::ENUM:
case DataType::JSON:
{
long double ret = Util::strtonum( getString( columnIndex ).c_str() );
return ret;
}
case DataType::REAL:
{
long double ret = !*m_pResultBind->m_pBind[columnIndex - 1].is_null ?
*reinterpret_cast< float* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0.;
return ret;
}
case DataType::DOUBLE:
{
long double ret = !*m_pResultBind->m_pBind[columnIndex - 1].is_null ?
*reinterpret_cast< double* >( m_pResultBind->m_pBind[columnIndex - 1].buffer ) : 0.;
return ret;
}
}
throw std::runtime_error("PreparedResultSet::getDouble: unhandled type. Please, report");
return .0;
}
long double Core::Db::PreparedResultSet::getDouble( const std::string& columnLabel ) const
{
return getDouble( findColumn( columnLabel ) );
}
size_t Core::Db::PreparedResultSet::getRow() const
{
return static_cast< size_t >( m_rowPosition );
}
size_t Core::Db::PreparedResultSet::rowsCount() const
{
return static_cast< uint32_t >( m_numRows );
}
const Core::Db::Statement* Core::Db::PreparedResultSet::getStatement() const
{
return m_pStmt;
}
std::istream* Core::Db::PreparedResultSet::getBlob( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getBlob: can't fetch because not on result set" );
return new std::istringstream( getString( columnIndex ) );
}
std::istream* Core::Db::PreparedResultSet::getBlob( const std::string& columnLabel ) const
{
return new std::istringstream( getString( columnLabel ) );
}
std::vector< char > Core::Db::PreparedResultSet::getBlobVector( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::getBlobVector: invalid value of 'columnIndex'" );
boost::scoped_ptr< std::istream > inStr( getBlob( columnIndex ) );
char buff[4196];
std::vector< char > data;
inStr->read( buff, sizeof( buff ) );
if( inStr->gcount() )
{
data.resize( static_cast< uint32_t >( inStr->gcount() ) );
memcpy( data.data(), buff, static_cast< size_t >( inStr->gcount() ) );
}
return data;
}
std::vector< char > Core::Db::PreparedResultSet::getBlobVector( const std::string& columnLabel ) const
{
return getBlobVector( findColumn( columnLabel ) );
}
bool Core::Db::PreparedResultSet::getBoolean( const uint32_t columnIndex ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::getBoolean: can't fetch because not on result set" );
return getInt(columnIndex ) != 0;
}
bool Core::Db::PreparedResultSet::getBoolean( const std::string& columnLabel ) const
{
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error("PreparedResultSet::getBoolean: can't fetch because not on result set");
return getInt(columnLabel ) != 0;
}
bool Core::Db::PreparedResultSet::isLast() const
{
return ( m_rowPosition == m_numRows );
}
bool Core::Db::PreparedResultSet::isFirst() const
{
return ( m_rowPosition == 1 );
}
bool Core::Db::PreparedResultSet::isNull( const uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "PreparedResultSet::isNull: invalid value of 'columnIndex'" );
if( isBeforeFirstOrAfterLast() )
throw std::runtime_error( "PreparedResultSet::isNull: can't fetch because not on result set" );
return *m_pResultBind->m_pBind[columnIndex - 1].is_null != 0;
}
bool Core::Db::PreparedResultSet::isNull( const std::string& columnLabel ) const
{
uint32_t index = findColumn( columnLabel );
if( index == 0 )
throw std::runtime_error( "PreparedResultSet::isNull: invalid value of 'columnLabel'" );
return isNull( index );
}
bool Core::Db::PreparedResultSet::next()
{
bool ret = false;
// reset last_queried_column
// m_lastQueriedColumn = std::numeric_limits< uint32_t >::max();
int result = mysql_stmt_fetch( m_pStmt->getRawStmt() );
if( !result || result == MYSQL_DATA_TRUNCATED )
ret = true;
if( result == MYSQL_NO_DATA )
ret = false;
if( result == 1 )
throw std::runtime_error( "PreparedResultSet:next: error getting next result" );
++m_rowPosition;
return ret;
}

View file

@ -1,115 +0,0 @@
#ifndef SAPPHIRE_PREPAREDRESULTSET_H
#define SAPPHIRE_PREPAREDRESULTSET_H
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include "ResultSet.h"
namespace Core
{
namespace Db
{
class PreparedStatement;
// class PreparedResultSetMetaData;
class ResultBind;
class PreparedResultSet : public ResultSet
{
private:
mutable uint32_t m_lastQueriedColumn; // this is updated by calls to getInt(int), getString(int), etc...
uint32_t m_numFields;
uint64_t m_numRows;
uint64_t m_rowPosition;
typedef std::map< std::string, uint32_t > FieldNameIndexMap;
FieldNameIndexMap m_fieldNameToIndex;
PreparedStatement * m_pStmt;
bool is_valid;
// boost::scoped_ptr< MySQL_PreparedResultSetMetaData > rs_meta;
boost::shared_ptr< ResultBind > m_pResultBind;
protected:
void checkValid() const;
void closeIntern();
bool isBeforeFirstOrAfterLast() const;
void seek();
int64_t getInt64_intern(const uint32_t columnIndex, bool cutTooBig) const;
uint64_t getUInt64_intern(const uint32_t columnIndex, bool cutTooBig) const;
public:
PreparedResultSet( boost::shared_ptr< ResultBind >& pBind, PreparedStatement* par );
virtual ~PreparedResultSet();
void clearWarnings();
void close();
uint32_t findColumn( const std::string& columnLabel ) const;
std::istream * getBlob(uint32_t columnIndex) const;
std::istream * getBlob(const std::string& columnLabel) const;
std::vector< char > getBlobVector( uint32_t columnIndex ) const;
std::vector< char > getBlobVector( 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;
void getWarnings();
bool isClosed() const;
void insertRow();
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;
};
}
}
#endif //SAPPHIRE_PREPAREDRESULTSET_H

View file

@ -1,698 +0,0 @@
#include "PreparedStatement.h"
#include "PreparedResultSet.h"
#include "Connection.h"
#include "ResultBind.h"
#include <boost/variant.hpp>
#include <boost/scoped_array.hpp>
#include <errmsg.h>
#include <string.h>
static const unsigned int MAX_SEND_LONGDATA_BUFFER = 1 << 18; //1<<18=256k (for istream)
static const unsigned int MAX_SEND_LONGDATA_CHUNK = 1 << 18; //1<<19=512k (for string)
namespace Core
{
namespace Db
{
// Visitor class to send long data contained in blob_bind
class LongDataSender : public boost::static_visitor< bool >
{
unsigned position;
MYSQL_STMT* m_pStmt;
LongDataSender()
{}
public:
LongDataSender(MYSQL_STMT* pStmt, unsigned int i)
: position( i )
, m_pStmt( pStmt )
{
}
bool operator()(std::istream* my_blob) const
{
if (my_blob == NULL)
return false;
//char buf[MAX_SEND_LONGDATA_BUFFER];
boost::scoped_array< char > buf( new char[MAX_SEND_LONGDATA_BUFFER] );
do
{
if( my_blob->eof() )
break;
my_blob->read( buf.get(), MAX_SEND_LONGDATA_BUFFER );
if( my_blob->bad() )
throw std::runtime_error( "Error while reading from blob (bad)" );
else if( my_blob->fail() )
{
if( !my_blob->eof() )
throw std::runtime_error( "Error while reading from blob (fail)" );
}
if( mysql_stmt_send_long_data( m_pStmt, position, buf.get(), static_cast< unsigned long >( my_blob->gcount() ) ) )
{
switch( mysql_stmt_errno( m_pStmt ) )
{
case CR_OUT_OF_MEMORY:
throw std::bad_alloc();
case CR_INVALID_BUFFER_USE:
throw std::runtime_error("PreparedStatement::setBlob: can't set blob value on that column");
case CR_SERVER_GONE_ERROR:
case CR_COMMANDS_OUT_OF_SYNC:
default:
throw std::runtime_error("PreparedStatement:: Default error");
}
}
} while( true );
return true;
}
bool operator()( std::string* str ) const
{
if ( str == nullptr )
return false;
uint32_t sent = 0, chunkSize;
while( sent < str->length() )
{
chunkSize = ( sent + MAX_SEND_LONGDATA_CHUNK > str->length()
? str->length() - sent
: MAX_SEND_LONGDATA_CHUNK );
if( mysql_stmt_send_long_data( m_pStmt, position, str->c_str() + sent, chunkSize ) )
{
switch( mysql_stmt_errno( m_pStmt ) )
{
case CR_OUT_OF_MEMORY:
throw std::bad_alloc();
case CR_INVALID_BUFFER_USE:
throw std::runtime_error( "PreparedStatement::setBlob: can't set blob value on that column" );
case CR_SERVER_GONE_ERROR:
case CR_COMMANDS_OUT_OF_SYNC:
default:
throw std::runtime_error( "PreparedStatement:: Default error" );
}
}
sent+= chunkSize;
}
return true;
}
};
class BlobBindDeleter : public boost::static_visitor<>
{
public:
void operator()( std::string*& str ) const
{
if( str != nullptr )
{
delete str;
str= nullptr;
}
}
void operator()( std::istream*& my_blob ) const
{
if( my_blob!= nullptr )
{
delete my_blob;
my_blob= nullptr;
}
}
};
class BlobIsNull : public boost::static_visitor< bool >
{
public:
bool operator()( std::string*& str ) const
{
return str == nullptr;
}
bool operator()( std::istream*& my_blob ) const
{
return my_blob == nullptr;
}
};
void resetBlobBind( MYSQL_BIND& param )
{
delete [] static_cast<char *>( param.buffer );
param.buffer_type = MYSQL_TYPE_LONG_BLOB;
param.buffer = nullptr;
param.buffer_length = 0;
param.is_null_value = 0;
delete param.length;
param.length = new unsigned long( 0 );
}
class ParamBind
{
public:
typedef boost::variant< std::istream*, std::string* > Blob_t;
private:
unsigned int m_paramCount;
boost::scoped_array< MYSQL_BIND > bind;
boost::scoped_array< bool > value_set;
boost::scoped_array< bool > delete_blob_after_execute;
typedef std::map< uint32_t, Blob_t > Blobs;
Blobs blob_bind;
public:
ParamBind( uint32_t paramCount )
: m_paramCount( paramCount ),
bind( nullptr ),
value_set( nullptr ),
delete_blob_after_execute( nullptr )
{
if( m_paramCount )
{
bind.reset( new MYSQL_BIND[paramCount] );
memset( bind.get(), 0, sizeof( MYSQL_BIND ) * paramCount );
value_set.reset( new bool[paramCount] );
delete_blob_after_execute.reset( new bool[paramCount] );
for( uint32_t i = 0; i < paramCount; ++i )
{
bind[i].is_null_value = 1;
value_set[i] = false;
delete_blob_after_execute[i] = false;
}
}
}
virtual ~ParamBind()
{
clearParameters();
for( Blobs::iterator it = blob_bind.begin(); it != blob_bind.end(); ++it )
{
if( delete_blob_after_execute[it->first] )
{
delete_blob_after_execute[it->first] = false;
boost::apply_visitor( BlobBindDeleter(), it->second );
}
}
}
void set( uint32_t position )
{
value_set[position] = true;
}
void unset( uint32_t position )
{
value_set[position] = false;
if( delete_blob_after_execute[position] )
{
delete_blob_after_execute[position] = false;
boost::apply_visitor( BlobBindDeleter(), blob_bind[position] );
blob_bind.erase( position );
}
}
void setBlob( uint32_t position, Blob_t & blob, bool delete_after_execute )
{
set( position );
resetBlobBind( bind[position] );
Blobs::iterator it = blob_bind.find( position );
if( it != blob_bind.end() && delete_blob_after_execute[position] )
boost::apply_visitor( BlobBindDeleter(), it->second );
if( boost::apply_visitor( BlobIsNull(), blob ) )
{
if( it != blob_bind.end() )
blob_bind.erase( it );
delete_blob_after_execute[position] = false;
}
else
{
blob_bind[position] = blob;
delete_blob_after_execute[position] = delete_after_execute;
}
}
bool isAllSet()
{
for( uint32_t i = 0; i < m_paramCount; ++i )
{
if( !value_set[i] )
return false;
}
return true;
}
void clearParameters()
{
for( uint32_t i = 0; i < m_paramCount; ++i )
{
delete ( char* ) bind[i].length;
bind[i].length = nullptr;
delete[] ( char* ) bind[i].buffer;
bind[i].buffer = nullptr;
if (value_set[i])
{
Blobs::iterator it = blob_bind.find( i );
if( it != blob_bind.end() && delete_blob_after_execute[i] )
{
boost::apply_visitor( BlobBindDeleter(), it->second );
blob_bind.erase( it );
}
blob_bind[i] = Blob_t();
value_set[i] = false;
}
}
}
MYSQL_BIND * getBindObject()
{
return bind.get();
}
boost::variant< std::istream*, std::string* > getBlobObject( uint32_t position )
{
Blobs::iterator it = blob_bind.find( position );
if( it != blob_bind.end() )
return it->second;
return Blob_t();
}
};
}
}
Core::Db::PreparedStatement::PreparedStatement( MYSQL_STMT* pStmt, Core::Db::Connection* pConn )
: Statement( pConn )
{
m_pStmt = pStmt;
m_pConnection = pConn;
m_paramCount = mysql_stmt_param_count( m_pStmt );
m_pParamBind.reset( new ParamBind( m_paramCount ) );
m_pResultBind.reset( new ResultBind( pStmt ) );
}
uint32_t Core::Db::PreparedStatement::errNo()
{
return mysql_stmt_errno( m_pStmt );
}
Core::Db::Connection *Core::Db::PreparedStatement::getConnection()
{
return m_pConnection;
}
Core::Db::PreparedStatement::~PreparedStatement()
{
if( m_pStmt )
closeIntern();
}
uint32_t Core::Db::PreparedStatement::getWarningCount()
{
return mysql_warning_count( m_pConnection->getRawCon() );
}
uint64_t Core::Db::PreparedStatement::getUpdateCount()
{
throw std::runtime_error( "PreparedStatement::getUpdateCount() Not implemented" );
return 0;
}
bool Core::Db::PreparedStatement::sendLongDataBeforeParamBind()
{
MYSQL_BIND* bind = m_pParamBind->getBindObject();
for( unsigned int i = 0; i < m_paramCount; ++i )
{
if( bind[i].buffer_type == MYSQL_TYPE_LONG_BLOB )
{
LongDataSender lv( m_pStmt, i );
ParamBind::Blob_t dummy( m_pParamBind->getBlobObject( i ) );
boost::apply_visitor( lv, dummy );
}
}
return true;
}
void Core::Db::PreparedStatement::doQuery()
{
if( m_paramCount && !m_pParamBind->isAllSet() )
throw std::runtime_error( "Value not set for all parameters" );
if( mysql_stmt_bind_param( m_pStmt, m_pParamBind->getBindObject() ) )
throw std::runtime_error("Couldn't bind : " + std::to_string( errNo() ) );
if( !sendLongDataBeforeParamBind() || mysql_stmt_execute( m_pStmt ) )
throw std::runtime_error( "Couldn't execute : " + std::to_string( errNo() ) + ": " + m_pConnection->getError() );
warningsCount = getWarningCount();
}
void Core::Db::PreparedStatement::closeIntern()
{
if( m_pStmt )
mysql_stmt_close( m_pStmt );
clearParameters();
}
void Core::Db::PreparedStatement::clearParameters()
{
m_pParamBind->clearParameters();
}
bool Core::Db::PreparedStatement::execute()
{
doQuery();
return mysql_stmt_field_count( m_pStmt ) > 0;
}
bool Core::Db::PreparedStatement::execute( const std::string &sql )
{
throw std::runtime_error("PreparedStatement::execute( const std::string &sql ) Not implemented");
return false;
}
Core::Db::ResultSet* Core::Db::PreparedStatement::executeQuery( const std::string &sql )
{
// not to be implemented for prepared statements
return nullptr;
}
Core::Db::ResultSet* Core::Db::PreparedStatement::executeQuery()
{
doQuery();
my_bool bool_tmp = 1;
mysql_stmt_attr_set( m_pStmt, STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp );
ResultSet* tmp = new PreparedResultSet( m_pResultBind, this );
return tmp;
}
Core::Db::ResultSet* Core::Db::PreparedStatement::getResultSet()
{
my_bool bool_tmp = 1;
mysql_stmt_attr_set( m_pStmt, STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp );
ResultSet* tmp = new PreparedResultSet( m_pResultBind, this );
return tmp;
}
MYSQL_STMT* Core::Db::PreparedStatement::getRawStmt()
{
return m_pStmt;
}
typedef std::pair< char*, size_t > BufferSizePair;
static BufferSizePair allocate_buffer_for_type(enum_field_types t)
{
switch( t )
{
case MYSQL_TYPE_LONG:
return BufferSizePair( new char[4], 4 );
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONGLONG:
return BufferSizePair( new char[8], 8 );
case MYSQL_TYPE_STRING:
return BufferSizePair( NULLCSTR, 0 );
case MYSQL_TYPE_NULL:
return BufferSizePair( NULLCSTR, 0 );
default:
throw std::runtime_error( "allocate_buffer_for_type: invalid result_bind data type" );
}
}
void Core::Db::PreparedStatement::setInt( uint32_t parameterIndex, int32_t value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setInt: invalid 'parameterIndex'" );
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_LONG;
BufferSizePair p = allocate_buffer_for_type(t);
m_pParamBind->set(parameterIndex);
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = p.first;
param->buffer_length = 0;
param->is_null_value = 0;
delete param->length;
param->length = nullptr;
memcpy( param->buffer, &value, p.second );
}
void Core::Db::PreparedStatement::setUInt( uint32_t parameterIndex, uint32_t value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setInt: invalid 'parameterIndex'" );
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_LONG;
BufferSizePair p = allocate_buffer_for_type(t);
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = p.first;
param->buffer_length = 0;
param->is_null_value = 0;
param->is_unsigned = 1;
delete param->length;
param->length = nullptr;
memcpy( param->buffer, &value, p.second );
}
void Core::Db::PreparedStatement::setInt64( uint32_t parameterIndex, int64_t value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setInt64: invalid 'parameterIndex'" );
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_LONGLONG;
BufferSizePair p = allocate_buffer_for_type(t);
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = p.first;
param->buffer_length = 0;
param->is_null_value = 0;
delete param->length;
param->length = nullptr;
memcpy( param->buffer, &value, p.second );
}
void Core::Db::PreparedStatement::setUInt64( uint32_t parameterIndex, uint64_t value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setInt64: invalid 'parameterIndex'" );
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_LONGLONG;
BufferSizePair p = allocate_buffer_for_type(t);
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = p.first;
param->buffer_length = 0;
param->is_null_value = 0;
param->is_unsigned = 1;
delete param->length;
param->length = nullptr;
memcpy( param->buffer, &value, p.second );
}
void Core::Db::PreparedStatement::setNull( uint32_t parameterIndex, int )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setNull: invalid 'parameterIndex'" );
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_NULL;
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = nullptr;
delete param->length;
param->length = nullptr;
}
void Core::Db::PreparedStatement::setString( uint32_t parameterIndex, const std::string& value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
{
throw std::runtime_error( "PreparedStatement::setString: invalid 'parameterIndex'" );
}
if( value.length() > 256*1024 )
{
std::string* pvalue = new std::string( value );
ParamBind::Blob_t dummy( pvalue );
return m_pParamBind->setBlob( --parameterIndex, dummy, true );
}
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_STRING;
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
delete [] static_cast< char* >( param->buffer );
param->buffer_type = t;
param->buffer = memcpy( new char[value.length() + 1], value.c_str(), value.length() + 1 );
param->buffer_length = static_cast< unsigned long >( value.length() ) + 1;
param->is_null_value = 0;
delete param->length;
param->length = new unsigned long( static_cast< unsigned long >( value.length() ) );
}
void Core::Db::PreparedStatement::setDouble( uint32_t parameterIndex, double value )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
{
throw std::runtime_error( "PreparedStatement::setDouble: invalid 'parameterIndex'" );
}
--parameterIndex;
{
ParamBind::Blob_t dummy;
m_pParamBind->setBlob( parameterIndex, dummy, false );
m_pParamBind->unset( parameterIndex );
}
enum_field_types t = MYSQL_TYPE_DOUBLE;
BufferSizePair p = allocate_buffer_for_type(t);
m_pParamBind->set( parameterIndex );
MYSQL_BIND* param = &m_pParamBind->getBindObject()[parameterIndex];
param->buffer_type = t;
delete [] static_cast< char* >( param->buffer );
param->buffer = p.first;
param->buffer_length = 0;
param->is_null_value = 0;
delete param->length;
param->length = nullptr;
memcpy( param->buffer, &value, p.second );
}
void Core::Db::PreparedStatement::setDateTime( uint32_t parameterIndex, const std::string& value )
{
setString( parameterIndex, value );
}
void Core::Db::PreparedStatement::setBoolean( uint32_t parameterIndex, bool value )
{
setInt( parameterIndex, value );
}
void Core::Db::PreparedStatement::setBigInt( uint32_t parameterIndex, const std::string& value )
{
setString( parameterIndex, value );
}
void Core::Db::PreparedStatement::setBlob( uint32_t parameterIndex, std::istream* blob )
{
if( parameterIndex == 0 || parameterIndex > m_paramCount )
throw std::runtime_error( "PreparedStatement::setBlob: invalid 'parameterIndex'" );
ParamBind::Blob_t dummy(blob);
m_pParamBind->setBlob( --parameterIndex, dummy, false );
}

View file

@ -1,95 +0,0 @@
#ifndef SAPPHIRE_PREPAREDSTATEMENT_H
#define SAPPHIRE_PREPAREDSTATEMENT_H
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include "Statement.h"
#include <mysql.h>
namespace Core
{
namespace Db
{
class ParamBind;
class ResultBind;
class PreparedStatement : public Statement
{
protected:
MYSQL_STMT * m_pStmt;
Connection * m_pConnection;
boost::scoped_ptr< ParamBind > m_pParamBind;
uint32_t m_paramCount;
int32_t resultSetConcurrency;
int32_t resultSetType;
//boost::scoped_ptr< MySQL_PreparedResultSetMetaData > res_meta;
//boost::scoped_ptr< MySQL_ParameterMetaData > param_meta;
boost::shared_ptr< ResultBind > m_pResultBind;
unsigned int warningsCount;
virtual void doQuery();
virtual void closeIntern();
bool sendLongDataBeforeParamBind();
public:
PreparedStatement( MYSQL_STMT* pStmt, Connection* pConn );
virtual ~PreparedStatement();
Connection* getConnection() override;
MYSQL_STMT* getRawStmt();
uint32_t errNo() override;
uint32_t getWarningCount() override;
uint64_t getUpdateCount() override;
void clearParameters();
bool execute();
bool execute( const std::string& sql );
ResultSet* executeQuery();
ResultSet* executeQuery( const std::string& sql );
bool getMoreResults();
ResultSet* getResultSet();
void setBlob( uint32_t parameterIndex, std::istream * blob );
void setBoolean( uint32_t parameterIndex, bool value );
void setBigInt( uint32_t parameterIndex, const std::string& value );
void setDateTime( uint32_t parameterIndex, const std::string& value );
void setDouble( uint32_t parameterIndex, double value );
void setInt( uint32_t parameterIndex, int32_t value );
void setUInt( uint32_t parameterIndex, uint32_t value );
void setInt64( uint32_t parameterIndex, int64_t value );
void setUInt64( uint32_t parameterIndex, uint64_t value );
void setNull( uint32_t parameterIndex, int sqlType );
void setString( uint32_t parameterIndex, const std::string& value );
private:
PreparedStatement( const PreparedStatement& );
void operator=( PreparedStatement& );
};
}
}
#endif //SAPPHIRE_PREPAREDSTATEMENT_H

View file

@ -1,157 +0,0 @@
#include "ResultBind.h"
#include "mysql_util.h"
#include "ResultBind.h"
#include <string.h>
#include <boost/scoped_ptr.hpp>
namespace Core
{
namespace Db
{
struct st_buffer_size_type
{
char * buffer;
size_t size;
enum_field_types type;
st_buffer_size_type( char * b, size_t s, enum_field_types t )
: buffer( b ),
size( s ),
type( t )
{
}
};
typedef std::pair< char*, size_t > BufferSizePair;
static struct st_buffer_size_type
allocate_buffer_for_field( const MYSQL_FIELD * const field )
{
switch( field->type )
{
case MYSQL_TYPE_NULL:
return st_buffer_size_type( nullptr, 0, field->type );
case MYSQL_TYPE_TINY:
return st_buffer_size_type( new char[1], 1, field->type );
case MYSQL_TYPE_SHORT:
return st_buffer_size_type( new char[2], 2, field->type );
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_FLOAT:
return st_buffer_size_type( new char[4], 4, field->type );
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONGLONG:
return st_buffer_size_type( new char[8], 8, field->type );
case MYSQL_TYPE_YEAR:
return st_buffer_size_type( new char[2], 2, MYSQL_TYPE_SHORT );
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
return st_buffer_size_type( new char[sizeof( MYSQL_TIME )], sizeof( MYSQL_TIME ), field->type );
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
#if LIBMYSQL_VERSION_ID > 50700
case MYSQL_TYPE_JSON:
return st_buffer_size_type(new char[field->max_length + 1], field->max_length + 1, field->type);
#endif //LIBMYSQL_VERSION_ID > 50700
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
return st_buffer_size_type( new char[64], 64, field->type );
#if A1
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_YEAR:
return st_buffer_size_type(new char[10], 10, field->type);
#endif
#if A0
// There two are not sent over the wire
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
#endif
case MYSQL_TYPE_BIT:
return st_buffer_size_type( new char[8], 8, MYSQL_TYPE_BIT );
case MYSQL_TYPE_GEOMETRY:
default:
throw std::runtime_error( "allocate_buffer_for_field: invalid rbind data type" );
}
}
ResultBind::ResultBind( MYSQL_STMT* pStmt )
: m_pStmt( pStmt ),
m_numFields( 0 ),
m_isNull( nullptr ),
m_err( nullptr ),
m_len( nullptr ),
m_pBind( nullptr )
{
}
ResultBind::~ResultBind()
{
if( m_pBind.get() )
{
for( uint32_t i = 0; i < m_numFields; ++i )
delete[] ( char* ) m_pBind[i].buffer;
}
}
void ResultBind::bindResult()
{
for( uint32_t i = 0; i < m_numFields; ++i )
delete[] ( char* ) m_pBind[i].buffer;
m_pBind.reset( nullptr );
m_isNull.reset( nullptr );
m_err.reset( nullptr );
m_len.reset( nullptr );
m_numFields = mysql_stmt_field_count( m_pStmt );
if( !m_numFields )
return;
m_pBind.reset( new MYSQL_BIND[m_numFields] );
memset( m_pBind.get(), 0, sizeof( MYSQL_BIND ) * m_numFields );
m_isNull.reset( new my_bool[m_numFields] );
memset( m_isNull.get(), 0, sizeof( my_bool ) * m_numFields );
m_err.reset( new my_bool[m_numFields] );
memset( m_err.get(), 0, sizeof( my_bool ) * m_numFields );
m_len.reset( new unsigned long[m_numFields] );
memset( m_len.get(), 0, sizeof( unsigned long ) * m_numFields );
//boost::scoped_ptr< NativeAPI::NativeResultsetWrapper > resultMeta(proxy->result_metadata());
MYSQL_RES* info = mysql_stmt_result_metadata( m_pStmt );
for( uint32_t i = 0; i < m_numFields; ++i )
{
// MYSQL_FIELD * field = resultMeta->fetch_field();
MYSQL_FIELD * field = mysql_fetch_field( info );
struct st_buffer_size_type p = allocate_buffer_for_field(field);
m_pBind[i].buffer_type = p.type;
m_pBind[i].buffer = p.buffer;
m_pBind[i].buffer_length = static_cast< unsigned long >( p.size );
m_pBind[i].length = &m_len[i];
m_pBind[i].is_null = &m_isNull[i];
m_pBind[i].error = &m_err[i];
m_pBind[i].is_unsigned = field->flags & UNSIGNED_FLAG;
}
if( mysql_stmt_bind_result( m_pStmt, m_pBind.get() ) )
throw std::runtime_error( "Couldn't bind : " + std::to_string( mysql_stmt_errno( m_pStmt ) ) );
}
}
}

View file

@ -1,37 +0,0 @@
#ifndef SAPPHIRE_RESULTBIND_H
#define SAPPHIRE_RESULTBIND_H
#include <boost/scoped_array.hpp>
#include "mysql_util.h"
#include "mysql.h"
#include "PreparedStatement.h"
namespace Core
{
namespace Db
{
class ResultBind
{
uint32_t m_numFields;
boost::scoped_array< char > m_isNull;
boost::scoped_array< char > m_err;
boost::scoped_array< unsigned long > m_len;
MYSQL_STMT* m_pStmt;
public:
boost::scoped_array< MYSQL_BIND > m_pBind;
ResultBind( MYSQL_STMT* pStmt );
~ResultBind();
void bindResult();
};
}
}
#endif //SAPPHIRE_RESULTBIND_H

View file

@ -1,297 +0,0 @@
#include "ResultSet.h"
#include "Connection.h"
#include "Statement.h"
#include "mysql_util.h"
#include <cctype>
#include <clocale>
#include <vector>
#include <boost/scoped_ptr.hpp>
#include <string.h>
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( uint32_t 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( uint32_t 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 Util::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 ) );
}
std::vector< char > Core::Db::ResultSet::getBlobVector( uint32_t columnIndex ) const
{
if( columnIndex == 0 || columnIndex > m_numFields )
throw std::runtime_error( "ResultSet::getBlobVector: invalid value of 'columnIndex'" );
boost::scoped_ptr< std::istream > inStr( getBlob( columnIndex ) );
char buff[4196];
std::vector< char > data;
inStr->read( buff, sizeof( buff ) );
if( inStr->gcount() )
{
data.resize( inStr->gcount() );
memcpy( data.data(), buff, inStr->gcount() );
}
return data;
}
std::vector< char > Core::Db::ResultSet::getBlobVector( const std::string& columnLabel ) const
{
return getBlobVector( findColumn( columnLabel ) );
}

View file

@ -1,106 +0,0 @@
#ifndef SAPPHIRE_RESULTSET_H
#define SAPPHIRE_RESULTSET_H
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <vector>
#include "ResultSetBase.h"
#include <mysql.h>
namespace Core
{
namespace Db
{
class Statement;
//class ResultSetMetaData;
class ResultSet
{
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();
virtual uint32_t findColumn( const std::string& columnLabel ) const;
virtual std::istream * getBlob( uint32_t columnIndex ) const;
virtual std::istream * getBlob( const std::string& columnLabel ) const;
virtual std::vector< char > getBlobVector( uint32_t columnIndex ) const;
virtual std::vector< char > getBlobVector( const std::string& columnLabel ) const;
virtual bool getBoolean( uint32_t columnIndex ) const;
virtual bool getBoolean( const std::string& columnLabel ) const;
virtual long double getDouble( uint32_t columnIndex ) const;
virtual long double getDouble( const std::string& columnLabel ) const;
virtual int32_t getInt( uint32_t columnIndex ) const;
virtual int32_t getInt( const std::string& columnLabel ) const;
virtual uint32_t getUInt( uint32_t columnIndex ) const;
virtual uint32_t getUInt( const std::string& columnLabel ) const;
virtual int64_t getInt64( uint32_t columnIndex ) const;
virtual int64_t getInt64( const std::string& columnLabel ) const;
virtual uint64_t getUInt64( uint32_t columnIndex ) const;
virtual uint64_t getUInt64( const std::string& columnLabel ) const;
//sql::ResultSetMetaData * getMetaData() const;
virtual size_t getRow() const;
virtual const Statement * getStatement() const;
virtual std::string getString( uint32_t columnIndex ) const;
virtual std::string getString( const std::string& columnLabel ) const;
virtual bool isFirst() const;
virtual bool isLast() const;
virtual bool isNull( uint32_t columnIndex ) const;
virtual bool isNull( const std::string& columnLabel ) const;
virtual bool next();
size_t rowsCount() const;
private:
ResultSet( const ResultSet& );
void operator=( ResultSet& );
};
}
}
#endif //SAPPHIRE_RESULTSET_H

View file

@ -1,70 +0,0 @@
#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

@ -1,66 +0,0 @@
#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

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

View file

@ -1,36 +0,0 @@
#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

@ -1,434 +0,0 @@
#include "mysql_util.h"
#include "DataType.h"
#include <mysql.h>
#include <vector>
#include <stdexcept>
long double Util::strtold(const char *nptr, char **endptr)
{
/*
* Experienced odd compilation errors on one of windows build hosts -
* cmake reported there is strold function. Since double and long double on windows
* are of the same size - we are using strtod on those platforms regardless
* to the HAVE_FUNCTION_STRTOLD value
*/
#ifdef _WIN32
return ::strtod(nptr, endptr);
#else
# ifndef HAVE_FUNCTION_STRTOLD
return ::strtod(nptr, endptr);
# else
# if defined(__hpux) && defined(_LONG_DOUBLE)
union {
long_double l_d;
long double ld;
} u;
u.l_d = ::strtold( nptr, endptr);
return u.ld;
# else
return ::strtold(nptr, endptr);
# endif
# endif
#endif
}
long double Util::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;
}
#define cppconn_mbcharlen_big5 NULL
#define check_mb_big5 NULL
#define cppconn_mbcharlen_ujis NULL
#define check_mb_ujis NULL
#define cppconn_mbcharlen_sjis NULL
#define check_mb_sjis NULL
#define cppconn_mbcharlen_euckr NULL
#define check_mb_euckr NULL
#define cppconn_mbcharlen_gb2312 NULL
#define check_mb_gb2312 NULL
#define cppconn_mbcharlen_gbk NULL
#define check_mb_gbk NULL
#define cppconn_mbcharlen_utf8 NULL
#define check_mb_utf8_valid NULL
#define cppconn_mbcharlen_ucs2 NULL
#define check_mb_ucs2 NULL
#define cppconn_mbcharlen_cp932 NULL
#define check_mb_cp932 NULL
#define cppconn_mbcharlen_eucjpms NULL
#define check_mb_eucjpms NULL
#define cppconn_mbcharlen_utf8 NULL
#define check_mb_utf8_valid NULL
#define cppconn_mbcharlen_utf8mb4 cppconn_mbcharlen_utf8
#define check_mb_utf8mb4_valid check_mb_utf8_valid
#define cppconn_mbcharlen_utf16 NULL
#define check_mb_utf16_valid NULL
#define cppconn_mbcharlen_utf32 NULL
#define check_mb_utf32_valid NULL
/* {{{ our_charsets60 */
const Util::OUR_CHARSET our_charsets60[] =
{
{ 1, "big5","big5_chinese_ci", 1, 2, "", cppconn_mbcharlen_big5, check_mb_big5},
{ 3, "dec8", "dec8_swedisch_ci", 1, 1, "", NULL, NULL},
{ 4, "cp850", "cp850_general_ci", 1, 1, "", NULL, NULL},
{ 6, "hp8", "hp8_english_ci", 1, 1, "", NULL, NULL},
{ 7, "koi8r", "koi8r_general_ci", 1, 1, "", NULL, NULL},
{ 8, "latin1", "latin1_swedish_ci", 1, 1, "", NULL, NULL},
{ 9, "latin2", "latin2_general_ci", 1, 1, "", NULL, NULL},
{ 10, "swe7", "swe7_swedish_ci", 1, 1, "", NULL, NULL},
{ 11, "ascii", "ascii_general_ci", 1, 1, "", NULL, NULL},
{ 12, "ujis", "ujis_japanese_ci", 1, 3, "", cppconn_mbcharlen_ujis, check_mb_ujis},
{ 13, "sjis", "sjis_japanese_ci", 1, 2, "", cppconn_mbcharlen_sjis, check_mb_sjis},
{ 16, "hebrew", "hebrew_general_ci", 1, 1, "", NULL, NULL},
{ 18, "tis620", "tis620_thai_ci", 1, 1, "", NULL, NULL},
{ 19, "euckr", "euckr_korean_ci", 1, 2, "", cppconn_mbcharlen_euckr, check_mb_euckr},
{ 22, "koi8u", "koi8u_general_ci", 1, 1, "", NULL, NULL},
{ 24, "gb2312", "gb2312_chinese_ci", 1, 2, "", cppconn_mbcharlen_gb2312, check_mb_gb2312},
{ 25, "greek", "greek_general_ci", 1, 1, "", NULL, NULL},
{ 26, "cp1250", "cp1250_general_ci", 1, 1, "", NULL, NULL},
{ 28, "gbk", "gbk_chinese_ci", 1, 2, "", cppconn_mbcharlen_gbk, check_mb_gbk},
{ 30, "latin5", "latin5_turkish_ci", 1, 1, "", NULL, NULL},
{ 32, "armscii8", "armscii8_general_ci", 1, 1, "", NULL, NULL},
{ 33, "utf8", "utf8_general_ci", 1, 3, "UTF-8 Unicode", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 35, "ucs2", "ucs2_general_ci", 2, 2, "UCS-2 Unicode", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 36, "cp866", "cp866_general_ci", 1, 1, "", NULL, NULL},
{ 37, "keybcs2", "keybcs2_general_ci", 1, 1, "", NULL, NULL},
{ 38, "macce", "macce_general_ci", 1, 1, "", NULL, NULL},
{ 39, "macroman", "macroman_general_ci", 1, 1, "", NULL, NULL},
{ 40, "cp852", "cp852_general_ci", 1, 1, "", NULL, NULL},
{ 41, "latin7", "latin7_general_ci", 1, 1, "", NULL, NULL},
{ 51, "cp1251", "cp1251_general_ci", 1, 1, "", NULL, NULL},
{ 57, "cp1256", "cp1256_general_ci", 1, 1, "", NULL, NULL},
{ 59, "cp1257", "cp1257_general_ci", 1, 1, "", NULL, NULL},
{ 63, "binary", "binary", 1, 1, "", NULL, NULL},
{ 92, "geostd8", "geostd8_general_ci", 1, 1, "", NULL, NULL},
{ 95, "cp932", "cp932_japanese_ci", 1, 2, "", cppconn_mbcharlen_cp932, check_mb_cp932},
{ 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, "", cppconn_mbcharlen_eucjpms, check_mb_eucjpms},
{ 2, "latin2", "latin2_czech_cs", 1, 1, "", NULL, NULL},
{ 5, "latin1", "latin1_german_ci", 1, 1, "", NULL, NULL},
{ 14, "cp1251", "cp1251_bulgarian_ci", 1, 1, "", NULL, NULL},
{ 15, "latin1", "latin1_danish_ci", 1, 1, "", NULL, NULL},
{ 17, "filename", "filename", 1, 5, "", NULL, NULL},
{ 20, "latin7", "latin7_estonian_cs", 1, 1, "", NULL, NULL},
{ 21, "latin2", "latin2_hungarian_ci", 1, 1, "", NULL, NULL},
{ 23, "cp1251", "cp1251_ukrainian_ci", 1, 1, "", NULL, NULL},
{ 27, "latin2", "latin2_croatian_ci", 1, 1, "", NULL, NULL},
{ 29, "cp1257", "cp1257_lithunian_ci", 1, 1, "", NULL, NULL},
{ 31, "latin1", "latin1_german2_ci", 1, 1, "", NULL, NULL},
{ 34, "cp1250", "cp1250_czech_cs", 1, 1, "", NULL, NULL},
{ 42, "latin7", "latin7_general_cs", 1, 1, "", NULL, NULL},
{ 43, "macce", "macce_bin", 1, 1, "", NULL, NULL},
{ 44, "cp1250", "cp1250_croatian_ci", 1, 1, "", NULL, NULL},
{ 47, "latin1", "latin1_bin", 1, 1, "", NULL, NULL},
{ 48, "latin1", "latin1_general_ci", 1, 1, "", NULL, NULL},
{ 49, "latin1", "latin1_general_cs", 1, 1, "", NULL, NULL},
{ 50, "cp1251", "cp1251_bin", 1, 1, "", NULL, NULL},
{ 52, "cp1251", "cp1251_general_cs", 1, 1, "", NULL, NULL},
{ 53, "macroman", "macroman_bin", 1, 1, "", NULL, NULL},
{ 58, "cp1257", "cp1257_bin", 1, 1, "", NULL, NULL},
{ 60, "armascii8", "armascii8_bin", 1, 1, "", NULL, NULL},
{ 65, "ascii", "ascii_bin", 1, 1, "", NULL, NULL},
{ 66, "cp1250", "cp1250_bin", 1, 1, "", NULL, NULL},
{ 67, "cp1256", "cp1256_bin", 1, 1, "", NULL, NULL},
{ 68, "cp866", "cp866_bin", 1, 1, "", NULL, NULL},
{ 69, "dec8", "dec8_bin", 1, 1, "", NULL, NULL},
{ 70, "greek", "greek_bin", 1, 1, "", NULL, NULL},
{ 71, "hebrew", "hebrew_bin", 1, 1, "", NULL, NULL},
{ 72, "hp8", "hp8_bin", 1, 1, "", NULL, NULL},
{ 73, "keybcs2", "keybcs2_bin", 1, 1, "", NULL, NULL},
{ 74, "koi8r", "koi8r_bin", 1, 1, "", NULL, NULL},
{ 75, "koi8u", "koi8u_bin", 1, 1, "", NULL, NULL},
{ 77, "latin2", "latin2_bin", 1, 1, "", NULL, NULL},
{ 78, "latin5", "latin5_bin", 1, 1, "", NULL, NULL},
{ 79, "latin7", "latin7_bin", 1, 1, "", NULL, NULL},
{ 80, "cp850", "cp850_bin", 1, 1, "", NULL, NULL},
{ 81, "cp852", "cp852_bin", 1, 1, "", NULL, NULL},
{ 82, "swe7", "swe7_bin", 1, 1, "", NULL, NULL},
{ 93, "geostd8", "geostd8_bin", 1, 1, "", NULL, NULL},
{ 83, "utf8", "utf8_bin", 1, 3, "UTF-8 Unicode", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 84, "big5", "big5_bin", 1, 2, "", cppconn_mbcharlen_big5, check_mb_big5},
{ 85, "euckr", "euckr_bin", 1, 2, "", cppconn_mbcharlen_euckr, check_mb_euckr},
{ 86, "gb2312", "gb2312_bin", 1, 2, "", cppconn_mbcharlen_gb2312, check_mb_gb2312},
{ 87, "gbk", "gbk_bin", 1, 2, "", cppconn_mbcharlen_gbk, check_mb_gbk},
{ 88, "sjis", "sjis_bin", 1, 2, "", cppconn_mbcharlen_sjis, check_mb_sjis},
{ 89, "tis620", "tis620_bin", 1, 1, "", NULL, NULL},
{ 90, "ucs2", "ucs2_bin", 2, 2, "UCS-2 Unicode", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 91, "ujis", "ujis_bin", 1, 3, "", cppconn_mbcharlen_ujis, check_mb_ujis},
{ 94, "latin1", "latin1_spanish_ci", 1, 1, "", NULL, NULL},
{ 96, "cp932", "cp932_bin", 1, 2, "", cppconn_mbcharlen_cp932, check_mb_cp932},
{ 99, "cp1250", "cp1250_polish_ci", 1, 1, "", NULL, NULL},
{ 98, "eucjpms", "eucjpms_bin", 1, 3, "", cppconn_mbcharlen_eucjpms, check_mb_eucjpms},
{ 128, "ucs2", "ucs2_unicode_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 129, "ucs2", "ucs2_icelandic_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 130, "ucs2", "ucs2_latvian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 131, "ucs2", "ucs2_romanian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 132, "ucs2", "ucs2_slovenian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 133, "ucs2", "ucs2_polish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 134, "ucs2", "ucs2_estonian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 135, "ucs2", "ucs2_spanish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 136, "ucs2", "ucs2_swedish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 137, "ucs2", "ucs2_turkish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 138, "ucs2", "ucs2_czech_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 139, "ucs2", "ucs2_danish_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 140, "ucs2", "ucs2_lithunian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 141, "ucs2", "ucs2_slovak_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 142, "ucs2", "ucs2_spanish2_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 143, "ucs2", "ucs2_roman_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 144, "ucs2", "ucs2_persian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 145, "ucs2", "ucs2_esperanto_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 146, "ucs2", "ucs2_hungarian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 147, "ucs2", "ucs2_sinhala_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 148, "ucs2", "ucs2_german2_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 149, "ucs2", "ucs2_croatian_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 150, "ucs2", "ucs2_unicode_520_ci", 2, 2, "", cppconn_mbcharlen_ucs2, check_mb_ucs2},
{ 192, "utf8", "utf8_unicode_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 193, "utf8", "utf8_icelandic_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 194, "utf8", "utf8_latvian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 195, "utf8", "utf8_romanian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 196, "utf8", "utf8_slovenian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 197, "utf8", "utf8_polish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 198, "utf8", "utf8_estonian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 199, "utf8", "utf8_spanish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 200, "utf8", "utf8_swedish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 201, "utf8", "utf8_turkish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 202, "utf8", "utf8_czech_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 203, "utf8", "utf8_danish_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid },
{ 204, "utf8", "utf8_lithunian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid },
{ 205, "utf8", "utf8_slovak_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 206, "utf8", "utf8_spanish2_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 207, "utf8", "utf8_roman_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 208, "utf8", "utf8_persian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 209, "utf8", "utf8_esperanto_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 210, "utf8", "utf8_hungarian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 211, "utf8", "utf8_sinhala_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 212, "utf8", "utf8_german2_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 213, "utf8", "utf8_croatian_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 214, "utf8", "utf8_unicode_520_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 215, "utf8", "utf8_vietnamese_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 223, "utf8", "utf8_general_mysql500_ci", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 45, "utf8mb4", "utf8mb4_general_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 46, "utf8mb4", "utf8mb4_bin", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 224, "utf8mb4", "utf8mb4_unicode_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 225, "utf8mb4", "utf8mb4_icelandic_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 226, "utf8mb4", "utf8mb4_latvian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 227, "utf8mb4", "utf8mb4_romanian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 228, "utf8mb4", "utf8mb4_slovenian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 229, "utf8mb4", "utf8mb4_polish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 230, "utf8mb4", "utf8mb4_estonian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 231, "utf8mb4", "utf8mb4_spanish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 232, "utf8mb4", "utf8mb4_swedish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 233, "utf8mb4", "utf8mb4_turkish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 234, "utf8mb4", "utf8mb4_czech_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 235, "utf8mb4", "utf8mb4_danish_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 236, "utf8mb4", "utf8mb4_lithuanian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 237, "utf8mb4", "utf8mb4_slovak_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 238, "utf8mb4", "utf8mb4_spanish2_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 239, "utf8mb4", "utf8mb4_roman_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 240, "utf8mb4", "utf8mb4_persian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 241, "utf8mb4", "utf8mb4_esperanto_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 242, "utf8mb4", "utf8mb4_hungarian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 243, "utf8mb4", "utf8mb4_sinhala_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 244, "utf8mb4", "utf8mb4_german2_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 245, "utf8mb4", "utf8mb4_croatian_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 246, "utf8mb4", "utf8mb4_unicode_520_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
{ 247, "utf8mb4", "utf8mb4_vietnamese_ci", 1, 4, "", cppconn_mbcharlen_utf8mb4, check_mb_utf8mb4_valid},
/*Should not really happen, but adding them */
{ 254, "utf8", "utf8_general_cs", 1, 3, "", cppconn_mbcharlen_utf8, check_mb_utf8_valid},
{ 101, "utf16", "utf16_unicode_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 102, "utf16", "utf16_icelandic_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 103, "utf16", "utf16_latvian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 104, "utf16", "utf16_romanian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 105, "utf16", "utf16_slovenian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 106, "utf16", "utf16_polish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 107, "utf16", "utf16_estonian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 108, "utf16", "utf16_spanish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 109, "utf16", "utf16_swedish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 110, "utf16", "utf16_turkish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 111, "utf16", "utf16_czech_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 112, "utf16", "utf16_danish_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 113, "utf16", "utf16_lithuanian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 114, "utf16", "utf16_slovak_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 115, "utf16", "utf16_spanish2_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 116, "utf16", "utf16_roman_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 117, "utf16", "utf16_persian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 118, "utf16", "utf16_esperanto_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 119, "utf16", "utf16_hungarian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 120, "utf16", "utf16_sinhala_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 121, "utf16", "utf16_german2_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 122, "utf16", "utf16_croatian_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 123, "utf16", "utf16_unicode_520_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 124, "utf16", "utf16_vietnamese_ci", 2, 4, "", cppconn_mbcharlen_utf16, check_mb_utf16_valid},
{ 160, "utf32", "utf32_unicode_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 161, "utf32", "utf32_icelandic_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 162, "utf32", "utf32_latvian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 163, "utf32", "utf32_romanian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 164, "utf32", "utf32_slovenian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 165, "utf32", "utf32_polish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 166, "utf32", "utf32_estonian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 167, "utf32", "utf32_spanish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 168, "utf32", "utf32_swedish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 169, "utf32", "utf32_turkish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 170, "utf32", "utf32_czech_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 171, "utf32", "utf32_danish_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 172, "utf32", "utf32_lithuanian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 173, "utf32", "utf32_slovak_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 174, "utf32", "utf32_spanish2_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 175, "utf32", "utf32_roman_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 176, "utf32", "utf32_persian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 177, "utf32", "utf32_esperanto_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 178, "utf32", "utf32_hungarian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 179, "utf32", "utf32_sinhala_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 180, "utf32", "utf32_german2_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 181, "utf32", "utf32_croatian_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 182, "utf32", "utf32_unicode_520_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 183, "utf32", "utf32_vietnamese_ci", 4, 4, "", cppconn_mbcharlen_utf32, check_mb_utf32_valid},
{ 0, NULL, NULL, 0, 0, NULL, NULL, NULL}
};
#define MAGIC_BINARY_CHARSET_NR 63
const Util::OUR_CHARSET * Util::find_charset(unsigned int charsetnr)
{
const OUR_CHARSET * c = our_charsets60;
do {
if (c->nr == charsetnr) {
return c;
}
++c;
} while (c[0].nr != 0);
return NULL;
}
int Util::mysql_type_to_datatype( const MYSQL_FIELD * const field )
{
switch (field->type) {
case MYSQL_TYPE_BIT:
if (field->flags !=(BINARY_FLAG|UNSIGNED_FLAG))
return Core::Db::DataType::BIT;
return Core::Db::DataType::BINARY;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
return Core::Db::DataType::DECIMAL;
case MYSQL_TYPE_TINY:
return Core::Db::DataType::TINYINT;
case MYSQL_TYPE_SHORT:
return Core::Db::DataType::SMALLINT;
case MYSQL_TYPE_INT24:
return Core::Db::DataType::MEDIUMINT;
case MYSQL_TYPE_LONG:
return Core::Db::DataType::INTEGER;
case MYSQL_TYPE_LONGLONG:
return Core::Db::DataType::BIGINT;
case MYSQL_TYPE_FLOAT:
return Core::Db::DataType::REAL;
case MYSQL_TYPE_DOUBLE:
return Core::Db::DataType::DOUBLE;
case MYSQL_TYPE_NULL:
return Core::Db::DataType::SQLNULL;
case MYSQL_TYPE_TIMESTAMP:
return Core::Db::DataType::TIMESTAMP;
case MYSQL_TYPE_DATE:
return Core::Db::DataType::DATE;
case MYSQL_TYPE_TIME:
return Core::Db::DataType::TIME;
case MYSQL_TYPE_YEAR:
return Core::Db::DataType::YEAR;
case MYSQL_TYPE_DATETIME:
return Core::Db::DataType::TIMESTAMP;
case MYSQL_TYPE_TINY_BLOB:// should no appear over the wire
{
bool isBinary = (field->flags & BINARY_FLAG) &&
field->charsetnr == MAGIC_BINARY_CHARSET_NR;
const Util::OUR_CHARSET * const cs =
Util::find_charset(field->charsetnr);
if (!cs) {
std::ostringstream msg("Server sent unknown charsetnr (");
msg << field->charsetnr << ") . Please report";
throw std::runtime_error( msg.str() );
}
return isBinary ? Core::Db::DataType::VARBINARY : Core::Db::DataType::VARCHAR;
}
case MYSQL_TYPE_MEDIUM_BLOB:// should no appear over the wire
case MYSQL_TYPE_LONG_BLOB:// should no appear over the wire
case MYSQL_TYPE_BLOB:
{
bool isBinary = (field->flags & BINARY_FLAG) &&
field->charsetnr == MAGIC_BINARY_CHARSET_NR;
const Util::OUR_CHARSET * const cs =
Util::find_charset(field->charsetnr);
if (!cs) {
std::ostringstream msg("Server sent unknown charsetnr (");
msg << field->charsetnr << ") . Please report";
throw std::runtime_error( msg.str() );
}
return isBinary ? Core::Db::DataType::LONGVARBINARY : Core::Db::DataType::LONGVARCHAR;
}
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
if (field->flags & SET_FLAG) {
return Core::Db::DataType::SET;
}
if (field->flags & ENUM_FLAG) {
return Core::Db::DataType::ENUM;
}
if ((field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR) {
return Core::Db::DataType::VARBINARY;
}
return Core::Db::DataType::VARCHAR;
case MYSQL_TYPE_STRING:
if (field->flags & SET_FLAG) {
return Core::Db::DataType::SET;
}
if (field->flags & ENUM_FLAG) {
return Core::Db::DataType::ENUM;
}
if ((field->flags & BINARY_FLAG) && field->charsetnr == MAGIC_BINARY_CHARSET_NR) {
return Core::Db::DataType::BINARY;
}
return Core::Db::DataType::CHAR;
case MYSQL_TYPE_ENUM:
/* This hould never happen - MYSQL_TYPE_ENUM is not sent over the wire, just used in the server */
return Core::Db::DataType::ENUM;
case MYSQL_TYPE_SET:
/* This hould never happen - MYSQL_TYPE_SET is not sent over the wire, just used in the server */
return Core::Db::DataType::SET;
case MYSQL_TYPE_GEOMETRY:
return Core::Db::DataType::GEOMETRY;
#if LIBMYSQL_VERSION_ID > 50700
case MYSQL_TYPE_JSON:
return Core::Db::DataType::JSON;
#endif //LIBMYSQL_VERSION_ID > 50700
default:
return Core::Db::DataType::UNKNOWN;
}
}

View file

@ -1,130 +0,0 @@
/*
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>
#include <mysql.h>
#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>(Util::strtold((__a), NULL))
# define HAVE_FUNCTION_STRTOLL 1
# endif
# ifndef HAVE_FUNCTION_STRTOULL
# define strtoull(__a, __b, __c) static_cast<unsigned long long>(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))
namespace Util
{
long double strtold( const char *nptr, char **endptr );
long double strtonum( const std::string &str, int radix = 10 );
int32_t mysql_type_to_datatype( const MYSQL_FIELD * const field );
typedef struct st_our_charset
{
unsigned int nr;
const char *name;
const char *collation;
unsigned int char_minlen;
unsigned int char_maxlen;
const char *comment;
unsigned int (*mb_charlen)(unsigned int c);
unsigned int (*mb_valid)(const char *start, const char *end);
} OUR_CHARSET;
const OUR_CHARSET * find_charset(unsigned int charsetnr);
}
#endif //SAPPHIRE_MYSQL_UTIL_H

View file

@ -26,9 +26,9 @@ if(MSVC)
endif()
if (UNIX)
target_link_libraries(server_lobby Common xivdat pthread mysqlclient dl z)
target_link_libraries(server_lobby Common xivdat pthread mysqlclient mysqlConnector dl z)
else()
target_link_libraries(server_lobby Common xivdat libmysql zlib1)
target_link_libraries(server_lobby Common xivdat libmysql mysqConnector zlib1)
endif()
target_link_libraries(server_lobby ${Boost_LIBRARIES} ${Boost_LIBRARIES})

View file

@ -25,9 +25,9 @@ if(MSVC)
endif()
if (UNIX)
target_link_libraries (server_rest Common xivdat pthread mysqlclient dl z)
target_link_libraries (server_rest Common xivdat pthread mysqlclient mysqlConnector dl z)
else()
target_link_libraries (server_rest Common xivdat libmysql zlib1)
target_link_libraries (server_rest Common xivdat libmysql mysqlConnector zlib1)
endif()
target_link_libraries( server_rest ${Boost_LIBRARIES} ${Boost_LIBRARIES} )

View file

@ -23,7 +23,7 @@ file(GLOB SERVER_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../../bin/")
add_executable(server_zone ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES} )
add_dependencies(server_zone Common xivdat)
add_dependencies(server_zone Common xivdat mysqlConnector )
set_target_properties(server_zone PROPERTIES
CXX_STANDARD 14
@ -41,9 +41,9 @@ if(MSVC)
endif()
if (UNIX)
target_link_libraries ( server_zone Common xivdat pthread mysqlclient dl z )
target_link_libraries ( server_zone Common xivdat pthread mysqlclient mysqlConnector dl z )
else()
target_link_libraries ( server_zone Common xivdat libmysql zlib1 )
target_link_libraries ( server_zone Common xivdat libmysql zlib1 mysqlConnector )
endif()
target_link_libraries(server_zone ${Boost_LIBRARIES} ${Boost_LIBRARIES} )

View file

@ -8,12 +8,12 @@
#include <src/servers/Server_Common/Config/XMLConfig.h>
#include <src/servers/Server_Common/Database/Database.h>
#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/Database/PreparedStatement.h>
#include <src/servers/Server_Common/Database/PreparedResultSet.h>
#include <MySqlBase.h>
#include <Connection.h>
#include <Statement.h>
#include <ResultSet.h>
#include <PreparedStatement.h>
#include <PreparedResultSet.h>
#include <src/servers/Server_Common/Network/Connection.h>
#include <src/servers/Server_Common/Network/Hive.h>