mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-19 03:57:14 +01:00
Partial untested implementation of the MySQL module.
This commit is contained in:
parent
f6987b3de2
commit
279479cddc
@ -7,6 +7,7 @@
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Win32 Debug Dynamic">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win32-d/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32-d/" />
|
||||
<Option object_output="../obj/mingw32-d/" />
|
||||
@ -17,6 +18,8 @@
|
||||
<Add option="-g" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
<Add directory="../config/mingw32/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
@ -27,6 +30,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win32 Release Dynamic">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win32/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32/" />
|
||||
<Option object_output="../obj/mingw32/" />
|
||||
@ -37,6 +41,8 @@
|
||||
<Add option="-m32" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
<Add directory="../config/mingw32/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -48,6 +54,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Debug Dynamic">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win64-d/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64-d/" />
|
||||
<Option object_output="../obj/mingw64-d/" />
|
||||
@ -59,6 +66,8 @@
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
<Add directory="../config/mingw64/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
@ -69,6 +78,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Release Dynamic">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win64/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64/" />
|
||||
<Option object_output="../obj/mingw64/" />
|
||||
@ -80,6 +90,8 @@
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
<Add directory="../config/mingw64/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -91,6 +103,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Debug Dynamic">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux32-d/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32-d/" />
|
||||
<Option object_output="../obj/gcc32-d/" />
|
||||
@ -102,13 +115,18 @@
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add directory="../lib/gcc32-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Release Dynamic">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux32/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32/" />
|
||||
<Option object_output="../obj/gcc32/" />
|
||||
@ -120,14 +138,19 @@
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m32" />
|
||||
<Add directory="../lib/gcc32" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux64 Debug Dynamic">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux64-d/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64-d/" />
|
||||
<Option object_output="../obj/gcc64-d/" />
|
||||
@ -140,13 +163,18 @@
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add directory="../lib/gcc64-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux64 Release Dynamic">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux64/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64/" />
|
||||
<Option object_output="../obj/gcc64/" />
|
||||
@ -159,14 +187,19 @@
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m64" />
|
||||
<Add directory="../lib/gcc64" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win32 Debug Standalone">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win32-d/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32-d/" />
|
||||
<Option object_output="../obj/mingw32-d/" />
|
||||
@ -180,6 +213,8 @@
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
<Add directory="../config/mingw32/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
@ -191,6 +226,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win32 Release Standalone">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win32/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32/" />
|
||||
<Option object_output="../obj/mingw32/" />
|
||||
@ -204,6 +240,8 @@
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
<Add directory="../config/mingw32/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -216,6 +254,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Debug Standalone">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win64-d/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64-d/" />
|
||||
<Option object_output="../obj/mingw64-d/" />
|
||||
@ -230,6 +269,8 @@
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
<Add directory="../config/mingw64/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
@ -241,6 +282,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Release Standalone">
|
||||
<Option platforms="Windows;" />
|
||||
<Option output="../bin/win64/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64/" />
|
||||
<Option object_output="../obj/mingw64/" />
|
||||
@ -255,6 +297,8 @@
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
<Add directory="../config/mingw64/mysql" />
|
||||
<Add directory="../include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -267,6 +311,7 @@
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Debug Standalone">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux32-d/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32-d/" />
|
||||
<Option object_output="../obj/gcc32-d/" />
|
||||
@ -281,14 +326,19 @@
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc32-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Release Standalone">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux32/mod_mysql32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32/" />
|
||||
<Option object_output="../obj/gcc32/" />
|
||||
@ -303,6 +353,7 @@
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -310,8 +361,12 @@
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc32" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux64 Debug Standalone">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux64-d/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64-d/" />
|
||||
<Option object_output="../obj/gcc64-d/" />
|
||||
@ -327,14 +382,19 @@
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc64-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux64 Release Standalone">
|
||||
<Option platforms="Unix;" />
|
||||
<Option output="../bin/linux64/mod_mysql64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64/" />
|
||||
<Option object_output="../obj/gcc64/" />
|
||||
@ -350,6 +410,7 @@
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
<Add directory="/usr/include/mysql" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
@ -357,6 +418,9 @@
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc64" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='/bin/cp -rf "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
@ -371,10 +435,36 @@
|
||||
<Add directory="../include" />
|
||||
<Add directory="../config/common" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="mysql" />
|
||||
</Linker>
|
||||
<Unit filename="../modules/mysql/Account.cpp" />
|
||||
<Unit filename="../modules/mysql/Account.hpp" />
|
||||
<Unit filename="../modules/mysql/Column.cpp" />
|
||||
<Unit filename="../modules/mysql/Column.hpp" />
|
||||
<Unit filename="../modules/mysql/Common.cpp" />
|
||||
<Unit filename="../modules/mysql/Common.hpp" />
|
||||
<Unit filename="../modules/mysql/Connection.cpp" />
|
||||
<Unit filename="../modules/mysql/Connection.hpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Connection.cpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Connection.hpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Result.cpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Result.hpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Statement.cpp" />
|
||||
<Unit filename="../modules/mysql/Handle/Statement.hpp" />
|
||||
<Unit filename="../modules/mysql/Module.cpp" />
|
||||
<Unit filename="../modules/mysql/Module.hpp" />
|
||||
<Unit filename="../modules/mysql/ResultSet.cpp" />
|
||||
<Unit filename="../modules/mysql/ResultSet.hpp" />
|
||||
<Unit filename="../modules/mysql/Savepoint.cpp" />
|
||||
<Unit filename="../modules/mysql/Savepoint.hpp" />
|
||||
<Unit filename="../modules/mysql/Statement.cpp" />
|
||||
<Unit filename="../modules/mysql/Statement.hpp" />
|
||||
<Unit filename="../modules/mysql/Transaction.cpp" />
|
||||
<Unit filename="../modules/mysql/Transaction.hpp" />
|
||||
<Unit filename="../shared/Base/Buffer.cpp" />
|
||||
<Unit filename="../shared/Base/Buffer.hpp" />
|
||||
<Unit filename="../shared/Base/Utility.cpp" />
|
||||
<Unit filename="../shared/Base/Utility.hpp" />
|
||||
<Unit filename="../shared/SqMod.cpp" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
|
@ -9,6 +9,7 @@
|
||||
<Project filename="ModJSON.cbp" />
|
||||
<Project filename="ModSQLite.cbp" />
|
||||
<Project filename="ModMMDB.cbp" />
|
||||
<Project filename="ModMySQL.cbp" />
|
||||
<Project filename="ModMongoose.cbp" />
|
||||
<Project filename="ModSample.cbp" />
|
||||
</Workspace>
|
||||
|
@ -1,49 +1,126 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
#include "Connection.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Account::Account(CSStr host, CSStr user, CSStr pass, CSStr schema, Uint16 port, CSStr socket)
|
||||
: m_Host(host ? host : _SC(""))
|
||||
, m_User(user ? user : _SC(""))
|
||||
, m_Pass(pass ? pass : _SC(""))
|
||||
, m_Port(port)
|
||||
, m_Schema(schema ? schema : _SC(""))
|
||||
, m_Socket(socket ? socket : _SC(""))
|
||||
const String Account::s_String = String(_SC(""));
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Account::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMySQLAccount");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Account::Account(CSStr host, CSStr user, CSStr pass, CSStr name, SQInteger port, CSStr socket)
|
||||
: m_Port(0)
|
||||
, m_Host()
|
||||
, m_User()
|
||||
, m_Pass()
|
||||
, m_Name()
|
||||
, m_Socket()
|
||||
, m_Flags(CLIENT_MULTI_STATEMENTS)
|
||||
, m_SSL_Key()
|
||||
, m_SSL_Cert()
|
||||
, m_SSL_CA()
|
||||
, m_SSL_CA_Path()
|
||||
, m_SSL_Cipher()
|
||||
, m_Autocommit()
|
||||
, m_Options()
|
||||
, m_AutoCommit(false)
|
||||
{
|
||||
// Attempt to extract the port number from the host
|
||||
String::size_type pos = m_Host.find(':');
|
||||
// Was it specified in the host
|
||||
if (pos != String::npos)
|
||||
// Validate the specified port number
|
||||
if (port >= 0xFFFF)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Attempt to extract the numeric value
|
||||
ULong num = std::stol(m_Host.substr(pos + 1));
|
||||
// Is the port number withing range?
|
||||
if (num > 0xFFFF)
|
||||
{
|
||||
SHROWF("Port number out of range: %lu");
|
||||
}
|
||||
// Assign the extracted port number
|
||||
m_Port = static_cast< Uint16 >(num);
|
||||
// Remove everything after the port number
|
||||
m_Host = m_Host.substr(0, pos);
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
SHROWF("Cannot extract the port number [%s]", e.what());
|
||||
}
|
||||
STHROWF("Port number out of range: " _PRINT_INT_FMT, port);
|
||||
}
|
||||
// Assign the specified port
|
||||
else
|
||||
{
|
||||
m_Port = ConvTo< Uint16 >::From(port);
|
||||
}
|
||||
// Assign the remaining values
|
||||
SetHost(host);
|
||||
SetUser(user);
|
||||
SetPass(pass);
|
||||
SetName(name);
|
||||
SetSocket(socket);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Account::Cmp(const Account & o) const
|
||||
{
|
||||
if (m_User == o.m_User && m_Pass == o.m_Pass)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_User > o.m_User && m_Pass > o.m_Pass)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Account::ToString() const
|
||||
{
|
||||
return ToStringF("%s:%s@%s:%u", m_User.c_str(), m_Pass.c_str(), m_Host.c_str(), m_Port);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Account::SetHost(CSStr addr)
|
||||
{
|
||||
// Clear the current host address
|
||||
m_Host.assign(_SC(""));
|
||||
// Validate the given address
|
||||
if (!addr || *addr == '\0')
|
||||
{
|
||||
return; // Nothing to set.
|
||||
}
|
||||
// See if there'sa colon in the address
|
||||
CSStr pos = std::strchr(addr, ':');
|
||||
// Should we look for a port number?
|
||||
if (pos != nullptr)
|
||||
{
|
||||
// Assign the address portion
|
||||
m_Host.assign(addr, pos - addr);
|
||||
// Attempt to extract the numeric value
|
||||
const Ulong num = std::strtoul(++pos, nullptr, 10);
|
||||
// Is the port number withing range?
|
||||
if (num > 0xFFFF)
|
||||
{
|
||||
STHROWF("Port number out of range: %lu", num);
|
||||
}
|
||||
// Assign the extracted port number
|
||||
m_Port = ConvTo< Uint16 >::From(num);
|
||||
}
|
||||
// Assign the address as is
|
||||
else
|
||||
{
|
||||
m_Host.assign(addr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Account::SetPortNum(SQInteger port)
|
||||
{
|
||||
// Validate the specified port number
|
||||
if (port >= 0xFFFF)
|
||||
{
|
||||
STHROWF("Port number out of range: " _PRINT_INT_FMT, port);
|
||||
}
|
||||
// Assign the specified port number
|
||||
m_Port = ConvTo< Uint16 >::From(port);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -68,7 +145,7 @@ void Account::SetSSL(CSStr key, CSStr cert, CSStr ca, CSStr ca_path, CSStr ciphe
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Table Account::GetOptions() const
|
||||
Table Account::GetOptionsTable() const
|
||||
{
|
||||
// Allocate an empty table
|
||||
Table tbl(DefaultVM::Get());
|
||||
@ -87,7 +164,7 @@ const String & Account::GetOption(CSStr name) const
|
||||
// Make sure the specified name is valid
|
||||
if (!name || *name == '\0')
|
||||
{
|
||||
SHROWF("Invalid or empty option name");
|
||||
STHROWF("Invalid or empty option name");
|
||||
}
|
||||
// Attempt to find the requested option
|
||||
const Options::const_iterator itr = m_Options.find(name);
|
||||
@ -101,22 +178,28 @@ void Account::SetOption(CSStr name, CSStr value)
|
||||
// Make sure the specified name is valid
|
||||
if (!name || *name == '\0')
|
||||
{
|
||||
SHROWF("Invalid or empty option name");
|
||||
STHROWF("Invalid or empty option name");
|
||||
}
|
||||
// Assign the specified value
|
||||
m_Options[name] = value ? value : _SC("");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Account::RemoveOption(CSStr name) const
|
||||
void Account::RemoveOption(CSStr name)
|
||||
{
|
||||
// Make sure the specified name is valid
|
||||
if (!name || *name == '\0')
|
||||
{
|
||||
SHROWF("Invalid or empty option name");
|
||||
STHROWF("Invalid or empty option name");
|
||||
}
|
||||
// Erase the specified value
|
||||
m_Options.erase(name);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection Account::Connect() const
|
||||
{
|
||||
return Connection(*this);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -17,6 +17,35 @@ public:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::unordered_map< String, String > Options;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Uint16 m_Port; // Server port.
|
||||
String m_Host; // Host address.
|
||||
String m_User; // User name.
|
||||
String m_Pass; // User password.
|
||||
String m_Name; // Database name.
|
||||
String m_Socket; // Unix socket.
|
||||
Ulong m_Flags; // Client connection flags.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String m_SSL_Key; // SSL key.
|
||||
String m_SSL_Cert; // SSL certificate.
|
||||
String m_SSL_CA; // SSL certificate authority.
|
||||
String m_SSL_CA_Path; // SSL certificate authority path.
|
||||
String m_SSL_Cipher; // SSL Cipher.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Options m_Options; // Option container.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool m_AutoCommit; // Toggle autocommit.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const String s_String; // Dummy used to return a reference to a null string.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base Constructor.
|
||||
*/
|
||||
@ -38,8 +67,8 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base Constructor.
|
||||
*/
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr schema)
|
||||
: Account(host, user, pass, schema, 3306, _SC(""))
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr name)
|
||||
: Account(host, user, pass, name, 3306, _SC(""))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -47,8 +76,8 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base Constructor.
|
||||
*/
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr schema, Uint16 port)
|
||||
: Account(host, user, pass, schema, 3306, _SC(""))
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr name, SQInteger port)
|
||||
: Account(host, user, pass, name, port, _SC(""))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -56,15 +85,15 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base Constructor.
|
||||
*/
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr schema, Uint16 port, CSStr socket);
|
||||
Account(CSStr host, CSStr user, CSStr pass, CSStr name, SQInteger port, CSStr socket);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor (disabled).
|
||||
* Copy constructor.
|
||||
*/
|
||||
Account(const Account & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor (disabled).
|
||||
* Move constructor.
|
||||
*/
|
||||
Account(Account && o) = default;
|
||||
|
||||
@ -74,47 +103,32 @@ public:
|
||||
~Account() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator (disabled).
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Account & operator = (const Account & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator (disabled).
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Account & operator = (Account && o) = default;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String m_Host; // Host address.
|
||||
String m_User; // User name.
|
||||
String m_Pass; // User password.
|
||||
Uint16 m_Port; // Server port.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String m_Schema; // Server schema.
|
||||
String m_Socket; // Unix socket.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String m_SSL_Key; // SSL key.
|
||||
String m_SSL_Cert; // SSL certificate.
|
||||
String m_SSL_CA; // SSL certificate authority.
|
||||
String m_SSL_CA_Path; // SSL certificate authority path.
|
||||
String m_SSL_Cipher; // SSL Cipher.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool m_Autocommit; // Toggle autocommit.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Options m_Options; // Option container.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const String s_String; // Dummy used to return a reference to a null string.
|
||||
|
||||
public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Account & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the host address specified during creation.
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the host address specified during creation.
|
||||
*/
|
||||
const String & GetHost() const
|
||||
{
|
||||
@ -122,7 +136,12 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the user name specified during creation.
|
||||
* Modify the host address specified during creation.
|
||||
*/
|
||||
void SetHost(CSStr addr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the user name specified during creation.
|
||||
*/
|
||||
const String & GetUser() const
|
||||
{
|
||||
@ -130,7 +149,15 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the password specified during creation.
|
||||
* Modify the user name specified during creation.
|
||||
*/
|
||||
void SetUser(CSStr user)
|
||||
{
|
||||
m_User.assign(user != nullptr ? user : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the password specified during creation.
|
||||
*/
|
||||
const String & GetPass() const
|
||||
{
|
||||
@ -138,23 +165,44 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the server port specified during creation.
|
||||
* Modify the password specified during creation.
|
||||
*/
|
||||
const Uint16 GetPort() const
|
||||
void SetPass(CSStr pass)
|
||||
{
|
||||
m_Pass.assign(pass != nullptr ? pass : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the database name specified during creation.
|
||||
*/
|
||||
const String & GetName() const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the database name specified during creation.
|
||||
*/
|
||||
void SetName(CSStr name)
|
||||
{
|
||||
m_Name.assign(name != nullptr ? name : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the server port specified during creation.
|
||||
*/
|
||||
Uint16 GetPortNum() const
|
||||
{
|
||||
return m_Port;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the server schema.
|
||||
* Modify the server port specified during creation.
|
||||
*/
|
||||
const String & GetSchema() const
|
||||
{
|
||||
return m_Schema;
|
||||
}
|
||||
void SetPortNum(SQInteger port);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the server schema.
|
||||
* Retrieve the server socket.
|
||||
*/
|
||||
const String & GetSocket() const
|
||||
{
|
||||
@ -162,7 +210,48 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the SSL key.
|
||||
* Modify the server socket.
|
||||
*/
|
||||
void SetSocket(CSStr socket)
|
||||
{
|
||||
m_Socket.assign(socket != nullptr ? socket : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current client connection flags.
|
||||
*/
|
||||
SQInteger GetFlags() const
|
||||
{
|
||||
return m_Flags;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the current client connection flags.
|
||||
*/
|
||||
void SetFlags(SQInteger flags)
|
||||
{
|
||||
m_Flags = flags;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the current client connection flags.
|
||||
*/
|
||||
void EnableFlags(SQInteger flags)
|
||||
{
|
||||
m_Flags |= flags;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the current client connection flags.
|
||||
*/
|
||||
void DisableFlags(SQInteger flags)
|
||||
{
|
||||
m_Flags |= flags;
|
||||
m_Flags ^= flags;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the SSL key.
|
||||
*/
|
||||
const String & GetSSL_Key() const
|
||||
{
|
||||
@ -170,15 +259,31 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the SSL certificate.
|
||||
* Modify the SSL key.
|
||||
*/
|
||||
const String & GetSSL_Cert() const
|
||||
void SetSSL_Key(CSStr key)
|
||||
{
|
||||
return m_SSL_Cipher;
|
||||
m_SSL_Key.assign(key != nullptr ? key : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the SSL certificate authority.
|
||||
* Retrieve the SSL certificate.
|
||||
*/
|
||||
const String & GetSSL_Cert() const
|
||||
{
|
||||
return m_SSL_Cert;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the SSL certificate.
|
||||
*/
|
||||
void SetSSL_Cert(CSStr cert)
|
||||
{
|
||||
m_SSL_Cert.assign(cert != nullptr ? cert : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the SSL certificate authority.
|
||||
*/
|
||||
const String & GetSSL_CA() const
|
||||
{
|
||||
@ -186,7 +291,15 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the SSL certificate authority path.
|
||||
* Modify the SSL certificate authority.
|
||||
*/
|
||||
void SetSSL_CA(CSStr ca)
|
||||
{
|
||||
m_SSL_CA.assign(ca != nullptr ? ca : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the SSL certificate authority path.
|
||||
*/
|
||||
const String & GetSSL_CA_Path() const
|
||||
{
|
||||
@ -194,13 +307,29 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the SSL cipher.
|
||||
* Modify the SSL certificate authority path.
|
||||
*/
|
||||
void SetSSL_CA_Path(CSStr capath)
|
||||
{
|
||||
m_SSL_CA_Path.assign(capath != nullptr ? capath : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the SSL cipher.
|
||||
*/
|
||||
const String & GetSSL_Cipher() const
|
||||
{
|
||||
return m_SSL_Cipher;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the SSL cipher.
|
||||
*/
|
||||
void SetSSL_Cipher(CSStr cipher)
|
||||
{
|
||||
m_SSL_Cipher.assign(cipher != nullptr ? cipher : _SC(""));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the SSL information.
|
||||
*/
|
||||
@ -209,26 +338,34 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether autocommit is enabled or not.
|
||||
*/
|
||||
bool GetAutocommit() const
|
||||
bool GetAutoCommit() const
|
||||
{
|
||||
return m_Autocommit;
|
||||
return m_AutoCommit;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether autocommit should be enabled or not.
|
||||
*/
|
||||
void SetAutocommit(bool toggle)
|
||||
void SetAutoCommit(bool toggle)
|
||||
{
|
||||
m_Autocommit = toggle;
|
||||
m_AutoCommit = toggle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the entire options container.
|
||||
* Retrieve the entire options container as a table.
|
||||
*/
|
||||
Table GetOptions() const;
|
||||
const Options & GetOptions() const
|
||||
{
|
||||
return m_Options;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get a value from the options container.
|
||||
* Retrieve the entire options container as a table.
|
||||
*/
|
||||
Table GetOptionsTable() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a value from the options container.
|
||||
*/
|
||||
const String & GetOption(CSStr name) const;
|
||||
|
||||
@ -240,10 +377,10 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Remove a value from the options container.
|
||||
*/
|
||||
void RemoveOption(CSStr name) const;
|
||||
void RemoveOption(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the number of values in the options container.
|
||||
* Retrieve the number of values in the options container.
|
||||
*/
|
||||
Uint32 OptionsCount() const
|
||||
{
|
||||
@ -265,6 +402,11 @@ public:
|
||||
{
|
||||
m_Options.clear();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create a connection with the current account information.
|
||||
*/
|
||||
Connection Connect() const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,17 +0,0 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
@ -1,5 +1,5 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
#ifndef _SQMYSQL_COLUMN_HPP_
|
||||
#define _SQMYSQL_COLUMN_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
@ -14,4 +14,4 @@ namespace SqMod {
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
||||
#endif // _SQMYSQL_COLUMN_HPP_
|
||||
|
@ -1,73 +1,9 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SStr GetTempBuff()
|
||||
{
|
||||
return g_Buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetTempBuffSize()
|
||||
{
|
||||
return sizeof(g_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqThrowF(CSStr str, ...)
|
||||
{
|
||||
// Initialize the argument list
|
||||
va_list args;
|
||||
va_start (args, str);
|
||||
// Write the requested contents
|
||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||
strcpy(g_Buffer, "Unknown error has occurred");
|
||||
// Release the argument list
|
||||
va_end(args);
|
||||
// Throw the exception with the resulted message
|
||||
throw Sqrat::Exception(g_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr FmtStr(CSStr str, ...)
|
||||
{
|
||||
// Initialize the argument list
|
||||
va_list args;
|
||||
va_start (args, str);
|
||||
// Write the requested contents
|
||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||
g_Buffer[0] = 0; /* make sure the string is terminated */
|
||||
// Release the argument list
|
||||
va_end(args);
|
||||
// Return the data from the buffer
|
||||
return g_Buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StackGuard::StackGuard(HSQUIRRELVM vm)
|
||||
: m_Top(sq_gettop(vm)), m_VM(vm)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StackGuard::~StackGuard()
|
||||
{
|
||||
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -2,23 +2,10 @@
|
||||
#define _SQMYSQL_COMMON_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "ModBase.hpp"
|
||||
#include "Base/Utility.hpp"
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Forward declaration of various MySQL types to avoid including the header where not necessary.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct st_mysql MYSQL;
|
||||
typedef struct st_mysql_stmt MYSQL_STMT;
|
||||
typedef struct st_mysql_bind MYSQL_BIND;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <mysql.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
@ -37,116 +24,25 @@ namespace SqMod {
|
||||
#define SQMYSQL_VERSION_PATCH 1
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the temporary buffer.
|
||||
* Handle validation.
|
||||
*/
|
||||
SStr GetTempBuff();
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
#define THROW_CURRENT(x, a) x.GetHnd().ThrowCurrent(a, __FILE__, __LINE__)
|
||||
#define THROW_CURRENT_HND(x, a) x.ThrowCurrent(a, __FILE__, __LINE__)
|
||||
#else
|
||||
#define THROW_CURRENT(x, a) x.GetHnd().ThrowCurrent(a)
|
||||
#define THROW_CURRENT_HND(x, a) x.ThrowCurrent(a)
|
||||
#endif // _DEBUG
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the size of the temporary buffer.
|
||||
* Forward declarations.
|
||||
*/
|
||||
Uint32 GetTempBuffSize();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Throw a formatted exception.
|
||||
*/
|
||||
void SqThrowF(CSStr str, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Generate a formatted string.
|
||||
*/
|
||||
CSStr FmtStr(CSStr str, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Implements RAII to restore the VM stack to it's initial size on function exit.
|
||||
*/
|
||||
struct StackGuard
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
StackGuard();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StackGuard(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StackGuard();
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
StackGuard(const StackGuard &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
StackGuard(StackGuard &&);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
StackGuard & operator = (const StackGuard &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
StackGuard & operator = (StackGuard &&);
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HSQUIRRELVM m_VM; // The VM where the stack should be restored.
|
||||
Int32 m_Top; // The top of the stack when this instance was created.
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Helper structure for retrieving a value from the stack as a string or a formatted string.
|
||||
*/
|
||||
struct StackStrF
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
CSStr mPtr; // Pointer to the C string that was retrieved.
|
||||
SQInteger mLen; // The string length if it could be retrieved.
|
||||
SQRESULT mRes; // The result of the retrieval attempts.
|
||||
HSQOBJECT mObj; // Strong reference to the string object.
|
||||
HSQUIRRELVM mVM; // The associated virtual machine.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
StackStrF(const StackStrF & o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
StackStrF(StackStrF && o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StackStrF();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
StackStrF & operator = (const StackStrF & o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
StackStrF & operator = (StackStrF && o) = delete;
|
||||
};
|
||||
class Account;
|
||||
class Column;
|
||||
class Connection;
|
||||
class ResultSet;
|
||||
class Statement;
|
||||
class Transaction;
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
|
@ -1,10 +1,120 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
#include "Connection.hpp"
|
||||
#include "Statement.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMySQLConnection");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Connection::Cmp(const Connection & o) const
|
||||
{
|
||||
if (m_Handle == o.m_Handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Handle.HndPtr() > o.m_Handle.HndPtr())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Connection::ToString() const
|
||||
{
|
||||
// Do we have a valid handle?
|
||||
if (m_Handle)
|
||||
{
|
||||
ToStringF("%s:%s@%s:%u", m_Handle->mUser.c_str(), m_Handle->mPass.c_str(),
|
||||
m_Handle->mHost.c_str(), m_Handle->mPort);
|
||||
}
|
||||
// Default to an epty string
|
||||
return _SC("");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::SetName(CSStr name)
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Attempt to select the database with the given name
|
||||
if (mysql_select_db(m_Handle, name) != 0)
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot select database");
|
||||
}
|
||||
// Remember the database name
|
||||
m_Handle->mName.assign(name);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::SetCharset(CSStr charset)
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Attempt to Set the default character set for the managed connection
|
||||
if (mysql_set_character_set(m_Handle, charset) != 0)
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot apply character set");
|
||||
}
|
||||
// Remember the character set
|
||||
m_Handle->mCharset.assign(charset);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::SetAutoCommit(bool toggle)
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Attempt to toggle auto-commit if necessary
|
||||
if (m_Handle->mAutoCommit != toggle && mysql_autocommit(m_Handle, toggle) != 0)
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot toggle auto-commit");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Handle->mAutoCommit = toggle;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::Execute(CSStr query)
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Perform the requested operation
|
||||
return m_Handle->Execute(query);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::Insert(CSStr /*query*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::Query(CSStr /*query*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Statement Connection::GetStatement(CSStr query)
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return Statement(m_Handle, query);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
#ifndef _SQMYSQL_CONNECTION_HPP_
|
||||
#define _SQMYSQL_CONNECTION_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
#include "Handle/Connection.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
@ -12,13 +12,30 @@ namespace SqMod {
|
||||
*/
|
||||
class Connection
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
ConnHnd m_Handle; // Handle to the actual database connection.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Connection()
|
||||
: m_Handle()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Connection(const Account & acc);
|
||||
Connection(const Account & acc)
|
||||
: m_Handle(acc)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
@ -45,28 +62,36 @@ protected:
|
||||
*/
|
||||
Connection & operator = (Connection && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Connection & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the managed connection handle and throw exception if it doesn't exist.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
ConnHnd m_Handle; // Handle to the actual database connection.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the hosted connection handle.
|
||||
* Implicit conversion to the managed connection handle.
|
||||
*/
|
||||
operator ConnHnd ()
|
||||
operator ConnHnd & ()
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the hosted connection handle.
|
||||
* Implicit conversion to the managed connection handle.
|
||||
*/
|
||||
operator const ConnHnd & () const
|
||||
{
|
||||
@ -74,91 +99,263 @@ public:
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to connect to the database.
|
||||
* Retrieve the managed connection handle.
|
||||
*/
|
||||
bool Connect();
|
||||
ConnHnd & GetHnd()
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Disconnect from the currently connected database.
|
||||
* Retrieve the managed connection handle.
|
||||
*/
|
||||
void Disconnect();
|
||||
const ConnHnd & GetHnd() const
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether a successful connection was made or not.
|
||||
*/
|
||||
bool Connected() const
|
||||
{
|
||||
return (m_Handle != nullptr);
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the account used to make the connection.
|
||||
* Disconnect from the currently connected database.
|
||||
*/
|
||||
const Account::Ref & GetAccount() const
|
||||
void Disconnect()
|
||||
{
|
||||
return m_Account;
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Perform the requested operation
|
||||
m_Handle->Disconnect();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the server schema.
|
||||
* Retrieve the last received error number.
|
||||
*/
|
||||
const String & GetSchema() const
|
||||
SQInteger GetLastErrNo() const
|
||||
{
|
||||
return m_Schema;
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Handle->mErrNo);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the server schema.
|
||||
* Retrieve the last received error message.
|
||||
*/
|
||||
void SetSchema(const String & schema);
|
||||
const String & GetLastErrStr() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mErrStr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Get the character set.
|
||||
* Retrieve the connection port number.
|
||||
*/
|
||||
SQInteger GetPortNum() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Handle->mPort);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection host address.
|
||||
*/
|
||||
const String & GetHost() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mHost;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection user name.
|
||||
*/
|
||||
const String & GetUser() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mUser;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection password.
|
||||
*/
|
||||
const String & GetPass() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mPass;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the selected database name.
|
||||
*/
|
||||
const String & GetName() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mName;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the selected database name.
|
||||
*/
|
||||
void SetName(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection socket.
|
||||
*/
|
||||
const String & GetSocket() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSocket;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection flags.
|
||||
*/
|
||||
SQInteger GetFlags() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Handle->mFlags);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection SSL key.
|
||||
*/
|
||||
const String & GetSSL_Key() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSSL_Key;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection SSL certificate.
|
||||
*/
|
||||
const String & GetSSL_Cert() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSSL_Cert;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection SSL certificate authority.
|
||||
*/
|
||||
const String & GetSSL_CA() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSSL_CA;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection SSL certificate authority path.
|
||||
*/
|
||||
const String & GetSSL_CA_Path() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSSL_CA_Path;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the connection SSL cipher.
|
||||
*/
|
||||
const String & GetSSL_Cipher() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mSSL_Cipher;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the default character set for the managed connection.
|
||||
*/
|
||||
const String & GetCharset() const
|
||||
{
|
||||
return m_Charset;
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mCharset;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the character set.
|
||||
* Modify the default character set for the managed connection.
|
||||
*/
|
||||
void SetCharset(const String & charset);
|
||||
void SetCharset(CSStr charset);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether auto-commit is enabled or not.
|
||||
*/
|
||||
bool GetAutocommit() const
|
||||
bool GetAutoCommit() const
|
||||
{
|
||||
return m_Autocommit;
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mAutoCommit;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether auto-commit should be enabled or not.
|
||||
*/
|
||||
void SetAutocommit(bool toggle);
|
||||
void SetAutoCommit(bool toggle);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the connection is in the middle of a transaction.
|
||||
*/
|
||||
bool GetInTransaction() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return m_Handle->mInTransaction;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Execute a query on the server.
|
||||
*/
|
||||
Uint64 Execute(const String & query);
|
||||
SQInteger Execute(CSStr query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Execute a query on the server.
|
||||
*/
|
||||
Uint64 Insert(const String & query);
|
||||
SQInteger Insert(CSStr query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Execute a query on the server.
|
||||
*/
|
||||
Uint64 Query(const String & query);
|
||||
SQInteger Query(CSStr query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*
|
||||
*/
|
||||
StatementRef GetStatement(const String & query);
|
||||
Statement GetStatement(CSStr query);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
||||
#endif // _SQMYSQL_CONNECTION_HPP_
|
||||
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,17 +0,0 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,17 +0,0 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
207
modules/mysql/Handle/Connection.cpp
Normal file
207
modules/mysql/Handle/Connection.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Connection.hpp"
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConnHnd::Validate() const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||
{
|
||||
STHROWF("Invalid MySQL connection reference");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
void ConnHnd::Handle::ThrowCurrent(CCStr act, CCStr file, Int32 line)
|
||||
#else
|
||||
void ConnHnd::Handle::ThrowCurrent(CCStr act)
|
||||
#endif // _DEBUG
|
||||
{
|
||||
// Grab the error number and message
|
||||
mErrNo = mysql_errno(mPtr);
|
||||
mErrStr.assign(mysql_error(mPtr));
|
||||
// Throw the exception with the resulted message
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
throw Sqrat::Exception(FmtStr("%s (%u) : %s =>[%s:%d]", act,
|
||||
mErrNo, mErrStr.c_str(), file, line));
|
||||
#else
|
||||
throw Sqrat::Exception(FmtStr("%s (%u) : %s", act,
|
||||
mErrNo, mErrStr.c_str()));
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ConnHnd::Handle::Handle(const Account & acc)
|
||||
: mPtr(mysql_init(NULL))
|
||||
, mRef(0)
|
||||
, mErrNo(0)
|
||||
, mErrStr(_SC(""))
|
||||
, mPort(acc.GetPortNum())
|
||||
, mHost(acc.GetHost())
|
||||
, mUser(acc.GetUser())
|
||||
, mPass(acc.GetPass())
|
||||
, mName(acc.GetName())
|
||||
, mSocket(acc.GetSocket())
|
||||
, mFlags(acc.GetFlags())
|
||||
, mSSL_Key(acc.GetSSL_Key())
|
||||
, mSSL_Cert(acc.GetSSL_Cert())
|
||||
, mSSL_CA(acc.GetSSL_CA())
|
||||
, mSSL_CA_Path(acc.GetSSL_CA_Path())
|
||||
, mSSL_Cipher(acc.GetSSL_Cipher())
|
||||
, mCharset()
|
||||
, mQueue()
|
||||
, mAutoCommit(acc.GetAutoCommit())
|
||||
, mInTransaction(false)
|
||||
{
|
||||
// See if a connection handle could be initialized
|
||||
if (!mPtr)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Cannot create MYSQL object");
|
||||
}
|
||||
// Attempt to configure SSL if specified
|
||||
else if (!mSSL_Key.empty() && mysql_ssl_set(mPtr, mSSL_Key.c_str(), mSSL_Cert.c_str(), mSSL_CA.c_str(),
|
||||
mSSL_CA_Path.c_str(), mSSL_Cipher.c_str()) != 0)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Cannot configure SSL");
|
||||
}
|
||||
// Attempt to connect to the specified server
|
||||
else if (!mysql_real_connect(mPtr, mHost.c_str(), mUser.c_str(), mPass.c_str(),
|
||||
mName.empty() ? nullptr : mName.c_str(), mPort,
|
||||
mSocket.empty() ? nullptr : mSocket.c_str(), mFlags))
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Cannot connect to database");
|
||||
}
|
||||
// Attempt configure the auto-commit option
|
||||
else if (mysql_autocommit(mPtr, mAutoCommit) != 0)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Cannot configure auto-commit");
|
||||
}
|
||||
// Get iterators to the options container
|
||||
Account::Options::const_iterator itr = acc.GetOptions().cbegin();
|
||||
Account::Options::const_iterator end = acc.GetOptions().cend();
|
||||
// Process each option in the container
|
||||
for (String sql(128, 0); itr != end; ++itr)
|
||||
{
|
||||
// Prepare the SQL query that applies the option
|
||||
sql.assign("SET OPTION ");
|
||||
sql.append(itr->first);
|
||||
sql.append("=");
|
||||
sql.append(itr->second);
|
||||
// Execute the resulted query
|
||||
if (Execute(sql.c_str(), static_cast< Ulong >(sql.size())) != 1)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Unable to apply option");
|
||||
}
|
||||
}
|
||||
MY_CHARSET_INFO charsetinfo;
|
||||
// Grab the information about the current character set
|
||||
mysql_get_character_set_info(mPtr, &charsetinfo);
|
||||
// We only need the character set name
|
||||
if (charsetinfo.name != nullptr)
|
||||
{
|
||||
mCharset.assign(charsetinfo.name);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ConnHnd::Handle::~Handle()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConnHnd::Handle::Disconnect()
|
||||
{
|
||||
if (mPtr != nullptr)
|
||||
{
|
||||
mysql_close(mPtr);
|
||||
// mysql_init() called mysql_thread_init() therefore it needs to clear memory
|
||||
// when the MYSQL handle is closed
|
||||
mysql_thread_end();
|
||||
// Prevent further use of this handle
|
||||
mPtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 ConnHnd::Handle::Flush(Uint32 /*num*/, Object & /*env*/, Function & /*func*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Ulong ConnHnd::Handle::Execute(CSStr query, Ulong size)
|
||||
{
|
||||
// Make sure that we are connected
|
||||
if (!mPtr)
|
||||
{
|
||||
STHROWF("Invalid MySQL connection");
|
||||
}
|
||||
// Make sure the specified query is valid
|
||||
else if (!query || *query == '\0')
|
||||
{
|
||||
STHROWF("Invalid or empty MySQL query");
|
||||
}
|
||||
// Are we supposed to compute the size?
|
||||
else if (!size)
|
||||
{
|
||||
size = std::strlen(query);
|
||||
}
|
||||
// Attempt to execute the specified query
|
||||
else if (mysql_real_query(mPtr, query, size) != 0)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Unable to execute query");
|
||||
}
|
||||
// Where the number of affected rows will be stored
|
||||
Ulong affected = 0UL;
|
||||
// Count the number of affected rows by any "upsert" statement
|
||||
while (true)
|
||||
{
|
||||
// Attempt to retrieve a buffered result set from the executed query
|
||||
ResType * result = mysql_store_result(mPtr);
|
||||
// If we have a result, then this was a SELECT statement and we should not count it
|
||||
// because it returns the number of selected rows and not modified/affected
|
||||
if (result)
|
||||
{
|
||||
// Just, free the memory associated with the obtained result set
|
||||
mysql_free_result(result);
|
||||
}
|
||||
// Non SELCT queries should have a field count of 0
|
||||
else if (mysql_field_count(mPtr) == 0)
|
||||
{
|
||||
// Sum the number of affected rows by this statement
|
||||
affected += mysql_affected_rows(mPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Unable to count affected rows");
|
||||
}
|
||||
// Prepare the next result from the executed query
|
||||
// If return code is 0 then we have a result ready to process
|
||||
const Int32 status = mysql_next_result(mPtr);
|
||||
// If return code is higher than 0 then an error occurred
|
||||
if (status > 0)
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Unable to prepare next result");
|
||||
}
|
||||
// If return code is less than 0 then there are no results left
|
||||
else if (status < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Return the number of affected rows
|
||||
return affected;
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
387
modules/mysql/Handle/Connection.hpp
Normal file
387
modules/mysql/Handle/Connection.hpp
Normal file
@ -0,0 +1,387 @@
|
||||
#ifndef _SQMYSQL_HANDLE_CONNECTION_HPP_
|
||||
#define _SQMYSQL_HANDLE_CONNECTION_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <vector>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted database connection handle.
|
||||
*/
|
||||
class ConnHnd
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Connection;
|
||||
friend class Statement;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_RES ResType; // Database result type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the connection handle and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::vector< String > QueryList; // Container used to queue queries.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain connection.
|
||||
*/
|
||||
struct Handle
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Pointer mPtr; // The connection handle resource.
|
||||
Counter mRef; // Reference count to the managed handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Uint32 mErrNo; // Last received error string.
|
||||
String mErrStr; // Last received error message.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Uint16 mPort; // Server port.
|
||||
String mHost; // Host address.
|
||||
String mUser; // User name user.
|
||||
String mPass; // User password.
|
||||
String mName; // Database name.
|
||||
String mSocket; // Unix socket.
|
||||
Ulong mFlags; // Client flags.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
String mSSL_Key; // SSL key.
|
||||
String mSSL_Cert; // SSL certificate.
|
||||
String mSSL_CA; // SSL certificate authority.
|
||||
String mSSL_CA_Path; // SSL certificate authority path.
|
||||
String mSSL_Cipher; // SSL Cipher.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
String mCharset; // Default connection character set.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
QueryList mQueue; // A queue of queries to be executed in groups.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
bool mAutoCommit; // Whether autocommit is enabled on this connection.
|
||||
bool mInTransaction; // Whether the connection is in the middle of a transaction.
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Handle(const Account & acc);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Handle();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Grab the current error in the connection handle and throw it.
|
||||
*/
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
void ThrowCurrent(CCStr act, CCStr file, Int32 line);
|
||||
#else
|
||||
void ThrowCurrent(CCStr act);
|
||||
#endif // _DEBUG
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Disconnect the managed connection handle.
|
||||
*/
|
||||
void Disconnect();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Execute a specific amount of queries from the queue.
|
||||
*/
|
||||
Int32 Flush(Uint32 num, Object & env, Function & func);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Execute a query on the server.
|
||||
*/
|
||||
Ulong Execute(CSStr query, Ulong size = 0UL);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Handle * m_Hnd; // The managed handle instance.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a connection handle.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
++(m_Hnd->mRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a connection handle.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Hnd && --(m_Hnd->mRef) == 0)
|
||||
{
|
||||
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
ConnHnd(const Account & acc)
|
||||
: m_Hnd(new Handle(acc))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
ConnHnd()
|
||||
: m_Hnd(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
ConnHnd(const ConnHnd & o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
ConnHnd(ConnHnd && o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~ConnHnd()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (const ConnHnd & o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
Drop();
|
||||
m_Hnd = o.m_Hnd;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (ConnHnd && o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
m_Hnd = o.m_Hnd;
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Status assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (Uint32 status)
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
m_Hnd->mErrNo = status;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two connection handles.
|
||||
*/
|
||||
bool operator == (const ConnHnd & o) const
|
||||
{
|
||||
return (m_Hnd == o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two connection handles.
|
||||
*/
|
||||
bool operator != (const ConnHnd & o) const
|
||||
{
|
||||
return (m_Hnd != o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison with an integer value status.
|
||||
*/
|
||||
bool operator == (Uint32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo == status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison with an integer value status.
|
||||
*/
|
||||
bool operator != (Uint32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo != status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return (m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer () const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Handle * operator -> () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Handle & operator * () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr()
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr() const
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mRef : 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
Handle & GetHnd()
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
const Handle & GetHnd() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_HANDLE_CONNECTION_HPP_
|
240
modules/mysql/Handle/Result.cpp
Normal file
240
modules/mysql/Handle/Result.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Result.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ResHnd::Validate() const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||
{
|
||||
STHROWF("Invalid MySQL query result reference");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ResHnd::ValidateIndex(Uint32 idx) const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||
{
|
||||
STHROWF("Invalid MySQL query result reference");
|
||||
}
|
||||
else if (idx >= m_Hnd->mFieldCount)
|
||||
{
|
||||
STHROWF("The specified index is out of range: %u >= %u", idx, m_Hnd->mFieldCount);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ResHnd::Bind::SetOutput(const FieldType & field, BindType * bind)
|
||||
{
|
||||
// Associate the library bind point with our bind wrapper
|
||||
mBind = bind;
|
||||
// Assign the 64 bit unsigned integer as the default buffer
|
||||
mBind->buffer = &mUint64;
|
||||
// Match the bind point type to the one from the field
|
||||
mBind->buffer_type = field.type;
|
||||
// Default to n empty buffer until type identification
|
||||
mBind->buffer_length = 0;
|
||||
// Allow the library to specify whether the value is null
|
||||
mBind->is_null = &mIsNull;
|
||||
// Allow the library to specify if errors occurred
|
||||
mBind->error = &mError;
|
||||
// Tell the library where to read the buffer size
|
||||
mBind->length = &(mBind->buffer_length);
|
||||
// Identify and configure the field type
|
||||
switch (field.type)
|
||||
{
|
||||
case MYSQL_TYPE_NULL:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_BIT:
|
||||
{
|
||||
mBind->buffer_length = 1;
|
||||
} break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int16);
|
||||
} break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int32);
|
||||
} break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int64);
|
||||
} break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Float32);
|
||||
} break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Float64);
|
||||
} break;
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
{
|
||||
mBind->buffer = &mTime;
|
||||
} break;
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
{
|
||||
// Allocate a buffer to match the field size
|
||||
mData.Adjust(field.max_length);
|
||||
// Assign the buffer as the new bind point buffer
|
||||
mBind->buffer = mData.Data();
|
||||
// Assign the buffer size as the new bind point size
|
||||
mBind->buffer_length = mData.Capacity();
|
||||
} break;
|
||||
default: STHROWF("Unknown MySQL field type");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ResHnd::Handle::Handle(const ConnHnd & conn)
|
||||
: mPtr(mysql_store_result(conn))
|
||||
, mRef(1)
|
||||
, mFieldCount(0)
|
||||
, mLengths(nullptr)
|
||||
, mFields(nullptr)
|
||||
, mBinds(nullptr)
|
||||
, mMyBinds(nullptr)
|
||||
, mRow(nullptr)
|
||||
, mStatement()
|
||||
, mIndexes()
|
||||
{
|
||||
// Did this query return any results?
|
||||
if (!mPtr)
|
||||
{
|
||||
return; // We're done here!
|
||||
}
|
||||
// Obtain the number of fields in the result set
|
||||
mFieldCount = mysql_num_fields(mPtr);
|
||||
// Obtain an array representing the fields in the result set
|
||||
mFields = mysql_fetch_fields(mPtr);
|
||||
// Associate the field names with their index
|
||||
for (Uint32 i = 0; i < mFieldCount; ++i)
|
||||
{
|
||||
mIndexes[mFields[i].name] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ResHnd::Handle::Handle(const StmtHnd & stmt)
|
||||
: mPtr(nullptr)
|
||||
, mRef(1)
|
||||
, mFieldCount(0)
|
||||
, mLengths(nullptr)
|
||||
, mFields(nullptr)
|
||||
, mBinds(nullptr)
|
||||
, mMyBinds(nullptr)
|
||||
, mRow(nullptr)
|
||||
, mStatement(stmt)
|
||||
, mIndexes()
|
||||
{
|
||||
// Validate the given statement handle
|
||||
mStatement.Validate();
|
||||
// Set the parameter value for the next operation
|
||||
int max_length = 1;
|
||||
// Force mysql_stmt_store_result() to update the meta-data MYSQL_FIELD->max_length value
|
||||
if (mysql_stmt_attr_set(mStatement, STMT_ATTR_UPDATE_MAX_LENGTH, &max_length) != 0)
|
||||
{
|
||||
THROW_CURRENT(mStatement, "Cannot apply statement attribute");
|
||||
}
|
||||
// Attempt to buffer the complete result set on the client
|
||||
if (mysql_stmt_store_result(mStatement))
|
||||
{
|
||||
THROW_CURRENT(mStatement, "Cannot buffer result-set");
|
||||
}
|
||||
// Obtain the number of fields in the result set
|
||||
mFieldCount = mysql_stmt_field_count(mStatement);
|
||||
// Obtain the result set meta-data
|
||||
mPtr = mysql_stmt_result_metadata(mStatement);
|
||||
// Obtain an array representing the fields in the result set
|
||||
mFields = mysql_fetch_fields(mPtr);
|
||||
// Are there any fields to allocate
|
||||
if (mFieldCount > 0)
|
||||
{
|
||||
// Allocate the bind wrappers
|
||||
mBinds = new Bind[mFieldCount];
|
||||
// Allocate the bind points
|
||||
mMyBinds = new BindType[mFieldCount];
|
||||
// Allocate the row pointers
|
||||
mRow = new CStr[mFieldCount];
|
||||
// Initialize the bind points to null
|
||||
std::memset(mMyBinds, 0, sizeof(BindType) * mFieldCount);
|
||||
}
|
||||
// Configure bind points and make associations
|
||||
for (Uint32 i = 0; i < mFieldCount; ++i)
|
||||
{
|
||||
// Associate the current field name with the current index
|
||||
mIndexes[mFields[i].name] = i;
|
||||
// Configure the current bind point according to the associated field
|
||||
mBinds[i].SetOutput(mFields[i], &mMyBinds[i]);
|
||||
// Store the bind point buffer into the associated row
|
||||
mRow[i] = mBinds[i].GetBuffer();
|
||||
}
|
||||
// Associate our bind points with the statement for result storage
|
||||
if (mFieldCount > 0 && mysql_stmt_bind_result(mStatement, mMyBinds) != 0)
|
||||
{
|
||||
THROW_CURRENT(mStatement, "Cannot bind variables to statement");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ResHnd::Handle::~Handle()
|
||||
{
|
||||
// Is there a result set that we should free?
|
||||
if (mPtr)
|
||||
{
|
||||
mysql_free_result(mPtr);
|
||||
}
|
||||
// Are there any bind points that we should free?
|
||||
if (mMyBinds)
|
||||
{
|
||||
delete [] mMyBinds;
|
||||
}
|
||||
// Was this result set from a statement?
|
||||
if (mStatement)
|
||||
{
|
||||
// Are there any rows pointers we should free?
|
||||
if (mRow)
|
||||
{
|
||||
delete [] mRow;
|
||||
}
|
||||
// Free the result set in the statement
|
||||
mysql_stmt_free_result(mStatement);
|
||||
}
|
||||
// Are there any bind wrappers that we should free?
|
||||
if (mBinds)
|
||||
{
|
||||
delete [] mBinds;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
409
modules/mysql/Handle/Result.hpp
Normal file
409
modules/mysql/Handle/Result.hpp
Normal file
@ -0,0 +1,409 @@
|
||||
#ifndef _SQMYSQL_HANDLE_RESULT_HPP_
|
||||
#define _SQMYSQL_HANDLE_RESULT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Statement.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <Base/Buffer.hpp>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <unordered_map>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted result set handle.
|
||||
*/
|
||||
class ResHnd
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Connection;
|
||||
friend class Statement;
|
||||
friend class ResultSet;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_RES Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_FIELD FieldType; // Database field type.
|
||||
typedef MYSQL_BIND BindType; // Database bind type.
|
||||
typedef MYSQL_TIME TimeType; // Database time type.
|
||||
typedef MYSQL_ROW RowType; // Database row type.
|
||||
typedef my_bool BoolType; // Database boolean type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the result set handle and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the result set handle and specified index and throw an error if invalid.
|
||||
*/
|
||||
void ValidateIndex(Uint32 idx) const;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::unordered_map< String, Uint32 > IndexMap;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain bind point.
|
||||
*/
|
||||
struct Bind
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
BoolType mIsNull; // Allows the database to specify if the field is null.
|
||||
BoolType mError; // Allows the database if errors occured on this field.
|
||||
Buffer mData; // Buffer to store non fundamental data for the field.
|
||||
BindType * mBind; // The associated database bind point handle.
|
||||
TimeType mTime; // Structure used to retrieve time data from database.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
union
|
||||
{
|
||||
Uint64 mUint64; // Retrieve unsigned integer values from a field.
|
||||
Int64 mInt64; // Retrieve signed integer values from a field.
|
||||
Int32 mInt32[2]; // Retrieve 32 bit signed integer values from a field.
|
||||
Float64 mFloat64; // Retrieve 32 bit floating point values from a field.
|
||||
Float32 mFloat32[2]; // Retrieve 64 bit floating point values from the field.
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Bind()
|
||||
: mIsNull(0), mError(0), mData(), mBind(nullptr), mTime(), mUint64(0)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
Bind(const Bind & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
Bind(Bind && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
Bind & operator = (const Bind & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
Bind & operator = (Bind && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the used buffer.
|
||||
*/
|
||||
CStr GetBuffer()
|
||||
{
|
||||
return mData ? mData.Data() : reinterpret_cast< CStr >(&mUint64);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the buffer length.
|
||||
*/
|
||||
Ulong GetLength() const
|
||||
{
|
||||
return mBind == nullptr ? 0 : mBind->buffer_length;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Configure the output to match the requirements of a certain field.
|
||||
*/
|
||||
void SetOutput(const FieldType & field, BindType * bind);
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain result set handle.
|
||||
*/
|
||||
struct Handle
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Pointer mPtr; // The managed result set handle.
|
||||
Counter mRef; // Reference count to the managed handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Uint32 mFieldCount; // Number of fields in the result set.
|
||||
Ulong * mLengths; // Data length when the result set came from a connection.
|
||||
FieldType * mFields; // Fields in the results set.
|
||||
Bind * mBinds; // Bind wrappers.
|
||||
BindType * mMyBinds; // Bind points.
|
||||
RowType mRow; // Row data.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
StmtHnd mStatement; // Associated statement.
|
||||
IndexMap mIndexes; // Field names and their associated index.
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Connection constructor.
|
||||
*/
|
||||
Handle(const ConnHnd & conn);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Statement constructor.
|
||||
*/
|
||||
Handle(const StmtHnd & stmt);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Handle();
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Handle * m_Hnd; // The managed handle instance.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a result set handle.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
++(m_Hnd->mRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a result set handle.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Hnd && --(m_Hnd->mRef) == 0)
|
||||
{
|
||||
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Connection constructor.
|
||||
*/
|
||||
ResHnd(const ConnHnd & conn)
|
||||
: m_Hnd(conn ? new Handle(conn) : nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Connection constructor.
|
||||
*/
|
||||
ResHnd(const StmtHnd & stmt)
|
||||
: m_Hnd(stmt ? new Handle(stmt) : nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
ResHnd()
|
||||
: m_Hnd(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
ResHnd(const ResHnd & o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
ResHnd(ResHnd && o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~ResHnd()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
ResHnd & operator = (const ResHnd & o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
Drop();
|
||||
m_Hnd = o.m_Hnd;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
ResHnd & operator = (ResHnd && o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
m_Hnd = o.m_Hnd;
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two result set handles.
|
||||
*/
|
||||
bool operator == (const ResHnd & o) const
|
||||
{
|
||||
return (m_Hnd == o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two result set handles.
|
||||
*/
|
||||
bool operator != (const ResHnd & o) const
|
||||
{
|
||||
return (m_Hnd != o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return (m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer () const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Handle * operator -> () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Handle & operator * () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr()
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr() const
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mRef : 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
Handle & GetHnd()
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
const Handle & GetHnd() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_HANDLE_RESULT_HPP_
|
198
modules/mysql/Handle/Statement.cpp
Normal file
198
modules/mysql/Handle/Statement.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Statement.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void StmtHnd::Validate() const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||
{
|
||||
STHROWF("Invalid MySQL statement reference");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void StmtHnd::ValidateIndex(Uint32 idx) const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||
{
|
||||
STHROWF("Invalid MySQL statement reference");
|
||||
}
|
||||
else if (idx >= m_Hnd->mParams)
|
||||
{
|
||||
STHROWF("Parameter index is out of range: %u >= %lu", idx, m_Hnd->mParams);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
void StmtHnd::Handle::ThrowCurrent(CCStr act, CCStr file, Int32 line)
|
||||
#else
|
||||
void StmtHnd::Handle::ThrowCurrent(CCStr act)
|
||||
#endif // _DEBUG
|
||||
{
|
||||
// Grab the error number and message
|
||||
mErrNo = mysql_stmt_errno(mPtr);
|
||||
mErrStr.assign(mysql_stmt_error(mPtr));
|
||||
// Throw the exception with the resulted message
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
throw Sqrat::Exception(FmtStr("%s (%u) : %s =>[%s:%d]", act,
|
||||
mErrNo, mErrStr.c_str(), file, line));
|
||||
#else
|
||||
throw Sqrat::Exception(FmtStr("%s (%u) : %s", act,
|
||||
mErrNo, mErrStr.c_str()));
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void StmtHnd::Bind::SetInput(enum_field_types type, BindType * bind, CCStr buffer, Ulong length)
|
||||
{
|
||||
// Associate the library bind point with our bind wrapper
|
||||
mBind = bind;
|
||||
// Assign the 64 bit unsigned integer as the default buffer
|
||||
mBind->buffer = &mUint64;
|
||||
// Match the bind point type to the one from the field
|
||||
mBind->buffer_type = type;
|
||||
// Default to n empty buffer until type identification
|
||||
mBind->buffer_length = 0;
|
||||
// Allow the library to specify whether the value is null
|
||||
mBind->is_null = &mIsNull;
|
||||
// Allow the library to specify if errors occurred
|
||||
mBind->error = &mError;
|
||||
// Tell the library where to read the buffer size
|
||||
mBind->length = &(mBind->buffer_length);
|
||||
// Identify and configure the parameter type
|
||||
switch (type)
|
||||
{
|
||||
case MYSQL_TYPE_NULL:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_BIT:
|
||||
{
|
||||
mBind->buffer_length = 1;
|
||||
} break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int16);
|
||||
} break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int32);
|
||||
} break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Int64);
|
||||
} break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Float32);
|
||||
} break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
{
|
||||
mBind->buffer_length = sizeof(Float64);
|
||||
} break;
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
{
|
||||
mBind->buffer = &mTime;
|
||||
} break;
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
{
|
||||
// Allocate a buffer to match the specified size
|
||||
mData.Adjust(length);
|
||||
// Should we copy anything into the buffer?
|
||||
if (buffer)
|
||||
{
|
||||
mData.Append(buffer, length);
|
||||
}
|
||||
// Assign the buffer as the new bind point buffer
|
||||
mBind->buffer = mData.Data();
|
||||
// Assign the buffer cursor position as the new bind point size
|
||||
mBind->buffer_length = mData.Position();
|
||||
} break;
|
||||
default: STHROWF("Unknown MySQL parameter type");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StmtHnd::Handle::Handle(const ConnHnd & conn, CSStr query)
|
||||
: mPtr(mysql_stmt_init(conn))
|
||||
, mRef(1)
|
||||
, mErrNo(0)
|
||||
, mParams(0)
|
||||
, mBinds(nullptr)
|
||||
, mMyBinds(nullptr)
|
||||
, mConnection(conn)
|
||||
, mQuery(query ? query : _SC(""))
|
||||
{
|
||||
// Validate the obtained statement handle
|
||||
if (!mPtr)
|
||||
{
|
||||
THROW_CURRENT(mConnection, "Cannot initialize statement");
|
||||
}
|
||||
// Attempt to prepare the statement
|
||||
else if (mysql_stmt_prepare(mPtr, mQuery.c_str(), mQuery.size()))
|
||||
{
|
||||
THROW_CURRENT_HND((*this), "Cannot prepare statement");
|
||||
}
|
||||
// Retrieve the amount of parameters supported by this statement
|
||||
mParams = mysql_stmt_param_count(mPtr);
|
||||
// Are there any parameters to allocate?
|
||||
if (mParams <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Allocate the necessary structures
|
||||
mBinds = new Bind[mParams];
|
||||
mMyBinds = new BindType[mParams];
|
||||
// Reset the allocated structures
|
||||
std::memset(mBinds, 0, sizeof(Bind) * mParams);
|
||||
std::memset(mMyBinds, 0, sizeof(BindType) * mParams);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StmtHnd::Handle::~Handle()
|
||||
{
|
||||
// Should delete native bindings?
|
||||
if (mMyBinds)
|
||||
{
|
||||
delete [] mMyBinds;
|
||||
}
|
||||
// Should we delete binding wrappers?
|
||||
if (mBinds)
|
||||
{
|
||||
delete [] mBinds;
|
||||
}
|
||||
// Should we release any statement?
|
||||
if (mPtr)
|
||||
{
|
||||
mysql_stmt_close(mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
441
modules/mysql/Handle/Statement.hpp
Normal file
441
modules/mysql/Handle/Statement.hpp
Normal file
@ -0,0 +1,441 @@
|
||||
#ifndef _SQMYSQL_HANDLE_STATEMENT_HPP_
|
||||
#define _SQMYSQL_HANDLE_STATEMENT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Connection.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <Base/Buffer.hpp>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted statement handle.
|
||||
*/
|
||||
class StmtHnd
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Connection;
|
||||
friend class Statement;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_STMT Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_BIND BindType; // Database bind type.
|
||||
typedef MYSQL_TIME TimeType; // Database time type.
|
||||
typedef my_bool BoolType; // Database boolean type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the statement handle and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the statement handle and parameter index and throw an error if invalid.
|
||||
*/
|
||||
void ValidateIndex(Uint32 idx) const;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::map< String, int > Indexes; // Container used to identify column indexes.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain bind point.
|
||||
*/
|
||||
struct Bind
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
BoolType mIsNull; // Allows the database to specify if the parameter is null.
|
||||
BoolType mError; // Allows the database if errors occured on this parameter.
|
||||
Buffer mData; // Buffer to store non fundamental data for the parameter.
|
||||
BindType * mBind; // The associated database bind point handle.
|
||||
TimeType mTime; // Structure used to store time data from database.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
union
|
||||
{
|
||||
Uint64 mUint64; // Store unsigned integer values for the parameter.
|
||||
Int64 mInt64; // Store signed integer values for the parameter.
|
||||
Int32 mInt32[2]; // Store 32 bit signed integer values for the parameter.
|
||||
Float64 mFloat64; // Store 32 bit floating point values for the parameter.
|
||||
Float32 mFloat32[2]; // Store 64 bit floating point values for the parameter.
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Bind()
|
||||
: mIsNull(0), mError(0), mData(), mBind(nullptr), mTime(), mUint64(0)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
Bind(const Bind & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
Bind(Bind && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
Bind & operator = (const Bind & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
Bind & operator = (Bind && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the used buffer.
|
||||
*/
|
||||
CStr GetBuffer()
|
||||
{
|
||||
return mData ? mData.Data() : reinterpret_cast< CStr >(&mUint64);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the buffer length.
|
||||
*/
|
||||
Ulong GetLength() const
|
||||
{
|
||||
return mBind == nullptr ? 0 : mBind->buffer_length;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Configure the input of a certain statement parameter.
|
||||
*/
|
||||
void SetInput(enum_field_types type, BindType * bind, CCStr buffer = nullptr, Ulong length = 0UL);
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain statement handle.
|
||||
*/
|
||||
struct Handle
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Pointer mPtr; // The managed statement handle.
|
||||
Counter mRef; // Reference count to the managed handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Uint32 mErrNo; // Last received error string.
|
||||
String mErrStr; // Last received error message.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Ulong mParams; // Number of parameters in the statement.
|
||||
Bind * mBinds; // List of parameter binds.
|
||||
BindType * mMyBinds; // List of parameter binds.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
ConnHnd mConnection; // Reference to the associated connection.
|
||||
String mQuery; // The query string.
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Handle(const ConnHnd & conn, CSStr query);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Handle();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Grab the current error in the connection handle and throw it.
|
||||
*/
|
||||
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
||||
void ThrowCurrent(CCStr act, CCStr file, Int32 line);
|
||||
#else
|
||||
void ThrowCurrent(CCStr act);
|
||||
#endif // _DEBUG
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Create the database statement resource.
|
||||
*/
|
||||
void Create(CSStr query);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Handle * m_Hnd; // The managed handle instance.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a statement handle.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
++(m_Hnd->mRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a statement handle.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Hnd && --(m_Hnd->mRef) == 0)
|
||||
{
|
||||
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StmtHnd(const ConnHnd & db, CSStr query)
|
||||
: m_Hnd(new Handle(db, query))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
StmtHnd()
|
||||
: m_Hnd(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
StmtHnd(const StmtHnd & o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
StmtHnd(StmtHnd && o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StmtHnd()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (const StmtHnd & o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
Drop();
|
||||
m_Hnd = o.m_Hnd;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (StmtHnd && o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
m_Hnd = o.m_Hnd;
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Status assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (Uint32 status)
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
m_Hnd->mErrNo = status;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two statement handles.
|
||||
*/
|
||||
bool operator == (const StmtHnd & o) const
|
||||
{
|
||||
return (m_Hnd == o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two statement handles.
|
||||
*/
|
||||
bool operator != (const StmtHnd & o) const
|
||||
{
|
||||
return (m_Hnd != o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison with an integer value status.
|
||||
*/
|
||||
bool operator == (Uint32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo == status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison with an integer status value.
|
||||
*/
|
||||
bool operator != (Uint32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo != status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return (m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer () const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert((m_Hnd != nullptr) && (m_Hnd->mPtr != nullptr));
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Handle * operator -> () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Handle & operator * () const
|
||||
{
|
||||
assert(m_Hnd != nullptr);
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr()
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr() const
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return (m_Hnd != nullptr) ? m_Hnd->mRef : 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
Handle & GetHnd()
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the handle reference but only if valid.
|
||||
*/
|
||||
const Handle & GetHnd() const
|
||||
{
|
||||
// Validate the managed handle
|
||||
Validate();
|
||||
// Return the requesed information
|
||||
return *m_Hnd;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_HANDLE_STATEMENT_HPP_
|
@ -1,25 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handles.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ConnHnd::Handle::~Handle()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConnHnd::Handle::Create(CSStr host, CSStr user, CSStr pass, CSStr schema, Uint16 port, CSStr socket)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,691 +0,0 @@
|
||||
#ifndef _SQMYSQL_HANDLES_HPP_
|
||||
#define _SQMYSQL_HANDLES_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <mysql.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Forward declarations.
|
||||
*/
|
||||
class Connection;
|
||||
class Statement;
|
||||
class Column;
|
||||
class Transaction;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted database connection handle.
|
||||
*/
|
||||
class ConnHnd
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Connection;
|
||||
friend class Statement;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::vector< String > QueryList; // Container used to queue queries.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain connection.
|
||||
*/
|
||||
struct Handle
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Pointer mPtr; // The connection handle resource.
|
||||
Counter mRef; // Reference count to the managed handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Uint32 mErrNo; // Last received error string.
|
||||
String mErrStr; // Last received error message.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String mHost; // Host address.
|
||||
String mUser; // User name user.
|
||||
String mPass; // User password.
|
||||
Uint16 mPort; // Server port.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String mSchema; // Server schema.
|
||||
String mSocket; // Unix socket.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String mSSL_Key; // SSL key.
|
||||
String mSSL_Cert; // SSL certificate.
|
||||
String mSSL_CA; // SSL certificate authority.
|
||||
String mSSL_CA_Path; // SSL certificate authority path.
|
||||
String mSSL_Cipher; // SSL Cipher.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Options mOptions; // Option container.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
QueryList mQueue; // A queue of queries to be executed in groups.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool mAutocommit; // Whether autocommit is enabled on this connection.
|
||||
bool mInTransaction; // Whether the connection is in the middle of a transaction.
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Handle(Counter counter)
|
||||
: mPtr(nullptr)
|
||||
, mRef(counter)
|
||||
, mErrNo(0)
|
||||
, mErrStr(_SC(""))
|
||||
, mHost(_SC(""))
|
||||
, mUser(_SC(""))
|
||||
, mPass(_SC(""))
|
||||
, mPort(3306)
|
||||
, mSchema(_SC(""))
|
||||
, mSocket(_SC(""))
|
||||
, mSSL_Key(_SC(""))
|
||||
, mSSL_Cert(_SC(""))
|
||||
, mSSL_CA(_SC(""))
|
||||
, mSSL_CA_Path(_SC(""))
|
||||
, mSSL_Cipher(_SC(""))
|
||||
, mOptions(_SC(""))
|
||||
, mQueue()
|
||||
, mAutocommit(false)
|
||||
, mInTransaction(false)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Handle();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Create the database connection resource.
|
||||
*/
|
||||
void Create(CSStr host, CSStr user, CSStr pass, CSStr schema, Uint16 port, CSStr socket);
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Execute a specific amount of queries from the queue.
|
||||
*/
|
||||
Int32 Flush(Uint32 num, Object & env, Function & func);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Handle* m_Hnd;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a connection handle.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
++(m_Hnd->mRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a connection handle.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Hnd && --(m_Hnd->mRef) == 0)
|
||||
{
|
||||
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
ConnHnd(CSStr name)
|
||||
: m_Hnd(name ? new Handle(1) : nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
ConnHnd()
|
||||
: m_Hnd(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
ConnHnd(const ConnHnd & o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
ConnHnd(ConnHnd && o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~ConnHnd()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (const ConnHnd & o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
Drop();
|
||||
m_Hnd = o.m_Hnd;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (ConnHnd && o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
m_Hnd = o.m_Hnd;
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Status assignment operator.
|
||||
*/
|
||||
ConnHnd & operator = (Int32 status)
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
m_Hnd->mErrNo = status;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two connection handles.
|
||||
*/
|
||||
bool operator == (const ConnHnd & o) const
|
||||
{
|
||||
return (m_Hnd == o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two connection handles.
|
||||
*/
|
||||
bool operator != (const ConnHnd & o) const
|
||||
{
|
||||
return (m_Hnd != o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison with an integer value status.
|
||||
*/
|
||||
bool operator == (Int32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo == status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison with an integer value status.
|
||||
*/
|
||||
bool operator != (Int32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo != status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return m_Hnd && m_Hnd->mPtr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer () const
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert(m_Hnd && m_Hnd->mPtr);
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert(m_Hnd && m_Hnd->mPtr);
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Handle * operator -> () const
|
||||
{
|
||||
assert(m_Hnd);
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Handle & operator * () const
|
||||
{
|
||||
assert(m_Hnd);
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr()
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr() const
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mRef : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted database statement handle.
|
||||
*/
|
||||
class StmtHnd
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Connection;
|
||||
friend class Statement;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_STMT Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MYSQL_BIND BindType; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef BindType* BindPointer; // Pointer to the managed type.
|
||||
typedef const BindType* BindConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef BindType& BindReference; // Reference to the managed type.
|
||||
typedef const BindType& BindConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::map< String, int > Indexes; // Container used to identify column indexes.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The structure that holds the data associated with a certain statement.
|
||||
*/
|
||||
struct Handle
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Pointer mPtr; // The statement handle resource.
|
||||
Counter mRef; // Reference count to the managed handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mErrNo; // The last status code of this connection handle.
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
MYSQL_BIND* mBinds;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Handle(const ConnHnd & conn, Counter counter)
|
||||
: mPtr(nullptr)
|
||||
, mRef(counter)
|
||||
, mErrNo(0)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Handle();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create the database statement resource.
|
||||
*/
|
||||
void Create(CSStr query);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Handle* m_Hnd;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a statement handle.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
++(m_Hnd->mRef);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a statement handle.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Hnd && --(m_Hnd->mRef) == 0)
|
||||
{
|
||||
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StmtHnd(const ConnHnd & db)
|
||||
: m_Hnd(new Handle(db, 1))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
StmtHnd()
|
||||
: m_Hnd(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
StmtHnd(const StmtHnd & o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
StmtHnd(StmtHnd && o)
|
||||
: m_Hnd(o.m_Hnd)
|
||||
{
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StmtHnd()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (const StmtHnd & o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
Drop();
|
||||
m_Hnd = o.m_Hnd;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (StmtHnd && o)
|
||||
{
|
||||
if (m_Hnd != o.m_Hnd)
|
||||
{
|
||||
m_Hnd = o.m_Hnd;
|
||||
o.m_Hnd = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Status assignment operator.
|
||||
*/
|
||||
StmtHnd & operator = (Int32 status)
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
m_Hnd->mErrNo = status;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two statement handles.
|
||||
*/
|
||||
bool operator == (const StmtHnd & o) const
|
||||
{
|
||||
return (m_Hnd == o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two statement handles.
|
||||
*/
|
||||
bool operator != (const StmtHnd & o) const
|
||||
{
|
||||
return (m_Hnd != o.m_Hnd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison with an integer value status.
|
||||
*/
|
||||
bool operator == (Int32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo == status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison with an integer status value.
|
||||
*/
|
||||
bool operator != (Int32 status) const
|
||||
{
|
||||
if (m_Hnd)
|
||||
{
|
||||
return (m_Hnd->mErrNo != status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return m_Hnd && m_Hnd->mPtr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Pointer () const
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert(m_Hnd && m_Hnd->mPtr);
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert(m_Hnd && m_Hnd->mPtr);
|
||||
return *(m_Hnd->mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Handle * operator -> () const
|
||||
{
|
||||
assert(m_Hnd);
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Handle & operator * () const
|
||||
{
|
||||
assert(m_Hnd);
|
||||
return *m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr()
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Handle * HndPtr() const
|
||||
{
|
||||
return m_Hnd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return m_Hnd ? m_Hnd->mRef : 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_HANDLES_HPP_
|
@ -1,34 +1,22 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include "Module.hpp"
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
#include "Account.hpp"
|
||||
#include "Column.hpp"
|
||||
#include "Connection.hpp"
|
||||
#include "ResultSet.hpp"
|
||||
#include "Savepoint.hpp"
|
||||
#include "Statement.hpp"
|
||||
#include "Transaction.hpp"
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
PluginFuncs* _Func = nullptr;
|
||||
PluginCallbacks* _Clbk = nullptr;
|
||||
PluginInfo* _Info = nullptr;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HSQAPI _SqAPI = nullptr;
|
||||
HSQEXPORTS _SqMod = nullptr;
|
||||
HSQUIRRELVM _SqVM = nullptr;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Bind speciffic functions to certain server events.
|
||||
* Bind specific functions to certain server events.
|
||||
*/
|
||||
void BindCallbacks();
|
||||
|
||||
@ -37,21 +25,23 @@ void BindCallbacks();
|
||||
*/
|
||||
void UnbindCallbacks();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Register the module API under the specified virtual machine.
|
||||
*/
|
||||
void RegisterAPI(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Initialize the plugin by obtaining the API provided by the host plugin.
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Initialize the plug-in by obtaining the API provided by the host plug-in.
|
||||
*/
|
||||
void OnSquirrelInitialize()
|
||||
{
|
||||
// Attempt to import the plugin API exported by the host plugin
|
||||
// Attempt to import the plug-in API exported by the host plug-in
|
||||
_SqMod = sq_api_import(_Func);
|
||||
// Did we failed to obtain the plugin exports?
|
||||
if(!_SqMod)
|
||||
OutputError("Failed to attach [%s] on host plugin.", SQMYSQL_NAME);
|
||||
// Did we failed to obtain the plug-in exports?
|
||||
if (!_SqMod)
|
||||
{
|
||||
OutputError("Failed to attach [%s] on host plug-in.", SQMYSQL_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Obtain the Squirrel API
|
||||
@ -61,19 +51,23 @@ void OnSquirrelInitialize()
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Load the module on the virtual machine provided by the host module.
|
||||
*/
|
||||
void OnSquirrelLoad()
|
||||
{
|
||||
// Make sure that we have a valid plugin API
|
||||
// Make sure that we have a valid plug-in API
|
||||
if (!_SqMod)
|
||||
return; /* Unable to proceed. */
|
||||
{
|
||||
return; // Unable to proceed.
|
||||
}
|
||||
// Obtain the Squirrel API and VM
|
||||
_SqVM = _SqMod->GetSquirrelVM();
|
||||
// Make sure that a valid virtual machine exists
|
||||
if (!_SqVM)
|
||||
return; /* Unable to proceed. */
|
||||
{
|
||||
return; // Unable to proceed.
|
||||
}
|
||||
// Set this as the default database
|
||||
DefaultVM::Set(_SqVM);
|
||||
// Register the module API
|
||||
@ -82,27 +76,34 @@ void OnSquirrelLoad()
|
||||
OutputMessage("Registered: %s", SQMYSQL_NAME);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* The virtual machine is about to be terminated and script resources should be released.
|
||||
*/
|
||||
void OnSquirrelTerminate()
|
||||
{
|
||||
OutputMessage("Terminating: %s", SQMYSQL_NAME);
|
||||
// Release null objects just in case
|
||||
NullObject().Release();
|
||||
NullTable().Release();
|
||||
NullArray().Release();
|
||||
NullFunction().ReleaseGently();
|
||||
// Release the current virtual machine, if any
|
||||
DefaultVM::Set(nullptr);
|
||||
// Release script resources...
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Validate the module API to make sure we don't run into issues.
|
||||
*/
|
||||
bool CheckAPIVer(CCStr ver)
|
||||
{
|
||||
// Obtain the numeric representation of the API version
|
||||
long vernum = strtol(ver, nullptr, 10);
|
||||
const LongI vernum = std::strtol(ver, nullptr, 10);
|
||||
// Check against version mismatch
|
||||
if (vernum == SQMOD_API_VER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Log the incident
|
||||
OutputError("API version mismatch on %s", SQMYSQL_NAME);
|
||||
OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER);
|
||||
@ -110,8 +111,8 @@ bool CheckAPIVer(CCStr ver)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* React to command sent by other plugins.
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* React to command sent by other plug-ins.
|
||||
*/
|
||||
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
|
||||
{
|
||||
@ -119,7 +120,9 @@ static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
|
||||
{
|
||||
case SQMOD_INITIALIZE_CMD:
|
||||
if (CheckAPIVer(message))
|
||||
{
|
||||
OnSquirrelInitialize();
|
||||
}
|
||||
break;
|
||||
case SQMOD_LOAD_CMD:
|
||||
OnSquirrelLoad();
|
||||
@ -132,8 +135,8 @@ static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The server was initialized and this plugin was loaded successfully.
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* The server was initialized and this plug-in was loaded successfully.
|
||||
*/
|
||||
static uint8_t OnServerInitialise()
|
||||
{
|
||||
@ -162,125 +165,114 @@ void UnbindCallbacks()
|
||||
_Clbk->OnPluginCommand = nullptr;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void RegisterAPI(HSQUIRRELVM vm)
|
||||
{
|
||||
SQMOD_UNUSED_VAR(vm);
|
||||
}
|
||||
Table sqlns(vm);
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputMessageImpl(const char * msg, va_list args)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
sqlns.Bind(_SC("Account"), Class< Account >(vm, _SC("SqMySQLAccount"))
|
||||
// Constructors
|
||||
.Ctor< const Account & >()
|
||||
.Ctor< CSStr, CSStr >()
|
||||
.Ctor< CSStr, CSStr, CSStr >()
|
||||
.Ctor< CSStr, CSStr, CSStr, CSStr >()
|
||||
.Ctor< CSStr, CSStr, CSStr, CSStr, SQInteger >()
|
||||
.Ctor< CSStr, CSStr, CSStr, CSStr, SQInteger, CSStr >()
|
||||
// Core Meta-methods
|
||||
.Func(_SC("_cmp"), &Account::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &Account::Typename)
|
||||
.Func(_SC("_tostring"), &Account::ToString)
|
||||
// Properties
|
||||
.Prop(_SC("Port"), &Account::GetPortNum, &Account::SetPortNum)
|
||||
.Prop(_SC("Host"), &Account::GetHost, &Account::SetHost)
|
||||
.Prop(_SC("User"), &Account::GetUser, &Account::SetUser)
|
||||
.Prop(_SC("Pass"), &Account::GetPass, &Account::SetPass)
|
||||
.Prop(_SC("Socket"), &Account::GetSocket, &Account::SetSocket)
|
||||
.Prop(_SC("Flags"), &Account::GetFlags, &Account::SetFlags)
|
||||
.Prop(_SC("SSL_Key"), &Account::GetSSL_Key, &Account::SetSSL_Key)
|
||||
.Prop(_SC("SSL_Cert"), &Account::GetSSL_Cert, &Account::SetSSL_Cert)
|
||||
.Prop(_SC("SSL_CA"), &Account::GetSSL_CA, &Account::SetSSL_CA)
|
||||
.Prop(_SC("SSL_CA_Path"), &Account::GetSSL_CA_Path, &Account::SetSSL_CA_Path)
|
||||
.Prop(_SC("SSL_Cipher"), &Account::GetSSL_Cipher, &Account::SetSSL_Cipher)
|
||||
.Prop(_SC("AutoCommit"), &Account::GetAutoCommit, &Account::SetAutoCommit)
|
||||
.Prop(_SC("Options"), &Account::GetOptionsTable)
|
||||
.Prop(_SC("OptionsCount"), &Account::OptionsCount)
|
||||
.Prop(_SC("OptionsEmpty"), &Account::OptionsEmpty)
|
||||
// Member Methods
|
||||
.Func(_SC("EnableFlags"), &Account::EnableFlags)
|
||||
.Func(_SC("DisableFlags"), &Account::DisableFlags)
|
||||
.Func(_SC("SetSSL"), &Account::SetSSL)
|
||||
.Func(_SC("GetOption"), &Account::GetOption)
|
||||
.Func(_SC("SetOption"), &Account::SetOption)
|
||||
.Func(_SC("RemoveOption"), &Account::RemoveOption)
|
||||
.Func(_SC("OptionsClear"), &Account::OptionsClear)
|
||||
.Func(_SC("Connect"), &Account::Connect)
|
||||
);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csb_before;
|
||||
GetConsoleScreenBufferInfo( hstdout, &csb_before);
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
|
||||
std::printf("[SQMOD] ");
|
||||
sqlns.Bind(_SC("Connection"), Class< Connection >(vm, _SC("SqMySQLConnection"))
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< const Account & >()
|
||||
// Core Meta-methods
|
||||
.Func(_SC("_cmp"), &Connection::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &Connection::Typename)
|
||||
.Func(_SC("_tostring"), &Connection::ToString)
|
||||
// Properties
|
||||
.Prop(_SC("Connected"), &Connection::Connected)
|
||||
.Prop(_SC("LastErrNo"), &Connection::GetLastErrNo)
|
||||
.Prop(_SC("LastErrStr"), &Connection::GetLastErrStr)
|
||||
.Prop(_SC("Port"), &Connection::GetPortNum)
|
||||
.Prop(_SC("Host"), &Connection::GetHost)
|
||||
.Prop(_SC("User"), &Connection::GetUser)
|
||||
.Prop(_SC("Pass"), &Connection::GetPass)
|
||||
.Prop(_SC("Name"), &Connection::GetName, &Connection::SetName)
|
||||
.Prop(_SC("Socket"), &Connection::GetSocket)
|
||||
.Prop(_SC("Flags"), &Connection::GetFlags)
|
||||
.Prop(_SC("SSL_Key"), &Connection::GetSSL_Key)
|
||||
.Prop(_SC("SSL_Cert"), &Connection::GetSSL_Cert)
|
||||
.Prop(_SC("SSL_CA"), &Connection::GetSSL_CA)
|
||||
.Prop(_SC("SSL_CA_Path"), &Connection::GetSSL_CA_Path)
|
||||
.Prop(_SC("SSL_Cipher"), &Connection::GetSSL_Cipher)
|
||||
.Prop(_SC("Charset"), &Connection::GetCharset, &Connection::SetCharset)
|
||||
.Prop(_SC("AutoCommit"), &Connection::GetAutoCommit, &Connection::SetAutoCommit)
|
||||
.Prop(_SC("InTransaction"), &Connection::GetInTransaction)
|
||||
// Member Methods
|
||||
.Func(_SC("Disconnect"), &Connection::Disconnect)
|
||||
.Func(_SC("SelectDb"), &Connection::SetName)
|
||||
.Func(_SC("Execute"), &Connection::Execute)
|
||||
.Func(_SC("Insert"), &Connection::Insert)
|
||||
.Func(_SC("Query"), &Connection::Query)
|
||||
);
|
||||
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
std::vprintf(msg, args);
|
||||
std::puts("");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
|
||||
#else
|
||||
std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27);
|
||||
std::vprintf(msg, args);
|
||||
std::puts("");
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputErrorImpl(const char * msg, va_list args)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csb_before;
|
||||
GetConsoleScreenBufferInfo( hstdout, &csb_before);
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
std::printf("[SQMOD] ");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
std::vprintf(msg, args);
|
||||
std::puts("");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
|
||||
#else
|
||||
std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27);
|
||||
std::vprintf(msg, args);
|
||||
std::puts("");
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputDebug(const char * msg, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputMessageImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
#else
|
||||
SQMOD_UNUSED_VAR(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputMessage(const char * msg, ...)
|
||||
{
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputMessageImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputError(const char * msg, ...)
|
||||
{
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputErrorImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
|
||||
{
|
||||
using namespace SqMod;
|
||||
// Output plugin header
|
||||
puts("");
|
||||
// Output plug-in header
|
||||
std::puts("");
|
||||
OutputMessage("--------------------------------------------------------------------");
|
||||
OutputMessage("Plugin: %s", SQMYSQL_NAME);
|
||||
OutputMessage("Plug-in: %s", SQMYSQL_NAME);
|
||||
OutputMessage("Author: %s", SQMYSQL_AUTHOR);
|
||||
OutputMessage("Legal: %s", SQMYSQL_COPYRIGHT);
|
||||
OutputMessage("--------------------------------------------------------------------");
|
||||
puts("");
|
||||
// Attempt to find the host plugin ID
|
||||
int host_plugin_id = functions->FindPlugin((char *)(SQMOD_HOST_NAME));
|
||||
// See if our plugin was loaded after the host plugin
|
||||
std::puts("");
|
||||
// Attempt to find the host plug-in ID
|
||||
const int host_plugin_id = functions->FindPlugin(SQMOD_HOST_NAME);
|
||||
// See if our plug-in was loaded after the host plug-in
|
||||
if (host_plugin_id < 0)
|
||||
{
|
||||
OutputError("%s could find the host plugin", SQMYSQL_NAME);
|
||||
OutputError("%s could find the host plug-in", SQMYSQL_NAME);
|
||||
// Don't load!
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
// Should never reach this point but just in case
|
||||
else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId)
|
||||
{
|
||||
OutputError("%s loaded after the host plugin", SQMYSQL_NAME);
|
||||
OutputError("%s loaded after the host plug-in", SQMYSQL_NAME);
|
||||
// Don't load!
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
@ -288,18 +280,18 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb
|
||||
_Func = functions;
|
||||
_Clbk = callbacks;
|
||||
_Info = info;
|
||||
// Assign plugin version
|
||||
// Assign plug-in version
|
||||
_Info->pluginVersion = SQMYSQL_VERSION;
|
||||
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
|
||||
_Info->apiMinorVersion = PLUGIN_API_MINOR;
|
||||
// Assign the plugin name
|
||||
// Assign the plug-in name
|
||||
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMYSQL_HOST_NAME);
|
||||
// Bind callbacks
|
||||
BindCallbacks();
|
||||
// Notify that the plugin was successfully loaded
|
||||
// Notify that the plug-in was successfully loaded
|
||||
OutputMessage("Successfully loaded %s", SQMYSQL_NAME);
|
||||
// Dummy spacing
|
||||
puts("");
|
||||
std::puts("");
|
||||
// Done!
|
||||
return SQMOD_SUCCESS;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
#ifndef _SQMYSQL_MODULE_HPP_
|
||||
#define _SQMYSQL_MODULE_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqMod.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Proxies to comunicate with the server.
|
||||
*/
|
||||
extern PluginFuncs* _Func;
|
||||
extern PluginCallbacks* _Clbk;
|
||||
extern PluginInfo* _Info;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Proxies to comunicate with the Squirrel plugin.
|
||||
*/
|
||||
extern HSQAPI _SqAPI;
|
||||
extern HSQEXPORTS _SqMod;
|
||||
extern HSQUIRRELVM _SqVM;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a message only if the _DEBUG was defined.
|
||||
*/
|
||||
void OutputDebug(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted user message to the console.
|
||||
*/
|
||||
void OutputMessage(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted error message to the console.
|
||||
*/
|
||||
void OutputError(const char * msg, ...);
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_MODULE_HPP_
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,17 +0,0 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
115
modules/mysql/ResultSet.cpp
Normal file
115
modules/mysql/ResultSet.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "ResultSet.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMySQLResultSet");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 ResultSet::Cmp(const ResultSet & o) const
|
||||
{
|
||||
if (m_Handle == o.m_Handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Handle.HndPtr() > o.m_Handle.HndPtr())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetInt8(Uint32 idx) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Should we retrieve the value from the bind wrapper?
|
||||
if (m_Handle->mStatement)
|
||||
{
|
||||
return ConvTo< Int8 >::From(m_Handle->mBinds[idx].mInt64);
|
||||
}
|
||||
// Retrieve the value directly from the row
|
||||
return ConvTo< Int8 >::From(*reinterpret_cast< Int8 ** >(m_Handle->mRow)[idx]);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetUint8(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetInt16(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetUint16(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetInt32(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger ResultSet::GetUint32(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object ResultSet::GetInt64(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object ResultSet::GetUint64(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQFloat ResultSet::GetFloat32(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQFloat ResultSet::GetFloat64(Uint32 idx) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ResultSet::GetBoolean(Uint32 idx) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Should we retrieve the value from the bind wrapper?
|
||||
if (m_Handle->mStatement)
|
||||
{
|
||||
return ConvTo< bool >::From(m_Handle->mBinds[idx].mUint64);
|
||||
}
|
||||
// Retrieve the value directly from the row
|
||||
return ConvTo< bool >::From(*reinterpret_cast< Uint8 ** >(m_Handle->mRow)[idx]);
|
||||
}
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
139
modules/mysql/ResultSet.hpp
Normal file
139
modules/mysql/ResultSet.hpp
Normal file
@ -0,0 +1,139 @@
|
||||
#ifndef _SQMYSQL_RESULTSET_HPP_
|
||||
#define _SQMYSQL_RESULTSET_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Result.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Allows management and interaction with a result set.
|
||||
*/
|
||||
class ResultSet
|
||||
{
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
ResHnd m_Handle; // The managed result set.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
ResultSet()
|
||||
: m_Handle()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
ResultSet(const ResHnd & hnd)
|
||||
: m_Handle(hnd)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
ResultSet(const ResultSet & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
ResultSet(ResultSet && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~ResultSet() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
ResultSet & operator = (const ResultSet & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
ResultSet & operator = (ResultSet && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const ResultSet & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 8 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetInt8(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 8 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetUint8(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 16 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetInt16(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 16 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetUint16(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 32 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetInt32(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 32 bit integer from a field.
|
||||
*/
|
||||
SQInteger GetUint32(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 64 bit integer from a field.
|
||||
*/
|
||||
Object GetInt64(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 64 bit integer from a field.
|
||||
*/
|
||||
Object GetUint64(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a 32 bit floating point from a field.
|
||||
*/
|
||||
SQFloat GetFloat32(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a 64 bit floating point from a field.
|
||||
*/
|
||||
SQFloat GetFloat64(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a boolean from a field.
|
||||
*/
|
||||
bool GetBoolean(Uint32 idx) const;
|
||||
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_RESULTSET_HPP_
|
@ -1,5 +1,5 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
#ifndef _SQMYSQL_SAVEPOINT_HPP_
|
||||
#define _SQMYSQL_SAVEPOINT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
@ -14,4 +14,4 @@ namespace SqMod {
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
||||
#endif // _SQMYSQL_SAVEPOINT_HPP_
|
||||
|
@ -1,10 +1,255 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
#include "Statement.hpp"
|
||||
#include "Connection.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <limits>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Statement::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMySQLStatement");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Statement::Cmp(const Statement & o) const
|
||||
{
|
||||
if (m_Handle == o.m_Handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Handle.HndPtr() > o.m_Handle.HndPtr())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Statement::Statement()
|
||||
: m_Handle()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Statement::Statement(const ConnHnd & connection, CSStr query)
|
||||
: m_Handle(connection, query)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Statement::Statement(const Connection & connection, CSStr query)
|
||||
: m_Handle(connection.GetHnd(), query)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Statement::Execute()
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Attempt to bind the parameters
|
||||
if (mysql_stmt_bind_param(m_Handle, m_Handle->mMyBinds))
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot bind statement parameters");
|
||||
}
|
||||
// Attempt to execute the statement
|
||||
else if (mysql_stmt_execute(m_Handle))
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot execute statement");
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysql_stmt_affected_rows(m_Handle);
|
||||
}
|
||||
// Default to a negative value to indicate error
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 Statement::Insert()
|
||||
{
|
||||
// Validate the managed handle
|
||||
m_Handle.Validate();
|
||||
// Attempt to bind the parameters
|
||||
if (mysql_stmt_bind_param(m_Handle, m_Handle->mMyBinds))
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot bind statement parameters");
|
||||
}
|
||||
// Attempt to execute the statement
|
||||
else if (mysql_stmt_execute(m_Handle))
|
||||
{
|
||||
THROW_CURRENT(m_Handle, "Cannot execute statement");
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysql_stmt_insert_id(m_Handle);
|
||||
}
|
||||
// Default to 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetInt8(Uint32 idx, SQInteger val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mInt64 = ConvTo< Int8 >::From(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetUint8(Uint32 idx, SQInteger val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mUint64 = ConvTo< Uint8 >::From(val);
|
||||
// Specify that this value is unsigned
|
||||
m_Handle->mMyBinds[idx].is_unsigned = true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetInt16(Uint32 idx, SQInteger val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SHORT, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mInt64 = ConvTo< Int16 >::From(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetUint16(Uint32 idx, SQInteger val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SHORT, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mUint64 = ConvTo< Uint16 >::From(val);
|
||||
// Specify that this value is unsigned
|
||||
m_Handle->mMyBinds[idx].is_unsigned = true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetInt32(Uint32 idx, SQInteger val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONG, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mInt64 = ConvTo< Int32 >::From(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetUint32(Uint32 idx, Uint32 val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONG, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mUint64 = ConvTo< Uint32 >::From(val);
|
||||
// Specify that this value is unsigned
|
||||
m_Handle->mMyBinds[idx].is_unsigned = true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetInt64(Uint32 idx, Object & val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg;
|
||||
// Push the specified object onto the stack
|
||||
Var< Object >::push(_SqVM, val);
|
||||
// Attempt to get the numeric value inside the specified object
|
||||
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &(m_Handle->mBinds[idx].mInt64))))
|
||||
{
|
||||
STHROWF("Invalid long integer specified");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetUint64(Uint32 idx, Object & val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
|
||||
// Specify that this value is unsigned
|
||||
m_Handle->mMyBinds[idx].is_unsigned = true;
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg;
|
||||
// Push the specified object onto the stack
|
||||
Var< Object >::push(_SqVM, val);
|
||||
// Attempt to get the numeric value inside the specified object
|
||||
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &(m_Handle->mBinds[idx].mUint64))))
|
||||
{
|
||||
STHROWF("Invalid long integer specified");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetFloat32(Uint32 idx, SQFloat val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_FLOAT, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mFloat32[0] = ConvTo< Float32 >::From(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetFloat64(Uint32 idx, SQFloat val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DOUBLE, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mFloat64 = ConvTo< Float64 >::From(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetBoolean(Uint32 idx, bool val) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TINY, &(m_Handle->mMyBinds[idx]));
|
||||
// Assign the value to the input
|
||||
m_Handle->mBinds[idx].mUint64 = val;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Statement::SetNull(Uint32 idx) const
|
||||
{
|
||||
// Validate the managed handle and specified index
|
||||
m_Handle.ValidateIndex(idx);
|
||||
// Attempt to set the input value
|
||||
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_NULL, &(m_Handle->mMyBinds[idx]));
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -1,23 +1,190 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
#ifndef _SQMYSQL_STATEMENT_HPP_
|
||||
#define _SQMYSQL_STATEMENT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
#include "Handle/Statement.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* ...
|
||||
*/
|
||||
class Statement
|
||||
{
|
||||
public:
|
||||
Statement();
|
||||
~Statement();
|
||||
|
||||
};
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
StmtHnd m_Handle; // Reference to the managed statement.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Statement();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct a statement under the specified connection using the specified string.
|
||||
*/
|
||||
Statement(const ConnHnd & connection, CSStr query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct a statement under the specified connection using the specified string.
|
||||
*/
|
||||
Statement(const Connection & connection, CSStr query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Statement(const Statement & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Statement(Statement && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Statement() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Statement & operator = (const Statement & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Statement & operator = (Statement && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Statement & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Execute the statement.
|
||||
*/
|
||||
Int32 Execute();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Execute the statement.
|
||||
*/
|
||||
Uint32 Insert();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a signed 8bit integer to a parameter.
|
||||
*/
|
||||
void SetInt8(Uint32 idx, SQInteger val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign an unsigned 8bit integer to a parameter.
|
||||
*/
|
||||
void SetUint8(Uint32 idx, SQInteger val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a signed 16bit integer to a parameter.
|
||||
*/
|
||||
void SetInt16(Uint32 idx, SQInteger val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign an unsigned 16bit integer to a parameter.
|
||||
*/
|
||||
void SetUint16(Uint32 idx, SQInteger val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a signed 32bit integer to a parameter.
|
||||
*/
|
||||
void SetInt32(Uint32 idx, SQInteger val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign an unsigned 32bit integer to a parameter.
|
||||
*/
|
||||
void SetUint32(Uint32 idx, Uint32 val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a signed 64bit integer to a parameter.
|
||||
*/
|
||||
void SetInt64(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign an unsigned 64bit integer to a parameter.
|
||||
*/
|
||||
void SetUint64(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a 32bit floating point to a parameter.
|
||||
*/
|
||||
void SetFloat32(Uint32 idx, SQFloat val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a 64bit floating point to a parameter.
|
||||
*/
|
||||
void SetFloat64(Uint32 idx, SQFloat val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a boolean to a parameter.
|
||||
*/
|
||||
void SetBoolean(Uint32 idx, bool val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a null to a parameter.
|
||||
*/
|
||||
void SetNull(Uint32 idx) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetBlob(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetData(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetDate(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetTime(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetDatetime(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetDecimal(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetString(Uint32 idx, Object & val) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetEnum(Uint32 idx, Object & val) const;
|
||||
|
||||
};
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
||||
#endif // _SQMYSQL_STATEMENT_HPP_
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef _SQMYSQL_ACCOUNT_HPP_
|
||||
#define _SQMYSQL_ACCOUNT_HPP_
|
||||
#ifndef _SQMYSQL_TRANSACTION_HPP_
|
||||
#define _SQMYSQL_TRANSACTION_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
@ -14,4 +14,4 @@ namespace SqMod {
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_ACCOUNT_HPP_
|
||||
#endif // _SQMYSQL_TRANSACTION_HPP_
|
||||
|
0
modules/mysql/Wrapper/CharsetInfo.cpp
Normal file
0
modules/mysql/Wrapper/CharsetInfo.cpp
Normal file
0
modules/mysql/Wrapper/CharsetInfo.hpp
Normal file
0
modules/mysql/Wrapper/CharsetInfo.hpp
Normal file
Loading…
x
Reference in New Issue
Block a user