mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Implemented RAII when modifying the stack before returning to sqrat inside SQLite module.
Also enabled the latest C++ revision in the project. Various other fixes and improvements.
This commit is contained in:
parent
7f0480c966
commit
4c66cfa49d
@ -362,8 +362,10 @@
|
|||||||
<Compiler>
|
<Compiler>
|
||||||
<Add option="-Wextra" />
|
<Add option="-Wextra" />
|
||||||
<Add option="-Wall" />
|
<Add option="-Wall" />
|
||||||
|
<Add option="-std=c++14" />
|
||||||
<Add option="-DSQMOD_PLUGIN_API" />
|
<Add option="-DSQMOD_PLUGIN_API" />
|
||||||
<Add option="-DSCRAT_USE_EXCEPTIONS" />
|
<Add option="-DSCRAT_USE_EXCEPTIONS" />
|
||||||
|
<Add option="-DSCRAT_USE_CXX11_OPTIMIZATIONS" />
|
||||||
<Add directory="../modules/sqlite" />
|
<Add directory="../modules/sqlite" />
|
||||||
<Add directory="../shared" />
|
<Add directory="../shared" />
|
||||||
<Add directory="../include" />
|
<Add directory="../include" />
|
||||||
|
@ -98,15 +98,11 @@ Object Column::GetLong() const
|
|||||||
// Validate the column and statement row
|
// Validate the column and statement row
|
||||||
ValidateRow();
|
ValidateRow();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_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
|
||||||
_SqMod->PushSLongObject(_SqVM, sqlite3_column_int64(m_Stmt, m_Index));
|
_SqMod->PushSLongObject(_SqVM, sqlite3_column_int64(m_Stmt, m_Index));
|
||||||
// Obtain the object from the stack
|
// Get the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the long integer instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -115,16 +111,12 @@ Object Column::GetString() const
|
|||||||
// Validate the column and statement row
|
// Validate the column and statement row
|
||||||
ValidateRow();
|
ValidateRow();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_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, (CSStr)sqlite3_column_text(m_Stmt, m_Index),
|
||||||
sqlite3_column_bytes(m_Stmt, m_Index));
|
sqlite3_column_bytes(m_Stmt, m_Index));
|
||||||
// Obtain the object from the stack
|
// Get the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the long integer instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -142,7 +134,7 @@ Object Column::GetBlob() const
|
|||||||
// Validate the column and statement row
|
// Validate the column and statement row
|
||||||
ValidateRow();
|
ValidateRow();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Obtain the size of the data
|
// Obtain the size of the data
|
||||||
const Int32 sz = sqlite3_column_bytes(m_Stmt, m_Index);
|
const Int32 sz = sqlite3_column_bytes(m_Stmt, m_Index);
|
||||||
// Allocate a blob of the same size
|
// Allocate a blob of the same size
|
||||||
@ -156,19 +148,15 @@ Object Column::GetBlob() const
|
|||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
// Pop the memory blob from the stack
|
// Pop the memory blob from the stack
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
sq_pop(_SqVM, 1);
|
||||||
// Push a null value instead
|
// Push a null value instead
|
||||||
sq_pushnull(_SqVM);
|
sq_pushnull(_SqVM);
|
||||||
}
|
}
|
||||||
// Copy the data into the memory blob
|
// Copy the data into the memory blob
|
||||||
else
|
else
|
||||||
memcpy(p, b, sz);
|
memcpy(p, b, sz);
|
||||||
// Obtain the object from the stack
|
// Get the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the blob instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#include <sqrat.h>
|
#include <sqrat.h>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
|
namespace SqMod {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
namespace SqMod {
|
static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
SStr GetTempBuff()
|
SStr GetTempBuff()
|
||||||
@ -21,6 +21,12 @@ SStr GetTempBuff()
|
|||||||
return g_Buffer;
|
return g_Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Uint32 GetTempBuffSize()
|
||||||
|
{
|
||||||
|
return sizeof(g_Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SqThrowF(CSStr str, ...)
|
void SqThrowF(CSStr str, ...)
|
||||||
{
|
{
|
||||||
@ -84,6 +90,19 @@ bool IsQueryEmpty(CSStr str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
StackGuard::StackGuard(HSQUIRRELVM vm)
|
||||||
|
: m_Top(sq_gettop(vm)), m_VM(vm)
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
StackGuard::~StackGuard()
|
||||||
|
{
|
||||||
|
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ConnHnd::Handle::~Handle()
|
ConnHnd::Handle::~Handle()
|
||||||
{
|
{
|
||||||
@ -290,30 +309,22 @@ Int32 ReleaseMemory(Int32 bytes)
|
|||||||
Object GetMemoryUsage()
|
Object GetMemoryUsage()
|
||||||
{
|
{
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_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
|
||||||
_SqMod->PushSLongObject(_SqVM, sqlite3_memory_used());
|
_SqMod->PushSLongObject(_SqVM, sqlite3_memory_used());
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the long integer instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Object GetMemoryHighwaterMark(bool reset)
|
Object GetMemoryHighwaterMark(bool reset)
|
||||||
{
|
{
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_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
|
||||||
_SqMod->PushSLongObject(_SqVM, sqlite3_memory_highwater(reset));
|
_SqMod->PushSLongObject(_SqVM, sqlite3_memory_highwater(reset));
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the long integer instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -348,7 +359,7 @@ CCStr EscapeStringEx(SQChar spec, CCStr str)
|
|||||||
// Attempt to escape the specified string
|
// Attempt to escape the specified string
|
||||||
sqlite3_snprintf(sizeof(g_Buffer), g_Buffer, fs, str);
|
sqlite3_snprintf(sizeof(g_Buffer), g_Buffer, fs, str);
|
||||||
// Restore the format specifier
|
// Restore the format specifier
|
||||||
fs[1] = '1';
|
fs[1] = 'q';
|
||||||
// Return the resulted string
|
// Return the resulted string
|
||||||
return g_Buffer;
|
return g_Buffer;
|
||||||
}
|
}
|
||||||
@ -389,6 +400,7 @@ CCStr ArrayToQueryColumns(Array & arr)
|
|||||||
return g_Buffer;
|
return g_Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
CCStr TableToQueryColumns(Table & tbl)
|
CCStr TableToQueryColumns(Table & tbl)
|
||||||
{
|
{
|
||||||
// Used to know the position of the next column name
|
// Used to know the position of the next column name
|
||||||
@ -404,7 +416,7 @@ 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())
|
||||||
SqThrowF("Invalid column name");
|
SqThrowF("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
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
extern "C" {
|
||||||
|
struct SQVM;
|
||||||
|
typedef struct SQVM* HSQUIRRELVM;
|
||||||
|
} /*extern "C"*/
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
namespace SqMod {
|
namespace SqMod {
|
||||||
|
|
||||||
@ -43,6 +49,11 @@ class Transaction;
|
|||||||
*/
|
*/
|
||||||
SStr GetTempBuff();
|
SStr GetTempBuff();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the size of the temporary buffer.
|
||||||
|
*/
|
||||||
|
Uint32 GetTempBuffSize();
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Throw a formatted exception.
|
* Throw a formatted exception.
|
||||||
*/
|
*/
|
||||||
@ -63,6 +74,50 @@ CSStr QFmtStr(CSStr str, ...);
|
|||||||
*/
|
*/
|
||||||
bool IsQueryEmpty(CSStr str);
|
bool IsQueryEmpty(CSStr str);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* Implements RAII to restore the VM stack to it's initial size on function exit.
|
||||||
|
*/
|
||||||
|
struct StackGuard
|
||||||
|
{
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Base constructor.
|
||||||
|
*/
|
||||||
|
StackGuard(HSQUIRRELVM vm);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
~StackGuard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
|
StackGuard(const StackGuard &);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
StackGuard(StackGuard &&);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copy assignment operator.
|
||||||
|
*/
|
||||||
|
StackGuard & operator = (const StackGuard &);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
StackGuard & operator = (StackGuard &&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
Int32 m_Top; /* The top of the stack when this instance was created. */
|
||||||
|
HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
|
||||||
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Manages a reference counted database connection handle.
|
* Manages a reference counted database connection handle.
|
||||||
*/
|
*/
|
||||||
@ -200,11 +255,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
ConnHnd(const ConnHnd & o)
|
ConnHnd(const ConnHnd & o)
|
||||||
: m_Hnd(o.m_Hnd)
|
: m_Hnd(o.m_Hnd)
|
||||||
|
|
||||||
{
|
{
|
||||||
Grab();
|
Grab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
ConnHnd(ConnHnd && o)
|
||||||
|
: m_Hnd(o.m_Hnd)
|
||||||
|
{
|
||||||
|
o.m_Hnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Destructor.
|
* Destructor.
|
||||||
*/
|
*/
|
||||||
@ -227,6 +290,20 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
ConnHnd & operator = (ConnHnd && o)
|
||||||
|
{
|
||||||
|
if (m_Hnd != o.m_Hnd)
|
||||||
|
{
|
||||||
|
m_Hnd = o.m_Hnd;
|
||||||
|
o.m_Hnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Status assignment operator.
|
* Status assignment operator.
|
||||||
*/
|
*/
|
||||||
@ -354,7 +431,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Counter Count() const
|
Counter Count() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd);
|
|
||||||
return m_Hnd ? m_Hnd->mRef : 0;
|
return m_Hnd ? m_Hnd->mRef : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,8 +439,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
CCStr ErrStr() const
|
CCStr ErrStr() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
// SQLite does it's null pointer validations internally
|
||||||
return sqlite3_errstr(sqlite3_errcode(m_Hnd->mPtr));
|
if (m_Hnd)
|
||||||
|
return sqlite3_errstr(sqlite3_errcode(m_Hnd->mPtr));
|
||||||
|
return _SC("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -372,8 +450,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
CCStr ErrMsg() const
|
CCStr ErrMsg() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
// SQLite does it's null pointer validations internally
|
||||||
return sqlite3_errmsg(m_Hnd->mPtr);
|
if (m_Hnd)
|
||||||
|
return sqlite3_errmsg(m_Hnd->mPtr);
|
||||||
|
return _SC("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -381,8 +461,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int32 ErrNo() const
|
Int32 ErrNo() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
// SQLite does it's null pointer validations internally
|
||||||
return sqlite3_errcode(m_Hnd->mPtr);
|
if (m_Hnd)
|
||||||
|
return sqlite3_errcode(m_Hnd->mPtr);
|
||||||
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -390,8 +472,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int32 ExErrNo() const
|
Int32 ExErrNo() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
// SQLite does it's null pointer validations internally
|
||||||
return sqlite3_extended_errcode(m_Hnd->mPtr);
|
if (m_Hnd)
|
||||||
|
return sqlite3_extended_errcode(m_Hnd->mPtr);
|
||||||
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -545,6 +629,15 @@ public:
|
|||||||
Grab();
|
Grab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
StmtHnd(StmtHnd && o)
|
||||||
|
: m_Hnd(o.m_Hnd)
|
||||||
|
{
|
||||||
|
o.m_Hnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Destructor.
|
* Destructor.
|
||||||
*/
|
*/
|
||||||
@ -567,6 +660,20 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
StmtHnd & operator = (StmtHnd && o)
|
||||||
|
{
|
||||||
|
if (m_Hnd != o.m_Hnd)
|
||||||
|
{
|
||||||
|
m_Hnd = o.m_Hnd;
|
||||||
|
o.m_Hnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Status assignment operator.
|
* Status assignment operator.
|
||||||
*/
|
*/
|
||||||
@ -604,7 +711,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Perform an inequality comparison with an integer value status.
|
* Perform an inequality comparison with an integer status value.
|
||||||
*/
|
*/
|
||||||
bool operator != (Int32 status) const
|
bool operator != (Int32 status) const
|
||||||
{
|
{
|
||||||
@ -694,7 +801,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Counter Count() const
|
Counter Count() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd);
|
|
||||||
return m_Hnd ? m_Hnd->mRef : 0;
|
return m_Hnd ? m_Hnd->mRef : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,8 +809,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
CCStr ErrStr() const
|
CCStr ErrStr() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
if (m_Hnd)
|
||||||
return m_Hnd->mConn.ErrStr();
|
return m_Hnd->mConn.ErrStr();
|
||||||
|
return _SC("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -712,8 +819,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
CCStr ErrMsg() const
|
CCStr ErrMsg() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
if (m_Hnd)
|
||||||
return m_Hnd->mConn.ErrMsg();
|
return m_Hnd->mConn.ErrMsg();
|
||||||
|
return _SC("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -721,8 +829,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int32 ErrNo() const
|
Int32 ErrNo() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
if (m_Hnd)
|
||||||
return m_Hnd->mConn.ErrNo();
|
return m_Hnd->mConn.ErrNo();
|
||||||
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
@ -730,8 +839,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Int32 ExErrNo() const
|
Int32 ExErrNo() const
|
||||||
{
|
{
|
||||||
assert(m_Hnd); // SQLite does it's null pointer validations internally
|
if (m_Hnd)
|
||||||
return m_Hnd->mConn.ExErrNo();
|
return m_Hnd->mConn.ExErrNo();
|
||||||
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,15 +129,11 @@ Object Connection::GetLastInsertRowID() const
|
|||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
Validate();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_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
|
||||||
_SqMod->PushSLongObject(_SqVM, sqlite3_last_insert_rowid(m_Handle));
|
_SqMod->PushSLongObject(_SqVM, sqlite3_last_insert_rowid(m_Handle));
|
||||||
// Obtain the object from the stack
|
// Get the object from the stack and return it
|
||||||
Var< Object > inst(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Removed pushed values (if any)
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Return the long integer instance
|
|
||||||
return inst.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -325,6 +325,7 @@ void RegisterAPI(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("Release"), &Column::Release)
|
.Func(_SC("Release"), &Column::Release)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sqlns.Func(_SC("IsQueryEmpty"), &IsQueryEmpty);
|
||||||
sqlns.Func(_SC("GetErrStr"), &GetErrStr);
|
sqlns.Func(_SC("GetErrStr"), &GetErrStr);
|
||||||
sqlns.Func(_SC("SetSoftHeapLimit"), &SetSoftHeapLimit);
|
sqlns.Func(_SC("SetSoftHeapLimit"), &SetSoftHeapLimit);
|
||||||
sqlns.Func(_SC("ReleaseMemory"), &ReleaseMemory);
|
sqlns.Func(_SC("ReleaseMemory"), &ReleaseMemory);
|
||||||
|
@ -245,17 +245,13 @@ void Statement::IndexBindL(Int32 idx, Object & value)
|
|||||||
// Validate the handle
|
// Validate the handle
|
||||||
Validate();
|
Validate();
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Push the specified object onto the stack
|
// Push the specified object onto the stack
|
||||||
Var< Object & >::push(_SqVM, value);
|
Var< Object & >::push(_SqVM, value);
|
||||||
// The resulted long integer value
|
// The resulted long integer value
|
||||||
Int64 longint = 0;
|
Int64 longint = 0;
|
||||||
// Attempt to get the numeric value inside the specified object
|
// Attempt to get the numeric value inside the specified object
|
||||||
const SQRESULT res = _SqMod->GetSLongValue(_SqVM, -1, &longint);
|
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Now it's safe to throw the error if necessary
|
|
||||||
if (SQ_FAILED(res))
|
|
||||||
SqThrowF("Invalid long integer specified");
|
SqThrowF("Invalid long integer specified");
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_int(m_Handle, idx, longint);
|
m_Handle = sqlite3_bind_int(m_Handle, idx, longint);
|
||||||
@ -382,17 +378,13 @@ void Statement::NameBindL(CSStr name, Object & value)
|
|||||||
if (!idx)
|
if (!idx)
|
||||||
SqThrowF("Unknown parameter named (%s)", name);
|
SqThrowF("Unknown parameter named (%s)", name);
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Push the specified object onto the stack
|
// Push the specified object onto the stack
|
||||||
Var< Object & >::push(_SqVM, value);
|
Var< Object & >::push(_SqVM, value);
|
||||||
// The resulted long integer value
|
// The resulted long integer value
|
||||||
Uint64 longint = 0;
|
Uint64 longint = 0;
|
||||||
// Attempt to get the numeric value inside the specified object
|
// Attempt to get the numeric value inside the specified object
|
||||||
const SQRESULT res = _SqMod->GetULongValue(_SqVM, -1, &longint);
|
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Now it's safe to throw the error if necessary
|
|
||||||
if (SQ_FAILED(res))
|
|
||||||
SqThrowF("Invalid long integer specified");
|
SqThrowF("Invalid long integer specified");
|
||||||
// Attempt to bind the specified value
|
// Attempt to bind the specified value
|
||||||
m_Handle = sqlite3_bind_int(m_Handle, idx, longint);
|
m_Handle = sqlite3_bind_int(m_Handle, idx, longint);
|
||||||
@ -590,7 +582,7 @@ Object Statement::FetchColumnIndex(Int32 idx) const
|
|||||||
if (!m_Handle->CheckIndex(idx))
|
if (!m_Handle->CheckIndex(idx))
|
||||||
SqThrowF("Column index is out of range: %d", idx);
|
SqThrowF("Column index is out of range: %d", idx);
|
||||||
// Obtain the initial stack size
|
// Obtain the initial stack size
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
const StackGuard sg(_SqVM);
|
||||||
// Identify which type of value must be pushed on the stack
|
// Identify which type of value must be pushed on the stack
|
||||||
switch (sqlite3_column_type(m_Handle, idx))
|
switch (sqlite3_column_type(m_Handle, idx))
|
||||||
{
|
{
|
||||||
@ -631,7 +623,7 @@ Object Statement::FetchColumnIndex(Int32 idx) const
|
|||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
// Pop the memory blob from the stack
|
// Pop the memory blob from the stack
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
sq_pop(_SqVM, 1);
|
||||||
// Push a null value instead
|
// Push a null value instead
|
||||||
sq_pushnull(_SqVM);
|
sq_pushnull(_SqVM);
|
||||||
}
|
}
|
||||||
@ -643,12 +635,8 @@ Object Statement::FetchColumnIndex(Int32 idx) const
|
|||||||
default:
|
default:
|
||||||
SqThrowF("Unknown value to fetch at index: %d", idx);
|
SqThrowF("Unknown value to fetch at index: %d", idx);
|
||||||
}
|
}
|
||||||
// Obtain the object with the value from the stack
|
// Obtain the object with the value from the stack and return it
|
||||||
Var< Object > obj(_SqVM, -1);
|
return Var< Object >(_SqVM, -1).value;
|
||||||
// Remove any pushed values (if any) to restore the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Now return the obtained object
|
|
||||||
return obj.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -695,8 +683,6 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
// Is the maximum in range?
|
// Is the maximum in range?
|
||||||
else if (!m_Handle->CheckIndex(max))
|
else if (!m_Handle->CheckIndex(max))
|
||||||
SqThrowF("Maximum is out of range");
|
SqThrowF("Maximum is out of range");
|
||||||
// Obtain the initial stack size
|
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
|
||||||
// Allocate an array large enough to hold the values from selected columns
|
// Allocate an array large enough to hold the values from selected columns
|
||||||
Array arr(_SqVM, max-min);
|
Array arr(_SqVM, max-min);
|
||||||
// Process the range of selected columns
|
// Process the range of selected columns
|
||||||
@ -728,6 +714,8 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
// Is this raw data?
|
// Is this raw data?
|
||||||
case SQLITE_BLOB:
|
case SQLITE_BLOB:
|
||||||
{
|
{
|
||||||
|
// Obtain the initial stack size
|
||||||
|
const StackGuard sg(_SqVM);
|
||||||
// Obtain the size of the data
|
// Obtain the size of the data
|
||||||
const Int32 sz = sqlite3_column_bytes(m_Handle, idx);
|
const Int32 sz = sqlite3_column_bytes(m_Handle, idx);
|
||||||
// Allocate a blob of the same size
|
// Allocate a blob of the same size
|
||||||
@ -741,7 +729,7 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
// Pop the memory blob from the stack
|
// Pop the memory blob from the stack
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
sq_pop(_SqVM, 1);
|
||||||
// Push a null value instead
|
// Push a null value instead
|
||||||
sq_pushnull(_SqVM);
|
sq_pushnull(_SqVM);
|
||||||
}
|
}
|
||||||
@ -750,8 +738,6 @@ Array Statement::FetchArray(Int32 min, Int32 max) const
|
|||||||
memcpy(p, b, sz);
|
memcpy(p, b, sz);
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack
|
||||||
Var< Object > obj(_SqVM, -1);
|
Var< Object > obj(_SqVM, -1);
|
||||||
// Pop the memory blob from the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Bind it as an array element
|
// Bind it as an array element
|
||||||
arr.Bind(elem, obj.value);
|
arr.Bind(elem, obj.value);
|
||||||
} break;
|
} break;
|
||||||
@ -799,8 +785,6 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
// Is the maximum in range?
|
// Is the maximum in range?
|
||||||
else if (!m_Handle->CheckIndex(max))
|
else if (!m_Handle->CheckIndex(max))
|
||||||
SqThrowF("Maximum is out of range");
|
SqThrowF("Maximum is out of range");
|
||||||
// Obtain the initial stack size
|
|
||||||
const Int32 top = sq_gettop(_SqVM);
|
|
||||||
// Create a table to hold the selected column values
|
// Create a table to hold the selected column values
|
||||||
Table tbl(_SqVM);
|
Table tbl(_SqVM);
|
||||||
// Used to bind null values
|
// Used to bind null values
|
||||||
@ -843,6 +827,8 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
// Is this raw data?
|
// Is this raw data?
|
||||||
case SQLITE_BLOB:
|
case SQLITE_BLOB:
|
||||||
{
|
{
|
||||||
|
// Obtain the initial stack size
|
||||||
|
const StackGuard sg(_SqVM);
|
||||||
// Obtain the size of the data
|
// Obtain the size of the data
|
||||||
const Int32 sz = sqlite3_column_bytes(m_Handle, idx);
|
const Int32 sz = sqlite3_column_bytes(m_Handle, idx);
|
||||||
// Allocate a blob of the same size
|
// Allocate a blob of the same size
|
||||||
@ -856,7 +842,7 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
else if (!b)
|
else if (!b)
|
||||||
{
|
{
|
||||||
// Pop the memory blob from the stack
|
// Pop the memory blob from the stack
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
sq_pop(_SqVM, 1);
|
||||||
// Push a null value instead
|
// Push a null value instead
|
||||||
sq_pushnull(_SqVM);
|
sq_pushnull(_SqVM);
|
||||||
}
|
}
|
||||||
@ -865,8 +851,6 @@ Table Statement::FetchTable(Int32 min, Int32 max) const
|
|||||||
memcpy(p, b, sz);
|
memcpy(p, b, sz);
|
||||||
// Obtain the object from the stack
|
// Obtain the object from the stack
|
||||||
Var< Object > obj(_SqVM, -1);
|
Var< Object > obj(_SqVM, -1);
|
||||||
// Pop the memory blob from the stack
|
|
||||||
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
||||||
// Bind it as a table element
|
// Bind it as a table element
|
||||||
tbl.Bind(name, obj.value);
|
tbl.Bind(name, obj.value);
|
||||||
} break;
|
} break;
|
||||||
|
Loading…
Reference in New Issue
Block a user