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:
parent
1fd5fda8c0
commit
1099c7fd20
@ -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
|
@ -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_
|
@ -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
|
@ -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
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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"
|
@ -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;
|
||||
}
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Parameter.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -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_
|
@ -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
|
@ -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_
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,17 +0,0 @@
|
||||
#ifndef _SQMYSQL_SAVEPOINT_HPP_
|
||||
#define _SQMYSQL_SAVEPOINT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMYSQL_SAVEPOINT_HPP_
|
@ -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
|
@ -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_
|
@ -1,10 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Account.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
|
@ -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_
|
@ -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
|
@ -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
|
@ -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
|
@ -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_
|
@ -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
|
@ -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_
|
@ -1,9 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
@ -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_
|
@ -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
|
@ -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_
|
@ -1,16 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Handle/Document.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DocumentRef::Validate() const
|
||||
{
|
||||
if (!m_Ptr)
|
||||
{
|
||||
STHROWF("Invalid XML document reference");
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
|
@ -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_
|
@ -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
|
@ -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
Loading…
Reference in New Issue
Block a user