mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-09-18 10:17:19 +02:00
Fixed excpetion throwing in SQLite document to that generated corrupted messages because snprintf was used instead of vsnprintf.
Revised most of the SQLite plugin and cleaned code.
This commit is contained in:
@@ -17,14 +17,6 @@ SQInteger Connection::Typename(HSQUIRRELVM vm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::Validate() const
|
||||
{
|
||||
// Is the handle valid?
|
||||
if (!m_Handle)
|
||||
STHROWF("Invalid SQLite connection reference");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection::Connection()
|
||||
: m_Handle()
|
||||
@@ -37,7 +29,9 @@ Connection::Connection(CSStr name)
|
||||
: m_Handle(name)
|
||||
{
|
||||
if (m_Handle.m_Hnd)
|
||||
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
{
|
||||
m_Handle->Create(name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -45,7 +39,9 @@ Connection::Connection(CSStr name, Int32 flags)
|
||||
: m_Handle(name)
|
||||
{
|
||||
if (m_Handle.m_Hnd)
|
||||
m_Handle->Create(name, flags, NULL);
|
||||
{
|
||||
m_Handle->Create(name, flags, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -53,17 +49,21 @@ Connection::Connection(CSStr name, Int32 flags, CSStr vfs)
|
||||
: m_Handle(name)
|
||||
{
|
||||
if (m_Handle.m_Hnd)
|
||||
{
|
||||
m_Handle->Create(name, flags, vfs);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Connection::Exec(CSStr str)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Attempt to execute the specified query
|
||||
if ((m_Handle = sqlite3_exec(m_Handle, str, NULL, NULL, NULL)) != SQLITE_OK)
|
||||
if ((m_Handle = sqlite3_exec(m_Handle, str, nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||
{
|
||||
STHROWF("Unable to execute query [%s]", m_Handle.ErrMsg());
|
||||
}
|
||||
// Return rows affected by this query
|
||||
return sqlite3_changes(m_Handle);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ Int32 Connection::Exec(CSStr str)
|
||||
Object Connection::Query(CSStr str) const
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Return the requested information
|
||||
return Object(new Statement(m_Handle, str));
|
||||
}
|
||||
@@ -81,10 +81,12 @@ Object Connection::Query(CSStr str) const
|
||||
void Connection::Queue(CSStr str)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Is there a query to commit?
|
||||
if (IsQueryEmpty(str))
|
||||
{
|
||||
STHROWF("No query string to queue");
|
||||
}
|
||||
// Add the specified string to the queue
|
||||
m_Handle->mQueue.push_back(str);
|
||||
}
|
||||
@@ -93,12 +95,14 @@ void Connection::Queue(CSStr str)
|
||||
bool Connection::IsReadOnly() const
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Request the desired information
|
||||
const int result = sqlite3_db_readonly(m_Handle, "main");
|
||||
// Verify the result
|
||||
if (result == -1)
|
||||
{
|
||||
STHROWF("'main' is not the name of a database on connection");
|
||||
}
|
||||
// Return the requested information
|
||||
return (result != 1);
|
||||
}
|
||||
@@ -107,7 +111,7 @@ bool Connection::IsReadOnly() const
|
||||
bool Connection::TableExists(CCStr name) const
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
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]=?");
|
||||
// Could the statement be created?
|
||||
@@ -117,7 +121,9 @@ bool Connection::TableExists(CCStr name) const
|
||||
stmt.IndexBindS(1, name);
|
||||
// Attempt to step the statement and obtain a value
|
||||
if (stmt.Step())
|
||||
{
|
||||
return (sqlite3_column_int(stmt, 0) == 1);
|
||||
}
|
||||
}
|
||||
// Assume it doesn't exist
|
||||
return false;
|
||||
@@ -127,7 +133,7 @@ bool Connection::TableExists(CCStr name) const
|
||||
Object Connection::GetLastInsertRowID() const
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(_SqVM);
|
||||
// Push a long integer instance with the requested value on the stack
|
||||
@@ -140,26 +146,32 @@ Object Connection::GetLastInsertRowID() const
|
||||
void Connection::SetBusyTimeout(Int32 millis)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Apply requested timeout
|
||||
if ((m_Handle = sqlite3_busy_timeout(m_Handle, millis)) != SQLITE_OK)
|
||||
{
|
||||
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
|
||||
Validate();
|
||||
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)
|
||||
{
|
||||
STHROWF("Unable to get runtime status information", m_Handle.ErrMsg());
|
||||
}
|
||||
// Return the high-water value if requested
|
||||
else if (highwater)
|
||||
{
|
||||
return hiwtr_value;
|
||||
}
|
||||
// Return the requested information
|
||||
return cur_value;
|
||||
}
|
||||
@@ -168,7 +180,7 @@ Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
|
||||
void Connection::ReserveQueue(Uint32 num)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Perform the requested operation
|
||||
m_Handle->mQueue.reserve(m_Handle->mQueue.size() + num);
|
||||
}
|
||||
@@ -177,7 +189,7 @@ void Connection::ReserveQueue(Uint32 num)
|
||||
Int32 Connection::Flush(Uint32 num)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// We need to supply a null callback
|
||||
Object env;
|
||||
Function func;
|
||||
@@ -189,7 +201,7 @@ Int32 Connection::Flush(Uint32 num)
|
||||
Int32 Connection::Flush(Uint32 num, Object & env, Function & func)
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
m_Handle.Validate();
|
||||
// Attempt to flush the requested amount of queries
|
||||
return m_Handle->Flush(num, env, func);
|
||||
}
|
||||
@@ -232,56 +244,21 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Do we have a valid connection identifier?
|
||||
else if (!conn->m_Handle)
|
||||
else if (!(conn->m_Handle))
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||
}
|
||||
// Do we have enough values to call the format function?
|
||||
else if (top > 2)
|
||||
// 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))
|
||||
{
|
||||
SStr sql = NULL;
|
||||
SQInteger len = 0;
|
||||
// Attempt to generate the specified string format
|
||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
{
|
||||
return ret; // Propagate the exception
|
||||
}
|
||||
// Attempt to execute the specified query
|
||||
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK)
|
||||
{
|
||||
// Generate the query message first
|
||||
String msg("Unable to execute query ");
|
||||
// (we can't use FmtStr here because Squirrel doesn't make a copy of the message)
|
||||
msg.push_back('[');
|
||||
msg.append(conn->m_Handle.ErrMsg());
|
||||
msg.push_back(']');
|
||||
// Now throw the message
|
||||
return sq_throwerror(vm, msg.c_str());
|
||||
}
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
else
|
||||
// Attempt to execute the specified query
|
||||
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, val.mPtr, nullptr, nullptr, nullptr)) != SQLITE_OK)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
Var< CSStr > sql(vm, 2);
|
||||
// See if the obtained value is a valid query string
|
||||
if (!sql.value)
|
||||
{
|
||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
||||
}
|
||||
// Attempt to execute the specified query
|
||||
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, sql.value, NULL, NULL, NULL)) != SQLITE_OK)
|
||||
{
|
||||
// Generate the query message first
|
||||
String msg("Unable to execute query ");
|
||||
// (we can't use FmtStr here because Squirrel doesn't make a copy of the message)
|
||||
msg.push_back('[');
|
||||
msg.append(conn->m_Handle.ErrMsg());
|
||||
msg.push_back(']');
|
||||
// Now throw the message
|
||||
return sq_throwerror(vm, msg.c_str());
|
||||
}
|
||||
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));
|
||||
@@ -316,37 +293,19 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Do we have a valid connection identifier?
|
||||
else if (!conn->m_Handle)
|
||||
else if (!(conn->m_Handle))
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||
}
|
||||
// Do we have enough values to call the format function?
|
||||
else if (top > 2)
|
||||
// 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))
|
||||
{
|
||||
SStr sql = NULL;
|
||||
SQInteger len = 0;
|
||||
// Attempt to generate the specified string format
|
||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
{
|
||||
return ret; // Propagate the exception
|
||||
}
|
||||
// Attempt to queue the specified query
|
||||
conn->m_Handle->mQueue.emplace_back(sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
Var< CSStr > sql(vm, 2);
|
||||
// See if the obtained value is a valid query string
|
||||
if (!sql.value)
|
||||
{
|
||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
||||
}
|
||||
// Attempt to queue the specified query
|
||||
conn->m_Handle->mQueue.emplace_back(sql.value);
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to queue the specified query
|
||||
conn->m_Handle->mQueue.emplace_back(val.mPtr);
|
||||
// This function does not return a value
|
||||
return 0;
|
||||
}
|
||||
@@ -378,50 +337,25 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
|
||||
return sq_throwerror(vm, "Invalid SQLite connection instance");
|
||||
}
|
||||
// Do we have a valid connection identifier?
|
||||
else if (!conn->m_Handle)
|
||||
else if (!(conn->m_Handle))
|
||||
{
|
||||
return sq_throwerror(vm, "Invalid SQLite connection reference");
|
||||
}
|
||||
// Do we have enough values to call the format function?
|
||||
else if (top > 2)
|
||||
// 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))
|
||||
{
|
||||
SStr sql = NULL;
|
||||
SQInteger len = 0;
|
||||
// Attempt to generate the specified string format
|
||||
SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
{
|
||||
return ret; // Propagate the exception
|
||||
}
|
||||
// Attempt to create a statement with the specified query
|
||||
try
|
||||
{
|
||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, sql));
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.Message().c_str());
|
||||
}
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
else
|
||||
// Attempt to create a statement with the specified query
|
||||
try
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
Var< CSStr > sql(vm, 2);
|
||||
// See if the obtained value is a valid query string
|
||||
if (!sql.value)
|
||||
{
|
||||
return sq_throwerror(vm, "Unable to retrieve the query");
|
||||
}
|
||||
// Attempt to create a statement with the specified query
|
||||
try
|
||||
{
|
||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, sql.value));
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.Message().c_str());
|
||||
}
|
||||
ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, val.mPtr));
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.Message().c_str());
|
||||
}
|
||||
// This function returned a value
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user