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

Untested revised implementation of the SQLite module.

This commit is contained in:
Sandu Liviu Catalin 2016-06-15 23:49:25 +03:00
parent 166760fd46
commit 8087d0482f
17 changed files with 2235 additions and 2300 deletions

View File

@ -421,6 +421,7 @@
<Unit filename="../modules/sqlite/Common.hpp" />
<Unit filename="../modules/sqlite/Connection.cpp" />
<Unit filename="../modules/sqlite/Connection.hpp" />
<Unit filename="../modules/sqlite/Constants.cpp" />
<Unit filename="../modules/sqlite/Handle/Connection.cpp" />
<Unit filename="../modules/sqlite/Handle/Connection.hpp" />
<Unit filename="../modules/sqlite/Handle/Statement.cpp" />

View File

@ -4,6 +4,8 @@
#include "Statement.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
@ -18,106 +20,280 @@ SQInteger Column::Typename(HSQUIRRELVM vm)
}
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::Validate(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
}
#else
void Column::Validate() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
STHROWF("Invalid column index");
SqThrowF("Invalid column index: %d < 0", m_Index);
}
// Do we have a valid statement handle?
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
// Do we belong to a valid statement?
m_Stmt.Validate();
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Column::ValidateRow() const
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::ValidateCreated(CCStr file, Int32 line) const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
STHROWF("Invalid column index");
SqThrowF("Invalid column index: %d < 0 =>[%s:%d]", m_Index, file, line);
}
// Do we belong to a valid statement?
m_Stmt.Validate();
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement =>[%s:%d]", file, line);
}
}
#else
void Column::ValidateCreated() const
{
// Are we pointing to a valid index?
if (m_Index < 0)
{
SqThrowF("Invalid column index: %d < 0", m_Index);
}
else if (!m_Handle)
{
SqThrowF("Invalid SQLite statement reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite statement");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Column::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const StmtRef & Column::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & Column::GetCreated(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
return m_Handle;
}
#else
const StmtRef & Column::GetCreated() const
{
ValidateCreated();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Column::ValidateRow(CCStr file, Int32 line) const
{
ValidateCreated(file, line);
// Do we have any rows available?
if (!m_Stmt->mGood)
if (!m_Handle->mGood)
{
STHROWF("No row available =>[%s:%d]", file, line);
}
}
#else
void Column::ValidateRow() const
{
ValidateCreated();
// Do we have any rows available?
if (!m_Handle->mGood)
{
STHROWF("No row available");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Object Column::GetStatement() const
{
// Validate the column
Validate();
// Return the requested information
return Object(new Statement(m_Stmt));
return Object(new Statement(m_Handle));
}
// ------------------------------------------------------------------------------------------------
Object Column::GetConnection() const
{
// Validate the column
Validate();
VALIDATE_HND(*this);
// Return the requested information
return Object(new Connection(m_Stmt->mConn));
return Object(new Connection(m_Handle->mConn));
}
// ------------------------------------------------------------------------------------------------
Int32 Column::GetNumber() const
Object Column::GetValue() const
{
// Validate the column and statement row
ValidateRow();
// Return the requested information
return sqlite3_column_int(m_Stmt, m_Index);
VALIDATE_ROW_HND(*this);
// Obtain the initial stack size
const StackGuard sg;
// Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index))
{
// Is this a null value?
case SQLITE_NULL:
{
sq_pushnull(DefaultVM::Get());
} break;
// Is this an integer?
case SQLITE_INTEGER:
{
sq_pushinteger(DefaultVM::Get(), sqlite3_column_integer(m_Handle->mPtr, m_Index));
} break;
// Is this a floating point?
case SQLITE_FLOAT:
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index)));
} break;
// Is this a string?
case SQLITE_TEXT:
{
sq_pushstring(DefaultVM::Get(),
reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index));
} break;
// Is this raw data?
case SQLITE_BLOB:
{
// Retrieve the size of the blob that must be allocated
const Int32 size = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Retrieve the the actual blob data that must be returned
CCStr data = reinterpret_cast< CCStr >(sqlite3_column_blob(m_Handle->mPtr, m_Index));
// Attempt to create a buffer with the blob data on the stack
if (SQ_FAILED(_SqMod->PushBufferData(DefaultVM::Get(), data, size, size)))
{
STHROWF("Unable to allocate buffer of at least (%d) bytes", size);
}
} break;
// Unknown type
default: STHROWF("Unknown value to fetch at index: %d", m_Index);
}
// Obtain the object with the value from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Column::GetNumber() const
{
VALIDATE_ROW_HND(*this);
// Obtain the initial stack size
const StackGuard sg;
// Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index))
{
// Is this a null value?
case SQLITE_NULL:
{
sq_pushinteger(DefaultVM::Get(), 0);
} break;
// Is this an integer?
case SQLITE_INTEGER:
{
sq_pushinteger(DefaultVM::Get(), sqlite3_column_integer(m_Handle->mPtr, m_Index));
} break;
// Is this a floating point?
case SQLITE_FLOAT:
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index)));
} break;
// Is this a string?
case SQLITE_TEXT:
{
CSStr str = reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index));
// Is there even a string to parse?
if (!str || *str == '\0')
{
sq_pushinteger(DefaultVM::Get(), 0);
}
// Can we treat this string as a float?
else if (!std::strchr(str, '.'))
{
sq_pushfloat(DefaultVM::Get(),
ConvTo< SQFloat >::From(std::strtod(str, nullptr)));
}
else
{
sq_pushinteger(DefaultVM::Get(),
ConvTo< SQInteger >::From(std::strtoll(str, nullptr, 10)));
}
} break;
// Unknown type
default: STHROWF("Unknown number to fetch at index: %d", m_Index);
}
// Obtain the object with the value from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
SQInteger Column::GetInteger() const
{
// Validate the column and statement row
ValidateRow();
VALIDATE_ROW_HND(*this);
// Return the requested information
#ifdef _SQ64
return sqlite3_column_int64(m_Stmt, m_Index);
#else
return sqlite3_column_int(m_Stmt, m_Index);
#endif
return sqlite3_column_integer(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
SQFloat Column::GetFloat() const
{
// Validate the column and statement row
ValidateRow();
VALIDATE_ROW_HND(*this);
// Return the requested information
return static_cast< SQFloat >(sqlite3_column_double(m_Stmt, m_Index));
return ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index));
}
// ------------------------------------------------------------------------------------------------
Object Column::GetLong() const
{
// Validate the column and statement row
ValidateRow();
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, sqlite3_column_int64(m_Stmt, m_Index));
// Get the object from the stack and return it
return Var< Object >(_SqVM, -1).value;
VALIDATE_ROW_HND(*this);
// Return the requested information
return MakeSLongObj(sqlite3_column_int64(m_Handle->mPtr, m_Index));
}
// ------------------------------------------------------------------------------------------------
Object Column::GetString() const
{
// Validate the column and statement row
ValidateRow();
VALIDATE_ROW_HND(*this);
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Push the column text on the stack
sq_pushstring(_SqVM, reinterpret_cast< CSStr >(sqlite3_column_text(m_Stmt, m_Index)),
sqlite3_column_bytes(m_Stmt, m_Index));
sq_pushstring(_SqVM, reinterpret_cast< CSStr >(sqlite3_column_text(m_Handle->mPtr, m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index));
// Get the object from the stack and return it
return Var< Object >(_SqVM, -1).value;
}
@ -125,25 +301,50 @@ Object Column::GetString() const
// ------------------------------------------------------------------------------------------------
bool Column::GetBoolean() const
{
// Validate the column and statement row
ValidateRow();
VALIDATE_ROW_HND(*this);
// Return the requested information
return sqlite3_column_int(m_Stmt, m_Index) > 0;
return sqlite3_column_int(m_Handle->mPtr, m_Index) > 0;
}
// ------------------------------------------------------------------------------------------------
SQChar Column::GetChar() const
{
VALIDATE_ROW_HND(*this);
// Return the requested information
return (SQChar)sqlite3_column_int(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
Object Column::GetBuffer() const
{
VALIDATE_ROW_HND(*this);
// Remember the current stack size
const StackGuard sg;
// Retrieve the size of the blob that must be allocated
const Int32 size = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Retrieve the the actual blob data that must be returned
CCStr data = reinterpret_cast< CCStr >(sqlite3_column_blob(m_Handle->mPtr, m_Index));
// Attempt to create a buffer with the blob data on the stack
if (SQ_FAILED(_SqMod->PushBufferData(DefaultVM::Get(), data, size, size)))
{
STHROWF("Unable to allocate buffer of at least (%d) bytes", size);
}
// Get the object from the stack and return it
return Var< Object >(_SqVM, -1).value;
}
// ------------------------------------------------------------------------------------------------
Object Column::GetBlob() const
{
// Validate the column and statement row
ValidateRow();
VALIDATE_ROW_HND(*this);
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Obtain the size of the data
const Int32 sz = sqlite3_column_bytes(m_Stmt, m_Index);
const Int32 sz = sqlite3_column_bytes(m_Handle->mPtr, m_Index);
// Allocate a blob of the same size
SQUserPointer p = sqstd_createblob(_SqVM, sz);
// Obtain a pointer to the data
const void * b = sqlite3_column_blob(m_Stmt, m_Index);
const void * b = sqlite3_column_blob(m_Handle->mPtr, m_Index);
// Could the memory blob be allocated?
if (!p)
{
@ -166,41 +367,29 @@ Object Column::GetBlob() const
return Var< Object >(_SqVM, -1).value;
}
// ------------------------------------------------------------------------------------------------
SQChar Column::GetChar() const
{
// Validate the column and statement row
ValidateRow();
// Return the requested information
return (SQChar)sqlite3_column_int(m_Stmt, m_Index);
}
// ------------------------------------------------------------------------------------------------
bool Column::IsNull() const
{
// Validate the column
Validate();
VALIDATE_CREATED_HND(*this);
// Return the requested information
return (sqlite3_column_type(m_Stmt, m_Index) == SQLITE_NULL);
return (sqlite3_column_type(m_Handle->mPtr, m_Index) == SQLITE_NULL);
}
// ------------------------------------------------------------------------------------------------
CSStr Column::GetName() const
{
// Validate the column
Validate();
VALIDATE_CREATED_HND(*this);
// Return the requested information
return sqlite3_column_name(m_Stmt, m_Index);
return sqlite3_column_name(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
CSStr Column::GetOriginName() const
{
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Validate the column
Validate();
VALIDATE_CREATED_HND(*this);
// Return the requested information
return sqlite3_column_origin_name(m_Stmt, m_Index);
return sqlite3_column_origin_name(m_Handle->mPtr, m_Index);
#else
STHROWF("The module was compiled without this feature");
// Request failed
@ -211,19 +400,55 @@ CSStr Column::GetOriginName() const
// ------------------------------------------------------------------------------------------------
Int32 Column::GetType() const
{
// Validate the column
Validate();
VALIDATE_CREATED_HND(*this);
// Return the requested information
return sqlite3_column_type(m_Stmt, m_Index);
return sqlite3_column_type(m_Handle->mPtr, m_Index);
}
// ------------------------------------------------------------------------------------------------
Int32 Column::GetBytes() const
{
// Validate the column
Validate();
VALIDATE_CREATED_HND(*this);
// Return the requested information
return sqlite3_column_bytes(m_Stmt, m_Index);
return sqlite3_column_bytes(m_Handle->mPtr, m_Index);
}
// ================================================================================================
void Register_Column(Table & sqlns)
{
sqlns.Bind(_SC("Column"),
Class< Column >(sqlns.GetVM(), _SC("SqSQLiteColumn"))
// Constructors
.Ctor()
.Ctor< const Column & >()
// Meta-methods
.Func(_SC("_cmp"), &Column::Cmp)
.SquirrelFunc(_SC("_typename"), &Column::Typename)
.Func(_SC("_tostring"), &Column::ToString)
// Properties
.Prop(_SC("IsValid"), &Column::IsValid)
.Prop(_SC("References"), &Column::GetRefCount)
.Prop(_SC("Index"), &Column::GetIndex)
.Prop(_SC("Statement"), &Column::GetNumber)
.Prop(_SC("Connection"), &Column::GetConnection)
.Prop(_SC("Value"), &Column::GetValue)
.Prop(_SC("Number"), &Column::GetNumber)
.Prop(_SC("Integer"), &Column::GetInteger)
.Prop(_SC("Float"), &Column::GetFloat)
.Prop(_SC("Long"), &Column::GetLong)
.Prop(_SC("String"), &Column::GetString)
.Prop(_SC("Boolean"), &Column::GetBoolean)
.Prop(_SC("Char"), &Column::GetChar)
.Prop(_SC("Buffer"), &Column::GetBuffer)
.Prop(_SC("Blob"), &Column::GetBlob)
.Prop(_SC("IsNull"), &Column::IsNull)
.Prop(_SC("Name"), &Column::GetName)
.Prop(_SC("OriginName"), &Column::GetOriginName)
.Prop(_SC("Type"), &Column::GetType)
.Prop(_SC("Bytes"), &Column::GetBytes)
// Member Methods
.Func(_SC("Release"), &Column::Release)
);
}
} // Namespace:: SqMod

View File

@ -8,7 +8,7 @@
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class used to manage statement columns.
* Tsed to manage and interact with statement columns.
*/
class Column
{
@ -21,23 +21,60 @@ private:
Int32 m_Index; // The index of the managed column.
// --------------------------------------------------------------------------------------------
StmtHnd m_Stmt; // The statement where the column exist.
StmtRef m_Handle; // The statement where the column exist.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and index, and throw an error if they're invalid.
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference, index and row, and throw an error if they're invalid.
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and row, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateRow(CCStr file, Int32 line) const;
#else
void ValidateRow() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
Column(const StmtHnd & stmt, Int32 idx)
: m_Index(idx), m_Stmt(stmt)
Column(const StmtRef & stmt, Int32 idx)
: m_Index(idx), m_Handle(stmt)
{
/* ... */
}
@ -48,7 +85,7 @@ public:
* Default constructor (null).
*/
Column()
: m_Index(-1), m_Stmt()
: m_Index(-1), m_Handle()
{
/* ... */
}
@ -56,29 +93,22 @@ public:
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Column(const Column & o)
: m_Index(o.m_Index), m_Stmt(o.m_Stmt)
{
/* ... */
}
Column(const Column & o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
* Move constructor.
*/
~Column()
{
/* Let the reference manager destroy the statement when necessary. */
}
Column(Column && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Column operator = (const Column & o)
{
m_Index = o.m_Index;
m_Stmt = o.m_Stmt;
return *this;
}
Column & operator = (const Column & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Column & operator = (Column && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connection handles.
@ -109,11 +139,11 @@ public:
*/
Int32 Cmp(const Column & o) const
{
if (m_Stmt == o.m_Stmt)
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Stmt.HndPtr() > o.m_Stmt.HndPtr())
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
@ -141,7 +171,7 @@ public:
*/
bool IsValid() const
{
return (bool)m_Stmt; // An invalid statement means an invalid column
return m_Handle; // An invalid statement means an invalid column
}
/* --------------------------------------------------------------------------------------------
@ -149,7 +179,7 @@ public:
*/
Uint32 GetRefCount() const
{
return m_Stmt.Count();
return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
@ -175,14 +205,19 @@ public:
*/
void Release()
{
m_Stmt = StmtHnd();
m_Handle.Reset();
m_Index = -1;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a 32bit integer.
* Retrieve the value inside the associated column cel as a dynamic type.
*/
Int32 GetNumber() const;
Object GetValue() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a numeric type.
*/
Object GetNumber() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a native script integer.
@ -209,16 +244,21 @@ public:
*/
bool GetBoolean() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a memory blob.
*/
Object GetBlob() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a character.
*/
SQChar GetChar() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a memory buffer.
*/
Object GetBuffer() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value inside the associated column cel as a memory blob.
*/
Object GetBlob() const;
/* --------------------------------------------------------------------------------------------
* Check whether the associated column is null.
*/

View File

@ -209,4 +209,20 @@ CCStr TableToQueryColumns(Table & tbl)
return GetTempBuff();
}
// ================================================================================================
void Register_Common(Table & sqlns)
{
sqlns.Func(_SC("IsQueryEmpty"), &IsQueryEmpty)
.Func(_SC("GetErrStr"), &GetErrStr)
.Func(_SC("SetSoftHeapLimit"), &SetSoftHeapLimit)
.Func(_SC("ReleaseMemory"), &ReleaseMemory)
.Func(_SC("MemoryUsage"), &GetMemoryUsage)
.Func(_SC("EscapeString"), &EscapeString)
.Func(_SC("EscapeStringEx"), &EscapeStringEx)
.Func(_SC("Escape"), &EscapeString)
.Func(_SC("EscapeEx"), &EscapeStringEx)
.Func(_SC("ArrayToQueryColumns"), &ArrayToQueryColumns)
.Func(_SC("TableToQueryColumns"), &TableToQueryColumns);
}
} // Namespace:: SqMod

View File

@ -31,6 +31,55 @@ class Transaction;
#define SQSQLITE_VERSION_MINOR 0
#define SQSQLITE_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Handle validation.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
#define VALIDATE_HND(x) (x).Validate(__FILE__, __LINE__)
#define VALIDATE_OPENED_HND(x) (x).ValidateOpened(__FILE__, __LINE__)
#define VALIDATE_CREATED_HND(x) (x).ValidateCreated(__FILE__, __LINE__)
#define VALIDATE_COLUMN_HND(x, i) (x).ValidateColumn((i), __FILE__, __LINE__)
#define VALIDATE_PARAMETER_HND(x, i) (x).ValidateParameter((i), __FILE__, __LINE__)
#define VALIDATE_ROW_HND(x) (x).ValidateRow(__FILE__, __LINE__)
#define GET_VALID_HND(x) (x).GetValid(__FILE__, __LINE__)
#define GET_OPENED_HND(x) (x).GetValid(__FILE__, __LINE__)
#define GET_CREATED_HND(x) (x).GetCreated(__FILE__, __LINE__)
#else
#define VALIDATE_HND(x) (x).Validate()
#define VALIDATE_OPENED_HND(x) (x).ValidateOpened()
#define VALIDATE_CREATED_HND(x) (x).ValidateCreated()
#define VALIDATE_COLUMN_HND(x, i) (x).ValidateColumn((i))
#define VALIDATE_PARAMETER_HND(x, i) (x).ValidateParameter((i))
#define VALIDATE_ROW_HND(x) (x).ValidateRow()
#define GET_VALID_HND(x) (x).GetValid()
#define GET_OPENED_HND(x) (x).GetValid()
#define GET_CREATED_HND(x) (x).GetCreated()
#endif // _DEBUG
/* ------------------------------------------------------------------------------------------------
* Helper macros for architecture differences.
*/
#ifdef _SQ64
#define sqlite3_bind_integer sqlite3_bind_int64
#define sqlite3_column_integer sqlite3_column_int64
#else
#define sqlite3_bind_integer sqlite3_bind_int
#define sqlite3_column_integer sqlite3_column_int
#endif
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
struct ConnHnd;
struct StmtHnd;
/* ------------------------------------------------------------------------------------------------
* Common typedefs.
*/
typedef SharedPtr< ConnHnd > ConnRef;
typedef SharedPtr< StmtHnd > StmtRef;
/* ------------------------------------------------------------------------------------------------
* Generate a formatted query.
*/

View File

@ -14,61 +14,148 @@ SQInteger Connection::Typename(HSQUIRRELVM vm)
}
// ------------------------------------------------------------------------------------------------
Connection::Connection()
: m_Handle()
void Connection::TraceOutput(void * /*ptr*/, CCStr sql)
{
/* ... */
_SqMod->LogInf("SQLite Trace: %s", sql);
}
// ------------------------------------------------------------------------------------------------
Connection::Connection(CSStr name)
: m_Handle(name)
void Connection::ProfileOutput(void * /*ptr*/, CCStr sql, sqlite3_uint64 time)
{
if (m_Handle.m_Hnd)
{
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
_SqMod->LogInf("SQLite profile (time: %llu): %s", time, sql);
}
// ------------------------------------------------------------------------------------------------
Connection::Connection(CSStr name, Int32 flags)
: m_Handle(name)
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::Validate(CCStr file, Int32 line) const
{
if (m_Handle.m_Hnd)
if (!m_Handle)
{
m_Handle->Create(name, flags, nullptr);
SqThrowF("Invalid SQLite connection reference =>[%s:%d]", file, line);
}
}
#else
void Connection::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Connection::ValidateOpened(CCStr file, Int32 line) const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference =>[%s:%d]", file, line);
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite connection =>[%s:%d]", file, line);
}
}
#else
void Connection::ValidateOpened() const
{
if (!m_Handle)
{
SqThrowF("Invalid SQLite connection reference");
}
else if (m_Handle->mPtr == nullptr)
{
SqThrowF("Invalid SQLite connection");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & Connection::GetOpened(CCStr file, Int32 line) const
{
ValidateOpened(file, line);
return m_Handle;
}
#else
const ConnRef & Connection::GetOpened() const
{
ValidateOpened();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
void Connection::Open(CSStr name)
{
// Make sure another database isn't opened
if (GET_VALID_HND(*this)->mPtr != nullptr)
{
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
// ------------------------------------------------------------------------------------------------
Connection::Connection(CSStr name, Int32 flags, CSStr vfs)
: m_Handle(name)
void Connection::Open(CSStr name, Int32 flags)
{
if (m_Handle.m_Hnd)
// Make sure another database isn't opened
if (GET_VALID_HND(*this)->mPtr != nullptr)
{
m_Handle->Create(name, flags, vfs);
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name, flags, nullptr);
}
// ------------------------------------------------------------------------------------------------
void Connection::Open(CSStr name, Int32 flags, CSStr vfs)
{
// Make sure another database isn't opened
if (GET_VALID_HND(*this)->mPtr != nullptr)
{
STHROWF("Already referencing a valid database connection");
}
// Perform the requested operation
m_Handle->Create(name, flags, vfs);
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Exec(CSStr str)
{
// Validate the handle
m_Handle.Validate();
VALIDATE_OPENED_HND(*this);
// Attempt to execute the specified query
if ((m_Handle = sqlite3_exec(m_Handle, str, nullptr, nullptr, nullptr)) != SQLITE_OK)
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, str, nullptr, nullptr, nullptr);
// Validate the execution result
if (m_Handle->mStatus != 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 sqlite3_changes(m_Handle);
return sqlite3_changes(m_Handle->mPtr);
}
// ------------------------------------------------------------------------------------------------
Object Connection::Query(CSStr str) const
{
// Validate the handle
m_Handle.Validate();
VALIDATE_OPENED_HND(*this);
// Return the requested information
return Object(new Statement(m_Handle, str));
}
@ -76,8 +163,7 @@ Object Connection::Query(CSStr str) const
// ------------------------------------------------------------------------------------------------
void Connection::Queue(CSStr str)
{
// Validate the handle
m_Handle.Validate();
VALIDATE_HND(*this);
// Is there a query to commit?
if (IsQueryEmpty(str))
{
@ -90,10 +176,8 @@ void Connection::Queue(CSStr str)
// ------------------------------------------------------------------------------------------------
bool Connection::IsReadOnly() const
{
// Validate the handle
m_Handle.Validate();
// Request the desired information
const int result = sqlite3_db_readonly(m_Handle, "main");
const int result = sqlite3_db_readonly(GET_OPENED_HND(*this)->mPtr, "main");
// Verify the result
if (result == -1)
{
@ -106,15 +190,13 @@ bool Connection::IsReadOnly() const
// ------------------------------------------------------------------------------------------------
bool Connection::TableExists(CCStr name) const
{
// Validate the handle
m_Handle.Validate();
// Prepare a statement to inspect the master table
Statement stmt(m_Handle, "SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
Statement stmt(GET_OPENED_HND(*this), "SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
// Could the statement be created?
if (stmt.IsValid())
{
// Bind the specified name onto the statement parameter
stmt.IndexBindS(1, name);
stmt.IndexBindString(1, name);
// Attempt to step the statement and obtain a value
if (stmt.Step())
{
@ -126,42 +208,66 @@ bool Connection::TableExists(CCStr name) const
}
// ------------------------------------------------------------------------------------------------
Object Connection::GetLastInsertRowID() const
void Connection::SetTracing(bool toggle)
{
// Validate the handle
m_Handle.Validate();
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, sqlite3_last_insert_rowid(m_Handle));
// Get the object from the stack and return it
return Var< Object >(_SqVM, -1).value;
// Check whether changes are necessary
if (GET_OPENED_HND(*this)->mTrace == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mTrace)
{
sqlite3_trace(m_Handle->mPtr, nullptr, nullptr);
}
// Go ahead and enable tracing
else
{
sqlite3_trace(m_Handle->mPtr, &Connection::TraceOutput, nullptr);
}
}
// ------------------------------------------------------------------------------------------------
void Connection::SetProfiling(bool toggle)
{
// Check whether changes are necessary
if (GET_OPENED_HND(*this)->mProfile == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mProfile)
{
sqlite3_profile(m_Handle->mPtr, nullptr, nullptr);
}
// Go ahead and enable profiling
else
{
sqlite3_profile(m_Handle->mPtr, &Connection::ProfileOutput, nullptr);
}
}
// ------------------------------------------------------------------------------------------------
void Connection::SetBusyTimeout(Int32 millis)
{
// Validate the handle
m_Handle.Validate();
// Apply requested timeout
if ((m_Handle = sqlite3_busy_timeout(m_Handle, millis)) != SQLITE_OK)
VALIDATE_OPENED_HND(*this);
// Apply the requested timeout
if ((m_Handle->mStatus = sqlite3_busy_timeout(m_Handle->mPtr, millis)) != SQLITE_OK)
{
STHROWF("Unable to set busy timeout [%s]", m_Handle.ErrMsg());
STHROWF("Unable to set busy timeout [%s]", m_Handle->ErrMsg());
}
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
{
// Don't even bother to continue if there's no valid connection handle
m_Handle.Validate();
// Where to retrieve the information
Int32 cur_value;
Int32 hiwtr_value;
// 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->mStatus = sqlite3_db_status(GET_OPENED_HND(*this)->mPtr, 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
else if (highwater)
@ -175,42 +281,52 @@ Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
// ------------------------------------------------------------------------------------------------
void Connection::ReserveQueue(Uint32 num)
{
// Validate the handle
m_Handle.Validate();
VALIDATE_HND(*this);
// Perform the requested operation
m_Handle->mQueue.reserve(m_Handle->mQueue.size() + num);
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(Uint32 num)
void Connection::PopQueue()
{
// Validate the handle
m_Handle.Validate();
// We need to supply a null callback
Object env;
Function func;
// Attempt to flush the requested amount of queries
return m_Handle->Flush(num, env, func);
VALIDATE_HND(*this);
// Perform the requested operation
if (!GET_VALID_HND(*this)->mQueue.empty())
{
m_Handle->mQueue.pop_back();
}
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(Uint32 num, Object & env, Function & func)
Int32 Connection::Flush()
{
// Validate the handle
m_Handle.Validate();
// Attempt to flush the requested amount of queries
return m_Handle->Flush(num, env, func);
VALIDATE_OPENED_HND(*this);
// Perform the requested operation
return m_Handle->Flush(m_Handle->mQueue.size(), NullObject(), NullFunction());
}
// ------------------------------------------------------------------------------------------------
void Connection::TraceOutput(void * /*ptr*/, CCStr sql)
Int32 Connection::Flush(SQInteger num)
{
_SqMod->LogInf("SQLite Trace: %s", sql);
VALIDATE_OPENED_HND(*this);
// Perform the requested operation
return m_Handle->Flush(ConvTo< Uint32 >::From(num), NullObject(), NullFunction());
}
void Connection::ProfileOutput(void * /*ptr*/, CCStr sql, sqlite3_uint64 time)
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(Object & env, Function & func)
{
_SqMod->LogInf("SQLite profile (time: %llu): %s", time, sql);
VALIDATE_OPENED_HND(*this);
// Perform the requested operation
return m_Handle->Flush(m_Handle->mQueue.size(), env, func);
}
// ------------------------------------------------------------------------------------------------
Int32 Connection::Flush(SQInteger num, Object & env, Function & func)
{
VALIDATE_OPENED_HND(*this);
// Perform the requested operation
return m_Handle->Flush(ConvTo< Uint32 >::From(num), env, func);
}
// ------------------------------------------------------------------------------------------------
@ -252,12 +368,14 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
return val.mRes; // Propagate the error!
}
// Attempt to execute the specified query
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, val.mPtr, nullptr, nullptr, nullptr)) != SQLITE_OK)
conn->m_Handle->mStatus = sqlite3_exec(conn->m_Handle->mPtr, val.mPtr, nullptr, nullptr, nullptr);
// Validate the result
if (conn->m_Handle->mStatus != SQLITE_OK)
{
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", conn->m_Handle.ErrMsg()));
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", conn->m_Handle->ErrMsg()));
}
// Push the number of changes onto the stack
sq_pushinteger(vm, sqlite3_changes(conn->m_Handle));
sq_pushinteger(vm, sqlite3_changes(conn->m_Handle->mPtr));
// This function returned a value
return 1;
}
@ -301,7 +419,7 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
return val.mRes; // Propagate the error!
}
// Attempt to queue the specified query
conn->m_Handle->mQueue.emplace_back(val.mPtr);
conn->m_Handle->mQueue.emplace_back(val.mPtr, val.mLen);
// This function does not return a value
return 0;
}
@ -357,4 +475,70 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
return 1;
}
// ================================================================================================
void Register_Connection(Table & sqlns)
{
sqlns.Bind(_SC("Connection"),
Class< Connection >(sqlns.GetVM(), _SC("SqSQLiteConnection"))
// Constructors
.Ctor()
.Ctor< CCStr >()
.Ctor< CCStr, Int32 >()
.Ctor< CCStr, Int32, CCStr >()
// Meta-methods
.Func(_SC("_cmp"), &Connection::Cmp)
.SquirrelFunc(_SC("_typename"), &Connection::Typename)
.Func(_SC("_tostring"), &Connection::ToString)
// Properties
.Prop(_SC("IsValid"), &Connection::IsValid)
.Prop(_SC("Connected"), &Connection::IsConnected)
.Prop(_SC("References"), &Connection::GetRefCount)
.Prop(_SC("Status"), &Connection::GetStatus)
.Prop(_SC("Flags"), &Connection::GetFlags)
.Prop(_SC("Name"), &Connection::GetName)
.Prop(_SC("VFS"), &Connection::GetVFS)
.Prop(_SC("ErrCode"), &Connection::GetErrorCode)
.Prop(_SC("ExErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ExtendedErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ErrStr"), &Connection::GetErrStr)
.Prop(_SC("ErrMsg"), &Connection::GetErrMsg)
.Prop(_SC("ReadOnly"), &Connection::IsReadOnly)
.Prop(_SC("Autocommit"), &Connection::GetAutoCommit)
.Prop(_SC("LastInsertRowId"), &Connection::GetLastInsertRowID)
.Prop(_SC("Changes"), &Connection::GetChanges)
.Prop(_SC("TotalChanges"), &Connection::GetTotalChanges)
.Prop(_SC("Trace"), &Connection::GetTracing, &Connection::SetTracing)
.Prop(_SC("Profile"), &Connection::GetProfiling, &Connection::SetProfiling)
.Prop(_SC("QueueSize"), &Connection::QueueSize)
// Member Methods
.Func(_SC("Release"), &Connection::Release)
.Func(_SC("Exec"), &Connection::Exec)
.Func(_SC("Queue"), &Connection::Queue)
.Func(_SC("Query"), &Connection::Query)
.Func(_SC("TableExists"), &Connection::TableExists)
.Func(_SC("InterruptOperation"), &Connection::InterruptOperation)
.Func(_SC("SetBusyTimeout"), &Connection::SetBusyTimeout)
.Func(_SC("ReleaseMemory"), &Connection::ReleaseMemory)
.Func(_SC("ReserveQueue"), &Connection::ReserveQueue)
.Func(_SC("CompactQueue"), &Connection::CompactQueue)
.Func(_SC("ClearQueue"), &Connection::ClearQueue)
.Func(_SC("PopQueue"), &Connection::PopQueue)
// Member Overloads
.Overload< void (Connection::*)(CSStr) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(CSStr, Int32) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(CSStr, Int32, CSStr) >(_SC("Open"), &Connection::Open)
.Overload< Int32 (Connection::*)(Int32) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(void) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(SQInteger) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(Object &, Function &) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(SQInteger, Object &, Function &) >(_SC("Flush"), &Connection::Flush)
// Squirrel Methods
.SquirrelFunc(_SC("ExecF"), &Connection::ExecF)
.SquirrelFunc(_SC("QueueF"), &Connection::QueueF)
.SquirrelFunc(_SC("QueryF"), &Connection::QueryF)
);
}
} // Namespace:: SqMod

View File

@ -8,7 +8,7 @@
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to manage a connection to an SQLite database.
* Used to manage and interact with a database connection.
*/
class Connection
{
@ -22,35 +22,99 @@ protected:
private:
// --------------------------------------------------------------------------------------------
ConnHnd m_Handle; // The handle to the managed database connection resource.
ConnRef m_Handle; // Reference to the managed connection.
protected:
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateTracing()
*/
static void TraceOutput(void * ptr, CCStr sql);
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateProfiling()
*/
static void ProfileOutput(void * ptr, CCStr sql, sqlite3_uint64 time);
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateOpened(CCStr file, Int32 line) const;
#else
void ValidateOpened() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetValid(CCStr file, Int32 line) const;
#else
const ConnRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & GetOpened(CCStr file, Int32 line) const;
#else
const ConnRef & GetOpened() const;
#endif // _DEBUG
public:
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
Connection();
Connection()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(CSStr name);
Connection(CSStr name)
: m_Handle(new ConnHnd())
{
GET_VALID_HND(*this)->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(CSStr name, Int32 flags);
Connection(CSStr name, Int32 flags)
: m_Handle(new ConnHnd())
{
GET_VALID_HND(*this)->Create(name, flags, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Connection(CSStr name, Int32 flags, CSStr vfs);
Connection(CSStr name, Int32 flags, CSStr vfs)
: m_Handle(new ConnHnd())
{
GET_VALID_HND(*this)->Create(name, flags, vfs);
}
/* --------------------------------------------------------------------------------------------
* Direct handle constructor.
*/
Connection(const ConnHnd & h)
: m_Handle(h)
Connection(const ConnRef & c)
: m_Handle(c)
{
/* ... */
}
@ -58,28 +122,22 @@ public:
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Connection(const Connection & o)
: m_Handle(o.m_Handle)
{
/* ... */
}
Connection(const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
* Move constructor.
*/
~Connection()
{
/* Let the reference manager destroy the connection when necessary. */
}
Connection(Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Connection & operator = (const Connection & o)
{
m_Handle = o.m_Handle;
return *this;
}
Connection & operator = (const Connection & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Connection & operator = (Connection && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connections.
@ -102,7 +160,7 @@ public:
*/
operator sqlite3 * ()
{
return m_Handle;
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
@ -110,7 +168,7 @@ public:
*/
operator sqlite3 * () const
{
return m_Handle;
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
@ -118,11 +176,11 @@ public:
*/
Int32 Cmp(const Connection & o) const
{
if (m_Handle == m_Handle)
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
@ -135,12 +193,9 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
const String & ToString() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mName.c_str();
return m_Handle ? m_Handle->mName : NullString();
}
/* --------------------------------------------------------------------------------------------
@ -149,7 +204,15 @@ public:
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this connection is valid.
* Retrieve the associated connection handle.
*/
const ConnRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed connection handle is valid.
*/
bool IsValid() const
{
@ -157,11 +220,11 @@ public:
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated connection handle.
* See whether the managed connection handle was connected.
*/
const ConnHnd & GetHandle() const
bool IsConnected() const
{
return m_Handle;
return m_Handle && (m_Handle->mPtr != nullptr);
}
/* --------------------------------------------------------------------------------------------
@ -177,7 +240,7 @@ public:
*/
void Release()
{
m_Handle.Drop();
m_Handle.Reset();
}
/* --------------------------------------------------------------------------------------------
@ -185,10 +248,7 @@ public:
*/
Int32 GetStatus() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mStatus;
return GET_VALID_HND(*this)->mStatus;
}
/* --------------------------------------------------------------------------------------------
@ -196,32 +256,23 @@ public:
*/
Int32 GetFlags() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mFlags;
return GET_VALID_HND(*this)->mFlags;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the name used to create this database connection.
*/
CSStr GetName() const
const String & GetName() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mName.c_str();
return GET_VALID_HND(*this)->mName;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the virtual file system used to create this database connection.
*/
CSStr GetVFS() const
const String GetVFS() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mVFS.c_str();
return GET_VALID_HND(*this)->mVFS;
}
/* --------------------------------------------------------------------------------------------
@ -229,10 +280,7 @@ public:
*/
Int32 GetErrorCode() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrNo();
return GET_VALID_HND(*this)->ErrNo();
}
/* --------------------------------------------------------------------------------------------
@ -240,10 +288,7 @@ public:
*/
Int32 GetExtendedErrorCode() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ExErrNo();
return GET_VALID_HND(*this)->ExErrNo();
}
/* --------------------------------------------------------------------------------------------
@ -251,10 +296,7 @@ public:
*/
CSStr GetErrStr() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrStr();
return GET_VALID_HND(*this)->ErrStr();
}
/* --------------------------------------------------------------------------------------------
@ -262,44 +304,23 @@ public:
*/
CSStr GetErrMsg() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrMsg();
return GET_VALID_HND(*this)->ErrMsg();
}
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(CSStr name)
{
if (m_Handle.m_Hnd)
{
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
}
}
void Open(CSStr name);
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(CSStr name, Int32 flags)
{
if (m_Handle.m_Hnd)
{
m_Handle->Create(name, flags, nullptr);
}
}
void Open(CSStr name, Int32 flags);
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
void Open(CSStr name, Int32 flags, CSStr vfs)
{
if (m_Handle.m_Hnd)
{
m_Handle->Create(name, flags, vfs);
}
}
void Open(CSStr name, Int32 flags, CSStr vfs);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
@ -331,16 +352,16 @@ public:
*/
bool GetAutoCommit() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return sqlite3_get_autocommit(m_Handle);
return sqlite3_get_autocommit(GET_OPENED_HND(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Get the row-id of the most recent successful INSERT into the database from the current connection.
*/
Object GetLastInsertRowID() const;
Object GetLastInsertRowID() const
{
return MakeSLongObj(sqlite3_last_insert_rowid(GET_OPENED_HND(*this)->mPtr));
}
/* --------------------------------------------------------------------------------------------
* Returns the number of database rows that were changed, inserted or deleted
@ -348,10 +369,7 @@ public:
*/
Int32 GetChanges() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return sqlite3_changes(m_Handle);
return sqlite3_changes(GET_OPENED_HND(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -360,10 +378,7 @@ public:
*/
Int32 GetTotalChanges() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return sqlite3_total_changes(m_Handle);
return sqlite3_total_changes(GET_OPENED_HND(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -371,70 +386,26 @@ public:
*/
bool GetTracing() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mTrace;
return GET_VALID_HND(*this)->mTrace;
}
/* --------------------------------------------------------------------------------------------
* Activate or deactivate tracing on this database connection.
*/
void SetTracing(bool toggle)
{
// Validate the handle
m_Handle.Validate();
// Check whether changes are necessary
if (m_Handle->mTrace == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mTrace)
{
sqlite3_trace(m_Handle, nullptr, nullptr);
}
// Go ahead and enable tracing
else
{
sqlite3_trace(m_Handle, &Connection::TraceOutput, nullptr);
}
}
void SetTracing(bool toggle);
/* --------------------------------------------------------------------------------------------
* See if this database connection has profiling enabled.
*/
bool GetProfiling() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mProfile;
return GET_VALID_HND(*this)->mProfile;
}
/* --------------------------------------------------------------------------------------------
* Activate or deactivate profiling on this database connection.
*/
void SetProfiling(bool toggle)
{
// Validate the handle
m_Handle.Validate();
// Check whether changes are necessary
if (m_Handle->mProfile == toggle)
{
return; // No point in proceeding
}
// Do we have to disable it?
else if (m_Handle->mProfile)
{
sqlite3_profile(m_Handle, nullptr, nullptr);
}
// Go ahead and enable profiling
else
{
sqlite3_profile(m_Handle, &Connection::ProfileOutput, nullptr);
}
}
void SetProfiling(bool toggle);
/* --------------------------------------------------------------------------------------------
* Set a busy handler that sleeps for a specified amount of time when a table is locked.
@ -446,10 +417,7 @@ public:
*/
void InterruptOperation() const
{
// Validate the handle
m_Handle.Validate();
// Perform the requested action
sqlite3_interrupt(m_Handle);
sqlite3_interrupt(GET_OPENED_HND(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -457,10 +425,7 @@ public:
*/
void ReleaseMemory() const
{
// Validate the handle
m_Handle.Validate();
// Perform the requested action
sqlite3_db_release_memory(m_Handle);
sqlite3_db_release_memory(GET_OPENED_HND(*this)->mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -474,7 +439,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Returns internal runtime status information associated with the current database connection.
*/
Int32 GetInfo(Int32 operation, bool highwater = false)
Int32 GetInfo(Int32 operation, bool highwater)
{
return GetInfo(operation, highwater, false);
}
@ -482,17 +447,14 @@ public:
/* --------------------------------------------------------------------------------------------
* Returns internal runtime status information associated with the current database connection.
*/
Int32 GetInfo(Int32 operation, bool highwater = false, bool reset = false);
Int32 GetInfo(Int32 operation, bool highwater, bool reset);
/* --------------------------------------------------------------------------------------------
* Retrieve the number of queries in the queue.
*/
Uint32 QueueSize() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return (Uint32)m_Handle->mQueue.size();
return ConvTo< Uint32 >::From(GET_VALID_HND(*this)->mQueue.size());
}
/* --------------------------------------------------------------------------------------------
@ -505,10 +467,7 @@ public:
*/
void CompactQueue()
{
// Validate the handle
m_Handle.Validate();
// Perform the requested operation
m_Handle->mQueue.shrink_to_fit();
GET_VALID_HND(*this)->mQueue.shrink_to_fit();
}
/* --------------------------------------------------------------------------------------------
@ -516,57 +475,33 @@ public:
*/
void ClearQueue()
{
// Validate the handle
m_Handle.Validate();
// Perform the requested operation
m_Handle->mQueue.clear();
GET_VALID_HND(*this)->mQueue.clear();
}
/* --------------------------------------------------------------------------------------------
* Remove the last query from the queue.
*/
void PopQueue()
{
// Validate the handle
m_Handle.Validate();
// Perform the requested action
if (!m_Handle->mQueue.empty())
{
m_Handle->mQueue.pop_back();
}
}
void PopQueue();
/* --------------------------------------------------------------------------------------------
* Flush all queries from the queue.
*/
Int32 Flush()
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return Flush(m_Handle->mQueue.size());
}
Int32 Flush();
/* --------------------------------------------------------------------------------------------
* Flush a specific amount of queries from the queue.
*/
Int32 Flush(Uint32 num);
Int32 Flush(SQInteger num);
/* --------------------------------------------------------------------------------------------
* Flush all queries from the queue and handle errors manually.
*/
Int32 Flush(Object & env, Function & func)
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return Flush(m_Handle->mQueue.size(), env, func);
}
Int32 Flush(Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Flush a specific amount of queries from the queue and handle errors manually.
*/
Int32 Flush(Uint32 num, Object & env, Function & func);
Int32 Flush(SQInteger num, Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query.
@ -582,18 +517,6 @@ public:
* Attempt to create a statement from the specified query.
*/
static SQInteger QueryF(HSQUIRRELVM vm);
protected:
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateTracing()
*/
static void TraceOutput(void * ptr, const char * sql);
/* --------------------------------------------------------------------------------------------
* Callback function for ActivateProfiling()
*/
static void ProfileOutput(void * ptr, const char * sql, sqlite3_uint64 time);
};
} // Namespace:: SqMod

View File

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

View File

@ -5,36 +5,29 @@
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void ConnHnd::Validate() const
ConnHnd::ConnHnd()
: mPtr(nullptr)
, mStatus(SQLITE_OK)
, mQueue()
, mFlags(0)
, mName()
, mVFS()
, mMemory(false)
, mTrace(false)
, mProfile(false)
{
// Is the handle valid?
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
{
STHROWF("Invalid SQLite connection reference");
}
/* ... */
}
// ------------------------------------------------------------------------------------------------
ConnHnd::Handle::~Handle()
ConnHnd::~ConnHnd()
{
// Is there anything to close?
if (!mPtr)
if (mPtr != nullptr)
{
return; // Nothing to close
}
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
else if (mRef != 0)
{
// 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());
}
else
{
// NOTE: Should we call sqlite3_interrupt(...) before closing?
Object env;
Function func;
// Flush remaining queries in the queue and ignore the result
Flush(mQueue.size(), env, func);
Flush(mQueue.size(), NullObject(), NullFunction());
// NOTE: Should we call sqlite3_interrupt(...) before closing?
// Attempt to close the database
if ((sqlite3_close(mPtr)) != SQLITE_OK)
{
@ -44,7 +37,7 @@ ConnHnd::Handle::~Handle()
}
// ------------------------------------------------------------------------------------------------
void ConnHnd::Handle::Create(CSStr name, Int32 flags, CSStr vfs)
void ConnHnd::Create(CSStr name, Int32 flags, CSStr vfs)
{
// Make sure a previous connection doesn't exist
if (mPtr)
@ -63,7 +56,7 @@ void ConnHnd::Handle::Create(CSStr name, Int32 flags, CSStr vfs)
String msg(sqlite3_errmsg(mPtr) ? sqlite3_errmsg(mPtr) : _SC("Unknown reason"));
// Must be destroyed regardless of result
sqlite3_close(mPtr);
// Explicitly make sure it's null
// Prevent further use of this handle
mPtr = nullptr;
// Now its safe to throw the error
STHROWF("Unable to connect to database [%s]", msg.c_str());
@ -77,7 +70,7 @@ void ConnHnd::Handle::Create(CSStr name, Int32 flags, CSStr vfs)
}
// ------------------------------------------------------------------------------------------------
Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
Int32 ConnHnd::Flush(Uint32 num, Object & env, Function & func)
{
// Do we even have a valid connection?
if (!mPtr)
@ -167,4 +160,4 @@ Int32 ConnHnd::Handle::Flush(Uint32 num, Object & env, Function & func)
return -1;
}
} // Namespace:: SqMod
} // Namespace:: SqMod

View File

@ -11,14 +11,10 @@
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted database connection handle.
* The structure that holds the data associated with a certain connection.
*/
class ConnHnd
struct ConnHnd
{
// --------------------------------------------------------------------------------------------
friend class Connection;
friend class Statement;
public:
// --------------------------------------------------------------------------------------------
@ -32,334 +28,76 @@ public:
typedef Type& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; // Reference counter type.
/* --------------------------------------------------------------------------------------------
* Validate the connection handle and throw an error if invalid.
*/
void Validate() const;
protected:
// --------------------------------------------------------------------------------------------
typedef std::vector< String > QueryList; // Container used to queue queries.
/* --------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain connection.
*/
struct Handle
{
// ----------------------------------------------------------------------------------------
Pointer mPtr; // The connection handle resource.
Counter mRef; // Reference count to the managed handle.
// ----------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// ----------------------------------------------------------------------------------------
QueryList mQueue; // A queue of queries to be executed in groups.
// ----------------------------------------------------------------------------------------
Int32 mFlags; // The flags used to create the database connection handle.
String mName; // The specified name to be used as the database file.
String mVFS; // The specified virtual file system.
// ----------------------------------------------------------------------------------------
bool mMemory; // Whether the database exists in memory and not disk.
bool mTrace; // Whether tracing was activated on the database.
bool mProfile; // Whether profiling was activated on the database.
/* ----------------------------------------------------------------------------------------
* Base constructor.
*/
Handle(Counter counter)
: mPtr(nullptr)
, mRef(counter)
, mStatus(SQLITE_OK)
, mQueue()
, mFlags(0)
, mName()
, mVFS()
, mMemory(false)
, mTrace(false)
, mProfile(false)
{
/* ... */
}
/* ----------------------------------------------------------------------------------------
* Destructor.
*/
~Handle();
/* ----------------------------------------------------------------------------------------
* Create the database connection resource.
*/
void Create(CSStr name, Int32 flags, CSStr vfs);
/* ----------------------------------------------------------------------------------------
* Execute a specific amount of queries from the queue.
*/
Int32 Flush(Uint32 num, Object & env, Function & func);
};
private:
// --------------------------------------------------------------------------------------------
Handle * m_Hnd; // The managed handle instance.
/* --------------------------------------------------------------------------------------------
* Grab a strong reference to a connection handle.
*/
void Grab()
{
if (m_Hnd)
{
++(m_Hnd->mRef);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a connection handle.
*/
void Drop()
{
if (m_Hnd && --(m_Hnd->mRef) == 0)
{
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
ConnHnd(CSStr name)
: m_Hnd(name ? new Handle(1) : nullptr)
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
ConnHnd()
: m_Hnd(nullptr)
{
/* ... */
}
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The connection handle resource.
// --------------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// --------------------------------------------------------------------------------------------
QueryList mQueue; // A queue of queries to be executed in groups.
// --------------------------------------------------------------------------------------------
Int32 mFlags; // The flags used to create the database connection handle.
String mName; // The specified name to be used as the database file.
String mVFS; // The specified virtual file system.
// --------------------------------------------------------------------------------------------
bool mMemory; // Whether the database exists in memory and not disk.
bool mTrace; // Whether tracing was activated on the database.
bool mProfile; // Whether profiling was activated on the database.
/* --------------------------------------------------------------------------------------------
* Copy constructor.
* Default constructor.
*/
ConnHnd(const ConnHnd & o)
: m_Hnd(o.m_Hnd)
{
Grab();
}
ConnHnd();
/* --------------------------------------------------------------------------------------------
* Move constructor.
* Copy constructor. (disabled)
*/
ConnHnd(ConnHnd && o)
: m_Hnd(o.m_Hnd)
{
o.m_Hnd = nullptr;
}
ConnHnd(const ConnHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
ConnHnd(ConnHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ConnHnd()
{
Drop();
}
~ConnHnd();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
* Copy assignment operator. (disabled)
*/
ConnHnd & operator = (const ConnHnd & o)
{
if (m_Hnd != o.m_Hnd)
{
Drop();
m_Hnd = o.m_Hnd;
Grab();
}
return *this;
}
ConnHnd & operator = (const ConnHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
* Move assignment operator. (disabled)
*/
ConnHnd & operator = (ConnHnd && o)
{
if (m_Hnd != o.m_Hnd)
{
m_Hnd = o.m_Hnd;
o.m_Hnd = nullptr;
}
return *this;
}
ConnHnd & operator = (ConnHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Status assignment operator.
* Create the database connection resource.
*/
ConnHnd & operator = (Int32 status)
{
if (m_Hnd)
{
m_Hnd->mStatus = status;
}
return *this;
}
void Create(CSStr name, Int32 flags, CSStr vfs);
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connection handles.
* Execute a specific amount of queries from the queue.
*/
bool operator == (const ConnHnd & o) const
{
return (m_Hnd == o.m_Hnd);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two connection handles.
*/
bool operator != (const ConnHnd & o) const
{
return (m_Hnd != o.m_Hnd);
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison with an integer value status.
*/
bool operator == (Int32 status) const
{
if (m_Hnd)
{
return (m_Hnd->mStatus == status);
}
return false;
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison with an integer value status.
*/
bool operator != (Int32 status) const
{
if (m_Hnd)
{
return (m_Hnd->mStatus != status);
}
return false;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Hnd && m_Hnd->mPtr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Pointer ()
{
return m_Hnd ? m_Hnd->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Pointer () const
{
return m_Hnd ? m_Hnd->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Reference ()
{
assert(m_Hnd && m_Hnd->mPtr);
return *(m_Hnd->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator ConstRef () const
{
assert(m_Hnd && m_Hnd->mPtr);
return *(m_Hnd->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Handle * operator -> () const
{
assert(m_Hnd);
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Handle & operator * () const
{
assert(m_Hnd);
return *m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw handle structure pointer.
*/
Handle * HndPtr()
{
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw handle structure pointer.
*/
Handle * HndPtr() const
{
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return m_Hnd ? m_Hnd->mRef : 0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last known status code.
*/
Int32 Status() const
{
return m_Hnd ? m_Hnd->mStatus : SQLITE_NOMEM;
}
Int32 Flush(Uint32 num, Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CCStr ErrStr() const
{
// SQLite does it's null pointer validations internally
if (m_Hnd)
{
return sqlite3_errstr(sqlite3_errcode(m_Hnd->mPtr));
}
return _SC("");
return sqlite3_errstr(sqlite3_errcode(mPtr));
}
/* --------------------------------------------------------------------------------------------
@ -367,12 +105,7 @@ public:
*/
CCStr ErrMsg() const
{
// SQLite does it's null pointer validations internally
if (m_Hnd)
{
return sqlite3_errmsg(m_Hnd->mPtr);
}
return _SC("");
return sqlite3_errmsg(mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -380,12 +113,7 @@ public:
*/
Int32 ErrNo() const
{
// SQLite does it's null pointer validations internally
if (m_Hnd)
{
return sqlite3_errcode(m_Hnd->mPtr);
}
return SQLITE_NOMEM;
return sqlite3_errcode(mPtr);
}
/* --------------------------------------------------------------------------------------------
@ -393,12 +121,7 @@ public:
*/
Int32 ExErrNo() const
{
// SQLite does it's null pointer validations internally
if (m_Hnd)
{
return sqlite3_extended_errcode(m_Hnd->mPtr);
}
return SQLITE_NOMEM;
return sqlite3_extended_errcode(mPtr);
}
};

View File

@ -1,45 +1,41 @@
// ------------------------------------------------------------------------------------------------
#include "Handle/Statement.hpp"
#include "Handle/Connection.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void StmtHnd::Validate() const
StmtHnd::StmtHnd(const ConnRef & conn)
: mPtr(nullptr)
, mStatus(SQLITE_OK)
, mConn(conn)
, mQuery()
, mColumns(0)
, mParameters(0)
, mIndexes()
, mGood(false)
, mDone(false)
{
// Is the handle valid?
if ((m_Hnd == nullptr) || (m_Hnd->mPtr == nullptr))
{
STHROWF("Invalid SQLite statement reference");
}
/* ... */
}
// ------------------------------------------------------------------------------------------------
StmtHnd::Handle::~Handle()
StmtHnd::~StmtHnd()
{
// Is there anything to finalize?
if (!mPtr)
{
return; // Nothing to finalize
}
// Are we dealing with a memory leak? Technically shouldn't reach this situation!
else if (mRef != 0)
{
// 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());
}
else
if (mPtr != nullptr)
{
// Attempt to finalize the statement
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());
}
}
}
// ------------------------------------------------------------------------------------------------
void StmtHnd::Handle::Create(CSStr query)
void StmtHnd::Create(CSStr query)
{
// Make sure a previous statement doesn't exist
if (mPtr)
@ -59,7 +55,7 @@ void StmtHnd::Handle::Create(CSStr query)
STHROWF("Unable to prepare statement. Invalid 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->mPtr, mQuery.c_str(), (Int32)mQuery.size(),
&mPtr, nullptr)) != SQLITE_OK)
{
// Clear the query string since it failed
@ -67,17 +63,19 @@ void StmtHnd::Handle::Create(CSStr query)
// Explicitly make sure the handle is null
mPtr = nullptr;
// Now it's safe to throw the error
STHROWF("Unable to prepare statement [%s]", mConn.ErrMsg());
STHROWF("Unable to prepare statement [%s]", mConn->ErrMsg());
}
else
{
// Obtain the number of available columns
mColumns = sqlite3_column_count(mPtr);
// Obtain the number of available parameters
mParameters = sqlite3_bind_parameter_count(mPtr);
}
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::Handle::GetColumnIndex(CSStr name)
Int32 StmtHnd::GetColumnIndex(CSStr name)
{
// Validate the handle
if (!mPtr)
@ -114,4 +112,28 @@ Int32 StmtHnd::Handle::GetColumnIndex(CSStr name)
return -1;
}
} // Namespace:: SqMod
// ------------------------------------------------------------------------------------------------
CCStr StmtHnd::ErrStr() const
{
return mConn ? sqlite3_errstr(sqlite3_errcode(mConn->mPtr)) : _SC("");
}
// ------------------------------------------------------------------------------------------------
CCStr StmtHnd::ErrMsg() const
{
return mConn ? sqlite3_errmsg(mConn->mPtr) : _SC("");
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::ErrNo() const
{
return mConn ? sqlite3_errcode(mConn->mPtr) : SQLITE_NOMEM;
}
// ------------------------------------------------------------------------------------------------
Int32 StmtHnd::ExErrNo() const
{
return mConn ? sqlite3_extended_errcode(mConn->mPtr) : SQLITE_NOMEM;
}
} // Namespace:: SqMod

View File

@ -2,7 +2,7 @@
#define _SQSQLITE_HANDLE_STATEMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Handle/Connection.hpp"
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
#include <map>
@ -11,14 +11,10 @@
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted database statement handle.
* The structure that holds the data associated with a certain statement.
*/
class StmtHnd
struct StmtHnd
{
// --------------------------------------------------------------------------------------------
friend class Connection;
friend class Statement;
public:
// --------------------------------------------------------------------------------------------
@ -32,379 +28,107 @@ public:
typedef Type& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; // Reference counter type.
/* --------------------------------------------------------------------------------------------
* Validate the statement handle and throw an error if invalid.
*/
void Validate() const;
protected:
// --------------------------------------------------------------------------------------------
typedef std::map< String, int > Indexes; // Container used to identify column indexes.
/* --------------------------------------------------------------------------------------------
* The structure that holds the data associated with a certain statement.
*/
struct Handle
{
// ----------------------------------------------------------------------------------------
Pointer mPtr; // The statement handle resource.
Counter mRef; // Reference count to the managed handle.
// ----------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// ----------------------------------------------------------------------------------------
ConnHnd mConn; // The handle to the associated database connection.
// ----------------------------------------------------------------------------------------
String mQuery; // The query string used to create this statement.
// ----------------------------------------------------------------------------------------
Int32 mColumns; // The amount of columns available in this statement.
Indexes mIndexes; // An associative container with column names and their index.
// ----------------------------------------------------------------------------------------
bool mGood; // True when a row has been fetched with step.
bool mDone; // True when the last step had no more rows to fetch.
/* ----------------------------------------------------------------------------------------
* Base constructor.
*/
Handle(const ConnHnd & conn, Counter counter)
: mPtr(nullptr)
, mRef(counter)
, mStatus(SQLITE_OK)
, mConn(conn)
, mQuery()
, mColumns(0)
, mIndexes()
, mGood(false)
, mDone(false)
{
/* ... */
}
/* ----------------------------------------------------------------------------------------
* Destructor.
*/
~Handle();
/* ----------------------------------------------------------------------------------------
* Create the database statement resource.
*/
void Create(CSStr query);
/* ----------------------------------------------------------------------------------------
* Check whether a specific index is in range.
*/
bool CheckIndex(Int32 idx) const
{
return (idx >= 0) && (idx <= mColumns);
}
/* ----------------------------------------------------------------------------------------
* Retrieve the column index associated with the specified name.
*/
Int32 GetColumnIndex(CSStr name);
};
private:
// --------------------------------------------------------------------------------------------
Handle * m_Hnd; // The managed handle instance.
/* --------------------------------------------------------------------------------------------
* Grab a strong reference to a statement handle.
*/
void Grab()
{
if (m_Hnd)
{
++(m_Hnd->mRef);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a statement handle.
*/
void Drop()
{
if (m_Hnd && --(m_Hnd->mRef) == 0)
{
delete m_Hnd; // Let the destructor take care of cleaning up (if necessary)
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
StmtHnd(const ConnHnd & db)
: m_Hnd(new Handle(db, 1))
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
StmtHnd()
: m_Hnd(nullptr)
{
/* ... */
}
// --------------------------------------------------------------------------------------------
Pointer mPtr; // The statement handle resource.
// --------------------------------------------------------------------------------------------
Int32 mStatus; // The last status code of this connection handle.
// --------------------------------------------------------------------------------------------
ConnRef mConn; // The handle to the associated database connection.
// --------------------------------------------------------------------------------------------
String mQuery; // The query string used to create this statement.
// --------------------------------------------------------------------------------------------
Int32 mColumns; // The amount of columns available in this statement.
Int32 mParameters; // The amount of parameters available in this statement.
Indexes mIndexes; // An associative container with column names and their index.
// --------------------------------------------------------------------------------------------
bool mGood; // True when a row has been fetched with step.
bool mDone; // True when the last step had no more rows to fetch.
/* --------------------------------------------------------------------------------------------
* Copy constructor.
* Default constructor.
*/
StmtHnd(const StmtHnd & o)
: m_Hnd(o.m_Hnd)
{
Grab();
}
StmtHnd(const ConnRef & conn);
/* --------------------------------------------------------------------------------------------
* Move constructor.
* Copy constructor. (disabled)
*/
StmtHnd(StmtHnd && o)
: m_Hnd(o.m_Hnd)
{
o.m_Hnd = nullptr;
}
StmtHnd(const StmtHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
StmtHnd(StmtHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~StmtHnd()
~StmtHnd();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
StmtHnd & operator = (const StmtHnd & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
StmtHnd & operator = (StmtHnd && o) = delete;
/* --------------------------------------------------------------------------------------------
* Create the database statement resource.
*/
void Create(CSStr query);
/* --------------------------------------------------------------------------------------------
* Check whether a specific column index is in range.
*/
bool CheckColumn(Int32 idx) const
{
Drop();
return (idx >= 0) && (idx <= mColumns);
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
* Check whether a specific parameter index is in range.
*/
StmtHnd & operator = (const StmtHnd & o)
bool CheckParameter(Int32 idx) const
{
if (m_Hnd != o.m_Hnd)
{
Drop();
m_Hnd = o.m_Hnd;
Grab();
}
return *this;
return (idx >= 1) && (idx <= mParameters);
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
* Retrieve the column index associated with the specified name.
*/
StmtHnd & operator = (StmtHnd && o)
{
if (m_Hnd != o.m_Hnd)
{
m_Hnd = o.m_Hnd;
o.m_Hnd = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Status assignment operator.
*/
StmtHnd & operator = (Int32 status)
{
if (m_Hnd)
{
m_Hnd->mStatus = status;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two statement handles.
*/
bool operator == (const StmtHnd & o) const
{
return (m_Hnd == o.m_Hnd);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two statement handles.
*/
bool operator != (const StmtHnd & o) const
{
return (m_Hnd != o.m_Hnd);
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison with an integer value status.
*/
bool operator == (Int32 status) const
{
if (m_Hnd)
{
return (m_Hnd->mStatus == status);
}
return false;
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison with an integer status value.
*/
bool operator != (Int32 status) const
{
if (m_Hnd)
{
return (m_Hnd->mStatus != status);
}
return false;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Hnd && m_Hnd->mPtr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Pointer ()
{
return m_Hnd ? m_Hnd->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Pointer () const
{
return m_Hnd ? m_Hnd->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator Reference ()
{
assert(m_Hnd && m_Hnd->mPtr);
return *(m_Hnd->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance.
*/
operator ConstRef () const
{
assert(m_Hnd && m_Hnd->mPtr);
return *(m_Hnd->mPtr);
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Handle * operator -> () const
{
assert(m_Hnd);
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Handle & operator * () const
{
assert(m_Hnd);
return *m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw handle structure pointer.
*/
Handle * HndPtr()
{
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw handle structure pointer.
*/
Handle * HndPtr() const
{
return m_Hnd;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return m_Hnd ? m_Hnd->mRef : 0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last known status code.
*/
Int32 Status() const
{
return m_Hnd ? m_Hnd->mStatus : SQLITE_NOMEM;
}
Int32 GetColumnIndex(CSStr name);
/* --------------------------------------------------------------------------------------------
* Retrieve the message of the last received error code.
*/
CCStr ErrStr() const
{
if (m_Hnd)
{
return m_Hnd->mConn.ErrStr();
}
return _SC("");
}
CCStr ErrStr() const;
/* --------------------------------------------------------------------------------------------
* Return the last error message associated with this database connection.
*/
CCStr ErrMsg() const
{
if (m_Hnd)
{
return m_Hnd->mConn.ErrMsg();
}
return _SC("");
}
CCStr ErrMsg() const;
/* --------------------------------------------------------------------------------------------
* Return the numeric result code for the most recent failed API call (if any).
*/
Int32 ErrNo() const
{
if (m_Hnd)
{
return m_Hnd->mConn.ErrNo();
}
return SQLITE_NOMEM;
}
Int32 ErrNo() const;
/* --------------------------------------------------------------------------------------------
* Return the extended numeric result code for the most recent failed API call (if any).
*/
Int32 ExErrNo() const
{
if (m_Hnd)
{
return m_Hnd->mConn.ExErrNo();
}
return SQLITE_NOMEM;
}
Int32 ExErrNo() const;
};
} // Namespace:: SqMod

View File

@ -1,9 +1,5 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Connection.hpp"
#include "Statement.hpp"
#include "Column.hpp"
#include "Transaction.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
@ -161,532 +157,27 @@ void UnbindCallbacks()
_Clbk->OnPluginCommand = nullptr;
}
// ------------------------------------------------------------------------------------------------
extern void Register_Constants(Table & sqlns);
extern void Register_Common(Table & sqlns);
extern void Register_Connection(Table & sqlns);
extern void Register_Statement(Table & sqlns);
extern void Register_Column(Table & sqlns);
extern void Register_Transaction(Table & sqlns);
// ------------------------------------------------------------------------------------------------
void RegisterAPI(HSQUIRRELVM vm)
{
Table sqlns(vm);
sqlns.Bind(_SC("Connection"), Class< Connection >(vm, _SC("SqSQLiteConnection"))
// Constructors
.Ctor()
.Ctor< CCStr >()
.Ctor< CCStr, Int32 >()
.Ctor< CCStr, Int32, CCStr >()
// Meta-methods
.Func(_SC("_cmp"), &Connection::Cmp)
.SquirrelFunc(_SC("_typename"), &Connection::Typename)
.Func(_SC("_tostring"), &Connection::ToString)
// Properties
.Prop(_SC("Valid"), &Connection::IsValid)
.Prop(_SC("Refs"), &Connection::GetRefCount)
.Prop(_SC("Connected"), &Connection::IsValid)
.Prop(_SC("Status"), &Connection::GetStatus)
.Prop(_SC("Flags"), &Connection::GetFlags)
.Prop(_SC("Name"), &Connection::GetName)
.Prop(_SC("VFS"), &Connection::GetVFS)
.Prop(_SC("ErrCode"), &Connection::GetErrorCode)
.Prop(_SC("ExErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ExtendedErrCode"), &Connection::GetExtendedErrorCode)
.Prop(_SC("ErrStr"), &Connection::GetErrStr)
.Prop(_SC("ErrMsg"), &Connection::GetErrMsg)
.Prop(_SC("ReadOnly"), &Connection::IsReadOnly)
.Prop(_SC("Autocommit"), &Connection::GetAutoCommit)
.Prop(_SC("LastInsertRowId"), &Connection::GetLastInsertRowID)
.Prop(_SC("Changes"), &Connection::GetChanges)
.Prop(_SC("TotalChanges"), &Connection::GetTotalChanges)
.Prop(_SC("Trace"), &Connection::GetTracing, &Connection::SetTracing)
.Prop(_SC("Profile"), &Connection::GetProfiling, &Connection::SetProfiling)
.Prop(_SC("BusyTimeout"), (Int32 (Connection::*)(void) const)(nullptr), &Connection::SetBusyTimeout)
.Prop(_SC("QueueSize"), &Connection::QueueSize)
// Member Methods
.Func(_SC("Release"), &Connection::Release)
.Overload< void (Connection::*)(CSStr) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(CSStr, Int32) >(_SC("Open"), &Connection::Open)
.Overload< void (Connection::*)(CSStr, Int32, CSStr) >(_SC("Open"), &Connection::Open)
.Func(_SC("Exec"), &Connection::Exec)
.Func(_SC("Queue"), &Connection::Queue)
.Func(_SC("Query"), &Connection::Query)
.Func(_SC("TableExists"), &Connection::TableExists)
.Func(_SC("InterruptOperation"), &Connection::InterruptOperation)
.Func(_SC("ReleaseMemory"), &Connection::ReleaseMemory)
.Overload< Int32 (Connection::*)(Int32) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Overload< Int32 (Connection::*)(Int32, bool, bool) >(_SC("GetInfo"), &Connection::GetInfo)
.Func(_SC("ReserveQueue"), &Connection::ReserveQueue)
.Func(_SC("CompactQueue"), &Connection::CompactQueue)
.Func(_SC("ClearQueue"), &Connection::ClearQueue)
.Func(_SC("PopQueue"), &Connection::PopQueue)
.Overload< Int32 (Connection::*)(void) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(Uint32) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(Object &, Function &) >(_SC("Flush"), &Connection::Flush)
.Overload< Int32 (Connection::*)(Uint32, Object &, Function &) >(_SC("Flush"), &Connection::Flush)
.SquirrelFunc(_SC("ExecF"), &Connection::ExecF)
.SquirrelFunc(_SC("QueueF"), &Connection::QueueF)
.SquirrelFunc(_SC("QueryF"), &Connection::QueryF)
);
sqlns.Bind(_SC("Statement"), Class< Statement >(vm, _SC("SqSQLiteStatement"))
// Constructors
.Ctor()
.Ctor< const Connection &, CCStr >()
.Ctor< const Statement & >()
// Meta-methods
.Func(_SC("_cmp"), &Statement::Cmp)
.SquirrelFunc(_SC("_typename"), &Statement::Typename)
.Func(_SC("_tostring"), &Statement::ToString)
// Properties
.Prop(_SC("Valid"), &Statement::IsValid)
.Prop(_SC("Refs"), &Statement::GetRefCount)
.Prop(_SC("Conn"), &Statement::GetConnection)
.Prop(_SC("Prepared"), &Statement::IsValid)
.Prop(_SC("Status"), &Statement::GetStatus)
.Prop(_SC("ErrCode"), &Statement::GetErrorCode)
.Prop(_SC("ExErrCode"), &Statement::GetExtendedErrorCode)
.Prop(_SC("ExtendedErrCode"), &Statement::GetExtendedErrorCode)
.Prop(_SC("ErrStr"), &Statement::GetErrStr)
.Prop(_SC("ErrMsg"), &Statement::GetErrMsg)
.Prop(_SC("Columns"), &Statement::GetColumns)
.Prop(_SC("Query"), &Statement::GetQuery)
.Prop(_SC("Good"), &Statement::GetGood)
.Prop(_SC("Done"), &Statement::GetDone)
// Member Methods
.Func(_SC("Release"), &Statement::Release)
.Func(_SC("Reset"), &Statement::Reset)
.Func(_SC("Clear"), &Statement::Clear)
.Func(_SC("Exec"), &Statement::Exec)
.Func(_SC("Step"), &Statement::Step)
.Func(_SC("IBindA"), &Statement::IndexBindA)
.Func(_SC("IBindI"), &Statement::IndexBindI)
.Func(_SC("IBindL"), &Statement::IndexBindL)
.Func(_SC("IBindV"), &Statement::IndexBindV)
.Func(_SC("IBindF"), &Statement::IndexBindF)
.Func(_SC("IBindS"), &Statement::IndexBindS)
.Func(_SC("IBindB"), &Statement::IndexBindB)
.Func(_SC("IBindN"), &Statement::IndexBindN)
.Func(_SC("NBindT"), &Statement::NameBindT)
.Func(_SC("NBindI"), &Statement::NameBindI)
.Func(_SC("NBindL"), &Statement::NameBindL)
.Func(_SC("NBindV"), &Statement::NameBindV)
.Func(_SC("NBindF"), &Statement::NameBindF)
.Func(_SC("NBindS"), &Statement::NameBindS)
.Func(_SC("NBindB"), &Statement::NameBindB)
.Func(_SC("NBindN"), &Statement::NameBindN)
.Func(_SC("IBind"), &Statement::IndexBind)
.Func(_SC("NBind"), &Statement::NameBind)
.Func(_SC("Bind"), &Statement::Bind)
.Func(_SC("FetchI"), &Statement::FetchColumnIndex)
.Func(_SC("FetchN"), &Statement::FetchColumnName)
.Func(_SC("Fetch"), &Statement::FetchColumn)
.Overload< Array (Statement::*)(void) const >(_SC("FetchA"), &Statement::FetchArray)
.Overload< Array (Statement::*)(Int32) const >(_SC("FetchA"), &Statement::FetchArray)
.Overload< Array (Statement::*)(Int32, Int32) const >(_SC("FetchA"), &Statement::FetchArray)
.Overload< Table (Statement::*)(void) const >(_SC("FetchT"), &Statement::FetchTable)
.Overload< Table (Statement::*)(Int32) const >(_SC("FetchT"), &Statement::FetchTable)
.Overload< Table (Statement::*)(Int32, Int32) const >(_SC("FetchT"), &Statement::FetchTable)
.Func(_SC("CheckIndex"), &Statement::CheckIndex)
.Func(_SC("IsColumnNull"), &Statement::IsColumnNull)
.Func(_SC("ColumnIndex"), &Statement::GetColumnIndex)
.Func(_SC("ColumnName"), &Statement::GetColumnName)
.Func(_SC("ColumnOriginName"), &Statement::GetColumnOriginName)
.Func(_SC("ColumnType"), &Statement::GetColumnType)
.Func(_SC("ColumnBytes"), &Statement::GetColumnBytes)
.Func(_SC("GetI"), &Statement::GetColumnByIndex)
.Func(_SC("GetN"), &Statement::GetColumnByName)
.Func(_SC("Get"), &Statement::GetColumn)
);
sqlns.Bind(_SC("Column"), Class< Column >(vm, _SC("SqSQLiteColumn"))
// Constructors
.Ctor()
.Ctor< const Column & >()
// Meta-methods
.Func(_SC("_cmp"), &Column::Cmp)
.SquirrelFunc(_SC("_typename"), &Column::Typename)
.Func(_SC("_tostring"), &Column::ToString)
// Properties
.Prop(_SC("Valid"), &Column::IsValid)
.Prop(_SC("Refs"), &Column::GetRefCount)
.Prop(_SC("Index"), &Column::GetIndex)
.Prop(_SC("Stmt"), &Column::GetNumber)
.Prop(_SC("Conn"), &Column::GetConnection)
.Prop(_SC("Number"), &Column::GetNumber)
.Prop(_SC("Integer"), &Column::GetInteger)
.Prop(_SC("Float"), &Column::GetFloat)
.Prop(_SC("Long"), &Column::GetLong)
.Prop(_SC("String"), &Column::GetString)
.Prop(_SC("Boolean"), &Column::GetBoolean)
.Prop(_SC("Blob"), &Column::GetBlob)
.Prop(_SC("Char"), &Column::GetChar)
.Prop(_SC("IsNull"), &Column::IsNull)
.Prop(_SC("Name"), &Column::GetName)
.Prop(_SC("OriginName"), &Column::GetOriginName)
.Prop(_SC("Type"), &Column::GetType)
.Prop(_SC("Bytes"), &Column::GetBytes)
// Member Methods
.Func(_SC("Release"), &Column::Release)
);
sqlns.Bind(_SC("Transaction"), Class< Transaction, NoCopy< Transaction > >(vm, _SC("SqSQLiteTransaction"))
// Constructors
.Ctor< const Connection & >()
// Properties
.Prop(_SC("Committed"), &Transaction::Commited)
// Member Methods
.Func(_SC("Commit"), &Transaction::Commit)
);
sqlns.Func(_SC("IsQueryEmpty"), &IsQueryEmpty);
sqlns.Func(_SC("GetErrStr"), &GetErrStr);
sqlns.Func(_SC("SetSoftHeapLimit"), &SetSoftHeapLimit);
sqlns.Func(_SC("ReleaseMemory"), &ReleaseMemory);
sqlns.Func(_SC("MemoryUsage"), &GetMemoryUsage);
sqlns.Func(_SC("EscapeString"), &EscapeString);
sqlns.Func(_SC("EscapeStringEx"), &EscapeStringEx);
sqlns.Func(_SC("Escape"), &EscapeString);
sqlns.Func(_SC("EscapeEx"), &EscapeStringEx);
sqlns.Func(_SC("ArrayToQueryColumns"), &ArrayToQueryColumns);
sqlns.Func(_SC("TableToQueryColumns"), &TableToQueryColumns);
Register_Constants(sqlns);
Register_Common(sqlns);
Register_Connection(sqlns);
Register_Statement(sqlns);
Register_Column(sqlns);
Register_Transaction(sqlns);
RootTable(vm).Bind(_SC("SQLite"), sqlns);
ConstTable(vm).Enum(_SC("ESQLite"), Enumeration(vm)
.Const(_SC("ABORT"), SQLITE_ABORT)
.Const(_SC("ABORT_ROLLBACK"), SQLITE_ABORT_ROLLBACK)
.Const(_SC("ACCESS_EXISTS"), SQLITE_ACCESS_EXISTS)
.Const(_SC("ACCESS_READ"), SQLITE_ACCESS_READ)
.Const(_SC("ACCESS_READWRITE"), SQLITE_ACCESS_READWRITE)
.Const(_SC("ALTER_TABLE"), SQLITE_ALTER_TABLE)
.Const(_SC("ANALYZE"), SQLITE_ANALYZE)
.Const(_SC("ANY"), SQLITE_ANY)
.Const(_SC("ATTACH"), SQLITE_ATTACH)
.Const(_SC("AUTH"), SQLITE_AUTH)
.Const(_SC("AUTH_USER"), SQLITE_AUTH_USER)
.Const(_SC("BLOB"), SQLITE_BLOB)
.Const(_SC("BUSY"), SQLITE_BUSY)
.Const(_SC("BUSY_RECOVERY"), SQLITE_BUSY_RECOVERY)
.Const(_SC("BUSY_SNAPSHOT"), SQLITE_BUSY_SNAPSHOT)
.Const(_SC("CANTOPEN"), SQLITE_CANTOPEN)
.Const(_SC("CANTOPEN_CONVPATH"), SQLITE_CANTOPEN_CONVPATH)
.Const(_SC("CANTOPEN_FULLPATH"), SQLITE_CANTOPEN_FULLPATH)
.Const(_SC("CANTOPEN_ISDIR"), SQLITE_CANTOPEN_ISDIR)
.Const(_SC("CANTOPEN_NOTEMPDIR"), SQLITE_CANTOPEN_NOTEMPDIR)
.Const(_SC("CHECKPOINT_FULL"), SQLITE_CHECKPOINT_FULL)
.Const(_SC("CHECKPOINT_PASSIVE"), SQLITE_CHECKPOINT_PASSIVE)
.Const(_SC("CHECKPOINT_RESTART"), SQLITE_CHECKPOINT_RESTART)
.Const(_SC("CHECKPOINT_TRUNCATE"), SQLITE_CHECKPOINT_TRUNCATE)
.Const(_SC("CONFIG_COVERING_INDEX_SCAN"), SQLITE_CONFIG_COVERING_INDEX_SCAN)
.Const(_SC("CONFIG_GETMALLOC"), SQLITE_CONFIG_GETMALLOC)
.Const(_SC("CONFIG_GETMUTEX"), SQLITE_CONFIG_GETMUTEX)
.Const(_SC("CONFIG_GETPCACHE"), SQLITE_CONFIG_GETPCACHE)
.Const(_SC("CONFIG_GETPCACHE2"), SQLITE_CONFIG_GETPCACHE2)
.Const(_SC("CONFIG_HEAP"), SQLITE_CONFIG_HEAP)
.Const(_SC("CONFIG_LOG"), SQLITE_CONFIG_LOG)
.Const(_SC("CONFIG_LOOKASIDE"), SQLITE_CONFIG_LOOKASIDE)
.Const(_SC("CONFIG_MALLOC"), SQLITE_CONFIG_MALLOC)
.Const(_SC("CONFIG_MEMSTATUS"), SQLITE_CONFIG_MEMSTATUS)
.Const(_SC("CONFIG_MMAP_SIZE"), SQLITE_CONFIG_MMAP_SIZE)
.Const(_SC("CONFIG_MULTITHREAD"), SQLITE_CONFIG_MULTITHREAD)
.Const(_SC("CONFIG_MUTEX"), SQLITE_CONFIG_MUTEX)
.Const(_SC("CONFIG_PAGECACHE"), SQLITE_CONFIG_PAGECACHE)
.Const(_SC("CONFIG_PCACHE"), SQLITE_CONFIG_PCACHE)
.Const(_SC("CONFIG_PCACHE2"), SQLITE_CONFIG_PCACHE2)
.Const(_SC("CONFIG_PCACHE_HDRSZ"), SQLITE_CONFIG_PCACHE_HDRSZ)
.Const(_SC("CONFIG_PMASZ"), SQLITE_CONFIG_PMASZ)
.Const(_SC("CONFIG_SCRATCH"), SQLITE_CONFIG_SCRATCH)
.Const(_SC("CONFIG_SERIALIZED"), SQLITE_CONFIG_SERIALIZED)
.Const(_SC("CONFIG_SINGLETHREAD"), SQLITE_CONFIG_SINGLETHREAD)
.Const(_SC("CONFIG_SQLLOG"), SQLITE_CONFIG_SQLLOG)
.Const(_SC("CONFIG_URI"), SQLITE_CONFIG_URI)
.Const(_SC("CONFIG_WIN32_HEAPSIZE"), SQLITE_CONFIG_WIN32_HEAPSIZE)
.Const(_SC("CONSTRAINT"), SQLITE_CONSTRAINT)
.Const(_SC("CONSTRAINT_CHECK"), SQLITE_CONSTRAINT_CHECK)
.Const(_SC("CONSTRAINT_COMMITHOOK"), SQLITE_CONSTRAINT_COMMITHOOK)
.Const(_SC("CONSTRAINT_FOREIGNKEY"), SQLITE_CONSTRAINT_FOREIGNKEY)
.Const(_SC("CONSTRAINT_FUNCTION"), SQLITE_CONSTRAINT_FUNCTION)
.Const(_SC("CONSTRAINT_NOTNULL"), SQLITE_CONSTRAINT_NOTNULL)
.Const(_SC("CONSTRAINT_PRIMARYKEY"), SQLITE_CONSTRAINT_PRIMARYKEY)
.Const(_SC("CONSTRAINT_ROWID"), SQLITE_CONSTRAINT_ROWID)
.Const(_SC("CONSTRAINT_TRIGGER"), SQLITE_CONSTRAINT_TRIGGER)
.Const(_SC("CONSTRAINT_UNIQUE"), SQLITE_CONSTRAINT_UNIQUE)
.Const(_SC("CONSTRAINT_VTAB"), SQLITE_CONSTRAINT_VTAB)
.Const(_SC("COPY"), SQLITE_COPY)
.Const(_SC("CORRUPT"), SQLITE_CORRUPT)
.Const(_SC("CORRUPT_VTAB"), SQLITE_CORRUPT_VTAB)
.Const(_SC("CREATE_INDEX"), SQLITE_CREATE_INDEX)
.Const(_SC("CREATE_TABLE"), SQLITE_CREATE_TABLE)
.Const(_SC("CREATE_TEMP_INDEX"), SQLITE_CREATE_TEMP_INDEX)
.Const(_SC("CREATE_TEMP_TABLE"), SQLITE_CREATE_TEMP_TABLE)
.Const(_SC("CREATE_TEMP_TRIGGER"), SQLITE_CREATE_TEMP_TRIGGER)
.Const(_SC("CREATE_TEMP_VIEW"), SQLITE_CREATE_TEMP_VIEW)
.Const(_SC("CREATE_TRIGGER"), SQLITE_CREATE_TRIGGER)
.Const(_SC("CREATE_VIEW"), SQLITE_CREATE_VIEW)
.Const(_SC("CREATE_VTABLE"), SQLITE_CREATE_VTABLE)
.Const(_SC("DBCONFIG_ENABLE_FKEY"), SQLITE_DBCONFIG_ENABLE_FKEY)
.Const(_SC("DBCONFIG_ENABLE_TRIGGER"), SQLITE_DBCONFIG_ENABLE_TRIGGER)
.Const(_SC("DBCONFIG_LOOKASIDE"), SQLITE_DBCONFIG_LOOKASIDE)
.Const(_SC("DBSTATUS_CACHE_HIT"), SQLITE_DBSTATUS_CACHE_HIT)
.Const(_SC("DBSTATUS_CACHE_MISS"), SQLITE_DBSTATUS_CACHE_MISS)
.Const(_SC("DBSTATUS_CACHE_USED"), SQLITE_DBSTATUS_CACHE_USED)
.Const(_SC("DBSTATUS_CACHE_WRITE"), SQLITE_DBSTATUS_CACHE_WRITE)
.Const(_SC("DBSTATUS_DEFERRED_FKS"), SQLITE_DBSTATUS_DEFERRED_FKS)
.Const(_SC("DBSTATUS_LOOKASIDE_HIT"), SQLITE_DBSTATUS_LOOKASIDE_HIT)
.Const(_SC("DBSTATUS_LOOKASIDE_MISS_FULL"), SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL)
.Const(_SC("DBSTATUS_LOOKASIDE_MISS_SIZE"), SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE)
.Const(_SC("DBSTATUS_LOOKASIDE_USED"), SQLITE_DBSTATUS_LOOKASIDE_USED)
.Const(_SC("DBSTATUS_MAX"), SQLITE_DBSTATUS_MAX)
.Const(_SC("DBSTATUS_SCHEMA_USED"), SQLITE_DBSTATUS_SCHEMA_USED)
.Const(_SC("DBSTATUS_STMT_USED"), SQLITE_DBSTATUS_STMT_USED)
.Const(_SC("DELETE"), SQLITE_DELETE)
.Const(_SC("DENY"), SQLITE_DENY)
.Const(_SC("DETACH"), SQLITE_DETACH)
.Const(_SC("DETERMINISTIC"), SQLITE_DETERMINISTIC)
.Const(_SC("DONE"), SQLITE_DONE)
.Const(_SC("DROP_INDEX"), SQLITE_DROP_INDEX)
.Const(_SC("DROP_TABLE"), SQLITE_DROP_TABLE)
.Const(_SC("DROP_TEMP_INDEX"), SQLITE_DROP_TEMP_INDEX)
.Const(_SC("DROP_TEMP_TABLE"), SQLITE_DROP_TEMP_TABLE)
.Const(_SC("DROP_TEMP_TRIGGER"), SQLITE_DROP_TEMP_TRIGGER)
.Const(_SC("DROP_TEMP_VIEW"), SQLITE_DROP_TEMP_VIEW)
.Const(_SC("DROP_TRIGGER"), SQLITE_DROP_TRIGGER)
.Const(_SC("DROP_VIEW"), SQLITE_DROP_VIEW)
.Const(_SC("DROP_VTABLE"), SQLITE_DROP_VTABLE)
.Const(_SC("EMPTY"), SQLITE_EMPTY)
.Const(_SC("ERROR"), SQLITE_ERROR)
.Const(_SC("FAIL"), SQLITE_FAIL)
.Const(_SC("FCNTL_BUSYHANDLER"), SQLITE_FCNTL_BUSYHANDLER)
.Const(_SC("FCNTL_CHUNK_SIZE"), SQLITE_FCNTL_CHUNK_SIZE)
.Const(_SC("FCNTL_COMMIT_PHASETWO"), SQLITE_FCNTL_COMMIT_PHASETWO)
.Const(_SC("FCNTL_FILE_POINTER"), SQLITE_FCNTL_FILE_POINTER)
.Const(_SC("FCNTL_GET_LOCKPROXYFILE"), SQLITE_FCNTL_GET_LOCKPROXYFILE)
.Const(_SC("FCNTL_HAS_MOVED"), SQLITE_FCNTL_HAS_MOVED)
.Const(_SC("FCNTL_LAST_ERRNO"), SQLITE_FCNTL_LAST_ERRNO)
.Const(_SC("FCNTL_LOCKSTATE"), SQLITE_FCNTL_LOCKSTATE)
.Const(_SC("FCNTL_MMAP_SIZE"), SQLITE_FCNTL_MMAP_SIZE)
.Const(_SC("FCNTL_OVERWRITE"), SQLITE_FCNTL_OVERWRITE)
.Const(_SC("FCNTL_PERSIST_WAL"), SQLITE_FCNTL_PERSIST_WAL)
.Const(_SC("FCNTL_POWERSAFE_OVERWRITE"), SQLITE_FCNTL_POWERSAFE_OVERWRITE)
.Const(_SC("FCNTL_PRAGMA"), SQLITE_FCNTL_PRAGMA)
.Const(_SC("FCNTL_RBU"), SQLITE_FCNTL_RBU)
.Const(_SC("FCNTL_SET_LOCKPROXYFILE"), SQLITE_FCNTL_SET_LOCKPROXYFILE)
.Const(_SC("FCNTL_SIZE_HINT"), SQLITE_FCNTL_SIZE_HINT)
.Const(_SC("FCNTL_SYNC"), SQLITE_FCNTL_SYNC)
.Const(_SC("FCNTL_SYNC_OMITTED"), SQLITE_FCNTL_SYNC_OMITTED)
.Const(_SC("FCNTL_TEMPFILENAME"), SQLITE_FCNTL_TEMPFILENAME)
.Const(_SC("FCNTL_TRACE"), SQLITE_FCNTL_TRACE)
.Const(_SC("FCNTL_VFSNAME"), SQLITE_FCNTL_VFSNAME)
.Const(_SC("FCNTL_WAL_BLOCK"), SQLITE_FCNTL_WAL_BLOCK)
.Const(_SC("FCNTL_WIN32_AV_RETRY"), SQLITE_FCNTL_WIN32_AV_RETRY)
.Const(_SC("FCNTL_WIN32_SET_HANDLE"), SQLITE_FCNTL_WIN32_SET_HANDLE)
.Const(_SC("FCNTL_ZIPVFS"), SQLITE_FCNTL_ZIPVFS)
.Const(_SC("FLOAT"), SQLITE_FLOAT)
.Const(_SC("FORMAT"), SQLITE_FORMAT)
.Const(_SC("FULL"), SQLITE_FULL)
.Const(_SC("FUNCTION"), SQLITE_FUNCTION)
.Const(_SC("IGNORE"), SQLITE_IGNORE)
.Const(_SC("INDEX_CONSTRAINT_EQ"), SQLITE_INDEX_CONSTRAINT_EQ)
.Const(_SC("INDEX_CONSTRAINT_GE"), SQLITE_INDEX_CONSTRAINT_GE)
.Const(_SC("INDEX_CONSTRAINT_GT"), SQLITE_INDEX_CONSTRAINT_GT)
.Const(_SC("INDEX_CONSTRAINT_LE"), SQLITE_INDEX_CONSTRAINT_LE)
.Const(_SC("INDEX_CONSTRAINT_LT"), SQLITE_INDEX_CONSTRAINT_LT)
.Const(_SC("INDEX_CONSTRAINT_MATCH"), SQLITE_INDEX_CONSTRAINT_MATCH)
.Const(_SC("INDEX_SCAN_UNIQUE"), SQLITE_INDEX_SCAN_UNIQUE)
.Const(_SC("INSERT"), SQLITE_INSERT)
.Const(_SC("INTEGER"), SQLITE_INTEGER)
.Const(_SC("INTERNAL"), SQLITE_INTERNAL)
.Const(_SC("INTERRUPT"), SQLITE_INTERRUPT)
.Const(_SC("IOCAP_ATOMIC"), SQLITE_IOCAP_ATOMIC)
.Const(_SC("IOCAP_ATOMIC16K"), SQLITE_IOCAP_ATOMIC16K)
.Const(_SC("IOCAP_ATOMIC1K"), SQLITE_IOCAP_ATOMIC1K)
.Const(_SC("IOCAP_ATOMIC2K"), SQLITE_IOCAP_ATOMIC2K)
.Const(_SC("IOCAP_ATOMIC32K"), SQLITE_IOCAP_ATOMIC32K)
.Const(_SC("IOCAP_ATOMIC4K"), SQLITE_IOCAP_ATOMIC4K)
.Const(_SC("IOCAP_ATOMIC512"), SQLITE_IOCAP_ATOMIC512)
.Const(_SC("IOCAP_ATOMIC64K"), SQLITE_IOCAP_ATOMIC64K)
.Const(_SC("IOCAP_ATOMIC8K"), SQLITE_IOCAP_ATOMIC8K)
.Const(_SC("IOCAP_IMMUTABLE"), SQLITE_IOCAP_IMMUTABLE)
.Const(_SC("IOCAP_POWERSAFE_OVERWRITE"), SQLITE_IOCAP_POWERSAFE_OVERWRITE)
.Const(_SC("IOCAP_SAFE_APPEND"), SQLITE_IOCAP_SAFE_APPEND)
.Const(_SC("IOCAP_SEQUENTIAL"), SQLITE_IOCAP_SEQUENTIAL)
.Const(_SC("IOCAP_UNDELETABLE_WHEN_OPEN"), SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
.Const(_SC("IOERR"), SQLITE_IOERR)
.Const(_SC("IOERR_ACCESS"), SQLITE_IOERR_ACCESS)
.Const(_SC("IOERR_BLOCKED"), SQLITE_IOERR_BLOCKED)
.Const(_SC("IOERR_CHECKRESERVEDLOCK"), SQLITE_IOERR_CHECKRESERVEDLOCK)
.Const(_SC("IOERR_CLOSE"), SQLITE_IOERR_CLOSE)
.Const(_SC("IOERR_CONVPATH"), SQLITE_IOERR_CONVPATH)
.Const(_SC("IOERR_DELETE"), SQLITE_IOERR_DELETE)
.Const(_SC("IOERR_DELETE_NOENT"), SQLITE_IOERR_DELETE_NOENT)
.Const(_SC("IOERR_DIR_CLOSE"), SQLITE_IOERR_DIR_CLOSE)
.Const(_SC("IOERR_DIR_FSYNC"), SQLITE_IOERR_DIR_FSYNC)
.Const(_SC("IOERR_FSTAT"), SQLITE_IOERR_FSTAT)
.Const(_SC("IOERR_FSYNC"), SQLITE_IOERR_FSYNC)
.Const(_SC("IOERR_GETTEMPPATH"), SQLITE_IOERR_GETTEMPPATH)
.Const(_SC("IOERR_LOCK"), SQLITE_IOERR_LOCK)
.Const(_SC("IOERR_MMAP"), SQLITE_IOERR_MMAP)
.Const(_SC("IOERR_NOMEM"), SQLITE_IOERR_NOMEM)
.Const(_SC("IOERR_RDLOCK"), SQLITE_IOERR_RDLOCK)
.Const(_SC("IOERR_READ"), SQLITE_IOERR_READ)
.Const(_SC("IOERR_SEEK"), SQLITE_IOERR_SEEK)
.Const(_SC("IOERR_SHMLOCK"), SQLITE_IOERR_SHMLOCK)
.Const(_SC("IOERR_SHMMAP"), SQLITE_IOERR_SHMMAP)
.Const(_SC("IOERR_SHMOPEN"), SQLITE_IOERR_SHMOPEN)
.Const(_SC("IOERR_SHMSIZE"), SQLITE_IOERR_SHMSIZE)
.Const(_SC("IOERR_SHORT_READ"), SQLITE_IOERR_SHORT_READ)
.Const(_SC("IOERR_TRUNCATE"), SQLITE_IOERR_TRUNCATE)
.Const(_SC("IOERR_UNLOCK"), SQLITE_IOERR_UNLOCK)
.Const(_SC("IOERR_VNODE"), SQLITE_IOERR_VNODE)
.Const(_SC("IOERR_WRITE"), SQLITE_IOERR_WRITE)
.Const(_SC("LIMIT_ATTACHED"), SQLITE_LIMIT_ATTACHED)
.Const(_SC("LIMIT_COLUMN"), SQLITE_LIMIT_COLUMN)
.Const(_SC("LIMIT_COMPOUND_SELECT"), SQLITE_LIMIT_COMPOUND_SELECT)
.Const(_SC("LIMIT_EXPR_DEPTH"), SQLITE_LIMIT_EXPR_DEPTH)
.Const(_SC("LIMIT_FUNCTION_ARG"), SQLITE_LIMIT_FUNCTION_ARG)
.Const(_SC("LIMIT_LENGTH"), SQLITE_LIMIT_LENGTH)
.Const(_SC("LIMIT_LIKE_PATTERN_LENGTH"), SQLITE_LIMIT_LIKE_PATTERN_LENGTH)
.Const(_SC("LIMIT_SQL_LENGTH"), SQLITE_LIMIT_SQL_LENGTH)
.Const(_SC("LIMIT_TRIGGER_DEPTH"), SQLITE_LIMIT_TRIGGER_DEPTH)
.Const(_SC("LIMIT_VARIABLE_NUMBER"), SQLITE_LIMIT_VARIABLE_NUMBER)
.Const(_SC("LIMIT_VDBE_OP"), SQLITE_LIMIT_VDBE_OP)
.Const(_SC("LIMIT_WORKER_THREADS"), SQLITE_LIMIT_WORKER_THREADS)
.Const(_SC("LOCKED"), SQLITE_LOCKED)
.Const(_SC("LOCKED_SHAREDCACHE"), SQLITE_LOCKED_SHAREDCACHE)
.Const(_SC("LOCK_EXCLUSIVE"), SQLITE_LOCK_EXCLUSIVE)
.Const(_SC("LOCK_NONE"), SQLITE_LOCK_NONE)
.Const(_SC("LOCK_PENDING"), SQLITE_LOCK_PENDING)
.Const(_SC("LOCK_RESERVED"), SQLITE_LOCK_RESERVED)
.Const(_SC("LOCK_SHARED"), SQLITE_LOCK_SHARED)
.Const(_SC("MISMATCH"), SQLITE_MISMATCH)
.Const(_SC("MISUSE"), SQLITE_MISUSE)
.Const(_SC("MUTEX_FAST"), SQLITE_MUTEX_FAST)
.Const(_SC("MUTEX_RECURSIVE"), SQLITE_MUTEX_RECURSIVE)
.Const(_SC("MUTEX_STATIC_APP1"), SQLITE_MUTEX_STATIC_APP1)
.Const(_SC("MUTEX_STATIC_APP2"), SQLITE_MUTEX_STATIC_APP2)
.Const(_SC("MUTEX_STATIC_APP3"), SQLITE_MUTEX_STATIC_APP3)
.Const(_SC("MUTEX_STATIC_LRU"), SQLITE_MUTEX_STATIC_LRU)
.Const(_SC("MUTEX_STATIC_LRU2"), SQLITE_MUTEX_STATIC_LRU2)
.Const(_SC("MUTEX_STATIC_MASTER"), SQLITE_MUTEX_STATIC_MASTER)
.Const(_SC("MUTEX_STATIC_MEM"), SQLITE_MUTEX_STATIC_MEM)
.Const(_SC("MUTEX_STATIC_MEM2"), SQLITE_MUTEX_STATIC_MEM2)
.Const(_SC("MUTEX_STATIC_OPEN"), SQLITE_MUTEX_STATIC_OPEN)
.Const(_SC("MUTEX_STATIC_PMEM"), SQLITE_MUTEX_STATIC_PMEM)
.Const(_SC("MUTEX_STATIC_PRNG"), SQLITE_MUTEX_STATIC_PRNG)
.Const(_SC("MUTEX_STATIC_VFS1"), SQLITE_MUTEX_STATIC_VFS1)
.Const(_SC("MUTEX_STATIC_VFS2"), SQLITE_MUTEX_STATIC_VFS2)
.Const(_SC("MUTEX_STATIC_VFS3"), SQLITE_MUTEX_STATIC_VFS3)
.Const(_SC("NOLFS"), SQLITE_NOLFS)
.Const(_SC("NOMEM"), SQLITE_NOMEM)
.Const(_SC("NOTADB"), SQLITE_NOTADB)
.Const(_SC("NOTFOUND"), SQLITE_NOTFOUND)
.Const(_SC("NOTICE"), SQLITE_NOTICE)
.Const(_SC("NOTICE_RECOVER_ROLLBACK"), SQLITE_NOTICE_RECOVER_ROLLBACK)
.Const(_SC("NOTICE_RECOVER_WAL"), SQLITE_NOTICE_RECOVER_WAL)
.Const(_SC("nullptr"), SQLITE_NULL)
.Const(_SC("OK"), SQLITE_OK)
.Const(_SC("OPEN_AUTOPROXY"), SQLITE_OPEN_AUTOPROXY)
.Const(_SC("OPEN_CREATE"), SQLITE_OPEN_CREATE)
.Const(_SC("OPEN_DELETEONCLOSE"), SQLITE_OPEN_DELETEONCLOSE)
.Const(_SC("OPEN_EXCLUSIVE"), SQLITE_OPEN_EXCLUSIVE)
.Const(_SC("OPEN_FULLMUTEX"), SQLITE_OPEN_FULLMUTEX)
.Const(_SC("OPEN_MAIN_DB"), SQLITE_OPEN_MAIN_DB)
.Const(_SC("OPEN_MAIN_JOURNAL"), SQLITE_OPEN_MAIN_JOURNAL)
.Const(_SC("OPEN_MASTER_JOURNAL"), SQLITE_OPEN_MASTER_JOURNAL)
.Const(_SC("OPEN_MEMORY"), SQLITE_OPEN_MEMORY)
.Const(_SC("OPEN_NOMUTEX"), SQLITE_OPEN_NOMUTEX)
.Const(_SC("OPEN_PRIVATECACHE"), SQLITE_OPEN_PRIVATECACHE)
.Const(_SC("OPEN_READONLY"), SQLITE_OPEN_READONLY)
.Const(_SC("OPEN_READWRITE"), SQLITE_OPEN_READWRITE)
.Const(_SC("OPEN_SHAREDCACHE"), SQLITE_OPEN_SHAREDCACHE)
.Const(_SC("OPEN_SUBJOURNAL"), SQLITE_OPEN_SUBJOURNAL)
.Const(_SC("OPEN_TEMP_DB"), SQLITE_OPEN_TEMP_DB)
.Const(_SC("OPEN_TEMP_JOURNAL"), SQLITE_OPEN_TEMP_JOURNAL)
.Const(_SC("OPEN_TRANSIENT_DB"), SQLITE_OPEN_TRANSIENT_DB)
.Const(_SC("OPEN_URI"), SQLITE_OPEN_URI)
.Const(_SC("OPEN_WAL"), SQLITE_OPEN_WAL)
.Const(_SC("PERM"), SQLITE_PERM)
.Const(_SC("PRAGMA"), SQLITE_PRAGMA)
.Const(_SC("PROTOCOL"), SQLITE_PROTOCOL)
.Const(_SC("RANGE"), SQLITE_RANGE)
.Const(_SC("READ"), SQLITE_READ)
.Const(_SC("READONLY"), SQLITE_READONLY)
.Const(_SC("READONLY_CANTLOCK"), SQLITE_READONLY_CANTLOCK)
.Const(_SC("READONLY_DBMOVED"), SQLITE_READONLY_DBMOVED)
.Const(_SC("READONLY_RECOVERY"), SQLITE_READONLY_RECOVERY)
.Const(_SC("READONLY_ROLLBACK"), SQLITE_READONLY_ROLLBACK)
.Const(_SC("RECURSIVE"), SQLITE_RECURSIVE)
.Const(_SC("REINDEX"), SQLITE_REINDEX)
.Const(_SC("REPLACE"), SQLITE_REPLACE)
.Const(_SC("ROLLBACK"), SQLITE_ROLLBACK)
.Const(_SC("ROW"), SQLITE_ROW)
.Const(_SC("SAVEPOINT"), SQLITE_SAVEPOINT)
.Const(_SC("SCANSTAT_EST"), SQLITE_SCANSTAT_EST)
.Const(_SC("SCANSTAT_EXPLAIN"), SQLITE_SCANSTAT_EXPLAIN)
.Const(_SC("SCANSTAT_NAME"), SQLITE_SCANSTAT_NAME)
.Const(_SC("SCANSTAT_NLOOP"), SQLITE_SCANSTAT_NLOOP)
.Const(_SC("SCANSTAT_NVISIT"), SQLITE_SCANSTAT_NVISIT)
.Const(_SC("SCANSTAT_SELECTID"), SQLITE_SCANSTAT_SELECTID)
.Const(_SC("SCHEMA"), SQLITE_SCHEMA)
.Const(_SC("SELECT"), SQLITE_SELECT)
.Const(_SC("SHM_EXCLUSIVE"), SQLITE_SHM_EXCLUSIVE)
.Const(_SC("SHM_LOCK"), SQLITE_SHM_LOCK)
.Const(_SC("SHM_NLOCK"), SQLITE_SHM_NLOCK)
.Const(_SC("SHM_SHARED"), SQLITE_SHM_SHARED)
.Const(_SC("SHM_UNLOCK"), SQLITE_SHM_UNLOCK)
.Const(_SC("SOURCE_ID"), SQLITE_SOURCE_ID)
.Const(_SC("STATUS_MALLOC_COUNT"), SQLITE_STATUS_MALLOC_COUNT)
.Const(_SC("STATUS_MALLOC_SIZE"), SQLITE_STATUS_MALLOC_SIZE)
.Const(_SC("STATUS_MEMORY_USED"), SQLITE_STATUS_MEMORY_USED)
.Const(_SC("STATUS_PAGECACHE_OVERFLOW"), SQLITE_STATUS_PAGECACHE_OVERFLOW)
.Const(_SC("STATUS_PAGECACHE_SIZE"), SQLITE_STATUS_PAGECACHE_SIZE)
.Const(_SC("STATUS_PAGECACHE_USED"), SQLITE_STATUS_PAGECACHE_USED)
.Const(_SC("STATUS_PARSER_STACK"), SQLITE_STATUS_PARSER_STACK)
.Const(_SC("STATUS_SCRATCH_OVERFLOW"), SQLITE_STATUS_SCRATCH_OVERFLOW)
.Const(_SC("STATUS_SCRATCH_SIZE"), SQLITE_STATUS_SCRATCH_SIZE)
.Const(_SC("STATUS_SCRATCH_USED"), SQLITE_STATUS_SCRATCH_USED)
.Const(_SC("STMTSTATUS_AUTOINDEX"), SQLITE_STMTSTATUS_AUTOINDEX)
.Const(_SC("STMTSTATUS_FULLSCAN_STEP"), SQLITE_STMTSTATUS_FULLSCAN_STEP)
.Const(_SC("STMTSTATUS_SORT"), SQLITE_STMTSTATUS_SORT)
.Const(_SC("STMTSTATUS_VM_STEP"), SQLITE_STMTSTATUS_VM_STEP)
.Const(_SC("SYNC_DATAONLY"), SQLITE_SYNC_DATAONLY)
.Const(_SC("SYNC_FULL"), SQLITE_SYNC_FULL)
.Const(_SC("SYNC_NORMAL"), SQLITE_SYNC_NORMAL)
.Const(_SC("TESTCTRL_ALWAYS"), SQLITE_TESTCTRL_ALWAYS)
.Const(_SC("TESTCTRL_ASSERT"), SQLITE_TESTCTRL_ASSERT)
.Const(_SC("TESTCTRL_BENIGN_MALLOC_HOOKS"), SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS)
.Const(_SC("TESTCTRL_BITVEC_TEST"), SQLITE_TESTCTRL_BITVEC_TEST)
.Const(_SC("TESTCTRL_BYTEORDER"), SQLITE_TESTCTRL_BYTEORDER)
.Const(_SC("TESTCTRL_EXPLAIN_STMT"), SQLITE_TESTCTRL_EXPLAIN_STMT)
.Const(_SC("TESTCTRL_FAULT_INSTALL"), SQLITE_TESTCTRL_FAULT_INSTALL)
.Const(_SC("TESTCTRL_FIRST"), SQLITE_TESTCTRL_FIRST)
.Const(_SC("TESTCTRL_IMPOSTER"), SQLITE_TESTCTRL_IMPOSTER)
.Const(_SC("TESTCTRL_ISINIT"), SQLITE_TESTCTRL_ISINIT)
.Const(_SC("TESTCTRL_ISKEYWORD"), SQLITE_TESTCTRL_ISKEYWORD)
.Const(_SC("TESTCTRL_LAST"), SQLITE_TESTCTRL_LAST)
.Const(_SC("TESTCTRL_LOCALTIME_FAULT"), SQLITE_TESTCTRL_LOCALTIME_FAULT)
.Const(_SC("TESTCTRL_NEVER_CORRUPT"), SQLITE_TESTCTRL_NEVER_CORRUPT)
.Const(_SC("TESTCTRL_OPTIMIZATIONS"), SQLITE_TESTCTRL_OPTIMIZATIONS)
.Const(_SC("TESTCTRL_PENDING_BYTE"), SQLITE_TESTCTRL_PENDING_BYTE)
.Const(_SC("TESTCTRL_PRNG_RESET"), SQLITE_TESTCTRL_PRNG_RESET)
.Const(_SC("TESTCTRL_PRNG_RESTORE"), SQLITE_TESTCTRL_PRNG_RESTORE)
.Const(_SC("TESTCTRL_PRNG_SAVE"), SQLITE_TESTCTRL_PRNG_SAVE)
.Const(_SC("TESTCTRL_RESERVE"), SQLITE_TESTCTRL_RESERVE)
.Const(_SC("TESTCTRL_SCRATCHMALLOC"), SQLITE_TESTCTRL_SCRATCHMALLOC)
.Const(_SC("TESTCTRL_SORTER_MMAP"), SQLITE_TESTCTRL_SORTER_MMAP)
.Const(_SC("TESTCTRL_VDBE_COVERAGE"), SQLITE_TESTCTRL_VDBE_COVERAGE)
.Const(_SC("TEXT"), SQLITE_TEXT)
.Const(_SC("TOOBIG"), SQLITE_TOOBIG)
.Const(_SC("TRANSACTION"), SQLITE_TRANSACTION)
.Const(_SC("UPDATE"), SQLITE_UPDATE)
.Const(_SC("UTF16"), SQLITE_UTF16)
.Const(_SC("UTF16BE"), SQLITE_UTF16BE)
.Const(_SC("UTF16LE"), SQLITE_UTF16LE)
.Const(_SC("UTF16_ALIGNED"), SQLITE_UTF16_ALIGNED)
.Const(_SC("UTF8"), SQLITE_UTF8)
.Const(_SC("VERSION"), SQLITE_VERSION)
.Const(_SC("VERSION_NUMBER"), SQLITE_VERSION_NUMBER)
.Const(_SC("VTAB_CONSTRAINT_SUPPORT"), SQLITE_VTAB_CONSTRAINT_SUPPORT)
.Const(_SC("WARNING"), SQLITE_WARNING)
.Const(_SC("WARNING_AUTOINDEX"), SQLITE_WARNING_AUTOINDEX)
);
}
} // Namespace:: SqMod

File diff suppressed because it is too large Load Diff

View File

@ -8,38 +8,101 @@
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to manage an SQLite statement.
* Used to manage and interact a database statement.
*/
class Statement
{
private:
// --------------------------------------------------------------------------------------------
StmtHnd m_Handle; // The handle to the managed database statement resource.
StmtRef m_Handle; // Reference to the managed statement.
protected:
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and index, and throw an error if they're invalid.
* Validate the managed statement handle and throw an error if invalid.
*/
void ValidateIndex(Int32 idx) const;
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void Validate(CCStr file, Int32 line) const;
#else
void Validate() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateCreated(CCStr file, Int32 line) const;
#else
void ValidateCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetValid(CCStr file, Int32 line) const;
#else
const StmtRef & GetValid() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & GetCreated(CCStr file, Int32 line) const;
#else
const StmtRef & GetCreated() const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and column index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateColumn(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateColumn(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and parameter index, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateParameter(Int32 idx, CCStr file, Int32 line) const;
#else
void ValidateParameter(Int32 idx) const;
#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
* Validate the statement reference and row, and throw an error if they're invalid.
*/
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
void ValidateRow(CCStr file, Int32 line) const;
#else
void ValidateRow() const;
#endif // _DEBUG
public:
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Statement();
Statement()
: m_Handle()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
*/
Statement(const ConnHnd & connection, CSStr query);
Statement(const ConnRef & connection, CSStr query)
: m_Handle(new StmtHnd(connection))
{
GET_VALID_HND(*this)->Create(query);
}
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
@ -49,8 +112,8 @@ public:
/* --------------------------------------------------------------------------------------------
* Direct handle constructor.
*/
Statement(const StmtHnd & h)
: m_Handle(h)
Statement(const StmtRef & s)
: m_Handle(s)
{
/* ... */
}
@ -58,35 +121,29 @@ public:
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Statement(const Statement & o)
: m_Handle(o.m_Handle)
{
/* ... */
}
Statement(const Statement & o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
* Move constructor.
*/
~Statement()
{
/* Let the reference manager destroy the statement when necessary. */
}
Statement(Statement && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Statement & operator = (const Statement & o)
{
m_Handle = o.m_Handle;
return *this;
}
Statement & operator = (const Statement & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Statement & operator = (Statement && o) = default;
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two connections.
*/
bool operator == (const Statement & o) const
{
return (m_Handle.m_Hnd == o.m_Handle.m_Hnd);
return (m_Handle.Get() == o.m_Handle.Get());
}
/* --------------------------------------------------------------------------------------------
@ -94,7 +151,7 @@ public:
*/
bool operator != (const Statement & o) const
{
return (m_Handle.m_Hnd != o.m_Handle.m_Hnd);
return (m_Handle.Get() != o.m_Handle.Get());
}
/* --------------------------------------------------------------------------------------------
@ -102,7 +159,7 @@ public:
*/
operator sqlite3_stmt * ()
{
return (sqlite3_stmt *)m_Handle;
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
@ -110,7 +167,7 @@ public:
*/
operator sqlite3_stmt * () const
{
return (sqlite3_stmt *)m_Handle;
return m_Handle ? m_Handle->mPtr : nullptr;
}
/* --------------------------------------------------------------------------------------------
@ -118,11 +175,11 @@ public:
*/
Int32 Cmp(const Statement & o) const
{
if (m_Handle.m_Hnd == o.m_Handle.m_Hnd)
if (m_Handle.Get() == o.m_Handle.Get())
{
return 0;
}
else if (m_Handle.m_Hnd > o.m_Handle.m_Hnd)
else if (m_Handle.Get() > o.m_Handle.Get())
{
return 1;
}
@ -135,15 +192,9 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
const String & ToString() const
{
// Validate the handle
if (m_Handle)
{
return m_Handle->mQuery.c_str();
}
// Request failed
return _SC("");
return m_Handle ? m_Handle->mQuery : NullString();
}
/* --------------------------------------------------------------------------------------------
@ -152,7 +203,15 @@ public:
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this statement is valid.
* Retrieve the associated statement handle.
*/
const StmtRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
@ -160,17 +219,17 @@ public:
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated statement handle.
* See whether the managed statement is valid.
*/
const StmtHnd & GetHandle() const
bool IsPrepared() const
{
return m_Handle;
return m_Handle && (m_Handle->mPtr != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this statement handle.
*/
Uint32 GetRefCount() const
Uint32 GetReferences() const
{
return m_Handle.Count();
}
@ -185,7 +244,7 @@ public:
*/
void Release()
{
m_Handle.Drop();
m_Handle.Reset();
}
/* --------------------------------------------------------------------------------------------
@ -193,10 +252,7 @@ public:
*/
Int32 GetStatus() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mStatus;
return GET_VALID_HND(*this)->mStatus;
}
/* --------------------------------------------------------------------------------------------
@ -204,10 +260,7 @@ public:
*/
Int32 GetErrorCode() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrNo();
return GET_VALID_HND(*this)->ErrNo();
}
/* --------------------------------------------------------------------------------------------
@ -215,10 +268,7 @@ public:
*/
Int32 GetExtendedErrorCode() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ExErrNo();
return GET_VALID_HND(*this)->ExErrNo();
}
/* --------------------------------------------------------------------------------------------
@ -226,10 +276,7 @@ public:
*/
CSStr GetErrStr() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrStr();
return GET_VALID_HND(*this)->ErrStr();
}
/* --------------------------------------------------------------------------------------------
@ -237,10 +284,7 @@ public:
*/
CSStr GetErrMsg() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle.ErrMsg();
return GET_VALID_HND(*this)->ErrMsg();
}
/* --------------------------------------------------------------------------------------------
@ -248,21 +292,23 @@ public:
*/
Int32 GetColumns() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mColumns;
return GET_VALID_HND(*this)->mColumns;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of specified parameters.
*/
Int32 GetParameters() const
{
return GET_VALID_HND(*this)->mParameters;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the query string used to create this statement.
*/
CSStr GetQuery() const
const String & GetQuery() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mQuery.c_str();
return GET_VALID_HND(*this)->mQuery;
}
/* --------------------------------------------------------------------------------------------
@ -270,10 +316,7 @@ public:
*/
bool GetGood() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mGood;
return GET_CREATED_HND(*this)->mGood;
}
/* --------------------------------------------------------------------------------------------
@ -281,10 +324,7 @@ public:
*/
bool GetDone() const
{
// Validate the handle
m_Handle.Validate();
// Return the requested information
return m_Handle->mDone;
return GET_CREATED_HND(*this)->mDone;
}
/* --------------------------------------------------------------------------------------------
@ -310,110 +350,110 @@ public:
/* --------------------------------------------------------------------------------------------
* Attempt to bind the values from an array starting at the specified index.
*/
void IndexBindA(Int32 idx, const Array & arr);
Statement & IndexBindArray(Int32 idx, const Array & arr);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a integer value at the the specified parameter index.
* Attempt to bind the a numeric value at the the specified parameter index.
*/
void IndexBindI(Int32 idx, Int32 value);
Statement & IndexBindValue(Int32 idx, Int32 value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a long integer value at the the specified parameter index.
*/
void IndexBindL(Int32 idx, const Object & value);
Statement & IndexBindLong(Int32 idx, const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a native integer value at the the specified parameter index.
*/
void IndexBindV(Int32 idx, SQInteger value);
Statement & IndexBindInteger(Int32 idx, SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a floating point value at the the specified parameter index.
*/
void IndexBindF(Int32 idx, SQFloat value);
Statement & IndexBindFloat(Int32 idx, SQFloat value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a string value at the the specified parameter index.
*/
void IndexBindS(Int32 idx, CSStr value);
Statement & IndexBindString(Int32 idx, CSStr value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a boolean value at the the specified parameter index.
*/
void IndexBindB(Int32 idx, bool value);
Statement & IndexBindBool(Int32 idx, bool value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a null value at the the specified parameter index.
*/
void IndexBindN(Int32 idx);
Statement & IndexBindNull(Int32 idx);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the values from an associative container.
*/
void NameBindT(const Table & tbl);
Statement & NameBindTable(const Table & tbl);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a integer value at the specified parameter name.
*/
void NameBindI(CSStr name, Int32 value);
Statement & NameBindValue(CSStr name, Int32 value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a long integer value at the specified parameter name.
*/
void NameBindL(CSStr name, const Object & value);
Statement & NameBindLong(CSStr name, const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a native integer value at the specified parameter name.
*/
void NameBindV(CSStr name, SQInteger value);
Statement & NameBindInteger(CSStr name, SQInteger value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a floating point value at the specified parameter name.
*/
void NameBindF(CSStr name, SQFloat value);
Statement & NameBindFloat(CSStr name, SQFloat value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a string value at the specified parameter name.
*/
void NameBindS(CSStr name, CSStr value);
Statement & NameBindString(CSStr name, CSStr value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a boolean value at the specified parameter name.
*/
void NameBindB(CSStr name, bool value);
Statement & NameBindBool(CSStr name, bool value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the a null value at the specified parameter name.
*/
void NameBindN(CSStr name);
Statement & NameBindNull(CSStr name);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the specified value at the specified parameter index.
*/
void IndexBind(Int32 idx, const Object & value);
Statement & IndexBind(Int32 idx, const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the specified value at the specified parameter name.
*/
void NameBind(CSStr name, const Object & value);
Statement & NameBind(CSStr name, const Object & value);
/* --------------------------------------------------------------------------------------------
* Attempt to bind the specified value at the specified parameter.
*/
void Bind(const Object & param, const Object & value);
Statement & Bind(const Object & param, const Object & value);
/* --------------------------------------------------------------------------------------------
* Fetch the value at the specifie column index.
* Fetch the value at the specific column index.
*/
Object FetchColumnIndex(Int32 idx) const;
/* --------------------------------------------------------------------------------------------
* Fetch the value at the specifie column name.
* Fetch the value at the specific column name.
*/
Object FetchColumnName(CSStr name) const;
/* --------------------------------------------------------------------------------------------
* Fetch the value at the specifie column.
* Fetch the value at the specific column.
*/
Object FetchColumn(const Object & column) const;
@ -448,9 +488,14 @@ public:
Table FetchTable(Int32 min, Int32 max) const;
/* --------------------------------------------------------------------------------------------
* Check whether a specific index is in range.
* Check whether a specific column index is in range.
*/
bool CheckIndex(Int32 idx) const;
bool CheckColumn(Int32 idx) const;
/* --------------------------------------------------------------------------------------------
* Check whether a specific parameter index is in range.
*/
bool CheckParameter(Int32 idx) const;
/* --------------------------------------------------------------------------------------------
* Check whether the specified column is null.
@ -496,6 +541,21 @@ public:
* Retrieve the column with the specified name or index.
*/
Object GetColumn(const Object & column) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of columns available in the current row.
*/
Int32 GetDataCount() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the parameter index associated with the specified name.
*/
Int32 GetParameterIndex(CSStr name) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the parameter name associated with the specified index.
*/
CSStr GetParameterName(Int32 idx) const;
};
} // Namespace:: SqMod

View File

@ -5,6 +5,14 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Transaction::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqSQLiteTransaction");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Transaction::Transaction(const Connection & db)
: Transaction(db.GetHandle())
@ -13,18 +21,20 @@ Transaction::Transaction(const Connection & db)
}
// ------------------------------------------------------------------------------------------------
Transaction::Transaction(const ConnHnd & db)
: m_Connection(db), m_Committed(false)
Transaction::Transaction(const ConnRef & db)
: m_Handle(db), m_Committed(false)
{
// Was the specified database connection valid?
if (!m_Connection)
if (!m_Handle)
{
STHROWF("Invalid connection handle");
}
// Attempt to begin transaction
else if ((m_Connection = sqlite3_exec(m_Connection, "BEGIN", nullptr, nullptr, nullptr)) != SQLITE_OK)
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "BEGIN", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to begin transaction [%s]", m_Connection.ErrMsg());
STHROWF("Unable to begin transaction [%s]", m_Handle->ErrMsg());
}
}
@ -37,9 +47,11 @@ Transaction::~Transaction()
return; // We're done here!
}
// Attempt to roll back changes because this failed to commit
if ((m_Connection = sqlite3_exec(m_Connection, "ROLLBACK", nullptr, nullptr, nullptr)) != SQLITE_OK)
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "ROLLBACK", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to rollback transaction [%s]", m_Connection.ErrMsg());
STHROWF("Unable to rollback transaction [%s]", m_Handle->ErrMsg());
}
}
@ -47,7 +59,7 @@ Transaction::~Transaction()
bool Transaction::Commit()
{
// We shouldn't even be here if there wasn't a valid connection but let's be sure
if (!m_Connection)
if (!m_Handle)
{
STHROWF("Invalid database connection");
}
@ -57,9 +69,11 @@ bool Transaction::Commit()
STHROWF("Transaction was already committed");
}
// Attempt to commit the change during this transaction
else if ((m_Connection = sqlite3_exec(m_Connection, "COMMIT", nullptr, nullptr, nullptr)) != SQLITE_OK)
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "COMMIT", nullptr, nullptr, nullptr);
// Validate the result
if (m_Handle->mStatus != SQLITE_OK)
{
STHROWF("Unable to commit transaction [%s]", m_Connection.ErrMsg());
STHROWF("Unable to commit transaction [%s]", m_Handle->ErrMsg());
}
else
{
@ -69,4 +83,22 @@ bool Transaction::Commit()
return m_Committed;
}
// ================================================================================================
void Register_Transaction(Table & sqlns)
{
sqlns.Bind(_SC("Transaction"),
Class< Transaction, NoCopy< Transaction > >(sqlns.GetVM(), _SC("SqSQLiteTransaction"))
// Constructors
.Ctor< const Connection & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Transaction::Typename)
.Func(_SC("_tostring"), &Transaction::ToString)
// Properties
.Prop(_SC("IsValid"), &Transaction::IsValid)
.Prop(_SC("Committed"), &Transaction::Commited)
// Member Methods
.Func(_SC("Commit"), &Transaction::Commit)
);
}
} // Namespace:: SqMod

View File

@ -22,7 +22,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Construct using the direct connection handle.
*/
Transaction(const ConnHnd & db);
Transaction(const ConnRef & db);
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
@ -49,6 +49,35 @@ public:
*/
Transaction & operator = (Transaction && o) = delete;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const
{
return m_Handle ? m_Handle->mName : NullString();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated statement handle.
*/
const ConnRef & GetHandle() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* See whether the managed handle is valid.
*/
bool IsValid() const
{
return m_Handle;
}
/* --------------------------------------------------------------------------------------------
* Attempt to commit changes to the database.
*/
@ -65,7 +94,7 @@ public:
private:
// --------------------------------------------------------------------------------------------
ConnHnd m_Connection; // The database connection handle where the transaction began.
ConnRef m_Handle; // The database connection handle where the transaction began.
bool m_Committed; // Whether changes were successfully committed to the database.
};