mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Adjust the SQLite module to use the new method of receiving formatted strings.
Several minor bugfixes and improvements came with this migration as well.
This commit is contained in:
parent
c541fb3ea9
commit
568bc385e9
@ -41,7 +41,7 @@ CSStr QFmtStr(CSStr str, ...)
|
||||
bool IsQueryEmpty(CSStr str)
|
||||
{
|
||||
// Is the pointer valid?
|
||||
if (!str)
|
||||
if (!str || *str == '\0')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -101,42 +101,21 @@ Object GetMemoryHighwaterMark(bool reset)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr EscapeString(CSStr str)
|
||||
CSStr EscapeString(const StackStrF & str)
|
||||
{
|
||||
// Is there even a string to escape?
|
||||
if (!str)
|
||||
if (str.mLen <= 0)
|
||||
{
|
||||
return _SC(""); // Default to empty string
|
||||
}
|
||||
// Attempt to escape the specified string
|
||||
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), "%q", str);
|
||||
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), "%q", str.mPtr);
|
||||
// Return the resulted string
|
||||
return GetTempBuff();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqEscapeString(HSQUIRRELVM vm)
|
||||
{
|
||||
// Was the string specified?
|
||||
if (sq_gettop(vm) <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing un-escaped string");
|
||||
}
|
||||
// Attempt to generate the string value
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to escape the obtained string and push it on the stack
|
||||
sq_pushstring(vm, EscapeString(val.mPtr), -1);
|
||||
// Specify that we have a return value
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CCStr EscapeStringEx(SQChar spec, CCStr str)
|
||||
CCStr EscapeStringEx(SQChar spec, const StackStrF & str)
|
||||
{
|
||||
// Utility that allows changing the format specifier temporarily
|
||||
static SQChar fs[] = _SC("%q");
|
||||
@ -146,62 +125,20 @@ CCStr EscapeStringEx(SQChar spec, CCStr str)
|
||||
STHROWF("Unknown format specifier: '%c'", spec);
|
||||
}
|
||||
// Is there even a string to escape?
|
||||
else if (!str)
|
||||
else if (!str.mLen)
|
||||
{
|
||||
return _SC(""); // Default to empty string
|
||||
}
|
||||
// Apply the format specifier
|
||||
fs[1] = spec;
|
||||
// Attempt to escape the specified string
|
||||
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), fs, str);
|
||||
sqlite3_snprintf(GetTempBuffSize(), GetTempBuff(), fs, str.mPtr);
|
||||
// Restore the format specifier
|
||||
fs[1] = 'q';
|
||||
// Return the resulted string
|
||||
return GetTempBuff();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqEscapeStringEx(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the escape specifier specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing escape specifier");
|
||||
}
|
||||
// Was the string specified?
|
||||
else if (top <= 2)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing un-escaped string");
|
||||
}
|
||||
SQInteger spec = 'q';
|
||||
// Attempt to extract the escape specifier
|
||||
const SQRESULT res = sq_getinteger(vm, 2, &spec);
|
||||
// Have we failed to retrieve the specifier?
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
return res; // Propagate the error!
|
||||
}
|
||||
// Attempt to generate the string value
|
||||
StackStrF val(vm, 3);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to escape the obtained string and push it on the stack
|
||||
try
|
||||
{
|
||||
sq_pushstring(vm, EscapeStringEx(static_cast< SQChar >(spec), val.mPtr), -1);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Specify that we have a return value
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CCStr ArrayToQueryColumns(Array & arr)
|
||||
{
|
||||
@ -295,10 +232,10 @@ void Register_Common(Table & sqlns)
|
||||
.Func(_SC("MemoryUsage"), &GetMemoryUsage)
|
||||
.Func(_SC("ArrayToQueryColumns"), &ArrayToQueryColumns)
|
||||
.Func(_SC("TableToQueryColumns"), &TableToQueryColumns)
|
||||
.SquirrelFunc(_SC("EscapeString"), &SqEscapeString)
|
||||
.SquirrelFunc(_SC("EscapeStringEx"), &SqEscapeStringEx)
|
||||
.SquirrelFunc(_SC("Escape"), &SqEscapeString)
|
||||
.SquirrelFunc(_SC("EscapeEx"), &SqEscapeStringEx);
|
||||
.FmtFunc(_SC("EscapeString"), &EscapeString)
|
||||
.FmtFunc(_SC("EscapeStringEx"), &EscapeStringEx)
|
||||
.FmtFunc(_SC("Escape"), &EscapeString)
|
||||
.FmtFunc(_SC("EscapeEx"), &EscapeStringEx);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -126,12 +126,12 @@ Object GetMemoryHighwaterMark(bool reset);
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the escaped version of the specified string.
|
||||
*/
|
||||
CSStr EscapeString(CSStr str);
|
||||
CSStr EscapeString(const StackStrF & str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the escaped version of the specified string using the supplied format specifier.
|
||||
*/
|
||||
CCStr EscapeStringEx(SQChar spec, CCStr str);
|
||||
CCStr EscapeStringEx(SQChar spec, const StackStrF & str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert the values from the specified array to a list of column names string.
|
||||
|
@ -102,7 +102,7 @@ const ConnRef & Connection::GetCreated() const
|
||||
#endif // _DEBUG
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::Open(CSStr name)
|
||||
void Connection::Open(const StackStrF & name)
|
||||
{
|
||||
// Should we create a connection handle?
|
||||
if (!m_Handle)
|
||||
@ -115,11 +115,11 @@ void Connection::Open(CSStr name)
|
||||
STHROWF("Already referencing a valid database connection");
|
||||
}
|
||||
// Perform the requested operation
|
||||
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
m_Handle->Create(name.mPtr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::Open(CSStr name, Int32 flags)
|
||||
void Connection::Open(const StackStrF & name, Int32 flags)
|
||||
{
|
||||
// Should we create a connection handle?
|
||||
if (!m_Handle)
|
||||
@ -132,11 +132,11 @@ void Connection::Open(CSStr name, Int32 flags)
|
||||
STHROWF("Already referencing a valid database connection");
|
||||
}
|
||||
// Perform the requested operation
|
||||
m_Handle->Create(name, flags, nullptr);
|
||||
m_Handle->Create(name.mPtr, flags, nullptr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::Open(CSStr name, Int32 flags, CSStr vfs)
|
||||
void Connection::Open(const StackStrF & name, Int32 flags, const StackStrF & vfs)
|
||||
{
|
||||
// Should we create a connection handle?
|
||||
if (!m_Handle)
|
||||
@ -149,15 +149,15 @@ void Connection::Open(CSStr name, Int32 flags, CSStr vfs)
|
||||
STHROWF("Already referencing a valid database connection");
|
||||
}
|
||||
// Perform the requested operation
|
||||
m_Handle->Create(name, flags, vfs);
|
||||
m_Handle->Create(name.mPtr, flags, vfs.mPtr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Connection::Exec(CSStr str)
|
||||
Int32 Connection::Exec(const StackStrF & str)
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*this);
|
||||
// Attempt to execute the specified query
|
||||
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, str, nullptr, nullptr, nullptr);
|
||||
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, str.mPtr, nullptr, nullptr, nullptr);
|
||||
// Validate the execution result
|
||||
if (m_Handle->mStatus != SQLITE_OK)
|
||||
{
|
||||
@ -168,7 +168,7 @@ Int32 Connection::Exec(CSStr str)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object Connection::Query(CSStr str) const
|
||||
Object Connection::Query(const StackStrF & str) const
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*this);
|
||||
// Return the requested information
|
||||
@ -176,16 +176,16 @@ Object Connection::Query(CSStr str) const
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::Queue(CSStr str)
|
||||
void Connection::Queue(const StackStrF & str)
|
||||
{
|
||||
SQMOD_VALIDATE(*this);
|
||||
// Is there a query to commit?
|
||||
if (IsQueryEmpty(str))
|
||||
if (!str.mLen || IsQueryEmpty(str.mPtr))
|
||||
{
|
||||
STHROWF("No query string to queue");
|
||||
}
|
||||
// Add the specified string to the queue
|
||||
m_Handle->mQueue.push_back(str);
|
||||
m_Handle->mQueue.emplace_back(str.mPtr, str.mLen);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -203,7 +203,7 @@ bool Connection::IsReadOnly() const
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Connection::TableExists(CCStr name) const
|
||||
bool Connection::TableExists(const StackStrF & name) const
|
||||
{
|
||||
// Prepare a statement to inspect the master table
|
||||
Statement stmt(SQMOD_GET_CREATED(*this), "SELECT count(*) FROM [sqlite_master] WHERE [type]='table' AND [name]=?");
|
||||
@ -344,167 +344,6 @@ Int32 Connection::Flush(SQInteger num, Object & env, Function & func)
|
||||
return m_Handle->Flush(ConvTo< Uint32 >::From(num), env, func);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the query value specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing query value");
|
||||
}
|
||||
// The connection instance
|
||||
Connection * conn = nullptr;
|
||||
// Attempt to extract the argument values
|
||||
try
|
||||
{
|
||||
conn = Var< Connection * >(vm, 1).value;
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Do we have a valid connection instance?
|
||||
if (!conn)
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Validate the connection info
|
||||
try
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*conn);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to execute the specified query
|
||||
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()));
|
||||
}
|
||||
// Push the number of changes onto the stack
|
||||
sq_pushinteger(vm, sqlite3_changes(conn->m_Handle->mPtr));
|
||||
// This function returned a value
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::QueueF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the query value specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing query value");
|
||||
}
|
||||
// The connection instance
|
||||
Connection * conn = nullptr;
|
||||
// Attempt to extract the argument values
|
||||
try
|
||||
{
|
||||
conn = Var< Connection * >(vm, 1).value;
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Do we have a valid connection instance?
|
||||
if (!conn)
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Validate the connection info
|
||||
try
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*conn);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to queue the specified query
|
||||
conn->m_Handle->mQueue.emplace_back(val.mPtr, val.mLen);
|
||||
// This function does not return a value
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::QueryF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the query value specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing query value");
|
||||
}
|
||||
// The connection instance
|
||||
Connection * conn = nullptr;
|
||||
// Attempt to extract the argument values
|
||||
try
|
||||
{
|
||||
conn = Var< Connection * >(vm, 1).value;
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Do we have a valid connection instance?
|
||||
if (!conn)
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Validate the connection info
|
||||
try
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*conn);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to create a statement with the specified query
|
||||
try
|
||||
{
|
||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, val.mPtr));
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// This function returned a value
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Connection(Table & sqlns)
|
||||
{
|
||||
@ -512,9 +351,9 @@ void Register_Connection(Table & sqlns)
|
||||
Class< Connection >(sqlns.GetVM(), _SC("SqSQLiteConnection"))
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< CCStr >()
|
||||
.Ctor< CCStr, Int32 >()
|
||||
.Ctor< CCStr, Int32, CCStr >()
|
||||
.Ctor< const StackStrF & >()
|
||||
.Ctor< const StackStrF &, Int32 >()
|
||||
.Ctor< const StackStrF &, Int32, const StackStrF & >()
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Connection::Typename)
|
||||
.Func(_SC("_tostring"), &Connection::ToString)
|
||||
@ -541,10 +380,10 @@ void Register_Connection(Table & sqlns)
|
||||
.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)
|
||||
.FmtFunc(_SC("Exec"), &Connection::Exec)
|
||||
.FmtFunc(_SC("Queue"), &Connection::Queue)
|
||||
.FmtFunc(_SC("Query"), &Connection::Query)
|
||||
.FmtFunc(_SC("TableExists"), &Connection::TableExists)
|
||||
.Func(_SC("InterruptOperation"), &Connection::InterruptOperation)
|
||||
.Func(_SC("SetBusyTimeout"), &Connection::SetBusyTimeout)
|
||||
.Func(_SC("ReleaseMemory"), &Connection::ReleaseMemory)
|
||||
@ -553,9 +392,9 @@ void Register_Connection(Table & sqlns)
|
||||
.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< void (Connection::*)(const StackStrF &) >(_SC("Open"), &Connection::Open)
|
||||
.Overload< void (Connection::*)(const StackStrF &, Int32) >(_SC("Open"), &Connection::Open)
|
||||
.Overload< void (Connection::*)(const StackStrF &, Int32, const StackStrF &) >(_SC("Open"), &Connection::Open)
|
||||
.Overload< Int32 (Connection::*)(Int32) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
.Overload< Int32 (Connection::*)(Int32, bool) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
.Overload< Int32 (Connection::*)(Int32, bool, bool) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
@ -563,10 +402,6 @@ void Register_Connection(Table & sqlns)
|
||||
.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)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,6 @@ namespace SqMod {
|
||||
*/
|
||||
class Connection
|
||||
{
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create the database connection resource.
|
||||
*/
|
||||
void Create(CSStr name, Int32 flags, CSStr vfs);
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -86,28 +79,28 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Connection(CSStr name)
|
||||
Connection(const StackStrF & name)
|
||||
: m_Handle(new ConnHnd())
|
||||
{
|
||||
SQMOD_GET_VALID(*this)->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
SQMOD_GET_VALID(*this)->Create(name.mPtr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Connection(CSStr name, Int32 flags)
|
||||
Connection(const StackStrF & name, Int32 flags)
|
||||
: m_Handle(new ConnHnd())
|
||||
{
|
||||
SQMOD_GET_VALID(*this)->Create(name, flags, nullptr);
|
||||
SQMOD_GET_VALID(*this)->Create(name.mPtr, flags, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Connection(CSStr name, Int32 flags, CSStr vfs)
|
||||
Connection(const StackStrF & name, Int32 flags, const StackStrF & vfs)
|
||||
: m_Handle(new ConnHnd())
|
||||
{
|
||||
SQMOD_GET_VALID(*this)->Create(name, flags, vfs);
|
||||
SQMOD_GET_VALID(*this)->Create(name.mPtr, flags, vfs.mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -291,32 +284,32 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to open the specified database.
|
||||
*/
|
||||
void Open(CSStr name);
|
||||
void Open(const StackStrF & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to open the specified database.
|
||||
*/
|
||||
void Open(CSStr name, Int32 flags);
|
||||
void Open(const StackStrF & name, Int32 flags);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to open the specified database.
|
||||
*/
|
||||
void Open(CSStr name, Int32 flags, CSStr vfs);
|
||||
void Open(const StackStrF & name, Int32 flags, const StackStrF & vfs);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to execute the specified query.
|
||||
*/
|
||||
Int32 Exec(CSStr str);
|
||||
Int32 Exec(const StackStrF & str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to queue the specified query.
|
||||
*/
|
||||
void Queue(CSStr str);
|
||||
void Queue(const StackStrF & str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to create a statement from the specified query.
|
||||
*/
|
||||
Object Query(CSStr str) const;
|
||||
Object Query(const StackStrF & str) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the database connection was opened in read-only mode.
|
||||
@ -326,7 +319,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Shortcut to test if a table exists.
|
||||
*/
|
||||
bool TableExists(CCStr name) const;
|
||||
bool TableExists(const StackStrF & name) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the database connection is or is not in auto-commit mode.
|
||||
@ -483,21 +476,6 @@ public:
|
||||
* Flush a specific amount of queries from the queue and handle errors manually.
|
||||
*/
|
||||
Int32 Flush(SQInteger num, Object & env, Function & func);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to execute the specified query.
|
||||
*/
|
||||
static SQInteger ExecF(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to queue the specified query.
|
||||
*/
|
||||
static SQInteger QueueF(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to create a statement from the specified query.
|
||||
*/
|
||||
static SQInteger QueryF(HSQUIRRELVM vm);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "Handle/Statement.hpp"
|
||||
#include "Handle/Connection.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
@ -35,7 +38,7 @@ StmtHnd::~StmtHnd()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void StmtHnd::Create(CSStr query)
|
||||
void StmtHnd::Create(CSStr query, SQInteger length)
|
||||
{
|
||||
// Make sure a previous statement doesn't exist
|
||||
if (mPtr)
|
||||
@ -47,15 +50,15 @@ void StmtHnd::Create(CSStr query)
|
||||
{
|
||||
STHROWF("Unable to prepare statement. Invalid connection handle");
|
||||
}
|
||||
// Save the query string and therefore multiple strlen(...) calls
|
||||
mQuery.assign(query ? query : _SC(""));
|
||||
// Is the specified query string we just saved, valid?
|
||||
if (mQuery.empty())
|
||||
// Is the specified query string valid?
|
||||
else if (!query || *query || !length)
|
||||
{
|
||||
STHROWF("Unable to prepare statement. Invalid query string");
|
||||
}
|
||||
// Save the query string
|
||||
mQuery.assign(query, length);
|
||||
// Attempt to prepare a statement with the specified query string
|
||||
else if ((mStatus = sqlite3_prepare_v2(mConn->mPtr, mQuery.c_str(), (Int32)mQuery.size(),
|
||||
if ((mStatus = sqlite3_prepare_v2(mConn->mPtr, mQuery.c_str(), ConvTo< Int32 >::From(mQuery.size()),
|
||||
&mPtr, nullptr)) != SQLITE_OK)
|
||||
{
|
||||
// Clear the query string since it failed
|
||||
@ -75,7 +78,7 @@ void StmtHnd::Create(CSStr query)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 StmtHnd::GetColumnIndex(CSStr name)
|
||||
Int32 StmtHnd::GetColumnIndex(CSStr name, SQInteger length)
|
||||
{
|
||||
// Validate the handle
|
||||
if (!mPtr)
|
||||
@ -101,8 +104,9 @@ Int32 StmtHnd::GetColumnIndex(CSStr name)
|
||||
}
|
||||
}
|
||||
}
|
||||
const String str(name, length < 0 ? std::strlen(name) : length);
|
||||
// Attempt to find the specified column
|
||||
const Indexes::iterator itr = mIndexes.find(name);
|
||||
const Indexes::iterator itr = mIndexes.find(str);
|
||||
// Was there a column with the specified name?
|
||||
if (itr != mIndexes.end())
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create the database statement resource.
|
||||
*/
|
||||
void Create(CSStr query);
|
||||
void Create(CSStr query, SQInteger length = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether a specific column index is in range.
|
||||
@ -108,7 +108,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the column index associated with the specified name.
|
||||
*/
|
||||
Int32 GetColumnIndex(CSStr name);
|
||||
Int32 GetColumnIndex(CSStr name, SQInteger length = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the message of the last received error code.
|
||||
|
@ -266,7 +266,15 @@ void Parameter::SetValue(const Object & value)
|
||||
} break;
|
||||
case OT_STRING:
|
||||
{
|
||||
SetString(value.Cast< CSStr >());
|
||||
SQMOD_VALIDATE_CREATED(*this);
|
||||
// Remember the current stack size
|
||||
const StackGuard sg;
|
||||
// Push the object onto the stack
|
||||
Var< Object >::push(DefaultVM::Get(), value);
|
||||
// Pop the object from the stack as a string
|
||||
const Var< CSStr > str(DefaultVM::Get(), -1);
|
||||
// Attempt to bind the specified value
|
||||
SetStringRaw(str.value, ConvTo< SQInteger >::From(str.size));
|
||||
} break;
|
||||
default: STHROWF("No known conversion for the specified value type");
|
||||
}
|
||||
@ -456,11 +464,11 @@ void Parameter::SetFloat64(SQFloat value)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parameter::SetString(CSStr value)
|
||||
void Parameter::SetString(const StackStrF & value)
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*this);
|
||||
// Attempt to bind the specified value
|
||||
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value, -1, SQLITE_TRANSIENT);
|
||||
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value.mPtr, value.mLen, SQLITE_TRANSIENT);
|
||||
// Validate the result
|
||||
if (m_Handle->mStatus != SQLITE_OK)
|
||||
{
|
||||
@ -469,7 +477,7 @@ void Parameter::SetString(CSStr value)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parameter::SetStringEx(CSStr value, Int32 length)
|
||||
void Parameter::SetStringRaw(CSStr value, SQInteger length)
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*this);
|
||||
// Attempt to bind the specified value
|
||||
@ -722,64 +730,6 @@ void Parameter::SetNull()
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Parameter::SetStringF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the parameter value specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing parameter value");
|
||||
}
|
||||
// The parameter instance
|
||||
Parameter * param = nullptr;
|
||||
// Attempt to extract the argument values
|
||||
try
|
||||
{
|
||||
param = Var< Parameter * >(vm, 1).value;
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Do we have a valid parameter instance?
|
||||
if (!param)
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite parameter instance");
|
||||
}
|
||||
// Validate the parameter info
|
||||
try
|
||||
{
|
||||
SQMOD_VALIDATE_CREATED(*param);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to bind the obtained string
|
||||
try
|
||||
{
|
||||
param->SetStringEx(val.mPtr, val.mLen);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// Propagate the error
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// This function does not return any value
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Parameter(Table & sqlns)
|
||||
{
|
||||
@ -816,7 +766,7 @@ void Register_Parameter(Table & sqlns)
|
||||
.Func(_SC("SetFloat"), &Parameter::SetFloat)
|
||||
.Func(_SC("SetFloat32"), &Parameter::SetFloat32)
|
||||
.Func(_SC("SetFloat64"), &Parameter::SetFloat64)
|
||||
.Func(_SC("SetString"), &Parameter::SetString)
|
||||
.FmtFunc(_SC("SetString"), &Parameter::SetString)
|
||||
.Func(_SC("SetZeroBlob"), &Parameter::SetZeroBlob)
|
||||
.Func(_SC("SetBlob"), &Parameter::SetBlob)
|
||||
.Func(_SC("SetData"), &Parameter::SetData)
|
||||
@ -828,8 +778,6 @@ void Register_Parameter(Table & sqlns)
|
||||
.Func(_SC("SetDatetimeEx"), &Parameter::SetDatetimeEx)
|
||||
.Func(_SC("SetNow"), &Parameter::SetNow)
|
||||
.Func(_SC("SetNull"), &Parameter::SetNull)
|
||||
// Squirrel Methods
|
||||
.SquirrelFunc(_SC("SetStringF"), &Parameter::SetStringF)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -346,12 +346,12 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to bind a string value at the referenced parameter index.
|
||||
*/
|
||||
void SetString(CSStr value);
|
||||
void SetString(const StackStrF & value);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to bind a string value at the referenced parameter index.
|
||||
*/
|
||||
void SetStringEx(CSStr value, Int32 length);
|
||||
void SetStringRaw(CSStr value, SQInteger length = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to bind a zeroed blob value at the referenced parameter index.
|
||||
@ -407,12 +407,6 @@ public:
|
||||
* Attempt to bind a null value at the referenced parameter index.
|
||||
*/
|
||||
void SetNull();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to bind a string value at the referenced parameter index.
|
||||
*/
|
||||
static SQInteger SetStringF(HSQUIRRELVM vm);
|
||||
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -165,10 +165,10 @@ void Statement::ValidateRow() const
|
||||
#endif // _DEBUG
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Statement::Statement(const Connection & connection, CSStr query)
|
||||
Statement::Statement(const Connection & connection, const StackStrF & query)
|
||||
: m_Handle(new StmtHnd(connection.GetHandle()))
|
||||
{
|
||||
SQMOD_GET_VALID(*this)->Create(query);
|
||||
SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -430,7 +430,7 @@ void Register_Statement(Table & sqlns)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< const Statement & >()
|
||||
.Ctor< const Connection &, CCStr >()
|
||||
.FmtCtor< const Connection & >()
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Statement::Typename)
|
||||
.Func(_SC("_tostring"), &Statement::ToString)
|
||||
@ -454,11 +454,11 @@ void Register_Statement(Table & sqlns)
|
||||
// Member Methods
|
||||
.Func(_SC("Release"), &Statement::Release)
|
||||
.Func(_SC("CheckParameter"), &Statement::CheckParameter)
|
||||
.Func(_SC("GetParameterIndex"), &Statement::GetParameterIndex)
|
||||
.FmtFunc(_SC("GetParameterIndex"), &Statement::GetParameterIndex)
|
||||
.Func(_SC("GetParameterName"), &Statement::GetParameterName)
|
||||
.Func(_SC("CheckColumn"), &Statement::CheckColumn)
|
||||
.Func(_SC("IsColumnNull"), &Statement::IsColumnNull)
|
||||
.Func(_SC("ColumnIndex"), &Statement::GetColumnIndex)
|
||||
.FmtFunc(_SC("ColumnIndex"), &Statement::GetColumnIndex)
|
||||
.Func(_SC("ColumnName"), &Statement::GetColumnName)
|
||||
.Func(_SC("ColumnOriginName"), &Statement::GetColumnOriginName)
|
||||
.Func(_SC("ColumnType"), &Statement::GetColumnType)
|
||||
@ -484,7 +484,7 @@ void Register_Statement(Table & sqlns)
|
||||
.Func(_SC("SetFloat"), &Statement::SetFloat)
|
||||
.Func(_SC("SetFloat32"), &Statement::SetFloat32)
|
||||
.Func(_SC("SetFloat64"), &Statement::SetFloat64)
|
||||
.Func(_SC("SetString"), &Statement::SetString)
|
||||
.FmtFunc(_SC("SetString"), &Statement::SetString)
|
||||
.Func(_SC("SetZeroBlob"), &Statement::SetZeroBlob)
|
||||
.Func(_SC("SetBlob"), &Statement::SetBlob)
|
||||
.Func(_SC("SetData"), &Statement::SetData)
|
||||
|
@ -98,16 +98,16 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct a statement under the specified connection using the specified string.
|
||||
*/
|
||||
Statement(const ConnRef & connection, CSStr query)
|
||||
Statement(const ConnRef & connection, const StackStrF & query)
|
||||
: m_Handle(new StmtHnd(connection))
|
||||
{
|
||||
SQMOD_GET_VALID(*this)->Create(query);
|
||||
SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct a statement under the specified connection using the specified string.
|
||||
*/
|
||||
Statement(const Connection & connection, CSStr query);
|
||||
Statement(const Connection & connection, const StackStrF & query);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Direct handle constructor.
|
||||
@ -319,9 +319,9 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the parameter index associated with the specified name.
|
||||
*/
|
||||
Int32 GetParameterIndex(CSStr name) const
|
||||
Int32 GetParameterIndex(const StackStrF & name) const
|
||||
{
|
||||
return sqlite3_bind_parameter_index(SQMOD_GET_VALID(*this)->mPtr, name);
|
||||
return sqlite3_bind_parameter_index(SQMOD_GET_VALID(*this)->mPtr, name.mPtr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -372,9 +372,9 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the column index associated with the specified name.
|
||||
*/
|
||||
Int32 GetColumnIndex(CSStr name) const
|
||||
Int32 GetColumnIndex(const StackStrF & name) const
|
||||
{
|
||||
return SQMOD_GET_VALID(*this)->GetColumnIndex(name);
|
||||
return SQMOD_GET_VALID(*this)->GetColumnIndex(name.mPtr, name.mLen);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -599,7 +599,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to bind a string value at the specified parameter index.
|
||||
*/
|
||||
Statement & SetString(const Object & param, CSStr value)
|
||||
Statement & SetString(const Object & param, const StackStrF & value)
|
||||
{
|
||||
Parameter(SQMOD_GET_CREATED(*this), param).SetString(value);
|
||||
// Allow chaining of operations
|
||||
|
Loading…
Reference in New Issue
Block a user