mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-31 09:57:14 +01:00
Fixed excpetion throwing in SQLite document to that generated corrupted messages because snprintf was used instead of vsnprintf.
Revised most of the SQLite plugin and cleaned code.
This commit is contained in:
parent
b6466b9181
commit
fab15840cb
@ -4,6 +4,9 @@
|
|||||||
#include "Statement.hpp"
|
#include "Statement.hpp"
|
||||||
#include "Module.hpp"
|
#include "Module.hpp"
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <sqrat.h>
|
#include <sqrat.h>
|
||||||
|
|
||||||
@ -23,10 +26,11 @@ void Column::Validate() const
|
|||||||
{
|
{
|
||||||
// Are we pointing to a valid index?
|
// Are we pointing to a valid index?
|
||||||
if (m_Index < 0)
|
if (m_Index < 0)
|
||||||
|
{
|
||||||
STHROWF("Invalid column index");
|
STHROWF("Invalid column index");
|
||||||
|
}
|
||||||
// Do we belong to a valid statement?
|
// Do we belong to a valid statement?
|
||||||
else if (!m_Stmt)
|
m_Stmt.Validate();
|
||||||
STHROWF("Invalid SQLite statement reference");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -34,13 +38,16 @@ void Column::ValidateRow() const
|
|||||||
{
|
{
|
||||||
// Are we pointing to a valid index?
|
// Are we pointing to a valid index?
|
||||||
if (m_Index < 0)
|
if (m_Index < 0)
|
||||||
|
{
|
||||||
STHROWF("Invalid column index");
|
STHROWF("Invalid column index");
|
||||||
|
}
|
||||||
// Do we belong to a valid statement?
|
// Do we belong to a valid statement?
|
||||||
else if (!m_Stmt)
|
m_Stmt.Validate();
|
||||||
STHROWF("Invalid SQLite statement reference");
|
|
||||||
// Do we have any rows available?
|
// Do we have any rows available?
|
||||||
else if (!m_Stmt->mGood)
|
if (!m_Stmt->mGood)
|
||||||
|
{
|
||||||
STHROWF("No row available");
|
STHROWF("No row available");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -89,7 +96,7 @@ SQFloat Column::GetFloat() const
|
|||||||
// Validate the column and statement row
|
// Validate the column and statement row
|
||||||
ValidateRow();
|
ValidateRow();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return (SQFloat)sqlite3_column_double(m_Stmt, m_Index);
|
return static_cast< SQFloat >(sqlite3_column_double(m_Stmt, m_Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -113,8 +120,8 @@ Object Column::GetString() const
|
|||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const StackGuard sg(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Push the column text on the stack
|
// Push the column text on the stack
|
||||||
sq_pushstring(_SqVM, (CSStr)sqlite3_column_text(m_Stmt, m_Index),
|
sq_pushstring(_SqVM, reinterpret_cast< CSStr >(sqlite3_column_text(m_Stmt, m_Index)),
|
||||||
sqlite3_column_bytes(m_Stmt, m_Index));
|
sqlite3_column_bytes(m_Stmt, m_Index));
|
||||||
// Get the object from the stack and return it
|
// Get the object from the stack and return it
|
||||||
return Var< Object >(_SqVM, -1).value;
|
return Var< Object >(_SqVM, -1).value;
|
||||||
}
|
}
|
||||||
@ -143,7 +150,9 @@ Object Column::GetBlob() const
|
|||||||
const void * b = sqlite3_column_blob(m_Stmt, m_Index);
|
const void * b = sqlite3_column_blob(m_Stmt, m_Index);
|
||||||
// Could the memory blob be allocated?
|
// Could the memory blob be allocated?
|
||||||
if (!p)
|
if (!p)
|
||||||
|
{
|
||||||
STHROWF("Unable to allocate space for column blob value");
|
STHROWF("Unable to allocate space for column blob value");
|
||||||
|
}
|
||||||
// Is there any data to read?
|
// Is there any data to read?
|
||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
@ -154,7 +163,9 @@ Object Column::GetBlob() const
|
|||||||
}
|
}
|
||||||
// Copy the data into the memory blob
|
// Copy the data into the memory blob
|
||||||
else
|
else
|
||||||
memcpy(p, b, sz);
|
{
|
||||||
|
std::memcpy(p, b, sz);
|
||||||
|
}
|
||||||
// Get the object from the stack and return it
|
// Get the object from the stack and return it
|
||||||
return Var< Object >(_SqVM, -1).value;
|
return Var< Object >(_SqVM, -1).value;
|
||||||
}
|
}
|
||||||
@ -196,9 +207,9 @@ CSStr Column::GetOriginName() const
|
|||||||
return sqlite3_column_origin_name(m_Stmt, m_Index);
|
return sqlite3_column_origin_name(m_Stmt, m_Index);
|
||||||
#else
|
#else
|
||||||
STHROWF("The module was compiled without this feature");
|
STHROWF("The module was compiled without this feature");
|
||||||
#endif
|
|
||||||
// Request failed
|
// Request failed
|
||||||
return _SC("");
|
return _SC("");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -111,11 +111,17 @@ public:
|
|||||||
Int32 Cmp(const Column & o) const
|
Int32 Cmp(const Column & o) const
|
||||||
{
|
{
|
||||||
if (m_Stmt == o.m_Stmt)
|
if (m_Stmt == o.m_Stmt)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else if (m_Stmt.HndPtr() > o.m_Stmt.HndPtr())
|
else if (m_Stmt.HndPtr() > o.m_Stmt.HndPtr())
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#include "Connection.hpp"
|
#include "Connection.hpp"
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <ctype.h>
|
#include <cctype>
|
||||||
#include <stdarg.h>
|
#include <cstring>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <sqrat.h>
|
#include <sqrat.h>
|
||||||
@ -35,8 +36,10 @@ void SqThrowF(CSStr str, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start (args, str);
|
va_start (args, str);
|
||||||
// Write the requested contents
|
// Write the requested contents
|
||||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||||
strcpy(g_Buffer, "Unknown error has occurred");
|
{
|
||||||
|
std::strcpy(g_Buffer, "Unknown error has occurred");
|
||||||
|
}
|
||||||
// Release the argument list
|
// Release the argument list
|
||||||
va_end(args);
|
va_end(args);
|
||||||
// Throw the exception with the resulted message
|
// Throw the exception with the resulted message
|
||||||
@ -50,8 +53,10 @@ CSStr FmtStr(CSStr str, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start (args, str);
|
va_start (args, str);
|
||||||
// Write the requested contents
|
// Write the requested contents
|
||||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||||
g_Buffer[0] = 0; /* make sure the string is terminated */
|
{
|
||||||
|
g_Buffer[0] = 0; // make sure the string is terminated
|
||||||
|
}
|
||||||
// Release the argument list
|
// Release the argument list
|
||||||
va_end(args);
|
va_end(args);
|
||||||
// Return the data from the buffer
|
// Return the data from the buffer
|
||||||
@ -77,23 +82,34 @@ bool IsQueryEmpty(CSStr str)
|
|||||||
{
|
{
|
||||||
// Is the pointer valid?
|
// Is the pointer valid?
|
||||||
if (!str)
|
if (!str)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
// Currently processed character
|
// Currently processed character
|
||||||
SQChar c = 0;
|
SQChar c = 0;
|
||||||
// See if the query contains any alpha numeric characters
|
// See if the query contains any alpha numeric characters
|
||||||
while ((c = *str) != 0)
|
while ((c = *str) != 0)
|
||||||
{
|
{
|
||||||
if (isalnum(c) != 0)
|
if (std::isalnum(c) != 0)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
++str;
|
++str;
|
||||||
}
|
}
|
||||||
// At this point we consider the query empty
|
// At this point we consider the query empty
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
StackGuard::StackGuard()
|
||||||
|
: m_VM(_SqVM), m_Top(sq_gettop(m_VM))
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
StackGuard::StackGuard(HSQUIRRELVM vm)
|
StackGuard::StackGuard(HSQUIRRELVM vm)
|
||||||
: m_Top(sq_gettop(vm)), m_VM(vm)
|
: m_VM(vm), m_Top(sq_gettop(vm))
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -104,16 +120,130 @@ StackGuard::~StackGuard()
|
|||||||
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt)
|
||||||
|
: mPtr(nullptr)
|
||||||
|
, mLen(-1)
|
||||||
|
, mRes(SQ_OK)
|
||||||
|
, mObj()
|
||||||
|
, mVM(vm)
|
||||||
|
{
|
||||||
|
const Int32 top = sq_gettop(vm);
|
||||||
|
// Reset the converted value object
|
||||||
|
sq_resetobject(&mObj);
|
||||||
|
// Was the string or value specified?
|
||||||
|
if (top <= (idx - 1))
|
||||||
|
{
|
||||||
|
mRes = sq_throwerror(vm, "Missing string or value");
|
||||||
|
}
|
||||||
|
// Do we have enough values to call the format function and are we allowed to?
|
||||||
|
else if (top > idx && fmt)
|
||||||
|
{
|
||||||
|
// Pointer to the generated string
|
||||||
|
SStr str = nullptr;
|
||||||
|
// Attempt to generate the specified string format
|
||||||
|
mRes = sqstd_format(vm, idx, &mLen, &str);
|
||||||
|
// Did the format succeeded but ended up with a null string pointer?
|
||||||
|
if (SQ_SUCCEEDED(mRes) && !str)
|
||||||
|
{
|
||||||
|
mRes = sq_throwerror(vm, "Unable to generate the string");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPtr = const_cast< CSStr >(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Is the value on the stack an actual string?
|
||||||
|
else if (sq_gettype(vm, idx) == OT_STRING)
|
||||||
|
{
|
||||||
|
// Obtain a reference to the string object
|
||||||
|
mRes = sq_getstackobj(vm, idx, &mObj);
|
||||||
|
// Could we retrieve the object from the stack?
|
||||||
|
if (SQ_SUCCEEDED(mRes))
|
||||||
|
{
|
||||||
|
// Keep a strong reference to the object
|
||||||
|
sq_addref(vm, &mObj);
|
||||||
|
// Attempt to retrieve the string value from the stack
|
||||||
|
mRes = sq_getstring(vm, idx, &mPtr);
|
||||||
|
}
|
||||||
|
// Did the retrieval succeeded but ended up with a null string pointer?
|
||||||
|
if (SQ_SUCCEEDED(mRes) && !mPtr)
|
||||||
|
{
|
||||||
|
mRes = sq_throwerror(vm, "Unable to retrieve the string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We have to try and convert it to string
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Attempt to convert the value from the stack to a string
|
||||||
|
mRes = sq_tostring(vm, idx);
|
||||||
|
// Could we convert the specified value to string?
|
||||||
|
if (SQ_SUCCEEDED(mRes))
|
||||||
|
{
|
||||||
|
// Obtain a reference to the resulted object
|
||||||
|
mRes = sq_getstackobj(vm, -1, &mObj);
|
||||||
|
// Could we retrieve the object from the stack?
|
||||||
|
if (SQ_SUCCEEDED(mRes))
|
||||||
|
{
|
||||||
|
// Keep a strong reference to the object
|
||||||
|
sq_addref(vm, &mObj);
|
||||||
|
// Attempt to obtain the string pointer
|
||||||
|
mRes = sq_getstring(vm, -1, &mPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Pop a value from the stack regardless of the result
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
// Did the retrieval succeeded but ended up with a null string pointer?
|
||||||
|
if (SQ_SUCCEEDED(mRes) && !mPtr)
|
||||||
|
{
|
||||||
|
mRes = sq_throwerror(vm, "Unable to retrieve the value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
StackStrF::~StackStrF()
|
||||||
|
{
|
||||||
|
if (mVM && !sq_isnull(mObj))
|
||||||
|
{
|
||||||
|
sq_release(mVM, &mObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConnHnd::Validate() const
|
||||||
|
{
|
||||||
|
// Is the handle valid?
|
||||||
|
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||||
|
{
|
||||||
|
STHROWF("Invalid SQLite connection reference");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void StmtHnd::Validate() const
|
||||||
|
{
|
||||||
|
// Is the handle valid?
|
||||||
|
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
|
||||||
|
{
|
||||||
|
STHROWF("Invalid SQLite statement reference");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ConnHnd::Handle::~Handle()
|
ConnHnd::Handle::~Handle()
|
||||||
{
|
{
|
||||||
// Is there anything to close?
|
// Is there anything to close?
|
||||||
if (!mPtr)
|
if (!mPtr)
|
||||||
|
{
|
||||||
return; // Nothing to close
|
return; // Nothing to close
|
||||||
|
}
|
||||||
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
|
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
|
||||||
else if (mRef != 0)
|
else if (mRef != 0)
|
||||||
|
{
|
||||||
// Should we deal with undefined behavior instead? How bad is one connection left open?
|
// Should we deal with undefined behavior instead? How bad is one connection left open?
|
||||||
_SqMod->LogErr("SQLite connection is still referenced (%s)", mName.c_str());
|
_SqMod->LogErr("SQLite connection is still referenced (%s)", mName.c_str());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// NOTE: Should we call sqlite3_interrupt(...) before closing?
|
// NOTE: Should we call sqlite3_interrupt(...) before closing?
|
||||||
@ -123,7 +253,9 @@ ConnHnd::Handle::~Handle()
|
|||||||
Flush(mQueue.size(), env, func);
|
Flush(mQueue.size(), env, func);
|
||||||
// Attempt to close the database
|
// Attempt to close the database
|
||||||
if ((sqlite3_close(mPtr)) != SQLITE_OK)
|
if ((sqlite3_close(mPtr)) != SQLITE_OK)
|
||||||
|
{
|
||||||
_SqMod->LogErr("Unable to close SQLite connection [%s]", sqlite3_errmsg(mPtr));
|
_SqMod->LogErr("Unable to close SQLite connection [%s]", sqlite3_errmsg(mPtr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,19 +264,25 @@ void ConnHnd::Handle::Create(CSStr name, Int32 flags, CSStr vfs)
|
|||||||
{
|
{
|
||||||
// Make sure a previous connection doesn't exist
|
// Make sure a previous connection doesn't exist
|
||||||
if (mPtr)
|
if (mPtr)
|
||||||
|
{
|
||||||
STHROWF("Unable to connect to database. Database already connected");
|
STHROWF("Unable to connect to database. Database already connected");
|
||||||
|
}
|
||||||
// Make sure the name is valid
|
// Make sure the name is valid
|
||||||
else if (!name || strlen(name) <= 0)
|
else if (!name || *name == '\0')
|
||||||
|
{
|
||||||
STHROWF("Unable to connect to database. The name is invalid");
|
STHROWF("Unable to connect to database. The name is invalid");
|
||||||
|
}
|
||||||
// Attempt to create the database connection
|
// Attempt to create the database connection
|
||||||
else if ((mStatus = sqlite3_open_v2(name, &mPtr, flags, vfs)) != SQLITE_OK)
|
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
|
// Must be destroyed regardless of result
|
||||||
sqlite3_close(mPtr);
|
sqlite3_close(mPtr);
|
||||||
// Explicitly make sure it's null
|
// Explicitly make sure it's null
|
||||||
mPtr = NULL;
|
mPtr = nullptr;
|
||||||
// Now its safe to throw the error
|
// Now its safe to throw the error
|
||||||
STHROWF("Unable to connect to database [%s]", sqlite3_errstr(mStatus));
|
STHROWF("Unable to connect to database [%s]", msg.c_str());
|
||||||
}
|
}
|
||||||
// Let's save the specified information
|
// Let's save the specified information
|
||||||
mName.assign(name);
|
mName.assign(name);
|
||||||
@ -178,7 +316,7 @@ Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
|
|||||||
QueryList::iterator itr = mQueue.begin();
|
QueryList::iterator itr = mQueue.begin();
|
||||||
QueryList::iterator end = mQueue.begin() + num;
|
QueryList::iterator end = mQueue.begin() + num;
|
||||||
// Attempt to begin the flush transaction
|
// Attempt to begin the flush transaction
|
||||||
if ((mStatus = sqlite3_exec(mPtr, "BEGIN", NULL, NULL, NULL)) != SQLITE_OK)
|
if ((mStatus = sqlite3_exec(mPtr, "BEGIN", nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
STHROWF("Unable to begin flush transaction [%s]", sqlite3_errmsg(mPtr));
|
STHROWF("Unable to begin flush transaction [%s]", sqlite3_errmsg(mPtr));
|
||||||
}
|
}
|
||||||
@ -193,7 +331,7 @@ Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// Attempt to execute the currently processed query string
|
// Attempt to execute the currently processed query string
|
||||||
if ((mStatus = sqlite3_exec(mPtr, itr->c_str(), NULL, NULL, NULL)) == SQLITE_OK)
|
if ((mStatus = sqlite3_exec(mPtr, itr->c_str(), nullptr, nullptr, nullptr)) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -227,12 +365,12 @@ Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
|
|||||||
// Erase all queries till end or till the point of failure (if any occurred)
|
// Erase all queries till end or till the point of failure (if any occurred)
|
||||||
mQueue.erase(mQueue.begin(), itr);
|
mQueue.erase(mQueue.begin(), itr);
|
||||||
// Attempt to commit changes requested during transaction
|
// Attempt to commit changes requested during transaction
|
||||||
if ((mStatus = sqlite3_exec(mPtr, "COMMIT", NULL, NULL, NULL)) == SQLITE_OK)
|
if ((mStatus = sqlite3_exec(mPtr, "COMMIT", nullptr, nullptr, nullptr)) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
return sqlite3_changes(mPtr);
|
return sqlite3_changes(mPtr);
|
||||||
}
|
}
|
||||||
// Attempt to roll back erroneous changes
|
// Attempt to roll back erroneous changes
|
||||||
else if ((mStatus = sqlite3_exec(mPtr, "ROLLBACK", NULL, NULL, NULL)) != SQLITE_OK)
|
else if ((mStatus = sqlite3_exec(mPtr, "ROLLBACK", nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
STHROWF("Unable to rollback flush transaction [%s]", sqlite3_errmsg(mPtr));
|
STHROWF("Unable to rollback flush transaction [%s]", sqlite3_errmsg(mPtr));
|
||||||
}
|
}
|
||||||
@ -250,16 +388,22 @@ StmtHnd::Handle::~Handle()
|
|||||||
{
|
{
|
||||||
// Is there anything to finalize?
|
// Is there anything to finalize?
|
||||||
if (!mPtr)
|
if (!mPtr)
|
||||||
|
{
|
||||||
return; // Nothing to finalize
|
return; // Nothing to finalize
|
||||||
|
}
|
||||||
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
|
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
|
||||||
else if (mRef != 0)
|
else if (mRef != 0)
|
||||||
|
{
|
||||||
// Should we deal with undefined behavior instead? How bad is one statement left alive?
|
// Should we deal with undefined behavior instead? How bad is one statement left alive?
|
||||||
_SqMod->LogErr("SQLite statement is still referenced (%s)", mQuery.c_str());
|
_SqMod->LogErr("SQLite statement is still referenced (%s)", mQuery.c_str());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Attempt to finalize the statement
|
// Attempt to finalize the statement
|
||||||
if ((sqlite3_finalize(mPtr)) != SQLITE_OK)
|
if ((sqlite3_finalize(mPtr)) != SQLITE_OK)
|
||||||
|
{
|
||||||
_SqMod->LogErr("Unable to finalize SQLite statement [%s]", mConn.ErrMsg());
|
_SqMod->LogErr("Unable to finalize SQLite statement [%s]", mConn.ErrMsg());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,29 +412,37 @@ void StmtHnd::Handle::Create(CSStr query)
|
|||||||
{
|
{
|
||||||
// Make sure a previous statement doesn't exist
|
// Make sure a previous statement doesn't exist
|
||||||
if (mPtr)
|
if (mPtr)
|
||||||
|
{
|
||||||
STHROWF("Unable to prepare statement. Statement already prepared");
|
STHROWF("Unable to prepare statement. Statement already prepared");
|
||||||
|
}
|
||||||
// Is the specified database connection is valid?
|
// Is the specified database connection is valid?
|
||||||
else if (!mConn)
|
else if (!mConn)
|
||||||
|
{
|
||||||
STHROWF("Unable to prepare statement. Invalid connection handle");
|
STHROWF("Unable to prepare statement. Invalid connection handle");
|
||||||
|
}
|
||||||
// Save the query string and therefore multiple strlen(...) calls
|
// Save the query string and therefore multiple strlen(...) calls
|
||||||
mQuery.assign(query ? query : _SC(""));
|
mQuery.assign(query ? query : _SC(""));
|
||||||
// Is the specified query string we just saved, valid?
|
// Is the specified query string we just saved, valid?
|
||||||
if (mQuery.empty())
|
if (mQuery.empty())
|
||||||
|
{
|
||||||
STHROWF("Unable to prepare statement. Invalid query string");
|
STHROWF("Unable to prepare statement. Invalid query string");
|
||||||
|
}
|
||||||
// Attempt to prepare a statement with the specified query string
|
// Attempt to prepare a statement with the specified query string
|
||||||
else if ((mStatus = sqlite3_prepare_v2(mConn, mQuery.c_str(), (Int32)mQuery.size(),
|
else if ((mStatus = sqlite3_prepare_v2(mConn, mQuery.c_str(), (Int32)mQuery.size(),
|
||||||
&mPtr, NULL)) != SQLITE_OK)
|
&mPtr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// Clear the query string since it failed
|
// Clear the query string since it failed
|
||||||
mQuery.clear();
|
mQuery.clear();
|
||||||
// Explicitly make sure the handle is null
|
// Explicitly make sure the handle is null
|
||||||
mPtr = NULL;
|
mPtr = nullptr;
|
||||||
// Now it's safe to throw the error
|
// Now it's safe to throw the error
|
||||||
STHROWF("Unable to prepare statement [%s]", mConn.ErrMsg());
|
STHROWF("Unable to prepare statement [%s]", mConn.ErrMsg());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// Obtain the number of available columns
|
// Obtain the number of available columns
|
||||||
mColumns = sqlite3_column_count(mPtr);
|
mColumns = sqlite3_column_count(mPtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -298,7 +450,9 @@ Int32 StmtHnd::Handle::GetColumnIndex(CSStr name)
|
|||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
if (!mPtr)
|
if (!mPtr)
|
||||||
|
{
|
||||||
STHROWF("Invalid SQLite statement");
|
STHROWF("Invalid SQLite statement");
|
||||||
|
}
|
||||||
// Are the names cached?
|
// Are the names cached?
|
||||||
else if (mIndexes.empty())
|
else if (mIndexes.empty())
|
||||||
{
|
{
|
||||||
@ -308,17 +462,23 @@ Int32 StmtHnd::Handle::GetColumnIndex(CSStr name)
|
|||||||
CSStr name = (CSStr)sqlite3_column_name(mPtr, i);
|
CSStr name = (CSStr)sqlite3_column_name(mPtr, i);
|
||||||
// Validate the name
|
// Validate the name
|
||||||
if (!name)
|
if (!name)
|
||||||
|
{
|
||||||
STHROWF("Unable to retrieve column name for index (%d)", i);
|
STHROWF("Unable to retrieve column name for index (%d)", i);
|
||||||
|
}
|
||||||
// Save it to guarantee the same lifetime as this instance
|
// Save it to guarantee the same lifetime as this instance
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mIndexes[name] = i;
|
mIndexes[name] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Attempt to find the specified column
|
// Attempt to find the specified column
|
||||||
const Indexes::iterator itr = mIndexes.find(name);
|
const Indexes::iterator itr = mIndexes.find(name);
|
||||||
// Was there a column with the specified name?
|
// Was there a column with the specified name?
|
||||||
if (itr != mIndexes.end())
|
if (itr != mIndexes.end())
|
||||||
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
|
}
|
||||||
// No such column exists (expecting the invoker to validate the result)
|
// No such column exists (expecting the invoker to validate the result)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -340,7 +500,7 @@ Transaction::Transaction(const ConnHnd & db)
|
|||||||
STHROWF("Invalid connection handle");
|
STHROWF("Invalid connection handle");
|
||||||
}
|
}
|
||||||
// Attempt to begin transaction
|
// Attempt to begin transaction
|
||||||
else if ((m_Connection = sqlite3_exec(m_Connection, "BEGIN", NULL, NULL, NULL)) != SQLITE_OK)
|
else if ((m_Connection = sqlite3_exec(m_Connection, "BEGIN", nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
STHROWF("Unable to begin transaction [%s]", m_Connection.ErrMsg());
|
STHROWF("Unable to begin transaction [%s]", m_Connection.ErrMsg());
|
||||||
}
|
}
|
||||||
@ -355,7 +515,7 @@ Transaction::~Transaction()
|
|||||||
return; // We're done here!
|
return; // We're done here!
|
||||||
}
|
}
|
||||||
// Attempt to roll back changes because this failed to commit
|
// Attempt to roll back changes because this failed to commit
|
||||||
if ((m_Connection = sqlite3_exec(m_Connection, "ROLLBACK", NULL, NULL, NULL)) != SQLITE_OK)
|
if ((m_Connection = sqlite3_exec(m_Connection, "ROLLBACK", nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
STHROWF("Unable to rollback transaction [%s]", m_Connection.ErrMsg());
|
STHROWF("Unable to rollback transaction [%s]", m_Connection.ErrMsg());
|
||||||
}
|
}
|
||||||
@ -375,7 +535,7 @@ bool Transaction::Commit()
|
|||||||
STHROWF("Transaction was already committed");
|
STHROWF("Transaction was already committed");
|
||||||
}
|
}
|
||||||
// Attempt to commit the change during this transaction
|
// Attempt to commit the change during this transaction
|
||||||
else if ((m_Connection = sqlite3_exec(m_Connection, "COMMIT", NULL, NULL, NULL)) != SQLITE_OK)
|
else if ((m_Connection = sqlite3_exec(m_Connection, "COMMIT", nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
STHROWF("Unable to commit transaction [%s]", m_Connection.ErrMsg());
|
STHROWF("Unable to commit transaction [%s]", m_Connection.ErrMsg());
|
||||||
}
|
}
|
||||||
@ -432,7 +592,9 @@ CSStr EscapeString(CSStr str)
|
|||||||
{
|
{
|
||||||
// Is there even a string to escape?
|
// Is there even a string to escape?
|
||||||
if (!str)
|
if (!str)
|
||||||
|
{
|
||||||
return _SC(""); // Default to empty string
|
return _SC(""); // Default to empty string
|
||||||
|
}
|
||||||
// Attempt to escape the specified string
|
// Attempt to escape the specified string
|
||||||
sqlite3_snprintf(sizeof(g_Buffer), g_Buffer, "%q", str);
|
sqlite3_snprintf(sizeof(g_Buffer), g_Buffer, "%q", str);
|
||||||
// Return the resulted string
|
// Return the resulted string
|
||||||
@ -445,15 +607,15 @@ CCStr EscapeStringEx(SQChar spec, CCStr str)
|
|||||||
// Utility that allows changing the format specifier temporarily
|
// Utility that allows changing the format specifier temporarily
|
||||||
static SQChar fs[] = _SC("%q");
|
static SQChar fs[] = _SC("%q");
|
||||||
// Validate the specified format specifier
|
// Validate the specified format specifier
|
||||||
if (spec != 'q' && spec != 'Q' && spec != 'w' && spec != 's')
|
if ((spec != 'q') && (spec != 'Q') && (spec != 'w') && (spec != 's'))
|
||||||
{
|
{
|
||||||
STHROWF("Unknown format specifier: %c", spec);
|
STHROWF("Unknown format specifier: '%c'", spec);
|
||||||
// Default to empty string
|
|
||||||
return _SC("");
|
|
||||||
}
|
}
|
||||||
// Is there even a string to escape?
|
// Is there even a string to escape?
|
||||||
else if (!str)
|
else if (!str)
|
||||||
|
{
|
||||||
return _SC(""); // Default to empty string
|
return _SC(""); // Default to empty string
|
||||||
|
}
|
||||||
// Apply the format specifier
|
// Apply the format specifier
|
||||||
fs[1] = spec;
|
fs[1] = spec;
|
||||||
// Attempt to escape the specified string
|
// Attempt to escape the specified string
|
||||||
@ -469,7 +631,9 @@ CCStr ArrayToQueryColumns(Array & arr)
|
|||||||
{
|
{
|
||||||
// Do we even have any elements to process?
|
// Do we even have any elements to process?
|
||||||
if (arr.Length() <= 0)
|
if (arr.Length() <= 0)
|
||||||
|
{
|
||||||
return _SC(""); // Default to empty string
|
return _SC(""); // Default to empty string
|
||||||
|
}
|
||||||
// Allocate a vector with the required amount of column names
|
// Allocate a vector with the required amount of column names
|
||||||
std::vector< String > values(arr.Length());
|
std::vector< String > values(arr.Length());
|
||||||
// Attempt to extract the array elements as strings
|
// Attempt to extract the array elements as strings
|
||||||
@ -483,7 +647,9 @@ CCStr ArrayToQueryColumns(Array & arr)
|
|||||||
{
|
{
|
||||||
// Is the name valid?
|
// Is the name valid?
|
||||||
if (itr->empty())
|
if (itr->empty())
|
||||||
|
{
|
||||||
STHROWF("Invalid column name");
|
STHROWF("Invalid column name");
|
||||||
|
}
|
||||||
// Attempt to append the column name to the buffer
|
// Attempt to append the column name to the buffer
|
||||||
sqlite3_snprintf(sizeof(g_Buffer) - offset, g_Buffer + offset, "[%q], ", itr->c_str());
|
sqlite3_snprintf(sizeof(g_Buffer) - offset, g_Buffer + offset, "[%q], ", itr->c_str());
|
||||||
// Add the column name size to the offset
|
// Add the column name size to the offset
|
||||||
@ -493,9 +659,13 @@ CCStr ArrayToQueryColumns(Array & arr)
|
|||||||
}
|
}
|
||||||
// Trim the last coma and space
|
// Trim the last coma and space
|
||||||
if (offset >= 2)
|
if (offset >= 2)
|
||||||
g_Buffer[offset-2] = 0;
|
{
|
||||||
|
g_Buffer[offset-2] = '\0';
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_Buffer[0] = 0;
|
{
|
||||||
|
g_Buffer[0] = '\0';
|
||||||
|
}
|
||||||
// Return the resulted string
|
// Return the resulted string
|
||||||
return g_Buffer;
|
return g_Buffer;
|
||||||
}
|
}
|
||||||
@ -516,7 +686,9 @@ CCStr TableToQueryColumns(Table & tbl)
|
|||||||
name.assign(itr.getName());
|
name.assign(itr.getName());
|
||||||
// Is the name valid?
|
// Is the name valid?
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
|
{
|
||||||
STHROWF("Invalid or empty column name");
|
STHROWF("Invalid or empty column name");
|
||||||
|
}
|
||||||
// Attempt to append the column name to the buffer
|
// Attempt to append the column name to the buffer
|
||||||
sqlite3_snprintf(sizeof(g_Buffer) - offset, g_Buffer + offset, "[%q], ", name.c_str());
|
sqlite3_snprintf(sizeof(g_Buffer) - offset, g_Buffer + offset, "[%q], ", name.c_str());
|
||||||
// Add the column name size to the offset
|
// Add the column name size to the offset
|
||||||
@ -526,9 +698,13 @@ CCStr TableToQueryColumns(Table & tbl)
|
|||||||
}
|
}
|
||||||
// Trim the last coma and space
|
// Trim the last coma and space
|
||||||
if (offset >= 2)
|
if (offset >= 2)
|
||||||
g_Buffer[offset-2] = 0;
|
{
|
||||||
|
g_Buffer[offset-2] = '\0';
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_Buffer[0] = 0;
|
{
|
||||||
|
g_Buffer[0] = '\0';
|
||||||
|
}
|
||||||
// Return the resulted string
|
// Return the resulted string
|
||||||
return g_Buffer;
|
return g_Buffer;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
#include <squirrel.h>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
namespace SqMod {
|
namespace SqMod {
|
||||||
@ -73,6 +74,11 @@ bool IsQueryEmpty(CSStr str);
|
|||||||
*/
|
*/
|
||||||
struct StackGuard
|
struct StackGuard
|
||||||
{
|
{
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
StackGuard();
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Base constructor.
|
* Base constructor.
|
||||||
*/
|
*/
|
||||||
@ -108,8 +114,51 @@ private:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Int32 m_Top; /* The top of the stack when this instance was created. */
|
HSQUIRRELVM m_VM; // The VM where the stack should be restored.
|
||||||
HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
|
Int32 m_Top; // The top of the stack when this instance was created.
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* Helper structure for retrieving a value from the stack as a string or a formatted string.
|
||||||
|
*/
|
||||||
|
struct StackStrF
|
||||||
|
{
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
CSStr mPtr; // Pointer to the C string that was retrieved.
|
||||||
|
SQInteger mLen; // The string length if it could be retrieved.
|
||||||
|
SQRESULT mRes; // The result of the retrieval attempts.
|
||||||
|
HSQOBJECT mObj; // Strong reference to the string object.
|
||||||
|
HSQUIRRELVM mVM; // The associated virtual machine.
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Base constructor.
|
||||||
|
*/
|
||||||
|
StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor. (disabled)
|
||||||
|
*/
|
||||||
|
StackStrF(const StackStrF & o) = delete;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor. (disabled)
|
||||||
|
*/
|
||||||
|
StackStrF(StackStrF && o) = delete;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
~StackStrF();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor. (disabled)
|
||||||
|
*/
|
||||||
|
StackStrF & operator = (const StackStrF & o) = delete;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor. (disabled)
|
||||||
|
*/
|
||||||
|
StackStrF & operator = (StackStrF && o) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
@ -137,6 +186,11 @@ public:
|
|||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
typedef unsigned int Counter; // Reference counter type.
|
typedef unsigned int Counter; // Reference counter type.
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Validate the connection handle and throw an error if invalid.
|
||||||
|
*/
|
||||||
|
void Validate() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
@ -171,7 +225,7 @@ protected:
|
|||||||
* Base constructor.
|
* Base constructor.
|
||||||
*/
|
*/
|
||||||
Handle(Counter counter)
|
Handle(Counter counter)
|
||||||
: mPtr(NULL)
|
: mPtr(nullptr)
|
||||||
, mRef(counter)
|
, mRef(counter)
|
||||||
, mStatus(SQLITE_OK)
|
, mStatus(SQLITE_OK)
|
||||||
, mQueue()
|
, mQueue()
|
||||||
@ -232,7 +286,7 @@ private:
|
|||||||
* Base constructor.
|
* Base constructor.
|
||||||
*/
|
*/
|
||||||
ConnHnd(CSStr name)
|
ConnHnd(CSStr name)
|
||||||
: m_Hnd(name ? new Handle(1) : NULL)
|
: m_Hnd(name ? new Handle(1) : nullptr)
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -243,7 +297,7 @@ public:
|
|||||||
* Default constructor (null).
|
* Default constructor (null).
|
||||||
*/
|
*/
|
||||||
ConnHnd()
|
ConnHnd()
|
||||||
: m_Hnd(NULL)
|
: m_Hnd(nullptr)
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -263,7 +317,7 @@ public:
|
|||||||
ConnHnd(ConnHnd && o)
|
ConnHnd(ConnHnd && o)
|
||||||
: m_Hnd(o.m_Hnd)
|
: m_Hnd(o.m_Hnd)
|
||||||
{
|
{
|
||||||
o.m_Hnd = NULL;
|
o.m_Hnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -296,7 +350,7 @@ public:
|
|||||||
if (m_Hnd != o.m_Hnd)
|
if (m_Hnd != o.m_Hnd)
|
||||||
{
|
{
|
||||||
m_Hnd = o.m_Hnd;
|
m_Hnd = o.m_Hnd;
|
||||||
o.m_Hnd = NULL;
|
o.m_Hnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -367,7 +421,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
operator Pointer ()
|
operator Pointer ()
|
||||||
{
|
{
|
||||||
return m_Hnd ? m_Hnd->mPtr : NULL;
|
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -375,7 +429,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
operator Pointer () const
|
operator Pointer () const
|
||||||
{
|
{
|
||||||
return m_Hnd ? m_Hnd->mPtr : NULL;
|
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -524,6 +578,11 @@ public:
|
|||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
typedef unsigned int Counter; // Reference counter type.
|
typedef unsigned int Counter; // Reference counter type.
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Validate the statement handle and throw an error if invalid.
|
||||||
|
*/
|
||||||
|
void Validate() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
@ -559,7 +618,7 @@ protected:
|
|||||||
* Base constructor.
|
* Base constructor.
|
||||||
*/
|
*/
|
||||||
Handle(const ConnHnd & conn, Counter counter)
|
Handle(const ConnHnd & conn, Counter counter)
|
||||||
: mPtr(NULL)
|
: mPtr(nullptr)
|
||||||
, mRef(counter)
|
, mRef(counter)
|
||||||
, mStatus(SQLITE_OK)
|
, mStatus(SQLITE_OK)
|
||||||
, mConn(conn)
|
, mConn(conn)
|
||||||
@ -638,7 +697,7 @@ public:
|
|||||||
* Default constructor (null).
|
* Default constructor (null).
|
||||||
*/
|
*/
|
||||||
StmtHnd()
|
StmtHnd()
|
||||||
: m_Hnd(NULL)
|
: m_Hnd(nullptr)
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -659,7 +718,7 @@ public:
|
|||||||
StmtHnd(StmtHnd && o)
|
StmtHnd(StmtHnd && o)
|
||||||
: m_Hnd(o.m_Hnd)
|
: m_Hnd(o.m_Hnd)
|
||||||
{
|
{
|
||||||
o.m_Hnd = NULL;
|
o.m_Hnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -692,7 +751,7 @@ public:
|
|||||||
if (m_Hnd != o.m_Hnd)
|
if (m_Hnd != o.m_Hnd)
|
||||||
{
|
{
|
||||||
m_Hnd = o.m_Hnd;
|
m_Hnd = o.m_Hnd;
|
||||||
o.m_Hnd = NULL;
|
o.m_Hnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -763,7 +822,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
operator Pointer ()
|
operator Pointer ()
|
||||||
{
|
{
|
||||||
return m_Hnd ? m_Hnd->mPtr : NULL;
|
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -771,7 +830,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
operator Pointer () const
|
operator Pointer () const
|
||||||
{
|
{
|
||||||
return m_Hnd ? m_Hnd->mPtr : NULL;
|
return m_Hnd ? m_Hnd->mPtr : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
@ -17,14 +17,6 @@ SQInteger Connection::Typename(HSQUIRRELVM vm)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void Connection::Validate() const
|
|
||||||
{
|
|
||||||
// Is the handle valid?
|
|
||||||
if (!m_Handle)
|
|
||||||
STHROWF("Invalid SQLite connection reference");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Connection::Connection()
|
Connection::Connection()
|
||||||
: m_Handle()
|
: m_Handle()
|
||||||
@ -37,7 +29,9 @@ Connection::Connection(CSStr name)
|
|||||||
: m_Handle(name)
|
: m_Handle(name)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
{
|
||||||
|
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -45,7 +39,9 @@ Connection::Connection(CSStr name, Int32 flags)
|
|||||||
: m_Handle(name)
|
: m_Handle(name)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
m_Handle->Create(name, flags, NULL);
|
{
|
||||||
|
m_Handle->Create(name, flags, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -53,17 +49,21 @@ Connection::Connection(CSStr name, Int32 flags, CSStr vfs)
|
|||||||
: m_Handle(name)
|
: m_Handle(name)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
|
{
|
||||||
m_Handle->Create(name, flags, vfs);
|
m_Handle->Create(name, flags, vfs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Int32 Connection::Exec(CSStr str)
|
Int32 Connection::Exec(CSStr str)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to execute the specified query
|
// Attempt to execute the specified query
|
||||||
if ((m_Handle = sqlite3_exec(m_Handle, str, NULL, NULL, NULL)) != SQLITE_OK)
|
if ((m_Handle = sqlite3_exec(m_Handle, str, nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
|
{
|
||||||
STHROWF("Unable to execute query [%s]", m_Handle.ErrMsg());
|
STHROWF("Unable to execute query [%s]", m_Handle.ErrMsg());
|
||||||
|
}
|
||||||
// Return rows affected by this query
|
// Return rows affected by this query
|
||||||
return sqlite3_changes(m_Handle);
|
return sqlite3_changes(m_Handle);
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ Int32 Connection::Exec(CSStr str)
|
|||||||
Object Connection::Query(CSStr str) const
|
Object Connection::Query(CSStr str) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return Object(new Statement(m_Handle, str));
|
return Object(new Statement(m_Handle, str));
|
||||||
}
|
}
|
||||||
@ -81,10 +81,12 @@ Object Connection::Query(CSStr str) const
|
|||||||
void Connection::Queue(CSStr str)
|
void Connection::Queue(CSStr str)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Is there a query to commit?
|
// Is there a query to commit?
|
||||||
if (IsQueryEmpty(str))
|
if (IsQueryEmpty(str))
|
||||||
|
{
|
||||||
STHROWF("No query string to queue");
|
STHROWF("No query string to queue");
|
||||||
|
}
|
||||||
// Add the specified string to the queue
|
// Add the specified string to the queue
|
||||||
m_Handle->mQueue.push_back(str);
|
m_Handle->mQueue.push_back(str);
|
||||||
}
|
}
|
||||||
@ -93,12 +95,14 @@ void Connection::Queue(CSStr str)
|
|||||||
bool Connection::IsReadOnly() const
|
bool Connection::IsReadOnly() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Request the desired information
|
// Request the desired information
|
||||||
const int result = sqlite3_db_readonly(m_Handle, "main");
|
const int result = sqlite3_db_readonly(m_Handle, "main");
|
||||||
// Verify the result
|
// Verify the result
|
||||||
if (result == -1)
|
if (result == -1)
|
||||||
|
{
|
||||||
STHROWF("'main' is not the name of a database on connection");
|
STHROWF("'main' is not the name of a database on connection");
|
||||||
|
}
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return (result != 1);
|
return (result != 1);
|
||||||
}
|
}
|
||||||
@ -107,7 +111,7 @@ bool Connection::IsReadOnly() const
|
|||||||
bool Connection::TableExists(CCStr name) const
|
bool Connection::TableExists(CCStr name) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Prepare a statement to inspect the master table
|
// Prepare a statement to inspect the master table
|
||||||
Statement stmt(m_Handle, "SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
|
Statement stmt(m_Handle, "SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
|
||||||
// Could the statement be created?
|
// Could the statement be created?
|
||||||
@ -117,7 +121,9 @@ bool Connection::TableExists(CCStr name) const
|
|||||||
stmt.IndexBindS(1, name);
|
stmt.IndexBindS(1, name);
|
||||||
// Attempt to step the statement and obtain a value
|
// Attempt to step the statement and obtain a value
|
||||||
if (stmt.Step())
|
if (stmt.Step())
|
||||||
|
{
|
||||||
return (sqlite3_column_int(stmt, 0) == 1);
|
return (sqlite3_column_int(stmt, 0) == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Assume it doesn't exist
|
// Assume it doesn't exist
|
||||||
return false;
|
return false;
|
||||||
@ -127,7 +133,7 @@ bool Connection::TableExists(CCStr name) const
|
|||||||
Object Connection::GetLastInsertRowID() const
|
Object Connection::GetLastInsertRowID() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const StackGuard sg(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Push a long integer instance with the requested value on the stack
|
// Push a long integer instance with the requested value on the stack
|
||||||
@ -140,26 +146,32 @@ Object Connection::GetLastInsertRowID() const
|
|||||||
void Connection::SetBusyTimeout(Int32 millis)
|
void Connection::SetBusyTimeout(Int32 millis)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Apply requested timeout
|
// Apply requested timeout
|
||||||
if ((m_Handle = sqlite3_busy_timeout(m_Handle, millis)) != SQLITE_OK)
|
if ((m_Handle = sqlite3_busy_timeout(m_Handle, millis)) != SQLITE_OK)
|
||||||
|
{
|
||||||
STHROWF("Unable to set busy timeout [%s]", m_Handle.ErrMsg());
|
STHROWF("Unable to set busy timeout [%s]", m_Handle.ErrMsg());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
|
Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
|
||||||
{
|
{
|
||||||
// Don't even bother to continue if there's no valid connection handle
|
// Don't even bother to continue if there's no valid connection handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Where to retrieve the information
|
// Where to retrieve the information
|
||||||
Int32 cur_value;
|
Int32 cur_value;
|
||||||
Int32 hiwtr_value;
|
Int32 hiwtr_value;
|
||||||
// Attempt to retrieve the specified information
|
// Attempt to retrieve the specified information
|
||||||
if ((m_Handle = sqlite3_db_status(m_Handle, operation, &cur_value, &hiwtr_value, reset)) != SQLITE_OK)
|
if ((m_Handle = sqlite3_db_status(m_Handle, operation, &cur_value, &hiwtr_value, reset)) != SQLITE_OK)
|
||||||
|
{
|
||||||
STHROWF("Unable to get runtime status information", m_Handle.ErrMsg());
|
STHROWF("Unable to get runtime status information", m_Handle.ErrMsg());
|
||||||
|
}
|
||||||
// Return the high-water value if requested
|
// Return the high-water value if requested
|
||||||
else if (highwater)
|
else if (highwater)
|
||||||
|
{
|
||||||
return hiwtr_value;
|
return hiwtr_value;
|
||||||
|
}
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return cur_value;
|
return cur_value;
|
||||||
}
|
}
|
||||||
@ -168,7 +180,7 @@ Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
|
|||||||
void Connection::ReserveQueue(Uint32 num)
|
void Connection::ReserveQueue(Uint32 num)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested operation
|
// Perform the requested operation
|
||||||
m_Handle->mQueue.reserve(m_Handle->mQueue.size() + num);
|
m_Handle->mQueue.reserve(m_Handle->mQueue.size() + num);
|
||||||
}
|
}
|
||||||
@ -177,7 +189,7 @@ void Connection::ReserveQueue(Uint32 num)
|
|||||||
Int32 Connection::Flush(Uint32 num)
|
Int32 Connection::Flush(Uint32 num)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// We need to supply a null callback
|
// We need to supply a null callback
|
||||||
Object env;
|
Object env;
|
||||||
Function func;
|
Function func;
|
||||||
@ -189,7 +201,7 @@ Int32 Connection::Flush(Uint32 num)
|
|||||||
Int32 Connection::Flush(Uint32 num, Object & env, Function & func)
|
Int32 Connection::Flush(Uint32 num, Object & env, Function & func)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to flush the requested amount of queries
|
// Attempt to flush the requested amount of queries
|
||||||
return m_Handle->Flush(num, env, func);
|
return m_Handle->Flush(num, env, func);
|
||||||
}
|
}
|
||||||
@ -232,56 +244,21 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
|||||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||||
}
|
}
|
||||||
// Do we have a valid connection identifier?
|
// Do we have a valid connection identifier?
|
||||||
else if (!conn->m_Handle)
|
else if (!(conn->m_Handle))
|
||||||
{
|
{
|
||||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||||
}
|
}
|
||||||
// Do we have enough values to call the format function?
|
// Attempt to retrieve the value from the stack as a string
|
||||||
else if (top > 2)
|
StackStrF val(vm, 2);
|
||||||
|
// Have we failed to retrieve the string?
|
||||||
|
if (SQ_FAILED(val.mRes))
|
||||||
{
|
{
|
||||||
SStr sql = NULL;
|
return val.mRes; // Propagate the error!
|
||||||
SQInteger len = 0;
|
|
||||||
// Attempt to generate the specified string format
|
|
||||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
|
||||||
// Did the format failed?
|
|
||||||
if (SQ_FAILED(ret))
|
|
||||||
{
|
|
||||||
return ret; // Propagate the exception
|
|
||||||
}
|
|
||||||
// Attempt to execute the specified query
|
|
||||||
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// Generate the query message first
|
|
||||||
String msg("Unable to execute query ");
|
|
||||||
// (we can't use FmtStr here because Squirrel doesn't make a copy of the message)
|
|
||||||
msg.push_back('[');
|
|
||||||
msg.append(conn->m_Handle.ErrMsg());
|
|
||||||
msg.push_back(']');
|
|
||||||
// Now throw the message
|
|
||||||
return sq_throwerror(vm, msg.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
// Attempt to execute the specified query
|
||||||
|
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, val.mPtr, nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// Attempt to retrieve the value from the stack as a string
|
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", conn->m_Handle.ErrMsg()));
|
||||||
Var< CSStr > sql(vm, 2);
|
|
||||||
// See if the obtained value is a valid query string
|
|
||||||
if (!sql.value)
|
|
||||||
{
|
|
||||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
|
||||||
}
|
|
||||||
// Attempt to execute the specified query
|
|
||||||
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, sql.value, NULL, NULL, NULL)) != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// Generate the query message first
|
|
||||||
String msg("Unable to execute query ");
|
|
||||||
// (we can't use FmtStr here because Squirrel doesn't make a copy of the message)
|
|
||||||
msg.push_back('[');
|
|
||||||
msg.append(conn->m_Handle.ErrMsg());
|
|
||||||
msg.push_back(']');
|
|
||||||
// Now throw the message
|
|
||||||
return sq_throwerror(vm, msg.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Push the number of changes onto the stack
|
// Push the number of changes onto the stack
|
||||||
sq_pushinteger(vm, sqlite3_changes(conn->m_Handle));
|
sq_pushinteger(vm, sqlite3_changes(conn->m_Handle));
|
||||||
@ -316,37 +293,19 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
|
|||||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||||
}
|
}
|
||||||
// Do we have a valid connection identifier?
|
// Do we have a valid connection identifier?
|
||||||
else if (!conn->m_Handle)
|
else if (!(conn->m_Handle))
|
||||||
{
|
{
|
||||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||||
}
|
}
|
||||||
// Do we have enough values to call the format function?
|
// Attempt to retrieve the value from the stack as a string
|
||||||
else if (top > 2)
|
StackStrF val(vm, 2);
|
||||||
|
// Have we failed to retrieve the string?
|
||||||
|
if (SQ_FAILED(val.mRes))
|
||||||
{
|
{
|
||||||
SStr sql = NULL;
|
return val.mRes; // Propagate the error!
|
||||||
SQInteger len = 0;
|
|
||||||
// Attempt to generate the specified string format
|
|
||||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
|
||||||
// Did the format failed?
|
|
||||||
if (SQ_FAILED(ret))
|
|
||||||
{
|
|
||||||
return ret; // Propagate the exception
|
|
||||||
}
|
|
||||||
// Attempt to queue the specified query
|
|
||||||
conn->m_Handle->mQueue.emplace_back(sql);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Attempt to retrieve the value from the stack as a string
|
|
||||||
Var< CSStr > sql(vm, 2);
|
|
||||||
// See if the obtained value is a valid query string
|
|
||||||
if (!sql.value)
|
|
||||||
{
|
|
||||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
|
||||||
}
|
|
||||||
// Attempt to queue the specified query
|
|
||||||
conn->m_Handle->mQueue.emplace_back(sql.value);
|
|
||||||
}
|
}
|
||||||
|
// Attempt to queue the specified query
|
||||||
|
conn->m_Handle->mQueue.emplace_back(val.mPtr);
|
||||||
// This function does not return a value
|
// This function does not return a value
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -378,50 +337,25 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
|
|||||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||||
}
|
}
|
||||||
// Do we have a valid connection identifier?
|
// Do we have a valid connection identifier?
|
||||||
else if (!conn->m_Handle)
|
else if (!(conn->m_Handle))
|
||||||
{
|
{
|
||||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||||
}
|
}
|
||||||
// Do we have enough values to call the format function?
|
// Attempt to retrieve the value from the stack as a string
|
||||||
else if (top > 2)
|
StackStrF val(vm, 2);
|
||||||
|
// Have we failed to retrieve the string?
|
||||||
|
if (SQ_FAILED(val.mRes))
|
||||||
{
|
{
|
||||||
SStr sql = NULL;
|
return val.mRes; // Propagate the error!
|
||||||
SQInteger len = 0;
|
|
||||||
// Attempt to generate the specified string format
|
|
||||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
|
||||||
// Did the format failed?
|
|
||||||
if (SQ_FAILED(ret))
|
|
||||||
{
|
|
||||||
return ret; // Propagate the exception
|
|
||||||
}
|
|
||||||
// Attempt to create a statement with the specified query
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, sql));
|
|
||||||
}
|
|
||||||
catch (const Sqrat::Exception & e)
|
|
||||||
{
|
|
||||||
return sq_throwerror(vm, e.Message().c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
// Attempt to create a statement with the specified query
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Attempt to retrieve the value from the stack as a string
|
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, val.mPtr));
|
||||||
Var< CSStr > sql(vm, 2);
|
}
|
||||||
// See if the obtained value is a valid query string
|
catch (const Sqrat::Exception & e)
|
||||||
if (!sql.value)
|
{
|
||||||
{
|
return sq_throwerror(vm, e.Message().c_str());
|
||||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
|
||||||
}
|
|
||||||
// Attempt to create a statement with the specified query
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, sql.value));
|
|
||||||
}
|
|
||||||
catch (const Sqrat::Exception & e)
|
|
||||||
{
|
|
||||||
return sq_throwerror(vm, e.Message().c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// This function returned a value
|
// This function returned a value
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -20,15 +20,10 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void Create(CSStr name, Int32 flags, CSStr vfs);
|
void Create(CSStr name, Int32 flags, CSStr vfs);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Validate the document reference and throw an error if invalid.
|
|
||||||
*/
|
|
||||||
void Validate() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
ConnHnd m_Handle; /* The handle to the managed database connection resource. */
|
ConnHnd m_Handle; // The handle to the managed database connection resource.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -125,11 +120,17 @@ public:
|
|||||||
Int32 Cmp(const Connection & o) const
|
Int32 Cmp(const Connection & o) const
|
||||||
{
|
{
|
||||||
if (m_Handle == m_Handle)
|
if (m_Handle == m_Handle)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
|
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -138,7 +139,7 @@ public:
|
|||||||
CSStr ToString() const
|
CSStr ToString() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mName.c_str();
|
return m_Handle->mName.c_str();
|
||||||
}
|
}
|
||||||
@ -186,7 +187,7 @@ public:
|
|||||||
Int32 GetStatus() const
|
Int32 GetStatus() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mStatus;
|
return m_Handle->mStatus;
|
||||||
}
|
}
|
||||||
@ -197,7 +198,7 @@ public:
|
|||||||
Int32 GetFlags() const
|
Int32 GetFlags() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mFlags;
|
return m_Handle->mFlags;
|
||||||
}
|
}
|
||||||
@ -208,7 +209,7 @@ public:
|
|||||||
CSStr GetName() const
|
CSStr GetName() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mName.c_str();
|
return m_Handle->mName.c_str();
|
||||||
}
|
}
|
||||||
@ -219,7 +220,7 @@ public:
|
|||||||
CSStr GetVFS() const
|
CSStr GetVFS() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mVFS.c_str();
|
return m_Handle->mVFS.c_str();
|
||||||
}
|
}
|
||||||
@ -230,7 +231,7 @@ public:
|
|||||||
Int32 GetErrorCode() const
|
Int32 GetErrorCode() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrNo();
|
return m_Handle.ErrNo();
|
||||||
}
|
}
|
||||||
@ -241,7 +242,7 @@ public:
|
|||||||
Int32 GetExtendedErrorCode() const
|
Int32 GetExtendedErrorCode() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ExErrNo();
|
return m_Handle.ExErrNo();
|
||||||
}
|
}
|
||||||
@ -252,7 +253,7 @@ public:
|
|||||||
CSStr GetErrStr() const
|
CSStr GetErrStr() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrStr();
|
return m_Handle.ErrStr();
|
||||||
}
|
}
|
||||||
@ -263,7 +264,7 @@ public:
|
|||||||
CSStr GetErrMsg() const
|
CSStr GetErrMsg() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrMsg();
|
return m_Handle.ErrMsg();
|
||||||
}
|
}
|
||||||
@ -274,7 +275,9 @@ public:
|
|||||||
void Open(CSStr name)
|
void Open(CSStr name)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
{
|
||||||
|
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -283,7 +286,9 @@ public:
|
|||||||
void Open(CSStr name, Int32 flags)
|
void Open(CSStr name, Int32 flags)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
m_Handle->Create(name, flags, NULL);
|
{
|
||||||
|
m_Handle->Create(name, flags, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -292,7 +297,9 @@ public:
|
|||||||
void Open(CSStr name, Int32 flags, CSStr vfs)
|
void Open(CSStr name, Int32 flags, CSStr vfs)
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd)
|
||||||
|
{
|
||||||
m_Handle->Create(name, flags, vfs);
|
m_Handle->Create(name, flags, vfs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -326,7 +333,7 @@ public:
|
|||||||
bool GetAutoCommit() const
|
bool GetAutoCommit() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return sqlite3_get_autocommit(m_Handle);
|
return sqlite3_get_autocommit(m_Handle);
|
||||||
}
|
}
|
||||||
@ -343,7 +350,7 @@ public:
|
|||||||
Int32 GetChanges() const
|
Int32 GetChanges() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return sqlite3_changes(m_Handle);
|
return sqlite3_changes(m_Handle);
|
||||||
}
|
}
|
||||||
@ -355,7 +362,7 @@ public:
|
|||||||
Int32 GetTotalChanges() const
|
Int32 GetTotalChanges() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return sqlite3_total_changes(m_Handle);
|
return sqlite3_total_changes(m_Handle);
|
||||||
}
|
}
|
||||||
@ -366,7 +373,7 @@ public:
|
|||||||
bool GetTracing() const
|
bool GetTracing() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mTrace;
|
return m_Handle->mTrace;
|
||||||
}
|
}
|
||||||
@ -377,16 +384,22 @@ public:
|
|||||||
void SetTracing(bool toggle)
|
void SetTracing(bool toggle)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Check whether changes are necessary
|
// Check whether changes are necessary
|
||||||
if (m_Handle->mTrace == toggle)
|
if (m_Handle->mTrace == toggle)
|
||||||
return; /* No point in proceeding */
|
{
|
||||||
|
return; // No point in proceeding
|
||||||
|
}
|
||||||
// Do we have to disable it?
|
// Do we have to disable it?
|
||||||
else if (m_Handle->mTrace)
|
else if (m_Handle->mTrace)
|
||||||
sqlite3_trace(m_Handle, NULL, NULL);
|
{
|
||||||
|
sqlite3_trace(m_Handle, nullptr, nullptr);
|
||||||
|
}
|
||||||
// Go ahead and enable tracing
|
// Go ahead and enable tracing
|
||||||
else
|
else
|
||||||
sqlite3_trace(m_Handle, &Connection::TraceOutput, NULL);
|
{
|
||||||
|
sqlite3_trace(m_Handle, &Connection::TraceOutput, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -395,7 +408,7 @@ public:
|
|||||||
bool GetProfiling() const
|
bool GetProfiling() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mProfile;
|
return m_Handle->mProfile;
|
||||||
}
|
}
|
||||||
@ -406,16 +419,22 @@ public:
|
|||||||
void SetProfiling(bool toggle)
|
void SetProfiling(bool toggle)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Check whether changes are necessary
|
// Check whether changes are necessary
|
||||||
if (m_Handle->mProfile == toggle)
|
if (m_Handle->mProfile == toggle)
|
||||||
return; /* No point in proceeding */
|
{
|
||||||
|
return; // No point in proceeding
|
||||||
|
}
|
||||||
// Do we have to disable it?
|
// Do we have to disable it?
|
||||||
else if (m_Handle->mProfile)
|
else if (m_Handle->mProfile)
|
||||||
sqlite3_profile(m_Handle, NULL, NULL);
|
{
|
||||||
|
sqlite3_profile(m_Handle, nullptr, nullptr);
|
||||||
|
}
|
||||||
// Go ahead and enable profiling
|
// Go ahead and enable profiling
|
||||||
else
|
else
|
||||||
sqlite3_profile(m_Handle, &Connection::ProfileOutput, NULL);
|
{
|
||||||
|
sqlite3_profile(m_Handle, &Connection::ProfileOutput, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -429,7 +448,7 @@ public:
|
|||||||
void InterruptOperation() const
|
void InterruptOperation() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested action
|
// Perform the requested action
|
||||||
sqlite3_interrupt(m_Handle);
|
sqlite3_interrupt(m_Handle);
|
||||||
}
|
}
|
||||||
@ -440,7 +459,7 @@ public:
|
|||||||
void ReleaseMemory() const
|
void ReleaseMemory() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested action
|
// Perform the requested action
|
||||||
sqlite3_db_release_memory(m_Handle);
|
sqlite3_db_release_memory(m_Handle);
|
||||||
}
|
}
|
||||||
@ -472,7 +491,7 @@ public:
|
|||||||
Uint32 QueueSize() const
|
Uint32 QueueSize() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return (Uint32)m_Handle->mQueue.size();
|
return (Uint32)m_Handle->mQueue.size();
|
||||||
}
|
}
|
||||||
@ -488,7 +507,7 @@ public:
|
|||||||
void CompactQueue()
|
void CompactQueue()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested operation
|
// Perform the requested operation
|
||||||
m_Handle->mQueue.shrink_to_fit();
|
m_Handle->mQueue.shrink_to_fit();
|
||||||
}
|
}
|
||||||
@ -499,7 +518,7 @@ public:
|
|||||||
void ClearQueue()
|
void ClearQueue()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested operation
|
// Perform the requested operation
|
||||||
m_Handle->mQueue.clear();
|
m_Handle->mQueue.clear();
|
||||||
}
|
}
|
||||||
@ -510,10 +529,12 @@ public:
|
|||||||
void PopQueue()
|
void PopQueue()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Perform the requested action
|
// Perform the requested action
|
||||||
if (!m_Handle->mQueue.empty())
|
if (!m_Handle->mQueue.empty())
|
||||||
|
{
|
||||||
m_Handle->mQueue.pop_back();
|
m_Handle->mQueue.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -522,7 +543,7 @@ public:
|
|||||||
Int32 Flush()
|
Int32 Flush()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return Flush(m_Handle->mQueue.size());
|
return Flush(m_Handle->mQueue.size());
|
||||||
}
|
}
|
||||||
@ -538,7 +559,7 @@ public:
|
|||||||
Int32 Flush(Object & env, Function & func)
|
Int32 Flush(Object & env, Function & func)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return Flush(m_Handle->mQueue.size(), env, func);
|
return Flush(m_Handle->mQueue.size(), env, func);
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#include "Column.hpp"
|
#include "Column.hpp"
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
#include <sqrat.h>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
#include <stdio.h>
|
#include <sqrat.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
#if defined(WIN32) || defined(_WIN32)
|
#if defined(WIN32) || defined(_WIN32)
|
||||||
@ -21,14 +21,14 @@
|
|||||||
namespace SqMod {
|
namespace SqMod {
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
PluginFuncs* _Func = NULL;
|
PluginFuncs* _Func = nullptr;
|
||||||
PluginCallbacks* _Clbk = NULL;
|
PluginCallbacks* _Clbk = nullptr;
|
||||||
PluginInfo* _Info = NULL;
|
PluginInfo* _Info = nullptr;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
HSQAPI _SqAPI = NULL;
|
HSQAPI _SqAPI = nullptr;
|
||||||
HSQEXPORTS _SqMod = NULL;
|
HSQEXPORTS _SqMod = nullptr;
|
||||||
HSQUIRRELVM _SqVM = NULL;
|
HSQUIRRELVM _SqVM = nullptr;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Bind speciffic functions to certain server events.
|
* Bind speciffic functions to certain server events.
|
||||||
@ -54,7 +54,9 @@ void OnSquirrelInitialize()
|
|||||||
_SqMod = sq_api_import(_Func);
|
_SqMod = sq_api_import(_Func);
|
||||||
// Did we failed to obtain the plugin exports?
|
// Did we failed to obtain the plugin exports?
|
||||||
if(!_SqMod)
|
if(!_SqMod)
|
||||||
|
{
|
||||||
OutputError("Failed to attach [%s] on host plugin.", SQSQLITE_NAME);
|
OutputError("Failed to attach [%s] on host plugin.", SQSQLITE_NAME);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Obtain the Squirrel API
|
// Obtain the Squirrel API
|
||||||
@ -71,12 +73,16 @@ void OnSquirrelLoad()
|
|||||||
{
|
{
|
||||||
// Make sure that we have a valid plugin API
|
// Make sure that we have a valid plugin API
|
||||||
if (!_SqMod)
|
if (!_SqMod)
|
||||||
return; /* Unable to proceed. */
|
{
|
||||||
|
return; // Unable to proceed.
|
||||||
|
}
|
||||||
// Obtain the Squirrel API and VM
|
// Obtain the Squirrel API and VM
|
||||||
_SqVM = _SqMod->GetSquirrelVM();
|
_SqVM = _SqMod->GetSquirrelVM();
|
||||||
// Make sure that a valid virtual machine exists
|
// Make sure that a valid virtual machine exists
|
||||||
if (!_SqVM)
|
if (!_SqVM)
|
||||||
return; /* Unable to proceed. */
|
{
|
||||||
|
return; // Unable to proceed.
|
||||||
|
}
|
||||||
// Set this as the default database
|
// Set this as the default database
|
||||||
DefaultVM::Set(_SqVM);
|
DefaultVM::Set(_SqVM);
|
||||||
// Register the module API
|
// Register the module API
|
||||||
@ -92,7 +98,7 @@ void OnSquirrelTerminate()
|
|||||||
{
|
{
|
||||||
OutputMessage("Terminating: %s", SQSQLITE_NAME);
|
OutputMessage("Terminating: %s", SQSQLITE_NAME);
|
||||||
// Release the current database (if any)
|
// Release the current database (if any)
|
||||||
DefaultVM::Set(NULL);
|
DefaultVM::Set(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -101,10 +107,12 @@ void OnSquirrelTerminate()
|
|||||||
bool CheckAPIVer(CCStr ver)
|
bool CheckAPIVer(CCStr ver)
|
||||||
{
|
{
|
||||||
// Obtain the numeric representation of the API version
|
// Obtain the numeric representation of the API version
|
||||||
long vernum = strtol(ver, NULL, 10);
|
long vernum = strtol(ver, nullptr, 10);
|
||||||
// Check against version mismatch
|
// Check against version mismatch
|
||||||
if (vernum == SQMOD_API_VER)
|
if (vernum == SQMOD_API_VER)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
// Log the incident
|
// Log the incident
|
||||||
OutputError("API version mismatch on %s", SQSQLITE_NAME);
|
OutputError("API version mismatch on %s", SQSQLITE_NAME);
|
||||||
OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER);
|
OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER);
|
||||||
@ -121,7 +129,9 @@ static int OnInternalCommand(unsigned int type, const char * text)
|
|||||||
{
|
{
|
||||||
case SQMOD_INITIALIZE_CMD:
|
case SQMOD_INITIALIZE_CMD:
|
||||||
if (CheckAPIVer(text))
|
if (CheckAPIVer(text))
|
||||||
|
{
|
||||||
OnSquirrelInitialize();
|
OnSquirrelInitialize();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SQMOD_LOAD_CMD:
|
case SQMOD_LOAD_CMD:
|
||||||
OnSquirrelLoad();
|
OnSquirrelLoad();
|
||||||
@ -159,9 +169,9 @@ void BindCallbacks()
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void UnbindCallbacks()
|
void UnbindCallbacks()
|
||||||
{
|
{
|
||||||
_Clbk->OnInitServer = NULL;
|
_Clbk->OnInitServer = nullptr;
|
||||||
_Clbk->OnInternalCommand = NULL;
|
_Clbk->OnInternalCommand = nullptr;
|
||||||
_Clbk->OnShutdownServer = NULL;
|
_Clbk->OnShutdownServer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
@ -199,7 +209,7 @@ void RegisterAPI(HSQUIRRELVM vm)
|
|||||||
.Prop(_SC("TotalChanges"), &Connection::GetTotalChanges)
|
.Prop(_SC("TotalChanges"), &Connection::GetTotalChanges)
|
||||||
.Prop(_SC("Trace"), &Connection::GetTracing, &Connection::SetTracing)
|
.Prop(_SC("Trace"), &Connection::GetTracing, &Connection::SetTracing)
|
||||||
.Prop(_SC("Profile"), &Connection::GetProfiling, &Connection::SetProfiling)
|
.Prop(_SC("Profile"), &Connection::GetProfiling, &Connection::SetProfiling)
|
||||||
.Prop(_SC("BusyTimeout"), (Int32 (Connection::*)(void) const)(NULL), &Connection::SetBusyTimeout)
|
.Prop(_SC("BusyTimeout"), (Int32 (Connection::*)(void) const)(nullptr), &Connection::SetBusyTimeout)
|
||||||
.Prop(_SC("QueueSize"), &Connection::QueueSize)
|
.Prop(_SC("QueueSize"), &Connection::QueueSize)
|
||||||
// Member Methods
|
// Member Methods
|
||||||
.Func(_SC("Release"), &Connection::Release)
|
.Func(_SC("Release"), &Connection::Release)
|
||||||
@ -584,7 +594,7 @@ void RegisterAPI(HSQUIRRELVM vm)
|
|||||||
.Const(_SC("NOTICE"), SQLITE_NOTICE)
|
.Const(_SC("NOTICE"), SQLITE_NOTICE)
|
||||||
.Const(_SC("NOTICE_RECOVER_ROLLBACK"), SQLITE_NOTICE_RECOVER_ROLLBACK)
|
.Const(_SC("NOTICE_RECOVER_ROLLBACK"), SQLITE_NOTICE_RECOVER_ROLLBACK)
|
||||||
.Const(_SC("NOTICE_RECOVER_WAL"), SQLITE_NOTICE_RECOVER_WAL)
|
.Const(_SC("NOTICE_RECOVER_WAL"), SQLITE_NOTICE_RECOVER_WAL)
|
||||||
.Const(_SC("NULL"), SQLITE_NULL)
|
.Const(_SC("nullptr"), SQLITE_NULL)
|
||||||
.Const(_SC("OK"), SQLITE_OK)
|
.Const(_SC("OK"), SQLITE_OK)
|
||||||
.Const(_SC("OPEN_AUTOPROXY"), SQLITE_OPEN_AUTOPROXY)
|
.Const(_SC("OPEN_AUTOPROXY"), SQLITE_OPEN_AUTOPROXY)
|
||||||
.Const(_SC("OPEN_CREATE"), SQLITE_OPEN_CREATE)
|
.Const(_SC("OPEN_CREATE"), SQLITE_OPEN_CREATE)
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
#include "Column.hpp"
|
#include "Column.hpp"
|
||||||
#include "Module.hpp"
|
#include "Module.hpp"
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <sqrat.h>
|
#include <sqrat.h>
|
||||||
|
|
||||||
@ -24,16 +27,6 @@ SQInteger Statement::Typename(HSQUIRRELVM vm)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void Statement::Validate() const
|
|
||||||
{
|
|
||||||
// Is the handle valid?
|
|
||||||
if (!m_Handle)
|
|
||||||
{
|
|
||||||
STHROWF("Invalid SQLite statement reference");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Statement::ValidateIndex(Int32 idx) const
|
void Statement::ValidateIndex(Int32 idx) const
|
||||||
{
|
{
|
||||||
@ -107,7 +100,7 @@ Statement::Statement(const Connection & connection, CSStr query)
|
|||||||
Object Statement::GetConnection() const
|
Object Statement::GetConnection() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return Object(new Connection(m_Handle->mConn));
|
return Object(new Connection(m_Handle->mConn));
|
||||||
}
|
}
|
||||||
@ -116,7 +109,7 @@ Object Statement::GetConnection() const
|
|||||||
void Statement::Reset()
|
void Statement::Reset()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Specify that we don't have a row available and we haven't finished stepping
|
// Specify that we don't have a row available and we haven't finished stepping
|
||||||
m_Handle->mGood = false;
|
m_Handle->mGood = false;
|
||||||
m_Handle->mDone = false;
|
m_Handle->mDone = false;
|
||||||
@ -133,7 +126,7 @@ void Statement::Reset()
|
|||||||
void Statement::Clear()
|
void Statement::Clear()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Specify that we don't have a row available and we haven't finished stepping
|
// Specify that we don't have a row available and we haven't finished stepping
|
||||||
m_Handle->mGood = false;
|
m_Handle->mGood = false;
|
||||||
m_Handle->mDone = false;
|
m_Handle->mDone = false;
|
||||||
@ -150,7 +143,7 @@ void Statement::Clear()
|
|||||||
Int32 Statement::Exec()
|
Int32 Statement::Exec()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Did we reset first?
|
// Did we reset first?
|
||||||
if (m_Handle->mDone)
|
if (m_Handle->mDone)
|
||||||
{
|
{
|
||||||
@ -188,7 +181,7 @@ Int32 Statement::Exec()
|
|||||||
bool Statement::Step()
|
bool Statement::Step()
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Did we reset first?
|
// Did we reset first?
|
||||||
if (m_Handle->mDone)
|
if (m_Handle->mDone)
|
||||||
{
|
{
|
||||||
@ -229,7 +222,7 @@ bool Statement::Step()
|
|||||||
void Statement::IndexBindA(Int32 idx, const Array & arr)
|
void Statement::IndexBindA(Int32 idx, const Array & arr)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Know when to stop trying to bind values
|
// Know when to stop trying to bind values
|
||||||
const Int32 max = sqlite3_bind_parameter_count(m_Handle);
|
const Int32 max = sqlite3_bind_parameter_count(m_Handle);
|
||||||
// Make sure that we are at least in bounds
|
// Make sure that we are at least in bounds
|
||||||
@ -267,7 +260,7 @@ void Statement::IndexBindA(Int32 idx, const Array & arr)
|
|||||||
void Statement::IndexBindI(Int32 idx, Int32 value)
|
void Statement::IndexBindI(Int32 idx, Int32 value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_int(m_Handle, idx, value);
|
m_Handle = sqlite3_bind_int(m_Handle, idx, value);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -281,7 +274,7 @@ void Statement::IndexBindI(Int32 idx, Int32 value)
|
|||||||
void Statement::IndexBindL(Int32 idx, const Object & value)
|
void Statement::IndexBindL(Int32 idx, const Object & value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const StackGuard sg(DefaultVM::Get());
|
const StackGuard sg(DefaultVM::Get());
|
||||||
// Push the specified object onto the stack
|
// Push the specified object onto the stack
|
||||||
@ -306,7 +299,7 @@ void Statement::IndexBindL(Int32 idx, const Object & value)
|
|||||||
void Statement::IndexBindV(Int32 idx, SQInteger value)
|
void Statement::IndexBindV(Int32 idx, SQInteger value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
#ifdef _SQ64
|
#ifdef _SQ64
|
||||||
m_Handle = sqlite3_bind_int64(m_Handle, idx, value);
|
m_Handle = sqlite3_bind_int64(m_Handle, idx, value);
|
||||||
@ -324,7 +317,7 @@ void Statement::IndexBindV(Int32 idx, SQInteger value)
|
|||||||
void Statement::IndexBindF(Int32 idx, SQFloat value)
|
void Statement::IndexBindF(Int32 idx, SQFloat value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_double(m_Handle, idx, value);
|
m_Handle = sqlite3_bind_double(m_Handle, idx, value);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -338,7 +331,7 @@ void Statement::IndexBindF(Int32 idx, SQFloat value)
|
|||||||
void Statement::IndexBindS(Int32 idx, CSStr value)
|
void Statement::IndexBindS(Int32 idx, CSStr value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_text(m_Handle, idx, value, -1, SQLITE_TRANSIENT);
|
m_Handle = sqlite3_bind_text(m_Handle, idx, value, -1, SQLITE_TRANSIENT);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -352,7 +345,7 @@ void Statement::IndexBindS(Int32 idx, CSStr value)
|
|||||||
void Statement::IndexBindB(Int32 idx, bool value)
|
void Statement::IndexBindB(Int32 idx, bool value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_int(m_Handle, idx, value);
|
m_Handle = sqlite3_bind_int(m_Handle, idx, value);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -366,7 +359,7 @@ void Statement::IndexBindB(Int32 idx, bool value)
|
|||||||
void Statement::IndexBindN(Int32 idx)
|
void Statement::IndexBindN(Int32 idx)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_null(m_Handle, idx);
|
m_Handle = sqlite3_bind_null(m_Handle, idx);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -380,7 +373,7 @@ void Statement::IndexBindN(Int32 idx)
|
|||||||
void Statement::NameBindT(const Table & tbl)
|
void Statement::NameBindT(const Table & tbl)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Should we clear the all the parameters?
|
// Should we clear the all the parameters?
|
||||||
if (tbl.GetSize() <= 0)
|
if (tbl.GetSize() <= 0)
|
||||||
{
|
{
|
||||||
@ -408,7 +401,7 @@ void Statement::NameBindT(const Table & tbl)
|
|||||||
void Statement::NameBindI(CSStr name, Int32 value)
|
void Statement::NameBindI(CSStr name, Int32 value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -429,7 +422,7 @@ void Statement::NameBindI(CSStr name, Int32 value)
|
|||||||
void Statement::NameBindL(CSStr name, const Object & value)
|
void Statement::NameBindL(CSStr name, const Object & value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -461,7 +454,7 @@ void Statement::NameBindL(CSStr name, const Object & value)
|
|||||||
void Statement::NameBindV(CSStr name, SQInteger value)
|
void Statement::NameBindV(CSStr name, SQInteger value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -486,7 +479,7 @@ void Statement::NameBindV(CSStr name, SQInteger value)
|
|||||||
void Statement::NameBindF(CSStr name, SQFloat value)
|
void Statement::NameBindF(CSStr name, SQFloat value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -507,7 +500,7 @@ void Statement::NameBindF(CSStr name, SQFloat value)
|
|||||||
void Statement::NameBindS(CSStr name, CSStr value)
|
void Statement::NameBindS(CSStr name, CSStr value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -528,7 +521,7 @@ void Statement::NameBindS(CSStr name, CSStr value)
|
|||||||
void Statement::NameBindB(CSStr name, bool value)
|
void Statement::NameBindB(CSStr name, bool value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -549,7 +542,7 @@ void Statement::NameBindB(CSStr name, bool value)
|
|||||||
void Statement::NameBindN(CSStr name)
|
void Statement::NameBindN(CSStr name)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -570,7 +563,7 @@ void Statement::NameBindN(CSStr name)
|
|||||||
void Statement::IndexBind(Int32 idx, const Object & value)
|
void Statement::IndexBind(Int32 idx, const Object & value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to identify the specified type
|
// Attempt to identify the specified type
|
||||||
switch (value.GetType())
|
switch (value.GetType())
|
||||||
{
|
{
|
||||||
@ -620,8 +613,7 @@ void Statement::IndexBind(Int32 idx, const Object & value)
|
|||||||
m_Handle = sqlite3_bind_int64(m_Handle, idx, longint);
|
m_Handle = sqlite3_bind_int64(m_Handle, idx, longint);
|
||||||
} break;
|
} break;
|
||||||
// We don't recognize this kind of value!
|
// We don't recognize this kind of value!
|
||||||
default:
|
default: STHROWF("Attempting to bind unknown value type (%d)", idx);
|
||||||
STHROWF("Attempting to bind unknown value type (%d)", idx);
|
|
||||||
}
|
}
|
||||||
// Validate the result
|
// Validate the result
|
||||||
if (m_Handle != SQLITE_OK)
|
if (m_Handle != SQLITE_OK)
|
||||||
@ -634,7 +626,7 @@ void Statement::IndexBind(Int32 idx, const Object & value)
|
|||||||
void Statement::NameBind(CSStr name, const Object & value)
|
void Statement::NameBind(CSStr name, const Object & value)
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the index of the specified parameter name
|
// Attempt to obtain the index of the specified parameter name
|
||||||
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
const Int32 idx = sqlite3_bind_parameter_index(m_Handle, name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -691,8 +683,7 @@ void Statement::NameBind(CSStr name, const Object & value)
|
|||||||
m_Handle = sqlite3_bind_int64(m_Handle, idx, longint);
|
m_Handle = sqlite3_bind_int64(m_Handle, idx, longint);
|
||||||
} break;
|
} break;
|
||||||
// We don't recognize this kind of value!
|
// We don't recognize this kind of value!
|
||||||
default:
|
default: STHROWF("Attempting to bind unknown value type (%s:%d)", name, idx);
|
||||||
STHROWF("Attempting to bind unknown value type (%s:%d)", name, idx);
|
|
||||||
}
|
}
|
||||||
// Validate the result
|
// Validate the result
|
||||||
if (m_Handle != SQLITE_OK)
|
if (m_Handle != SQLITE_OK)
|
||||||
@ -766,7 +757,9 @@ Object Statement::FetchColumnIndex(Int32 idx) const
|
|||||||
const void * b = sqlite3_column_blob(m_Handle, idx);
|
const void * b = sqlite3_column_blob(m_Handle, idx);
|
||||||
// Could the memory blob be allocated?
|
// Could the memory blob be allocated?
|
||||||
if (!p)
|
if (!p)
|
||||||
|
{
|
||||||
STHROWF("Unable to allocate space for column blob value");
|
STHROWF("Unable to allocate space for column blob value");
|
||||||
|
}
|
||||||
// Is there any data to read?
|
// Is there any data to read?
|
||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
@ -777,11 +770,12 @@ Object Statement::FetchColumnIndex(Int32 idx) const
|
|||||||
}
|
}
|
||||||
// Copy the data into the memory blob
|
// Copy the data into the memory blob
|
||||||
else
|
else
|
||||||
memcpy(p, b, sz);
|
{
|
||||||
|
std::memcpy(p, b, sz);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
// Unknown type
|
// Unknown type
|
||||||
default:
|
default: STHROWF("Unknown value to fetch at index: %d", idx);
|
||||||
STHROWF("Unknown value to fetch at index: %d", idx);
|
|
||||||
}
|
}
|
||||||
// Obtain the object with the value from the stack and return it
|
// Obtain the object with the value from the stack and return it
|
||||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||||
@ -819,7 +813,7 @@ Object Statement::FetchColumn(const Object & column) const
|
|||||||
Array Statement::FetchArray() const
|
Array Statement::FetchArray() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return FetchArray(0, m_Handle->mColumns);
|
return FetchArray(0, m_Handle->mColumns);
|
||||||
}
|
}
|
||||||
@ -828,7 +822,7 @@ Array Statement::FetchArray() const
|
|||||||
Array Statement::FetchArray(Int32 min) const
|
Array Statement::FetchArray(Int32 min) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return FetchArray(min, m_Handle->mColumns);
|
return FetchArray(min, m_Handle->mColumns);
|
||||||
}
|
}
|
||||||
@ -913,7 +907,7 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
// Copy the data into the memory blob
|
// Copy the data into the memory blob
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(p, b, sz);
|
std::memcpy(p, b, sz);
|
||||||
}
|
}
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack
|
||||||
Var< Object > obj(DefaultVM::Get(), -1);
|
Var< Object > obj(DefaultVM::Get(), -1);
|
||||||
@ -921,8 +915,7 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
arr.Bind(elem, obj.value);
|
arr.Bind(elem, obj.value);
|
||||||
} break;
|
} break;
|
||||||
// Unknown type
|
// Unknown type
|
||||||
default:
|
default: STHROWF("Unknown value to fetch at index: %d", idx);
|
||||||
STHROWF("Unknown value to fetch at index: %d", idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return the resulted array
|
// Return the resulted array
|
||||||
@ -933,7 +926,7 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
Table Statement::FetchTable() const
|
Table Statement::FetchTable() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return FetchTable(0, m_Handle->mColumns);
|
return FetchTable(0, m_Handle->mColumns);
|
||||||
}
|
}
|
||||||
@ -942,7 +935,7 @@ Table Statement::FetchTable() const
|
|||||||
Table Statement::FetchTable(Int32 min) const
|
Table Statement::FetchTable(Int32 min) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return FetchTable(min, m_Handle->mColumns);
|
return FetchTable(min, m_Handle->mColumns);
|
||||||
}
|
}
|
||||||
@ -983,7 +976,9 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
CSStr name = sqlite3_column_name(m_Handle, idx);
|
CSStr name = sqlite3_column_name(m_Handle, idx);
|
||||||
// Validate the obtained name
|
// Validate the obtained name
|
||||||
if (!name)
|
if (!name)
|
||||||
|
{
|
||||||
STHROWF("Unable to retrieve name of column (%d)", idx);
|
STHROWF("Unable to retrieve name of column (%d)", idx);
|
||||||
|
}
|
||||||
// Identify the type of value that must be assigned
|
// Identify the type of value that must be assigned
|
||||||
switch (sqlite3_column_type(m_Handle, idx))
|
switch (sqlite3_column_type(m_Handle, idx))
|
||||||
{
|
{
|
||||||
@ -1038,7 +1033,7 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
// Copy the data into the memory blob
|
// Copy the data into the memory blob
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(p, b, sz);
|
std::memcpy(p, b, sz);
|
||||||
}
|
}
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack
|
||||||
Var< Object > obj(DefaultVM::Get(), -1);
|
Var< Object > obj(DefaultVM::Get(), -1);
|
||||||
@ -1046,8 +1041,7 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
tbl.Bind(name, obj.value);
|
tbl.Bind(name, obj.value);
|
||||||
} break;
|
} break;
|
||||||
// Unknown type
|
// Unknown type
|
||||||
default:
|
default: STHROWF("Unknown value to fetch at index: %d", idx);
|
||||||
STHROWF("Unknown value to fetch at index: %d", idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return the resulted table
|
// Return the resulted table
|
||||||
@ -1058,7 +1052,7 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
bool Statement::CheckIndex(Int32 idx) const
|
bool Statement::CheckIndex(Int32 idx) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->CheckIndex(idx);
|
return m_Handle->CheckIndex(idx);
|
||||||
}
|
}
|
||||||
@ -1076,7 +1070,7 @@ bool Statement::IsColumnNull(Int32 idx) const
|
|||||||
Int32 Statement::GetColumnIndex(CSStr name) const
|
Int32 Statement::GetColumnIndex(CSStr name) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->GetColumnIndex(name);
|
return m_Handle->GetColumnIndex(name);
|
||||||
}
|
}
|
||||||
@ -1139,7 +1133,7 @@ Object Statement::GetColumnByIndex(Int32 idx) const
|
|||||||
Object Statement::GetColumnByName(CSStr name) const
|
Object Statement::GetColumnByName(CSStr name) const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Attempt to obtain the requested column index
|
// Attempt to obtain the requested column index
|
||||||
const Int32 idx = m_Handle->GetColumnIndex(name);
|
const Int32 idx = m_Handle->GetColumnIndex(name);
|
||||||
// Validate the obtained index
|
// Validate the obtained index
|
||||||
@ -1166,7 +1160,7 @@ Object Statement::GetColumn(const Object & column) const
|
|||||||
}
|
}
|
||||||
// We don't recognize this kind of value!
|
// We don't recognize this kind of value!
|
||||||
STHROWF("Unknown column identifier type");
|
STHROWF("Unknown column identifier type");
|
||||||
// We have to return something!
|
// We have to return something even if we don't rach this point!
|
||||||
return Object();
|
return Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,15 +16,10 @@ class Statement
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
StmtHnd m_Handle; /* The handle to the managed database statement resource. */
|
StmtHnd m_Handle; // The handle to the managed database statement resource.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Validate the statement reference and throw an error if invalid.
|
|
||||||
*/
|
|
||||||
void Validate() const;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Validate the statement reference and index, and throw an error if they're invalid.
|
* Validate the statement reference and index, and throw an error if they're invalid.
|
||||||
*/
|
*/
|
||||||
@ -125,11 +120,17 @@ public:
|
|||||||
Int32 Cmp(const Statement & o) const
|
Int32 Cmp(const Statement & o) const
|
||||||
{
|
{
|
||||||
if (m_Handle.m_Hnd == o.m_Handle.m_Hnd)
|
if (m_Handle.m_Hnd == o.m_Handle.m_Hnd)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
|
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -139,7 +140,9 @@ public:
|
|||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
if (m_Handle)
|
if (m_Handle)
|
||||||
|
{
|
||||||
return m_Handle->mQuery.c_str();
|
return m_Handle->mQuery.c_str();
|
||||||
|
}
|
||||||
// Request failed
|
// Request failed
|
||||||
return _SC("");
|
return _SC("");
|
||||||
}
|
}
|
||||||
@ -154,7 +157,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
return (bool)m_Handle;
|
return m_Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -192,7 +195,7 @@ public:
|
|||||||
Int32 GetStatus() const
|
Int32 GetStatus() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mStatus;
|
return m_Handle->mStatus;
|
||||||
}
|
}
|
||||||
@ -203,7 +206,7 @@ public:
|
|||||||
Int32 GetErrorCode() const
|
Int32 GetErrorCode() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrNo();
|
return m_Handle.ErrNo();
|
||||||
}
|
}
|
||||||
@ -214,7 +217,7 @@ public:
|
|||||||
Int32 GetExtendedErrorCode() const
|
Int32 GetExtendedErrorCode() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ExErrNo();
|
return m_Handle.ExErrNo();
|
||||||
}
|
}
|
||||||
@ -225,7 +228,7 @@ public:
|
|||||||
CSStr GetErrStr() const
|
CSStr GetErrStr() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrStr();
|
return m_Handle.ErrStr();
|
||||||
}
|
}
|
||||||
@ -236,7 +239,7 @@ public:
|
|||||||
CSStr GetErrMsg() const
|
CSStr GetErrMsg() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle.ErrMsg();
|
return m_Handle.ErrMsg();
|
||||||
}
|
}
|
||||||
@ -247,7 +250,7 @@ public:
|
|||||||
Int32 GetColumns() const
|
Int32 GetColumns() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mColumns;
|
return m_Handle->mColumns;
|
||||||
}
|
}
|
||||||
@ -258,7 +261,7 @@ public:
|
|||||||
CSStr GetQuery() const
|
CSStr GetQuery() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mQuery.c_str();
|
return m_Handle->mQuery.c_str();
|
||||||
}
|
}
|
||||||
@ -269,7 +272,7 @@ public:
|
|||||||
bool GetGood() const
|
bool GetGood() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mGood;
|
return m_Handle->mGood;
|
||||||
}
|
}
|
||||||
@ -280,7 +283,7 @@ public:
|
|||||||
bool GetDone() const
|
bool GetDone() const
|
||||||
{
|
{
|
||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
m_Handle.Validate();
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_Handle->mDone;
|
return m_Handle->mDone;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user