1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-07-10 02:47:11 +02: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:
Sandu Liviu Catalin
2016-02-28 16:20:33 +02:00
parent 7f0480c966
commit 4c66cfa49d
7 changed files with 190 additions and 97 deletions

View File

@ -14,6 +14,12 @@
// ------------------------------------------------------------------------------------------------
#include <sqlite3.h>
// ------------------------------------------------------------------------------------------------
extern "C" {
struct SQVM;
typedef struct SQVM* HSQUIRRELVM;
} /*extern "C"*/
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@ -43,6 +49,11 @@ class Transaction;
*/
SStr GetTempBuff();
/* ------------------------------------------------------------------------------------------------
* Retrieve the size of the temporary buffer.
*/
Uint32 GetTempBuffSize();
/* ------------------------------------------------------------------------------------------------
* Throw a formatted exception.
*/
@ -63,6 +74,50 @@ CSStr QFmtStr(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.
*/
@ -200,11 +255,19 @@ public:
*/
ConnHnd(const ConnHnd & o)
: m_Hnd(o.m_Hnd)
{
Grab();
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
ConnHnd(ConnHnd && o)
: m_Hnd(o.m_Hnd)
{
o.m_Hnd = NULL;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
@ -227,6 +290,20 @@ public:
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.
*/
@ -354,7 +431,6 @@ public:
*/
Counter Count() const
{
assert(m_Hnd);
return m_Hnd ? m_Hnd->mRef : 0;
}
@ -363,8 +439,10 @@ public:
*/
CCStr ErrStr() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return sqlite3_errstr(sqlite3_errcode(m_Hnd->mPtr));
// SQLite does it's null pointer validations internally
if (m_Hnd)
return sqlite3_errstr(sqlite3_errcode(m_Hnd->mPtr));
return _SC("");
}
/* --------------------------------------------------------------------------------------------
@ -372,8 +450,10 @@ public:
*/
CCStr ErrMsg() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return sqlite3_errmsg(m_Hnd->mPtr);
// SQLite does it's null pointer validations internally
if (m_Hnd)
return sqlite3_errmsg(m_Hnd->mPtr);
return _SC("");
}
/* --------------------------------------------------------------------------------------------
@ -381,8 +461,10 @@ public:
*/
Int32 ErrNo() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return sqlite3_errcode(m_Hnd->mPtr);
// SQLite does it's null pointer validations internally
if (m_Hnd)
return sqlite3_errcode(m_Hnd->mPtr);
return SQLITE_NOMEM;
}
/* --------------------------------------------------------------------------------------------
@ -390,8 +472,10 @@ public:
*/
Int32 ExErrNo() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return sqlite3_extended_errcode(m_Hnd->mPtr);
// SQLite does it's null pointer validations internally
if (m_Hnd)
return sqlite3_extended_errcode(m_Hnd->mPtr);
return SQLITE_NOMEM;
}
};
@ -545,6 +629,15 @@ public:
Grab();
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
StmtHnd(StmtHnd && o)
: m_Hnd(o.m_Hnd)
{
o.m_Hnd = NULL;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
@ -567,6 +660,20 @@ public:
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.
*/
@ -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
{
@ -694,7 +801,6 @@ public:
*/
Counter Count() const
{
assert(m_Hnd);
return m_Hnd ? m_Hnd->mRef : 0;
}
@ -703,8 +809,9 @@ public:
*/
CCStr ErrStr() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return m_Hnd->mConn.ErrStr();
if (m_Hnd)
return m_Hnd->mConn.ErrStr();
return _SC("");
}
/* --------------------------------------------------------------------------------------------
@ -712,8 +819,9 @@ public:
*/
CCStr ErrMsg() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return m_Hnd->mConn.ErrMsg();
if (m_Hnd)
return m_Hnd->mConn.ErrMsg();
return _SC("");
}
/* --------------------------------------------------------------------------------------------
@ -721,8 +829,9 @@ public:
*/
Int32 ErrNo() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return m_Hnd->mConn.ErrNo();
if (m_Hnd)
return m_Hnd->mConn.ErrNo();
return SQLITE_NOMEM;
}
/* --------------------------------------------------------------------------------------------
@ -730,8 +839,9 @@ public:
*/
Int32 ExErrNo() const
{
assert(m_Hnd); // SQLite does it's null pointer validations internally
return m_Hnd->mConn.ExErrNo();
if (m_Hnd)
return m_Hnd->mConn.ExErrNo();
return SQLITE_NOMEM;
}
};