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:
parent
bfd3cbac3c
commit
2cd801c7cf
25 changed files with 17 additions and 3389 deletions
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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 ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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 ) );
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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})
|
||||
|
|
|
@ -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} )
|
||||
|
|
|
@ -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} )
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue