1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Discard modules.

This commit is contained in:
Sandu Liviu Catalin 2020-03-21 14:58:32 +02:00
parent 1fd5fda8c0
commit 1099c7fd20
102 changed files with 0 additions and 24659 deletions

View File

@ -1,154 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void * IrcAllocMem(size_t n)
{
// Does the requested size exceed the common shared buffer size?
if (n > GetTempBuffSize())
{
return std::malloc(n);
}
// Return the common shared buffer
return GetTempBuff();
}
// ------------------------------------------------------------------------------------------------
void IrcFreeMem(void * p)
{
// Only release if it's not the temporary buffer
if ((p < GetTempBuff()) || (p > (GetTempBuff() + GetTempBuffSize())))
{
std::free(p);
}
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqGetNick(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Attempt to retrieve the nickname
irc_target_get_nick(val.mPtr, GetTempBuff(), GetTempBuffSize());
// Push the resulted value on the stack
sq_pushstring(vm, GetTempBuff(), -1);
// Specify that this function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqGetHost(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Attempt to retrieve the host
irc_target_get_host(val.mPtr, GetTempBuff(), GetTempBuffSize());
// Push the resulted value on the stack
sq_pushstring(vm, GetTempBuff(), -1);
// Specify that this function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqStripColorFromMIRC(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Attempt to strip the colors
CStr str = irc_color_strip_from_mirc(val.mPtr);
// Could the IRC library allocate memory?
if (!str)
{
return sq_throwerror(vm, _SC("Unable to allocate memory"));
}
// Push the resulted value on the stack
sq_pushstring(vm, str, -1);
// Free the memory allocated by the IRC library
std::free(str);
// Specify that this function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqConvertColorFromMIRC(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Attempt to convert the colors
CStr str = irc_color_convert_from_mirc(val.mPtr);
// Could the IRC library allocate memory?
if (!str)
{
return sq_throwerror(vm, _SC("Unable to allocate memory"));
}
// Push the resulted value on the stack
sq_pushstring(vm, str, -1);
// Free the memory allocated by the IRC library
std::free(str);
// Specify that this function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqConvertColorToMIRC(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Attempt to convert the colors
CStr str = irc_color_convert_to_mirc(val.mPtr, IrcAllocMem);
// Could the IRC library allocate memory?
if (!str)
{
return sq_throwerror(vm, _SC("Unable to allocate memory"));
}
// Push the resulted value on the stack
sq_pushstring(vm, str, -1);
// Free the memory allocated by the IRC library
IrcFreeMem(str);
// Specify that this function returned a value
return 1;
}
// ================================================================================================
void Register_Common(Table & ircns)
{
ircns.Func(_SC("GetErrStr"), &irc_strerror);
ircns.SquirrelFunc(_SC("GetNick"), &SqGetNick);
ircns.SquirrelFunc(_SC("GetHost"), &SqGetHost);
ircns.SquirrelFunc(_SC("StripColorFromMIRC"), &SqStripColorFromMIRC);
ircns.SquirrelFunc(_SC("ConvertColorFromMIRC"), &SqConvertColorFromMIRC);
ircns.SquirrelFunc(_SC("ConvertColorToMIRC"), &SqConvertColorToMIRC);
}
} // Namespace:: SqMod

View File

@ -1,98 +0,0 @@
#ifndef _SQIRC_COMMON_HPP_
#define _SQIRC_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <libircclient.h>
#include <libirc_rfcnumeric.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQIRC_NAME "Squirrel IRC Module"
#define SQIRC_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQIRC_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQIRC_HOST_NAME "SqModIRCHost"
#define SQIRC_VERSION 001
#define SQIRC_VERSION_STR "0.0.1"
#define SQIRC_VERSION_MAJOR 0
#define SQIRC_VERSION_MINOR 0
#define SQIRC_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Types of events that the session emits.
*/
enum SessionEvent
{
SET_CONNECT = 0,
SET_NICK,
SET_QUIT,
SET_JOIN,
SET_PART,
SET_MODE,
SET_UMODE,
SET_TOPIC,
SET_KICK,
SET_CHANNEL,
SET_PRIVMSG,
SET_NOTICE,
SET_CHANNELNOTICE,
SET_INVITE,
SET_CTCPREQ,
SET_CTCPREP,
SET_CTCPACTION,
SET_UNKNOWN,
SET_NUMERIC,
SET_DCCCHATREQ,
SET_DCCSENDREQ,
SET_MAX
};
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class Session;
/* ------------------------------------------------------------------------------------------------
* Used by IRC as proxy to allocate memory if the requested size is larger than the common buffer.
*/
void * IrcAllocMem(size_t n);
/* ------------------------------------------------------------------------------------------------
* Release memory previously allocated with IrcAllocMem, only if necessary. Nasty but we'll try.
*/
void IrcFreeMem(void * p);
/* ------------------------------------------------------------------------------------------------
* Extract the name from the specified origin.
*/
SQInteger GetNick(HSQUIRRELVM vm);
/* ------------------------------------------------------------------------------------------------
* Extract the host from the specified origin.
*/
SQInteger GetHost(HSQUIRRELVM vm);
/* ------------------------------------------------------------------------------------------------
* Returns a new plain text message with stripped mIRC color codes.
*/
SQInteger StripColorFromMIRC(HSQUIRRELVM vm);
/* ------------------------------------------------------------------------------------------------
* Returns a new message with converted mIRC color codes and format options.
*/
SQInteger ConvertColorFromMIRC(HSQUIRRELVM vm);
/* ------------------------------------------------------------------------------------------------
* Returns a new message with converted color codes and format options.
*/
SQInteger ConvertColorToMIRC(HSQUIRRELVM vm);
} // Namespace:: SqMod
#endif // _SQIRC_COMMON_HPP_

View File

@ -1,244 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class that represents an integral enumeration value. Used to reduce compilation times.
*/
struct EnumElement
{
CSStr Name;
Int32 Value;
};
// ------------------------------------------------------------------------------------------------
#define SQENUMCOUNT(arr) (sizeof(arr) / sizeof(EnumElement))
// ------------------------------------------------------------------------------------------------
static const EnumElement g_IrcEvent[] = {
{_SC("Connect"), SET_CONNECT},
{_SC("Nick"), SET_NICK},
{_SC("Quit"), SET_QUIT},
{_SC("Join"), SET_JOIN},
{_SC("Part"), SET_PART},
{_SC("Mode"), SET_MODE},
{_SC("Umode"), SET_UMODE},
{_SC("Topic"), SET_TOPIC},
{_SC("Kick"), SET_KICK},
{_SC("Channel"), SET_CHANNEL},
{_SC("PrivMsg"), SET_PRIVMSG},
{_SC("Notice"), SET_NOTICE},
{_SC("ChannelNotice"), SET_CHANNELNOTICE},
{_SC("Invite"), SET_INVITE},
{_SC("CtcpReq"), SET_CTCPREQ},
{_SC("CtcpRep"), SET_CTCPREP},
{_SC("CtcpAction"), SET_CTCPACTION},
{_SC("Unknown"), SET_UNKNOWN},
{_SC("Numeric"), SET_NUMERIC},
{_SC("DccChatReq"), SET_DCCCHATREQ},
{_SC("DccSendReq"), SET_DCCSENDREQ}
};
// ------------------------------------------------------------------------------------------------
static const EnumElement g_IrcErr[] = {
{_SC("Ok"), LIBIRC_ERR_OK},
{_SC("InVal"), LIBIRC_ERR_INVAL},
{_SC("Resolv"), LIBIRC_ERR_RESOLV},
{_SC("Socket"), LIBIRC_ERR_SOCKET},
{_SC("Connect"), LIBIRC_ERR_CONNECT},
{_SC("Closed"), LIBIRC_ERR_CLOSED},
{_SC("NoMem"), LIBIRC_ERR_NOMEM},
{_SC("Accept"), LIBIRC_ERR_ACCEPT},
{_SC("NoDccSend"), LIBIRC_ERR_NODCCSEND},
{_SC("Read"), LIBIRC_ERR_READ},
{_SC("Write"), LIBIRC_ERR_WRITE},
{_SC("State"), LIBIRC_ERR_STATE},
{_SC("Timeout"), LIBIRC_ERR_TIMEOUT},
{_SC("OpenFile"), LIBIRC_ERR_OPENFILE},
{_SC("Terminated"), LIBIRC_ERR_TERMINATED},
{_SC("NoIPv6"), LIBIRC_ERR_NOIPV6},
{_SC("SSLNotSupported"), LIBIRC_ERR_SSL_NOT_SUPPORTED},
{_SC("SSLInitFailed"), LIBIRC_ERR_SSL_INIT_FAILED},
{_SC("ConnectSSLFailed"), LIBIRC_ERR_CONNECT_SSL_FAILED},
{_SC("SSLCertVerifyFailed"), LIBIRC_ERR_SSL_CERT_VERIFY_FAILED},
{_SC("Max"), LIBIRC_ERR_MAX}
};
// ------------------------------------------------------------------------------------------------
static const EnumElement g_IrcOpt[] = {
{_SC("Debug"), LIBIRC_OPTION_DEBUG},
{_SC("StripNicks"), LIBIRC_OPTION_STRIPNICKS},
{_SC("SSLNoVerify"), LIBIRC_OPTION_SSL_NO_VERIFY}
};
// ------------------------------------------------------------------------------------------------
static const EnumElement g_IrcRFC[] = {
{_SC("RPL_WELCOME"), LIBIRC_RFC_RPL_WELCOME},
{_SC("RPL_YOURHOST"), LIBIRC_RFC_RPL_YOURHOST},
{_SC("RPL_CREATED"), LIBIRC_RFC_RPL_CREATED},
{_SC("RPL_MYINFO"), LIBIRC_RFC_RPL_MYINFO},
{_SC("RPL_BOUNCE"), LIBIRC_RFC_RPL_BOUNCE},
{_SC("RPL_NONE"), LIBIRC_RFC_RPL_NONE},
{_SC("RPL_USERHOST"), LIBIRC_RFC_RPL_USERHOST},
{_SC("RPL_ISON"), LIBIRC_RFC_RPL_ISON},
{_SC("RPL_AWAY"), LIBIRC_RFC_RPL_AWAY},
{_SC("RPL_UNAWAY"), LIBIRC_RFC_RPL_UNAWAY},
{_SC("RPL_NOWAWAY"), LIBIRC_RFC_RPL_NOWAWAY},
{_SC("RPL_WHOISUSER"), LIBIRC_RFC_RPL_WHOISUSER},
{_SC("RPL_WHOISSERVER"), LIBIRC_RFC_RPL_WHOISSERVER},
{_SC("RPL_WHOISOPERATOR"), LIBIRC_RFC_RPL_WHOISOPERATOR},
{_SC("RPL_WHOISIDLE"), LIBIRC_RFC_RPL_WHOISIDLE},
{_SC("RPL_ENDOFWHOIS"), LIBIRC_RFC_RPL_ENDOFWHOIS},
{_SC("RPL_WHOISCHANNELS"), LIBIRC_RFC_RPL_WHOISCHANNELS},
{_SC("RPL_WHOWASUSER"), LIBIRC_RFC_RPL_WHOWASUSER},
{_SC("RPL_ENDOFWHOWAS"), LIBIRC_RFC_RPL_ENDOFWHOWAS},
{_SC("RPL_LISTSTART"), LIBIRC_RFC_RPL_LISTSTART},
{_SC("RPL_LIST"), LIBIRC_RFC_RPL_LIST},
{_SC("RPL_LISTEND"), LIBIRC_RFC_RPL_LISTEND},
{_SC("RPL_UNIQOPIS"), LIBIRC_RFC_RPL_UNIQOPIS},
{_SC("RPL_CHANNELMODEIS"), LIBIRC_RFC_RPL_CHANNELMODEIS},
{_SC("RPL_NOTOPIC"), LIBIRC_RFC_RPL_NOTOPIC},
{_SC("RPL_TOPIC"), LIBIRC_RFC_RPL_TOPIC},
{_SC("RPL_INVITING"), LIBIRC_RFC_RPL_INVITING},
{_SC("RPL_SUMMONING"), LIBIRC_RFC_RPL_SUMMONING},
{_SC("RPL_INVITELIST"), LIBIRC_RFC_RPL_INVITELIST},
{_SC("RPL_ENDOFINVITELIST"), LIBIRC_RFC_RPL_ENDOFINVITELIST},
{_SC("RPL_EXCEPTLIST"), LIBIRC_RFC_RPL_EXCEPTLIST},
{_SC("RPL_ENDOFEXCEPTLIST"), LIBIRC_RFC_RPL_ENDOFEXCEPTLIST},
{_SC("RPL_VERSION"), LIBIRC_RFC_RPL_VERSION},
{_SC("RPL_WHOREPLY"), LIBIRC_RFC_RPL_WHOREPLY},
{_SC("RPL_ENDOFWHO"), LIBIRC_RFC_RPL_ENDOFWHO},
{_SC("RPL_NAMREPLY"), LIBIRC_RFC_RPL_NAMREPLY},
{_SC("RPL_ENDOFNAMES"), LIBIRC_RFC_RPL_ENDOFNAMES},
{_SC("RPL_LINKS"), LIBIRC_RFC_RPL_LINKS},
{_SC("RPL_ENDOFLINKS"), LIBIRC_RFC_RPL_ENDOFLINKS},
{_SC("RPL_BANLIST"), LIBIRC_RFC_RPL_BANLIST},
{_SC("RPL_ENDOFBANLIST"), LIBIRC_RFC_RPL_ENDOFBANLIST},
{_SC("RPL_INFO"), LIBIRC_RFC_RPL_INFO},
{_SC("RPL_ENDOFINFO"), LIBIRC_RFC_RPL_ENDOFINFO},
{_SC("RPL_MOTDSTART"), LIBIRC_RFC_RPL_MOTDSTART},
{_SC("RPL_MOTD"), LIBIRC_RFC_RPL_MOTD},
{_SC("RPL_ENDOFMOTD"), LIBIRC_RFC_RPL_ENDOFMOTD},
{_SC("RPL_YOUREOPER"), LIBIRC_RFC_RPL_YOUREOPER},
{_SC("RPL_REHASHING"), LIBIRC_RFC_RPL_REHASHING},
{_SC("RPL_YOURESERVICE"), LIBIRC_RFC_RPL_YOURESERVICE},
{_SC("RPL_TIME"), LIBIRC_RFC_RPL_TIME},
{_SC("RPL_USERSSTART"), LIBIRC_RFC_RPL_USERSSTART},
{_SC("RPL_USERS"), LIBIRC_RFC_RPL_USERS},
{_SC("RPL_ENDOFUSERS"), LIBIRC_RFC_RPL_ENDOFUSERS},
{_SC("RPL_NOUSERS"), LIBIRC_RFC_RPL_NOUSERS},
{_SC("RPL_TRACELINK"), LIBIRC_RFC_RPL_TRACELINK},
{_SC("RPL_TRACECONNECTING"), LIBIRC_RFC_RPL_TRACECONNECTING},
{_SC("RPL_TRACEHANDSHAKE"), LIBIRC_RFC_RPL_TRACEHANDSHAKE},
{_SC("RPL_TRACEUNKNOWN"), LIBIRC_RFC_RPL_TRACEUNKNOWN},
{_SC("RPL_TRACEOPERATOR"), LIBIRC_RFC_RPL_TRACEOPERATOR},
{_SC("RPL_TRACEUSER"), LIBIRC_RFC_RPL_TRACEUSER},
{_SC("RPL_TRACESERVER"), LIBIRC_RFC_RPL_TRACESERVER},
{_SC("RPL_TRACESERVICE"), LIBIRC_RFC_RPL_TRACESERVICE},
{_SC("RPL_TRACENEWTYPE"), LIBIRC_RFC_RPL_TRACENEWTYPE},
{_SC("RPL_TRACECLASS"), LIBIRC_RFC_RPL_TRACECLASS},
{_SC("RPL_TRACELOG"), LIBIRC_RFC_RPL_TRACELOG},
{_SC("RPL_TRACEEND"), LIBIRC_RFC_RPL_TRACEEND},
{_SC("RPL_STATSLINKINFO"), LIBIRC_RFC_RPL_STATSLINKINFO},
{_SC("RPL_STATSCOMMANDS"), LIBIRC_RFC_RPL_STATSCOMMANDS},
{_SC("RPL_ENDOFSTATS"), LIBIRC_RFC_RPL_ENDOFSTATS},
{_SC("RPL_STATSUPTIME"), LIBIRC_RFC_RPL_STATSUPTIME},
{_SC("RPL_STATSOLINE"), LIBIRC_RFC_RPL_STATSOLINE},
{_SC("RPL_UMODEIS"), LIBIRC_RFC_RPL_UMODEIS},
{_SC("RPL_SERVLIST"), LIBIRC_RFC_RPL_SERVLIST},
{_SC("RPL_SERVLISTEND"), LIBIRC_RFC_RPL_SERVLISTEND},
{_SC("RPL_LUSERCLIENT"), LIBIRC_RFC_RPL_LUSERCLIENT},
{_SC("RPL_LUSEROP"), LIBIRC_RFC_RPL_LUSEROP},
{_SC("RPL_LUSERUNKNOWN"), LIBIRC_RFC_RPL_LUSERUNKNOWN},
{_SC("RPL_LUSERCHANNELS"), LIBIRC_RFC_RPL_LUSERCHANNELS},
{_SC("RPL_LUSERME"), LIBIRC_RFC_RPL_LUSERME},
{_SC("RPL_ADMINME"), LIBIRC_RFC_RPL_ADMINME},
{_SC("RPL_ADMINLOC1"), LIBIRC_RFC_RPL_ADMINLOC1},
{_SC("RPL_ADMINLOC2"), LIBIRC_RFC_RPL_ADMINLOC2},
{_SC("RPL_ADMINEMAIL"), LIBIRC_RFC_RPL_ADMINEMAIL},
{_SC("RPL_TRYAGAIN"), LIBIRC_RFC_RPL_TRYAGAIN},
{_SC("ERR_NOSUCHNICK"), LIBIRC_RFC_ERR_NOSUCHNICK},
{_SC("ERR_NOSUCHSERVER"), LIBIRC_RFC_ERR_NOSUCHSERVER},
{_SC("ERR_NOSUCHCHANNEL"), LIBIRC_RFC_ERR_NOSUCHCHANNEL},
{_SC("ERR_CANNOTSENDTOCHAN"), LIBIRC_RFC_ERR_CANNOTSENDTOCHAN},
{_SC("ERR_TOOMANYCHANNELS"), LIBIRC_RFC_ERR_TOOMANYCHANNELS},
{_SC("ERR_WASNOSUCHNICK"), LIBIRC_RFC_ERR_WASNOSUCHNICK},
{_SC("ERR_TOOMANYTARGETS"), LIBIRC_RFC_ERR_TOOMANYTARGETS},
{_SC("ERR_NOSUCHSERVICE"), LIBIRC_RFC_ERR_NOSUCHSERVICE},
{_SC("ERR_NOORIGIN"), LIBIRC_RFC_ERR_NOORIGIN},
{_SC("ERR_NORECIPIENT"), LIBIRC_RFC_ERR_NORECIPIENT},
{_SC("ERR_NOTEXTTOSEND"), LIBIRC_RFC_ERR_NOTEXTTOSEND},
{_SC("ERR_NOTOPLEVEL"), LIBIRC_RFC_ERR_NOTOPLEVEL},
{_SC("ERR_WILDTOPLEVEL"), LIBIRC_RFC_ERR_WILDTOPLEVEL},
{_SC("ERR_BADMASK"), LIBIRC_RFC_ERR_BADMASK},
{_SC("ERR_UNKNOWNCOMMAND"), LIBIRC_RFC_ERR_UNKNOWNCOMMAND},
{_SC("ERR_NOMOTD"), LIBIRC_RFC_ERR_NOMOTD},
{_SC("ERR_NOADMININFO"), LIBIRC_RFC_ERR_NOADMININFO},
{_SC("ERR_FILEERROR"), LIBIRC_RFC_ERR_FILEERROR},
{_SC("ERR_NONICKNAMEGIVEN"), LIBIRC_RFC_ERR_NONICKNAMEGIVEN},
{_SC("ERR_ERRONEUSNICKNAME"), LIBIRC_RFC_ERR_ERRONEUSNICKNAME},
{_SC("ERR_NICKNAMEINUSE"), LIBIRC_RFC_ERR_NICKNAMEINUSE},
{_SC("ERR_NICKCOLLISION"), LIBIRC_RFC_ERR_NICKCOLLISION},
{_SC("ERR_UNAVAILRESOURCE"), LIBIRC_RFC_ERR_UNAVAILRESOURCE},
{_SC("ERR_USERNOTINCHANNEL"), LIBIRC_RFC_ERR_USERNOTINCHANNEL},
{_SC("ERR_NOTONCHANNEL"), LIBIRC_RFC_ERR_NOTONCHANNEL},
{_SC("ERR_USERONCHANNEL"), LIBIRC_RFC_ERR_USERONCHANNEL},
{_SC("ERR_NOLOGIN"), LIBIRC_RFC_ERR_NOLOGIN},
{_SC("ERR_SUMMONDISABLED"), LIBIRC_RFC_ERR_SUMMONDISABLED},
{_SC("ERR_USERSDISABLED"), LIBIRC_RFC_ERR_USERSDISABLED},
{_SC("ERR_NOTREGISTERED"), LIBIRC_RFC_ERR_NOTREGISTERED},
{_SC("ERR_NEEDMOREPARAMS"), LIBIRC_RFC_ERR_NEEDMOREPARAMS},
{_SC("ERR_ALREADYREGISTRED"), LIBIRC_RFC_ERR_ALREADYREGISTRED},
{_SC("ERR_NOPERMFORHOST"), LIBIRC_RFC_ERR_NOPERMFORHOST},
{_SC("ERR_PASSWDMISMATCH"), LIBIRC_RFC_ERR_PASSWDMISMATCH},
{_SC("ERR_YOUREBANNEDCREEP"), LIBIRC_RFC_ERR_YOUREBANNEDCREEP},
{_SC("ERR_YOUWILLBEBANNED"), LIBIRC_RFC_ERR_YOUWILLBEBANNED},
{_SC("ERR_KEYSET"), LIBIRC_RFC_ERR_KEYSET},
{_SC("ERR_CHANNELISFULL"), LIBIRC_RFC_ERR_CHANNELISFULL},
{_SC("ERR_UNKNOWNMODE"), LIBIRC_RFC_ERR_UNKNOWNMODE},
{_SC("ERR_INVITEONLYCHAN"), LIBIRC_RFC_ERR_INVITEONLYCHAN},
{_SC("ERR_BANNEDFROMCHAN"), LIBIRC_RFC_ERR_BANNEDFROMCHAN},
{_SC("ERR_BADCHANNELKEY"), LIBIRC_RFC_ERR_BADCHANNELKEY},
{_SC("ERR_BADCHANMASK"), LIBIRC_RFC_ERR_BADCHANMASK},
{_SC("ERR_NOCHANMODES"), LIBIRC_RFC_ERR_NOCHANMODES},
{_SC("ERR_BANLISTFULL"), LIBIRC_RFC_ERR_BANLISTFULL},
{_SC("ERR_NOPRIVILEGES"), LIBIRC_RFC_ERR_NOPRIVILEGES},
{_SC("ERR_CHANOPRIVSNEEDED"), LIBIRC_RFC_ERR_CHANOPRIVSNEEDED},
{_SC("ERR_CANTKILLSERVER"), LIBIRC_RFC_ERR_CANTKILLSERVER},
{_SC("ERR_RESTRICTED"), LIBIRC_RFC_ERR_RESTRICTED},
{_SC("ERR_UNIQOPPRIVSNEEDED"), LIBIRC_RFC_ERR_UNIQOPPRIVSNEEDED},
{_SC("ERR_NOOPERHOST"), LIBIRC_RFC_ERR_NOOPERHOST},
{_SC("ERR_UMODEUNKNOWNFLAG"), LIBIRC_RFC_ERR_UMODEUNKNOWNFLAG},
{_SC("ERR_USERSDONTMATCH"), LIBIRC_RFC_ERR_USERSDONTMATCH}
};
// ------------------------------------------------------------------------------------------------
static Enumeration RegisterEnum(HSQUIRRELVM vm, CSStr name, const EnumElement * data, Uint32 count)
{
// Allocate an empty enumeration
Enumeration e(vm);
// Register the values from the received data
for (Uint32 n = 0; n < count; ++n, ++data)
{
e.Const(data->Name, data->Value);
}
// Bind the enumeration to the constant table
ConstTable(vm).Enum(name, e);
// Return the enumeration for further changes if necessary
return e;
}
// ================================================================================================
void Register_Constants(Table & ircns)
{
RegisterEnum(ircns.GetVM(), _SC("SqIrcEvent"), g_IrcEvent, SQENUMCOUNT(g_IrcEvent));
RegisterEnum(ircns.GetVM(), _SC("SqIrcErr"), g_IrcErr, SQENUMCOUNT(g_IrcErr));
RegisterEnum(ircns.GetVM(), _SC("SqIrcOpt"), g_IrcOpt, SQENUMCOUNT(g_IrcOpt));
RegisterEnum(ircns.GetVM(), _SC("SqIrcRFC"), g_IrcRFC, SQENUMCOUNT(g_IrcRFC));
}
} // Namespace:: SqMod

View File

@ -1,243 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#include <Winsock2.h>
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void SessionProcess();
extern void SessionTerminate();
// ------------------------------------------------------------------------------------------------
extern void Register_Common(Table & ircns);
extern void Register_Session(Table & ircns);
extern void Register_Constants(Table & ircns);
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQIRC_NAME);
// Registration failed
return false;
}
Table ircns(vm);
Register_Common(ircns);
Register_Session(ircns);
Register_Constants(ircns);
RootTable(vm).Bind(_SC("SqIRC"), ircns);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQIRC_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQIRC_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQIRC_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQIRC_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Terminate all sessions, if any
SessionTerminate();
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQIRC_NAME))
{
try
{
ImportModuleAPI(_Func, SQIRC_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnServerFrame = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
/* ------------------------------------------------------------------------------------------------
* Update the plug-in on each frame.
*/
static void OnServerFrame(float /*delta*/)
{
SessionProcess(); // Update the sessions and pool for events
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQIRC_NAME);
OutputMessage("Author: %s", SQIRC_AUTHOR);
OutputMessage("Legal: %s", SQIRC_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQIRC_NAME))
{
return SQMOD_FAILURE;
}
#ifdef SQMOD_OS_WINDOWS
WSADATA wsa_data;
// Initialize the sockets on windows
if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
{
OutputError("Unable to initialize the windows sockets");
// Don't load!
return SQMOD_FAILURE;
}
#endif // SQMOD_OS_WINDOWS
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQIRC_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQIRC_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnServerFrame = OnServerFrame;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQIRC_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,306 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "JValue.hpp"
#include "JArray.hpp"
#include "JObject.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
CSStr JSONTypeToStr(json_type type)
{
switch (type)
{
case JSON_OBJECT: return _SC("object");
case JSON_ARRAY: return _SC("array");
case JSON_STRING: return _SC("string");
case JSON_INTEGER: return _SC("integer");
case JSON_REAL: return _SC("real");
case JSON_TRUE: return _SC("true");
case JSON_FALSE: return _SC("false");
case JSON_NULL: return _SC("null");
default: return _SC("unknown");
}
}
// ------------------------------------------------------------------------------------------------
void SqThrowLast(HSQUIRRELVM vm, CSStr msg)
{
// Remember the current stack size
const StackGuard sg(vm);
// Push the last error on the stack
sq_getlasterror(vm);
// Attempt to obtained the error as a string
StackStrF val(vm, -1, false);
// Did the retrieval failed?
if (SQ_FAILED(val.mRes))
{
STHROWF("%s [Unknown error]", msg);
}
// Throw the resulting error message
STHROWF("%s [%s]", msg, val.mPtr);
}
// ------------------------------------------------------------------------------------------------
Object SqFromJSON(HSQUIRRELVM /*vm*/, json_t * jval)
{
switch (json_typeof(jval))
{
case JSON_OBJECT:
{
} break;
case JSON_ARRAY:
{
} break;
case JSON_STRING:
{
} break;
case JSON_INTEGER:
{
} break;
case JSON_REAL:
{
} break;
case JSON_TRUE:
{
} break;
case JSON_FALSE:
{
} break;
case JSON_NULL:
{
} break;
default: STHROWF("Unknown JSON value type");
}
return Object();
}
// ------------------------------------------------------------------------------------------------
json_t * SqToJSON(HSQUIRRELVM vm, SQInteger idx)
{
switch (sq_gettype(vm, idx))
{
case OT_NULL:
{
return json_null();
} break;
case OT_INTEGER:
{
SQInteger i;
// Retrieve the integer value
if (SQ_FAILED(sq_getinteger(vm, idx, &i)))
{
SqThrowLast(vm, "Cannot retrieve integer value");
}
// Return the JSON value
return json_integer(i);
} break;
case OT_FLOAT:
{
SQFloat f;
// Retrieve the float value
if (SQ_FAILED(sq_getfloat(vm, idx, &f)))
{
SqThrowLast(vm, "Cannot retrieve float value");
}
// Return the JSON value
return json_real(f);
} break;
case OT_BOOL:
{
SQBool b;
// Retrieve the boolean value
if (SQ_FAILED(sq_getbool(vm, idx, &b)))
{
SqThrowLast(vm, "Cannot retrieve boolean value");
}
// Return the JSON value
return json_boolean(b);
} break;
case OT_STRING:
{
CSStr s = nullptr;
SQInteger n;
// Retrieve the string value
if (SQ_FAILED(sq_getstringandsize(vm, idx, &s, &n)))
{
SqThrowLast(vm, "Cannot retrieve string value");
}
// Return the JSON value
return json_stringn(s, ConvTo< std::size_t >::From(n));
} break;
case OT_TABLE:
{
// Create an object wrapper to release automatically in case of failure
JObject obj;
// Remember the current stack size
const StackGuard sg(vm);
// Push null to begin table iteration
sq_pushnull(vm);
// Compute the new table index on the stack if necessary
if (idx < 0)
{
--idx;
}
// Start iterating table elements
while(SQ_SUCCEEDED(sq_next(vm, idx)))
{
// Attempt to convert the key to a string
StackStrF val(vm, -2, false);
// Did the conversion failed?
if (SQ_FAILED(val.mRes))
{
SqThrowLast(vm, "Invalid table key");
}
// Assign the value with further recursive scanning
if (json_object_set_new(obj, val.mPtr, SqToJSON(vm, -1)) < 0)
{
STHROWF("Unable to set table element (&s)", val.mPtr);
}
// Pop the key and value before the new iteration
sq_pop(vm, 2);
}
// Increase the reference count so that we don't destroy the object
json_incref(obj);
// Return the resulted object
return obj;
} break;
case OT_ARRAY:
{
// Create an array wrapper to release automatically in case of failure
JArray arr;
// Remember the current stack size
const StackGuard sg(vm);
// Obtain the total size of the array
const SQInteger size = sq_getsize(vm, idx);
// Push null to begin array iteration
sq_pushnull(vm);
// Compute the new array index on the stack if necessary
if (idx < 0)
{
--idx;
}
// Currently processed element
SQInteger pos;
// Start iterating array elements
while(SQ_SUCCEEDED(sq_next(vm, idx)))
{
// Retrieve the currently processed array element index
if (SQ_FAILED(sq_getinteger(vm, -2, &pos)))
{
SqThrowLast(vm, "Unable to retrieve iterator position");
}
// Are we still within the array bounds?
else if (pos >= size)
{
break; // Stop iterating
}
// Assign the value with further recursive scanning
if (json_array_append_new(arr, SqToJSON(vm, -1)) < 0)
{
STHROWF("Unable to set array element: " _PRINT_INT_FMT, pos);
}
// Pop the key and value before the new iteration
sq_pop(vm, 2);
}
// Increase the reference count so that we don't destroy the array
json_incref(arr);
// Return the resulted array
return arr;
} break;
default:
{
// Grab the type name of the object on the stack
const String tn(SqTypeName(vm, idx));
// Now throw the error with the obtained name
STHROWF("Unknown conversion for type: %s", tn.c_str());
}
}
// Should not reach this point
return nullptr;
}
// ------------------------------------------------------------------------------------------------
JObject SqTableToJSONObject(Table & tbl)
{
// Make sure that the given table is not null
if (tbl.IsNull())
{
return JObject(); // Nothing to add
}
// Remember the current stack size
const StackGuard sg(tbl.GetVM());
// Push our table onto the stack
Var< Table & >::push(tbl.GetVM(), tbl);
// Attempt to extract the values from the given table
return JObject(SqToJSON(tbl.GetVM(), -1), false);
}
// ------------------------------------------------------------------------------------------------
JArray SqArrayToJSONArray(Array & arr)
{
// Make sure that the given array is not null
if (arr.IsNull())
{
return JArray(); // Nothing to add
}
// Remember the current stack size
const StackGuard sg(arr.GetVM());
// Push our array onto the stack
Var< Array & >::push(arr.GetVM(), arr);
// Attempt to extract the values from the given array
return JArray(SqToJSON(arr.GetVM(), -1), false);
}
// ------------------------------------------------------------------------------------------------
JObject SqObjectToJSONObject(Object & obj)
{
// Make sure that the given object is not null
if (obj.IsNull())
{
return JObject(); // Nothing to add
}
// Remember the current stack size
const StackGuard sg(obj.GetVM());
// Push our object onto the stack
Var< Object & >::push(obj.GetVM(), obj);
// Attempt to extract the values from the given object
return JObject(SqToJSON(obj.GetVM(), -1), false);
}
// ------------------------------------------------------------------------------------------------
JValue SqValueToJSONValue(Object & obj)
{
// Make sure that the given object is not null
if (obj.IsNull())
{
return JValue(); // Nothing to add
}
// Remember the current stack size
const StackGuard sg(obj.GetVM());
// Push our object onto the stack
Var< Object & >::push(obj.GetVM(), obj);
// Attempt to extract the values from the given object
return JValue(SqToJSON(obj.GetVM(), -1), false);
}
// ================================================================================================
void Register_Common(Table & jns)
{
jns.Func(_SC("FromTable"), &SqTableToJSONObject);
jns.Func(_SC("FromArray"), &SqArrayToJSONArray);
jns.Func(_SC("ToObject"), &SqObjectToJSONObject);
jns.Func(_SC("ToValue"), &SqValueToJSONValue);
}
} // Namespace:: SqMod

View File

@ -1,126 +0,0 @@
#ifndef _SQJSON_COMMON_HPP_
#define _SQJSON_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
#include <jansson.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQJSON_NAME "Squirrel JSON Module"
#define SQJSON_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQJSON_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQJSON_HOST_NAME "SqModJSONHost"
#define SQJSON_VERSION 001
#define SQJSON_VERSION_STR "0.0.1"
#define SQJSON_VERSION_MAJOR 0
#define SQJSON_VERSION_MINOR 0
#define SQJSON_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class JValue;
class JArray;
class JObject;
/* ------------------------------------------------------------------------------------------------
* Implements RAII to free the strings obtained from dumps even after exceptions.
*/
struct CStrGuard
{
// --------------------------------------------------------------------------------------------
CStr mPtr; // The managed pointer
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CStrGuard(CStr p)
: mPtr(p)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CStrGuard()
{
if (mPtr)
{
std::free(mPtr);
}
}
};
/* ------------------------------------------------------------------------------------------------
* Class that represents an error occurred while parsing JSON data.
*/
struct JError
{
public:
// --------------------------------------------------------------------------------------------
json_error_t mErr; // The managed error instance.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
JError();
};
/* ------------------------------------------------------------------------------------------------
* Retrieve the string representation of JSON value type.
*/
CSStr JSONTypeToStr(json_type type);
/* ------------------------------------------------------------------------------------------------
* Retrieve the string representation of JSON value type.
*/
inline CSStr JSONTypeStr(json_t * ptr)
{
return (ptr == nullptr) ? _SC("unknown") : JSONTypeToStr(json_typeof(ptr));
}
/* ------------------------------------------------------------------------------------------------
* Convert a script value from the stack to a JSON object.
*/
Object SqFromJSON(HSQUIRRELVM vm, json_t * jval);
/* ------------------------------------------------------------------------------------------------
* Convert a script value from the stack to a JSON object.
*/
json_t * SqToJSON(HSQUIRRELVM vm, SQInteger idx);
/* ------------------------------------------------------------------------------------------------
* Convert a script table to a JSON object.
*/
JObject SqTableToJSONObject(Table & obj);
/* ------------------------------------------------------------------------------------------------
* Convert a script array to a JSON array.
*/
JArray SqArrayToJSONArray(Array & obj);
/* ------------------------------------------------------------------------------------------------
* Convert a script object to a JSON object.
*/
JObject SqObjectToJSONObject(Object & obj);
/* ------------------------------------------------------------------------------------------------
* Convert a script value to a JSON value.
*/
JValue SqValueToJSONValue(Object & obj);
} // Namespace:: SqMod
#endif // _SQJSON_COMMON_HPP_

View File

@ -1,49 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "JArray.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
std::size_t JArray::s_Flags = JSON_ENCODE_ANY;
// ------------------------------------------------------------------------------------------------
SQInteger JArray::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqJSONArray");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Object JArray::ToString() const
{
// Dump the values to a string
const CStrGuard csg(json_dumps(m_Ptr, s_Flags));
// Remember the current stack size
const StackGuard sg;
// Transform the string into a script object
sq_pushstring(DefaultVM::Get(), csg.mPtr ? csg.mPtr : _SC(""), -1);
// Return the created script object
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ================================================================================================
void Register_JArray(Table & jns)
{
jns.Bind(_SC("Array"), Class< JArray >(jns.GetVM(), _SC("SqJSONArray"))
// Constructors
.Ctor()
.Ctor< const JArray & >()
// Core Meta-methods
.Func(_SC("_cmp"), &JArray::Cmp)
.SquirrelFunc(_SC("_typename"), &JArray::Typename)
.Func(_SC("_tostring"), &JArray::ToString)
// Properties
//.Prop(_SC("Prop"), &JArray::Prop)
// Member Methods
//.Func(_SC("Func"), &JArray::Func)
);
}
} // Namespace:: SqMod

View File

@ -1,201 +0,0 @@
#ifndef _SQJSON_ARRAY_HPP_
#define _SQJSON_ARRAY_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a JSON array.
*/
class JArray
{
public:
// --------------------------------------------------------------------------------------------
typedef json_t 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.
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; // Pointer to the managed array instance.
// --------------------------------------------------------------------------------------------
static std::size_t s_Flags; // Global flags used when dumping to a string.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (empty)
*/
JArray()
: m_Ptr(json_array())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JArray(Pointer ptr)
: m_Ptr(ptr)
{
if (json_is_array(m_Ptr))
{
json_incref(m_Ptr);
}
else
{
STHROWF("Expected JSON array got: %s", JSONTypeStr(m_Ptr));
}
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JArray(Pointer ptr, bool inc)
: m_Ptr(ptr)
{
if (json_is_array(m_Ptr))
{
if (inc)
{
json_incref(m_Ptr);
}
}
else
{
STHROWF("Expected JSON array got: %s", JSONTypeStr(m_Ptr));
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
JArray(const JArray & o)
: m_Ptr(json_incref(o.m_Ptr))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
JArray(JArray && o)
: m_Ptr(o.m_Ptr)
{
// Prevent further interaction
o.m_Ptr = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~JArray()
{
// Decrease the reference count of the managed object
json_decref(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
JArray & operator = (const JArray & o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Grab the reference of the new object
m_Ptr = json_incref(o.m_Ptr);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
JArray & operator = (JArray && o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Steal reference
m_Ptr = o.m_Ptr;
// Prevent further interaction
o.m_Ptr = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const JArray & o) const
{
if (json_equal(m_Ptr, o.m_Ptr))
{
return 0;
}
else if (m_Ptr > o.m_Ptr)
{
return 1;
}
else
{
return 0;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
Object ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is valid.
*/
bool IsValid() const
{
return (m_Ptr != nullptr);
}
};
} // Namespace:: SqMod
#endif // _SQJSON_ARRAY_HPP_

View File

@ -1,49 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "JObject.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
std::size_t JObject::s_Flags = JSON_ENCODE_ANY;
// ------------------------------------------------------------------------------------------------
SQInteger JObject::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqJSONObject");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Object JObject::ToString() const
{
// Dump the values to a string
const CStrGuard csg(json_dumps(m_Ptr, s_Flags));
// Remember the current stack size
const StackGuard sg;
// Transform the string into a script object
sq_pushstring(DefaultVM::Get(), csg.mPtr ? csg.mPtr : _SC(""), -1);
// Return the created script object
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ================================================================================================
void Register_JObject(Table & jns)
{
jns.Bind(_SC("Object"), Class< JObject >(jns.GetVM(), _SC("SqJSONObject"))
// Constructors
.Ctor()
.Ctor< const JObject & >()
// Core Meta-methods
.Func(_SC("_cmp"), &JObject::Cmp)
.SquirrelFunc(_SC("_typename"), &JObject::Typename)
.Func(_SC("_tostring"), &JObject::ToString)
// Properties
//.Prop(_SC("Prop"), &JObject::Prop)
// Member Methods
//.Func(_SC("Func"), &JObject::Func)
);
}
} // Namespace:: SqMod

View File

@ -1,201 +0,0 @@
#ifndef _SQJSON_JOBJECT_HPP_
#define _SQJSON_JOBJECT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a JSON object.
*/
class JObject
{
public:
// --------------------------------------------------------------------------------------------
typedef json_t 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.
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; // Pointer to the managed object instance.
// --------------------------------------------------------------------------------------------
static std::size_t s_Flags; // Global flags used when dumping to a string.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (empty)
*/
JObject()
: m_Ptr(json_object())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JObject(Pointer ptr)
: m_Ptr(ptr)
{
if (json_is_object(m_Ptr))
{
json_incref(m_Ptr);
}
else
{
STHROWF("Expected JSON object got: %s", JSONTypeStr(m_Ptr));
}
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JObject(Pointer ptr, bool inc)
: m_Ptr(ptr)
{
if (json_is_object(m_Ptr))
{
if (inc)
{
json_incref(m_Ptr);
}
}
else
{
STHROWF("Expected JSON object got: %s", JSONTypeStr(m_Ptr));
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
JObject(const JObject & o)
: m_Ptr(json_incref(o.m_Ptr))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
JObject(JObject && o)
: m_Ptr(o.m_Ptr)
{
// Prevent further interaction
o.m_Ptr = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~JObject()
{
// Release the managed object
json_decref(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
JObject & operator = (const JObject & o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Grab the reference of the new object
m_Ptr = json_incref(o.m_Ptr);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
JObject & operator = (JObject && o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Steal reference
m_Ptr = o.m_Ptr;
// Prevent further interaction
o.m_Ptr = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const JObject & o) const
{
if (json_equal(m_Ptr, o.m_Ptr))
{
return 0;
}
else if (m_Ptr > o.m_Ptr)
{
return 1;
}
else
{
return 0;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
Object ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is valid.
*/
bool IsValid() const
{
return (m_Ptr != nullptr);
}
};
} // Namespace:: SqMod
#endif // _SQJSON_JOBJECT_HPP_

View File

@ -1,65 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "JValue.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
std::size_t JValue::s_Flags = JSON_ENCODE_ANY;
// ------------------------------------------------------------------------------------------------
SQInteger JValue::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqJSONValue");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Object JValue::ToString() const
{
// Dump the values to a string
const CStrGuard csg(json_dumps(m_Ptr, s_Flags));
// Remember the current stack size
const StackGuard sg;
// Transform the string into a script object
sq_pushstring(DefaultVM::Get(), csg.mPtr ? csg.mPtr : _SC(""), -1);
// Return the created script object
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object JValue::GetValue() const
{
return Object();
}
// ================================================================================================
void Register_JValue(Table & jns)
{
jns.Bind(_SC("Value"), Class< JValue >(jns.GetVM(), _SC("SqJSONValue"))
// Constructors
.Ctor()
.Ctor< const JValue & >()
// Core Meta-methods
.Func(_SC("_cmp"), &JValue::Cmp)
.SquirrelFunc(_SC("_typename"), &JValue::Typename)
.Func(_SC("_tostring"), &JValue::ToString)
// Properties
.Prop(_SC("IsObject"), &JValue::IsObject)
.Prop(_SC("IsArray"), &JValue::IsArray)
.Prop(_SC("IsString"), &JValue::IsString)
.Prop(_SC("IsInteger"), &JValue::IsInteger)
.Prop(_SC("IsReal"), &JValue::IsReal)
.Prop(_SC("IsNumber"), &JValue::IsNumber)
.Prop(_SC("IsTrue"), &JValue::IsTrue)
.Prop(_SC("IsFalse"), &JValue::IsFalse)
.Prop(_SC("IsBoolean"), &JValue::IsBoolean)
.Prop(_SC("IsNull"), &JValue::IsNull)
.Prop(_SC("Value"), &JValue::GetValue)
// Member Methods
//.Func(_SC("Func"), &JValue::Func)
);
}
} // Namespace:: SqMod

View File

@ -1,340 +0,0 @@
#ifndef _SQJSON_JVALUE_HPP_
#define _SQJSON_JVALUE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a JSON value.
*/
class JValue
{
public:
// --------------------------------------------------------------------------------------------
typedef json_t 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.
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; // Pointer to the managed value instance.
// --------------------------------------------------------------------------------------------
static std::size_t s_Flags; // Global flags used when dumping to a string.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
JValue()
: m_Ptr(json_null())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JValue(Pointer ptr)
: m_Ptr(json_incref(ptr))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Pointer constructor.
*/
JValue(Pointer ptr, bool inc)
: m_Ptr(inc ? json_incref(ptr) : ptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Null pointer constructor.
*/
JValue(std::nullptr_t)
: m_Ptr(json_null())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Boolean constructor.
*/
JValue(bool val)
: m_Ptr(json_boolean(val))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* String constructor.
*/
JValue(CSStr val, bool check = true)
: m_Ptr(check ? json_string(val) : json_string_nocheck(val))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* String constructor.
*/
JValue(CSStr val, std::size_t len, bool check = true)
: m_Ptr(check ? json_stringn(val, len) : json_stringn_nocheck(val,len))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* 32 bit signed integer constructor.
*/
JValue(Int32 val)
: m_Ptr(json_integer(ConvTo< json_int_t >::From(val)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* 64 bit signed integer constructor.
*/
JValue(Int64 val)
: m_Ptr(json_integer(ConvTo< json_int_t >::From(val)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* 32 bit floating point number constructor.
*/
JValue(Float32 val)
: m_Ptr(json_real(val))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* 64 bit floating point number constructor.
*/
JValue(Float64 val)
: m_Ptr(json_real(val))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
JValue(const JValue & o)
: m_Ptr(json_incref(o.m_Ptr))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
JValue(JValue && o)
: m_Ptr(o.m_Ptr)
{
// Prevent further interaction
o.m_Ptr = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~JValue()
{
// Decrease the reference count of the managed value
json_decref(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
JValue & operator = (const JValue & o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Grab the reference of the new object
m_Ptr = json_incref(o.m_Ptr);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
JValue & operator = (JValue && o)
{
// Avoid self assignment
if (m_Ptr != o.m_Ptr)
{
// Release the current object
json_decref(m_Ptr);
// Steal reference
m_Ptr = o.m_Ptr;
// Prevent further interaction
o.m_Ptr = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const JValue & o) const
{
if (json_equal(m_Ptr, o.m_Ptr))
{
return 0;
}
else if (m_Ptr > o.m_Ptr)
{
return 1;
}
else
{
return 0;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
Object ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed JSON value.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is valid.
*/
bool IsValid() const
{
return (m_Ptr != nullptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is object.
*/
bool IsObject() const
{
return json_is_object(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is array.
*/
bool IsArray() const
{
return json_is_array(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is string.
*/
bool IsString() const
{
return json_is_string(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is integer.
*/
bool IsInteger() const
{
return json_is_integer(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is real number.
*/
bool IsReal() const
{
return json_is_real(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is number.
*/
bool IsNumber() const
{
return json_is_number(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is boolean true.
*/
bool IsTrue() const
{
return json_is_true(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is boolean false.
*/
bool IsFalse() const
{
return json_is_false(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is boolean.
*/
bool IsBoolean() const
{
return json_is_boolean(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* See whether the managed value is null.
*/
bool IsNull() const
{
return json_is_null(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the script equivalent of the managed value.
*/
Object GetValue() const;
};
} // Namespace:: SqMod
#endif // _SQJSON_JVALUE_HPP_

View File

@ -1,15 +0,0 @@
/* ------------------------------------------------------------------------------------------------
* Include the entire library into a single C source so it can be compiled at the same time.
*/
#include "dump.c"
#include "error.c"
#include "hashtable.c"
#include "hashtable_seed.c"
#include "load.c"
#include "memory.c"
#include "pack_unpack.c"
#include "strbuffer.c"
#include "strconv.c"
#include "utf.c"
#include "value.c"

View File

@ -1,225 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Common(Table & jns);
extern void Register_JArray(Table & jns);
extern void Register_JObject(Table & jns);
extern void Register_JValue(Table & jns);
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQJSON_NAME);
// Registration failed
return false;
}
Table jns(vm);
Register_Common(jns);
Register_JArray(jns);
Register_JObject(jns);
Register_JValue(jns);
RootTable(vm).Bind(_SC("SqJSON"), jns);
Sqrat::ConstTable(vm)
.Const(_SC("JSON_OBJECT"), JSON_OBJECT)
.Const(_SC("JSON_ARRAY"), JSON_ARRAY)
.Const(_SC("JSON_STRING"), JSON_STRING)
.Const(_SC("JSON_INTEGER"), JSON_INTEGER)
.Const(_SC("JSON_REAL"), JSON_REAL)
.Const(_SC("JSON_TRUE"), JSON_TRUE)
.Const(_SC("JSON_FALSE"), JSON_FALSE)
.Const(_SC("JSON_NULL"), JSON_NULL);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQJSON_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQJSON_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQJSON_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQJSON_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQJSON_NAME))
{
try
{
ImportModuleAPI(_Func, SQJSON_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
std::puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQJSON_NAME);
OutputMessage("Author: %s", SQJSON_AUTHOR);
OutputMessage("Legal: %s", SQJSON_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
std::puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQJSON_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQJSON_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQJSON_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQJSON_NAME);
// Dummy spacing
std::puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,452 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
// N[0] - contains least significant bits, N[3] - most significant
static SQChar * Bin128ToDec(const Uint32 N[4])
{
// log10(x) = log2(x) / log2(10) ~= log2(x) / 3.322
static SQChar s[128 / 3 + 1 + 1];
Uint32 n[4];
SQChar * p = s;
int i;
std::memset(s, '0', sizeof(s) - 1);
s[sizeof(s) - 1] = '\0';
std::memcpy(n, N, sizeof(n));
for (i = 0; i < 128; i++)
{
int j, carry;
carry = (n[3] >= 0x80000000);
// Shift n[] left, doubling it
n[3] = ((n[3] << 1) & 0xFFFFFFFF) + (n[2] >= 0x80000000);
n[2] = ((n[2] << 1) & 0xFFFFFFFF) + (n[1] >= 0x80000000);
n[1] = ((n[1] << 1) & 0xFFFFFFFF) + (n[0] >= 0x80000000);
n[0] = ((n[0] << 1) & 0xFFFFFFFF);
// Add s[] to itself in decimal, doubling it
for (j = sizeof(s) - 2; j >= 0; j--)
{
s[j] += s[j] - '0' + carry;
carry = (s[j] > '9');
if (carry)
{
s[j] -= 10;
}
}
}
while ((p[0] == '0') && (p < &s[sizeof(s) - 2]))
{
p++;
}
return p;
}
// ------------------------------------------------------------------------------------------------
CSStr AsTypeStr(Uint32 id)
{
switch (id)
{
case MMDB_DATA_TYPE_EXTENDED: return _SC("extended");
case MMDB_DATA_TYPE_POINTER: return _SC("pointer");
case MMDB_DATA_TYPE_UTF8_STRING: return _SC("string");
case MMDB_DATA_TYPE_DOUBLE: return _SC("double");
case MMDB_DATA_TYPE_BYTES: return _SC("bytes");
case MMDB_DATA_TYPE_UINT16: return _SC("uint16");
case MMDB_DATA_TYPE_UINT32: return _SC("uint32");
case MMDB_DATA_TYPE_MAP: return _SC("map");
case MMDB_DATA_TYPE_INT32: return _SC("int32");
case MMDB_DATA_TYPE_UINT64: return _SC("uint64");
case MMDB_DATA_TYPE_UINT128: return _SC("uint128");
case MMDB_DATA_TYPE_ARRAY: return _SC("array");
case MMDB_DATA_TYPE_CONTAINER: return _SC("container");
case MMDB_DATA_TYPE_END_MARKER: return _SC("endmarker");
case MMDB_DATA_TYPE_BOOLEAN: return _SC("boolean");
case MMDB_DATA_TYPE_FLOAT: return _SC("float");
default: return _SC("unknonw");
}
}
// ------------------------------------------------------------------------------------------------
bool GetEntryAsBool(const MMDB_entry_data_s & ed)
{
bool value = false;
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
value = ed.pointer > 0;
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
if (ed.data_size > 0)
{
value = ConvTo< bool >::From(reinterpret_cast< CSStr >(ed.utf8_string));
}
} break;
case MMDB_DATA_TYPE_DOUBLE: {
value = ConvTo< bool >::From(ed.double_value);
} break;
case MMDB_DATA_TYPE_BYTES: {
for (Uint32 i = 0; i < ed.data_size; ++i)
{
if (ed.bytes[i] != 0)
{
value = true;
// Found somethinf that isn't 0
break;
}
}
} break;
case MMDB_DATA_TYPE_UINT16: {
value = ConvTo< bool >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT32: {
value = ConvTo< bool >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_INT32: {
value = ConvTo< bool >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT64: {
value = ConvTo< bool >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT128: {
#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
for (Uint32 i = 0; i < sizeof(ed.uint128); ++i)
{
if (ed.uint128[i] != 0)
{
value = true;
// Found somethinf that isn't 0
break;
}
}
#else
value = ed.uint128 > 0;
#endif // MMDB_UINT128_IS_BYTE_ARRAY
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
value = ed.boolean ? true : false;
} break;
case MMDB_DATA_TYPE_FLOAT: {
value = ConvTo< bool >::From(ed.float_value);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (boolean)", AsTypeStr(ed.type));
}
// Return the extracted value
return value;
}
// ------------------------------------------------------------------------------------------------
SQInteger GetEntryAsInteger(const MMDB_entry_data_s & ed)
{
SQInteger value = 0;
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
value = static_cast< SQInteger >(ed.pointer);
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
if (ed.data_size > 0)
{
value = ConvTo< SQInteger >::From(reinterpret_cast< CSStr >(ed.utf8_string));
}
} break;
case MMDB_DATA_TYPE_DOUBLE: {
value = ConvTo< SQInteger >::From(ed.double_value);
} break;
case MMDB_DATA_TYPE_BYTES: {
std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
} break;
case MMDB_DATA_TYPE_UINT16: {
value = ConvTo< SQInteger >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT32: {
value = ConvTo< SQInteger >::From(ed.uint32);
} break;
case MMDB_DATA_TYPE_INT32: {
value = ConvTo< SQInteger >::From(ed.int32);
} break;
case MMDB_DATA_TYPE_UINT64: {
value = ConvTo< SQInteger >::From(ed.uint64);
} break;
case MMDB_DATA_TYPE_UINT128: {
#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
std::memcpy(&value, ed.uint128, sizeof(value));
#else
std::memcpy(&value, &ed.uint128, sizeof(value));
#endif // MMDB_UINT128_IS_BYTE_ARRAY
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
value = ed.boolean ? 1 : 0;
} break;
case MMDB_DATA_TYPE_FLOAT: {
value = ConvTo< SQInteger >::From(ed.float_value);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (integer)", AsTypeStr(ed.type));
}
// Return the extracted value
return value;
}
// ------------------------------------------------------------------------------------------------
SQFloat GetEntryAsFloat(const MMDB_entry_data_s & ed)
{
SQFloat value = 0.0;
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
value = ConvTo< SQFloat >::From(static_cast< SQInteger >(ed.pointer));
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
if (ed.data_size > 0)
{
value = ConvTo< SQFloat >::From(reinterpret_cast< CSStr >(ed.utf8_string));
}
} break;
case MMDB_DATA_TYPE_DOUBLE: {
value = ConvTo< SQFloat >::From(ed.double_value);
} break;
case MMDB_DATA_TYPE_BYTES: {
// Not our problem if the result will be junk!
std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
} break;
case MMDB_DATA_TYPE_UINT16: {
value = ConvTo< SQFloat >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT32: {
value = ConvTo< SQFloat >::From(ed.uint32);
} break;
case MMDB_DATA_TYPE_INT32: {
value = ConvTo< SQFloat >::From(ed.int32);
} break;
case MMDB_DATA_TYPE_UINT64: {
value = ConvTo< SQFloat >::From(ed.uint64);
} break;
case MMDB_DATA_TYPE_UINT128: {
SQInteger num;
// Convert to integer first
#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
std::memcpy(&num, ed.uint128, sizeof(num));
#else
std::memcpy(&num, &ed.uint128, sizeof(num));
#endif // MMDB_UINT128_IS_BYTE_ARRAY
// Now convert to float
value = ConvTo< SQFloat >::From(num);
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
value = ed.boolean ? 1.0 : 0.0;
} break;
case MMDB_DATA_TYPE_FLOAT: {
value = ConvTo< SQFloat >::From(ed.float_value);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (float)", AsTypeStr(ed.type));
}
// Return the extracted value
return value;
}
// ------------------------------------------------------------------------------------------------
Object GetEntryAsLong(const MMDB_entry_data_s & ed)
{
Uint64 value = 0;
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
value = static_cast< Uint64 >(ed.pointer);
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
if (ed.data_size > 0)
{
value = ConvTo< Uint64 >::From(reinterpret_cast< CSStr >(ed.utf8_string));
}
} break;
case MMDB_DATA_TYPE_DOUBLE: {
value = ConvTo< Uint64 >::From(ed.double_value);
} break;
case MMDB_DATA_TYPE_BYTES: {
std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
} break;
case MMDB_DATA_TYPE_UINT16: {
value = ConvTo< Uint64 >::From(ed.uint16);
} break;
case MMDB_DATA_TYPE_UINT32: {
value = ConvTo< Uint64 >::From(ed.uint32);
} break;
case MMDB_DATA_TYPE_INT32: {
value = ConvTo< Uint64 >::From(ed.int32);
} break;
case MMDB_DATA_TYPE_UINT64: {
value = ConvTo< Uint64 >::From(ed.uint64);
} break;
case MMDB_DATA_TYPE_UINT128: {
#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
std::memcpy(&value, ed.uint128, sizeof(value));
#else
std::memcpy(&value, &ed.uint128, sizeof(value));
#endif // MMDB_UINT128_IS_BYTE_ARRAY
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
value = ed.boolean ? 1 : 0;
} break;
case MMDB_DATA_TYPE_FLOAT: {
value = ConvTo< Uint64 >::From(ed.float_value);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (long)", AsTypeStr(ed.type));
}
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), value);
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object GetEntryAsString(const MMDB_entry_data_s & ed)
{
// Obtain the initial stack size
const StackGuard sg;
// The default vm
HSQUIRRELVM vm = DefaultVM::Get();
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
sq_pushstring(vm, ToStrF("%p", ed.pointer), -1);
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
sq_pushstring(vm, ed.utf8_string, ed.data_size);
} break;
case MMDB_DATA_TYPE_DOUBLE: {
sq_pushstring(vm, ToStrF("%f", ed.double_value), -1);
} break;
case MMDB_DATA_TYPE_BYTES: {
sq_pushstring(vm, reinterpret_cast< CSStr >(ed.bytes), ed.data_size / sizeof(SQChar));
} break;
case MMDB_DATA_TYPE_UINT16: {
sq_pushstring(vm, ToStrF("%u", ed.uint16), -1);
} break;
case MMDB_DATA_TYPE_UINT32: {
sq_pushstring(vm, ToStrF("%u", ed.uint32), -1);
} break;
case MMDB_DATA_TYPE_INT32: {
sq_pushstring(vm, ToStrF("%d", ed.int32), -1);
} break;
case MMDB_DATA_TYPE_UINT64: {
sq_pushstring(vm, ToStrF("%llu", ed.uint64), -1);
} break;
case MMDB_DATA_TYPE_UINT128: {
#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
sq_pushstring(vm, Bin128ToDec(reinterpret_cast< const Uint32 * >(ed.uint128)), -1);
#else
sq_pushstring(vm, Bin128ToDec(reinterpret_cast< const Uint32 * >(&ed.uint128)), -1);
#endif // MMDB_UINT128_IS_BYTE_ARRAY
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
sq_pushstring(vm, ed.boolean ? _SC("true") : _SC("false"), -1);
} break;
case MMDB_DATA_TYPE_FLOAT: {
sq_pushstring(vm, ToStrF("%f", ed.float_value), -1);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (string)", AsTypeStr(ed.type));
}
// Obtain the object from the stack and return it
return Var< Object >(vm, -1).value;
}
// ------------------------------------------------------------------------------------------------
Object GetEntryAsBytes(const MMDB_entry_data_s & ed)
{
// Obtain the initial stack size
const StackGuard sg;
// The result of operations
SQRESULT res = SQ_OK;
// The default vm
HSQUIRRELVM vm = DefaultVM::Get();
// Identify the type of entry data
switch (ed.type)
{
case MMDB_DATA_TYPE_POINTER: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.pointer), sizeof(ed.pointer), 0);
} break;
case MMDB_DATA_TYPE_UTF8_STRING: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(ed.utf8_string), ed.data_size, 0);
} break;
case MMDB_DATA_TYPE_DOUBLE: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.double_value), sizeof(ed.double_value), 0);
} break;
case MMDB_DATA_TYPE_BYTES: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(ed.bytes), ed.data_size, 0);
} break;
case MMDB_DATA_TYPE_UINT16: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.uint16), sizeof(ed.uint16), 0);
} break;
case MMDB_DATA_TYPE_UINT32: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.uint32), sizeof(ed.uint32), 0);
} break;
case MMDB_DATA_TYPE_INT32: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.int32), sizeof(ed.int32), 0);
} break;
case MMDB_DATA_TYPE_UINT64: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.uint64), sizeof(ed.uint64), 0);
} break;
case MMDB_DATA_TYPE_UINT128: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.uint128), sizeof(ed.uint128), 0);
} break;
case MMDB_DATA_TYPE_BOOLEAN: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.boolean), sizeof(ed.boolean), 0);
} break;
case MMDB_DATA_TYPE_FLOAT: {
res = SqMod_PushBufferData(vm,
reinterpret_cast< const char * >(&ed.float_value),
sizeof(ed.float_value), 0);
} break;
default:
STHROWF("Unsupported conversion from (%s) to (buffer)", AsTypeStr(ed.type));
}
// Did we fail to push the buffer o the stack?
if (SQ_FAILED(res))
{
STHROWF("Failed to convert the (%s) value to a buffer.", AsTypeStr(ed.type));
}
// Obtain the object from the stack and return it
return Var< Object >(vm, -1).value;
}
} // Namespace:: SqMod

View File

@ -1,100 +0,0 @@
#ifndef _SQMMDB_COMMON_HPP_
#define _SQMMDB_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <maxminddb.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQMMDB_NAME "Squirrel MaxmindDB Module"
#define SQMMDB_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQMMDB_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQMMDB_HOST_NAME "SqModMMDBHost"
#define SQMMDB_VERSION 001
#define SQMMDB_VERSION_STR "0.0.1"
#define SQMMDB_VERSION_MAJOR 0
#define SQMMDB_VERSION_MINOR 0
#define SQMMDB_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Handle validation.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
#define SQMOD_VALIDATE(x) (x).Validate(__FILE__, __LINE__)
#define SQMOD_GET_VALID(x) (x).GetValid(__FILE__, __LINE__)
#define SQMOD_GET_VALID_ELEM(x) (x).GetValidElem(__FILE__, __LINE__)
#define SQMOD_GET_VALID_DATA(x) (x).GetValidData(__FILE__, __LINE__)
#else
#define SQMOD_VALIDATE(x) (x).Validate()
#define SQMOD_GET_VALID(x) (x).GetValid()
#define SQMOD_GET_VALID_ELEM(x) (x).GetValidElem()
#define SQMOD_GET_VALID_DATA(x) (x).GetValidData()
#endif // _DEBUG
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class Database;
class Metadata;
class Description;
class SockAddr;
class EntryData;
class EntryDataList;
class LookupResult;
class SearchNode;
/* ------------------------------------------------------------------------------------------------
* Forward handle declarations.
*/
struct DbHnd;
/* ------------------------------------------------------------------------------------------------
* Common typedefs.
*/
typedef SharedPtr< DbHnd > DbRef;
/* ------------------------------------------------------------------------------------------------
* Used to retrieve the string representation of the specified type identifier.
*/
CSStr AsTypeStr(Uint32 id);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a boolean.
*/
bool GetEntryAsBool(const MMDB_entry_data_s & ed);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a native integer.
*/
SQInteger GetEntryAsInteger(const MMDB_entry_data_s & ed);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a floating point.
*/
SQFloat GetEntryAsFloat(const MMDB_entry_data_s & ed);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a long integer.
*/
Object GetEntryAsLong(const MMDB_entry_data_s & ed);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a string.
*/
Object GetEntryAsString(const MMDB_entry_data_s & ed);
/* ------------------------------------------------------------------------------------------------
* Retrieve the value from the specified entry data as a stream of bytes.
*/
Object GetEntryAsBytes(const MMDB_entry_data_s & ed);
} // Namespace:: SqMod
#endif // _SQMMDB_COMMON_HPP_

View File

@ -1,172 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Database.hpp"
#include "SockAddr.hpp"
#include "Metadata.hpp"
#include "SearchNode.hpp"
#include "LookupResult.hpp"
#include "EntryDataList.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Database::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMDatabase");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Database::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void Database::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const DbRef & Database::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const DbRef & Database::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Metadata Database::GetMetadata() const
{
return Metadata(m_Handle, &(SQMOD_GET_VALID(*this)->mDb).metadata);
}
// ------------------------------------------------------------------------------------------------
Object Database::GetMetadataAsEntryDataList() const
{
MMDB_entry_data_list_s * entry_data_list = nullptr;
// Attempt to retrieve the database meta-data as an entry data list
const int status = MMDB_get_metadata_as_entry_data_list(&(SQMOD_GET_VALID(*this)->mDb), &entry_data_list);
// Validate the status code
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get meta-data entry data list [%s]", MMDB_strerror(status));
}
// Return the resulted list
return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupString(CSStr addr)
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Validate the specified string
if (!addr || *addr == '\0')
{
STHROWF("Invalid address string");
}
// Dummy variables to obtain the status codes
int gai_error, mmdb_error;
// Attempt to perform the actual lookup
MMDB_lookup_result_s result = MMDB_lookup_string(&m_Handle->mDb, addr, &gai_error, &mmdb_error);
// Validate the result of the getaddrinfo() function call
if (gai_error != 0)
{
STHROWF("Unable to resolve address (%s) because [%s]", addr, gai_strerror(gai_error));
}
// Validate the lookup status code
else if (mmdb_error != MMDB_SUCCESS)
{
STHROWF("Unable to lookup address (%s) because [%s]", addr, MMDB_strerror(mmdb_error));
}
// Now it's safe to return the lookup result
return LookupResult(m_Handle, result);
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupSockAddr(SockAddr & addr)
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Validate the specified socket address
if (!addr.IsValid())
{
STHROWF("Invalid address instance");
}
// Dummy variable to obtain the status codes
int mmdb_error;
// Attempt to perform the actual lookup
MMDB_lookup_result_s result = MMDB_lookup_sockaddr(&m_Handle->mDb, addr.GetHandle()->ai_addr, &mmdb_error);
// Validate the lookup status code
if (mmdb_error != MMDB_SUCCESS)
{
STHROWF("Unable to lookup address (%s) because [%s]", addr.GetAddress(), MMDB_strerror(mmdb_error));
}
// Now it's safe to return the lookup result
return LookupResult(m_Handle, result);
}
// ------------------------------------------------------------------------------------------------
SearchNode Database::ReadNode(Uint32 node) const
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Prepare a temporary search node
MMDB_search_node_s search_node;
// Attempt to retrieve the requested node from the database
const int status = MMDB_read_node(&(SQMOD_GET_VALID(*this)->mDb), node, &search_node);
// Validate the status code
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get node [%s]", MMDB_strerror(status));
}
// Return the resulted list
return SearchNode(m_Handle, search_node);
}
// ================================================================================================
void Register_Database(Table & mmns)
{
mmns.Bind(_SC("Database"),
Class< Database >(mmns.GetVM(), _SC("SqMMDatabase"))
// Constructors
.Ctor()
.Ctor< CSStr >()
.Ctor< CSStr, Uint32 >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Database::Typename)
.Func(_SC("_tostring"), &Database::ToString)
// Properties
.Prop(_SC("IsValid"), &Database::IsValid)
.Prop(_SC("References"), &Database::GetRefCount)
.Prop(_SC("Metadata"), &Database::GetMetadata)
.Prop(_SC("MetadataAsEntryDataList"), &Database::GetMetadataAsEntryDataList)
// Member methods
.Func(_SC("Release"), &Database::Release)
.Func(_SC("LookupString"), &Database::LookupString)
.Func(_SC("LookupSockAddr"), &Database::LookupSockAddr)
.Func(_SC("ReadNode"), &Database::ReadNode)
// Member overloads
.Overload< void (Database::*)(CSStr) >(_SC("Open"), &Database::Open)
.Overload< void (Database::*)(CSStr, Uint32) >(_SC("Open"), &Database::Open)
);
}
} // Namespace:: SqMod

View File

@ -1,200 +0,0 @@
#ifndef _SQMMDB_DATABASE_HPP_
#define _SQMMDB_DATABASE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can be used to open and query information from MaxMind database files.
*/
class Database
{
public:
// --------------------------------------------------------------------------------------------
typedef DbHnd::Type 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif //
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const DbRef & GetValid(CCStr file, Int32 line) const;
#else
const DbRef & GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The managed database handle.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Database()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor. (default flags)
*/
Database(CSStr filepath)
: m_Handle(new DbHnd(filepath, 0))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
Database(CSStr filepath, Uint32 flags)
: m_Handle(new DbHnd(filepath, flags))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit handle constructor.
*/
Database(const DbRef & db)
: m_Handle(db)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Database(const Database & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Database(Database && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Database & operator = (const Database & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Database & operator = (Database && o) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Handle ? m_Handle->mDb.filename : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database instance.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release()
{
m_Handle.Reset();
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(CSStr filepath)
{
Open(filepath, 0);
}
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(CSStr filepath, Uint32 flags)
{
// Make sure there isn't another database handle
if (!m_Handle)
{
m_Handle = DbRef(new DbHnd(filepath, flags));
}
else
{
STHROWF("Loading is disabled while database is referenced");
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve the metadata associated with the managed database handle.
*/
Metadata GetMetadata() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the metadata associated with the managed database handle as an entry data list.
*/
Object GetMetadataAsEntryDataList() const;
/* --------------------------------------------------------------------------------------------
* Look up an IP address that is passed in as a null-terminated string.
*/
LookupResult LookupString(CSStr addr);
/* --------------------------------------------------------------------------------------------
* Looks up an IP address that has already been resolved by getaddrinfo().
*/
LookupResult LookupSockAddr(SockAddr & sockaddr);
/* --------------------------------------------------------------------------------------------
* Retrieve a speciffic node from the managed database.
*/
SearchNode ReadNode(Uint32 node) const;
};
} // Namespace:: SqMod
#endif // _SQMMDB_DATABASE_HPP_

View File

@ -1,94 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Description.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Description::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMDescription");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Description::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void Description::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Description::Pointer Description::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
// Validate the referenced description
if (!m_Description)
{
SqThrowF("Invalid Maxmind meta-data description reference =>[%s:%d]", file, line);
}
// Return the description pointer
return m_Description;
}
#else
Description::Pointer Description::GetValid() const
{
Validate();
// Validate the referenced description
if (!m_Description)
{
SqThrowF("Invalid Maxmind meta-data description reference");
}
// Return the description pointer
return m_Description;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Database Description::GetDatabase() const
{
return Database(m_Handle);
}
// ================================================================================================
void Register_Description(Table & mmns)
{
mmns.Bind(_SC("Description"),
Class< Description >(mmns.GetVM(), _SC("SqMMDescription"))
// Constructors
.Ctor()
.Ctor< const Description & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Description::Typename)
.Func(_SC("_tostring"), &Description::ToString)
// Properties
.Prop(_SC("IsValid"), &Description::IsValid)
.Prop(_SC("Database"), &Description::GetDatabase)
.Prop(_SC("References"), &Description::GetRefCount)
.Prop(_SC("Value"), &Description::GetDescriptionValue)
.Prop(_SC("Language"), &Description::GetDescriptionLanguage)
// Member methods
.Func(_SC("Release"), &Description::Release)
);
}
} // Namespace:: SqMod

View File

@ -1,157 +0,0 @@
#ifndef _SQMMDB_DESCRIPTION_HPP_
#define _SQMMDB_DESCRIPTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used inspect meta-data descriptions.
*/
class Description
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_description_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and description pointer and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Pointer GetValid(CCStr file, Int32 line) const;
#else
Pointer GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database associated with this meta-data description.
Pointer m_Description; // The inspected meta-data description structure.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Description()
: m_Handle(), m_Description(nullptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct and with a specific meta-data description.
*/
Description(const DbRef & db, Pointer description)
: m_Handle(db), m_Description(description)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Description(const Description &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Description(Description &&) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Description & operator = (const Description &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Description & operator = (Description &&) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Description ? m_Description->description : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and description structure.
*/
bool IsValid() const
{
return m_Handle; // If there's a database handle then there's a description too
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release()
{
m_Handle.Reset();
m_Description = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value of the managed description handle.
*/
CSStr GetDescriptionValue() const
{
return SQMOD_GET_VALID(*this)->description;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the language of the managed description handle.
*/
CSStr GetDescriptionLanguage() const
{
return SQMOD_GET_VALID(*this)->language;
}
};
} // Namespace:: SqMod
#endif // _SQMMDB_DESCRIPTION_HPP_

View File

@ -1,117 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "EntryData.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger EntryData::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMEntryData");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void EntryData::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void EntryData::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
EntryData::ConstRef EntryData::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
// See if the entry has any data
if (!m_Entry.has_data)
{
SqThrowF("The referenced entry has no data =>[%s:%d]", file, line);
}
// Return the entry
return m_Entry;
}
#else
EntryData::ConstRef EntryData::GetValid() const
{
Validate();
// See if the entry has any data
if (!m_Entry.has_data)
{
SqThrowF("The referenced entry has no data");
}
// Return the entry
return m_Entry;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
EntryData::EntryData()
: m_Handle(), m_Entry()
{
std::memset(&m_Entry, 0, sizeof(Type));
}
// ------------------------------------------------------------------------------------------------
void EntryData::Release()
{
std::memset(&m_Entry, 0, sizeof(Type));
m_Handle.Reset();
}
// ------------------------------------------------------------------------------------------------
Database EntryData::GetDatabase() const
{
return Database(m_Handle);
}
// ================================================================================================
void Register_EntryData(Table & mmns)
{
mmns.Bind(_SC("EntryData"),
Class< EntryData >(mmns.GetVM(), _SC("SqMMEntryData"))
// Constructors
.Ctor()
.Ctor< const EntryData & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &EntryData::Typename)
.Func(_SC("_tostring"), &EntryData::ToString)
// Properties
.Prop(_SC("IsValid"), &EntryData::IsValid)
.Prop(_SC("Database"), &EntryData::GetDatabase)
.Prop(_SC("References"), &EntryData::GetRefCount)
.Prop(_SC("TypeName"), &EntryData::TypeName)
.Prop(_SC("HasData"), &EntryData::HasData)
.Prop(_SC("Type"), &EntryData::GetType)
.Prop(_SC("Offset"), &EntryData::GetOffset)
.Prop(_SC("DataSize"), &EntryData::DataSize)
.Prop(_SC("String"), &EntryData::GetString)
.Prop(_SC("Integer"), &EntryData::GetInteger)
.Prop(_SC("Float"), &EntryData::GetFloat)
.Prop(_SC("Long"), &EntryData::GetLong)
.Prop(_SC("Bool"), &EntryData::GetBool)
.Prop(_SC("Bytes"), &EntryData::GetBytes)
// Member methods
.Func(_SC("Release"), &EntryData::Release)
);
}
} // Namespace:: SqMod

View File

@ -1,223 +0,0 @@
#ifndef _SQMMDB_ENTRYDATA_HPP_
#define _SQMMDB_ENTRYDATA_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used to inspect entry data values.
*/
class EntryData
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_entry_data_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
ConstRef GetValid(CCStr file, Int32 line) const;
#else
ConstRef GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database from which this result comes from.
Type m_Entry; // The managed entry-data structure.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
EntryData();
/* --------------------------------------------------------------------------------------------
* Construct and take ownership of a certain entry data.
*/
EntryData(const DbRef & db, Reference entry)
: m_Handle(db), m_Entry(entry)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
EntryData(const EntryData &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
EntryData(EntryData &&) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
EntryData & operator = (const EntryData &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
EntryData & operator = (EntryData &&) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return AsTypeStr(m_Entry.type);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and entry structure.
*/
bool IsValid() const
{
return m_Handle && m_Entry.has_data;
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release();
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Used to retrieve the type of the current element as a string.
*/
CSStr TypeName() const
{
// Validate the handle
SQMOD_VALIDATE(*this);
// Return the requested information
return AsTypeStr(m_Entry.type);
}
/* --------------------------------------------------------------------------------------------
* See whether a valid element is currently processed.
*/
bool HasData() const
{
return ConvTo< bool >::From(SQMOD_GET_VALID(*this).has_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the type identifier of the current element.
*/
SQInteger GetType() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this).type);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the offset of the current element.
*/
SQInteger GetOffset() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this).offset);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the offset of the next element.
*/
SQInteger DataSize() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this).data_size);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a boolean.
*/
bool GetBool() const
{
return GetEntryAsBool(SQMOD_GET_VALID(*this));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a native integer.
*/
SQInteger GetInteger() const
{
return GetEntryAsInteger(SQMOD_GET_VALID(*this));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a floating point.
*/
SQFloat GetFloat() const
{
return GetEntryAsFloat(SQMOD_GET_VALID(*this));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a long integer.
*/
Object GetLong() const
{
return GetEntryAsLong(SQMOD_GET_VALID(*this));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a string.
*/
Object GetString() const
{
return GetEntryAsString(SQMOD_GET_VALID(*this));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a stream of bytes.
*/
Object GetBytes() const
{
return GetEntryAsBytes(SQMOD_GET_VALID(*this));
}
};
} // Namespace:: SqMod
#endif // _SQMMDB_ENTRYDATA_HPP_

View File

@ -1,207 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "EntryDataList.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger EntryDataList::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMEntryDataList");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void EntryDataList::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void EntryDataList::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
EntryDataList::Pointer EntryDataList::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
// Validate the managed list
if (!m_List)
{
SqThrowF("Invalid Maxmind entry data list reference =>[%s:%d]", file, line);
}
// return the list
return m_List;
}
#else
EntryDataList::Pointer EntryDataList::GetValid() const
{
Validate();
// Validate the managed list
if (!m_List)
{
SqThrowF("Invalid Maxmind entry data list reference");
}
// return the list
return m_List;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
EntryDataList::Pointer EntryDataList::GetValidElem(CCStr file, Int32 line) const
{
Validate(file, line);
// Validate the current element
if (!m_List)
{
SqThrowF("Invalid Maxmind entry data element reference =>[%s:%d]", file, line);
}
// return the element
return m_Elem;
}
#else
EntryDataList::Pointer EntryDataList::GetValidElem() const
{
Validate();
// Validate the current element
if (!m_List)
{
SqThrowF("Invalid Maxmind entry data element reference");
}
// return the element
return m_Elem;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Database EntryDataList::GetDatabase() const
{
return Database(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Uint32 EntryDataList::GetCount() const
{
// Prepare a counter
Uint32 count = 0;
// Do we even have a list?
if (m_List)
{
for (Pointer elem = m_List; elem; elem = elem->next)
{
++count;
}
}
// Return the counter
return count;
}
// ------------------------------------------------------------------------------------------------
bool EntryDataList::Next()
{
// Attempt to fetch the next element
m_Elem = SQMOD_GET_VALID(*this) ? m_Elem->next : nullptr;
// Return whether we have a valid element
return (m_Elem != nullptr);
}
// ------------------------------------------------------------------------------------------------
bool EntryDataList::Advance(SQInteger n)
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Attempt to skip as many elements as possible
while (n && m_Elem)
{
// Fetch the next element
m_Elem = m_Elem->next;
// Decrease the counter
--n;
}
// Return whether we have a valid element
return m_Elem;
}
// ------------------------------------------------------------------------------------------------
void EntryDataList::DumpTo(CSStr filepath, Int32 indent) const
{
// Validate the database and list handle
Pointer ptr = SQMOD_GET_VALID(*this);
// Validate the specified file path
if (!filepath || *filepath == '\0')
{
STHROWF("Invalid file path");
}
// Attempt to open the specified file
FILE * fp = fopen(filepath, "w");
// Validate the file handle
if (!fp)
{
STHROWF("Unable to open file %s", filepath);
}
// Attempt to dump the entry data list
Int32 status = MMDB_dump_entry_data_list(fp, ptr, indent);
// Close the file handle
fclose(fp);
// Validate the result of the operation
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to dump the list [%s]", MMDB_strerror(status));
}
}
// ================================================================================================
void Register_EntryDataList(Table & mmns)
{
mmns.Bind(_SC("EntryDataList"),
Class< EntryDataList, NoCopy< EntryDataList > >(mmns.GetVM(), _SC("SqMMEntryDataList"))
// Constructors
.Ctor()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &EntryDataList::Typename)
.Func(_SC("_tostring"), &EntryDataList::ToString)
// Properties
.Prop(_SC("IsValid"), &EntryDataList::IsValid)
.Prop(_SC("Database"), &EntryDataList::GetDatabase)
.Prop(_SC("References"), &EntryDataList::GetRefCount)
.Prop(_SC("HaveElement"), &EntryDataList::HaveElement)
.Prop(_SC("TypeName"), &EntryDataList::TypeName)
.Prop(_SC("Count"), &EntryDataList::GetCount)
.Prop(_SC("HasData"), &EntryDataList::HasData)
.Prop(_SC("Type"), &EntryDataList::GetType)
.Prop(_SC("Offset"), &EntryDataList::GetOffset)
.Prop(_SC("DataSize"), &EntryDataList::DataSize)
.Prop(_SC("String"), &EntryDataList::GetString)
.Prop(_SC("Integer"), &EntryDataList::GetInteger)
.Prop(_SC("Float"), &EntryDataList::GetFloat)
.Prop(_SC("Long"), &EntryDataList::GetLong)
.Prop(_SC("Bool"), &EntryDataList::GetBool)
.Prop(_SC("Bytes"), &EntryDataList::GetBytes)
// Member methods
.Func(_SC("Release"), &EntryDataList::Release)
.Func(_SC("Next"), &EntryDataList::Next)
.Func(_SC("Advance"), &EntryDataList::Advance)
.Func(_SC("Reset"), &EntryDataList::Reset)
// Member Overloads
.Overload< void (EntryDataList::*)(CSStr) const >(_SC("DumpTo"), &EntryDataList::DumpTo)
.Overload< void (EntryDataList::*)(CSStr, Int32) const >(_SC("DumpTo"), &EntryDataList::DumpTo)
);
}
} // Namespace:: SqMod

View File

@ -1,319 +0,0 @@
#ifndef _SQMMDB_ENTRYDATALIST_HPP_
#define _SQMMDB_ENTRYDATALIST_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used inspect database meta-data.
*/
class EntryDataList
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_entry_data_list_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Pointer GetValid(CCStr file, Int32 line) const;
#else
Pointer GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Pointer GetValidElem(CCStr file, Int32 line) const;
#else
Pointer GetValidElem() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database associated with this meta-data.
Pointer m_List; // The managed entry data list.
Pointer m_Elem; // The currently processed element from the list.
public:
/* --------------------------------------------------------------------------------------------
* Construct and with a specific entry list.
*/
EntryDataList(const DbRef & db, Pointer list)
: m_Handle(db), m_List(list), m_Elem(list)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
EntryDataList()
: m_Handle(), m_List(nullptr), m_Elem(nullptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
EntryDataList(const EntryDataList &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
EntryDataList(EntryDataList && o)
: m_Handle(o.m_Handle)
, m_List(o.m_List)
, m_Elem(o.m_Elem)
{
o.m_List = nullptr;
o.m_Elem = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~EntryDataList()
{
// Do we have to free any list?
if (m_List)
{
MMDB_free_entry_data_list(m_List);
}
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
EntryDataList & operator = (const EntryDataList &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
EntryDataList & operator = (EntryDataList && o)
{
if (m_List != o.m_List)
{
m_Handle = o.m_Handle;
m_List = o.m_List;
m_Elem = o.m_Elem;
o.m_List = nullptr;
o.m_Elem = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Elem ? AsTypeStr(m_Elem->entry_data.type) : _SC("invalid");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and element pointer.
*/
bool IsValid() const
{
return m_Handle && m_Elem;
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release()
{
m_Handle.Reset();
// Do we have to free any list?
if (m_List)
{
MMDB_free_entry_data_list(m_List);
}
// Finally, release those as well
m_List = nullptr;
m_Elem = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether a valid element is currently processed.
*/
bool HaveElement() const
{
return m_Elem;
}
/* --------------------------------------------------------------------------------------------
* Used to retrieve the type of the current element as a string.
*/
CSStr TypeName() const
{
return AsTypeStr(SQMOD_GET_VALID_ELEM(*this)->entry_data.type);
}
/* --------------------------------------------------------------------------------------------
* Return the total entries in the list.
*/
Uint32 GetCount() const;
/* --------------------------------------------------------------------------------------------
* Go to the next element.
*/
bool Next();
/* --------------------------------------------------------------------------------------------
* Advance a certain number of elements.
*/
bool Advance(SQInteger n);
/* --------------------------------------------------------------------------------------------
* Go back to the first element in the list.
*/
void Reset()
{
m_Elem = SQMOD_GET_VALID_ELEM(*this);
}
/* --------------------------------------------------------------------------------------------
* See whether a valid element is currently processed.
*/
bool HasData() const
{
return ConvTo< bool >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.has_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the type identifier of the current element.
*/
SQInteger GetType() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.type);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the offset of the current element.
*/
SQInteger GetOffset() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.offset);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the offset of the next element.
*/
SQInteger DataSize() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.data_size);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a boolean.
*/
bool GetBool() const
{
return GetEntryAsBool(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a native integer.
*/
SQInteger GetInteger() const
{
return GetEntryAsInteger(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a floating point.
*/
SQFloat GetFloat() const
{
return GetEntryAsFloat(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a long integer.
*/
Object GetLong() const
{
return GetEntryAsLong(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a string.
*/
Object GetString() const
{
return GetEntryAsString(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a stream of bytes.
*/
Object GetBytes() const
{
return GetEntryAsBytes(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Dumpt the contents of the list to the specified list.
*/
void DumpTo(CSStr filepath) const
{
DumpTo(filepath, 0);
}
/* --------------------------------------------------------------------------------------------
* Dumpt the contents of the list to the specified list.
*/
void DumpTo(CSStr filepath, Int32 indent) const;
};
} // Namespace:: SqMod
#endif // _SQMMDB_ENTRYDATALIST_HPP_

View File

@ -1,32 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
DbHnd::DbHnd(CSStr filepath, Uint32 flags)
: mDb()
{
// Validate the specified file path
if (!filepath || *filepath == '\0')
{
STHROWF("Invalid database file path");
}
// Let's attempt to open the specified database
const Int32 status = MMDB_open(filepath, flags, &mDb);
// Validate the result of the operation
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to open the specified database [%s]", MMDB_strerror(status));
}
}
// ------------------------------------------------------------------------------------------------
DbHnd::~DbHnd()
{
// We don't need the database handle anymore
MMDB_close(&mDb);
}
} // Namespace:: SqMod

View File

@ -1,69 +0,0 @@
#ifndef _SQMMDB_HANDLE_DATABASE_HPP_
#define _SQMMDB_HANDLE_DATABASE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted database instance.
*/
class DbHnd
{
// --------------------------------------------------------------------------------------------
friend class Database;
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_s 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.
public:
// --------------------------------------------------------------------------------------------
MMDB_s mDb; // The managed database handle.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DbHnd(CSStr filepath, Uint32 flags);
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
DbHnd(const DbHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
DbHnd(DbHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DbHnd();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
DbHnd & operator = (const DbHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
DbHnd & operator = (DbHnd && o) = delete;
};
} // Namespace:: SqMod
#endif // _SQMMDB_HANDLE_DATABASE_HPP_

View File

@ -1,200 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "LookupResult.hpp"
#include "EntryData.hpp"
#include "EntryDataList.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger LookupResult::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMLookupResult");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void LookupResult::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void LookupResult::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const DbRef & LookupResult::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const DbRef & LookupResult::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
LookupResult::LookupResult()
: m_Handle(), m_Result()
{
std::memset(&m_Result, 0, sizeof(Type));
}
// ------------------------------------------------------------------------------------------------
void LookupResult::Release()
{
std::memset(&m_Result, 0, sizeof(Type));
m_Handle.Reset();
}
// ------------------------------------------------------------------------------------------------
Database LookupResult::GetDatabase() const
{
return Database(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Object LookupResult::GetEntryDataList()
{
// See if there's an entry
if (!m_Result.found_entry)
{
STHROWF("Result does not have an entry");
}
MMDB_entry_data_list_s * entry_data_list = nullptr;
// Attempt to retrieve the entire entry data list at once
const int status = MMDB_get_entry_data_list(&m_Result.entry, &entry_data_list);
// Validate the status code
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get entry data list [%s]", MMDB_strerror(status));
}
// Return the resulted list
return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
SQInteger LookupResult::GetValue(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// The lookup result instance
LookupResult * lookup = nullptr;
// Attempt to extract the lookup result instance
try
{
lookup = Var< LookupResult * >(vm, 1).value;
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Do we have a valid lookup result instance?
if (!lookup)
{
return sq_throwerror(vm, "Invalid lookup result instance");
}
// See if there's a handle
else if (!lookup->m_Handle)
{
return sq_throwerror(vm, "Invalid Maxmind database reference");
}
// See if there's an entry
else if (!(lookup->m_Result.found_entry))
{
return sq_throwerror(vm, "Result does not have an entry");
}
typedef std::vector< StackStrF > ArgList;
// The list of extracted arguments
ArgList arglist;
// Extract each argument as a string
for (SQInteger i = 2; i <= top; ++i)
{
arglist.emplace_back(vm, i);
// Did we fail to extract the argument value?
if (SQ_FAILED(arglist.back().Proc(false)))
{
return arglist.back().mRes; // Propagate the error
}
}
typedef std::vector< CSStr > PtrList;
// The list of pointers to path segments
PtrList ptrlist;
// Grab the pointers to argument values
for (const auto & a : arglist)
{
ptrlist.push_back(a.mPtr);
}
// Push null to specify the end of the list
ptrlist.push_back(nullptr);
MMDB_entry_data_s entry_data;
// Attempt to retrieve the specified entry data
const int status = MMDB_aget_value(&(lookup->m_Result.entry), &entry_data, ptrlist.data());
// Validate the status code
if (status != MMDB_SUCCESS)
{
return sq_throwerror(vm, ToStrF("Unable to get entry data [%s]", MMDB_strerror(status)));
}
// Push the resulted list object onto the stack
try
{
ClassType< EntryData >::PushInstance(vm, new EntryData(lookup->m_Handle, entry_data));
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Specify that we returned a value
return 1;
}
// ================================================================================================
void Register_LookupResult(Table & mmns)
{
mmns.Bind(_SC("LookupResult"),
Class< LookupResult >(mmns.GetVM(), _SC("SqMMLookupResult"))
// Constructors
.Ctor()
.Ctor< const LookupResult & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &LookupResult::Typename)
.Func(_SC("_tostring"), &LookupResult::ToString)
// Properties
.Prop(_SC("IsValid"), &LookupResult::IsValid)
.Prop(_SC("Database"), &LookupResult::GetDatabase)
.Prop(_SC("References"), &LookupResult::GetRefCount)
.Prop(_SC("FoundEntry"), &LookupResult::FoundEntry)
.Prop(_SC("NetMask"), &LookupResult::GetNetMask)
.Prop(_SC("EntryDataList"), &LookupResult::GetEntryDataList)
// Member methods
.Func(_SC("Release"), &LookupResult::Release)
// Squirrel functions
.SquirrelFunc(_SC("GetValue"), &LookupResult::GetValue)
);
}
} // Namespace:: SqMod

View File

@ -1,164 +0,0 @@
#ifndef _SQMMDB_LOOKUPRESULT_HPP_
#define _SQMMDB_LOOKUPRESULT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used to work with lookup results.
*/
class LookupResult
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_lookup_result_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const DbRef & GetValid(CCStr file, Int32 line) const;
#else
const DbRef & GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database from which this result comes from.
Type m_Result; // The managed result structure.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
LookupResult();
/* --------------------------------------------------------------------------------------------
* Construct and take ownership of a certain result.
*/
LookupResult(const DbRef & db, Reference result)
: m_Handle(db), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
LookupResult(const LookupResult &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
LookupResult(LookupResult &&) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
LookupResult & operator = (const LookupResult &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
LookupResult & operator = (LookupResult &&) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return FmtStr("%u", m_Result.entry.offset);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and result structure.
*/
bool IsValid() const
{
return m_Handle && m_Result.found_entry;
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release();
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether the result contains a valid entry in the associated database.
*/
bool FoundEntry() const
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Return the requested information
return m_Result.found_entry;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the net-mask from the result structure.
*/
SQInteger GetNetMask() const
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Return the requested information
return static_cast< SQInteger >(m_Result.netmask);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the entire entry data list.
*/
Object GetEntryDataList();
/* --------------------------------------------------------------------------------------------
* Lookup data in the associated result using the specified path.
*/
static SQInteger GetValue(HSQUIRRELVM vm);
};
} // Namespace:: SqMod
#endif // _SQMMDB_LOOKUPRESULT_HPP_

View File

@ -1,118 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Metadata.hpp"
#include "Description.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Metadata::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMMetadata");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Metadata::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void Metadata::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Metadata::Pointer Metadata::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
// Validate the referenced meta-data
if (!m_Metadata)
{
SqThrowF("Invalid Maxmind meta-data reference =>[%s:%d]", file, line);
}
// Return the meta-data pointer
return m_Metadata;
}
#else
Metadata::Pointer Metadata::GetValid() const
{
Validate();
// Validate the referenced meta-data
if (!m_Metadata)
{
SqThrowF("Invalid Maxmind meta-data reference");
}
// Return the meta-data pointer
return m_Metadata;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Database Metadata::GetDatabase() const
{
return Database(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Description Metadata::GetDescriptionHandle(Uint32 idx) const
{
// Validate the specified index
if (idx > SQMOD_GET_VALID(*this)->description.count)
{
STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
}
// Return the requested description
return Description(m_Handle, m_Metadata->description.descriptions[idx]);
}
// ================================================================================================
void Register_Metadata(Table & mmns)
{
mmns.Bind(_SC("Metadata"),
Class< Metadata >(mmns.GetVM(), _SC("SqMMMetadata"))
// Constructors
.Ctor()
.Ctor< const Metadata & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Metadata::Typename)
.Func(_SC("_tostring"), &Metadata::ToString)
// Properties
.Prop(_SC("IsValid"), &Metadata::IsValid)
.Prop(_SC("Database"), &Metadata::GetDatabase)
.Prop(_SC("References"), &Metadata::GetRefCount)
.Prop(_SC("NodeCount"), &Metadata::GetNodeCount)
.Prop(_SC("RecordSize"), &Metadata::GetRecordSize)
.Prop(_SC("IpVersion"), &Metadata::GetIpVersion)
.Prop(_SC("DatabaseType"), &Metadata::GetDatabaseType)
.Prop(_SC("LanguageCount"), &Metadata::GetLanguageCount)
.Prop(_SC("BinaryFormatMajorVersion"), &Metadata::GetBinaryFormatMajorVersion)
.Prop(_SC("BinaryFormatMinorVersion"), &Metadata::GetBinaryFormatMinorVersion)
.Prop(_SC("BuildEpoch"), &Metadata::GetBuildEpoch)
.Prop(_SC("DescriptionCount"), &Metadata::GetDescriptionCount)
// Member methods
.Func(_SC("Release"), &Metadata::Release)
.Func(_SC("GetLanguageName"), &Metadata::GetLanguageName)
.Func(_SC("GetDescriptionHandle"), &Metadata::GetDescriptionHandle)
.Func(_SC("GetDescriptionValue"), &Metadata::GetDescriptionValue)
.Func(_SC("GetDescriptionLanguage"), &Metadata::GetDescriptionLanguage)
);
}
} // Namespace:: SqMod

View File

@ -1,264 +0,0 @@
#ifndef _SQMMDB_METADATA_HPP_
#define _SQMMDB_METADATA_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used inspect database meta-data.
*/
class Metadata
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_metadata_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Pointer GetValid(CCStr file, Int32 line) const;
#else
Pointer GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database associated with this meta-data.
Pointer m_Metadata; // The inspected meta-data structure.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Metadata()
: m_Handle(), m_Metadata(nullptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct and with a specific meta-data.
*/
Metadata(const DbRef & db, Pointer metadata)
: m_Handle(db), m_Metadata(metadata)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Metadata(const Metadata &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Metadata(Metadata &&) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Metadata & operator = (const Metadata &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Metadata & operator = (Metadata &&) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Metadata ? m_Metadata->database_type : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and meta-data pointer.
*/
bool IsValid() const
{
return m_Handle; // If there's a database handle then there's a meta-data too
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release()
{
m_Handle.Reset();
m_Metadata = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the node count.
*/
SQInteger GetNodeCount() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->node_count);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the record size.
*/
SQInteger GetRecordSize() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->record_size);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the IP version.
*/
SQInteger GetIpVersion() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->ip_version);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the database type.
*/
CSStr GetDatabaseType() const
{
return SQMOD_GET_VALID(*this)->database_type;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of language names.
*/
SQInteger GetLanguageCount() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->languages.count);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the name of a certain language.
*/
CSStr GetLanguageName(Uint32 idx) const
{
// Validate the specified index
if (idx > SQMOD_GET_VALID(*this)->languages.count)
{
STHROWF("The specified language index is out of range: %u > %u", idx, m_Metadata->languages.count);
}
// Return the requested name
return m_Metadata->languages.names[idx];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the major version of the binary format.
*/
SQInteger GetBinaryFormatMajorVersion() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->binary_format_major_version);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the minor version of the binary format.
*/
SQInteger GetBinaryFormatMinorVersion() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->binary_format_minor_version);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the build epoch.
*/
Object GetBuildEpoch() const
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), ConvTo< Uint64 >::From(SQMOD_GET_VALID(*this)->build_epoch));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of available description handles.
*/
SQInteger GetDescriptionCount() const
{
return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->description.count);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the handle of a certain description.
*/
Description GetDescriptionHandle(Uint32 idx) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the description of a certain description handle.
*/
CSStr GetDescriptionValue(Uint32 idx) const
{
// Validate the specified index
if (idx > SQMOD_GET_VALID(*this)->description.count)
{
STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
}
// Return the requested description value
return m_Metadata->description.descriptions[idx]->description;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the language of a certain description handle.
*/
CSStr GetDescriptionLanguage(Uint32 idx) const
{
// Validate the specified index
if (idx > SQMOD_GET_VALID(*this)->description.count)
{
STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
}
// Return the requested description language
return m_Metadata->description.descriptions[idx]->language;
}
};
} // Namespace:: SqMod
#endif // _SQMMDB_METADATA_HPP_

View File

@ -1,273 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Database(Table & mmns);
extern void Register_Description(Table & mmns);
extern void Register_EntryData(Table & mmns);
extern void Register_EntryDataList(Table & mmns);
extern void Register_LookupResult(Table & mmns);
extern void Register_Metadata(Table & mmns);
extern void Register_SearchNode(Table & mmns);
extern void Register_SockAddr(Table & mmns);
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQMMDB_NAME);
// Registration failed
return false;
}
Table mmns(vm);
Register_Database(mmns);
Register_Description(mmns);
Register_EntryData(mmns);
Register_EntryDataList(mmns);
Register_LookupResult(mmns);
Register_Metadata(mmns);
Register_SearchNode(mmns);
Register_SockAddr(mmns);
mmns.Func(_SC("StrError"), MMDB_strerror);
mmns.Func(_SC("LibVersion"), MMDB_lib_version);
mmns.Func(_SC("TypeStr"), AsTypeStr);
RootTable(vm).Bind(_SC("SqMMDB"), mmns);
ConstTable(vm).Enum(_SC("SqMMDataType"), Enumeration(vm)
.Const(_SC("Extended"), MMDB_DATA_TYPE_EXTENDED)
.Const(_SC("Pointer"), MMDB_DATA_TYPE_POINTER)
.Const(_SC("Utf8String"), MMDB_DATA_TYPE_UTF8_STRING)
.Const(_SC("Double"), MMDB_DATA_TYPE_DOUBLE)
.Const(_SC("Bytes"), MMDB_DATA_TYPE_BYTES)
.Const(_SC("Uint16"), MMDB_DATA_TYPE_UINT16)
.Const(_SC("Uint32"), MMDB_DATA_TYPE_UINT32)
.Const(_SC("Map"), MMDB_DATA_TYPE_MAP)
.Const(_SC("Int32"), MMDB_DATA_TYPE_INT32)
.Const(_SC("Uint64"), MMDB_DATA_TYPE_UINT64)
.Const(_SC("Uint128"), MMDB_DATA_TYPE_UINT128)
.Const(_SC("Array"), MMDB_DATA_TYPE_ARRAY)
.Const(_SC("Container"), MMDB_DATA_TYPE_CONTAINER)
.Const(_SC("EndMarker"), MMDB_DATA_TYPE_END_MARKER)
.Const(_SC("Boolean"), MMDB_DATA_TYPE_BOOLEAN)
.Const(_SC("Float"), MMDB_DATA_TYPE_FLOAT)
);
ConstTable(vm).Enum(_SC("SqMMRecordType"), Enumeration(vm)
.Const(_SC("SearchNode"), MMDB_RECORD_TYPE_SEARCH_NODE)
.Const(_SC("Empty"), MMDB_RECORD_TYPE_EMPTY)
.Const(_SC("Data"), MMDB_RECORD_TYPE_DATA)
.Const(_SC("Invalid"), MMDB_RECORD_TYPE_INVALID)
);
ConstTable(vm).Enum(_SC("SqMMErrCode"), Enumeration(vm)
.Const(_SC("Success"), MMDB_SUCCESS)
.Const(_SC("FileOpenError"), MMDB_FILE_OPEN_ERROR)
.Const(_SC("CorruptSearchTreeError"), MMDB_CORRUPT_SEARCH_TREE_ERROR)
.Const(_SC("InvalidMetadataError"), MMDB_INVALID_METADATA_ERROR)
.Const(_SC("IOError"), MMDB_IO_ERROR)
.Const(_SC("OutOfMemoryError"), MMDB_OUT_OF_MEMORY_ERROR)
.Const(_SC("UnknownDatabaseFormatError"), MMDB_UNKNOWN_DATABASE_FORMAT_ERROR)
.Const(_SC("InvalidDataError"), MMDB_INVALID_DATA_ERROR)
.Const(_SC("InvalidLookupPathError"), MMDB_INVALID_LOOKUP_PATH_ERROR)
.Const(_SC("LookupPathDoesNotMatchDataError"), MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR)
.Const(_SC("InvalidNodeNumberError"), MMDB_INVALID_NODE_NUMBER_ERROR)
.Const(_SC("Ipv6LookupInIpv4DatabaseError"), MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR)
);
Sqrat::ConstTable(vm)
.Const(_SC("MMDB_MODE_MMAP"), MMDB_MODE_MMAP)
.Const(_SC("MMDB_MODE_MASK"), MMDB_MODE_MASK);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQMMDB_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQMMDB_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQMMDB_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQMMDB_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullFunction().ReleaseGently();
// Release script resources...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQMMDB_NAME))
{
try
{
ImportModuleAPI(_Func, SQMMDB_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQMMDB_NAME);
OutputMessage("Author: %s", SQMMDB_AUTHOR);
OutputMessage("Legal: %s", SQMMDB_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQMMDB_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQMMDB_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMMDB_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQMMDB_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,214 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "SearchNode.hpp"
#include "EntryData.hpp"
#include "EntryDataList.hpp"
#include "Database.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger SearchNode::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMSearchNode");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void SearchNode::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
#else
void SearchNode::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SearchNode::Reference SearchNode::GetValid(CCStr file, Int32 line)
{
Validate(file, line);
return m_Node;
}
#else
SearchNode::Reference SearchNode::GetValid()
{
Validate();
return m_Node;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
SearchNode::SearchNode()
: m_Handle(), m_Node()
{
std::memset(&m_Node, 0, sizeof(Type));
}
// ------------------------------------------------------------------------------------------------
void SearchNode::Release()
{
std::memset(&m_Node, 0, sizeof(Type));
m_Handle.Reset();
}
// ------------------------------------------------------------------------------------------------
Database SearchNode::GetDatabase() const
{
return Database(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Object SearchNode::GetLeftRecordEntryDataList()
{
// Prepare a temporary entry data list pointer
MMDB_entry_data_list_s * entry_data_list = nullptr;
// Attempt to retrieve the entire entry data list at once
const int status = MMDB_get_entry_data_list(&(SQMOD_GET_VALID(*this).left_record_entry), &entry_data_list);
// Validate the status code
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get entry data list [%s]", MMDB_strerror(status));
}
// Return the resulted list
return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
Object SearchNode::GetRightRecordEntryDataList()
{
// Prepare a temporary entry data list pointer
MMDB_entry_data_list_s * entry_data_list = nullptr;
// Attempt to retrieve the entire entry data list at once
const int status = MMDB_get_entry_data_list(&(SQMOD_GET_VALID(*this).right_record_entry), &entry_data_list);
// Validate the status code
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get entry data list [%s]", MMDB_strerror(status));
}
// Return the resulted list
return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
SQInteger SearchNode::GetRecordEntryData(HSQUIRRELVM vm, bool right)
{
const Int32 top = sq_gettop(vm);
// The search node result instance
SearchNode * node = nullptr;
// Attempt to extract the search node result instance
try
{
node = Var< SearchNode * >(vm, 1).value;
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Do we have a valid search node result instance?
if (!node)
{
return sq_throwerror(vm, "Invalid search node result instance");
}
// See if there's a handle
else if (!node->m_Handle)
{
return sq_throwerror(vm, "Invalid Maxmind database reference");
}
typedef std::vector< StackStrF > ArgList;
// The list of extracted arguments
ArgList arglist;
// Extract each argument as a string
for (SQInteger i = 2; i <= top; ++i)
{
arglist.emplace_back(vm, i);
// Did we fail to extract the argument value?
if (SQ_FAILED(arglist.back().Proc(false)))
{
return arglist.back().mRes; // Propagate the error
}
}
typedef std::vector< CSStr > PtrList;
// The list of pointers to path segments
PtrList ptrlist;
// Grab the pointers to argument values
for (const auto & a : arglist)
{
ptrlist.push_back(a.mPtr);
}
// Push null to specify the end of the list
ptrlist.push_back(nullptr);
// Grab the requested entry
MMDB_entry_s * entry = &(right ? node->m_Node.right_record_entry : node->m_Node.left_record_entry);
MMDB_entry_data_s entry_data;
// Attempt to retrieve the specified entry data
const int status = MMDB_aget_value(entry, &entry_data, ptrlist.data());
// Validate the status code
if (status != MMDB_SUCCESS)
{
return sq_throwerror(vm, ToStrF("Unable to get entry data [%s]", MMDB_strerror(status)));
}
// Push the resulted list object onto the stack
try
{
ClassType< EntryData >::PushInstance(vm, new EntryData(node->m_Handle, entry_data));
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Specify that we returned a value
return 1;
}
// ================================================================================================
void Register_SearchNode(Table & mmns)
{
mmns.Bind(_SC("SearchNode"),
Class< SearchNode >(mmns.GetVM(), _SC("SqMMSearchNode"))
// Constructors
.Ctor()
.Ctor< const SearchNode & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SearchNode::Typename)
.Func(_SC("_tostring"), &SearchNode::ToString)
// Properties
.Prop(_SC("IsValid"), &SearchNode::IsValid)
.Prop(_SC("Database"), &SearchNode::GetDatabase)
.Prop(_SC("References"), &SearchNode::GetRefCount)
.Prop(_SC("LeftRecord"), &SearchNode::GetLeftRecord)
.Prop(_SC("RightRecord"), &SearchNode::GetRightRecord)
.Prop(_SC("LeftRecordType"), &SearchNode::GetLeftRecordType)
.Prop(_SC("RightRecordType"), &SearchNode::GetRightRecordType)
.Prop(_SC("LeftRecordEntryDataList"), &SearchNode::GetLeftRecordEntryDataList)
.Prop(_SC("RightRecordEntryDataList"), &SearchNode::GetRightRecordEntryDataList)
// Member methods
.Func(_SC("Release"), &SearchNode::Release)
// Squirrel methods
.SquirrelFunc(_SC("GetLeftRecordValue"), &SearchNode::GetLeftRecordEntryData)
.SquirrelFunc(_SC("GetRightRecordValue"), &SearchNode::GetRightRecordEntryData)
);
}
} // Namespace:: SqMod

View File

@ -1,208 +0,0 @@
#ifndef _SQMMDB_SEARCHNODE_HPP_
#define _SQMMDB_SEARCHNODE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can hold and be used to work with search nodes.
*/
class SearchNode
{
public:
// --------------------------------------------------------------------------------------------
typedef MMDB_search_node_s 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed database handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Reference GetValid(CCStr file, Int32 line);
#else
Reference GetValid();
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
DbRef m_Handle; // The database from which this search node comes from.
Type m_Node; // The managed search node structure.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
SearchNode();
/* --------------------------------------------------------------------------------------------
* Construct and take ownership of a certain search node.
*/
SearchNode(const DbRef & db, Reference node)
: m_Handle(db), m_Node(node)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SearchNode(const SearchNode &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SearchNode(SearchNode &&) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
SearchNode & operator = (const SearchNode &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SearchNode & operator = (SearchNode &&) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return FmtStr("<%llu:%s,%llu:s>", m_Node.left_record, AsTypeStr(m_Node.left_record_type)
, m_Node.right_record, AsTypeStr(m_Node.right_record_type));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid database and node structure.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Release the manages handles/pointers and become a null instance.
*/
void Release();
/* --------------------------------------------------------------------------------------------
* Retrieve the database associated with the managed handle/pointer.
*/
Database GetDatabase() const;
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the managed database instance.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the left record value.
*/
Object GetLeftRecord()
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), ConvTo< Uint64 >::From(SQMOD_GET_VALID(*this).left_record));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the right record value.
*/
Object GetRightRecord()
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), ConvTo< Uint64 >::From(SQMOD_GET_VALID(*this).right_record));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the left record value type.
*/
SQInteger GetLeftRecordType()
{
return static_cast< SQInteger >(SQMOD_GET_VALID(*this).left_record_type);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the right record value type.
*/
SQInteger GetRightRecordType()
{
return static_cast< SQInteger >(SQMOD_GET_VALID(*this).right_record_type);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the left record entry data list.
*/
Object GetLeftRecordEntryDataList();
/* --------------------------------------------------------------------------------------------
* Retrieve the right record entry data list.
*/
Object GetRightRecordEntryDataList();
/* --------------------------------------------------------------------------------------------
* Retrieve the left record entry data.
*/
static SQInteger GetLeftRecordEntryData(HSQUIRRELVM vm)
{
return GetRecordEntryData(vm, false);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the left record entry data.
*/
static SQInteger GetRightRecordEntryData(HSQUIRRELVM vm)
{
return GetRecordEntryData(vm, true);
}
protected:
/* --------------------------------------------------------------------------------------------
* Shared function to retrieve the left/right record entry data.
*/
static SQInteger GetRecordEntryData(HSQUIRRELVM vm, bool right);
};
} // Namespace:: SqMod
#endif // _SQMMDB_SEARCHNODE_HPP_

View File

@ -1,102 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "SockAddr.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger SockAddr::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMSockAddr");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void SockAddr::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid sockaddr structure handle =>[%s:%d]", file, line);
}
}
#else
void SockAddr::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid sockaddr structure handle");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SockAddr::Pointer SockAddr::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
SockAddr::Pointer SockAddr::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
SockAddr::SockAddr(CSStr addr)
: m_Handle(nullptr), m_Addres(_SC(""))
{
struct addrinfo hints;
// Configure the hints structure
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_NUMERICHOST;
// We set ai_socktype so that we only get one result back
hints.ai_socktype = SOCK_STREAM;
// Attempt to obtain information about the specified address
Int32 status = getaddrinfo(addr, nullptr, &hints, &m_Handle);
// Validate the success of the operation
if (!status)
{
// See if we must free any handles (just in case)
if (m_Handle)
{
freeaddrinfo(m_Handle);
}
// Now it's safe to throw the error
STHROWF("Unable to query the specified address for information [%s]", gai_strerror(status));
}
// Save the specified string address
m_Addres.assign(addr ? addr : _SC(""));
}
// ------------------------------------------------------------------------------------------------
SockAddr::~SockAddr()
{
if (m_Handle)
{
freeaddrinfo(m_Handle);
}
}
// ================================================================================================
void Register_SockAddr(Table & mmns)
{
mmns.Bind(_SC("SockAddr"),
Class< SockAddr, NoCopy< SockAddr > >(mmns.GetVM(), _SC("SqMMSockAddr"))
// Constructors
.Ctor()
.Ctor< CSStr >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SockAddr::Typename)
.Func(_SC("_tostring"), &SockAddr::ToString)
// Properties
.Prop(_SC("IsValid"), &SockAddr::IsValid)
.Prop(_SC("Address"), &SockAddr::GetAddress)
);
}
} // Namespace:: SqMod

View File

@ -1,157 +0,0 @@
#ifndef _SQMMDB_SOCKADDR_HPP_
#define _SQMMDB_SOCKADDR_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can obtain information from string addresses and be used repeatedly thereafter.
*/
class SockAddr
{
public:
// --------------------------------------------------------------------------------------------
typedef struct addrinfo 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.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed sockaddr pointer and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed sockaddr pointer and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
Pointer GetValid(CCStr file, Int32 line) const;
#else
Pointer GetValid() const;
#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
Pointer m_Handle; // The managed sockaddr structure.
String m_Addres; // The address that was queried for information.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
SockAddr()
: m_Handle(nullptr), m_Addres(_SC(""))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
SockAddr(CSStr addr);
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
SockAddr(const SockAddr & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SockAddr(SockAddr && o)
: m_Handle(o.m_Handle)
, m_Addres(o.m_Addres)
{
o.m_Handle = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SockAddr();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
SockAddr & operator = (const SockAddr & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SockAddr & operator = (SockAddr && o)
{
if (m_Handle != o.m_Handle)
{
m_Handle = o.m_Handle;
m_Addres = o.m_Addres;
o.m_Handle = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal addrinfo structure pointer.
*/
Pointer GetHandle()
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal addrinfo structure pointer.
*/
Pointer GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Addres.c_str();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid addrinfo structure.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated string address.
*/
CSStr GetAddress() const
{
return m_Addres.c_str();
}
};
} // Namespace:: SqMod
#endif // _SQMMDB_SOCKADDR_HPP_

View File

@ -1,249 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Account.hpp"
#include "Connection.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
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_Options()
, m_AutoCommit(true)
{
// Validate the specified port number
if (port >= 0xFFFF)
{
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);
}
// ------------------------------------------------------------------------------------------------
void Account::SetSSL(CSStr key, CSStr cert, CSStr ca, CSStr ca_path, CSStr cipher)
{
if (!key || *key == '\0')
{
m_SSL_Key.clear();
m_SSL_Cert.clear();
m_SSL_CA.clear();
m_SSL_CA_Path.clear();
m_SSL_Cipher.clear();
}
else
{
m_SSL_Key.assign(key ? key : _SC(""));
m_SSL_Cert.assign(cert ? cert : _SC(""));
m_SSL_CA.assign(ca ? ca : _SC(""));
m_SSL_CA_Path.assign(ca_path ? ca_path : _SC(""));
m_SSL_Cipher.assign(cipher ? cipher : _SC(""));
}
}
// ------------------------------------------------------------------------------------------------
Table Account::GetOptionsTable() const
{
// Allocate an empty table
Table tbl(DefaultVM::Get());
// Insert every option into the table
for (const auto & opt : m_Options)
{
tbl.SetValue(opt.first.c_str(), opt.second);
}
// Return the resulted table
return tbl;
}
// ------------------------------------------------------------------------------------------------
const String & Account::GetOption(CSStr name) const
{
// Make sure the specified name is valid
if (!name || *name == '\0')
{
STHROWF("Invalid or empty option name");
}
// Attempt to find the requested option
const Options::const_iterator itr = m_Options.find(name);
// Return the result
return (itr == m_Options.cend()) ? s_String : itr->second;
}
// ------------------------------------------------------------------------------------------------
void Account::SetOption(CSStr name, CSStr value)
{
// Make sure the specified name is valid
if (!name || *name == '\0')
{
STHROWF("Invalid or empty option name");
}
// Assign the specified value
m_Options[name] = value ? value : _SC("");
}
// ------------------------------------------------------------------------------------------------
void Account::RemoveOption(CSStr name)
{
// Make sure the specified name is valid
if (!name || *name == '\0')
{
STHROWF("Invalid or empty option name");
}
// Erase the specified value
m_Options.erase(name);
}
// ------------------------------------------------------------------------------------------------
Connection Account::Connect() const
{
return Connection(*this);
}
// ================================================================================================
void Register_Account(Table & sqlns)
{
sqlns.Bind(_SC("Account")
, Class< Account >(sqlns.GetVM(), _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)
);
}
} // Namespace:: SqMod

View File

@ -1,414 +0,0 @@
#ifndef _SQMYSQL_ACCOUNT_HPP_
#define _SQMYSQL_ACCOUNT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class containing shared connection information to avoid repetition.
*/
class Account
{
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.
*/
Account(CSStr host, CSStr user)
: Account(host, user, _SC(""), _SC(""), 3306, _SC(""))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base Constructor.
*/
Account(CSStr host, CSStr user, CSStr pass)
: Account(host, user, pass, _SC(""), 3306, _SC(""))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base Constructor.
*/
Account(CSStr host, CSStr user, CSStr pass, CSStr name)
: Account(host, user, pass, name, 3306, _SC(""))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base Constructor.
*/
Account(CSStr host, CSStr user, CSStr pass, CSStr name, SQInteger port)
: Account(host, user, pass, name, port, _SC(""))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base Constructor.
*/
Account(CSStr host, CSStr user, CSStr pass, CSStr name, SQInteger port, CSStr socket);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Account(const Account & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Account(Account && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Account() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Account & operator = (const Account & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Account & operator = (Account && o) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Account & 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 the host address specified during creation.
*/
const String & GetHost() const
{
return m_Host;
}
/* --------------------------------------------------------------------------------------------
* Modify the host address specified during creation.
*/
void SetHost(CSStr addr);
/* --------------------------------------------------------------------------------------------
* Retrieve the user name specified during creation.
*/
const String & GetUser() const
{
return m_User;
}
/* --------------------------------------------------------------------------------------------
* 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
{
return m_Pass;
}
/* --------------------------------------------------------------------------------------------
* Modify the password specified during creation.
*/
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;
}
/* --------------------------------------------------------------------------------------------
* Modify the server port specified during creation.
*/
void SetPortNum(SQInteger port);
/* --------------------------------------------------------------------------------------------
* Retrieve the server socket.
*/
const String & GetSocket() const
{
return m_Socket;
}
/* --------------------------------------------------------------------------------------------
* 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
{
return m_SSL_Key;
}
/* --------------------------------------------------------------------------------------------
* Modify the SSL key.
*/
void SetSSL_Key(CSStr key)
{
m_SSL_Key.assign(key != nullptr ? key : _SC(""));
}
/* --------------------------------------------------------------------------------------------
* 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
{
return m_SSL_CA;
}
/* --------------------------------------------------------------------------------------------
* 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
{
return m_SSL_CA_Path;
}
/* --------------------------------------------------------------------------------------------
* 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.
*/
void SetSSL(CSStr key, CSStr cert, CSStr ca, CSStr ca_path, CSStr cipher);
/* --------------------------------------------------------------------------------------------
* See whether autocommit is enabled or not.
*/
bool GetAutoCommit() const
{
return m_AutoCommit;
}
/* --------------------------------------------------------------------------------------------
* Set whether autocommit should be enabled or not.
*/
void SetAutoCommit(bool toggle)
{
m_AutoCommit = toggle;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the entire options container as a table.
*/
const Options & GetOptions() const
{
return m_Options;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the entire options container as a table.
*/
Table GetOptionsTable() const;
/* --------------------------------------------------------------------------------------------
* Retrieve a value from the options container.
*/
const String & GetOption(CSStr name) const;
/* --------------------------------------------------------------------------------------------
* Set a value in the options container.
*/
void SetOption(CSStr name, CSStr value);
/* --------------------------------------------------------------------------------------------
* Remove a value from the options container.
*/
void RemoveOption(CSStr name);
/* --------------------------------------------------------------------------------------------
* Retrieve the number of values in the options container.
*/
Uint32 OptionsCount() const
{
return static_cast< Uint32 >(m_Options.size());
}
/* --------------------------------------------------------------------------------------------
* See whether the options container is empty or not.
*/
bool OptionsEmpty() const
{
return m_Options.empty();
}
/* --------------------------------------------------------------------------------------------
* Remove all the options from the options container.
*/
void OptionsClear()
{
m_Options.clear();
}
/* --------------------------------------------------------------------------------------------
* Create a connection with the current account information.
*/
Connection Connect() const;
};
} // Namespace:: SqMod
#endif // _SQMYSQL_ACCOUNT_HPP_

View File

@ -1,97 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void SqDateToMySQLTime(Object & obj, MYSQL_TIME & t)
{
// The resulted date values
uint16_t year = 0;
uint8_t month = 0, day = 0;
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), obj);
// Attempt to get the values inside the specified object
if (SQ_FAILED(SqMod_GetDate(DefaultVM::Get(), -1, &year, &month, &day)))
{
STHROWF("Invalid date specified");
}
}
// Populate the given structure
t.year = year;
t.month = month;
t.day = day;
t.hour = 0;
t.minute = 0;
t.second = 0;
t.neg = false;
t.second_part = 0;
t.time_type = MYSQL_TIMESTAMP_DATE;
}
// ------------------------------------------------------------------------------------------------
void SqTimeToMySQLTime(Object & obj, MYSQL_TIME & t)
{
// The resulted time values
uint8_t hour = 0, minute = 0, second = 0;
uint16_t milli = 0;
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), obj);
// Attempt to get the values inside the specified object
if (SQ_FAILED(SqMod_GetTime(DefaultVM::Get(), -1, &hour, &minute, &second, &milli)))
{
STHROWF("Invalid time specified");
}
}
// Populate the given structure
t.year = 0;
t.month = 0;
t.day = 0;
t.neg = false;
t.second_part = (milli * 1000L);
t.time_type = MYSQL_TIMESTAMP_TIME;
}
// ------------------------------------------------------------------------------------------------
void SqDatetimeToMySQLTime(Object & obj, MYSQL_TIME & t)
{
// The resulted date values
uint16_t year = 0, milli = 0;
uint8_t month = 0, day = 0, hour = 0, minute = 0, second = 0;
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), obj);
// Attempt to get the values inside the specified object
if (SQ_FAILED(SqMod_GetDatetime(DefaultVM::Get(), -1, &year, &month, &day, &hour, &minute, &second, &milli)))
{
STHROWF("Invalid date and time specified");
}
}
// Populate the given structure
t.year = year;
t.month = month;
t.day = day;
t.hour = hour;
t.minute = minute;
t.second = second;
t.neg = false;
t.second_part = (milli * 1000L);
t.time_type = MYSQL_TIMESTAMP_DATETIME;
}
} // Namespace:: SqMod

View File

@ -1,87 +0,0 @@
#ifndef _SQMYSQL_COMMON_HPP_
#define _SQMYSQL_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Convert.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQMYSQL_NAME "Squirrel MySQL Module"
#define SQMYSQL_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQMYSQL_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQMYSQL_HOST_NAME "SqModMySQLHost"
#define SQMYSQL_VERSION 001
#define SQMYSQL_VERSION_STR "0.0.1"
#define SQMYSQL_VERSION_MAJOR 0
#define SQMYSQL_VERSION_MINOR 0
#define SQMYSQL_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Handle validation.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
#define SQMOD_THROW_CURRENT(x, a) (x).ThrowCurrent(a, __FILE__, __LINE__)
#define SQMOD_VALIDATE(x) (x).Validate(__FILE__, __LINE__)
#define SQMOD_VALIDATE_CREATED(x) (x).ValidateCreated(__FILE__, __LINE__)
#define SQMOD_VALIDATE_PARAM(x, i) (x).ValidateParam((i), __FILE__, __LINE__)
#define SQMOD_VALIDATE_FIELD(x, i) (x).ValidateField((i), __FILE__, __LINE__)
#define SQMOD_VALIDATE_STEPPED(x) (x).ValidateStepped(__FILE__, __LINE__)
#define SQMOD_GET_VALID(x) (x).GetValid(__FILE__, __LINE__)
#define SQMOD_GET_CREATED(x) (x).GetCreated(__FILE__, __LINE__)
#define SQMOD_GET_STEPPED(x) (x).GetStepped(__FILE__, __LINE__)
#else
#define SQMOD_THROW_CURRENT(x, a) (x).ThrowCurrent(a)
#define SQMOD_VALIDATE(x) (x).Validate()
#define SQMOD_VALIDATE_CREATED(x) (x).ValidateCreated()
#define SQMOD_VALIDATE_PARAM(x, i) (x).ValidateParam((i))
#define SQMOD_VALIDATE_FIELD(x, i) (x).ValidateField((i))
#define SQMOD_VALIDATE_STEPPED(x) (x).ValidateStepped()
#define SQMOD_GET_VALID(x) (x).GetValid()
#define SQMOD_GET_CREATED(x) (x).GetCreated()
#define SQMOD_GET_STEPPED(x) (x).GetStepped()
#endif // _DEBUG
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
struct ConnHnd;
struct StmtHnd;
struct ResHnd;
// ------------------------------------------------------------------------------------------------
class Account;
class Column;
class Connection;
class ResultSet;
class Statement;
class Transaction;
/* ------------------------------------------------------------------------------------------------
* Common typedefs.
*/
typedef SharedPtr< ConnHnd > ConnRef;
typedef SharedPtr< StmtHnd > StmtRef;
typedef SharedPtr< ResHnd > ResRef;
/* ------------------------------------------------------------------------------------------------
* Replicate the values of a script Date type to a database time type.
*/
void SqDateToMySQLTime(Object & obj, MYSQL_TIME & t);
/* ------------------------------------------------------------------------------------------------
* Replicate the values of a script Date type to a database time type.
*/
void SqTimeToMySQLTime(Object & obj, MYSQL_TIME & t);
/* ------------------------------------------------------------------------------------------------
* Replicate the values of a script Date type to a database time type.
*/
void SqDatetimeToMySQLTime(Object & obj, MYSQL_TIME & t);
} // Namespace:: SqMod
#endif // _SQMYSQL_COMMON_HPP_

View File

@ -1,419 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Connection.hpp"
#include "Account.hpp"
#include "Statement.hpp"
#include "ResultSet.hpp"
#include "Transaction.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
#include <vector>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Connection::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMySQLConnection");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL connection reference =>[%s:%d]", file, line);
}
}
#else
void Connection::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL connection reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::ValidateCreated(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL connection reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL connection =>[%s:%d]", file, line);
}
}
#else
void Connection::ValidateCreated() const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL connection reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL connection");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Object Connection::Insert(CSStr query)
{
// Make sure the specified query is valid
if (!query || *query == '\0')
{
STHROWF("Invalid or empty MySQL query");
}
// Attempt to execute the specified query
else if (mysql_real_query(SQMOD_GET_CREATED(*this)->mPtr, query, std::strlen(query)) != 0)
{
SQMOD_THROW_CURRENT(*m_Handle, "Unable to execute MySQL query");
}
// Return the identifier of the inserted row
return MakeULongObj(mysql_insert_id(m_Handle->mPtr));
}
// ------------------------------------------------------------------------------------------------
ResultSet Connection::Query(CSStr query)
{
// Make sure the specified query is valid
if (!query || *query == '\0')
{
STHROWF("Invalid or empty MySQL query");
}
// Attempt to execute the specified query
else if (mysql_real_query(SQMOD_GET_CREATED(*this)->mPtr, query, std::strlen(query)) != 0)
{
SQMOD_THROW_CURRENT(*m_Handle, "Unable to execute MySQL query");
}
// Return the identifier of the inserted row
return ResultSet(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Statement Connection::GetStatement(CSStr query)
{
return Statement(SQMOD_GET_CREATED(*this), query);
}
// ------------------------------------------------------------------------------------------------
Transaction Connection::GetTransaction()
{
return Transaction();
}
// ------------------------------------------------------------------------------------------------
SQInteger Connection::ExecuteF(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the query value specified?
if (top <= 1)
{
return sq_throwerror(vm, "Missing query value");
}
// The connection instance
Connection * conn = nullptr;
// Attempt to extract the argument values
try
{
conn = Var< Connection * >(vm, 1).value;
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Do we have a valid connection instance?
if (!conn)
{
return sq_throwerror(vm, "Invalid MySQL connection instance");
}
// Validate the connection info
try
{
SQMOD_VALIDATE_CREATED(*conn);
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Make sure the query string is valid
else if (!(val.mPtr) || *(val.mPtr) == '\0')
{
STHROWF("Invalid or empty MySQL query");
}
// Attempt to execute the specified query
try
{
const SQRESULT res = SqMod_PushULongObject(vm, conn->m_Handle->Execute(val.mPtr, val.mLen));
// Validate the result of pushing the number of database changes on the stack
if (SQ_FAILED(res))
{
return res; // Propagate the error!
}
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// This function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
SQInteger Connection::InsertF(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the query value specified?
if (top <= 1)
{
return sq_throwerror(vm, "Missing query value");
}
// The connection instance
Connection * conn = nullptr;
// Attempt to extract the argument values
try
{
conn = Var< Connection * >(vm, 1).value;
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Do we have a valid connection instance?
if (!conn)
{
return sq_throwerror(vm, "Invalid MySQL connection instance");
}
// Validate the connection info
try
{
SQMOD_VALIDATE_CREATED(*conn);
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Make sure the query string is valid
else if (!(val.mPtr) || *(val.mPtr) == '\0')
{
return sq_throwerror(vm, "Invalid or empty MySQL query");
}
// Attempt to execute the specified query
try
{
if (mysql_real_query(conn->m_Handle->mPtr, val.mPtr, val.mLen) != 0)
{
SQMOD_THROW_CURRENT(*(conn->m_Handle), "Unable to execute MySQL query");
}
// Return the identifier of the inserted row
const SQRESULT res = SqMod_PushULongObject(vm, mysql_insert_id(conn->m_Handle->mPtr));
// Validate the result of pushing the identifier of the inserted row
if (SQ_FAILED(res))
{
return res; // Propagate the error!
}
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// This function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
SQInteger Connection::QueryF(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the query value specified?
if (top <= 1)
{
return sq_throwerror(vm, "Missing query value");
}
// The connection instance
Connection * conn = nullptr;
// Attempt to extract the argument values
try
{
conn = Var< Connection * >(vm, 1).value;
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Do we have a valid connection instance?
if (!conn)
{
return sq_throwerror(vm, "Invalid MySQL connection instance");
}
// Validate the connection info
try
{
SQMOD_VALIDATE_CREATED(*conn);
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Make sure the query string is valid
else if (!(val.mPtr) || *(val.mPtr) == '\0')
{
return sq_throwerror(vm, "Invalid or empty MySQL query");
}
// Attempt to execute the specified query
try
{
if (mysql_real_query(conn->m_Handle->mPtr, val.mPtr, val.mLen) != 0)
{
SQMOD_THROW_CURRENT(*(conn->m_Handle), "Unable to execute MySQL query");
}
// Return a new instance with the obtained result set
Var< ResultSet * >::push(vm, new ResultSet(conn->m_Handle));
}
catch (const Sqrat::Exception & e)
{
// Propagate the error
return sq_throwerror(vm, e.what());
}
// This function returned a value
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj Connection::EscapeString(StackStrF & str)
{
// Is there even a string to escape?
if (str.mLen <= 0)
{
return LightObj(_SC(""), 0, str.mVM); // Default to empty string
}
// Allocate a buffer for the given string
std::vector< SQChar > buffer(str.mLen * 2 + 1);
// Attempt to ecape the specified string
const Ulong len = mysql_real_escape_string(m_Handle->mPtr, buffer.data(), str.mPtr, str.mLen);
// Return the resulted string
return LightObj(buffer.data(), static_cast< SQInteger >(len), str.mVM);
}
// ================================================================================================
void Register_Connection(Table & sqlns)
{
sqlns.Bind(_SC("Connection")
, Class< Connection >(sqlns.GetVM(), _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("IsValid"), &Connection::IsValid)
.Prop(_SC("Connected"), &Connection::IsConnected)
.Prop(_SC("References"), &Connection::GetRefCount)
.Prop(_SC("ErrNo"), &Connection::GetErrNo)
.Prop(_SC("ErrStr"), &Connection::GetErrStr)
.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)
.Func(_SC("Statement"), &Connection::GetStatement)
.Func(_SC("Transaction"), &Connection::GetTransaction)
.FmtFunc(_SC("EscapeString"), &Connection::EscapeString)
// Squirrel Methods
.SquirrelFunc(_SC("ExecuteF"), &Connection::ExecuteF)
.SquirrelFunc(_SC("InsertF"), &Connection::InsertF)
.SquirrelFunc(_SC("QueryF"), &Connection::QueryF)
);
}
} // Namespace:: SqMod

View File

@ -1,438 +0,0 @@
#ifndef _SQMYSQL_CONNECTION_HPP_
#define _SQMYSQL_CONNECTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a connection handle.
*/
class Connection
{
private:
// --------------------------------------------------------------------------------------------
ConnRef m_Handle; // Reference to the actual database connection.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetValid(CCStr file, Int32 line) const;
#else
const ConnRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetCreated(CCStr file, Int32 line) const;
#else
const ConnRef & GetCreated() const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Connection()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
Connection(const Account & acc)
: m_Handle(new ConnHnd())
{
m_Handle->Create(acc);
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
Connection(const ConnRef & conn)
: m_Handle(conn)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Connection(const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Connection(Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Connection & operator = (const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Connection & operator = (Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Connection & o) const
{
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Handle ? mysql_get_host_info(m_Handle->mPtr) : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated connection handle.
*/
const ConnRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed connection handle was connected.
*/
bool IsConnected() const
{
return m_Handle && (m_Handle->mPtr != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this connection handle.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current error number.
*/
SQInteger GetErrNo() const
{
return static_cast< SQInteger >(mysql_errno(SQMOD_GET_CREATED(*this)->mPtr));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current error message.
*/
CSStr GetErrStr() const
{
return mysql_error(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last received error number.
*/
SQInteger GetLastErrNo() const
{
return static_cast< SQInteger >(SQMOD_GET_VALID(*this)->mErrNo);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last received error message.
*/
const String & GetLastErrStr() const
{
return SQMOD_GET_VALID(*this)->mErrStr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection port number.
*/
SQInteger GetPortNum() const
{
return static_cast< SQInteger >(SQMOD_GET_VALID(*this)->mPort);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection host address.
*/
const String & GetHost() const
{
return SQMOD_GET_VALID(*this)->mHost;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection user name.
*/
const String & GetUser() const
{
return SQMOD_GET_VALID(*this)->mUser;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection password.
*/
const String & GetPass() const
{
return SQMOD_GET_VALID(*this)->mPass;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the selected database name.
*/
const String & GetName() const
{
return SQMOD_GET_VALID(*this)->mName;
}
/* --------------------------------------------------------------------------------------------
* Modify the selected database name.
*/
void SetName(CSStr name)
{
// Validate the specified name
if (!name)
{
STHROWF("Invalid MySQL database name");
}
// Attempt to select the database with the given name
else if (mysql_select_db(SQMOD_GET_CREATED(*this)->mPtr, name) != 0)
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot select MySQL database");
}
// Remember the database name
m_Handle->mName.assign(name);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection socket.
*/
const String & GetSocket() const
{
return SQMOD_GET_VALID(*this)->mSocket;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection flags.
*/
SQInteger GetFlags() const
{
return static_cast< SQInteger >(SQMOD_GET_VALID(*this)->mFlags);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection SSL key.
*/
const String & GetSSL_Key() const
{
return SQMOD_GET_VALID(*this)->mSSL_Key;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection SSL certificate.
*/
const String & GetSSL_Cert() const
{
return SQMOD_GET_VALID(*this)->mSSL_Cert;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection SSL certificate authority.
*/
const String & GetSSL_CA() const
{
return SQMOD_GET_VALID(*this)->mSSL_CA;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection SSL certificate authority path.
*/
const String & GetSSL_CA_Path() const
{
return SQMOD_GET_VALID(*this)->mSSL_CA_Path;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the connection SSL cipher.
*/
const String & GetSSL_Cipher() const
{
return SQMOD_GET_VALID(*this)->mSSL_Cipher;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the default character set for the managed connection.
*/
const String & GetCharset() const
{
return SQMOD_GET_VALID(*this)->mCharset;
}
/* --------------------------------------------------------------------------------------------
* Modify the default character set for the managed connection.
*/
void SetCharset(CSStr charset)
{
// Validate the specified string
if (!charset)
{
STHROWF("Invalid charset string");
}
// Attempt to Set the default character set for the managed connection
else if (mysql_set_character_set(SQMOD_GET_CREATED(*this)->mPtr, charset) != 0)
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot apply character set");
}
// Remember the character set
m_Handle->mCharset.assign(charset);
}
/* --------------------------------------------------------------------------------------------
* See whether auto-commit is enabled or not.
*/
bool GetAutoCommit() const
{
return SQMOD_GET_VALID((*this))->mAutoCommit;
}
/* --------------------------------------------------------------------------------------------
* Set whether auto-commit should be enabled or not.
*/
void SetAutoCommit(bool toggle)
{
// Attempt to toggle auto-commit if necessary
if (SQMOD_GET_CREATED(*this)->mAutoCommit != toggle &&
mysql_autocommit(m_Handle->mPtr, toggle) != 0)
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot toggle auto-commit");
}
else
{
m_Handle->mAutoCommit = toggle;
}
}
/* --------------------------------------------------------------------------------------------
* See whether the connection is in the middle of a transaction.
*/
bool GetInTransaction() const
{
return SQMOD_GET_VALID(*this)->mInTransaction;
}
/* --------------------------------------------------------------------------------------------
* Disconnect from the currently connected database.
*/
void Disconnect()
{
SQMOD_GET_CREATED(*this)->Disconnect();
}
/* --------------------------------------------------------------------------------------------
* Execute a query on the server.
*/
Object Execute(CSStr query)
{
return MakeULongObj(SQMOD_GET_CREATED(*this)->Execute(query));
}
/* --------------------------------------------------------------------------------------------
* Execute a query on the server.
*/
Object Insert(CSStr query);
/* --------------------------------------------------------------------------------------------
* Execute a query on the server.
*/
ResultSet Query(CSStr query);
/* --------------------------------------------------------------------------------------------
* Create a new statement on the managed connection.
*/
Statement GetStatement(CSStr query);
/* --------------------------------------------------------------------------------------------
* Create a new transaction on the managed connection.
*/
Transaction GetTransaction();
/* --------------------------------------------------------------------------------------------
* Escape unwanted characters from a given string.
*/
LightObj EscapeString(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
*/
static SQInteger ExecuteF(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
*/
static SQInteger InsertF(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
*/
static SQInteger QueryF(HSQUIRRELVM vm);
};
} // Namespace:: SqMod
#endif // _SQMYSQL_CONNECTION_HPP_

View File

@ -1,474 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Convert.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
CSStr SqMySQLTypename(enum_field_types type)
{
switch(type)
{
case MYSQL_TYPE_DECIMAL: return _SC("decimal");
case MYSQL_TYPE_TINY: return _SC("tiny");
case MYSQL_TYPE_SHORT: return _SC("short");
case MYSQL_TYPE_LONG: return _SC("long");
case MYSQL_TYPE_FLOAT: return _SC("float");
case MYSQL_TYPE_DOUBLE: return _SC("double");
case MYSQL_TYPE_NULL: return _SC("null");
case MYSQL_TYPE_TIMESTAMP: return _SC("time-stamp");
case MYSQL_TYPE_LONGLONG: return _SC("long-long");
case MYSQL_TYPE_INT24: return _SC("int24");
case MYSQL_TYPE_DATE: return _SC("date");
case MYSQL_TYPE_TIME: return _SC("time");
case MYSQL_TYPE_DATETIME: return _SC("date-time");
case MYSQL_TYPE_YEAR: return _SC("year");
case MYSQL_TYPE_NEWDATE: return _SC("new-date");
case MYSQL_TYPE_VARCHAR: return _SC("var-char");
case MYSQL_TYPE_BIT: return _SC("bit");
#ifdef MYSQL_TYPE_TIMESTAMP2
case MYSQL_TYPE_TIMESTAMP2: return _SC("time-stamp2");
#endif // MYSQL_TYPE_TIMESTAMP2
#ifdef MYSQL_TYPE_DATETIME2
case MYSQL_TYPE_DATETIME2: return _SC("date-time2");
#endif // MYSQL_TYPE_DATETIME2
#ifdef MYSQL_TYPE_TIME2
case MYSQL_TYPE_TIME2: return _SC("time2");
#endif // MYSQL_TYPE_TIME2
case MYSQL_TYPE_NEWDECIMAL: return _SC("new-decimal");
case MYSQL_TYPE_ENUM: return _SC("enum");
case MYSQL_TYPE_SET: return _SC("set");
case MYSQL_TYPE_TINY_BLOB: return _SC("tiny-blob");
case MYSQL_TYPE_MEDIUM_BLOB: return _SC("medium-blob");
case MYSQL_TYPE_LONG_BLOB: return _SC("long-blob");
case MYSQL_TYPE_BLOB: return _SC("blob");
case MYSQL_TYPE_VAR_STRING: return _SC("var-string");
case MYSQL_TYPE_STRING: return _SC("string");
case MYSQL_TYPE_GEOMETRY: return _SC("geometry");
default: return _SC("unknown");
}
}
// ------------------------------------------------------------------------------------------------
CSStr SqMySQLTypenameC(enum_field_types type)
{
switch(type)
{
case MYSQL_TYPE_DECIMAL: return _SC("Decimal");
case MYSQL_TYPE_TINY: return _SC("Tiny");
case MYSQL_TYPE_SHORT: return _SC("Short");
case MYSQL_TYPE_LONG: return _SC("Long");
case MYSQL_TYPE_FLOAT: return _SC("Float");
case MYSQL_TYPE_DOUBLE: return _SC("Double");
case MYSQL_TYPE_NULL: return _SC("Null");
case MYSQL_TYPE_TIMESTAMP: return _SC("Time-Stamp");
case MYSQL_TYPE_LONGLONG: return _SC("Long-Long");
case MYSQL_TYPE_INT24: return _SC("Int24");
case MYSQL_TYPE_DATE: return _SC("Date");
case MYSQL_TYPE_TIME: return _SC("Time");
case MYSQL_TYPE_DATETIME: return _SC("Date-Time");
case MYSQL_TYPE_YEAR: return _SC("Year");
case MYSQL_TYPE_NEWDATE: return _SC("New-Date");
case MYSQL_TYPE_VARCHAR: return _SC("Var-Char");
case MYSQL_TYPE_BIT: return _SC("Bit");
#ifdef MYSQL_TYPE_TIMESTAMP2
case MYSQL_TYPE_TIMESTAMP2: return _SC("Time-Stamp2");
#endif // MYSQL_TYPE_TIMESTAMP2
#ifdef MYSQL_TYPE_DATETIME2
case MYSQL_TYPE_DATETIME2: return _SC("Date-Time2");
#endif // MYSQL_TYPE_DATETIME2
#ifdef MYSQL_TYPE_TIME2
case MYSQL_TYPE_TIME2: return _SC("Time2");
#endif // MYSQL_TYPE_TIME2
case MYSQL_TYPE_NEWDECIMAL: return _SC("New-Decimal");
case MYSQL_TYPE_ENUM: return _SC("Enum");
case MYSQL_TYPE_SET: return _SC("Set");
case MYSQL_TYPE_TINY_BLOB: return _SC("Tiny-Blob");
case MYSQL_TYPE_MEDIUM_BLOB: return _SC("Medium-Blob");
case MYSQL_TYPE_LONG_BLOB: return _SC("Long-Blob");
case MYSQL_TYPE_BLOB: return _SC("Blob");
case MYSQL_TYPE_VAR_STRING: return _SC("Var-String");
case MYSQL_TYPE_STRING: return _SC("String");
case MYSQL_TYPE_GEOMETRY: return _SC("Geometry");
default: return _SC("Unknown");
}
}
// ------------------------------------------------------------------------------------------------
static inline Int64 MySQLDateStrToSeconds(CSStr value)
{
Uint32 y = 1000, m = 1, d = 1;
// Attempt to extract the numeric values from the string
std::sscanf(value, "%u - %u - %u", &y, &m, &d);
// Calculate the number of seconds and return it
return SqMod_DateRangeToSeconds(1000, 1, 1, y, m, d);
}
// ------------------------------------------------------------------------------------------------
static inline Int64 MySQLTimeStrToSeconds(CSStr value)
{
Int32 h = 0, m = 0, s = 0;
// Attempt to extract the numeric values from the string
std::sscanf(value, "%d : %d : %d", &h, &m, &s);
// Convert the hours to seconds
h *= (60 * 60);
// Add the remaining minutes and seconds and return the result
return (h < 0) ? (h - ((m * 60) + s)) : (h + ((m * 60) + s));
}
// ------------------------------------------------------------------------------------------------
static inline Int64 MySQLDatetimeStrToSeconds(CSStr value)
{
Uint32 y = 1000, mo = 1, d = 1, h = 0, mi = 0, s = 0;
// Attempt to extract the numeric values from the string
std::sscanf(value, "%u - %u - %u %u : %u : %u", &y, &mo, &d, &h, &mi, &s);
// Calculate the number of seconds and return it
return SqMod_DateRangeToSeconds(1000, 1, 1, y, mo, d) + (h * (60 * 60)) + ((mi * 60) + s);
}
// ------------------------------------------------------------------------------------------------
static inline Int64 MySQLTimestampStrToSeconds(CSStr value)
{
Uint32 y = 1000, mo = 1, d = 1, h = 0, mi = 0, s = 0;
// Attempt to extract the numeric values from the string
std::sscanf(value, "%u - %u - %u %u : %u : %u", &y, &mo, &d, &h, &mi, &s);
// Detect if this was time-stamp 0
if (!y && !mo && !d && !h && !mi && !s)
{
return 0;
}
// Calculate the number of seconds and return it
return SqMod_DateRangeToSeconds(1970, 1, 1, y, mo, d) + (h * (60 * 60)) + ((mi * 60) + s);
}
// ------------------------------------------------------------------------------------------------
template < typename T > static inline T MemToNum(const Uint8 * b, Ulong l)
{
union
{
Uint8 a[8];
T n;
};
n = 0ULL;
switch (l)
{
default:
case 8:
{
a[7] = b[0];
a[6] = b[1];
a[5] = b[2];
a[4] = b[3];
a[3] = b[4];
a[2] = b[5];
a[1] = b[6];
a[0] = b[7];
} break;
case 7:
{
a[6] = b[0];
a[5] = b[1];
a[4] = b[2];
a[3] = b[3];
a[2] = b[4];
a[1] = b[5];
a[0] = b[6];
} break;
case 6:
{
a[5] = b[0];
a[4] = b[1];
a[3] = b[2];
a[2] = b[3];
a[1] = b[4];
a[0] = b[5];
} break;
case 5:
{
a[4] = b[0];
a[3] = b[1];
a[2] = b[2];
a[1] = b[3];
a[0] = b[4];
} break;
case 4:
{
a[3] = b[0];
a[2] = b[1];
a[1] = b[2];
a[0] = b[3];
} break;
case 3:
{
a[2] = b[0];
a[1] = b[1];
a[0] = b[2];
} break;
case 2:
{
a[1] = b[0];
a[0] = b[1];
} break;
case 1:
{
a[0] = b[0];
} break;
case 0: break;
}
return n;
}
// ------------------------------------------------------------------------------------------------
template < typename T >
static inline T ConvertToSInt(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
// Is there even a value to attempt to extract?
if (!value || *value == '\0')
{
return 0;
}
// Identify the type of value that must be converted and try to at least approximate something
switch(type)
{
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_GEOMETRY: return static_cast< T >(0);
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG: return ConvTo< T >::From(std::strtol(value, nullptr, 10));
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET: return ConvTo< T >::From(std::strtoll(value, nullptr, 10));
case MYSQL_TYPE_FLOAT: return ConvTo< T >::From(std::strtof(value, nullptr));
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: return ConvTo< T >::From(std::strtod(value, nullptr));
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: return ConvTo< T >::From(MySQLDateStrToSeconds(value));
case MYSQL_TYPE_TIME: return ConvTo< T >::From(MySQLTimeStrToSeconds(value));
case MYSQL_TYPE_TIMESTAMP: return ConvTo< T >::From(MySQLTimestampStrToSeconds(value));
case MYSQL_TYPE_DATETIME: return ConvTo< T >::From(MySQLDatetimeStrToSeconds(value));
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: return MemToNum< T >(reinterpret_cast< const Uint8 * >(value), length);
default:
{
STHROWF("Unknown conversion from (%s) to (%s)", SqMySQLTypenameC(type), tn);
} break;
}
// Should not reach this point!
return 0;
}
// ------------------------------------------------------------------------------------------------
template < typename T >
static inline T ConvertToUInt(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
// Is there even a value to attempt to extract?
if (!value || *value == '\0')
{
return 0;
}
// Identify the type of value that must be converted and try to at least approximate something
switch(type)
{
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_GEOMETRY: return static_cast< T >(0);
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG: return ConvTo< T >::From(std::strtoul(value, nullptr, 10));
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET: return ConvTo< T >::From(std::strtoull(value, nullptr, 10));
case MYSQL_TYPE_FLOAT: return ConvTo< T >::From(std::strtof(value, nullptr));
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: return ConvTo< T >::From(std::strtod(value, nullptr));
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: return ConvTo< T >::From(MySQLDateStrToSeconds(value));
case MYSQL_TYPE_TIME: return ConvTo< T >::From(MySQLTimeStrToSeconds(value));
case MYSQL_TYPE_TIMESTAMP: return ConvTo< T >::From(MySQLTimestampStrToSeconds(value));
case MYSQL_TYPE_DATETIME: return ConvTo< T >::From(MySQLDatetimeStrToSeconds(value));
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: return MemToNum< T >(reinterpret_cast< const Uint8 * >(value), length);
default:
{
STHROWF("Unknown conversion from (%s) to (%s)", SqMySQLTypenameC(type), tn);
} break;
}
// Should not reach this point!
return 0;
}
// ------------------------------------------------------------------------------------------------
Int8 DbConvTo< Int8 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToSInt< Int8 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Uint8 DbConvTo< Uint8 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToUInt< Uint8 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Int16 DbConvTo< Int16 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToSInt< Int16 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Uint16 DbConvTo< Uint16 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToUInt< Uint16 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Int32 DbConvTo< Int32 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToSInt< Int32 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Uint32 DbConvTo< Uint32 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToUInt< Uint32 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Int64 DbConvTo< Int64 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToSInt< Int64 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Uint64 DbConvTo< Uint64 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToUInt< Uint64 >(value, length, type, tn);
}
// ------------------------------------------------------------------------------------------------
Float32 DbConvTo< Float32 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
// Is there even a value to attempt to extract?
if (!value || *value == '\0')
{
return 0;
}
// Identify the type of value that must be converted and try to at least approximate something
switch(type)
{
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_GEOMETRY: return static_cast< Float32 >(0);
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG: return ConvTo< Float32 >::From(std::strtol(value, nullptr, 10));
case MYSQL_TYPE_LONGLONG: return ConvTo< Float32 >::From(std::strtoll(value, nullptr, 10));
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_FLOAT: return std::strtof(value, nullptr);
case MYSQL_TYPE_DOUBLE: return ConvTo< Float32 >::From(std::strtod(value, nullptr));
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: return std::strtof(value, nullptr);
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: return ConvTo< Float32 >::From(MySQLDateStrToSeconds(value));
case MYSQL_TYPE_TIME: return ConvTo< Float32 >::From(MySQLTimeStrToSeconds(value));
case MYSQL_TYPE_TIMESTAMP: return ConvTo< Float32 >::From(MySQLTimestampStrToSeconds(value));
case MYSQL_TYPE_DATETIME: return ConvTo< Float32 >::From(MySQLDatetimeStrToSeconds(value));
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: return MemToNum< Float32 >(reinterpret_cast< const Uint8 * >(value), length);
default:
{
STHROWF("Unknown conversion from (%s) to (%s)", SqMySQLTypenameC(type), tn);
} break;
}
// Should not reach this point!
return 0;
}
// ------------------------------------------------------------------------------------------------
Float64 DbConvTo< Float64 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
// Is there even a value to attempt to extract?
if (!value || *value == '\0')
{
return 0;
}
// Identify the type of value that must be converted and try to at least approximate something
switch(type)
{
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_GEOMETRY: return static_cast< Float64 >(0);
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG: return ConvTo< Float64 >::From(std::strtol(value, nullptr, 10));
case MYSQL_TYPE_LONGLONG: return ConvTo< Float64 >::From(std::strtoll(value, nullptr, 10));
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: return std::strtod(value, nullptr);
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: return ConvTo< Float64 >::From(MySQLDateStrToSeconds(value));
case MYSQL_TYPE_TIME: return ConvTo< Float64 >::From(MySQLTimeStrToSeconds(value));
case MYSQL_TYPE_TIMESTAMP: return ConvTo< Float64 >::From(MySQLTimestampStrToSeconds(value));
case MYSQL_TYPE_DATETIME: return ConvTo< Float64 >::From(MySQLDatetimeStrToSeconds(value));
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: return MemToNum< Float64 >(reinterpret_cast< const Uint8 * >(value), length);
default:
{
STHROWF("Unknown conversion from (%s) to (%s)", SqMySQLTypenameC(type), tn);
} break;
}
// Should not reach this point!
return 0;
}
// ------------------------------------------------------------------------------------------------
bool DbConvTo< bool >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn)
{
return ConvertToSInt< Int64 >(value, length, type, tn) > 0;
}
} // Namespace:: SqMod

View File

@ -1,126 +0,0 @@
#ifndef _SQMYSQL_CONVERT_HPP_
#define _SQMYSQL_CONVERT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <mysql.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
*
*/
struct DbDecimal;
struct DbDate;
struct DbTime;
struct DbDatetime;
/* ------------------------------------------------------------------------------------------------
* Retrieve the lowercase name of a MySQL data-type.
*/
CSStr SqMySQLTypename(enum_field_types type);
/* ------------------------------------------------------------------------------------------------
* Retrieve the capitalized name of a MySQL data-type.
*/
CSStr SqMySQLTypenameC(enum_field_types type);
/* ------------------------------------------------------------------------------------------------
* Utility used to convert from database types to known types.
*/
template < typename T > struct DbConvTo;
/* ------------------------------------------------------------------------------------------------
* Specialization for signed 8 bit integer.
*/
template<> struct DbConvTo< Int8 >
{
static Int8 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Int8"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for unsigned 8 bit integer.
*/
template<> struct DbConvTo< Uint8 >
{
static Uint8 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Uint8"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for signed 16 bit integer.
*/
template<> struct DbConvTo< Int16 >
{
static Int16 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Int16"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for unsigned 16 bit integer.
*/
template<> struct DbConvTo< Uint16 >
{
static Uint16 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Uint16"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for signed 32 bit integer.
*/
template<> struct DbConvTo< Int32 >
{
static Int32 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Int32"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for unsigned 32 bit integer.
*/
template<> struct DbConvTo< Uint32 >
{
static Uint32 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Uint32"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for signed 64 bit integer.
*/
template<> struct DbConvTo< Int64 >
{
static Int64 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Int64"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for unsigned 64 bit integer.
*/
template<> struct DbConvTo< Uint64 >
{
static Uint64 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Uint64"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for 32 floating point.
*/
template<> struct DbConvTo< Float32 >
{
static Float32 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Float32"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for 64 floating point.
*/
template<> struct DbConvTo< Float64 >
{
static Float64 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Float64"));
};
/* ------------------------------------------------------------------------------------------------
* Specialization for boolean value.
*/
template<> struct DbConvTo< bool >
{
static bool From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Boolean"));
};
} // Namespace:: SqMod
#endif // _SQMYSQL_CONVERT_HPP_

View File

@ -1,587 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Field.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
static inline bool IsDigitsOnly(CSStr str)
{
while (std::isdigit(*str) || std::isspace(*str))
{
++str;
}
// Return whether we reached the end while searching
return *str == '\0';
}
// ------------------------------------------------------------------------------------------------
const Uint32 Field::INVALID_INDEX = std::numeric_limits< Uint32 >::max();
// ------------------------------------------------------------------------------------------------
SQInteger Field::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMySQLField");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Field::Validate(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
// Are we pointing to a valid index?
else if (m_Index >= m_Handle->mFieldCount)
{
SqThrowF("Field index is out of range: %u >= %lu =>[%s:%d]",
m_Index, m_Handle->mFieldCount, file, line);
}
}
#else
void Field::Validate() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
// Are we pointing to a valid index?
else if (m_Index >= m_Handle->mFieldCount)
{
SqThrowF("Field index is out of range: %u >= %lu", m_Index, m_Handle->mFieldCount);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Field::ValidateCreated(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
// Are we pointing to a valid index?
m_Handle->ValidateField(m_Index, file, line);
}
#else
void Field::ValidateCreated() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
// Are we pointing to a valid index?
m_Handle->ValidateField(m_Index);
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Field::ValidateStepped(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
// Do we have a valid row available?
else if (m_Handle->mRow == nullptr)
{
SqThrowF("No row available in MySQL result-set =>[%s:%d]", file, line);
}
// Are we pointing to a valid index?
m_Handle->ValidateField(m_Index, file, line);
}
#else
void Field::ValidateStepped() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
// Do we have a valid row available?
else if (m_Handle->mRow == nullptr)
{
SqThrowF("No row available in MySQL result-set");
}
// Are we pointing to a valid index?
m_Handle->ValidateField(m_Index);
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & Field::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const ResRef & Field::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & Field::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const ResRef & Field::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & Field::GetStepped(CCStr file, Int32 line) const
{
ValidateStepped(file, line);
return m_Handle;
}
#else
const ResRef & Field::GetStepped() const
{
ValidateStepped();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Field::ValidateField(Uint32 idx, CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
// Validate the specified field index
m_Handle->ValidateField(idx, file, line);
}
#else
void Field::ValidateField(Uint32 idx) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
// Validate the specified field index
m_Handle->ValidateField(idx);
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Field::SetIndex(const Object & field)
{
// Where the index will be extracted
Uint32 idx = INVALID_INDEX;
// Grab the object virtual machine
HSQUIRRELVM vm = field.GetVM();
// Remember the current stack size
const StackGuard sg(vm);
// Push the specified object onto the stack
Var< const Object & >::push(vm, field);
// Identify the type of field was given
switch (field.GetType())
{
// Is this a string value?
case OT_STRING:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty field name");
}
// Attempt to find a field with the specified name
idx = m_Handle->GetFieldIndex(val.mPtr);
} break;
// Is this an integer value? (or at least can be easily converted to one)
case OT_INTEGER:
case OT_FLOAT:
case OT_BOOL:
{
idx = ConvTo< Uint32 >::From(SqMod_PopStackInteger(vm, -1));
} break;
// Is this an instance that we can extract either a string or integer from it?
case OT_INSTANCE:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty field name");
}
// Check if this value is made only of digits
else if (IsDigitsOnly(val.mPtr))
{
idx = ConvNum< Uint32 >::FromStr(val.mPtr);
}
// Attempt to find a field with the specified name
else
{
idx = m_Handle->GetFieldIndex(val.mPtr);
}
} break;
// We don't recognize this kind of value!
default: STHROWF("Unknown field index of type (%s)", SqTypeName(field.GetType()));
}
// Validate the obtained field index
SQMOD_VALIDATE_FIELD(*this, idx);
// Assign the new index
m_Index = idx;
}
// ------------------------------------------------------------------------------------------------
Object Field::GetResultSet() const
{
return Object();
}
// ------------------------------------------------------------------------------------------------
Object Field::GetConnection() const
{
return Object();
}
// ------------------------------------------------------------------------------------------------
bool Field::GetBoolean() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< bool >::From(m_Handle->mBinds[m_Index].mUint64);
}
// Retrieve the value directly from the row
return DbConvTo< bool >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQChar Field::GetChar() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< SQChar >::From(m_Handle->mBinds[m_Index].mInt32[0]);
}
// Retrieve the value directly from the row
return DbConvTo< SQChar >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetInteger() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
#ifdef _SQ64
return ConvTo< SQInteger >::From(m_Handle->mBinds[m_Index].mInt64);
#else
return ConvTo< SQInteger >::From(m_Handle->mBinds[m_Index].mInt32[0]);
#endif // _SQ64
}
// Retrieve the value directly from the row
return DbConvTo< SQInteger >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQFloat Field::GetFloat() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
#ifdef SQUSEDOUBLE
return ConvTo< SQFloat >::From(m_Handle->mBinds[m_Index].mFloat64);
#else
return ConvTo< SQFloat >::From(m_Handle->mBinds[m_Index].mFloat32[0]);
#endif // SQUSEDOUBLE
}
// Retrieve the value directly from the row
return DbConvTo< SQFloat >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetInt8() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Int8 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Int8 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetUint8() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Uint8 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Uint8 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetInt16() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Int16 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Int16 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetUint16() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Uint16 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Uint16 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetInt32() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Int32 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Int32 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQInteger Field::GetUint32() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Uint32 >::From(m_Handle->mBinds[m_Index].mInt64);
}
// Retrieve the value directly from the row
return DbConvTo< Uint32 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
Object Field::GetInt64() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Obtain the initial stack size
const StackGuard sg;
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
SqMod_PushSLongObject(DefaultVM::Get(),
ConvTo< Int64 >::From(m_Handle->mBinds[m_Index].mInt64));
}
// Retrieve the value directly from the row
else
{
SqMod_PushSLongObject(DefaultVM::Get(),
DbConvTo< Int64 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type));
}
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Field::GetUint64() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Obtain the initial stack size
const StackGuard sg;
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
SqMod_PushULongObject(DefaultVM::Get(),
ConvTo< Uint64 >::From(m_Handle->mBinds[m_Index].mUint64));
}
// Retrieve the value directly from the row
else
{
SqMod_PushULongObject(DefaultVM::Get(),
DbConvTo< Uint64 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type));
}
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
SQFloat Field::GetFloat32() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Float32 >::From(m_Handle->mBinds[m_Index].mFloat32[0]);
}
// Retrieve the value directly from the row
return DbConvTo< Float32 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
SQFloat Field::GetFloat64() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Should we retrieve the value from the bind wrapper?
if (m_Handle->mStatement)
{
return ConvTo< Float64 >::From(m_Handle->mBinds[m_Index].mFloat64);
}
// Retrieve the value directly from the row
return DbConvTo< Float64 >::From(m_Handle->mRow[m_Index],
m_Handle->mLengths[m_Index],
m_Handle->mFields[m_Index].type);
}
// ------------------------------------------------------------------------------------------------
Object Field::GetString() const
{
SQMOD_VALIDATE_STEPPED(*this);
// Obtain the initial stack size
const StackGuard sg;
// Retrieve the value directly from the row and push it on the stack
sq_pushstring(DefaultVM::Get(), m_Handle->mRow[m_Index], m_Handle->mLengths[m_Index]);
// Obtain the object from the stack
Object stro(-1, DefaultVM::Get());
// Restore the stack
sg.Restore();
// Return it the string object
return stro;
}
// ------------------------------------------------------------------------------------------------
Object Field::GetBuffer() const
{
return NullObject();
}
// ------------------------------------------------------------------------------------------------
Object Field::GetBlob() const
{
return NullObject();
}
// ================================================================================================
void Register_Field(Table & sqlns)
{
sqlns.Bind(_SC("Field"),
Class< Field >(sqlns.GetVM(), _SC("SqMySQLField"))
// Constructors
.Ctor()
.Ctor< const Field & >()
// Meta-methods
.Func(_SC("_cmp"), &Field::Cmp)
.SquirrelFunc(_SC("_typename"), &Field::Typename)
.Func(_SC("_tostring"), &Field::ToString)
// Properties
.Prop(_SC("IsValid"), &Field::IsValid)
.Prop(_SC("References"), &Field::GetRefCount)
.Prop(_SC("Index"), &Field::GetIndex)
.Prop(_SC("ResultSet"), &Field::GetResultSet)
.Prop(_SC("Connection"), &Field::GetConnection)
.Prop(_SC("Bool"), &Field::GetBoolean)
.Prop(_SC("Boolean"), &Field::GetBoolean)
.Prop(_SC("Char"), &Field::GetChar)
.Prop(_SC("Integer"), &Field::GetInteger)
.Prop(_SC("Float"), &Field::GetFloat)
.Prop(_SC("Int8"), &Field::GetInt8)
.Prop(_SC("Uint8"), &Field::GetUint8)
.Prop(_SC("Int16"), &Field::GetInt16)
.Prop(_SC("Uint16"), &Field::GetUint16)
.Prop(_SC("Int32"), &Field::GetInt32)
.Prop(_SC("Uint32"), &Field::GetUint32)
.Prop(_SC("Int64"), &Field::GetInt64)
.Prop(_SC("Uint64"), &Field::GetUint64)
.Prop(_SC("Float32"), &Field::GetFloat32)
.Prop(_SC("Float64"), &Field::GetFloat64)
.Prop(_SC("String"), &Field::GetString)
.Prop(_SC("Buffer"), &Field::GetBuffer)
.Prop(_SC("Blob"), &Field::GetBlob)
// Member Methods
.Func(_SC("Release"), &Field::Release)
);
}
} // Namespace:: SqMod

View File

@ -1,385 +0,0 @@
#ifndef _SQMYSQL_FIELD_HPP_
#define _SQMYSQL_FIELD_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/ResultSet.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Used to manage and interact with fields from result-sets.
*/
class Field
{
// --------------------------------------------------------------------------------------------
friend class ResultSet;
private:
// --------------------------------------------------------------------------------------------
Uint32 m_Index; // The actual index of the referenced field.
ResRef m_Handle; // Reference to the actual database result-set.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle and field index, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle and field index, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle, field index and row, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateStepped(CCStr file, Int32 line) const;
#else
void ValidateStepped() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle and field index, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetValid(CCStr file, Int32 line) const;
#else
const ResRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle and field index, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetCreated(CCStr file, Int32 line) const;
#else
const ResRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle field index and row, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetStepped(CCStr file, Int32 line) const;
#else
const ResRef & GetStepped() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the associated result-set handle and field index, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateField(Uint32 idx, CCStr file, Int32 line) const;
#else
void ValidateField(Uint32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(Int32 idx)
{
SQMOD_VALIDATE_FIELD(*this, idx);
// Assign the new index
m_Index = idx;
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(CSStr name)
{
SetIndex(SQMOD_GET_CREATED(*this)->GetFieldIndex(name));
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(const Object & field);
public:
// --------------------------------------------------------------------------------------------
static const Uint32 INVALID_INDEX; // Value that represents an invalid index.
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
Field()
: m_Index(INVALID_INDEX), m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* No field constructor.
*/
Field(const ResRef & rset)
: m_Index(INVALID_INDEX), m_Handle(rset)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Index constructor.
*/
Field(const ResRef & rset, Uint32 idx)
: m_Index(idx), m_Handle(rset)
{
SQMOD_VALIDATE_FIELD(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Name constructor.
*/
Field(const ResRef & rset, CSStr name)
: m_Index(rset ? rset->GetFieldIndex(name) : -1), m_Handle(rset)
{
SQMOD_VALIDATE_FIELD(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Dynamic constructor.
*/
Field(const ResRef & rset, const Object & field)
: m_Index(INVALID_INDEX), m_Handle(rset)
{
if (!m_Handle)
{
STHROWF("Invalid MySQL result-set reference");
}
// Extract the index
SetIndex(field);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Field(const Field & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Field(Field && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Field & operator = (const Field & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Field & operator = (Field && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two result-set field indexes.
*/
bool operator == (const Field & o) const
{
return (m_Index == o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two result-set field indexes.
*/
bool operator != (const Field & o) const
{
return (m_Index != o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return (m_Handle && m_Handle->CheckFieldIndex(m_Index));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Field & o) const
{
if (m_Index == o.m_Index)
{
return 0;
}
else if (m_Index > o.m_Index)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
CSStr val = nullptr;
// Can we attempt to return the parameter name?
if (m_Handle && m_Handle->CheckFieldIndex(m_Index))
{
val = m_Handle->mFields[m_Index].name;
}
else
{
val = ToStrF(_SC("%d"), m_Index);
}
// Return the value if valid
return val ? val : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether the field is valid.
*/
bool IsValid() const
{
return m_Handle; // An invalid result-set means an invalid field
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the associated result-set handle.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced field index.
*/
SQInteger GetIndex() const
{
return ConvTo< SQInteger >::From(m_Index);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced database result-set.
*/
Object GetResultSet() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced database connection.
*/
Object GetConnection() const;
/* --------------------------------------------------------------------------------------------
* Release the reference to the referenced database result-set and field index.
*/
void Release()
{
m_Handle.Reset();
m_Index = INVALID_INDEX;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a boolean value.
*/
bool GetBoolean() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a character.
*/
SQChar GetChar() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a native script integer.
*/
SQInteger GetInteger() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a native script floating point.
*/
SQFloat GetFloat() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a signed 8 bit integer value.
*/
SQInteger GetInt8() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as an unsigned 8 bit integer value.
*/
SQInteger GetUint8() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a signed 16 bit integer value.
*/
SQInteger GetInt16() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as an unsigned 16 bit integer value.
*/
SQInteger GetUint16() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a signed 32 bit integer value.
*/
SQInteger GetInt32() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as an unsigned 32 bit integer value.
*/
SQInteger GetUint32() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a signed 64 bit integer value.
*/
Object GetInt64() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as an unsigned 64 bit integer value.
*/
Object GetUint64() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a 32 bit floating point value.
*/
SQFloat GetFloat32() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a 64 bit floating point value.
*/
SQFloat GetFloat64() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a string value.
*/
Object GetString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a memory buffer.
*/
Object GetBuffer() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced field as a memory blob.
*/
Object GetBlob() const;
};
} // Namespace:: SqMod
#endif // _SQMYSQL_FIELD_HPP_

View File

@ -1,225 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
#include "Account.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstring>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void ConnHnd::GrabCurrent()
{
mErrNo = mysql_errno(mPtr);
mErrStr.assign(mysql_error(mPtr));
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ConnHnd::ThrowCurrent(CCStr act, CCStr file, Int32 line)
{
GrabCurrent();
// Throw the exception with the resulted message
throw Sqrat::Exception(FmtStr("%s (%u) : %s =>[%s:%d]", act,
mErrNo, mErrStr.c_str(), file, line));
}
#else
void ConnHnd::ThrowCurrent(CCStr act)
{
GrabCurrent();
// Throw the exception with the resulted message
throw Sqrat::Exception(FmtStr("%s (%u) : %s", act,
mErrNo, mErrStr.c_str()));
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
ConnHnd::ConnHnd()
: mPtr(nullptr)
, mErrNo(0)
, mErrStr(_SC(""))
, mPort()
, mHost()
, mUser()
, mPass()
, mName()
, mSocket()
, mFlags()
, mSSL_Key()
, mSSL_Cert()
, mSSL_CA()
, mSSL_CA_Path()
, mSSL_Cipher()
, mCharset()
, mAutoCommit()
, mInTransaction(false)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
ConnHnd::~ConnHnd()
{
Disconnect();
}
// ------------------------------------------------------------------------------------------------
void ConnHnd::Create(const Account & acc)
{
// Is this connection already created?
if (mPtr != nullptr)
{
STHROWF("MySQL connection was already created");
}
// Attempt to initialize a connection handle
mPtr = mysql_init(NULL);
// See if a connection handle could be initialized
if (!mPtr)
{
STHROWF("Cannot initialize MYSQL connection structure");
}
// Store all the account information
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();
mAutoCommit = acc.GetAutoCommit();
// Attempt to configure SSL if specified
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)
{
SQMOD_THROW_CURRENT(*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))
{
SQMOD_THROW_CURRENT(*this, "Cannot connect to database");
}
// Attempt configure the auto-commit option
else if (mysql_autocommit(mPtr, mAutoCommit) != 0)
{
SQMOD_THROW_CURRENT(*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)
{
SQMOD_THROW_CURRENT(*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);
}
}
// ------------------------------------------------------------------------------------------------
void ConnHnd::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;
}
}
// ------------------------------------------------------------------------------------------------
Uint64 ConnHnd::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
if (mysql_real_query(mPtr, query, size))
{
SQMOD_THROW_CURRENT(*this, "Unable to execute query");
}
// Where the number of affected rows will be stored
Uint64 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 if (mysql_errno(mPtr) != 0)
{
SQMOD_THROW_CURRENT(*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)
{
SQMOD_THROW_CURRENT(*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

View File

@ -1,105 +0,0 @@
#ifndef _SQMYSQL_HANDLE_CONNECTION_HPP_
#define _SQMYSQL_HANDLE_CONNECTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain connection.
*/
struct ConnHnd
{
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 MYSQL_RES ResType; // Database result type.
public:
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The connection handle resource.
// --------------------------------------------------------------------------------------------
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.
// --------------------------------------------------------------------------------------------
bool mAutoCommit; // Whether autocommit is enabled on this connection.
bool mInTransaction; // Whether the connection is in the middle of a transaction.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ConnHnd();
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ConnHnd();
/* --------------------------------------------------------------------------------------------
* Grab the current error in the connection handle.
*/
void GrabCurrent();
/* --------------------------------------------------------------------------------------------
* 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 connection handle.
*/
void Create(const Account & acc);
/* --------------------------------------------------------------------------------------------
* Disconnect the managed connection handle.
*/
void Disconnect();
/* --------------------------------------------------------------------------------------------
* Execute a query on the server.
*/
Uint64 Execute(CSStr query, Ulong size = 0UL);
};
} // Namespace:: SqMod
#endif // _SQMYSQL_HANDLE_CONNECTION_HPP_

View File

@ -1,444 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/ResultSet.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstring>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void ResBind::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_SET:
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::ResHnd()
: mPtr(nullptr)
, mFieldCount(0)
, mLengths(nullptr)
, mFields(nullptr)
, mBinds(nullptr)
, mMyBinds(nullptr)
, mRow(nullptr)
, mConnection()
, mStatement()
, mIndexes()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
ResHnd::~ResHnd()
{
// 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->mPtr);
}
// Are there any bind wrappers that we should free?
if (mBinds)
{
delete [] (mBinds);
}
}
// ------------------------------------------------------------------------------------------------
void ResHnd::GrabCurrent()
{
if (mConnection)
{
mConnection->GrabCurrent();
}
else if (mStatement)
{
mStatement->GrabCurrent();
}
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResHnd::ThrowCurrent(CCStr act, CCStr file, Int32 line)
{
GrabCurrent();
// Throw the exception with the resulted message
if (mConnection)
{
mConnection->ThrowCurrent(act, file, line);
}
else if (mStatement)
{
mStatement->ThrowCurrent(act, file, line);
}
}
#else
void ResHnd::ThrowCurrent(CCStr act)
{
GrabCurrent();
// Throw the exception with the resulted message
if (mConnection)
{
mConnection->ThrowCurrent(act);
}
else if (mStatement)
{
mStatement->ThrowCurrent(act);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResHnd::ValidateField(Uint32 idx, CCStr file, Int32 line) const
{
// Is the handle valid?
if (mPtr == nullptr)
{
STHROWF("Invalid MySQL result-set =>[%s:%d]", file, line);
}
else if (idx >= mFieldCount)
{
STHROWF("Field index is out of range: %u >= %lu =>[%s:%d]", idx, mFieldCount, file, line);
}
}
#else
void ResHnd::ValidateField(Uint32 idx) const
{
// Is the handle valid?
if (mPtr == nullptr)
{
STHROWF("Invalid MySQL result-set");
}
else if (idx >= mFieldCount)
{
STHROWF("Field index is out of range: %u >= %lu", idx, mFieldCount);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Uint32 ResHnd::GetFieldIndex(CSStr name)
{
// Validate the handle
if (!mPtr)
{
STHROWF("Invalid MySQL result-set");
}
// Attempt to find the specified field
const IndexMap::iterator itr = mIndexes.find(name);
// Was there a field with the specified name?
if (itr != mIndexes.end())
{
return itr->second;
}
// No such field exists (expecting the invoker to validate the result)
return std::numeric_limits< Uint32 >::max();
}
// ------------------------------------------------------------------------------------------------
void ResHnd::Create(const ConnRef & conn)
{
// Is this result-set already created?
if (mPtr != nullptr)
{
STHROWF("MySQL result-set was already created");
}
// Validate the specified connection handle
else if (!conn)
{
STHROWF("Invalid MySQL connection reference");
}
else if (conn->mPtr == nullptr)
{
STHROWF("Invalid MySQL connection");
}
// Store the connection handle
mConnection = conn;
// Retrieve the complete result-set to the client, if any
mPtr = mysql_store_result(mConnection->mPtr);
// 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)
{
// Associate the current field name with the current index
mIndexes[mFields[i].name] = i;
// Include table names if available
if (mFields[i].table_length > 0)
{
mIndexes[ToStrF("%s.%s", mFields[i].table, mFields[i].name)] = i;
}
else if (mFields[i].org_table_length > 0)
{
mIndexes[ToStrF("%s.%s", mFields[i].org_table, mFields[i].name)] = i;
}
}
}
// ------------------------------------------------------------------------------------------------
void ResHnd::Create(const StmtRef & stmt)
{
// Is this result-set already created?
if (mPtr != nullptr)
{
STHROWF("MySQL result-set was already created");
}
// Validate the given statement handle
else if (!stmt)
{
STHROWF("Invalid MySQL statement reference");
}
else if (stmt->mPtr == nullptr)
{
STHROWF("Invalid MySQL statement");
}
// Store the statement handle
mStatement = stmt;
// 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->mPtr, STMT_ATTR_UPDATE_MAX_LENGTH, &max_length) != 0)
{
SQMOD_THROW_CURRENT(*mStatement, "Cannot apply MySQL statement attribute");
}
// Attempt to buffer the complete result-set on the client
if (mysql_stmt_store_result(mStatement->mPtr))
{
SQMOD_THROW_CURRENT(*mStatement, "Cannot buffer MySQL result-set");
}
// Obtain the number of fields in the result-set
mFieldCount = mysql_stmt_field_count(mStatement->mPtr);
// Obtain the result-set meta-data
mPtr = mysql_stmt_result_metadata(mStatement->mPtr);
// 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 ResBind[mFieldCount];
// Validate the allocated structures
if (!mBinds)
{
STHROWF("Unable to allocate MySQL bind point wrappers");
}
// Allocate the bind points
mMyBinds = new BindType[mFieldCount];
// Validate the allocated structures
if (!mMyBinds)
{
STHROWF("Unable to allocate MySQL bind point structures");
}
// Allocate the row pointers
mRow = new CStr[mFieldCount];
// Validate the allocated structures
if (!mRow)
{
STHROWF("Unable to allocate MySQL row pointers");
}
// 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;
// Include table names if available
if (mFields[i].table_length > 0)
{
mIndexes[ToStrF("%s.%s", mFields[i].table, mFields[i].name)] = i;
}
else if (mFields[i].org_table_length > 0)
{
mIndexes[ToStrF("%s.%s", mFields[i].org_table, 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->mPtr, mMyBinds) != 0)
{
SQMOD_THROW_CURRENT(*mStatement, "Cannot bind MySQL variables to statement");
}
}
// ------------------------------------------------------------------------------------------------
Uint64 ResHnd::RowIndex() const
{
// Is this result-set even valid?
if (!mPtr)
{
STHROWF("Invalid MySQL result-set");
}
// Did we come from a statement?
else if (mStatement)
{
return (Uint64)mysql_stmt_row_tell(mStatement->mPtr);
}
// Just retrieve it from the result set
return (Uint64)mysql_row_tell(mPtr);
}
// ------------------------------------------------------------------------------------------------
Uint64 ResHnd::RowCount() const
{
// Is this result-set even valid?
if (!mPtr)
{
STHROWF("Invalid MySQL result-set");
}
// Did we come from a statement?
else if (mStatement)
{
return mysql_stmt_num_rows(mStatement->mPtr);
}
// Just retrieve it from the result set
return mysql_num_rows(mPtr);
}
// ------------------------------------------------------------------------------------------------
bool ResHnd::Next()
{
// Is this result-set even valid?
if (!mPtr)
{
STHROWF("Invalid MySQL result-set");
}
// Did we come from a statement?
if (mStatement)
{
// Step the statement
return !mysql_stmt_fetch(mStatement->mPtr);
}
// Fetch another row from the result set
mRow = mysql_fetch_row(mPtr);
// Fetch the data lengths
mLengths = mysql_fetch_lengths(mPtr);
// Return whether the fetched row is valid
return (mRow != NULL);
}
// ------------------------------------------------------------------------------------------------
bool ResHnd::SetRowIndex(Uint64 index)
{
// Is this result-set even valid?
if (!mPtr)
{
STHROWF("Invalid MySQL result-set");
}
// Did we come from a statement?
else if (mStatement)
{
mysql_stmt_data_seek(mStatement->mPtr, index);
}
else
{
mysql_data_seek(mPtr, index);
}
// Step the result set
return Next();
}
} // Namespace:: SqMod

View File

@ -1,243 +0,0 @@
#ifndef _SQMYSQL_HANDLE_RESULTSET_HPP_
#define _SQMYSQL_HANDLE_RESULTSET_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <unordered_map>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain field.
*/
struct ResBind
{
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 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.
// --------------------------------------------------------------------------------------------
typedef std::unordered_map< String, Uint32 > IndexMap;
public:
// --------------------------------------------------------------------------------------------
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.
};
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ResBind()
: mIsNull(0), mError(0), mData(), mBind(nullptr), mTime(), mUint64(0)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
ResBind(const ResBind & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
ResBind(ResBind && o) = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
ResBind & operator = (const ResBind & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
ResBind & operator = (ResBind && 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 ResHnd
{
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 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.
// --------------------------------------------------------------------------------------------
typedef std::unordered_map< String, Uint32 > IndexMap; // Name to index association of fields.
public:
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The managed result-set 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.
ResBind * mBinds; // Bind wrappers.
BindType * mMyBinds; // Bind points.
RowType mRow; // Row data.
// --------------------------------------------------------------------------------------------
ConnRef mConnection; // Associated connection.
StmtRef mStatement; // Associated statement.
IndexMap mIndexes; // Field names and their associated index.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ResHnd();
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ResHnd();
/* --------------------------------------------------------------------------------------------
* Grab the current error in the associated statement or connection handle.
*/
void GrabCurrent();
/* --------------------------------------------------------------------------------------------
* Grab the current error in the associated statement or 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
/* --------------------------------------------------------------------------------------------
* Validate the statement handle and field index and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateField(Uint32 idx, CCStr file, Int32 line) const;
#else
void ValidateField(Uint32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Check whether a specific field index is within range.
*/
bool CheckFieldIndex(Uint32 idx) const
{
return (idx < mFieldCount);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the field index associated with the specified name.
*/
Uint32 GetFieldIndex(CSStr name);
/* --------------------------------------------------------------------------------------------
* Create the result-set from a Connection.
*/
void Create(const ConnRef & conn);
/* --------------------------------------------------------------------------------------------
* Create the result-set from a Statement.
*/
void Create(const StmtRef & stmt);
/* --------------------------------------------------------------------------------------------
* Returns the current position of the row cursor for the last Next().
*/
Uint64 RowIndex() const;
/* --------------------------------------------------------------------------------------------
* Returns the number of rows in the result set.
*/
Uint64 RowCount() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the next row from the query.
*/
bool Next();
/* --------------------------------------------------------------------------------------------
* Seeks to an arbitrary row in a query result set.
*/
bool SetRowIndex(Uint64 index);
};
} // Namespace:: SqMod
#endif // _SQMYSQL_HANDLE_RESULTSET_HPP_

View File

@ -1,249 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstring>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void StmtBind::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_SET:
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");
}
}
// ------------------------------------------------------------------------------------------------
void StmtHnd::GrabCurrent()
{
mErrNo = mysql_stmt_errno(mPtr);
mErrStr.assign(mysql_stmt_error(mPtr));
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void StmtHnd::ThrowCurrent(CCStr act, CCStr file, Int32 line)
{
GrabCurrent();
// Throw the exception with the resulted message
throw Sqrat::Exception(FmtStr("%s (%u) : %s =>[%s:%d]", act,
mErrNo, mErrStr.c_str(), file, line));
}
#else
void StmtHnd::ThrowCurrent(CCStr act)
{
GrabCurrent();
// Throw the exception with the resulted message
throw Sqrat::Exception(FmtStr("%s (%u) : %s", act,
mErrNo, mErrStr.c_str()));
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void StmtHnd::ValidateParam(Uint32 idx, CCStr file, Int32 line) const
{
// Is the handle valid?
if (mPtr == nullptr)
{
STHROWF("Invalid MySQL statement reference =>[%s:%d]", file, line);
}
else if (idx >= mParams)
{
STHROWF("Parameter index is out of range: %u >= %lu =>[%s:%d]", idx, mParams, file, line);
}
}
#else
void StmtHnd::ValidateParam(Uint32 idx) const
{
// Is the handle valid?
if (mPtr == nullptr)
{
STHROWF("Invalid MySQL statement reference");
}
else if (idx >= mParams)
{
STHROWF("Parameter index is out of range: %u >= %lu", idx, mParams);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
StmtHnd::StmtHnd()
: mPtr(nullptr)
, mErrNo(0)
, mErrStr(_SC(""))
, mParams(0)
, mBinds(nullptr)
, mMyBinds(nullptr)
, mConnection()
, mQuery(_SC(""))
{
}
// ------------------------------------------------------------------------------------------------
StmtHnd::~StmtHnd()
{
// 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);
}
}
// ------------------------------------------------------------------------------------------------
void StmtHnd::Create(const ConnRef & conn, CSStr query)
{
// Is this statement already created?
if (mPtr != nullptr)
{
STHROWF("MySQL statement was already created");
}
// Validate the specified connection handle
else if (!conn)
{
STHROWF("Invalid MySQL connection reference");
}
else if (conn->mPtr == nullptr)
{
STHROWF("Invalid MySQL connection");
}
// Validate the specified query string
else if (!query || *query == '\0')
{
STHROWF("Invalid or empty MySQL query");
}
// Store the connection handle and query string
mConnection = conn;
mQuery.assign(query);
// Attempt to initialize the statement handle
mPtr = mysql_stmt_init(mConnection->mPtr);
// Validate the obtained statement handle
if (!mPtr)
{
SQMOD_THROW_CURRENT(*mConnection, "Cannot initialize MySQL statement");
}
// Attempt to prepare the statement with the given query
else if (mysql_stmt_prepare(mPtr, mQuery.c_str(), mQuery.size()))
{
SQMOD_THROW_CURRENT(*this, "Cannot prepare MySQL 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)
{
// We're done here!
return;
}
// Allocate the binding wrappers
mBinds = new StmtBind[mParams];
// Validate the allocated memory
if (!mBinds)
{
STHROWF("Unable to allocate MySQL bind point wrappers");
}
// Allocate the binding points
mMyBinds = new BindType[mParams];
// Validate the allocated memory
if (!mMyBinds)
{
STHROWF("Unable to allocate MySQL bind point structures");
}
// Reset the allocated points
std::memset(mMyBinds, 0, sizeof(BindType) * mParams);
}
} // Namespace:: SqMod

View File

@ -1,197 +0,0 @@
#ifndef _SQMYSQL_HANDLE_STATEMENT_HPP_
#define _SQMYSQL_HANDLE_STATEMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain bind point.
*/
struct StmtBind
{
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; // Database bind type.
typedef MYSQL_TIME TimeType; // Database time type.
typedef my_bool BoolType; // Database boolean type.
public:
// --------------------------------------------------------------------------------------------
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.
};
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
StmtBind()
: mIsNull(0), mError(0), mData(), mBind(nullptr), mTime(), mUint64(0)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
StmtBind(const StmtBind & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
StmtBind(StmtBind && o) = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
StmtBind & operator = (const StmtBind & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
StmtBind & operator = (StmtBind && 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 = 0);
};
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain statement handle.
*/
struct StmtHnd
{
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; // Database bind type.
typedef MYSQL_TIME TimeType; // Database time type.
typedef my_bool BoolType; // Database boolean type.
public:
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The managed statement handle.
// --------------------------------------------------------------------------------------------
Uint32 mErrNo; // Last received error string.
String mErrStr; // Last received error message.
// --------------------------------------------------------------------------------------------
Ulong mParams; // Number of parameters in the statement.
StmtBind * mBinds; // List of parameter binds.
BindType * mMyBinds; // List of parameter binds.
// --------------------------------------------------------------------------------------------
ConnRef mConnection; // Reference to the associated connection.
String mQuery; // The query string.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
StmtHnd();
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~StmtHnd();
/* --------------------------------------------------------------------------------------------
* Grab the current error in the associated statement handle.
*/
void GrabCurrent();
/* --------------------------------------------------------------------------------------------
* Grab the current error in the associated statement 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
/* --------------------------------------------------------------------------------------------
* Validate the associated statement handle and parameter index and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateParam(Uint32 idx, CCStr file, Int32 line) const;
#else
void ValidateParam(Uint32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Check whether a specific param index is within range.
*/
bool CheckParamIndex(Uint32 idx) const
{
return (idx < mParams);
}
/* --------------------------------------------------------------------------------------------
* Create the actual statement.
*/
void Create(const ConnRef & conn, CSStr query);
};
} // Namespace:: SqMod
#endif // _SQMYSQL_HANDLE_STATEMENT_HPP_

View File

@ -1,218 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Account(Table & sqlns);
extern void Register_Connection(Table & sqlns);
extern void Register_Field(Table & sqlns);
extern void Register_ResultSet(Table & sqlns);
extern void Register_Statement(Table & sqlns);
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQMYSQL_NAME);
// Registration failed
return false;
}
Table sqlns(vm);
Register_Account(sqlns);
Register_Connection(sqlns);
Register_Field(sqlns);
Register_ResultSet(sqlns);
Register_Statement(sqlns);
RootTable(vm).Bind(_SC("SqMySQL"), sqlns);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQMYSQL_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQMYSQL_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQMYSQL_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQMYSQL_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Release script resources...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQMYSQL_NAME))
{
try
{
ImportModuleAPI(_Func, SQMYSQL_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
std::puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQMYSQL_NAME);
OutputMessage("Author: %s", SQMYSQL_AUTHOR);
OutputMessage("Legal: %s", SQMYSQL_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
std::puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQMYSQL_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQMYSQL_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMYSQL_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQMYSQL_NAME);
// Dummy spacing
std::puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,10 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Parameter.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
} // Namespace:: SqMod

View File

@ -1,51 +0,0 @@
#ifndef _SQMYSQL_PARAMETER_HPP_
#define _SQMYSQL_PARAMETER_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* ...
*/
class Parameter
{
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Parameter();
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Parameter(const Parameter & o);
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Parameter(Parameter && o);
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Parameter();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Parameter & operator = (const Parameter & o);
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Parameter & operator = (Parameter && o);
};
} // Namespace:: SqMod
#endif // _SQMYSQL_PARAMETER_HPP_

View File

@ -1,287 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "ResultSet.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger ResultSet::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMySQLResultSet");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResultSet::Validate(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
}
#else
void ResultSet::Validate() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResultSet::ValidateCreated(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL result-set =>[%s:%d]", file, line);
}
}
#else
void ResultSet::ValidateCreated() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL result-set");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResultSet::ValidateStepped(CCStr file, Int32 line) const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line);
}
// Do we have a valid row available?
else if (m_Handle->mRow == nullptr)
{
SqThrowF("No row available in MySQL result-set =>[%s:%d]", file, line);
}
}
#else
void ResultSet::ValidateStepped() const
{
// Do we have a valid result-set handle?
if (!m_Handle)
{
SqThrowF("Invalid MySQL result-set reference");
}
// Do we have a valid row available?
else if (m_Handle->mRow == nullptr)
{
SqThrowF("No row available in MySQL result-set");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & ResultSet::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const ResRef & ResultSet::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & ResultSet::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const ResRef & ResultSet::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & ResultSet::GetStepped(CCStr file, Int32 line) const
{
ValidateStepped(file, line);
return m_Handle;
}
#else
const ResRef & ResultSet::GetStepped() const
{
ValidateStepped();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ResultSet::ValidateField(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
m_Handle->ValidateField(idx, file, line);
}
#else
void ResultSet::ValidateField(Int32 idx) const
{
ValidateCreated();
m_Handle->ValidateField(idx);
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Array ResultSet::GetFieldNames() const
{
SQMOD_VALIDATE_CREATED(*this);
// Grab the number of available fields
const SQInteger fcount = ConvTo< SQInteger >::From(m_Handle->mFieldCount);
// Grab the array with field instances
const ResHnd::FieldType * fields = m_Handle->mFields;
// Is there even something to process?
if (!fcount || !fields)
{
return Array(DefaultVM::Get(), 0);
}
// Allocate an array with the same amount of elements as the number of fields
Array arr(DefaultVM::Get(), fcount);
// Iterate over all the available fields and insert them into the created array
for (SQInteger n = 0; n < fcount; ++n)
{
arr.SetValue(n, (fields[n].name == nullptr) ? ToStrF("<field_%ld>", n) : fields[n].name);
}
// Return the resulted array
return arr;
}
// ------------------------------------------------------------------------------------------------
Array ResultSet::GetFieldsArray() const
{
SQMOD_VALIDATE_CREATED(*this);
// Grab the number of available fields
const SQInteger fcount = ConvTo< SQInteger >::From(m_Handle->mFieldCount);
// Is there even something to process?
if (!fcount)
{
return Array(DefaultVM::Get(), 0);
}
// Create a field instance to insert as copy
Field field(m_Handle);
// Allocate an array with the same amount of elements as the number of fields
Array arr(DefaultVM::Get(), fcount);
// Iterate over all the available fields and insert them into the created array
for (SQInteger n = 0; n < fcount; ++n)
{
// Update the field index
field.SetIndex(ConvTo< Int32 >::From(n));
// Insert a copy of the field instance into the array
arr.SetValue(n, field);
}
// Return the resulted array
return arr;
}
// ------------------------------------------------------------------------------------------------
Table ResultSet::GetFieldsTable() const
{
SQMOD_VALIDATE_CREATED(*this);
// Grab the number of available fields
const SQInteger fcount = ConvTo< SQInteger >::From(m_Handle->mFieldCount);
// Grab the array with field instances
const ResHnd::FieldType * fields = m_Handle->mFields;
// Is there even something to process?
if (!fcount || !fields)
{
return Table();
}
// Create a field instance to insert as copy
Field field(m_Handle);
// Allocate a table to be populated with field instances
Table tbl(DefaultVM::Get(), fcount);
// Iterate over all the available fields and insert them into the created table
for (SQInteger n = 0; n < fcount; ++n)
{
// Update the field index
field.SetIndex(ConvTo< Int32 >::From(n));
// Insert a copy of the field instance into the table
tbl.SetValue((fields[n].name == nullptr) ? ToStrF("<field_%ld>", n) : fields[n].name, field);
}
// Return the resulted table
return tbl;
}
// ================================================================================================
void Register_ResultSet(Table & sqlns)
{
sqlns.Bind(_SC("ResultSet")
, Class< ResultSet >(sqlns.GetVM(), _SC("SqMySQLResultSet"))
// Constructors
.Ctor()
.Ctor< const ResultSet & >()
// Core Meta-methods
.Func(_SC("_cmp"), &ResultSet::Cmp)
.SquirrelFunc(_SC("_typename"), &ResultSet::Typename)
.Func(_SC("_tostring"), &ResultSet::ToString)
// Properties
.Prop(_SC("IsValid"), &ResultSet::IsValid)
.Prop(_SC("FieldNames"), &ResultSet::GetFieldNames)
.Prop(_SC("FieldsArray"), &ResultSet::GetFieldsArray)
.Prop(_SC("FieldsTable"), &ResultSet::GetFieldsTable)
.Prop(_SC("RowIndex"), &ResultSet::RowIndex)
.Prop(_SC("RowCount"), &ResultSet::RowCount)
// Member Methods
.Func(_SC("Next"), &ResultSet::Next)
.Func(_SC("Step"), &ResultSet::Next)
.Func(_SC("SetRowIndex"), &ResultSet::SetRowIndex)
.Func(_SC("SetLongRowIndex"), &ResultSet::SetLongRowIndex)
.Func(_SC("Get"), &ResultSet::GetField)
.Func(_SC("GetField"), &ResultSet::GetField)
.Func(_SC("GetBool"), &ResultSet::GetBoolean)
.Func(_SC("GetBoolean"), &ResultSet::GetBoolean)
.Func(_SC("GetChar"), &ResultSet::GetChar)
.Func(_SC("GetInteger"), &ResultSet::GetInteger)
.Func(_SC("GetFloat"), &ResultSet::GetFloat)
.Func(_SC("GetInt8"), &ResultSet::GetInt8)
.Func(_SC("GetUint8"), &ResultSet::GetUint8)
.Func(_SC("GetInt16"), &ResultSet::GetInt16)
.Func(_SC("GetUint16"), &ResultSet::GetUint16)
.Func(_SC("GetInt32"), &ResultSet::GetInt32)
.Func(_SC("GetUint32"), &ResultSet::GetUint32)
.Func(_SC("GetInt64"), &ResultSet::GetInt64)
.Func(_SC("GetUint64"), &ResultSet::GetUint64)
.Func(_SC("GetFloat32"), &ResultSet::GetFloat32)
.Func(_SC("GetFloat64"), &ResultSet::GetFloat64)
.Func(_SC("GetString"), &ResultSet::GetString)
.Func(_SC("GetBuffer"), &ResultSet::GetBuffer)
.Func(_SC("GetBlob"), &ResultSet::GetBlob)
);
}
} // Namespace:: SqMod

View File

@ -1,397 +0,0 @@
#ifndef _SQMYSQL_RESULTSET_HPP_
#define _SQMYSQL_RESULTSET_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/ResultSet.hpp"
#include "Field.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a result set handle.
*/
class ResultSet
{
private:
// --------------------------------------------------------------------------------------------
ResRef m_Handle; // Reference to the actual database result-set.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and row, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateStepped(CCStr file, Int32 line) const;
#else
void ValidateStepped() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetValid(CCStr file, Int32 line) const;
#else
const ResRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetCreated(CCStr file, Int32 line) const;
#else
const ResRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and row, and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ResRef & GetStepped(CCStr file, Int32 line) const;
#else
const ResRef & GetStepped() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and field index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateField(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateField(Int32 idx) const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ResultSet()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Connection constructor.
*/
ResultSet(const ConnRef & conn)
: m_Handle(new ResHnd())
{
m_Handle->Create(conn);
}
/* --------------------------------------------------------------------------------------------
* Statement constructor.
*/
ResultSet(const StmtRef & stmt)
: m_Handle(new ResHnd())
{
m_Handle->Create(stmt);
}
/* --------------------------------------------------------------------------------------------
* Handle constructor.
*/
ResultSet(const ResRef & 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
{
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
// Do we have a valid handle?
if (m_Handle)
{
ToStrF("%u", m_Handle->mFieldCount);
}
// Default to a negative value
return _SC("-1");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Returns an array with all the field names available in the managed result set.
*/
Array GetFieldNames() const;
/* --------------------------------------------------------------------------------------------
* Returns an array with wrapper instances for all the field available in the managed result set.
*/
Array GetFieldsArray() const;
/* --------------------------------------------------------------------------------------------
* Returns a table with wrapper instances for all the field available in the managed result set.
*/
Table GetFieldsTable() const;
/* --------------------------------------------------------------------------------------------
* Returns the current position of the row cursor for the last Next().
*/
Object RowIndex() const
{
return MakeULongObj(SQMOD_GET_CREATED(*this)->RowIndex());
}
/* --------------------------------------------------------------------------------------------
* Returns the number of rows in the result set.
*/
Object RowCount() const
{
return MakeULongObj(SQMOD_GET_CREATED(*this)->RowCount());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the next row from the query.
*/
bool Next() const
{
return SQMOD_GET_CREATED(*this)->Next();
}
/* --------------------------------------------------------------------------------------------
* Seeks to an arbitrary row in a query result set.
*/
bool SetRowIndex(SQInteger index) const
{
return SQMOD_GET_CREATED(*this)->SetRowIndex(ConvTo< Uint64 >::From(index));
}
/* --------------------------------------------------------------------------------------------
* Seeks to an arbitrary row in a query result set.
*/
bool SetLongRowIndex(Object & index) const
{
return SQMOD_GET_CREATED(*this)->SetRowIndex(FetchULongObjVal(index));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the field with the specified name or index.
*/
Field GetField(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a boolean value.
*/
bool GetBoolean(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetBoolean();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a character.
*/
SQChar GetChar(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetChar();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a native script integer.
*/
SQInteger GetInteger(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetInteger();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a native script floating point.
*/
SQFloat GetFloat(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetFloat();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a signed 8 bit integer value.
*/
SQInteger GetInt8(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetInt8();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as an unsigned 8 bit integer value.
*/
SQInteger GetUint8(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetUint8();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a signed 16 bit integer value.
*/
SQInteger GetInt16(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetInt16();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as an unsigned 16 bit integer value.
*/
SQInteger GetUint16(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetUint16();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a signed 32 bit integer value.
*/
SQInteger GetInt32(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetInt32();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as an unsigned 32 bit integer value.
*/
SQInteger GetUint32(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetUint32();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a signed 64 bit integer value.
*/
Object GetInt64(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetInt64();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as an unsigned 64 bit integer value.
*/
Object GetUint64(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetUint64();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a 32 bit floating point value.
*/
SQFloat GetFloat32(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetFloat32();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a 64 bit floating point value.
*/
SQFloat GetFloat64(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetFloat64();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a string value.
*/
Object GetString(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetString();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a memory buffer.
*/
Object GetBuffer(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetBuffer();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the specified field as a memory blob.
*/
Object GetBlob(const Object & field) const
{
return Field(SQMOD_GET_STEPPED(*this), field).GetBlob();
}
};
} // Namespace:: SqMod
#endif // _SQMYSQL_RESULTSET_HPP_

View File

@ -1,10 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Account.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
} // Namespace:: SqMod

View File

@ -1,17 +0,0 @@
#ifndef _SQMYSQL_SAVEPOINT_HPP_
#define _SQMYSQL_SAVEPOINT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
*
*/
} // Namespace:: SqMod
#endif // _SQMYSQL_SAVEPOINT_HPP_

View File

@ -1,464 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Statement.hpp"
#include "Connection.hpp"
#include "ResultSet.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Statement::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMySQLStatement");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL statement reference =>[%s:%d]", file, line);
}
}
#else
void Statement::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL statement reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateCreated(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL statement reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL statement =>[%s:%d]", file, line);
}
}
#else
void Statement::ValidateCreated() const
{
if (!m_Handle)
{
SqThrowF("Invalid MySQL statement reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid MySQL statement");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Statement::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const StmtRef & Statement::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Statement::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const StmtRef & Statement::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateParam(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
m_Handle->ValidateParam(idx, file, line);
}
#else
void Statement::ValidateParam(Int32 idx) const
{
ValidateCreated();
m_Handle->ValidateParam(idx);
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Statement::Statement(const Connection & connection, CSStr query)
: Statement(connection.GetHandle(), query)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Connection Statement::GetConnection() const
{
return Connection(SQMOD_GET_VALID(*this)->mConnection);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetConnection(const Connection & conn)
{
SQMOD_GET_VALID(*this)->mConnection = conn.GetHandle();
}
// ------------------------------------------------------------------------------------------------
Int32 Statement::Execute()
{
// Attempt to bind the parameters
if (mysql_stmt_bind_param(SQMOD_GET_CREATED(*this)->mPtr, m_Handle->mMyBinds))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot bind MySQL statement parameters");
}
// Attempt to execute the statement
else if (mysql_stmt_execute(m_Handle->mPtr))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot execute MySQL statement");
}
// Return the number of rows affected by this query
return mysql_stmt_affected_rows(m_Handle->mPtr);
}
// ------------------------------------------------------------------------------------------------
Uint32 Statement::Insert()
{
// Attempt to bind the parameters
if (mysql_stmt_bind_param(SQMOD_GET_CREATED(*this)->mPtr, m_Handle->mMyBinds))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot bind MySQL statement parameters");
}
// Attempt to execute the statement
else if (mysql_stmt_execute(m_Handle->mPtr))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot execute MySQL statement");
}
// Return the identifier of the inserted row
return mysql_stmt_insert_id(m_Handle->mPtr);
}
// ------------------------------------------------------------------------------------------------
ResultSet Statement::Query()
{
// Attempt to bind the parameters
if (mysql_stmt_bind_param(SQMOD_GET_CREATED(*this)->mPtr, m_Handle->mMyBinds))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot bind MySQL statement parameters");
}
// Attempt to execute the statement
else if (mysql_stmt_execute(m_Handle->mPtr))
{
SQMOD_THROW_CURRENT(*m_Handle, "Cannot execute MySQL statement");
}
// Return the results of this query
return ResultSet(m_Handle);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetInt8(Uint32 idx, SQInteger val) const
{
SQMOD_VALIDATE_PARAM(*this, 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
{
SQMOD_VALIDATE_PARAM(*this, 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
{
SQMOD_VALIDATE_PARAM(*this, 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
{
SQMOD_VALIDATE_PARAM(*this, 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
{
SQMOD_VALIDATE_PARAM(*this, 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, SQInteger val) const
{
SQMOD_VALIDATE_PARAM(*this, 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, SQInteger val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
// Assign the value to the input
m_Handle->mBinds[idx].mInt64 = ConvTo< Int64 >::From(val);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetUint64(Uint32 idx, SQInteger val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
// Assign the value to the input
m_Handle->mBinds[idx].mUint64 = ConvTo< Uint64 >::From(val);
// Specify that this value is unsigned
m_Handle->mMyBinds[idx].is_unsigned = true;
}
// ------------------------------------------------------------------------------------------------
void Statement::SetSLongInt(Uint32 idx, Object & val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
// Attempt to assign the numeric value inside the specified object
m_Handle->mBinds[idx].mInt64 = FetchSLongObjVal(val);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetULongInt(Uint32 idx, Object & val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_LONGLONG, &(m_Handle->mMyBinds[idx]));
// Attempt to assign the numeric value inside the specified object
m_Handle->mBinds[idx].mUint64 = FetchULongObjVal(val);
// Specify that this value is unsigned
m_Handle->mMyBinds[idx].is_unsigned = true;
}
// ------------------------------------------------------------------------------------------------
void Statement::SetInteger(Uint32 idx, SQInteger val) const
{
#ifdef _SQ64
SetInt64(idx, val);
#else
SetInt32(idx, val);
#endif // _SQ64
}
// ------------------------------------------------------------------------------------------------
void Statement::SetFloat32(Uint32 idx, SQFloat val) const
{
SQMOD_VALIDATE_PARAM(*this, 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
{
SQMOD_VALIDATE_PARAM(*this, 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::SetFloat(Uint32 idx, SQFloat val) const
{
#ifdef SQUSEDOUBLE
SetFloat64(idx, val);
#else
SetFloat32(idx, val);
#endif // SQUSEDOUBLE
}
// ------------------------------------------------------------------------------------------------
void Statement::SetBoolean(Uint32 idx, bool val) const
{
SQMOD_VALIDATE_PARAM(*this, 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::SetDate(Uint32 idx, Object & val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DATE, &(m_Handle->mMyBinds[idx]));
// Assign the value to the input
SqDateToMySQLTime(val, m_Handle->mBinds[idx].mTime);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetTime(Uint32 idx, Object & val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_TIME, &(m_Handle->mMyBinds[idx]));
// Assign the value to the input
SqTimeToMySQLTime(val, m_Handle->mBinds[idx].mTime);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetDatetime(Uint32 idx, Object & val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_DATETIME, &(m_Handle->mMyBinds[idx]));
// Assign the value to the input
SqDatetimeToMySQLTime(val, m_Handle->mBinds[idx].mTime);
}
// ------------------------------------------------------------------------------------------------
void Statement::SetString(Uint32 idx, CSStr val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_STRING, &(m_Handle->mMyBinds[idx]), val, std::strlen(val));
}
// ------------------------------------------------------------------------------------------------
void Statement::SetEnum(Uint32 idx, CSStr val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_ENUM, &(m_Handle->mMyBinds[idx]), val, std::strlen(val));
}
// ------------------------------------------------------------------------------------------------
void Statement::SetSet(Uint32 idx, CSStr val) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_SET, &(m_Handle->mMyBinds[idx]), val, std::strlen(val));
}
// ------------------------------------------------------------------------------------------------
void Statement::SetBlob(Uint32 /*idx*/, Object & /*val*/) const
{
// TODO...
}
// ------------------------------------------------------------------------------------------------
void Statement::SetData(Uint32 /*idx*/, Object & /*val*/) const
{
// TODO...
}
// ------------------------------------------------------------------------------------------------
void Statement::SetNull(Uint32 idx) const
{
SQMOD_VALIDATE_PARAM(*this, idx);
// Attempt to set the input value
m_Handle->mBinds[idx].SetInput(MYSQL_TYPE_NULL, &(m_Handle->mMyBinds[idx]));
}
// ================================================================================================
void Register_Statement(Table & sqlns)
{
sqlns.Bind(_SC("Statement")
, Class< Statement >(sqlns.GetVM(), _SC("SqMySQLStatement"))
// Constructors
.Ctor()
.Ctor< const Statement & >()
.Ctor< const Connection &, CSStr >()
// Core Meta-methods
.Func(_SC("_cmp"), &Statement::Cmp)
.SquirrelFunc(_SC("_typename"), &Statement::Typename)
.Func(_SC("_tostring"), &Statement::ToString)
// Properties
.Prop(_SC("IsValid"), &Statement::IsValid)
.Prop(_SC("Connection"), &Statement::GetConnection, &Statement::SetConnection)
// Member Methods
.Func(_SC("Execute"), &Statement::Execute)
.Func(_SC("Insert"), &Statement::Insert)
.Func(_SC("Query"), &Statement::Query)
.Func(_SC("SetInt8"), &Statement::SetInt8)
.Func(_SC("SetUint8"), &Statement::SetUint8)
.Func(_SC("SetInt16"), &Statement::SetInt16)
.Func(_SC("SetUint16"), &Statement::SetUint16)
.Func(_SC("SetInt32"), &Statement::SetInt32)
.Func(_SC("SetUint32"), &Statement::SetUint32)
.Func(_SC("SetInt64"), &Statement::SetInt64)
.Func(_SC("SetUint64"), &Statement::SetUint64)
.Func(_SC("SetSLongInt"), &Statement::SetSLongInt)
.Func(_SC("SetULongInt"), &Statement::SetULongInt)
.Func(_SC("SetInteger"), &Statement::SetInteger)
.Func(_SC("SetFloat32"), &Statement::SetFloat32)
.Func(_SC("SetFloat64"), &Statement::SetFloat64)
.Func(_SC("SetFloat"), &Statement::SetFloat)
.Func(_SC("SetBoolean"), &Statement::SetBoolean)
.Func(_SC("SetDate"), &Statement::SetDate)
.Func(_SC("SetTime"), &Statement::SetTime)
.Func(_SC("SetDatetime"), &Statement::SetDatetime)
.Func(_SC("SetString"), &Statement::SetString)
.Func(_SC("SetEnum"), &Statement::SetEnum)
.Func(_SC("SetSet"), &Statement::SetSet)
.Func(_SC("SetBlob"), &Statement::SetBlob)
.Func(_SC("SetData"), &Statement::SetData)
.Func(_SC("SetBuffer"), &Statement::SetData)
.Func(_SC("SetNull"), &Statement::SetNull)
);
}
} // Namespace:: SqMod

View File

@ -1,314 +0,0 @@
#ifndef _SQMYSQL_STATEMENT_HPP_
#define _SQMYSQL_STATEMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows management and interaction with a statement handle.
*/
class Statement
{
private:
// --------------------------------------------------------------------------------------------
StmtRef m_Handle; // Reference to the actual database statement.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and parameter index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateParam(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateParam(Int32 idx) const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Statement()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
*/
Statement(const ConnRef & connection, CSStr query)
: m_Handle(new StmtHnd())
{
m_Handle->Create(connection, 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;
/* --------------------------------------------------------------------------------------------
* 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
{
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const
{
// Do we have a valid handle?
if (m_Handle)
{
m_Handle->mQuery;
}
// Default to an empty string
return NullString();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated connection handle.
*/
const StmtRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the currently associated statement connection.
*/
Connection GetConnection() const;
/* --------------------------------------------------------------------------------------------
* Modify the currently associated statement connection.
*/
void SetConnection(const Connection & conn);
/* --------------------------------------------------------------------------------------------
* Execute the statement.
*/
Int32 Execute();
/* --------------------------------------------------------------------------------------------
* Execute the statement.
*/
Uint32 Insert();
/* --------------------------------------------------------------------------------------------
* Execute the statement.
*/
ResultSet Query();
/* --------------------------------------------------------------------------------------------
* 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, SQInteger val) const;
/* --------------------------------------------------------------------------------------------
* Assign a signed 64bit integer to a parameter.
*/
void SetInt64(Uint32 idx, SQInteger val) const;
/* --------------------------------------------------------------------------------------------
* Assign an unsigned 64bit integer to a parameter.
*/
void SetUint64(Uint32 idx, SQInteger val) const;
/* --------------------------------------------------------------------------------------------
* Assign a signed long integer to a parameter.
*/
void SetSLongInt(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign an unsigned long integer to a parameter.
*/
void SetULongInt(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a native integer to a parameter.
*/
void SetInteger(Uint32 idx, SQInteger 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 native float to a parameter.
*/
void SetFloat(Uint32 idx, SQFloat val) const;
/* --------------------------------------------------------------------------------------------
* Assign a boolean to a parameter.
*/
void SetBoolean(Uint32 idx, bool val) const;
/* --------------------------------------------------------------------------------------------
* Assign a date to a parameter.
*/
void SetDate(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a time to a parameter.
*/
void SetTime(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a date and time to a parameter.
*/
void SetDatetime(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a string to a parameter.
*/
void SetString(Uint32 idx, CSStr val) const;
/* --------------------------------------------------------------------------------------------
* Assign an enumeration to a parameter.
*/
void SetEnum(Uint32 idx, CSStr val) const;
/* --------------------------------------------------------------------------------------------
* Assign an enumeration to a parameter.
*/
void SetSet(Uint32 idx, CSStr val) const;
/* --------------------------------------------------------------------------------------------
* Assign a blob to a parameter.
*/
void SetBlob(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a buffer to a paramete.
*/
void SetData(Uint32 idx, Object & val) const;
/* --------------------------------------------------------------------------------------------
* Assign a null to a parameter.
*/
void SetNull(Uint32 idx) const;
};
} // Namespace:: SqMod
#endif // _SQMYSQL_STATEMENT_HPP_

View File

@ -1,10 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Account.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
} // Namespace:: SqMod

View File

@ -1,57 +0,0 @@
#ifndef _SQMYSQL_TRANSACTION_HPP_
#define _SQMYSQL_TRANSACTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* ...
*/
class Transaction
{
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Transaction()
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Transaction(const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Transaction(Transaction && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Transaction()
{
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Transaction & operator = (const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Transaction & operator = (Transaction && o) = default;
};
} // Namespace:: SqMod
#endif // _SQMYSQL_TRANSACTION_HPP_

View File

@ -1,20 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
int SampleFunction()
{
OutputMessage("Hello from the sample plug-in function!");
return rand();
}
// ------------------------------------------------------------------------------------------------
void SampleType::SampleMethod() const
{
OutputMessage("I have the values %d and %d", m_MyVal, mMyNum);
}
} // Namespace:: SqMod

View File

@ -1,66 +0,0 @@
#ifndef _SQSAMPLE_COMMON_HPP_
#define _SQSAMPLE_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQSAMPLE_NAME "Squirrel Sample Module"
#define SQSAMPLE_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQSAMPLE_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQSAMPLE_HOST_NAME "SqModSampleHost"
#define SQSAMPLE_VERSION 001
#define SQSAMPLE_VERSION_STR "0.0.1"
#define SQSAMPLE_VERSION_MAJOR 0
#define SQSAMPLE_VERSION_MINOR 0
#define SQSAMPLE_VERSION_PATCH 1
/* --------------------------------------------------------------------------------------------
* Sample Plug-in API
*/
int SampleFunction();
class SampleType
{
private:
int m_MyVal;
public:
int mMyNum;
SampleType()
: m_MyVal(0), mMyNum(0)
{
}
SampleType(int num)
: m_MyVal(num * 2), mMyNum(num)
{
}
int GetMyVal() const
{
return m_MyVal;
}
void SetMyVal(int val)
{
m_MyVal = val;
}
void SampleMethod() const;
};
} // Namespace:: SqMod
#endif // _SQSAMPLE_COMMON_HPP_

View File

@ -1,213 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQSAMPLE_NAME);
// Registration failed
return false;
}
RootTable(vm).Bind(_SC("SampleType"),
Class< SampleType >(vm, _SC("SampleType"))
.Ctor()
.Ctor< int >()
.Var(_SC("MyNum"), &SampleType::mMyNum)
.Prop(_SC("MyVal"), &SampleType::GetMyVal, &SampleType::SetMyVal)
.Func(_SC("SampleMethod"), &SampleType::SampleMethod)
);
RootTable(vm).Func(_SC("SampleFunction"), &SampleFunction);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQSAMPLE_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQSAMPLE_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullObject() = Object();
NullTable() = Table();
NullArray() = Array();
NullLightObj() = LightObj();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQSAMPLE_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQSAMPLE_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Release script resources...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQSAMPLE_NAME))
{
try
{
ImportModuleAPI(_Func, SQSAMPLE_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQSAMPLE_NAME);
OutputMessage("Author: %s", SQSAMPLE_AUTHOR);
OutputMessage("Legal: %s", SQSAMPLE_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQSAMPLE_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQSAMPLE_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQSAMPLE_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQSAMPLE_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,544 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Column.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqLiteColumn"))
// ------------------------------------------------------------------------------------------------
static inline bool IsDigitsOnly(CSStr str)
{
while (std::isdigit(*str) || std::isspace(*str))
{
++str;
}
// Return whether we reached the end while searching
return *str == '\0';
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::Validate(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
}
#else
void Column::Validate() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0", m_Index);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::ValidateCreated(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement =>[%s:%d]", file, line);
}
}
#else
void Column::ValidateCreated() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0", m_Index);
}
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Column::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const StmtRef & Column::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Column::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const StmtRef & Column::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::ValidateColumn(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Is the specified index in range?
if (!m_Handle->CheckColumn(idx))
{
SqThrowF("Column index is out of range: %d:%d =>[%s:%d]", idx, m_Handle->mColumns,
file, line);
}
}
#else
void Column::ValidateColumn(Int32 idx) const
{
ValidateCreated();
// Is the specified index in range?
if (!m_Handle->CheckColumn(idx))
{
SqThrowF("Column index is out of range: %d:%d", idx, m_Handle->mColumns);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::ValidateRow(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Do we have any rows available?
if (!m_Handle->mGood)
{
STHROWF("No row available =>[%s:%d]", file, line);
}
}
#else
void Column::ValidateRow() const
{
ValidateCreated();
// Do we have any rows available?
if (!m_Handle->mGood)
{
STHROWF("No row available");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Column::SetIndex(const Object & column)
{
// Where the index will be extracted
Int32 idx = -1;
// Grab the object virtual machine
HSQUIRRELVM vm = column.GetVM();
// Remember the current stack size
const StackGuard sg(vm);
// Push the specified object onto the stack
Var< const Object & >::push(vm, column);
// Identify the type of column was given
switch (column.GetType())
{
// Is this a string value?
case OT_STRING:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty column name");
}
// Attempt to find a column with the specified name
idx = m_Handle->GetColumnIndex(val.mPtr);
} break;
// Is this an integer value? (or at least can be easily converted to one)
case OT_INTEGER:
case OT_FLOAT:
case OT_BOOL:
{
idx = ConvTo< Int32 >::From(SqMod_PopStackInteger(vm, -1));
} break;
// Is this an instance that we can extract either a string or integer from it?
case OT_INSTANCE:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty column name");
}
// Check if this value is made only of digits
else if (IsDigitsOnly(val.mPtr))
{
idx = ConvNum< Int32 >::FromStr(val.mPtr);
}
// Attempt to find a column with the specified name
else
{
idx = m_Handle->GetColumnIndex(val.mPtr);
}
} break;
// We don't recognize this kind of value!
default: STHROWF("Unknown column index of type (%s)", SqTypeName(column.GetType()));
}
// Assign the index with a failsafe to invalid on error
AutoAssign< Int32 > aa(m_Index, -1, idx);
// Validate the obtained column index
SQMOD_VALIDATE_COLUMN(*this, idx);
// Don't fall back to the invalid index anymore
aa.Set(idx);
}
// ------------------------------------------------------------------------------------------------
Object Column::GetStatement() const
{
return GetStatementObj(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Object Column::GetConnection() const
{
return GetConnectionObj(SQMOD_GET_VALID(*this)->mConn);
}
// ------------------------------------------------------------------------------------------------
bool Column::IsNull() const
{
return (sqlite3_column_type(SQMOD_GET_CREATED(*this)->mPtr, m_Index) == SQLITE_NULL);
}
// ------------------------------------------------------------------------------------------------
CSStr Column::GetName() const
{
return sqlite3_column_name(SQMOD_GET_CREATED(*this)->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
CSStr Column::GetOriginName() const
{
#ifdef SQLITE_ENABLE_COLUMN_METADATA
return sqlite3_column_origin_name(SQMOD_GET_CREATED(*this)->mPtr, m_Index);
#else
STHROWF("The module was compiled without this feature");
// Request failed
return _SC("");
#endif
}
// ------------------------------------------------------------------------------------------------
Int32 Column::GetType() const
{
return sqlite3_column_type(SQMOD_GET_CREATED(*this)->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
Int32 Column::GetBytes() const
{
return sqlite3_column_bytes(SQMOD_GET_CREATED(*this)->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
Object Column::GetValue() const
{
SQMOD_VALIDATE_ROW(*this);
// Obtain the initial stack size
const StackGuard sg;
// Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index))
{
// Is this a null value?
case SQLITE_NULL:
{
sq_pushnull(DefaultVM::Get());
} break;
// Is this an integer?
case SQLITE_INTEGER:
{
sq_pushinteger(DefaultVM::Get(), sqlite3_column_integer(m_Handle->mPtr, m_Index));
} break;
// Is this a floating point?
case SQLITE_FLOAT:
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index)));
} break;
// Is this a string?
case SQLITE_TEXT:
{
sq_pushstring(DefaultVM::Get(),
reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index));
} break;
// Is this raw data?
case SQLITE_BLOB:
{
// Retrieve the size of the blob that must be allocated
const Int32 size = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Retrieve the the actual blob data that must be returned
CCStr data = reinterpret_cast< CCStr >(sqlite3_column_blob(m_Handle->mPtr, m_Index));
// Attempt to create a buffer with the blob data on the stack
if (SQ_FAILED(SqMod_PushBufferData(DefaultVM::Get(), data, size, 0)))
{
STHROWF("Unable to allocate buffer of at least (%d) bytes", size);
}
} break;
// Unknown type
default: STHROWF("Unknown value to fetch at index: %d", m_Index);
}
// Obtain the object with the value from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Column::GetNumber() const
{
SQMOD_VALIDATE_ROW(*this);
// Obtain the initial stack size
const StackGuard sg;
// Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index))
{
// Is this a null value?
case SQLITE_NULL:
{
sq_pushinteger(DefaultVM::Get(), 0);
} break;
// Is this an integer?
case SQLITE_INTEGER:
{
sq_pushinteger(DefaultVM::Get(), sqlite3_column_integer(m_Handle->mPtr, m_Index));
} break;
// Is this a floating point?
case SQLITE_FLOAT:
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index)));
} break;
// Is this a string?
case SQLITE_TEXT:
{
CSStr str = reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index));
// Is there even a string to parse?
if (!str || *str == '\0')
{
sq_pushinteger(DefaultVM::Get(), 0);
}
// Can we treat this string as a float?
else if (!std::strchr(str, '.'))
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(std::strtod(str, nullptr)));
}
else
{
sq_pushinteger(DefaultVM::Get(),
ConvTo< SQInteger >::From(std::strtoll(str, nullptr, 10)));
}
} break;
// Unknown type
default: STHROWF("Unknown number to fetch at index: %d", m_Index);
}
// Obtain the object with the value from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
SQInteger Column::GetInteger() const
{
SQMOD_VALIDATE_ROW(*this);
// Return the requested information
return sqlite3_column_integer(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
SQFloat Column::GetFloat() const
{
SQMOD_VALIDATE_ROW(*this);
// Return the requested information
return ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index));
}
// ------------------------------------------------------------------------------------------------
Object Column::GetLong() const
{
SQMOD_VALIDATE_ROW(*this);
// Return the requested information
return MakeSLongObj(sqlite3_column_int64(m_Handle->mPtr, m_Index));
}
// ------------------------------------------------------------------------------------------------
Object Column::GetString() const
{
SQMOD_VALIDATE_ROW(*this);
// Obtain the initial stack size
const StackGuard sg;
// Push the column text on the stack
sq_pushstring(DefaultVM::Get(), reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index));
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
bool Column::GetBoolean() const
{
SQMOD_VALIDATE_ROW(*this);
// Return the requested information
return sqlite3_column_int(m_Handle->mPtr, m_Index) > 0;
}
// ------------------------------------------------------------------------------------------------
SQChar Column::GetChar() const
{
SQMOD_VALIDATE_ROW(*this);
// Return the requested information
return (SQChar)sqlite3_column_int(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
Object Column::GetBuffer() const
{
SQMOD_VALIDATE_ROW(*this);
// Remember the current stack size
const StackGuard sg;
// Retrieve the size of the blob that must be allocated
const Int32 size = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Retrieve the the actual blob data that must be returned
CCStr data = reinterpret_cast< CCStr >(sqlite3_column_blob(m_Handle->mPtr, m_Index));
// Attempt to create a buffer with the blob data on the stack
if (SQ_FAILED(SqMod_PushBufferData(DefaultVM::Get(), data, size, 0)))
{
STHROWF("Unable to allocate buffer of at least (%d) bytes", size);
}
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Column::GetBlob() const
{
SQMOD_VALIDATE_ROW(*this);
// Obtain the initial stack size
const StackGuard sg;
// Obtain the size of the data
const Int32 sz = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Allocate a blob of the same size
SQUserPointer p = sqstd_createblob(DefaultVM::Get(), sz);
// Obtain a pointer to the data
const void * b = sqlite3_column_blob(m_Handle->mPtr, m_Index);
// Could the memory blob be allocated?
if (!p)
{
STHROWF("Unable to allocate space for column blob value");
}
// Is there any data to read?
else if (!b)
{
// Pop the memory blob from the stack
sq_pop(DefaultVM::Get(), 1);
// Push a null value instead
sq_pushnull(DefaultVM::Get());
}
// Copy the data into the memory blob
else
{
std::memcpy(p, b, sz);
}
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ================================================================================================
void Register_Column(Table & sqlns)
{
sqlns.Bind(_SC("Column"),
Class< Column >(sqlns.GetVM(), Typename::Str)
// Constructors
.Ctor()
.Ctor< const Column & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Column::ToString)
// Properties
.Prop(_SC("IsValid"), &Column::IsValid)
.Prop(_SC("References"), &Column::GetRefCount)
.Prop(_SC("Index"), &Column::GetIndex)
.Prop(_SC("Statement"), &Column::GetStatement)
.Prop(_SC("Connection"), &Column::GetConnection)
.Prop(_SC("IsNull"), &Column::IsNull)
.Prop(_SC("Name"), &Column::GetName)
.Prop(_SC("OriginName"), &Column::GetOriginName)
.Prop(_SC("Type"), &Column::GetType)
.Prop(_SC("Bytes"), &Column::GetBytes)
.Prop(_SC("Value"), &Column::GetValue)
.Prop(_SC("Number"), &Column::GetNumber)
.Prop(_SC("Integer"), &Column::GetInteger)
.Prop(_SC("Float"), &Column::GetFloat)
.Prop(_SC("Long"), &Column::GetLong)
.Prop(_SC("String"), &Column::GetString)
.Prop(_SC("Boolean"), &Column::GetBoolean)
.Prop(_SC("Char"), &Column::GetChar)
.Prop(_SC("Buffer"), &Column::GetBuffer)
.Prop(_SC("Blob"), &Column::GetBlob)
// Member Methods
.Func(_SC("Release"), &Column::Release)
);
}
} // Namespace:: SqMod

View File

@ -1,342 +0,0 @@
#ifndef _SQSQLITE_COLUMN_HPP_
#define _SQSQLITE_COLUMN_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Used to manage and interact with statement columns.
*/
class Column
{
// --------------------------------------------------------------------------------------------
friend class Statement;
private:
// --------------------------------------------------------------------------------------------
Int32 m_Index; // The index of the managed column.
StmtRef m_Handle; // The statement where the column exist.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and column index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateColumn(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateColumn(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and row, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateRow(CCStr file, Int32 line) const;
#else
void ValidateRow() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(Int32 idx)
{
// Assign the index with a failsafe to invalid on error
AutoAssign< Int32 > aa(m_Index, -1, idx);
// Validate the obtained column index
SQMOD_VALIDATE_COLUMN(*this, idx);
// Don't fall back to the invalid index anymore
aa.Set(idx);
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(CSStr name)
{
SetIndex(SQMOD_GET_CREATED(*this)->GetColumnIndex(name));
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(const Object & column);
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
Column()
: m_Index(-1), m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* No column constructor.
*/
Column(const StmtRef & stmt)
: m_Index(-1), m_Handle(stmt)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Index constructor.
*/
Column(const StmtRef & stmt, Int32 idx)
: m_Index(idx), m_Handle(stmt)
{
SQMOD_VALIDATE_COLUMN(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Name constructor.
*/
Column(const StmtRef & stmt, CSStr name)
: m_Index(stmt ? stmt->GetColumnIndex(name) : -1), m_Handle(stmt)
{
SQMOD_VALIDATE_COLUMN(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Dynamic constructor.
*/
Column(const StmtRef & stmt, const Object & column)
: m_Index(-1), m_Handle(stmt)
{
if (!m_Handle)
{
STHROWF("Invalid SQLite statement reference");
}
// Extract the index
SetIndex(column);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Column(const Column & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Column(Column && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Column & operator = (const Column & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Column & operator = (Column && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two table column indexes.
*/
bool operator == (const Column & o) const
{
return (m_Index == o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two table column indexes.
*/
bool operator != (const Column & o) const
{
return (m_Index != o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Index >= 0;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
CSStr val = nullptr;
// Can we attempt to return the parameter name?
if (m_Handle && m_Index)
{
val = sqlite3_column_name(m_Handle->mPtr, m_Index);
}
else
{
val = ToStrF(_SC("%d"), m_Index);
}
// Return the value if valid
return val ? val : _SC("");
}
/* --------------------------------------------------------------------------------------------
* See whether the column is valid.
*/
bool IsValid() const
{
return m_Handle; // An invalid statement means an invalid column
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to the associated statement handle.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced column index.
*/
Int32 GetIndex() const
{
return m_Index;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced database statement.
*/
Object GetStatement() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the referenced database connection.
*/
Object GetConnection() const;
/* --------------------------------------------------------------------------------------------
* Release the reference to the referenced database statement and column index.
*/
void Release()
{
m_Handle.Reset();
m_Index = -1;
}
/* --------------------------------------------------------------------------------------------
* Check whether the referenced column is null.
*/
bool IsNull() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the name of the referenced column index.
*/
CSStr GetName() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the column origin name if the library was compiled with such feature.
*/
CSStr GetOriginName() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the type identifier of the referenced column index.
*/
Int32 GetType() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the size in bytes of the referenced column index.
*/
Int32 GetBytes() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a dynamic type.
*/
Object GetValue() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a numeric type.
*/
Object GetNumber() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a native script integer.
*/
SQInteger GetInteger() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a native script floating point.
*/
SQFloat GetFloat() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a long integer.
*/
Object GetLong() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a string.
*/
Object GetString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a boolean.
*/
bool GetBoolean() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a character.
*/
SQChar GetChar() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a memory buffer.
*/
Object GetBuffer() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a memory blob.
*/
Object GetBlob() const;
};
} // Namespace:: SqMod
#endif // _SQSQLITE_COLUMN_HPP_

View File

@ -1,241 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Connection.hpp"
#include "Statement.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstring>
#include <cstdarg>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
Object GetConnectionObj(const ConnRef & conn)
{
return Object(new Connection(conn));
}
// ------------------------------------------------------------------------------------------------
Object GetStatementObj(const StmtRef & stmt)
{
return Object(new Statement(stmt));
}
// ------------------------------------------------------------------------------------------------
CSStr QFmtStr(CSStr str, ...)
{
// Initialize the argument list
va_list args;
va_start (args, str);
// Write the requested contents
sqlite3_vsnprintf(GetTempBuffSize(), GetTempBuff(), str, args);
// Release the argument list
va_end(args);
// Return the data from the buffer
return GetTempBuff();
}
// ------------------------------------------------------------------------------------------------
bool IsQueryEmpty(CSStr str)
{
// Is the pointer valid?
if (!str || *str == '\0')
{
return true;
}
// Currently processed character
SQChar c = 0;
// See if the query contains any alpha numeric characters
while ((c = *str) != 0)
{
if (std::isalnum(c) != 0)
{
return false;
}
++str;
}
// At this point we consider the query empty
return true;
}
// ------------------------------------------------------------------------------------------------
CSStr GetErrStr(Int32 status)
{
return sqlite3_errstr(status);
}
// ------------------------------------------------------------------------------------------------
void SetSoftHeapLimit(Int32 limit)
{
sqlite3_soft_heap_limit(limit);
}
// ------------------------------------------------------------------------------------------------
Int32 ReleaseMemory(Int32 bytes)
{
return sqlite3_release_memory(bytes);
}
// ------------------------------------------------------------------------------------------------
Object GetMemoryUsage()
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), sqlite3_memory_used());
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object GetMemoryHighwaterMark(bool reset)
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), sqlite3_memory_highwater(reset));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
CSStr EscapeString(StackStrF & str)
{
// Is there even a string to escape?
if (str.mLen <= 0)
{
return _SC(""); // Default to empty string
}
// Attempt to escape the specified string
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), "%q", str.mPtr);
// Return the resulted string
return GetTempBuff();
}
// ------------------------------------------------------------------------------------------------
CCStr EscapeStringEx(SQChar spec, StackStrF & str)
{
// Utility that allows changing the format specifier temporarily
static SQChar fs[] = _SC("%q");
// Validate the specified format specifier
if ((spec != 'q') && (spec != 'Q') && (spec != 'w') && (spec != 's'))
{
STHROWF("Unknown format specifier: '%c'", spec);
}
// Is there even a string to escape?
else if (!str.mLen)
{
return _SC(""); // Default to empty string
}
// Apply the format specifier
fs[1] = spec;
// Attempt to escape the specified string
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), fs, str.mPtr);
// Restore the format specifier
fs[1] = 'q';
// Return the resulted string
return GetTempBuff();
}
// ------------------------------------------------------------------------------------------------
CCStr ArrayToQueryColumns(Array & arr)
{
// Do we even have any elements to process?
if (arr.Length() <= 0)
{
return _SC(""); // Default to empty string
}
// Allocate a vector with the required amount of column names
std::vector< String > values(arr.Length());
// Attempt to extract the array elements as strings
arr.GetArray< String >(&values[0], values.size());
// Used to know the position of the next column name
Uint32 offset = 0;
// Obtain the start of the array
std::vector< String >::iterator itr = values.begin();
// Process all elements within range
for (; itr != values.end() && offset < GetTempBuffSize(); ++itr)
{
// Is the name valid?
if (itr->empty())
{
STHROWF("Invalid column name");
}
// Attempt to append the column name to the buffer
sqlite3_snprintf(GetTempBuffSize() - offset, GetTempBuff() + offset, "[%q], ", itr->c_str());
// Add the column name size to the offset
offset += itr->size();
// Also include the comma and space in the offset
offset += 2;
}
// Trim the last coma and space
if (offset >= 2)
{
GetTempBuff()[offset-2] = '\0';
}
else
{
GetTempBuff()[0] = '\0';
}
// Return the resulted string
return GetTempBuff();
}
// ------------------------------------------------------------------------------------------------
CCStr TableToQueryColumns(Table & tbl)
{
// Used to know the position of the next column name
Uint32 offset = 0;
// Used to obtain the column name temporarily
String name;
// Obtain the start of the table
Table::iterator itr;
// Process all elements within range
while (tbl.Next(itr))
{
// Use the element key as the column name
name.assign(itr.getName());
// Is the name valid?
if (name.empty())
{
STHROWF("Invalid or empty column name");
}
// Attempt to append the column name to the buffer
sqlite3_snprintf(GetTempBuffSize() - offset, GetTempBuff() + offset, "[%q], ", name.c_str());
// Add the column name size to the offset
offset += name.size();
// Also include the comma and space in the offset
offset += 2;
}
// Trim the last coma and space
if (offset >= 2)
{
GetTempBuff()[offset-2] = '\0';
}
else
{
GetTempBuff()[0] = '\0';
}
// Return the resulted string
return GetTempBuff();
}
// ================================================================================================
void Register_Common(Table & sqlns)
{
sqlns.Func(_SC("IsQueryEmpty"), &IsQueryEmpty)
.Func(_SC("GetErrStr"), &GetErrStr)
.Func(_SC("SetSoftHeapLimit"), &SetSoftHeapLimit)
.Func(_SC("ReleaseMemory"), &ReleaseMemory)
.Func(_SC("MemoryUsage"), &GetMemoryUsage)
.Func(_SC("ArrayToQueryColumns"), &ArrayToQueryColumns)
.Func(_SC("TableToQueryColumns"), &TableToQueryColumns)
.FmtFunc(_SC("EscapeString"), &EscapeString)
.FmtFunc(_SC("EscapeStringEx"), &EscapeStringEx)
.FmtFunc(_SC("Escape"), &EscapeString)
.FmtFunc(_SC("EscapeEx"), &EscapeStringEx);
}
} // Namespace:: SqMod

View File

@ -1,148 +0,0 @@
#ifndef _SQSQLITE_COMMON_HPP_
#define _SQSQLITE_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqlite3.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class Connection;
class Statement;
class Column;
class Transaction;
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQSQLITE_NAME "Squirrel SQLite Module"
#define SQSQLITE_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQSQLITE_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQSQLITE_HOST_NAME "SqModSQLiteHost"
#define SQSQLITE_VERSION 001
#define SQSQLITE_VERSION_STR "0.0.1"
#define SQSQLITE_VERSION_MAJOR 0
#define SQSQLITE_VERSION_MINOR 0
#define SQSQLITE_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Handle validation.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
#define SQMOD_THROW_CURRENT(x, a) (x).ThrowCurrent(a, __FILE__, __LINE__)
#define SQMOD_VALIDATE(x) (x).Validate(__FILE__, __LINE__)
#define SQMOD_VALIDATE_CREATED(x) (x).ValidateCreated(__FILE__, __LINE__)
#define SQMOD_VALIDATE_PARAM(x, i) (x).ValidateParam((i), __FILE__, __LINE__)
#define SQMOD_VALIDATE_COLUMN(x, i) (x).ValidateColumn((i), __FILE__, __LINE__)
#define SQMOD_VALIDATE_ROW(x) (x).ValidateRow(__FILE__, __LINE__)
#define SQMOD_GET_VALID(x) (x).GetValid(__FILE__, __LINE__)
#define SQMOD_GET_CREATED(x) (x).GetCreated(__FILE__, __LINE__)
#else
#define SQMOD_THROW_CURRENT(x, a) (x).ThrowCurrent(a)
#define SQMOD_VALIDATE(x) (x).Validate()
#define SQMOD_VALIDATE_CREATED(x) (x).ValidateCreated()
#define SQMOD_VALIDATE_PARAM(x, i) (x).ValidateParam((i))
#define SQMOD_VALIDATE_COLUMN(x, i) (x).ValidateColumn((i))
#define SQMOD_VALIDATE_ROW(x) (x).ValidateRow()
#define SQMOD_GET_VALID(x) (x).GetValid()
#define SQMOD_GET_CREATED(x) (x).GetCreated()
#endif // _DEBUG
/* ------------------------------------------------------------------------------------------------
* Helper macros for architecture differences.
*/
#ifdef _SQ64
#define sqlite3_bind_integer sqlite3_bind_int64
#define sqlite3_column_integer sqlite3_column_int64
#else
#define sqlite3_bind_integer sqlite3_bind_int
#define sqlite3_column_integer sqlite3_column_int
#endif
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
struct ConnHnd;
struct StmtHnd;
/* ------------------------------------------------------------------------------------------------
* Common typedefs.
*/
typedef SharedPtr< ConnHnd > ConnRef;
typedef SharedPtr< StmtHnd > StmtRef;
/* ------------------------------------------------------------------------------------------------
* Obtain a script object from a connection handle. (meant to avoid having to include the header)
*/
Object GetConnectionObj(const ConnRef & conn);
/* ------------------------------------------------------------------------------------------------
* Obtain a script object from a statement handle. (meant to avoid having to include the header)
*/
Object GetStatementObj(const StmtRef & stmt);
/* ------------------------------------------------------------------------------------------------
* Generate a formatted query.
*/
CSStr QFmtStr(CSStr str, ...);
/* ------------------------------------------------------------------------------------------------
* Tests if a certain query string is empty.
*/
bool IsQueryEmpty(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Retrieve the string representation of a certain status code.
*/
CSStr GetErrStr(Int32 status);
/* ------------------------------------------------------------------------------------------------
* Set a specific heap limit.
*/
void SetSoftHeapLimit(Int32 limit);
/* ------------------------------------------------------------------------------------------------
* Release the specified amount of memory.
*/
Int32 ReleaseMemory(Int32 bytes);
/* ------------------------------------------------------------------------------------------------
* Retrieve the current memory usage.
*/
Object GetMemoryUsage();
/* ------------------------------------------------------------------------------------------------
* Retrieve the memory high watermark.
*/
Object GetMemoryHighwaterMark(bool reset);
/* ------------------------------------------------------------------------------------------------
* Retrieve the escaped version of the specified string.
*/
CSStr EscapeString(StackStrF & str);
/* ------------------------------------------------------------------------------------------------
* Retrieve the escaped version of the specified string using the supplied format specifier.
*/
CCStr EscapeStringEx(SQChar spec, StackStrF & str);
/* ------------------------------------------------------------------------------------------------
* Convert the values from the specified array to a list of column names string.
*/
CCStr ArrayToQueryColumns(Array & arr);
/* ------------------------------------------------------------------------------------------------
* Convert the keys from the specified array to a list of column names string.
*/
CCStr TableToQueryColumns(Table & tbl);
} // Namespace:: SqMod
#endif // _SQSQLITE_COMMON_HPP_

View File

@ -1,404 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Connection.hpp"
#include "Statement.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqLiteConnection"))
// ------------------------------------------------------------------------------------------------
void Connection::TraceOutput(void * /*ptr*/, CCStr sql)
{
SqMod_LogInf("SQLite Trace: %s", sql);
}
// ------------------------------------------------------------------------------------------------
void Connection::ProfileOutput(void * /*ptr*/, CCStr sql, sqlite3_uint64 time)
{
SqMod_LogInf("SQLite profile (time: %llu): %s", time, sql);
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference =>[%s:%d]", file, line);
}
}
#else
void Connection::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::ValidateCreated(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite connection =>[%s:%d]", file, line);
}
}
#else
void Connection::ValidateCreated() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite connection");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Connection::Open(StackStrF & name)
{
// Should we create a connection handle?
if (!m_Handle)
{
m_Handle = ConnRef(new ConnHnd());
}
// Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
{
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name.mPtr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
// ------------------------------------------------------------------------------------------------
void Connection::Open(StackStrF & name, Int32 flags)
{
// Should we create a connection handle?
if (!m_Handle)
{
m_Handle = ConnRef(new ConnHnd());
}
// Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
{
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name.mPtr, flags, nullptr);
}
// ------------------------------------------------------------------------------------------------
void Connection::Open(StackStrF & name, Int32 flags, StackStrF & vfs)
{
// Should we create a connection handle?
if (!m_Handle)
{
m_Handle = ConnRef(new ConnHnd());
}
// Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
{
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name.mPtr, flags, vfs.mPtr);
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Exec(StackStrF & str)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to execute the specified query
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, str.mPtr, nullptr, nullptr, nullptr);
// Validate the execution result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to execute query [%s]", m_Handle->ErrMsg());
}
// Return rows affected by this query
return sqlite3_changes(m_Handle->mPtr);
}
// ------------------------------------------------------------------------------------------------
Object Connection::Query(StackStrF & str) const
{
SQMOD_VALIDATE_CREATED(*this);
// Return the requested information
return Object(new Statement(m_Handle, str));
}
// ------------------------------------------------------------------------------------------------
void Connection::Queue(StackStrF & str)
{
SQMOD_VALIDATE(*this);
// Is there a query to commit?
if (!str.mLen || IsQueryEmpty(str.mPtr))
{
STHROWF("No query string to queue");
}
// Add the specified string to the queue
m_Handle->mQueue.emplace_back(str.mPtr, str.mLen);
}
// ------------------------------------------------------------------------------------------------
bool Connection::IsReadOnly() const
{
// Request the desired information
const int result = sqlite3_db_readonly(SQMOD_GET_CREATED(*this)->mPtr, "main");
// Verify the result
if (result == -1)
{
STHROWF("'main' is not the name of a database on connection");
}
// Return the requested information
return (result != 1);
}
// ------------------------------------------------------------------------------------------------
bool Connection::TableExists(StackStrF & name) const
{
StackStrF query("SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
// Prepare a statement to inspect the master table
Statement stmt(SQMOD_GET_CREATED(*this), query);
// Could the statement be created?
if (stmt.IsValid())
{
// Bind the specified name onto the statement parameter
Parameter(stmt.GetHandle(), 1).SetString(name);
// Attempt to step the statement and obtain a value
if (stmt.Step())
{
return (sqlite3_column_int(stmt, 0) == 1);
}
}
// Assume it doesn't exist
return false;
}
// ------------------------------------------------------------------------------------------------
void Connection::SetTracing(bool toggle)
{
// Check whether changes are necessary
if (SQMOD_GET_CREATED(*this)->mTrace == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mTrace)
{
sqlite3_trace(m_Handle->mPtr, nullptr, nullptr);
}
// Go ahead and enable tracing
else
{
sqlite3_trace(m_Handle->mPtr, &Connection::TraceOutput, nullptr);
}
}
// ------------------------------------------------------------------------------------------------
void Connection::SetProfiling(bool toggle)
{
// Check whether changes are necessary
if (SQMOD_GET_CREATED(*this)->mProfile == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mProfile)
{
sqlite3_profile(m_Handle->mPtr, nullptr, nullptr);
}
// Go ahead and enable profiling
else
{
sqlite3_profile(m_Handle->mPtr, &Connection::ProfileOutput, nullptr);
}
}
// ------------------------------------------------------------------------------------------------
void Connection::SetBusyTimeout(Int32 millis)
{
SQMOD_VALIDATE_CREATED(*this);
// Apply the requested timeout
if ((m_Handle->mStatus = sqlite3_busy_timeout(m_Handle->mPtr, millis)) != SQLITE_OK)
{
STHROWF("Unable to set busy timeout [%s]", m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
{
// Where to retrieve the information
Int32 cur_value;
Int32 hiwtr_value;
// Attempt to retrieve the specified information
if ((m_Handle->mStatus = sqlite3_db_status(SQMOD_GET_CREATED(*this)->mPtr, operation, &cur_value, &hiwtr_value, reset)) != SQLITE_OK)
{
STHROWF("Unable to get runtime status information", m_Handle->ErrMsg());
}
// Return the high-water value if requested
else if (highwater)
{
return hiwtr_value;
}
// Return the requested information
return cur_value;
}
// ------------------------------------------------------------------------------------------------
void Connection::ReserveQueue(Uint32 num)
{
SQMOD_VALIDATE(*this);
// Perform the requested operation
m_Handle->mQueue.reserve(m_Handle->mQueue.size() + num);
}
// ------------------------------------------------------------------------------------------------
void Connection::PopQueue()
{
SQMOD_VALIDATE(*this);
// Perform the requested operation
if (!SQMOD_GET_VALID(*this)->mQueue.empty())
{
m_Handle->mQueue.pop_back();
}
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush()
{
SQMOD_VALIDATE_CREATED(*this);
// Perform the requested operation
return m_Handle->Flush(m_Handle->mQueue.size(), NullObject(), NullFunction());
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(SQInteger num)
{
SQMOD_VALIDATE_CREATED(*this);
// Perform the requested operation
return m_Handle->Flush(ConvTo< Uint32 >::From(num), NullObject(), NullFunction());
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(Object & env, Function & func)
{
SQMOD_VALIDATE_CREATED(*this);
// Perform the requested operation
return m_Handle->Flush(m_Handle->mQueue.size(), env, func);
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(SQInteger num, Object & env, Function & func)
{
SQMOD_VALIDATE_CREATED(*this);
// Perform the requested operation
return m_Handle->Flush(ConvTo< Uint32 >::From(num), env, func);
}
// ================================================================================================
void Register_Connection(Table & sqlns)
{
sqlns.Bind(_SC("Connection"),
Class< Connection >(sqlns.GetVM(), Typename::Str)
// Constructors
.Ctor()
.Ctor< StackStrF & >()
.Ctor< StackStrF &, Int32 >()
.Ctor< StackStrF &, Int32, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Connection::ToString)
// Properties
.Prop(_SC("IsValid"), &Connection::IsValid)
.Prop(_SC("Connected"), &Connection::IsConnected)
.Prop(_SC("References"), &Connection::GetRefCount)
.Prop(_SC("Status"), &Connection::GetStatus)
.Prop(_SC("Flags"), &Connection::GetFlags)
.Prop(_SC("Name"), &Connection::GetName)
.Prop(_SC("VFS"), &Connection::GetVFS)
.Prop(_SC("ErrCode"), &Connection::GetErrorCode)
.Prop(_SC("ExErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ExtendedErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ErrStr"), &Connection::GetErrStr)
.Prop(_SC("ErrMsg"), &Connection::GetErrMsg)
.Prop(_SC("ReadOnly"), &Connection::IsReadOnly)
.Prop(_SC("Autocommit"), &Connection::GetAutoCommit)
.Prop(_SC("LastInsertRowId"), &Connection::GetLastInsertRowID)
.Prop(_SC("Changes"), &Connection::GetChanges)
.Prop(_SC("TotalChanges"), &Connection::GetTotalChanges)
.Prop(_SC("Trace"), &Connection::GetTracing, &Connection::SetTracing)
.Prop(_SC("Profile"), &Connection::GetProfiling, &Connection::SetProfiling)
.Prop(_SC("QueueSize"), &Connection::QueueSize)
// Member Methods
.Func(_SC("Release"), &Connection::Release)
.FmtFunc(_SC("Exec"), &Connection::Exec)
.FmtFunc(_SC("Queue"), &Connection::Queue)
.FmtFunc(_SC("Query"), &Connection::Query)
.FmtFunc(_SC("TableExists"), &Connection::TableExists)
.Func(_SC("InterruptOperation"), &Connection::InterruptOperation)
.Func(_SC("SetBusyTimeout"), &Connection::SetBusyTimeout)
.Func(_SC("ReleaseMemory"), &Connection::ReleaseMemory)
.Func(_SC("ReserveQueue"), &Connection::ReserveQueue)
.Func(_SC("CompactQueue"), &Connection::CompactQueue)
.Func(_SC("ClearQueue"), &Connection::ClearQueue)
.Func(_SC("PopQueue"), &Connection::PopQueue)
// Member Overloads
.Overload< void (Connection::*)(StackStrF &) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(StackStrF &, Int32) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(StackStrF &, Int32, StackStrF &) >(_SC("Open"), &Connection::Open)
.Overload< Int32 (Connection::*)(Int32) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(void) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(SQInteger) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(Object &, Function &) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(SQInteger, Object &, Function &) >(_SC("Flush"), &Connection::Flush)
);
}
} // Namespace:: SqMod

View File

@ -1,478 +0,0 @@
#ifndef _SQSQLITE_CONNECTION_HPP_
#define _SQSQLITE_CONNECTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Used to manage and interact with a database connection.
*/
class Connection
{
private:
// --------------------------------------------------------------------------------------------
ConnRef m_Handle; // Reference to the managed connection.
protected:
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateTracing()
*/
static void TraceOutput(void * ptr, CCStr sql);
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateProfiling()
*/
static void ProfileOutput(void * ptr, CCStr sql, sqlite3_uint64 time);
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetValid(CCStr file, Int32 line) const;
#else
const ConnRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetCreated(CCStr file, Int32 line) const;
#else
const ConnRef & GetCreated() const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
Connection()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(StackStrF & name)
: m_Handle(new ConnHnd())
{
SQMOD_GET_VALID(*this)->Create(name.mPtr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(StackStrF & name, Int32 flags)
: m_Handle(new ConnHnd())
{
SQMOD_GET_VALID(*this)->Create(name.mPtr, flags, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(StackStrF & name, Int32 flags, StackStrF & vfs)
: m_Handle(new ConnHnd())
{
SQMOD_GET_VALID(*this)->Create(name.mPtr, flags, vfs.mPtr);
}
/* --------------------------------------------------------------------------------------------
* Direct handle constructor.
*/
Connection(const ConnRef & c)
: m_Handle(c)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Connection(const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Connection(Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Connection & operator = (const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Connection & operator = (Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connections.
*/
bool operator == (const Connection & o) const
{
return (m_Handle == o.m_Handle);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two connections.
*/
bool operator != (const Connection & o) const
{
return (m_Handle != o.m_Handle);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the raw connection handle.
*/
operator sqlite3 * ()
{
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the raw connection handle.
*/
operator sqlite3 * () const
{
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const
{
return m_Handle ? m_Handle->mName : NullString();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated connection handle.
*/
const ConnRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed connection handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed connection handle was connected.
*/
bool IsConnected() const
{
return m_Handle && (m_Handle->mPtr != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this connection handle.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Release the reference to the associated database connection.
*/
void Release()
{
m_Handle.Reset();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last received status code.
*/
Int32 GetStatus() const
{
return SQMOD_GET_VALID(*this)->mStatus;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the flags used to create this database connection.
*/
Int32 GetFlags() const
{
return SQMOD_GET_VALID(*this)->mFlags;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the name used to create this database connection.
*/
const String & GetName() const
{
return SQMOD_GET_VALID(*this)->mName;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the virtual file system used to create this database connection.
*/
const String GetVFS() const
{
return SQMOD_GET_VALID(*this)->mVFS;
}
/* --------------------------------------------------------------------------------------------
* Return the numeric result code for the most recent failed API call (if any).
*/
Int32 GetErrorCode() const
{
return SQMOD_GET_VALID(*this)->ErrNo();
}
/* --------------------------------------------------------------------------------------------
* Return the extended numeric result code for the most recent failed API call (if any).
*/
Int32 GetExtendedErrorCode() const
{
return SQMOD_GET_VALID(*this)->ExErrNo();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CSStr GetErrStr() const
{
return SQMOD_GET_VALID(*this)->ErrStr();
}
/* --------------------------------------------------------------------------------------------
* Return the last error message associated with this database connection.
*/
CSStr GetErrMsg() const
{
return SQMOD_GET_VALID(*this)->ErrMsg();
}
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(StackStrF & name);
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(StackStrF & name, Int32 flags);
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(StackStrF & name, Int32 flags, StackStrF & vfs);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
*/
Int32 Exec(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Attempt to queue the specified query.
*/
void Queue(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Attempt to create a statement from the specified query.
*/
Object Query(StackStrF & str) const;
/* --------------------------------------------------------------------------------------------
* See if the database connection was opened in read-only mode.
*/
bool IsReadOnly() const;
/* --------------------------------------------------------------------------------------------
* Shortcut to test if a table exists.
*/
bool TableExists(StackStrF & name) const;
/* --------------------------------------------------------------------------------------------
* See if the database connection is or is not in auto-commit mode.
*/
bool GetAutoCommit() const
{
return sqlite3_get_autocommit(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Get the row-id of the most recent successful INSERT into the database from the current connection.
*/
Object GetLastInsertRowID() const
{
return MakeSLongObj(sqlite3_last_insert_rowid(SQMOD_GET_CREATED(*this)->mPtr));
}
/* --------------------------------------------------------------------------------------------
* Returns the number of database rows that were changed, inserted or deleted
* by the most recently completed SQL statement.
*/
Int32 GetChanges() const
{
return sqlite3_changes(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Returns the total number of row changes caused by INSERT, UPDATE or DELETE statements
* since the database connection was opened.
*/
Int32 GetTotalChanges() const
{
return sqlite3_total_changes(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* See if this database connection has tracing enabled.
*/
bool GetTracing() const
{
return SQMOD_GET_VALID(*this)->mTrace;
}
/* --------------------------------------------------------------------------------------------
* Activate or deactivate tracing on this database connection.
*/
void SetTracing(bool toggle);
/* --------------------------------------------------------------------------------------------
* See if this database connection has profiling enabled.
*/
bool GetProfiling() const
{
return SQMOD_GET_VALID(*this)->mProfile;
}
/* --------------------------------------------------------------------------------------------
* Activate or deactivate profiling on this database connection.
*/
void SetProfiling(bool toggle);
/* --------------------------------------------------------------------------------------------
* Set a busy handler that sleeps for a specified amount of time when a table is locked.
*/
void SetBusyTimeout(Int32 millis);
/* --------------------------------------------------------------------------------------------
* Causes any pending database operation to abort and return at its earliest opportunity.
*/
void InterruptOperation() const
{
sqlite3_interrupt(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Attempts to free as much heap memory as possible from the database connection.
*/
void ReleaseMemory() const
{
sqlite3_db_release_memory(SQMOD_GET_CREATED(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Returns internal runtime status information associated with the current database connection.
*/
Int32 GetInfo(Int32 operation)
{
return GetInfo(operation, false, false);
}
/* --------------------------------------------------------------------------------------------
* Returns internal runtime status information associated with the current database connection.
*/
Int32 GetInfo(Int32 operation, bool highwater)
{
return GetInfo(operation, highwater, false);
}
/* --------------------------------------------------------------------------------------------
* Returns internal runtime status information associated with the current database connection.
*/
Int32 GetInfo(Int32 operation, bool highwater, bool reset);
/* --------------------------------------------------------------------------------------------
* Retrieve the number of queries in the queue.
*/
Uint32 QueueSize() const
{
return ConvTo< Uint32 >::From(SQMOD_GET_VALID(*this)->mQueue.size());
}
/* --------------------------------------------------------------------------------------------
* Reserve space upfront for the specified amount of queries in the query queue.
*/
void ReserveQueue(Uint32 num);
/* --------------------------------------------------------------------------------------------
* Release memory that is not occupied from the query queue.
*/
void CompactQueue()
{
SQMOD_GET_VALID(*this)->mQueue.shrink_to_fit();
}
/* --------------------------------------------------------------------------------------------
* Remove all queries from the queue without executing them.
*/
void ClearQueue()
{
SQMOD_GET_VALID(*this)->mQueue.clear();
}
/* --------------------------------------------------------------------------------------------
* Remove the last query from the queue.
*/
void PopQueue();
/* --------------------------------------------------------------------------------------------
* Flush all queries from the queue.
*/
Int32 Flush();
/* --------------------------------------------------------------------------------------------
* Flush a specific amount of queries from the queue.
*/
Int32 Flush(SQInteger num);
/* --------------------------------------------------------------------------------------------
* Flush all queries from the queue and handle errors manually.
*/
Int32 Flush(Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Flush a specific amount of queries from the queue and handle errors manually.
*/
Int32 Flush(SQInteger num, Object & env, Function & func);
};
} // Namespace:: SqMod
#endif // _SQSQLITE_CONNECTION_HPP_

View File

@ -1,367 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class that represents an integral enumeration value. Used to reduce compilation times.
*/
struct EnumElement
{
CSStr Name;
Int32 Value;
};
// ------------------------------------------------------------------------------------------------
static const EnumElement g_MainEnum[] = {
{_SC("ABORT"), SQLITE_ABORT},
{_SC("ABORT_ROLLBACK"), SQLITE_ABORT_ROLLBACK},
{_SC("ACCESS_EXISTS"), SQLITE_ACCESS_EXISTS},
{_SC("ACCESS_READ"), SQLITE_ACCESS_READ},
{_SC("ACCESS_READWRITE"), SQLITE_ACCESS_READWRITE},
{_SC("ALTER_TABLE"), SQLITE_ALTER_TABLE},
{_SC("ANALYZE"), SQLITE_ANALYZE},
{_SC("ANY"), SQLITE_ANY},
{_SC("ATTACH"), SQLITE_ATTACH},
{_SC("AUTH"), SQLITE_AUTH},
{_SC("AUTH_USER"), SQLITE_AUTH_USER},
{_SC("BLOB"), SQLITE_BLOB},
{_SC("BUSY"), SQLITE_BUSY},
{_SC("BUSY_RECOVERY"), SQLITE_BUSY_RECOVERY},
{_SC("BUSY_SNAPSHOT"), SQLITE_BUSY_SNAPSHOT},
{_SC("CANTOPEN"), SQLITE_CANTOPEN},
{_SC("CANTOPEN_CONVPATH"), SQLITE_CANTOPEN_CONVPATH},
{_SC("CANTOPEN_FULLPATH"), SQLITE_CANTOPEN_FULLPATH},
{_SC("CANTOPEN_ISDIR"), SQLITE_CANTOPEN_ISDIR},
{_SC("CANTOPEN_NOTEMPDIR"), SQLITE_CANTOPEN_NOTEMPDIR},
{_SC("CHECKPOINT_FULL"), SQLITE_CHECKPOINT_FULL},
{_SC("CHECKPOINT_PASSIVE"), SQLITE_CHECKPOINT_PASSIVE},
{_SC("CHECKPOINT_RESTART"), SQLITE_CHECKPOINT_RESTART},
{_SC("CHECKPOINT_TRUNCATE"), SQLITE_CHECKPOINT_TRUNCATE},
{_SC("CONFIG_COVERING_INDEX_SCAN"), SQLITE_CONFIG_COVERING_INDEX_SCAN},
{_SC("CONFIG_GETMALLOC"), SQLITE_CONFIG_GETMALLOC},
{_SC("CONFIG_GETMUTEX"), SQLITE_CONFIG_GETMUTEX},
{_SC("CONFIG_GETPCACHE"), SQLITE_CONFIG_GETPCACHE},
{_SC("CONFIG_GETPCACHE2"), SQLITE_CONFIG_GETPCACHE2},
{_SC("CONFIG_HEAP"), SQLITE_CONFIG_HEAP},
{_SC("CONFIG_LOG"), SQLITE_CONFIG_LOG},
{_SC("CONFIG_LOOKASIDE"), SQLITE_CONFIG_LOOKASIDE},
{_SC("CONFIG_MALLOC"), SQLITE_CONFIG_MALLOC},
{_SC("CONFIG_MEMSTATUS"), SQLITE_CONFIG_MEMSTATUS},
{_SC("CONFIG_MMAP_SIZE"), SQLITE_CONFIG_MMAP_SIZE},
{_SC("CONFIG_MULTITHREAD"), SQLITE_CONFIG_MULTITHREAD},
{_SC("CONFIG_MUTEX"), SQLITE_CONFIG_MUTEX},
{_SC("CONFIG_PAGECACHE"), SQLITE_CONFIG_PAGECACHE},
{_SC("CONFIG_PCACHE"), SQLITE_CONFIG_PCACHE},
{_SC("CONFIG_PCACHE2"), SQLITE_CONFIG_PCACHE2},
{_SC("CONFIG_PCACHE_HDRSZ"), SQLITE_CONFIG_PCACHE_HDRSZ},
{_SC("CONFIG_PMASZ"), SQLITE_CONFIG_PMASZ},
{_SC("CONFIG_SCRATCH"), SQLITE_CONFIG_SCRATCH},
{_SC("CONFIG_SERIALIZED"), SQLITE_CONFIG_SERIALIZED},
{_SC("CONFIG_SINGLETHREAD"), SQLITE_CONFIG_SINGLETHREAD},
{_SC("CONFIG_SQLLOG"), SQLITE_CONFIG_SQLLOG},
{_SC("CONFIG_URI"), SQLITE_CONFIG_URI},
{_SC("CONFIG_WIN32_HEAPSIZE"), SQLITE_CONFIG_WIN32_HEAPSIZE},
{_SC("CONSTRAINT"), SQLITE_CONSTRAINT},
{_SC("CONSTRAINT_CHECK"), SQLITE_CONSTRAINT_CHECK},
{_SC("CONSTRAINT_COMMITHOOK"), SQLITE_CONSTRAINT_COMMITHOOK},
{_SC("CONSTRAINT_FOREIGNKEY"), SQLITE_CONSTRAINT_FOREIGNKEY},
{_SC("CONSTRAINT_FUNCTION"), SQLITE_CONSTRAINT_FUNCTION},
{_SC("CONSTRAINT_NOTNULL"), SQLITE_CONSTRAINT_NOTNULL},
{_SC("CONSTRAINT_PRIMARYKEY"), SQLITE_CONSTRAINT_PRIMARYKEY},
{_SC("CONSTRAINT_ROWID"), SQLITE_CONSTRAINT_ROWID},
{_SC("CONSTRAINT_TRIGGER"), SQLITE_CONSTRAINT_TRIGGER},
{_SC("CONSTRAINT_UNIQUE"), SQLITE_CONSTRAINT_UNIQUE},
{_SC("CONSTRAINT_VTAB"), SQLITE_CONSTRAINT_VTAB},
{_SC("COPY"), SQLITE_COPY},
{_SC("CORRUPT"), SQLITE_CORRUPT},
{_SC("CORRUPT_VTAB"), SQLITE_CORRUPT_VTAB},
{_SC("CREATE_INDEX"), SQLITE_CREATE_INDEX},
{_SC("CREATE_TABLE"), SQLITE_CREATE_TABLE},
{_SC("CREATE_TEMP_INDEX"), SQLITE_CREATE_TEMP_INDEX},
{_SC("CREATE_TEMP_TABLE"), SQLITE_CREATE_TEMP_TABLE},
{_SC("CREATE_TEMP_TRIGGER"), SQLITE_CREATE_TEMP_TRIGGER},
{_SC("CREATE_TEMP_VIEW"), SQLITE_CREATE_TEMP_VIEW},
{_SC("CREATE_TRIGGER"), SQLITE_CREATE_TRIGGER},
{_SC("CREATE_VIEW"), SQLITE_CREATE_VIEW},
{_SC("CREATE_VTABLE"), SQLITE_CREATE_VTABLE},
{_SC("DBCONFIG_ENABLE_FKEY"), SQLITE_DBCONFIG_ENABLE_FKEY},
{_SC("DBCONFIG_ENABLE_TRIGGER"), SQLITE_DBCONFIG_ENABLE_TRIGGER},
{_SC("DBCONFIG_LOOKASIDE"), SQLITE_DBCONFIG_LOOKASIDE},
{_SC("DBSTATUS_CACHE_HIT"), SQLITE_DBSTATUS_CACHE_HIT},
{_SC("DBSTATUS_CACHE_MISS"), SQLITE_DBSTATUS_CACHE_MISS},
{_SC("DBSTATUS_CACHE_USED"), SQLITE_DBSTATUS_CACHE_USED},
{_SC("DBSTATUS_CACHE_WRITE"), SQLITE_DBSTATUS_CACHE_WRITE},
{_SC("DBSTATUS_DEFERRED_FKS"), SQLITE_DBSTATUS_DEFERRED_FKS},
{_SC("DBSTATUS_LOOKASIDE_HIT"), SQLITE_DBSTATUS_LOOKASIDE_HIT},
{_SC("DBSTATUS_LOOKASIDE_MISS_FULL"), SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL},
{_SC("DBSTATUS_LOOKASIDE_MISS_SIZE"), SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE},
{_SC("DBSTATUS_LOOKASIDE_USED"), SQLITE_DBSTATUS_LOOKASIDE_USED},
{_SC("DBSTATUS_MAX"), SQLITE_DBSTATUS_MAX},
{_SC("DBSTATUS_SCHEMA_USED"), SQLITE_DBSTATUS_SCHEMA_USED},
{_SC("DBSTATUS_STMT_USED"), SQLITE_DBSTATUS_STMT_USED},
{_SC("DELETE"), SQLITE_DELETE},
{_SC("DENY"), SQLITE_DENY},
{_SC("DETACH"), SQLITE_DETACH},
{_SC("DETERMINISTIC"), SQLITE_DETERMINISTIC},
{_SC("DONE"), SQLITE_DONE},
{_SC("DROP_INDEX"), SQLITE_DROP_INDEX},
{_SC("DROP_TABLE"), SQLITE_DROP_TABLE},
{_SC("DROP_TEMP_INDEX"), SQLITE_DROP_TEMP_INDEX},
{_SC("DROP_TEMP_TABLE"), SQLITE_DROP_TEMP_TABLE},
{_SC("DROP_TEMP_TRIGGER"), SQLITE_DROP_TEMP_TRIGGER},
{_SC("DROP_TEMP_VIEW"), SQLITE_DROP_TEMP_VIEW},
{_SC("DROP_TRIGGER"), SQLITE_DROP_TRIGGER},
{_SC("DROP_VIEW"), SQLITE_DROP_VIEW},
{_SC("DROP_VTABLE"), SQLITE_DROP_VTABLE},
{_SC("EMPTY"), SQLITE_EMPTY},
{_SC("ERROR"), SQLITE_ERROR},
{_SC("FAIL"), SQLITE_FAIL},
{_SC("FCNTL_BUSYHANDLER"), SQLITE_FCNTL_BUSYHANDLER},
{_SC("FCNTL_CHUNK_SIZE"), SQLITE_FCNTL_CHUNK_SIZE},
{_SC("FCNTL_COMMIT_PHASETWO"), SQLITE_FCNTL_COMMIT_PHASETWO},
{_SC("FCNTL_FILE_POINTER"), SQLITE_FCNTL_FILE_POINTER},
{_SC("FCNTL_GET_LOCKPROXYFILE"), SQLITE_FCNTL_GET_LOCKPROXYFILE},
{_SC("FCNTL_HAS_MOVED"), SQLITE_FCNTL_HAS_MOVED},
{_SC("FCNTL_LAST_ERRNO"), SQLITE_FCNTL_LAST_ERRNO},
{_SC("FCNTL_LOCKSTATE"), SQLITE_FCNTL_LOCKSTATE},
{_SC("FCNTL_MMAP_SIZE"), SQLITE_FCNTL_MMAP_SIZE},
{_SC("FCNTL_OVERWRITE"), SQLITE_FCNTL_OVERWRITE},
{_SC("FCNTL_PERSIST_WAL"), SQLITE_FCNTL_PERSIST_WAL},
{_SC("FCNTL_POWERSAFE_OVERWRITE"), SQLITE_FCNTL_POWERSAFE_OVERWRITE},
{_SC("FCNTL_PRAGMA"), SQLITE_FCNTL_PRAGMA},
{_SC("FCNTL_RBU"), SQLITE_FCNTL_RBU},
{_SC("FCNTL_SET_LOCKPROXYFILE"), SQLITE_FCNTL_SET_LOCKPROXYFILE},
{_SC("FCNTL_SIZE_HINT"), SQLITE_FCNTL_SIZE_HINT},
{_SC("FCNTL_SYNC"), SQLITE_FCNTL_SYNC},
{_SC("FCNTL_SYNC_OMITTED"), SQLITE_FCNTL_SYNC_OMITTED},
{_SC("FCNTL_TEMPFILENAME"), SQLITE_FCNTL_TEMPFILENAME},
{_SC("FCNTL_TRACE"), SQLITE_FCNTL_TRACE},
{_SC("FCNTL_VFSNAME"), SQLITE_FCNTL_VFSNAME},
{_SC("FCNTL_WAL_BLOCK"), SQLITE_FCNTL_WAL_BLOCK},
{_SC("FCNTL_WIN32_AV_RETRY"), SQLITE_FCNTL_WIN32_AV_RETRY},
{_SC("FCNTL_WIN32_SET_HANDLE"), SQLITE_FCNTL_WIN32_SET_HANDLE},
{_SC("FCNTL_ZIPVFS"), SQLITE_FCNTL_ZIPVFS},
{_SC("FLOAT"), SQLITE_FLOAT},
{_SC("FORMAT"), SQLITE_FORMAT},
{_SC("FULL"), SQLITE_FULL},
{_SC("FUNCTION"), SQLITE_FUNCTION},
{_SC("IGNORE"), SQLITE_IGNORE},
{_SC("INDEX_CONSTRAINT_EQ"), SQLITE_INDEX_CONSTRAINT_EQ},
{_SC("INDEX_CONSTRAINT_GE"), SQLITE_INDEX_CONSTRAINT_GE},
{_SC("INDEX_CONSTRAINT_GT"), SQLITE_INDEX_CONSTRAINT_GT},
{_SC("INDEX_CONSTRAINT_LE"), SQLITE_INDEX_CONSTRAINT_LE},
{_SC("INDEX_CONSTRAINT_LT"), SQLITE_INDEX_CONSTRAINT_LT},
{_SC("INDEX_CONSTRAINT_MATCH"), SQLITE_INDEX_CONSTRAINT_MATCH},
{_SC("INDEX_SCAN_UNIQUE"), SQLITE_INDEX_SCAN_UNIQUE},
{_SC("INSERT"), SQLITE_INSERT},
{_SC("INTEGER"), SQLITE_INTEGER},
{_SC("INTERNAL"), SQLITE_INTERNAL},
{_SC("INTERRUPT"), SQLITE_INTERRUPT},
{_SC("IOCAP_ATOMIC"), SQLITE_IOCAP_ATOMIC},
{_SC("IOCAP_ATOMIC16K"), SQLITE_IOCAP_ATOMIC16K},
{_SC("IOCAP_ATOMIC1K"), SQLITE_IOCAP_ATOMIC1K},
{_SC("IOCAP_ATOMIC2K"), SQLITE_IOCAP_ATOMIC2K},
{_SC("IOCAP_ATOMIC32K"), SQLITE_IOCAP_ATOMIC32K},
{_SC("IOCAP_ATOMIC4K"), SQLITE_IOCAP_ATOMIC4K},
{_SC("IOCAP_ATOMIC512"), SQLITE_IOCAP_ATOMIC512},
{_SC("IOCAP_ATOMIC64K"), SQLITE_IOCAP_ATOMIC64K},
{_SC("IOCAP_ATOMIC8K"), SQLITE_IOCAP_ATOMIC8K},
{_SC("IOCAP_IMMUTABLE"), SQLITE_IOCAP_IMMUTABLE},
{_SC("IOCAP_POWERSAFE_OVERWRITE"), SQLITE_IOCAP_POWERSAFE_OVERWRITE},
{_SC("IOCAP_SAFE_APPEND"), SQLITE_IOCAP_SAFE_APPEND},
{_SC("IOCAP_SEQUENTIAL"), SQLITE_IOCAP_SEQUENTIAL},
{_SC("IOCAP_UNDELETABLE_WHEN_OPEN"), SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN},
{_SC("IOERR"), SQLITE_IOERR},
{_SC("IOERR_ACCESS"), SQLITE_IOERR_ACCESS},
{_SC("IOERR_BLOCKED"), SQLITE_IOERR_BLOCKED},
{_SC("IOERR_CHECKRESERVEDLOCK"), SQLITE_IOERR_CHECKRESERVEDLOCK},
{_SC("IOERR_CLOSE"), SQLITE_IOERR_CLOSE},
{_SC("IOERR_CONVPATH"), SQLITE_IOERR_CONVPATH},
{_SC("IOERR_DELETE"), SQLITE_IOERR_DELETE},
{_SC("IOERR_DELETE_NOENT"), SQLITE_IOERR_DELETE_NOENT},
{_SC("IOERR_DIR_CLOSE"), SQLITE_IOERR_DIR_CLOSE},
{_SC("IOERR_DIR_FSYNC"), SQLITE_IOERR_DIR_FSYNC},
{_SC("IOERR_FSTAT"), SQLITE_IOERR_FSTAT},
{_SC("IOERR_FSYNC"), SQLITE_IOERR_FSYNC},
{_SC("IOERR_GETTEMPPATH"), SQLITE_IOERR_GETTEMPPATH},
{_SC("IOERR_LOCK"), SQLITE_IOERR_LOCK},
{_SC("IOERR_MMAP"), SQLITE_IOERR_MMAP},
{_SC("IOERR_NOMEM"), SQLITE_IOERR_NOMEM},
{_SC("IOERR_RDLOCK"), SQLITE_IOERR_RDLOCK},
{_SC("IOERR_READ"), SQLITE_IOERR_READ},
{_SC("IOERR_SEEK"), SQLITE_IOERR_SEEK},
{_SC("IOERR_SHMLOCK"), SQLITE_IOERR_SHMLOCK},
{_SC("IOERR_SHMMAP"), SQLITE_IOERR_SHMMAP},
{_SC("IOERR_SHMOPEN"), SQLITE_IOERR_SHMOPEN},
{_SC("IOERR_SHMSIZE"), SQLITE_IOERR_SHMSIZE},
{_SC("IOERR_SHORT_READ"), SQLITE_IOERR_SHORT_READ},
{_SC("IOERR_TRUNCATE"), SQLITE_IOERR_TRUNCATE},
{_SC("IOERR_UNLOCK"), SQLITE_IOERR_UNLOCK},
{_SC("IOERR_VNODE"), SQLITE_IOERR_VNODE},
{_SC("IOERR_WRITE"), SQLITE_IOERR_WRITE},
{_SC("LIMIT_ATTACHED"), SQLITE_LIMIT_ATTACHED},
{_SC("LIMIT_COLUMN"), SQLITE_LIMIT_COLUMN},
{_SC("LIMIT_COMPOUND_SELECT"), SQLITE_LIMIT_COMPOUND_SELECT},
{_SC("LIMIT_EXPR_DEPTH"), SQLITE_LIMIT_EXPR_DEPTH},
{_SC("LIMIT_FUNCTION_ARG"), SQLITE_LIMIT_FUNCTION_ARG},
{_SC("LIMIT_LENGTH"), SQLITE_LIMIT_LENGTH},
{_SC("LIMIT_LIKE_PATTERN_LENGTH"), SQLITE_LIMIT_LIKE_PATTERN_LENGTH},
{_SC("LIMIT_SQL_LENGTH"), SQLITE_LIMIT_SQL_LENGTH},
{_SC("LIMIT_TRIGGER_DEPTH"), SQLITE_LIMIT_TRIGGER_DEPTH},
{_SC("LIMIT_VARIABLE_NUMBER"), SQLITE_LIMIT_VARIABLE_NUMBER},
{_SC("LIMIT_VDBE_OP"), SQLITE_LIMIT_VDBE_OP},
{_SC("LIMIT_WORKER_THREADS"), SQLITE_LIMIT_WORKER_THREADS},
{_SC("LOCKED"), SQLITE_LOCKED},
{_SC("LOCKED_SHAREDCACHE"), SQLITE_LOCKED_SHAREDCACHE},
{_SC("LOCK_EXCLUSIVE"), SQLITE_LOCK_EXCLUSIVE},
{_SC("LOCK_NONE"), SQLITE_LOCK_NONE},
{_SC("LOCK_PENDING"), SQLITE_LOCK_PENDING},
{_SC("LOCK_RESERVED"), SQLITE_LOCK_RESERVED},
{_SC("LOCK_SHARED"), SQLITE_LOCK_SHARED},
{_SC("MISMATCH"), SQLITE_MISMATCH},
{_SC("MISUSE"), SQLITE_MISUSE},
{_SC("MUTEX_FAST"), SQLITE_MUTEX_FAST},
{_SC("MUTEX_RECURSIVE"), SQLITE_MUTEX_RECURSIVE},
{_SC("MUTEX_STATIC_APP1"), SQLITE_MUTEX_STATIC_APP1},
{_SC("MUTEX_STATIC_APP2"), SQLITE_MUTEX_STATIC_APP2},
{_SC("MUTEX_STATIC_APP3"), SQLITE_MUTEX_STATIC_APP3},
{_SC("MUTEX_STATIC_LRU"), SQLITE_MUTEX_STATIC_LRU},
{_SC("MUTEX_STATIC_LRU2"), SQLITE_MUTEX_STATIC_LRU2},
{_SC("MUTEX_STATIC_MASTER"), SQLITE_MUTEX_STATIC_MASTER},
{_SC("MUTEX_STATIC_MEM"), SQLITE_MUTEX_STATIC_MEM},
{_SC("MUTEX_STATIC_MEM2"), SQLITE_MUTEX_STATIC_MEM2},
{_SC("MUTEX_STATIC_OPEN"), SQLITE_MUTEX_STATIC_OPEN},
{_SC("MUTEX_STATIC_PMEM"), SQLITE_MUTEX_STATIC_PMEM},
{_SC("MUTEX_STATIC_PRNG"), SQLITE_MUTEX_STATIC_PRNG},
{_SC("MUTEX_STATIC_VFS1"), SQLITE_MUTEX_STATIC_VFS1},
{_SC("MUTEX_STATIC_VFS2"), SQLITE_MUTEX_STATIC_VFS2},
{_SC("MUTEX_STATIC_VFS3"), SQLITE_MUTEX_STATIC_VFS3},
{_SC("NOLFS"), SQLITE_NOLFS},
{_SC("NOMEM"), SQLITE_NOMEM},
{_SC("NOTADB"), SQLITE_NOTADB},
{_SC("NOTFOUND"), SQLITE_NOTFOUND},
{_SC("NOTICE"), SQLITE_NOTICE},
{_SC("NOTICE_RECOVER_ROLLBACK"), SQLITE_NOTICE_RECOVER_ROLLBACK},
{_SC("NOTICE_RECOVER_WAL"), SQLITE_NOTICE_RECOVER_WAL},
{_SC("NULL"), SQLITE_NULL},
{_SC("OK"), SQLITE_OK},
{_SC("OPEN_AUTOPROXY"), SQLITE_OPEN_AUTOPROXY},
{_SC("OPEN_CREATE"), SQLITE_OPEN_CREATE},
{_SC("OPEN_DELETEONCLOSE"), SQLITE_OPEN_DELETEONCLOSE},
{_SC("OPEN_EXCLUSIVE"), SQLITE_OPEN_EXCLUSIVE},
{_SC("OPEN_FULLMUTEX"), SQLITE_OPEN_FULLMUTEX},
{_SC("OPEN_MAIN_DB"), SQLITE_OPEN_MAIN_DB},
{_SC("OPEN_MAIN_JOURNAL"), SQLITE_OPEN_MAIN_JOURNAL},
{_SC("OPEN_MASTER_JOURNAL"), SQLITE_OPEN_MASTER_JOURNAL},
{_SC("OPEN_MEMORY"), SQLITE_OPEN_MEMORY},
{_SC("OPEN_NOMUTEX"), SQLITE_OPEN_NOMUTEX},
{_SC("OPEN_PRIVATECACHE"), SQLITE_OPEN_PRIVATECACHE},
{_SC("OPEN_READONLY"), SQLITE_OPEN_READONLY},
{_SC("OPEN_READWRITE"), SQLITE_OPEN_READWRITE},
{_SC("OPEN_SHAREDCACHE"), SQLITE_OPEN_SHAREDCACHE},
{_SC("OPEN_SUBJOURNAL"), SQLITE_OPEN_SUBJOURNAL},
{_SC("OPEN_TEMP_DB"), SQLITE_OPEN_TEMP_DB},
{_SC("OPEN_TEMP_JOURNAL"), SQLITE_OPEN_TEMP_JOURNAL},
{_SC("OPEN_TRANSIENT_DB"), SQLITE_OPEN_TRANSIENT_DB},
{_SC("OPEN_URI"), SQLITE_OPEN_URI},
{_SC("OPEN_WAL"), SQLITE_OPEN_WAL},
{_SC("PERM"), SQLITE_PERM},
{_SC("PRAGMA"), SQLITE_PRAGMA},
{_SC("PROTOCOL"), SQLITE_PROTOCOL},
{_SC("RANGE"), SQLITE_RANGE},
{_SC("READ"), SQLITE_READ},
{_SC("READONLY"), SQLITE_READONLY},
{_SC("READONLY_CANTLOCK"), SQLITE_READONLY_CANTLOCK},
{_SC("READONLY_DBMOVED"), SQLITE_READONLY_DBMOVED},
{_SC("READONLY_RECOVERY"), SQLITE_READONLY_RECOVERY},
{_SC("READONLY_ROLLBACK"), SQLITE_READONLY_ROLLBACK},
{_SC("RECURSIVE"), SQLITE_RECURSIVE},
{_SC("REINDEX"), SQLITE_REINDEX},
{_SC("REPLACE"), SQLITE_REPLACE},
{_SC("ROLLBACK"), SQLITE_ROLLBACK},
{_SC("ROW"), SQLITE_ROW},
{_SC("SAVEPOINT"), SQLITE_SAVEPOINT},
{_SC("SCANSTAT_EST"), SQLITE_SCANSTAT_EST},
{_SC("SCANSTAT_EXPLAIN"), SQLITE_SCANSTAT_EXPLAIN},
{_SC("SCANSTAT_NAME"), SQLITE_SCANSTAT_NAME},
{_SC("SCANSTAT_NLOOP"), SQLITE_SCANSTAT_NLOOP},
{_SC("SCANSTAT_NVISIT"), SQLITE_SCANSTAT_NVISIT},
{_SC("SCANSTAT_SELECTID"), SQLITE_SCANSTAT_SELECTID},
{_SC("SCHEMA"), SQLITE_SCHEMA},
{_SC("SELECT"), SQLITE_SELECT},
{_SC("SHM_EXCLUSIVE"), SQLITE_SHM_EXCLUSIVE},
{_SC("SHM_LOCK"), SQLITE_SHM_LOCK},
{_SC("SHM_NLOCK"), SQLITE_SHM_NLOCK},
{_SC("SHM_SHARED"), SQLITE_SHM_SHARED},
{_SC("SHM_UNLOCK"), SQLITE_SHM_UNLOCK},
{_SC("STATUS_MALLOC_COUNT"), SQLITE_STATUS_MALLOC_COUNT},
{_SC("STATUS_MALLOC_SIZE"), SQLITE_STATUS_MALLOC_SIZE},
{_SC("STATUS_MEMORY_USED"), SQLITE_STATUS_MEMORY_USED},
{_SC("STATUS_PAGECACHE_OVERFLOW"), SQLITE_STATUS_PAGECACHE_OVERFLOW},
{_SC("STATUS_PAGECACHE_SIZE"), SQLITE_STATUS_PAGECACHE_SIZE},
{_SC("STATUS_PAGECACHE_USED"), SQLITE_STATUS_PAGECACHE_USED},
{_SC("STATUS_PARSER_STACK"), SQLITE_STATUS_PARSER_STACK},
{_SC("STATUS_SCRATCH_OVERFLOW"), SQLITE_STATUS_SCRATCH_OVERFLOW},
{_SC("STATUS_SCRATCH_SIZE"), SQLITE_STATUS_SCRATCH_SIZE},
{_SC("STATUS_SCRATCH_USED"), SQLITE_STATUS_SCRATCH_USED},
{_SC("STMTSTATUS_AUTOINDEX"), SQLITE_STMTSTATUS_AUTOINDEX},
{_SC("STMTSTATUS_FULLSCAN_STEP"), SQLITE_STMTSTATUS_FULLSCAN_STEP},
{_SC("STMTSTATUS_SORT"), SQLITE_STMTSTATUS_SORT},
{_SC("STMTSTATUS_VM_STEP"), SQLITE_STMTSTATUS_VM_STEP},
{_SC("SYNC_DATAONLY"), SQLITE_SYNC_DATAONLY},
{_SC("SYNC_FULL"), SQLITE_SYNC_FULL},
{_SC("SYNC_NORMAL"), SQLITE_SYNC_NORMAL},
{_SC("TESTCTRL_ALWAYS"), SQLITE_TESTCTRL_ALWAYS},
{_SC("TESTCTRL_ASSERT"), SQLITE_TESTCTRL_ASSERT},
{_SC("TESTCTRL_BENIGN_MALLOC_HOOKS"), SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS},
{_SC("TESTCTRL_BITVEC_TEST"), SQLITE_TESTCTRL_BITVEC_TEST},
{_SC("TESTCTRL_BYTEORDER"), SQLITE_TESTCTRL_BYTEORDER},
{_SC("TESTCTRL_EXPLAIN_STMT"), SQLITE_TESTCTRL_EXPLAIN_STMT},
{_SC("TESTCTRL_FAULT_INSTALL"), SQLITE_TESTCTRL_FAULT_INSTALL},
{_SC("TESTCTRL_FIRST"), SQLITE_TESTCTRL_FIRST},
{_SC("TESTCTRL_IMPOSTER"), SQLITE_TESTCTRL_IMPOSTER},
{_SC("TESTCTRL_ISINIT"), SQLITE_TESTCTRL_ISINIT},
{_SC("TESTCTRL_ISKEYWORD"), SQLITE_TESTCTRL_ISKEYWORD},
{_SC("TESTCTRL_LAST"), SQLITE_TESTCTRL_LAST},
{_SC("TESTCTRL_LOCALTIME_FAULT"), SQLITE_TESTCTRL_LOCALTIME_FAULT},
{_SC("TESTCTRL_NEVER_CORRUPT"), SQLITE_TESTCTRL_NEVER_CORRUPT},
{_SC("TESTCTRL_OPTIMIZATIONS"), SQLITE_TESTCTRL_OPTIMIZATIONS},
{_SC("TESTCTRL_PENDING_BYTE"), SQLITE_TESTCTRL_PENDING_BYTE},
{_SC("TESTCTRL_PRNG_RESET"), SQLITE_TESTCTRL_PRNG_RESET},
{_SC("TESTCTRL_PRNG_RESTORE"), SQLITE_TESTCTRL_PRNG_RESTORE},
{_SC("TESTCTRL_PRNG_SAVE"), SQLITE_TESTCTRL_PRNG_SAVE},
{_SC("TESTCTRL_RESERVE"), SQLITE_TESTCTRL_RESERVE},
{_SC("TESTCTRL_SCRATCHMALLOC"), SQLITE_TESTCTRL_SCRATCHMALLOC},
{_SC("TESTCTRL_SORTER_MMAP"), SQLITE_TESTCTRL_SORTER_MMAP},
{_SC("TESTCTRL_VDBE_COVERAGE"), SQLITE_TESTCTRL_VDBE_COVERAGE},
{_SC("TEXT"), SQLITE_TEXT},
{_SC("TOOBIG"), SQLITE_TOOBIG},
{_SC("TRANSACTION"), SQLITE_TRANSACTION},
{_SC("UPDATE"), SQLITE_UPDATE},
{_SC("UTF16"), SQLITE_UTF16},
{_SC("UTF16BE"), SQLITE_UTF16BE},
{_SC("UTF16LE"), SQLITE_UTF16LE},
{_SC("UTF16_ALIGNED"), SQLITE_UTF16_ALIGNED},
{_SC("UTF8"), SQLITE_UTF8},
{_SC("VERSION_NUMBER"), SQLITE_VERSION_NUMBER},
{_SC("VTAB_CONSTRAINT_SUPPORT"), SQLITE_VTAB_CONSTRAINT_SUPPORT},
{_SC("WARNING"), SQLITE_WARNING},
{_SC("WARNING_AUTOINDEX"), SQLITE_WARNING_AUTOINDEX}
};
// ================================================================================================
void Register_Constants(Table & sqlns)
{
Enumeration e(sqlns.GetVM());
for (Uint32 n = 0; n < (sizeof(g_MainEnum) / sizeof(EnumElement)); ++n)
{
e.Const(g_MainEnum[n].Name, g_MainEnum[n].Value);
}
ConstTable(sqlns.GetVM()).Enum(_SC("ESQLite"), e);
}
} // Namespace:: SqMod

View File

@ -1,163 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
ConnHnd::ConnHnd()
: mPtr(nullptr)
, mStatus(SQLITE_OK)
, mQueue()
, mFlags(0)
, mName()
, mVFS()
, mMemory(false)
, mTrace(false)
, mProfile(false)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
ConnHnd::~ConnHnd()
{
// Is there anything to close?
if (mPtr != nullptr)
{
// Flush remaining queries in the queue and ignore the result
Flush(mQueue.size(), NullObject(), NullFunction());
// NOTE: Should we call sqlite3_interrupt(...) before closing?
// Attempt to close the database
if ((sqlite3_close(mPtr)) != SQLITE_OK)
{
SqMod_LogErr("Unable to close SQLite connection [%s]", sqlite3_errmsg(mPtr));
}
}
}
// ------------------------------------------------------------------------------------------------
void ConnHnd::Create(CSStr name, Int32 flags, CSStr vfs)
{
// Make sure a previous connection doesn't exist
if (mPtr)
{
STHROWF("Unable to connect to database. Database already connected");
}
// Make sure the name is valid
else if (!name || *name == '\0')
{
STHROWF("Unable to connect to database. The name is invalid");
}
// Attempt to create the database connection
else if ((mStatus = sqlite3_open_v2(name, &mPtr, flags, vfs)) != SQLITE_OK)
{
// Grab the error message before destroying the handle
String msg(sqlite3_errmsg(mPtr) ? sqlite3_errmsg(mPtr) : _SC("Unknown reason"));
// Must be destroyed regardless of result
sqlite3_close(mPtr);
// Prevent further use of this handle
mPtr = nullptr;
// Now its safe to throw the error
STHROWF("Unable to connect to database [%s]", msg.c_str());
}
// Let's save the specified information
mName.assign(name);
mFlags = flags;
mVFS.assign(vfs ? vfs : _SC(""));
// Optional check if database is initially stored in memory
mMemory = (mName.compare(_SC(":memory:")) == 0);
}
// ------------------------------------------------------------------------------------------------
Int32 ConnHnd::Flush(Uint32 num, Object & env, Function & func)
{
// Do we even have a valid connection?
if (!mPtr)
{
return -1; // No connection!
}
// Is there anything to flush?
else if (!num || mQueue.empty())
{
return 0; // Nothing to process!
}
// Can we even flush that many?
else if (num > mQueue.size())
{
num = mQueue.size();
}
// Generate the function that should be called upon error
Function callback = Function(env.GetVM(), env.GetObject(), func.GetFunc());
// Obtain iterators to the range of queries that should be flushed
QueryList::iterator itr = mQueue.begin();
QueryList::iterator end = mQueue.begin() + num;
// Attempt to begin the flush transaction
if ((mStatus = sqlite3_exec(mPtr, "BEGIN", nullptr, nullptr, nullptr)) != SQLITE_OK)
{
STHROWF("Unable to begin flush transaction [%s]", sqlite3_errmsg(mPtr));
}
// Process all queries within range of selection
for (; itr != end; ++itr)
{
// Should we manually terminate this query?
/*
if (*(*itr).rbegin() != ';')
{
itr->push_back(';');
}
*/
// Attempt to execute the currently processed query string
if ((mStatus = sqlite3_exec(mPtr, itr->c_str(), nullptr, nullptr, nullptr)) == SQLITE_OK)
{
continue;
}
// Do we have to execute any callback to resolve our issue?
else if (!callback.IsNull())
{
try
{
// Ask the callback whether the query processing should end here
SharedPtr< bool > ret = callback.Evaluate< bool >(mStatus, *itr);
// Should we break here?
if (!!ret && (*ret == false))
{
break;
}
}
catch (const Sqrat::Exception & e)
{
SqMod_LogErr("Squirrel error caught in flush handler [%s]", e.what());
}
catch (const std::exception & e)
{
SqMod_LogErr("Program error caught in flush handler [%s]", e.what());
}
catch (...)
{
SqMod_LogErr("Unknown error caught in flush handler");
}
}
}
// Erase all queries till end or till the point of failure (if any occurred)
mQueue.erase(mQueue.begin(), itr);
// Attempt to commit changes requested during transaction
if ((mStatus = sqlite3_exec(mPtr, "COMMIT", nullptr, nullptr, nullptr)) == SQLITE_OK)
{
return sqlite3_changes(mPtr);
}
// Attempt to roll back erroneous changes
else if ((mStatus = sqlite3_exec(mPtr, "ROLLBACK", nullptr, nullptr, nullptr)) != SQLITE_OK)
{
STHROWF("Unable to rollback flush transaction [%s]", sqlite3_errmsg(mPtr));
}
// The transaction failed somehow but we managed to rollback
else
{
STHROWF("Unable to commit flush transaction [%s]", sqlite3_errmsg(mPtr));
}
// Operation failed
return -1;
}
} // Namespace:: SqMod

View File

@ -1,130 +0,0 @@
#ifndef _SQSQLITE_HANDLE_CONNECTION_HPP_
#define _SQSQLITE_HANDLE_CONNECTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain connection.
*/
struct ConnHnd
{
public:
// --------------------------------------------------------------------------------------------
typedef sqlite3 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 std::vector< String > QueryList; // Container used to queue queries.
public:
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The connection handle resource.
// --------------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// --------------------------------------------------------------------------------------------
QueryList mQueue; // A queue of queries to be executed in groups.
// --------------------------------------------------------------------------------------------
Int32 mFlags; // The flags used to create the database connection handle.
String mName; // The specified name to be used as the database file.
String mVFS; // The specified virtual file system.
// --------------------------------------------------------------------------------------------
bool mMemory; // Whether the database exists in memory and not disk.
bool mTrace; // Whether tracing was activated on the database.
bool mProfile; // Whether profiling was activated on the database.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ConnHnd();
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
ConnHnd(const ConnHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
ConnHnd(ConnHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ConnHnd();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
ConnHnd & operator = (const ConnHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
ConnHnd & operator = (ConnHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Create the database connection resource.
*/
void Create(CSStr name, Int32 flags, CSStr vfs);
/* --------------------------------------------------------------------------------------------
* Execute a specific amount of queries from the queue.
*/
Int32 Flush(Uint32 num, Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CCStr ErrStr() const
{
return sqlite3_errstr(sqlite3_errcode(mPtr));
}
/* --------------------------------------------------------------------------------------------
* Return the last error message associated with this database connection.
*/
CCStr ErrMsg() const
{
return sqlite3_errmsg(mPtr);
}
/* --------------------------------------------------------------------------------------------
* Return the numeric result code for the most recent failed API call (if any).
*/
Int32 ErrNo() const
{
return sqlite3_errcode(mPtr);
}
/* --------------------------------------------------------------------------------------------
* Return the extended numeric result code for the most recent failed API call (if any).
*/
Int32 ExErrNo() const
{
return sqlite3_extended_errcode(mPtr);
}
};
} // Namespace:: SqMod
#endif // _SQSQLITE_HANDLE_CONNECTION_HPP_

View File

@ -1,143 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
StmtHnd::StmtHnd(const ConnRef & conn)
: mPtr(nullptr)
, mStatus(SQLITE_OK)
, mConn(conn)
, mQuery()
, mColumns(0)
, mParameters(0)
, mIndexes()
, mGood(false)
, mDone(false)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
StmtHnd::~StmtHnd()
{
// Is there anything to finalize?
if (mPtr != nullptr)
{
// Attempt to finalize the statement
if ((sqlite3_finalize(mPtr)) != SQLITE_OK)
{
SqMod_LogErr("Unable to finalize SQLite statement [%s]", mConn->ErrMsg());
}
}
}
// ------------------------------------------------------------------------------------------------
void StmtHnd::Create(CSStr query, SQInteger length)
{
// Make sure a previous statement doesn't exist
if (mPtr)
{
STHROWF("Unable to prepare statement. Statement already prepared");
}
// Is the specified database connection is valid?
else if (!mConn)
{
STHROWF("Unable to prepare statement. Invalid connection handle");
}
// Is the specified query string valid?
else if (!query || !length || *query == '\0')
{
STHROWF("Unable to prepare statement. Invalid or empty query string");
}
// Save the query string
mQuery.assign(query, length);
// Attempt to prepare a statement with the specified query string
if ((mStatus = sqlite3_prepare_v2(mConn->mPtr, mQuery.c_str(), ConvTo< Int32 >::From(mQuery.size()),
&mPtr, nullptr)) != SQLITE_OK)
{
// Clear the query string since it failed
mQuery.clear();
// Explicitly make sure the handle is null
mPtr = nullptr;
// Now it's safe to throw the error
STHROWF("Unable to prepare statement [%s]", mConn->ErrMsg());
}
else
{
// Obtain the number of available columns
mColumns = sqlite3_column_count(mPtr);
// Obtain the number of available parameters
mParameters = sqlite3_bind_parameter_count(mPtr);
}
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::GetColumnIndex(CSStr name, SQInteger length)
{
// Validate the handle
if (!mPtr)
{
STHROWF("Invalid SQLite statement");
}
// Are the names cached?
else if (mIndexes.empty())
{
for (Int32 i = 0; i < mColumns; ++i)
{
// Get the column name at the current index
CSStr name = static_cast< CSStr >(sqlite3_column_name(mPtr, i));
// Validate the name
if (!name)
{
STHROWF("Unable to retrieve column name for index (%d)", i);
}
// Save it to guarantee the same lifetime as this instance
else
{
mIndexes[name] = i;
}
}
}
const String str(name, length < 0 ? std::strlen(name) : length);
// Attempt to find the specified column
const Indexes::iterator itr = mIndexes.find(str);
// Was there a column with the specified name?
if (itr != mIndexes.end())
{
return itr->second;
}
// No such column exists (expecting the invoker to validate the result)
return -1;
}
// ------------------------------------------------------------------------------------------------
CCStr StmtHnd::ErrStr() const
{
return mConn ? sqlite3_errstr(sqlite3_errcode(mConn->mPtr)) : _SC("");
}
// ------------------------------------------------------------------------------------------------
CCStr StmtHnd::ErrMsg() const
{
return mConn ? sqlite3_errmsg(mConn->mPtr) : _SC("");
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::ErrNo() const
{
return mConn ? sqlite3_errcode(mConn->mPtr) : SQLITE_NOMEM;
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::ExErrNo() const
{
return mConn ? sqlite3_extended_errcode(mConn->mPtr) : SQLITE_NOMEM;
}
} // Namespace:: SqMod

View File

@ -1,136 +0,0 @@
#ifndef _SQSQLITE_HANDLE_STATEMENT_HPP_
#define _SQSQLITE_HANDLE_STATEMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <map>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain statement.
*/
struct StmtHnd
{
public:
// --------------------------------------------------------------------------------------------
typedef sqlite3_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 std::map< String, int > Indexes; // Container used to identify column indexes.
public:
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The statement handle resource.
// --------------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// --------------------------------------------------------------------------------------------
ConnRef mConn; // The handle to the associated database connection.
// --------------------------------------------------------------------------------------------
String mQuery; // The query string used to create this statement.
// --------------------------------------------------------------------------------------------
Int32 mColumns; // The amount of columns available in this statement.
Int32 mParameters; // The amount of parameters available in this statement.
Indexes mIndexes; // An associative container with column names and their index.
// --------------------------------------------------------------------------------------------
bool mGood; // True when a row has been fetched with step.
bool mDone; // True when the last step had no more rows to fetch.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
StmtHnd(const ConnRef & conn);
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
StmtHnd(const StmtHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
StmtHnd(StmtHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~StmtHnd();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
StmtHnd & operator = (const StmtHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
StmtHnd & operator = (StmtHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Create the database statement resource.
*/
void Create(CSStr query, SQInteger length = -1);
/* --------------------------------------------------------------------------------------------
* Check whether a specific column index is in range.
*/
bool CheckColumn(Int32 idx) const
{
return (idx >= 0) && (idx < mColumns);
}
/* --------------------------------------------------------------------------------------------
* Check whether a specific parameter index is in range.
*/
bool CheckParameter(Int32 idx) const
{
return (idx >= 1) && (idx <= mParameters);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the column index associated with the specified name.
*/
Int32 GetColumnIndex(CSStr name, SQInteger length = -1);
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CCStr ErrStr() const;
/* --------------------------------------------------------------------------------------------
* Return the last error message associated with this database connection.
*/
CCStr ErrMsg() const;
/* --------------------------------------------------------------------------------------------
* Return the numeric result code for the most recent failed API call (if any).
*/
Int32 ErrNo() const;
/* --------------------------------------------------------------------------------------------
* Return the extended numeric result code for the most recent failed API call (if any).
*/
Int32 ExErrNo() const;
};
} // Namespace:: SqMod
#endif // _SQSQLITE_HANDLE_STATEMENT_HPP_

View File

@ -1,222 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Constants(Table & sqlns);
extern void Register_Common(Table & sqlns);
extern void Register_Connection(Table & sqlns);
extern void Register_Statement(Table & sqlns);
extern void Register_Parameter(Table & sqlns);
extern void Register_Column(Table & sqlns);
extern void Register_Transaction(Table & sqlns);
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQSQLITE_NAME);
// Registration failed
return false;
}
Table sqlns(vm);
Register_Constants(sqlns);
Register_Common(sqlns);
Register_Connection(sqlns);
Register_Statement(sqlns);
Register_Parameter(sqlns);
Register_Column(sqlns);
Register_Transaction(sqlns);
RootTable(vm).Bind(_SC("SQLite"), sqlns);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQSQLITE_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQSQLITE_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQSQLITE_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQSQLITE_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Release script resources...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQSQLITE_NAME))
{
try
{
ImportModuleAPI(_Func, SQSQLITE_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQSQLITE_NAME);
OutputMessage("Author: %s", SQSQLITE_AUTHOR);
OutputMessage("Legal: %s", SQSQLITE_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQSQLITE_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQSQLITE_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQSQLITE_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQSQLITE_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,779 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Parameter.hpp"
// ------------------------------------------------------------------------------------------------
#include <ctime>
#include <cerrno>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
// Error message when failed to bind value to parameter index.
#define SQMOD_BINDFAILED "Unable to bind (%s) parameter (%d) because [%s]"
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqLiteParameter"))
// ------------------------------------------------------------------------------------------------
static inline bool IsDigitsOnly(CSStr str)
{
while (std::isdigit(*str) || std::isspace(*str))
{
++str;
}
// Return whether we reached the end while searching
return *str == '\0';
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Parameter::Validate(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
}
#else
void Parameter::Validate() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0", m_Index);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Parameter::ValidateCreated(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement =>[%s:%d]", file, line);
}
}
#else
void Parameter::ValidateCreated() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0", m_Index);
}
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Parameter::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const StmtRef & Parameter::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Parameter::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const StmtRef & Parameter::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Parameter::ValidateParam(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Is the specified index in range?
if (!m_Handle->CheckParameter(idx))
{
SqThrowF("Parameter index is out of range (%d:%d) =>[%s:%d]", idx, m_Handle->mParameters,
file, line);
}
}
#else
void Parameter::ValidateParam(Int32 idx) const
{
ValidateCreated();
// Is the specified index in range?
if (!m_Handle->CheckParameter(idx))
{
SqThrowF("Parameter index is out of range (%d:%d)", idx, m_Handle->mParameters);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Parameter::SetIndex(const Object & param)
{
// Where the index will be extracted
Int32 idx = 0;
// Grab the object virtual machine
HSQUIRRELVM vm = param.GetVM();
// Remember the current stack size
const StackGuard sg(vm);
// Push the specified object onto the stack
Var< const Object & >::push(vm, param);
// Identify the type of parameter was given
switch (param.GetType())
{
// Is this a string value?
case OT_STRING:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty parameter name");
}
// Attempt to find a parameter with the specified name
idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, val.mPtr);
} break;
// Is this an integer value? (or at least can be easily converted to one)
case OT_INTEGER:
case OT_FLOAT:
case OT_BOOL:
{
idx = ConvTo< Int32 >::From(SqMod_PopStackInteger(vm, -1));
} break;
// Is this an instance that we can extract either a string or integer from it?
case OT_INSTANCE:
{
// Obtain the object from the stack as a string
StackStrF val(vm, -1);
// Validate the result
if (SQ_FAILED(val.Proc(false)))
{
STHROWF("%s", LastErrorString(vm).c_str());
}
// Is the obtained string empty?
else if (val.mLen <= 0)
{
STHROWF("Cannot use an empty parameter name");
}
// Check if this value is made only of digits
else if (IsDigitsOnly(val.mPtr))
{
idx = ConvNum< Int32 >::FromStr(val.mPtr);
}
// Attempt to find a parameter with the specified name
else
{
idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, val.mPtr);
}
} break;
// We don't recognize this kind of value!
default: STHROWF("Unknown parameter index of type (%s)", SqTypeName(param.GetType()));
}
// Assign the index with a failsafe to invalid on error
AutoAssign< Int32 > aa(m_Index, 0, idx);
// Validate the obtained parameter index
SQMOD_VALIDATE_PARAM(*this, idx);
// Don't fall back to the invalid index anymore
aa.Set(idx);
}
// ------------------------------------------------------------------------------------------------
Object Parameter::GetStatement() const
{
return GetStatementObj(m_Handle);
}
// ------------------------------------------------------------------------------------------------
Object Parameter::GetConnection() const
{
return GetConnectionObj(SQMOD_GET_VALID(*this)->mConn);
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetValue(const Object & value)
{
switch (value.GetType())
{
case OT_NULL:
{
SetNull();
} break;
case OT_INTEGER:
{
SetInteger(value.Cast< SQInteger >());
} break;
case OT_FLOAT:
{
SetFloat(value.Cast< SQFloat >());
} break;
case OT_BOOL:
{
SetBool(value.Cast< bool >());
} break;
case OT_STRING:
{
SQMOD_VALIDATE_CREATED(*this);
// Remember the current stack size
const StackGuard sg;
// Push the object onto the stack
Var< Object >::push(DefaultVM::Get(), value);
// Pop the object from the stack as a string
const Var< CSStr > str(DefaultVM::Get(), -1);
// Attempt to bind the specified value
SetStringRaw(str.value, ConvTo< SQInteger >::From(str.size));
} break;
default: STHROWF("No known conversion for the specified value type");
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetBool(bool value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, value);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "bool", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetChar(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< SQChar >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "char", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetInteger(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_integer(m_Handle->mPtr, m_Index, value);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "integer", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetInt8(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Int8 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "int8", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetUint8(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Uint8 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "uint8", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetInt16(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Int16 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "int16", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetUint16(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Uint16 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "uint16", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetInt32(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Int32 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "int32", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetUint32(SQInteger value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< Uint32 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "uint32", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetInt64(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int64(m_Handle->mPtr, m_Index, FetchSLongObjVal(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "int64", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetUint64(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int64(m_Handle->mPtr, m_Index,
static_cast< Int64 >(FetchULongObjVal(value)));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "uint64", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetFloat(SQFloat value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, value);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "float", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetFloat32(SQFloat value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, ConvTo< Float32 >::From(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "float32", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetFloat64(SQFloat value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, value);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "float64", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetString(StackStrF & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value.mPtr, value.mLen, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "string", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetStringRaw(CSStr value, SQInteger length)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value, length, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "string", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetZeroBlob(SQInteger size)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_zeroblob(m_Handle->mPtr, m_Index, ConvTo< Int32 >::From(size));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "blob", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetBlob(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// The blob data pointer and size
SQUserPointer ptr = 0;
SQInteger len = 0;
// Grab the associated object virtual machine
HSQUIRRELVM vm = value.GetVM();
// Extract the blob data from the specified object
{
// Remember the current stack size
const StackGuard sg(vm);
// Push the specified object onto the stack
Var< const Object & >::push(vm, value);
// Grab the blob data pointer
if (SQ_FAILED(sqstd_getblob(vm, -1, &ptr)))
{
STHROWF("Unable to obtain the blob data");
}
// Grab the blob data size
len = sqstd_getblobsize(vm, -1);
}
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_blob(m_Handle->mPtr, m_Index, ptr, len, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "blob", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetData(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// The buffer data pointer and size
CCStr ptr = 0;
SQInteger len = 0;
// Grab the associated object virtual machine
HSQUIRRELVM vm = value.GetVM();
// Extract the buffer data from the specified object
{
// Remember the current stack size
const StackGuard sg(vm);
// Push the specified object onto the stack
Var< const Object & >::push(vm, value);
// Grab the buffer data pointer and size
if (SQ_FAILED(SqMod_GetBufferInfo(vm, -1, &ptr, &len, nullptr)))
{
STHROWF("Unable to obtain the buffer data");
}
}
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_blob(m_Handle->mPtr, m_Index, ptr, len, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "buffer", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetDate(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to generate the specified date string
CSStr ptr = FmtStr(_SC("%s 00:00:00"), FetchDateObjStr(value));
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, ptr, -1, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "date", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetDateEx(SQInteger year, SQInteger month, SQInteger day)
{
SQMOD_VALIDATE_CREATED(*this);
// Convert the specified values within the proper ranges
const uint16_t y = ConvTo< uint16_t >::From(year);
const uint8_t m = ConvTo< uint8_t >::From(month), d = ConvTo< uint8_t >::From(day);
// Validate the specified date
if (!SqMod_ValidDate(y, m, d))
{
STHROWF("Invalid date (%u-%u-%u)", y, m, d);
}
// Attempt to generate the specified date string
CSStr ptr = FmtStr(_SC("%u-%u-%u 00:00:00"), y, m, d);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, ptr, -1, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "date", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetTime(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, FetchTimeObjSeconds(value));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "time", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetTimeEx(SQInteger hour, SQInteger minute, SQInteger second)
{
SQMOD_VALIDATE_CREATED(*this);
// Convert the specified values within the proper ranges
const uint8_t h = ConvTo< uint8_t >::From(hour)
, m = ConvTo< uint8_t >::From(minute)
, s = ConvTo< uint8_t >::From(second);
// Is the specified hour within range?
if (h >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", h);
}
// Is the specified minute within range?
else if (m >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", m);
}
// Is the specified second within range?
else if (s >= 60)
{
STHROWF("Second value is out of range: %u >= 60", s);
}
// Calculate the number of seconds in the specified time and bind the resulted value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, (h * (60 * 60)) + (m * 60) + s);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "time", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetDatetime(const Object & value)
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to generate the specified date string and bind the resulted value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, FetchDatetimeObjStr(value),
-1, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "date-time", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetDatetimeEx(SQInteger year, SQInteger month, SQInteger day, SQInteger hour, SQInteger minute, SQInteger second)
{
SQMOD_VALIDATE_CREATED(*this);
// Convert the specified values within the proper ranges
const uint16_t y = ConvTo< uint16_t >::From(year);
const uint8_t mo = ConvTo< uint8_t >::From(month)
, d = ConvTo< uint8_t >::From(day)
, h = ConvTo< uint8_t >::From(hour)
, mi = ConvTo< uint8_t >::From(minute)
, s = ConvTo< uint8_t >::From(second);
// Validate the specified date
if (!SqMod_ValidDate(y, mo, d))
{
STHROWF("Invalid date (%u-%u-%u)", y, mo, d);
}
// Is the specified hour within range?
else if (h >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", h);
}
// Is the specified minute within range?
else if (mi >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", mi);
}
// Is the specified second within range?
else if (s >= 60)
{
STHROWF("Second value is out of range: %u >= 60", s);
}
// Attempt to generate the specified date string
CSStr ptr = FmtStr(_SC("%04u-%02u-%02u %02u:%02u:%02u"), y, mo, d, h, mi, s);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, ptr, -1, SQLITE_TRANSIENT);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "date-time", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetNow()
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index,
static_cast< Int32 >(std::time(nullptr)));
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "time-stamp", m_Index, m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
void Parameter::SetNull()
{
SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_null(m_Handle->mPtr, m_Index);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF(SQMOD_BINDFAILED, "null", m_Index, m_Handle->ErrMsg());
}
}
// ================================================================================================
void Register_Parameter(Table & sqlns)
{
sqlns.Bind(_SC("Parameter"),
Class< Parameter >(sqlns.GetVM(), Typename::Str)
// Constructors
.Ctor()
.Ctor< const Parameter & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Parameter::ToString)
// Properties
.Prop(_SC("IsValid"), &Parameter::IsValid)
.Prop(_SC("References"), &Parameter::GetRefCount)
.Prop(_SC("Index"), &Parameter::GetIndex)
.Prop(_SC("Statement"), &Parameter::GetStatement)
.Prop(_SC("Connection"), &Parameter::GetConnection)
.Prop(_SC("References"), &Parameter::GetRefCount)
.Prop(_SC("Name"), &Parameter::GetName)
// Member Methods
.Func(_SC("Release"), &Parameter::Release)
.Func(_SC("SetValue"), &Parameter::SetValue)
.Func(_SC("SetBool"), &Parameter::SetBool)
.Func(_SC("SetChar"), &Parameter::SetChar)
.Func(_SC("SetInteger"), &Parameter::SetInteger)
.Func(_SC("SetInt8"), &Parameter::SetInt8)
.Func(_SC("SetUint8"), &Parameter::SetUint8)
.Func(_SC("SetInt16"), &Parameter::SetInt16)
.Func(_SC("SetUint16"), &Parameter::SetUint16)
.Func(_SC("SetInt32"), &Parameter::SetInt32)
.Func(_SC("SetUint32"), &Parameter::SetUint32)
.Func(_SC("SetInt64"), &Parameter::SetInt64)
.Func(_SC("SetUint64"), &Parameter::SetUint64)
.Func(_SC("SetFloat"), &Parameter::SetFloat)
.Func(_SC("SetFloat32"), &Parameter::SetFloat32)
.Func(_SC("SetFloat64"), &Parameter::SetFloat64)
.FmtFunc(_SC("SetString"), &Parameter::SetString)
.Func(_SC("SetZeroBlob"), &Parameter::SetZeroBlob)
.Func(_SC("SetBlob"), &Parameter::SetBlob)
.Func(_SC("SetData"), &Parameter::SetData)
.Func(_SC("SetDate"), &Parameter::SetDate)
.Func(_SC("SetDateEx"), &Parameter::SetDateEx)
.Func(_SC("SetTime"), &Parameter::SetTime)
.Func(_SC("SetTimeEx"), &Parameter::SetTimeEx)
.Func(_SC("SetDatetime"), &Parameter::SetDatetime)
.Func(_SC("SetDatetimeEx"), &Parameter::SetDatetimeEx)
.Func(_SC("SetNow"), &Parameter::SetNow)
.Func(_SC("SetNull"), &Parameter::SetNull)
);
}
} // Namespace:: SqMod

View File

@ -1,409 +0,0 @@
#ifndef _SQSQLITE_PARAMETER_HPP_
#define _SQSQLITE_PARAMETER_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
// ------------------------------------------------------------------------------------------------
#include <cctype>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Used to manage and interact with parameters from a database statement.
*/
class Parameter
{
// --------------------------------------------------------------------------------------------
friend class Statement;
private:
// --------------------------------------------------------------------------------------------
Int32 m_Index; // The index of the managed parameter.
StmtRef m_Handle; // Reference to the managed statement.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and parameter index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateParam(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateParam(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(Int32 idx)
{
// Assign the index with a failsafe to invalid on error
AutoAssign< Int32 > aa(m_Index, -1, idx);
// Validate the obtained parameter index
SQMOD_VALIDATE_PARAM(*this, idx);
// Don't fall back to the invalid index anymore
aa.Set(idx);
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(CSStr name)
{
SetIndex(sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, name));
}
/* --------------------------------------------------------------------------------------------
* Modify the index to the specified value.
*/
void SetIndex(const Object & param);
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
Parameter()
: m_Index(0), m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* No parameter constructor.
*/
Parameter(const StmtRef & stmt)
: m_Index(0), m_Handle(stmt)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Index constructor.
*/
Parameter(const StmtRef & stmt, Int32 idx)
: m_Index(idx), m_Handle(stmt)
{
SQMOD_VALIDATE_PARAM(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Name constructor.
*/
Parameter(const StmtRef & stmt, CSStr name)
: m_Index(stmt ? sqlite3_bind_parameter_index(stmt->mPtr, name) : 0), m_Handle(stmt)
{
SQMOD_VALIDATE_PARAM(*this, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Dynamic constructor.
*/
Parameter(const StmtRef & stmt, const Object & param)
: m_Index(0), m_Handle(stmt)
{
if (!m_Handle)
{
STHROWF("Invalid SQLite statement reference");
}
// Extract the index
SetIndex(param);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Parameter(const Parameter & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Parameter(Parameter && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Parameter & operator = (const Parameter & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Parameter & operator = (Parameter && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two parameter indexes.
*/
bool operator == (const Parameter & o) const
{
return (m_Index == o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two parameter indexes.
*/
bool operator != (const Parameter & o) const
{
return (m_Index != o.m_Index);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Index >= 0;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
CSStr val = nullptr;
// Can we attempt to return the parameter name?
if (m_Handle && m_Index)
{
val = sqlite3_bind_parameter_name(m_Handle->mPtr, m_Index);
}
else
{
val = ToStrF(_SC("%d"), m_Index);
}
// Return the value if valid
return val ? val : _SC("");
}
/* --------------------------------------------------------------------------------------------
* See whether this statement is valid.
*/
bool IsValid() const
{
return m_Handle; // An invalid statement means an invalid parameter
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this statement handle.
*/
Uint32 GetRefCount() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated parameter index.
*/
Int32 GetIndex() const
{
return m_Index;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated database statement.
*/
Object GetStatement() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated database connection.
*/
Object GetConnection() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the name of the referenced parameter.
*/
CSStr GetName() const
{
return sqlite3_bind_parameter_name(SQMOD_GET_CREATED(*this)->mPtr, m_Index);
}
/* --------------------------------------------------------------------------------------------
* Release the reference to the associated database statement and parameter index.
*/
void Release()
{
m_Handle.Reset();
m_Index = 0;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a dynamic value at the referenced parameter index.
*/
void SetValue(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a boolean value at the referenced parameter index.
*/
void SetBool(bool value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a character value at the referenced parameter index.
*/
void SetChar(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a native integer value at the referenced parameter index.
*/
void SetInteger(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 8 bit integer value at the referenced parameter index.
*/
void SetInt8(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 8 bit integer value at the referenced parameter index.
*/
void SetUint8(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 16 bit integer value at the referenced parameter index.
*/
void SetInt16(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 16 bit integer value at the referenced parameter index.
*/
void SetUint16(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 32 bit integer value at the referenced parameter index.
*/
void SetInt32(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 32 bit integer value at the referenced parameter index.
*/
void SetUint32(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 64 bit integer value at the referenced parameter index.
*/
void SetInt64(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 64 bit integer value at the referenced parameter index.
*/
void SetUint64(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a native floating point value at the referenced parameter index.
*/
void SetFloat(SQFloat value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a 32 bit floating point value at the referenced parameter index.
*/
void SetFloat32(SQFloat value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a 64 bit floating point value at the referenced parameter index.
*/
void SetFloat64(SQFloat value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a string value at the referenced parameter index.
*/
void SetString(StackStrF & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a string value at the referenced parameter index.
*/
void SetStringRaw(CSStr value, SQInteger length = -1);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a zeroed blob value at the referenced parameter index.
*/
void SetZeroBlob(SQInteger size);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a blob value at the referenced parameter index.
*/
void SetBlob(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a buffer value at the referenced parameter index.
*/
void SetData(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date value at the referenced parameter index.
*/
void SetDate(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date value at the referenced parameter index.
*/
void SetDateEx(SQInteger year, SQInteger month, SQInteger day);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a time value at the referenced parameter index.
*/
void SetTime(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a time value at the referenced parameter index.
*/
void SetTimeEx(SQInteger hour, SQInteger minute, SQInteger second);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date-time value at the referenced parameter index.
*/
void SetDatetime(const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date-time value at the referenced parameter index.
*/
void SetDatetimeEx(SQInteger year, SQInteger month, SQInteger day, SQInteger hour, SQInteger minute, SQInteger second);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the current timestamp at the referenced parameter index.
*/
void SetNow();
/* --------------------------------------------------------------------------------------------
* Attempt to bind a null value at the referenced parameter index.
*/
void SetNull();
};
} // Namespace:: SqMod
#endif // _SQSQLITE_PARAMETER_HPP_

View File

@ -1,525 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Statement.hpp"
#include "Connection.hpp"
#include "Column.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqLiteStatement"))
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::Validate(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
}
#else
void Statement::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateCreated(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement =>[%s:%d]", file, line);
}
}
#else
void Statement::ValidateCreated() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Statement::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const StmtRef & Statement::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Statement::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const StmtRef & Statement::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateColumn(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Is the specified index in range?
if (!m_Handle->CheckColumn(idx))
{
SqThrowF("Column index is out of range: %d:%d =>[%s:%d]", idx, m_Handle->mColumns,
file, line);
}
}
#else
void Statement::ValidateColumn(Int32 idx) const
{
ValidateCreated();
// Is the specified index in range?
if (!m_Handle->CheckColumn(idx))
{
SqThrowF("Column index is out of range: %d:%d", idx, m_Handle->mColumns);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateParam(Int32 idx, CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Is the specified index in range?
if (!m_Handle->CheckParameter(idx))
{
SqThrowF("Parameter index is out of range: %d:%d =>[%s:%d]", idx, m_Handle->mParameters,
file, line);
}
}
#else
void Statement::ValidateParam(Int32 idx) const
{
ValidateCreated();
// Is the specified index in range?
if (!m_Handle->CheckParameter(idx))
{
SqThrowF("Parameter index is out of range: %d:%d", idx, m_Handle->mParameters);
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Statement::ValidateRow(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Do we have any rows available?
if (!m_Handle->mGood)
{
SqThrowF("No row available =>[%s:%d]", file, line);
}
}
#else
void Statement::ValidateRow() const
{
ValidateCreated();
// Do we have any rows available?
if (!m_Handle->mGood)
{
SqThrowF("No row available");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Statement::Statement(const Connection & connection, StackStrF & query)
: m_Handle(new StmtHnd(connection.GetHandle()))
{
SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen);
}
// ------------------------------------------------------------------------------------------------
Object Statement::GetConnection() const
{
return Object(new Connection(SQMOD_GET_VALID(*this)->mConn));
}
// ------------------------------------------------------------------------------------------------
Statement & Statement::Reset()
{
SQMOD_VALIDATE_CREATED(*this);
// Specify that we don't have a row available and we haven't finished stepping
m_Handle->mGood = false;
m_Handle->mDone = false;
// Attempt to reset the statement to it's initial state
m_Handle->mStatus = sqlite3_reset(m_Handle->mPtr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to reset statement [%s]", m_Handle->ErrStr());
}
// Allow further chaining of operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Statement & Statement::Clear()
{
SQMOD_VALIDATE_CREATED(*this);
// Specify that we don't have a row available and we haven't finished stepping
m_Handle->mGood = false;
m_Handle->mDone = false;
// Attempt to clear the statement
m_Handle->mStatus = sqlite3_clear_bindings(m_Handle->mPtr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to clear statement [%s]", m_Handle->ErrStr());
}
// Allow further chaining of operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Int32 Statement::Exec()
{
SQMOD_VALIDATE_CREATED(*this);
// Did we reset first?
if (m_Handle->mDone)
{
STHROWF("Executed without resetting first");
}
// Attempt to step the statement
m_Handle->mStatus = sqlite3_step(m_Handle->mPtr);
// Have we finished stepping?
if (m_Handle->mStatus == SQLITE_DONE)
{
// Specify that we don't have row available and we finished stepping
m_Handle->mGood = false;
m_Handle->mDone = true;
// Return the changes made by this statement
return sqlite3_changes(m_Handle->mConn->mPtr);
}
// Specify that we don't have any row and we haven't finished stepping
m_Handle->mGood = false;
m_Handle->mDone = false;
// Inspect the result
switch (m_Handle->mStatus)
{
// We don't expect any rows to be returned in this case!
case SQLITE_ROW: STHROWF("Results were found");
// fall through
case SQLITE_BUSY: STHROWF("Database was busy");
// fall through
case SQLITE_ERROR: STHROWF("Runtime error occurred");
// fall through
case SQLITE_MISUSE: STHROWF("Statement misuse");
// fall through
default: STHROWF("Unknown failure [%s]", m_Handle->ErrStr());
}
// Operation failed (shouldn't reach this point!)
return -1;
}
// ------------------------------------------------------------------------------------------------
bool Statement::Step()
{
SQMOD_VALIDATE_CREATED(*this);
// Did we reset first?
if (m_Handle->mDone)
{
STHROWF("Stepped without resetting first");
}
// Attempt to step the statement
m_Handle->mStatus = sqlite3_step(m_Handle->mPtr);
// Do we have a row available?
if (m_Handle->mStatus == SQLITE_ROW)
{
// Specify that we have a row available
return (m_Handle->mGood = true);
}
// Have we finished stepping?
else if (m_Handle->mStatus == SQLITE_DONE)
{
// Specify that we finished stepping
m_Handle->mDone = true;
// Specify that we don't have a row available
return (m_Handle->mGood = false);
}
// Specify that we don't have any row and we haven't finished stepping
m_Handle->mGood = false;
m_Handle->mDone = false;
// Inspect the result
switch (m_Handle->mStatus)
{
case SQLITE_BUSY: STHROWF("Database was busy");
// fall through
case SQLITE_ERROR: STHROWF("Runtime error occurred");
// fall through
case SQLITE_MISUSE: STHROWF("Statement misuse");
// fall through
default: STHROWF("Unknown failure [%s]", m_Handle->ErrStr());
}
// Operation failed (shouldn't reach this point!)
return false;
}
// ------------------------------------------------------------------------------------------------
Statement & Statement::SetArray(Int32 idx, const Array & arr)
{
// Obtain a script iterator
Array::iterator itr;
// Create a parameter instance to bind the values
Parameter param(m_Handle);
// Process each element until _next returns null
while (idx <= m_Handle->mParameters && arr.Next(itr))
{
// Update the parameter index
param.SetIndex(idx++);
// Bind it to the current index
param.SetValue(Object(itr.getValue()));
}
// Allow further chaining of operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Statement & Statement::SetTable(const Table & tbl)
{
// Is there anything to bind?
if (tbl.GetSize() <= 0)
{
return *this; // Nothing to bind!
}
// Obtain a table iterator
Table::iterator itr;
// Create a parameter instance to bind the values
Parameter param(m_Handle);
// Process each element until _next returns null
while (tbl.Next(itr))
{
// Update the parameter index
param.SetIndex(itr.getName());
// Bind it to the current index
param.SetValue(Object(itr.getValue()));
}
// Allow further chaining of operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Array Statement::GetArray(Int32 min, Int32 max) const
{
SQMOD_VALIDATE_ROW(*this);
// Is the specified minimum index valid?
if (min < 0)
{
STHROWF("Minimum is bellow zero: %d", min);
}
// Is the minimum actually the minimum?
else if (min > max)
{
STHROWF("Minimum is higher than maximum: %d > %d", min, max);
}
// Is the minimum in range?
else if (!m_Handle->CheckColumn(min))
{
STHROWF("Minimum is out of range: %d:%d", min, m_Handle->mColumns);
}
// Is the maximum in range?
else if (!m_Handle->CheckColumn(max))
{
STHROWF("Maximum is out of range: %d:%d", max, m_Handle->mColumns);
}
// Allocate an array large enough to hold the values from selected columns
Array arr(DefaultVM::Get(), max-min);
// Create a column instance to retrieve the values
Column column(m_Handle);
// Array element counter
Int32 elem = 0;
// Process the range of selected columns
while (min <= max)
{
// Update the column index
column.SetIndex(min++);
// Retrieve the column value and bind it to the array
arr.SetValue(elem++, column.GetValue());
}
// Return the resulted array
return arr;
}
// ------------------------------------------------------------------------------------------------
Table Statement::GetTable(Int32 min, Int32 max) const
{
SQMOD_VALIDATE_ROW(*this);
// Is the specified minimum index valid?
if (min < 0)
{
STHROWF("Minimum is bellow zero: %d", min);
}
// Is the minimum actually the minimum?
else if (min > max)
{
STHROWF("Minimum is higher than maximum: %d > %d", min, max);
}
// Is the minimum in range>
else if (!m_Handle->CheckColumn(min))
{
STHROWF("Minimum is out of range: %d:%d", min, m_Handle->mColumns);
}
// Is the maximum in range?
else if (!m_Handle->CheckColumn(max))
{
STHROWF("Maximum is out of range: %d:%d", max, m_Handle->mColumns);
}
// Create a table to hold the selected column values
Table tbl(DefaultVM::Get());
// Create a column instance to retrieve the values
Column column(m_Handle);
// Process the range of selected columns
while (min <= max)
{
// Attempt to obtain the column name
CSStr name = sqlite3_column_name(m_Handle->mPtr, min);
// Validate the obtained name
if (!name)
{
STHROWF("Unable to retrieve name of column (%d)", min);
}
// Update the column index
column.SetIndex(min++);
// Retrieve the column value and bind it to the table
tbl.SetValue(name, column.GetValue());
}
// Return the resulted table
return tbl;
}
// ================================================================================================
void Register_Statement(Table & sqlns)
{
sqlns.Bind(_SC("Statement"),
Class< Statement >(sqlns.GetVM(), Typename::Str)
// Constructors
.Ctor()
.Ctor< const Statement & >()
.Ctor< const Connection &, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Statement::ToString)
// Properties
.Prop(_SC("IsValid"), &Statement::IsValid)
.Prop(_SC("Prepared"), &Statement::IsPrepared)
.Prop(_SC("References"), &Statement::GetReferences)
.Prop(_SC("Connection"), &Statement::GetConnection)
.Prop(_SC("Status"), &Statement::GetStatus)
.Prop(_SC("ErrCode"), &Statement::GetErrorCode)
.Prop(_SC("ExErrCode"), &Statement::GetExtendedErrorCode)
.Prop(_SC("ExtendedErrCode"), &Statement::GetExtendedErrorCode)
.Prop(_SC("ErrStr"), &Statement::GetErrStr)
.Prop(_SC("ErrMsg"), &Statement::GetErrMsg)
.Prop(_SC("Columns"), &Statement::GetColumns)
.Prop(_SC("Parameters"), &Statement::GetParameters)
.Prop(_SC("Query"), &Statement::GetQuery)
.Prop(_SC("Good"), &Statement::GetGood)
.Prop(_SC("Done"), &Statement::GetDone)
.Prop(_SC("DataCount"), &Statement::GetDataCount)
// Member Methods
.Func(_SC("Release"), &Statement::Release)
.Func(_SC("CheckParameter"), &Statement::CheckParameter)
.FmtFunc(_SC("GetParameterIndex"), &Statement::GetParameterIndex)
.Func(_SC("GetParameterName"), &Statement::GetParameterName)
.Func(_SC("CheckColumn"), &Statement::CheckColumn)
.Func(_SC("IsColumnNull"), &Statement::IsColumnNull)
.FmtFunc(_SC("ColumnIndex"), &Statement::GetColumnIndex)
.Func(_SC("ColumnName"), &Statement::GetColumnName)
.Func(_SC("ColumnOriginName"), &Statement::GetColumnOriginName)
.Func(_SC("ColumnType"), &Statement::GetColumnType)
.Func(_SC("ColumnBytes"), &Statement::GetColumnBytes)
.Func(_SC("Reset"), &Statement::Reset)
.Func(_SC("Clear"), &Statement::Clear)
.Func(_SC("Exec"), &Statement::Exec)
.Func(_SC("Step"), &Statement::Step)
.Func(_SC("Param"), &Statement::GetParameter)
.Func(_SC("Parameter"), &Statement::GetParameter)
.Func(_SC("SetValue"), &Statement::SetValue)
.Func(_SC("SetBool"), &Statement::SetBool)
.Func(_SC("SetChar"), &Statement::SetChar)
.Func(_SC("SetInteger"), &Statement::SetInteger)
.Func(_SC("SetInt8"), &Statement::SetInt8)
.Func(_SC("SetUint8"), &Statement::SetUint8)
.Func(_SC("SetInt16"), &Statement::SetInt16)
.Func(_SC("SetUint16"), &Statement::SetUint16)
.Func(_SC("SetInt32"), &Statement::SetInt32)
.Func(_SC("SetUint32"), &Statement::SetUint32)
.Func(_SC("SetInt64"), &Statement::SetInt64)
.Func(_SC("SetUint64"), &Statement::SetUint64)
.Func(_SC("SetFloat"), &Statement::SetFloat)
.Func(_SC("SetFloat32"), &Statement::SetFloat32)
.Func(_SC("SetFloat64"), &Statement::SetFloat64)
.FmtFunc(_SC("SetString"), &Statement::SetString)
.Func(_SC("SetZeroBlob"), &Statement::SetZeroBlob)
.Func(_SC("SetBlob"), &Statement::SetBlob)
.Func(_SC("SetData"), &Statement::SetData)
.Func(_SC("SetDate"), &Statement::SetDate)
.Func(_SC("SetDateEx"), &Statement::SetDateEx)
.Func(_SC("SetTime"), &Statement::SetTime)
.Func(_SC("SetTimeEx"), &Statement::SetTimeEx)
.Func(_SC("SetDatetime"), &Statement::SetDatetime)
.Func(_SC("SetDatetimeEx"), &Statement::SetDatetimeEx)
.Func(_SC("SetNow"), &Statement::SetNow)
.Func(_SC("SetNull"), &Statement::SetNull)
.Func(_SC("SetArray"), &Statement::SetArray)
.Func(_SC("SetTable"), &Statement::SetTable)
.Func(_SC("Field"), &Statement::GetColumn)
.Func(_SC("Column"), &Statement::GetColumn)
.Func(_SC("GetValue"), &Statement::GetValue)
.Func(_SC("GetNumber"), &Statement::GetNumber)
.Func(_SC("GetInteger"), &Statement::GetInteger)
.Func(_SC("GetFloat"), &Statement::GetFloat)
.Func(_SC("GetLong"), &Statement::GetLong)
.Func(_SC("GetString"), &Statement::GetString)
.Func(_SC("GetBoolean"), &Statement::GetBoolean)
.Func(_SC("GetChar"), &Statement::GetChar)
.Func(_SC("GetBuffer"), &Statement::GetBuffer)
.Func(_SC("GetBlob"), &Statement::GetBlob)
// Member overloads
.Overload< Array (Statement::*)(void) const >(_SC("GetArray"), &Statement::GetArray)
.Overload< Array (Statement::*)(Int32) const >(_SC("GetArray"), &Statement::GetArray)
.Overload< Array (Statement::*)(Int32, Int32) const >(_SC("GetArray"), &Statement::GetArray)
.Overload< Table (Statement::*)(void) const >(_SC("GetTable"), &Statement::GetTable)
.Overload< Table (Statement::*)(Int32) const >(_SC("GetTable"), &Statement::GetTable)
.Overload< Table (Statement::*)(Int32, Int32) const >(_SC("GetTable"), &Statement::GetTable)
);
}
} // Namespace:: SqMod

View File

@ -1,870 +0,0 @@
#ifndef _SQSQLITE_STATEMENT_HPP
#define _SQSQLITE_STATEMENT_HPP
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
#include "Parameter.hpp"
#include "Column.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Used to manage and interact a database statement.
*/
class Statement
{
private:
// --------------------------------------------------------------------------------------------
StmtRef m_Handle; // Reference to the managed statement.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and column index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateColumn(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateColumn(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and parameter index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateParam(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateParam(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and row, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateRow(CCStr file, Int32 line) const;
#else
void ValidateRow() const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Statement()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
*/
Statement(const ConnRef & connection, StackStrF & query)
: m_Handle(new StmtHnd(connection))
{
SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen);
}
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
*/
Statement(const Connection & connection, StackStrF & query);
/* --------------------------------------------------------------------------------------------
* Direct handle constructor.
*/
Statement(const StmtRef & s)
: m_Handle(s)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Statement(const Statement & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Statement(Statement && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Statement & operator = (const Statement & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Statement & operator = (Statement && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connections.
*/
bool operator == (const Statement & o) const
{
return (m_Handle.Get() == o.m_Handle.Get());
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two connections.
*/
bool operator != (const Statement & o) const
{
return (m_Handle.Get() != o.m_Handle.Get());
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the raw connection handle.
*/
operator sqlite3_stmt * ()
{
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the raw connection handle.
*/
operator sqlite3_stmt * () const
{
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const
{
return m_Handle ? m_Handle->mQuery : NullString();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated statement handle.
*/
const StmtRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed statement is valid.
*/
bool IsPrepared() const
{
return m_Handle && (m_Handle->mPtr != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this statement handle.
*/
Uint32 GetReferences() const
{
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated database connection.
*/
Object GetConnection() const;
/* --------------------------------------------------------------------------------------------
* Release the reference to the associated database statement.
*/
void Release()
{
m_Handle.Reset();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last received status code.
*/
Int32 GetStatus() const
{
return SQMOD_GET_VALID(*this)->mStatus;
}
/* --------------------------------------------------------------------------------------------
* Return the numeric result code for the most recent failed API call (if any).
*/
Int32 GetErrorCode() const
{
return SQMOD_GET_VALID(*this)->ErrNo();
}
/* --------------------------------------------------------------------------------------------
* Return the extended numeric result code for the most recent failed API call (if any).
*/
Int32 GetExtendedErrorCode() const
{
return SQMOD_GET_VALID(*this)->ExErrNo();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CSStr GetErrStr() const
{
return SQMOD_GET_VALID(*this)->ErrStr();
}
/* --------------------------------------------------------------------------------------------
* Return the last error message associated with this database connection.
*/
CSStr GetErrMsg() const
{
return SQMOD_GET_VALID(*this)->ErrMsg();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of requested columns.
*/
Int32 GetColumns() const
{
return SQMOD_GET_VALID(*this)->mColumns;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of specified parameters.
*/
Int32 GetParameters() const
{
return SQMOD_GET_VALID(*this)->mParameters;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the query string used to create this statement.
*/
const String & GetQuery() const
{
return SQMOD_GET_VALID(*this)->mQuery;
}
/* --------------------------------------------------------------------------------------------
* See if the last step retrieved a valid row.
*/
bool GetGood() const
{
return SQMOD_GET_CREATED(*this)->mGood;
}
/* --------------------------------------------------------------------------------------------
* See if there are any steps left.
*/
bool GetDone() const
{
return SQMOD_GET_CREATED(*this)->mDone;
}
/* --------------------------------------------------------------------------------------------
* Check whether a specific parameter index is within range.
*/
bool CheckParameter(Int32 idx) const
{
return SQMOD_GET_VALID(*this)->CheckParameter(idx);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the parameter index associated with the specified name.
*/
Int32 GetParameterIndex(StackStrF & name) const
{
return sqlite3_bind_parameter_index(SQMOD_GET_VALID(*this)->mPtr, name.mPtr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the parameter name associated with the specified index.
*/
CSStr GetParameterName(Int32 idx) const
{
// Validate the specified index
if (!idx)
{
STHROWF("Invalid parameter index (%d)", idx);
}
// Attempt to locate the name at the specified index
CSStr name = sqlite3_bind_parameter_name(SQMOD_GET_VALID(*this)->mPtr, idx);
// Validate the obtained string
if (!name)
{
STHROWF("No such parameter exists (%d)", idx);
}
// Return the obtained string
return name;
}
/* --------------------------------------------------------------------------------------------
* Check whether a specific column index is within range.
*/
bool CheckColumn(Int32 idx) const
{
return SQMOD_GET_VALID(*this)->CheckColumn(idx);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of columns available in the current row.
*/
Int32 GetDataCount() const
{
return sqlite3_data_count(SQMOD_GET_VALID(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Check whether the specified column is null.
*/
bool IsColumnNull(Int32 idx) const
{
return (sqlite3_column_type(SQMOD_GET_VALID(*this)->mPtr, idx) == SQLITE_NULL);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the column index associated with the specified name.
*/
Int32 GetColumnIndex(StackStrF & name) const
{
return SQMOD_GET_VALID(*this)->GetColumnIndex(name.mPtr, name.mLen);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the column name associated with the specified index.
*/
CSStr GetColumnName(Int32 idx) const
{
return sqlite3_column_name(SQMOD_GET_VALID(*this)->mPtr, idx);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the column origin name if the library was compiled with such feature.
*/
CSStr GetColumnOriginName(Int32 idx) const
{
#ifdef SQLITE_ENABLE_COLUMN_METADATA
return sqlite3_column_origin_name(SQMOD_GET_VALID(*this)->mPtr, idx);
#else
// The compiler moans when extra warnings are enabled
SQMOD_UNUSED_VAR(idx);
// Stop the execution here!
STHROWF("The module was compiled without this feature");
// We have to return something
return _SC("");
#endif
}
/* --------------------------------------------------------------------------------------------
* Retrieve the type identifier of the column associated with the specified index.
*/
Int32 GetColumnType(Int32 idx) const
{
return sqlite3_column_type(SQMOD_GET_VALID(*this)->mPtr, idx);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the size in bytes of the column associated with the specified index.
*/
Int32 GetColumnBytes(Int32 idx) const
{
return sqlite3_column_bytes(SQMOD_GET_VALID(*this)->mPtr, idx);
}
/* --------------------------------------------------------------------------------------------
* Reset the statement back to its initial position to be stepped again.
*/
Statement & Reset();
/* --------------------------------------------------------------------------------------------
* Clear any values binded to this statement.
*/
Statement & Clear();
/* --------------------------------------------------------------------------------------------
* Execute this statement and don't expect any rows to be returned.
*/
Int32 Exec();
/* --------------------------------------------------------------------------------------------
* Step the statement and expect a row to be returned.
*/
bool Step();
/* --------------------------------------------------------------------------------------------
* Retrieve the parameter with the specified name or index.
*/
Object GetParameter(const Object & param) const
{
return Object(new Parameter(m_Handle, param));
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a dynamic value at the specified parameter index.
*/
Statement & SetValue(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetValue(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a boolean value at the specified parameter index.
*/
Statement & SetBool(const Object & param, bool value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetBool(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a character value at the specified parameter index.
*/
Statement & SetChar(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetChar(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a native integer value at the specified parameter index.
*/
Statement & SetInteger(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetInteger(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 8 bit integer value at the specified parameter index.
*/
Statement & SetInt8(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetInt8(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 8 bit integer value at the specified parameter index.
*/
Statement & SetUint8(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetUint8(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 16 bit integer value at the specified parameter index.
*/
Statement & SetInt16(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetInt16(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 16 bit integer value at the specified parameter index.
*/
Statement & SetUint16(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetUint16(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 32 bit integer value at the specified parameter index.
*/
Statement & SetInt32(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetInt32(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 32 bit integer value at the specified parameter index.
*/
Statement & SetUint32(const Object & param, SQInteger value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetUint32(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a signed 64 bit integer value at the specified parameter index.
*/
Statement & SetInt64(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetInt64(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind an unsigned 64 bit integer value at the specified parameter index.
*/
Statement & SetUint64(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetUint64(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a native floating point value at the specified parameter index.
*/
Statement & SetFloat(const Object & param, SQFloat value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetFloat(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a 32 bit floating point value at the specified parameter index.
*/
Statement & SetFloat32(const Object & param, SQFloat value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetFloat32(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a 64 bit floating point value at the specified parameter index.
*/
Statement & SetFloat64(const Object & param, SQFloat value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetFloat64(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a string value at the specified parameter index.
*/
Statement & SetString(const Object & param, StackStrF & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetString(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a zeroed blob value at the specified parameter index.
*/
Statement & SetZeroBlob(const Object & param, SQInteger size)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetZeroBlob(size);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a blob value at the specified parameter index.
*/
Statement & SetBlob(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetBlob(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a buffer value at the specified parameter index.
*/
Statement & SetData(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetData(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date value at the specified parameter index.
*/
Statement & SetDate(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetDate(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date value at the specified parameter index.
*/
Statement & SetDateEx(const Object & param, SQInteger year, SQInteger month, SQInteger day)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetDateEx(year, month, day);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a time value at the specified parameter index.
*/
Statement & SetTime(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetTime(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a time value at the specified parameter index.
*/
Statement & SetTimeEx(const Object & param, SQInteger hour, SQInteger minute, SQInteger second)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetTimeEx(hour, minute, second);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date-time value at the specified parameter index.
*/
Statement & SetDatetime(const Object & param, const Object & value)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetDatetime(value);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a date-time value at the specified parameter index.
*/
Statement & SetDatetimeEx(const Object & param, SQInteger year, SQInteger month, SQInteger day,
SQInteger hour, SQInteger minute, SQInteger second)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetDatetimeEx(year, month, day, hour, minute, second);
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind the current timestamp at the specified parameter index.
*/
Statement & SetNow(const Object & param)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetNow();
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind a null value at the specified parameter index.
*/
Statement & SetNull(const Object & param)
{
Parameter(SQMOD_GET_CREATED(*this), param).SetNull();
// Allow chaining of operations
return *this;
}
/* --------------------------------------------------------------------------------------------
* Attempt to bind the values from an array starting at the specified index.
*/
Statement & SetArray(Int32 idx, const Array & arr);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the values from an associative container.
*/
Statement & SetTable(const Table & tbl);
/* --------------------------------------------------------------------------------------------
* Retrieve the column with the specified name or index.
*/
Object GetColumn(const Object & column) const
{
return Object(new Column(m_Handle, column));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a dynamic type.
*/
Object GetValue(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetValue();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a numeric type.
*/
Object GetNumber(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetNumber();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a native script integer.
*/
SQInteger GetInteger(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetInteger();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a native script floating point.
*/
SQFloat GetFloat(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetFloat();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a long integer.
*/
Object GetLong(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetLong();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a string.
*/
Object GetString(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetString();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a boolean.
*/
bool GetBoolean(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetBoolean();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a character.
*/
SQChar GetChar(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetChar();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a memory buffer.
*/
Object GetBuffer(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetBuffer();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the referenced column as a memory blob.
*/
Object GetBlob(const Object & column) const
{
return Column(SQMOD_GET_CREATED(*this), column).GetBlob();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an array container.
*/
Array GetArray() const
{
return GetArray(0, SQMOD_GET_CREATED(*this)->mColumns);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an array container.
*/
Array GetArray(Int32 min) const
{
return GetArray(min, SQMOD_GET_CREATED(*this)->mColumns);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an array container.
*/
Array GetArray(Int32 min, Int32 max) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an associative container.
*/
Table GetTable() const
{
// Is there something to return?
if (SQMOD_GET_CREATED(*this)->mColumns > 0)
{
return GetTable(0, m_Handle->mColumns - 1);
}
// Fallback to empty table
return NullTable();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an associative container.
*/
Table GetTable(Int32 min) const
{
// Is there something to return?
if (SQMOD_GET_CREATED(*this)->mColumns > 0)
{
return GetTable(min, m_Handle->mColumns - 1);
}
// Fallback to empty table
return NullTable();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the row as an associative container.
*/
Table GetTable(Int32 min, Int32 max) const;
};
} // Namespace:: SqMod
#endif // _SQSQLITE_STATEMENT_HPP

View File

@ -1,100 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Transaction.hpp"
#include "Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqLiteTransaction"))
// ------------------------------------------------------------------------------------------------
Transaction::Transaction(const Connection & db)
: Transaction(db.GetHandle())
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Transaction::Transaction(const ConnRef & db)
: m_Handle(db), m_Committed(false)
{
// Was the specified database connection valid?
if (!m_Handle)
{
STHROWF("Invalid connection handle");
}
// Attempt to begin transaction
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "BEGIN", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to begin transaction [%s]", m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
Transaction::~Transaction()
{
// Was this transaction successfully committed?
if (m_Committed)
{
return; // We're done here!
}
// Attempt to roll back changes because this failed to commit
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "ROLLBACK", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
// We cannot throw exceptions in destructor
SqMod_LogErr("Unable to rollback transaction [%s]", m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
bool Transaction::Commit()
{
// We shouldn't even be here if there wasn't a valid connection but let's be sure
if (!m_Handle)
{
STHROWF("Invalid database connection");
}
// Was this transaction already committed?
else if (m_Committed)
{
STHROWF("Transaction was already committed");
}
// Attempt to commit the change during this transaction
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "COMMIT", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to commit transaction [%s]", m_Handle->ErrMsg());
}
else
{
m_Committed = true; // Everything was committed successfully
}
// Return the result
return m_Committed;
}
// ================================================================================================
void Register_Transaction(Table & sqlns)
{
sqlns.Bind(_SC("Transaction"),
Class< Transaction, NoCopy< Transaction > >(sqlns.GetVM(), Typename::Str)
// Constructors
.Ctor< const Connection & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Transaction::ToString)
// Properties
.Prop(_SC("IsValid"), &Transaction::IsValid)
.Prop(_SC("Committed"), &Transaction::Commited)
// Member Methods
.Func(_SC("Commit"), &Transaction::Commit)
);
}
} // Namespace:: SqMod

View File

@ -1,98 +0,0 @@
#ifndef _SQSQLITE_TRANSACTION_HPP_
#define _SQSQLITE_TRANSACTION_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Implements the RAII pattern for database transactions.
*/
class Transaction
{
public:
/* --------------------------------------------------------------------------------------------
* Construct by taking the handle from a connection.
*/
Transaction(const Connection & db);
/* --------------------------------------------------------------------------------------------
* Construct using the direct connection handle.
*/
Transaction(const ConnRef & db);
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Transaction(const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Transaction(Transaction && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Transaction();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Transaction & operator = (const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Transaction & operator = (Transaction && o) = delete;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const
{
return m_Handle ? m_Handle->mName : NullString();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated statement handle.
*/
const ConnRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Attempt to commit changes to the database.
*/
bool Commit();
/* --------------------------------------------------------------------------------------------
* See whether the change during this transaction were successfully committed.
*/
bool Commited() const
{
return m_Committed;
}
private:
// --------------------------------------------------------------------------------------------
ConnRef m_Handle; // The database connection handle where the transaction began.
bool m_Committed; // Whether changes were successfully committed to the database.
};
} // Namespace:: SqMod
#endif // _SQSQLITE_TRANSACTION_HPP_

View File

@ -1,149 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Attribute.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Attribute::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqXmlAttribute");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Object Attribute::AsLong(Object & def) const
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), def);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), m_Attr.as_llong(longint));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Attribute::AsUlong(Object & def) const
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), def);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), m_Attr.as_ullong(longint));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
bool Attribute::ApplyLong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value and return the result
return m_Attr.set_value(longint);
}
// ------------------------------------------------------------------------------------------------
bool Attribute::ApplyUlong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value and return the result
return m_Attr.set_value(longint);
}
// ------------------------------------------------------------------------------------------------
Object Attribute::GetLong() const
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), m_Attr.as_llong());
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetLong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value
m_Attr = longint;
}
// ------------------------------------------------------------------------------------------------
Object Attribute::GetUlong() const
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), m_Attr.as_ullong());
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetUlong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value
m_Attr = longint;
}
} // Namespace:: SqMod

View File

@ -1,445 +0,0 @@
#ifndef _SQXML_ATTRIBUTE_HPP_
#define _SQXML_ATTRIBUTE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Document.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A light-weight handle for manipulating attributes in DOM tree.
*/
class Attribute
{
// --------------------------------------------------------------------------------------------
friend class Node;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_attribute Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Attribute(const DocumentRef doc, const Type & attr)
: m_Doc(doc), m_Attr(attr)
{
/* ... */
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main xml document instance.
Type m_Attr; // The managed node attribute.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Attribute()
: m_Doc(), m_Attr()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Attribute(const Attribute & o)
: m_Doc(o.m_Doc), m_Attr(o.m_Attr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Attribute()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Attribute & operator = (const Attribute & o)
{
m_Doc = o.m_Doc;
m_Attr = o.m_Attr;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Attribute & o)
{
if (m_Attr == o.m_Attr)
{
return 0;
}
else if (m_Attr > o.m_Attr)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Attr.value();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether the attribute is empty.
*/
bool IsEmpty() const
{
return m_Attr.empty();
}
/* --------------------------------------------------------------------------------------------
* Get hash value (unique for handles to the same object).
*/
SQInteger GetHashValue() const
{
return (SQInteger)m_Attr.hash_value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute name.
*/
CSStr GetName() const
{
return m_Attr.name();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute name.
*/
void SetName(CSStr name)
{
if (!m_Attr.set_name(name))
{
STHROWF("Unable to set XML attribute name");
}
}
/* --------------------------------------------------------------------------------------------
* Modify the attribute name.
*/
bool ApplyName(CSStr name)
{
return m_Attr.set_name(name);
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute value.
*/
CSStr GetValue() const
{
return m_Attr.value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute value.
*/
void SetValue(CSStr name)
{
if (!m_Attr.set_value(name))
{
STHROWF("Unable to set XML attribute value");
}
}
/* --------------------------------------------------------------------------------------------
* Modify the attribute value.
*/
bool ApplyValue(CSStr value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string or the specified default value if empty.
*/
CSStr AsString(CSStr def) const
{
return m_Attr.as_string(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer or the specified default value if empty.
*/
Int32 AsInt(Int32 def) const
{
return m_Attr.as_int(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer or the specified default value if empty.
*/
Uint32 AsUint(Uint32 def) const
{
return m_Attr.as_uint(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point or the specified default value if empty.
*/
SQFloat AsFloat(SQFloat def) const
{
return (SQFloat)m_Attr.as_float(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point or the specified default value if empty.
*/
SQFloat AsDouble(SQFloat def) const
{
return (SQFloat)m_Attr.as_double(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer or the specified default value if empty.
*/
Object AsLong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer or the specified default value if empty.
*/
Object AsUlong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean or the specified default value if empty.
*/
bool AsBool(bool def) const
{
return m_Attr.as_bool(def);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
bool ApplyString(CSStr value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
bool ApplyInt(Int32 value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
bool ApplyUint(Uint32 value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
bool ApplyFloat(SQFloat value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
bool ApplyDouble(SQFloat value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
bool ApplyLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
bool ApplyUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
bool ApplyBool(bool value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string.
*/
CSStr GetString() const
{
return m_Attr.as_string();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
void SetString(CSStr value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer.
*/
Int32 GetInt() const
{
return m_Attr.as_int();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
void SetInt(Int32 value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer.
*/
Uint32 GetUint() const
{
return m_Attr.as_uint();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
void SetUint(Uint32 value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point.
*/
SQFloat GetFloat() const
{
return static_cast< SQFloat >(m_Attr.as_float());
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
void SetFloat(SQFloat value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point.
*/
SQFloat GetDouble() const
{
return static_cast< SQFloat >(m_Attr.as_double());
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
void SetDouble(SQFloat value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer.
*/
Object GetLong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
void SetLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer.
*/
Object GetUlong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
void SetUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean.
*/
bool GetBool() const
{
return m_Attr.as_bool();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
void SetBool(bool value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve next attribute in the attribute list of the parent node.
*/
Attribute NextAttribute() const
{
return Attribute(m_Doc, m_Attr.next_attribute());
}
/* --------------------------------------------------------------------------------------------
* Retrieve previous attribute in the attribute list of the parent node.
*/
Attribute PrevAttribute() const
{
return Attribute(m_Doc, m_Attr.previous_attribute());
}
};
} // Namespace:: SqMod
#endif // _SQXML_ATTRIBUTE_HPP_

View File

@ -1,9 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod

View File

@ -1,43 +0,0 @@
#ifndef _SQXML_COMMON_HPP_
#define _SQXML_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <pugixml.hpp>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQXML_NAME "Squirrel XML Module"
#define SQXML_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQXML_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin"
#define SQXML_HOST_NAME "SqModXMLHost"
#define SQXML_VERSION 001
#define SQXML_VERSION_STR "0.0.1"
#define SQXML_VERSION_MAJOR 0
#define SQXML_VERSION_MINOR 0
#define SQXML_VERSION_PATCH 1
// ------------------------------------------------------------------------------------------------
using namespace pugi;
// ------------------------------------------------------------------------------------------------
class Node;
class Text;
class Document;
class Attribute;
class XPathNode;
class XPathNodeSet;
class XPathVariable;
class XPathVariableSet;
class XPathVariableQuery;
class ParseResult;
} // Namespace:: SqMod
#endif // _SQXML_COMMON_HPP_

View File

@ -1,38 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Document.hpp"
#include "Node.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Document::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqXmlDocument");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
void Document::CanLoad() const
{
// Is the document even valid?
m_Doc.Validate();
// Are there any other references?
if (m_Doc.Count() > 1)
{
// To load new values now, would mean to cause undefined behavior in existing references
STHROWF("Loading is disabled while document is referenced");
}
}
// ------------------------------------------------------------------------------------------------
Node Document::GetNode() const
{
// Validate the document handle
m_Doc.Validate();
// Return the requested information
return Node(m_Doc, m_Doc->document_element());
}
} // Namespace:: SqMod

View File

@ -1,257 +0,0 @@
#ifndef _SQXML_DOCUMENT_HPP_
#define _SQXML_DOCUMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Document.hpp"
#include "Wrapper/ParseResult.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can read/write and alter the contents of XML files.
*/
class Document
{
protected:
// --------------------------------------------------------------------------------------------
typedef xml_document Type;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Document(const Document & o);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Document & operator = (const Document & o);
/* --------------------------------------------------------------------------------------------
* See if the document is allowed to overwrite its contents and throw an error if not.
*/
void CanLoad() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main xml document instance.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Document()
: m_Doc(nullptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Document()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Document & o) const
{
if (m_Doc && !o.m_Doc)
{
return 1;
}
else if (!m_Doc && o.m_Doc)
{
return -1;
}
else if (!m_Doc && !o.m_Doc)
{
return 0;
}
else if (*m_Doc == *o.m_Doc)
{
return 0;
}
else if (*m_Doc > *o.m_Doc)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
// Do we manage a valid document?
if (m_Doc)
{
return m_Doc->name();
}
// Default to an empty name
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* Removes all nodes, leaving the empty document.
*/
void Reset()
{
// Validate the document handle
m_Doc.Validate();
// Perform the requested operation
m_Doc->reset();
}
/* --------------------------------------------------------------------------------------------
* Removes all nodes, then copies the entire contents of the specified document.
*/
void Reset(const Document & doc)
{
// Validate the document handles
m_Doc.Validate();
doc.m_Doc.Validate();
// Perform the requested operation
m_Doc->reset(*(doc.m_Doc));
}
/* --------------------------------------------------------------------------------------------
* Load document from zero-terminated string. (LoadString collides with the windows api)
*/
ParseResult LoadData(CSStr source)
{
// Make sure that we are allowed to load in data
CanLoad();
// Perform the requested operation and return the result
return ParseResult(m_Doc, m_Doc->load_string(source));
}
/* --------------------------------------------------------------------------------------------
* Load document from zero-terminated string. (LoadString collides with the windows api)
*/
ParseResult LoadData(CSStr source, Uint32 options)
{
// Make sure that we are allowed to load in data
CanLoad();
// Perform the requested operation and return the result
return ParseResult(m_Doc, m_Doc->load_string(source, options));
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath)
{
// Make sure that we are allowed to load in data
CanLoad();
// Perform the requested operation and return the result
return ParseResult(m_Doc, m_Doc->load_file(filepath));
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath, Uint32 options)
{
// Make sure that we are allowed to load in data
CanLoad();
// Perform the requested operation and return the result
return ParseResult(m_Doc, m_Doc->load_file(filepath, options));
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath, Uint32 options, Int32 encoding)
{
// Make sure that we are allowed to load in data
CanLoad();
// Perform the requested operation and return the result
return ParseResult(m_Doc, m_Doc->load_file(filepath, options,
static_cast< xml_encoding >(encoding)));
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath)
{
// Validate the document handle
m_Doc.Validate();
// Perform the requested operation
m_Doc->save_file(filepath);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent)
{
// Validate the document handle
m_Doc.Validate();
// Perform the requested operation
m_Doc->save_file(filepath, indent);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent, Uint32 format)
{
// Validate the document handle
m_Doc.Validate();
// Perform the requested operation
m_Doc->save_file(filepath, indent, format);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent, Uint32 format, Int32 encoding)
{
// Validate the document handle
m_Doc.Validate();
// Perform the requested operation
m_Doc->save_file(filepath, indent, format, static_cast< xml_encoding >(encoding));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the document root node.
*/
Node GetNode() const;
};
} // Namespace:: SqMod
#endif // _SQXML_DOCUMENT_HPP_

View File

@ -1,16 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Document.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void DocumentRef::Validate() const
{
if (!m_Ptr)
{
STHROWF("Invalid XML document reference");
}
}
} // Namespace:: SqMod

View File

@ -1,236 +0,0 @@
#ifndef _SQXML_HANDLE_DOCUMENT_HPP_
#define _SQXML_HANDLE_DOCUMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted xml document instance.
*/
class DocumentRef
{
// --------------------------------------------------------------------------------------------
friend class Document;
public:
// --------------------------------------------------------------------------------------------
typedef xml_document 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. */
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and throw exception if invalid.
*/
void Validate() const;
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; /* The document reader, writer and manager instance. */
Counter* m_Ref; /* Reference count to the managed instance. */
/* --------------------------------------------------------------------------------------------
* Grab a strong reference to a document instance.
*/
void Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a document instance.
*/
void Drop()
{
if (m_Ptr && --(*m_Ref) == 0)
{
delete m_Ptr;
delete m_Ref;
m_Ptr = NULL;
m_Ref = NULL;
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
DocumentRef(VoidP /* unused */)
: m_Ptr(new Type())
, m_Ref(new Counter(1))
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
DocumentRef()
: m_Ptr(NULL), m_Ref(NULL)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
DocumentRef(const DocumentRef & o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
Grab();
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DocumentRef(DocumentRef && o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DocumentRef()
{
Drop();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
DocumentRef & operator = (const DocumentRef & o)
{
if (m_Ptr != o.m_Ptr)
{
Drop();
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
Grab();
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DocumentRef & operator = (DocumentRef && o)
{
if (m_Ptr != o.m_Ptr)
{
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two document instances.
*/
bool operator == (const DocumentRef & o) const
{
return (m_Ptr == o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two document instances.
*/
bool operator != (const DocumentRef & o) const
{
return (m_Ptr != o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator Reference ()
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator ConstRef () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Pointer operator -> () const
{
assert(m_Ptr);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
}
};
} // Namespace:: SqMod
#endif // _SQXML_HANDLE_DOCUMENT_HPP_

View File

@ -1,500 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Attribute.hpp"
#include "Text.hpp"
#include "Node.hpp"
#include "Document.hpp"
#include "Wrapper/ParseResult.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
static bool RegisterAPI(HSQUIRRELVM vm)
{
// Make sure there's a valid virtual machine before proceeding
if (!vm)
{
OutputError("%s: Cannot register API without a valid virtual machine", SQXML_NAME);
// Registration failed
return false;
}
Table xmlns(vm);
xmlns.Bind(_SC("ParseResult"), Class< ParseResult >(vm, _SC("SqXmlParseResult"))
// Constructors
.Ctor()
.Ctor< const ParseResult & >()
// Core Meta-methods
.Func(_SC("_cmp"), &ParseResult::Cmp)
.SquirrelFunc(_SC("_typename"), &ParseResult::Typename)
.Func(_SC("_tostring"), &ParseResult::ToString)
// Properties
.Prop(_SC("Valid"), &ParseResult::IsValid)
.Prop(_SC("References"), &ParseResult::GetRefCount)
.Prop(_SC("Ok"), &ParseResult::IsOk)
.Prop(_SC("Status"), &ParseResult::GetStatus)
.Prop(_SC("Offset"), &ParseResult::GetOffset)
.Prop(_SC("Encoding"), &ParseResult::GetEncoding)
.Prop(_SC("Description"), &ParseResult::GetDescription)
// Member Methods
.Func(_SC("Check"), &ParseResult::Check)
);
xmlns.Bind(_SC("Attribute"), Class< Attribute >(vm, _SC("SqXmlAttribute"))
// Constructors
.Ctor()
.Ctor< const Attribute & >()
// Core Meta-methods
.Func(_SC("_cmp"), &Attribute::Cmp)
.SquirrelFunc(_SC("_typename"), &Attribute::Typename)
.Func(_SC("_tostring"), &Attribute::ToString)
// Properties
.Prop(_SC("Valid"), &Attribute::IsValid)
.Prop(_SC("References"), &Attribute::GetRefCount)
.Prop(_SC("Empty"), &Attribute::IsEmpty)
.Prop(_SC("Hash"), &Attribute::GetHashValue)
.Prop(_SC("Name"), &Attribute::GetName, &Attribute::SetName)
.Prop(_SC("Value"), &Attribute::GetValue, &Attribute::SetValue)
.Prop(_SC("Int"), &Attribute::GetInt, &Attribute::SetInt)
.Prop(_SC("Uint"), &Attribute::GetUint, &Attribute::SetUint)
.Prop(_SC("Float"), &Attribute::GetFloat, &Attribute::SetFloat)
.Prop(_SC("Double"), &Attribute::GetDouble, &Attribute::SetDouble)
.Prop(_SC("Long"), &Attribute::GetLong, &Attribute::SetLong)
.Prop(_SC("Ulong"), &Attribute::GetUlong, &Attribute::SetUlong)
.Prop(_SC("Bool"), &Attribute::GetBool, &Attribute::SetBool)
.Prop(_SC("Next"), &Attribute::NextAttribute)
.Prop(_SC("Prev"), &Attribute::PrevAttribute)
// Member Methods
.Func(_SC("SetName"), &Attribute::ApplyName)
.Func(_SC("SetValue"), &Attribute::ApplyValue)
.Func(_SC("AsString"), &Attribute::AsString)
.Func(_SC("AsInt"), &Attribute::AsInt)
.Func(_SC("AsUint"), &Attribute::AsUint)
.Func(_SC("AsFloat"), &Attribute::AsFloat)
.Func(_SC("AsDouble"), &Attribute::AsDouble)
.Func(_SC("AsLong"), &Attribute::AsLong)
.Func(_SC("AsUlong"), &Attribute::AsUlong)
.Func(_SC("AsBool"), &Attribute::AsBool)
.Func(_SC("SetString"), &Attribute::ApplyString)
.Func(_SC("SetInt"), &Attribute::ApplyInt)
.Func(_SC("SetUint"), &Attribute::ApplyUint)
.Func(_SC("SetFloat"), &Attribute::ApplyFloat)
.Func(_SC("SetDouble"), &Attribute::ApplyDouble)
.Func(_SC("SetLong"), &Attribute::ApplyLong)
.Func(_SC("SetUlong"), &Attribute::ApplyUlong)
.Func(_SC("SetBool"), &Attribute::ApplyBool)
);
xmlns.Bind(_SC("Text"), Class< Text >(vm, _SC("SqXmlText"))
// Constructors
.Ctor()
.Ctor< const Text & >()
// Core Meta-methods
.Func(_SC("_cmp"), &Text::Cmp)
.SquirrelFunc(_SC("_typename"), &Text::Typename)
.Func(_SC("_tostring"), &Text::ToString)
// Properties
.Prop(_SC("Valid"), &Text::IsValid)
.Prop(_SC("References"), &Text::GetRefCount)
.Prop(_SC("Empty"), &Text::IsEmpty)
.Prop(_SC("Value"), &Text::GetValue)
.Prop(_SC("Int"), &Text::GetInt, &Text::SetInt)
.Prop(_SC("Uint"), &Text::GetUint, &Text::SetUint)
.Prop(_SC("Float"), &Text::GetFloat, &Text::SetFloat)
.Prop(_SC("Double"), &Text::GetDouble, &Text::SetDouble)
.Prop(_SC("Long"), &Text::GetLong, &Text::SetLong)
.Prop(_SC("Ulong"), &Text::GetUlong, &Text::SetUlong)
.Prop(_SC("Bool"), &Text::GetBool, &Text::SetBool)
.Prop(_SC("Data"), &Text::GetData)
// Member Methods
.Func(_SC("AsString"), &Text::AsString)
.Func(_SC("AsInt"), &Text::AsInt)
.Func(_SC("AsUint"), &Text::AsUint)
.Func(_SC("AsFloat"), &Text::AsFloat)
.Func(_SC("AsDouble"), &Text::AsDouble)
.Func(_SC("AsLong"), &Text::AsLong)
.Func(_SC("AsUlong"), &Text::AsUlong)
.Func(_SC("AsBool"), &Text::AsBool)
.Func(_SC("SetString"), &Text::ApplyString)
.Func(_SC("SetInt"), &Text::ApplyInt)
.Func(_SC("SetUint"), &Text::ApplyUint)
.Func(_SC("SetFloat"), &Text::ApplyFloat)
.Func(_SC("SetDouble"), &Text::ApplyDouble)
.Func(_SC("SetLong"), &Text::ApplyLong)
.Func(_SC("SetUlong"), &Text::ApplyUlong)
.Func(_SC("SetBool"), &Text::ApplyBool)
);
xmlns.Bind(_SC("Node"), Class< Node >(vm, _SC("SqXmlNode"))
// Constructors
.Ctor()
.Ctor< const Node & >()
// Core Meta-methods
.Func(_SC("_cmp"), &Node::Cmp)
.SquirrelFunc(_SC("_typename"), &Node::Typename)
.Func(_SC("_tostring"), &Node::ToString)
// Properties
.Prop(_SC("Valid"), &Node::IsValid)
.Prop(_SC("References"), &Node::GetRefCount)
.Prop(_SC("Empty"), &Node::IsEmpty)
.Prop(_SC("Hash"), &Node::GetHashValue)
.Prop(_SC("OffsetDebug"), &Node::GetOffsetDebug)
.Prop(_SC("Type"), &Node::GetType)
.Prop(_SC("Name"), &Node::GetName, &Node::SetName)
.Prop(_SC("Value"), &Node::GetValue, &Node::SetValue)
.Prop(_SC("FirstAttr"), &Node::GetFirstAttr)
.Prop(_SC("LastAttr"), &Node::GetLastAttr)
.Prop(_SC("FirstChild"), &Node::GetFirstChild)
.Prop(_SC("LastChild"), &Node::GetLastChild)
.Prop(_SC("NextSibling"), &Node::GetNextSibling)
.Prop(_SC("PrevSibling"), &Node::GetPrevSibling)
.Prop(_SC("Parent"), &Node::GetParent)
.Prop(_SC("Root"), &Node::GetRoot)
.Prop(_SC("Text"), &Node::GetText)
.Prop(_SC("ChildValue"), &Node::GetChildValue)
// Member Methods
.Overload< ParseResult (Node::*)(CSStr) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Overload< ParseResult (Node::*)(CSStr, Uint32) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Overload< ParseResult (Node::*)(CSStr, Uint32, Int32) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Func(_SC("SetName"), &Node::ApplyName)
.Func(_SC("SetValue"), &Node::ApplyValue)
.Func(_SC("GetChild"), &Node::Child)
.Func(_SC("GetAttr"), &Node::GetAttribute)
.Func(_SC("GetAttribute"), &Node::GetAttribute)
.Func(_SC("GetAttrFrom"), &Node::AttributeFrom)
.Func(_SC("GetAttributeFrom"), &Node::AttributeFrom)
.Func(_SC("GetNextSibling"), &Node::NextSibling)
.Func(_SC("GetPrevSibling"), &Node::PrevSibling)
.Func(_SC("GetChildValue"), &Node::ChildValue)
.Func(_SC("AppendAttr"), &Node::AppendAttr)
.Func(_SC("PrependAttr"), &Node::PrependAttr)
.Func(_SC("InsertAttrAfter"), &Node::InsertAttrAfter)
.Func(_SC("InsertAttrBefore"), &Node::InsertAttrBefore)
.Func(_SC("AppendAttrCopy"), &Node::AppendAttrCopy)
.Func(_SC("PrependAttrCopy"), &Node::PrependAttrCopy)
.Func(_SC("InsertAttrCopyAfter"), &Node::InsertAttrCopyAfter)
.Func(_SC("InsertAttrCopyBefore"), &Node::InsertAttrCopyBefore)
.Func(_SC("AppendChild"), &Node::AppendChild)
.Func(_SC("PrependChild"), &Node::PrependChild)
.Func(_SC("AppendChildNode"), &Node::AppendChildNode)
.Func(_SC("PrependChildNode"), &Node::PrependChildNode)
.Func(_SC("AppendChildType"), &Node::AppendChildType)
.Func(_SC("PrependChildType"), &Node::PrependChildType)
.Func(_SC("InsertChildAfter"), &Node::InsertChildAfter)
.Func(_SC("InsertChildBefore"), &Node::InsertChildBefore)
.Func(_SC("InsertChildTypeAfter"), &Node::InsertChildTypeAfter)
.Func(_SC("InsertChildTypeBefore"), &Node::InsertChildTypeBefore)
.Func(_SC("AppendCopy"), &Node::AppendCopy)
.Func(_SC("PrependCopy"), &Node::PrependCopy)
.Func(_SC("InsertCopyAfter"), &Node::InsertCopyAfter)
.Func(_SC("InsertCopyBefore"), &Node::InsertCopyBefore)
.Func(_SC("AppendMove"), &Node::AppendMove)
.Func(_SC("PrependMove"), &Node::PrependMove)
.Func(_SC("InsertMoveAfter"), &Node::InsertMoveAfter)
.Func(_SC("InsertMoveBefore"), &Node::InsertMoveBefore)
.Func(_SC("RemoveAttr"), &Node::RemoveAttr)
.Func(_SC("RemoveAttrInst"), &Node::RemoveAttrInst)
.Func(_SC("RemoveChild"), &Node::RemoveChild)
.Func(_SC("RemoveChildInst"), &Node::RemoveChildInst)
.Overload< Node (Node::*)(CSStr, CSStr) const >(_SC("FindChildByAttr"), &Node::FindChildByAttr)
.Overload< Node (Node::*)(CSStr, CSStr, CSStr) const >(_SC("FindChildByAttr"), &Node::FindChildByAttr)
.Func(_SC("FindElemByPath"), &Node::FindElemByPath)
);
xmlns.Bind(_SC("Document"), Class< Document, NoCopy< Document > >(vm, _SC("SqXmlDocument"))
// Constructors
.Ctor()
// Core Meta-methods
.Func(_SC("_cmp"), &Document::Cmp)
.SquirrelFunc(_SC("_typename"), &Document::Typename)
.Func(_SC("_tostring"), &Document::ToString)
// Properties
.Prop(_SC("Valid"), &Document::IsValid)
.Prop(_SC("References"), &Document::GetRefCount)
.Prop(_SC("Node"), &Document::GetNode)
// Member Methods
.Overload< void (Document::*)(void) >(_SC("Reset"), &Document::Reset)
.Overload< void (Document::*)(const Document &) >(_SC("Reset"), &Document::Reset)
.Overload< ParseResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
.Overload< ParseResult (Document::*)(CSStr, Uint32) >(_SC("LoadString"), &Document::LoadData)
.Overload< ParseResult (Document::*)(CSStr) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< ParseResult (Document::*)(CSStr, Uint32) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< ParseResult (Document::*)(CSStr, Uint32, Int32) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< void (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr, Uint32) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr, Uint32, Int32) >(_SC("SaveFile"), &Document::SaveFile)
);
RootTable(vm).Bind(_SC("SqXml"), xmlns);
ConstTable(vm).Enum(_SC("SqXmlNodeType"), Enumeration(vm)
.Const(_SC("Null"), static_cast< Int32 >(node_null))
.Const(_SC("Document"), static_cast< Int32 >(node_document))
.Const(_SC("Element"), static_cast< Int32 >(node_element))
.Const(_SC("PCData"), static_cast< Int32 >(node_pcdata))
.Const(_SC("CData"), static_cast< Int32 >(node_cdata))
.Const(_SC("Comment"), static_cast< Int32 >(node_comment))
.Const(_SC("Pi"), static_cast< Int32 >(node_pi))
.Const(_SC("Declaration"), static_cast< Int32 >(node_declaration))
.Const(_SC("Doctype"), static_cast< Int32 >(node_doctype))
);
ConstTable(vm).Enum(_SC("SqXmlParse"), Enumeration(vm)
.Const(_SC("Minimal"), static_cast< Int32 >(parse_minimal))
.Const(_SC("Default"), static_cast< Int32 >(parse_default))
.Const(_SC("Full"), static_cast< Int32 >(parse_full))
.Const(_SC("Pi"), static_cast< Int32 >(parse_pi))
.Const(_SC("Comments"), static_cast< Int32 >(parse_comments))
.Const(_SC("CData"), static_cast< Int32 >(parse_cdata))
.Const(_SC("WSPCData"), static_cast< Int32 >(parse_ws_pcdata))
.Const(_SC("Escapes"), static_cast< Int32 >(parse_escapes))
.Const(_SC("EOL"), static_cast< Int32 >(parse_eol))
.Const(_SC("WConvAttribute"), static_cast< Int32 >(parse_wconv_attribute))
.Const(_SC("WNormAttribute"), static_cast< Int32 >(parse_wnorm_attribute))
.Const(_SC("Declaration"), static_cast< Int32 >(parse_declaration))
.Const(_SC("Doctype"), static_cast< Int32 >(parse_doctype))
.Const(_SC("WSPCDataSingle"), static_cast< Int32 >(parse_ws_pcdata_single))
.Const(_SC("TrimPCData"), static_cast< Int32 >(parse_trim_pcdata))
.Const(_SC("Fragment"), static_cast< Int32 >(parse_fragment))
.Const(_SC("EmbedPCData"), static_cast< Int32 >(parse_embed_pcdata))
);
ConstTable(vm).Enum(_SC("SqXmlEncoding"), Enumeration(vm)
.Const(_SC("Auto"), static_cast< Int32 >(encoding_auto))
.Const(_SC("Utf8"), static_cast< Int32 >(encoding_utf8))
.Const(_SC("Utf16LE"), static_cast< Int32 >(encoding_utf16_le))
.Const(_SC("Utf16BE"), static_cast< Int32 >(encoding_utf16_be))
.Const(_SC("Utf16"), static_cast< Int32 >(encoding_utf16))
.Const(_SC("Utf32LE"), static_cast< Int32 >(encoding_utf32_le))
.Const(_SC("Utf32BE"), static_cast< Int32 >(encoding_utf32_be))
.Const(_SC("Utf32"), static_cast< Int32 >(encoding_utf32))
.Const(_SC("WChar"), static_cast< Int32 >(encoding_wchar))
.Const(_SC("Latin1"), static_cast< Int32 >(encoding_latin1))
);
ConstTable(vm).Enum(_SC("SqXmlFormat"), Enumeration(vm)
.Const(_SC("Indent"), static_cast< Int32 >(format_indent))
.Const(_SC("WriteBOM"), static_cast< Int32 >(format_write_bom))
.Const(_SC("Raw"), static_cast< Int32 >(format_raw))
.Const(_SC("NoDeclaration"), static_cast< Int32 >(format_no_declaration))
.Const(_SC("NoEscapes"), static_cast< Int32 >(format_no_escapes))
.Const(_SC("SaveFileText"), static_cast< Int32 >(format_save_file_text))
.Const(_SC("IndentAttributes"), static_cast< Int32 >(format_indent_attributes))
.Const(_SC("Default"), static_cast< Int32 >(format_default))
);
ConstTable(vm).Enum(_SC("SqXmlParseStatus"), Enumeration(vm)
.Const(_SC("Ok"), static_cast< Int32 >(status_ok))
.Const(_SC("FileNotFound"), static_cast< Int32 >(status_file_not_found))
.Const(_SC("IOError"), static_cast< Int32 >(status_io_error))
.Const(_SC("OutOfMemory"), static_cast< Int32 >(status_out_of_memory))
.Const(_SC("InternalError"), static_cast< Int32 >(status_internal_error))
.Const(_SC("UnrecognizedTag"), static_cast< Int32 >(status_unrecognized_tag))
.Const(_SC("BadPi"), static_cast< Int32 >(status_bad_pi))
.Const(_SC("BadComment"), static_cast< Int32 >(status_bad_comment))
.Const(_SC("BadCData"), static_cast< Int32 >(status_bad_cdata))
.Const(_SC("BadDoctype"), static_cast< Int32 >(status_bad_doctype))
.Const(_SC("BadPCData"), static_cast< Int32 >(status_bad_pcdata))
.Const(_SC("BadStartElement"), static_cast< Int32 >(status_bad_start_element))
.Const(_SC("BadAttribute"), static_cast< Int32 >(status_bad_attribute))
.Const(_SC("BadEndElement"), static_cast< Int32 >(status_bad_end_element))
.Const(_SC("EndElementMismatch"), static_cast< Int32 >(status_end_element_mismatch))
.Const(_SC("AppendInvalidRoot"), static_cast< Int32 >(status_append_invalid_root))
.Const(_SC("NoDocumentElement"), static_cast< Int32 >(status_no_document_element))
);
ConstTable(vm).Enum(_SC("SqXmlXpathValueType"), Enumeration(vm)
.Const(_SC("None"), static_cast< Int32 >(xpath_type_none))
.Const(_SC("NodeSet"), static_cast< Int32 >(xpath_type_node_set))
.Const(_SC("Number"), static_cast< Int32 >(xpath_type_number))
.Const(_SC("String"), static_cast< Int32 >(xpath_type_string))
.Const(_SC("Boolean"), static_cast< Int32 >(xpath_type_boolean))
);
// Registration was successful
return true;
}
/* ------------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
static bool OnSquirrelLoad()
{
// Make sure that we have a valid module API
if (!SqMod_GetSquirrelVM)
{
OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQXML_NAME);
// Unable to proceed!
return false;
}
// Obtain the Squirrel virtual machine from the host plug-in
DefaultVM::Set(SqMod_GetSquirrelVM());
// Make sure that a valid virtual machine exists
if (!DefaultVM::Get())
{
OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQXML_NAME);
// Unable to proceed!
return false;
}
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullFunction() = Function();
// Register the module API
if (RegisterAPI(DefaultVM::Get()))
{
OutputMessage("Registered: %s", SQXML_NAME);
}
else
{
return false;
}
// At this point, the module was successfully loaded
return true;
}
/* ------------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
static void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQXML_NAME);
// Release null objects just in case
NullObject().Release();
NullTable().Release();
NullArray().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Release script resources...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined is about to be closed. Last chance to release anything manually.
*/
static void OnSquirrelClosing()
{
// Nothing to release manually...
}
/* ------------------------------------------------------------------------------------------------
* The virtual machined was closed and all memory associated with it was released.
*/
static void OnSquirrelReleased()
{
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* ------------------------------------------------------------------------------------------------
* React to command sent by other plug-ins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
{
if (CheckModuleAPIVer(message, SQXML_NAME))
{
try
{
ImportModuleAPI(_Func, SQXML_NAME);
}
catch (const Sqrat::Exception & e)
{
OutputError("%s", e.what());
// Failed to initialize
return 0;
}
}
} break;
case SQMOD_LOAD_CMD:
{
return OnSquirrelLoad();
} break;
case SQMOD_TERMINATE_CMD:
{
OnSquirrelTerminate();
} break;
case SQMOD_CLOSING_CMD:
{
OnSquirrelClosing();
} break;
case SQMOD_RELEASED_CMD:
{
OnSquirrelReleased();
} break;
default: break;
}
return 1;
}
/* ------------------------------------------------------------------------------------------------
* The server was initialized and this plug-in was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1; // Initialization was successful
}
/* ------------------------------------------------------------------------------------------------
* The server is about to shutdown gracefully.
*/
static void OnServerShutdown(void)
{
// The server may still send callbacks
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info)
{
using namespace SqMod;
// Output plug-in header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plug-in: %s", SQXML_NAME);
OutputMessage("Author: %s", SQXML_AUTHOR);
OutputMessage("Legal: %s", SQXML_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Make sure that the module was loaded after the host plug-in
if (!CheckModuleOrder(functions, info->pluginId, SQXML_NAME))
{
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plug-in version
_Info->pluginVersion = SQXML_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQXML_HOST_NAME);
// Bind to the server callbacks
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
// Notify that the plug-in was successfully loaded
OutputMessage("Successfully loaded %s", SQXML_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,101 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Node.hpp"
#include "Attribute.hpp"
#include "Text.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Node::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqXmlNode");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetFirstAttr() const
{
return Attribute(m_Doc, m_Node.first_attribute());
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetLastAttr() const
{
return Attribute(m_Doc, m_Node.last_attribute());
}
// ------------------------------------------------------------------------------------------------
Text Node::GetText() const
{
return Text(m_Doc, m_Node.text());
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetAttribute(CSStr name) const
{
return Attribute(m_Doc, m_Node.attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AttributeFrom(CSStr name, Attribute & attr) const
{
return Attribute(m_Doc, m_Node.attribute(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AppendAttr(CSStr name)
{
return Attribute(m_Doc, m_Node.append_attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::PrependAttr(CSStr name)
{
return Attribute(m_Doc, m_Node.prepend_attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrAfter(CSStr name, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_attribute_after(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrBefore(CSStr name, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_attribute_before(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AppendAttrCopy(const Attribute & proto)
{
return Attribute(m_Doc, m_Node.append_copy(proto.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::PrependAttrCopy(const Attribute & proto)
{
return Attribute(m_Doc, m_Node.prepend_copy(proto.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrCopyAfter(const Attribute & proto, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_copy_after(proto.m_Attr, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrCopyBefore(const Attribute & proto, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_copy_before(proto.m_Attr, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
bool Node::RemoveAttrInst(const Attribute & attr)
{
return m_Node.remove_attribute(attr.m_Attr);
}
} // Namespace:: SqMod

View File

@ -1,613 +0,0 @@
#ifndef _SQXML_NODE_HPP_
#define _SQXML_NODE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Document.hpp"
#include "Wrapper/ParseResult.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A light-weight handle for manipulating nodes in DOM tree.
*/
class Node
{
// --------------------------------------------------------------------------------------------
friend class Document;
friend class Text;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_node Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Node(const DocumentRef doc, const Type & node)
: m_Doc(doc), m_Node(node)
{
/* ... */
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main xml document instance.
Type m_Node; // The managed document node.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Node()
: m_Doc(), m_Node()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Node(const Node & o)
: m_Doc(o.m_Doc), m_Node(o.m_Node)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Node()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Node & operator = (const Node & o)
{
m_Doc = o.m_Doc;
m_Node = o.m_Node;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Node & o)
{
if (m_Node == o.m_Node)
{
return 0;
}
else if (m_Node > o.m_Node)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Node.value();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether the node is empty.
*/
bool IsEmpty() const
{
return m_Node.empty();
}
/* --------------------------------------------------------------------------------------------
* Get hash value (unique for handles to the same object).
*/
SQInteger GetHashValue() const
{
return static_cast< SQInteger >(m_Node.hash_value());
}
/* --------------------------------------------------------------------------------------------
* Get node offset in parsed file/string (in char_t units) for debugging purposes.
*/
SQInteger GetOffsetDebug() const
{
return static_cast< SQInteger >(m_Node.offset_debug());
}
/* --------------------------------------------------------------------------------------------
* Retrieve node type.
*/
Int32 GetType() const
{
return static_cast< Int32 >(m_Node.type());
}
/* --------------------------------------------------------------------------------------------
* Retrieve node name.
*/
CSStr GetName() const
{
return m_Node.name();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node name.
*/
void SetName(CSStr name)
{
if (!m_Node.set_name(name))
{
STHROWF("Unable to set XML node name");
}
}
/* --------------------------------------------------------------------------------------------
* Modify the node name.
*/
bool ApplyName(CSStr name)
{
return m_Node.set_name(name);
}
/* --------------------------------------------------------------------------------------------
* Retrieve node value.
*/
CSStr GetValue() const
{
return m_Node.value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node value.
*/
void SetValue(CSStr name)
{
if (!m_Node.set_value(name))
{
STHROWF("Unable to set XML node value");
}
}
/* --------------------------------------------------------------------------------------------
* Modify the node value.
*/
bool ApplyValue(CSStr value)
{
return m_Node.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source)
{
// Is the specified source buffer even valid?
if (source)
{
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar)));
}
// Return the default result
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source, Uint32 options)
{
// Is the specified source buffer even valid?
if (source)
{
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar), options));
}
// Return the default result
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source, Uint32 options, Int32 encoding)
{
// Is the specified source buffer even valid?
if (source)
{
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar),
options, (xml_encoding)encoding));
}
// Return the default result
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the first child attribute.
*/
Attribute GetFirstAttr() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last child attribute.
*/
Attribute GetLastAttr() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the first child node.
*/
Node GetFirstChild() const
{
return Node(m_Doc, m_Node.first_child());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last child node.
*/
Node GetLastChild() const
{
return Node(m_Doc, m_Node.last_child());
}
/* --------------------------------------------------------------------------------------------
* Get next sibling in the children list of the parent node.
*/
Node GetNextSibling() const
{
return Node(m_Doc, m_Node.next_sibling());
}
/* --------------------------------------------------------------------------------------------
* Get previous sibling in the children list of the parent node
*/
Node GetPrevSibling() const
{
return Node(m_Doc, m_Node.previous_sibling());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the parent node.
*/
Node GetParent() const
{
return Node(m_Doc, m_Node.parent());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the root node.
*/
Node GetRoot() const
{
return Node(m_Doc, m_Node.root());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the text object for the current node.
*/
Text GetText() const;
/* --------------------------------------------------------------------------------------------
* Retrieve child node with the specified name.
*/
Node Child(CSStr name) const
{
return Node(m_Doc, m_Node.child(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve child attribute with the specified name.
*/
Attribute GetAttribute(CSStr name) const;
/* --------------------------------------------------------------------------------------------
* Retrieve next sibling with the specified name.
*/
Node NextSibling(CSStr name) const
{
return Node(m_Doc, m_Node.next_sibling(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve previous sibling with the specified name.
*/
Node PrevSibling(CSStr name) const
{
return Node(m_Doc, m_Node.previous_sibling(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve child attribute, starting the search from a hint.
*/
Attribute AttributeFrom(CSStr name, Attribute & attr) const;
/* --------------------------------------------------------------------------------------------
* Get child value of current node; that is, value of the first child node of type PCDATA/CDATA.
*/
CSStr GetChildValue() const
{
return m_Node.child_value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve child value of child with specified name.
*/
CSStr ChildValue(CSStr name) const
{
return m_Node.child_value(name);
}
/* --------------------------------------------------------------------------------------------
* Append a child attribute with the specified name.
*/
Attribute AppendAttr(CSStr name);
/* --------------------------------------------------------------------------------------------
* Prepend a child attribute with the specified name.
*/
Attribute PrependAttr(CSStr name);
/* --------------------------------------------------------------------------------------------
* Insert a child attribute with the specified name, after the specified node.
*/
Attribute InsertAttrAfter(CSStr name, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Insert a child attribute with the specified name, before the specified node.
*/
Attribute InsertAttrBefore(CSStr name, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Append a copy of the specified attribute as a child.
*/
Attribute AppendAttrCopy(const Attribute & proto);
/* --------------------------------------------------------------------------------------------
* Prepend a copy of the specified attribute as a child.
*/
Attribute PrependAttrCopy(const Attribute & proto);
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified attribute as a child after the specified attribute.
*/
Attribute InsertAttrCopyAfter(const Attribute & proto, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified attribute as a child before the specified attribute.
*/
Attribute InsertAttrCopyBefore(const Attribute & proto, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Append a basic child node with the specified name.
*/
Node AppendChild(CSStr name)
{
return Node(m_Doc, m_Node.append_child(name));
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node with the specified name.
*/
Node PrependChild(CSStr name)
{
return Node(m_Doc, m_Node.prepend_child(name));
}
/* --------------------------------------------------------------------------------------------
* Append a basic child node.
*/
Node AppendChildNode()
{
return Node(m_Doc, m_Node.append_child());
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node.
*/
Node PrependChildNode()
{
return Node(m_Doc, m_Node.prepend_child());
}
/* --------------------------------------------------------------------------------------------
* Append a basic child node with the specified type.
*/
Node AppendChildType(Int32 type)
{
return Node(m_Doc, m_Node.append_child(static_cast< xml_node_type >(type)));
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node with the specified type.
*/
Node PrependChildType(Int32 type)
{
return Node(m_Doc, m_Node.prepend_child(static_cast< xml_node_type >(type)));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified name, after the specified node.
*/
Node InsertChildAfter(CSStr name, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_after(name, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified name, before the specified node.
*/
Node InsertChildBefore(CSStr name, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_before(name, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified type, after the specified node.
*/
Node InsertChildTypeAfter(Int32 type, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_after(static_cast< xml_node_type >(type),
node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified type, before the specified node.
*/
Node InsertChildTypeBefore(Int32 type, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_before(static_cast< xml_node_type >(type),
node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Append a copy of the specified node as a child.
*/
Node AppendCopy(const Node & proto)
{
return Node(m_Doc, m_Node.append_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Prepend a copy of the specified node as a child.
*/
Node PrependCopy(const Node & proto)
{
return Node(m_Doc, m_Node.prepend_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified node as a child after the specified node.
*/
Node InsertCopyAfter(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_after(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified node as a child before the specified node.
*/
Node InsertCopyBefore(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_before(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Append the specified node as a child and take ownership of it.
*/
Node AppendMove(const Node & proto)
{
return Node(m_Doc, m_Node.append_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Prepend the specified node as a child and take ownership of it.
*/
Node PrependMove(const Node & proto)
{
return Node(m_Doc, m_Node.prepend_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert the specified node as a child after the specified node and take ownership of it.
*/
Node InsertMoveAfter(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_after(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert the specified node as a child before the specified node and take ownership of it.
*/
Node InsertMoveBefore(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_before(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Remove the child attribute matching the specified name.
*/
bool RemoveAttr(CSStr name)
{
return m_Node.remove_attribute(name);
}
/* --------------------------------------------------------------------------------------------
* Remove the specified attribute.
*/
bool RemoveAttrInst(const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Remove the child node matching the specified name.
*/
bool RemoveChild(CSStr name)
{
return m_Node.remove_child(name);
}
/* --------------------------------------------------------------------------------------------
* Remove the specified node.
*/
bool RemoveChildInst(const Node & node)
{
return m_Node.remove_child(node.m_Node);
}
/* --------------------------------------------------------------------------------------------
* Find child node by attribute name/value.
*/
Node FindChildByAttr(CSStr attr_name, CSStr attr_value) const
{
return Node(m_Doc, m_Node.find_child_by_attribute(attr_name, attr_value));
}
/* --------------------------------------------------------------------------------------------
* Find child node by attribute name/value.
*/
Node FindChildByAttr(CSStr name, CSStr attr_name, CSStr attr_value) const
{
return Node(m_Doc, m_Node.find_child_by_attribute(name, attr_name, attr_value));
}
/* --------------------------------------------------------------------------------------------
* Search for a node by path consisting of node names and . or .. elements.
*/
Node FindElemByPath(CSStr path, SQChar delimiter) const
{
return Node(m_Doc, m_Node.first_element_by_path(path, delimiter));
}
};
} // Namespace:: SqMod
#endif // _SQXML_NODE_HPP_

View File

@ -1,176 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Text.hpp"
#include "Node.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Text::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqXmlText");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Text::Cmp(const Text & o)
{
if (strcmp(m_Text.get(), o.m_Text.get()) == 0)
{
return 0;
}
else if (strlen(m_Text.get()) > strlen(o.m_Text.get()))
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
Object Text::AsLong(Object & def) const
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), def);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), m_Text.as_llong(longint));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Text::AsUlong(Object & def) const
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object >::push(DefaultVM::Get(), def);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), m_Text.as_ullong(longint));
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
bool Text::ApplyLong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value and return the result
return m_Text.set(longint);
}
// ------------------------------------------------------------------------------------------------
bool Text::ApplyUlong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value and return the result
return m_Text.set(longint);
}
// ------------------------------------------------------------------------------------------------
Object Text::GetLong() const
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushSLongObject(DefaultVM::Get(), m_Text.as_llong());
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
void Text::SetLong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetSLongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value
m_Text = longint;
}
// ------------------------------------------------------------------------------------------------
Object Text::GetUlong() const
{
// Obtain the initial stack size
const StackGuard sg;
// Push a long integer instance with the requested value on the stack
SqMod_PushULongObject(DefaultVM::Get(), m_Text.as_ullong());
// Obtain the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
void Text::SetUlong(Object & value)
{
// Obtain the initial stack size
const StackGuard sg;
// Push the specified object onto the stack
Var< Object & >::push(DefaultVM::Get(), value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(SqMod_GetULongValue(DefaultVM::Get(), -1, &longint)))
{
STHROWF("Invalid long integer specified");
}
// Assign the obtained value
m_Text = longint;
}
// ------------------------------------------------------------------------------------------------
Node Text::GetData() const
{
return Node(m_Doc, m_Text.data());
}
} // Namespace:: SqMod

View File

@ -1,365 +0,0 @@
#ifndef _SQXML_TEXT_HPP_
#define _SQXML_TEXT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Document.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A helper for working with text inside PCDATA nodes.
*/
class Text
{
// --------------------------------------------------------------------------------------------
friend class Node;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_text Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Text(const DocumentRef doc, const Type & text)
: m_Doc(doc), m_Text(text)
{
/* ... */
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main xml document instance.
Type m_Text; // The managed document node.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Text()
: m_Doc(), m_Text()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Text(const Text & o)
: m_Doc(o.m_Doc), m_Text(o.m_Text)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Text()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Text & operator = (const Text & o)
{
m_Doc = o.m_Doc;
m_Text = o.m_Text;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Text & o);
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Text.get();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether the text is empty.
*/
bool IsEmpty() const
{
return m_Text.empty();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the text value.
*/
CSStr GetValue() const
{
return m_Text.get();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string or the specified default value if empty.
*/
CSStr AsString(CSStr def) const
{
return m_Text.as_string(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer or the specified default value if empty.
*/
Int32 AsInt(Int32 def) const
{
return m_Text.as_int(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer or the specified default value if empty.
*/
Uint32 AsUint(Uint32 def) const
{
return m_Text.as_uint(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point or the specified default value if empty.
*/
SQFloat AsFloat(SQFloat def) const
{
return static_cast< SQFloat >(m_Text.as_float(static_cast< Float32 >(def)));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point or the specified default value if empty.
*/
SQFloat AsDouble(SQFloat def) const
{
return static_cast< SQFloat >(m_Text.as_double(static_cast< Float64 >(def)));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer or the specified default value if empty.
*/
Object AsLong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer or the specified default value if empty.
*/
Object AsUlong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean or the specified default value if empty.
*/
bool AsBool(bool def) const
{
return m_Text.as_bool(def);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
bool ApplyString(CSStr value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
bool ApplyInt(Int32 value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
bool ApplyUint(Uint32 value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
bool ApplyFloat(SQFloat value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
bool ApplyDouble(SQFloat value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
bool ApplyLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
bool ApplyUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
bool ApplyBool(bool value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string.
*/
CSStr GetString() const
{
return m_Text.as_string();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
void SetString(CSStr value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer.
*/
Int32 GetInt() const
{
return m_Text.as_int();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
void SetInt(Int32 value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer.
*/
Uint32 GetUint() const
{
return m_Text.as_uint();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
void SetUint(Uint32 value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point.
*/
SQFloat GetFloat() const
{
return static_cast< SQFloat >(m_Text.as_float());
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
void SetFloat(SQFloat value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point.
*/
SQFloat GetDouble() const
{
return static_cast< SQFloat >(m_Text.as_double());
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
void SetDouble(SQFloat value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer.
*/
Object GetLong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
void SetLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer.
*/
Object GetUlong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
void SetUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean.
*/
bool GetBool() const
{
return m_Text.as_bool();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
void SetBool(bool value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the data node (node_pcdata or node_cdata) for this object.
*/
Node GetData() const;
};
} // Namespace:: SqMod
#endif // _SQXML_TEXT_HPP_

Some files were not shown because too many files have changed in this diff Show More