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

Reimplemented the formatted query methods in SQLite connection using a better approach.

This commit is contained in:
Sandu Liviu Catalin 2016-03-11 21:07:55 +02:00
parent 3fa7b17bd7
commit 9ca2c7ca7d

View File

@ -344,41 +344,32 @@ void Connection::TakeSnapshot(const ConnHnd & destination)
SQInteger Connection::ExecF(HSQUIRRELVM vm) SQInteger Connection::ExecF(HSQUIRRELVM vm)
{ {
const Int32 top = sq_gettop(vm); const Int32 top = sq_gettop(vm);
// Do we even have enough arguments? // Was the query value specified?
if (top <= 1) if (top <= 1)
return sq_throwerror(vm, "Missing the query string");
// Obtain the connection instance
Var< Connection * > inst(vm, 1);
// Do we have a valid connection instance?
if (!inst.value)
return sq_throwerror(vm, "Invalid connection instance");
// Do we have a valid connection reference?
else if (!inst.value->m_Handle)
return sq_throwerror(vm, "Invalid SQLite connection reference");
// Is the specified message value a string or something convertible to string?
else if (top == 2 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1))))
{ {
CCStr sql = NULL; return sq_throwerror(vm, "Missing query value");
// Attempt to retrieve the string from the stack }
if (SQ_FAILED(sq_getstring(vm, -1, &sql))) // The connection instance
{ Connection * conn = nullptr;
// If the value was converted to a string then pop the string // Attempt to extract the argument values
sq_pop(vm, sq_gettop(vm) - top); try
// Now we can throw the error message {
return sq_throwerror(vm, "Unable to retrieve the query"); conn = Var< Connection * >(vm, 1).value;
} }
// Prevent the object from being destroyed once we pop it catch (const Sqrat::Exception & e)
Var< Object > obj(vm, -1); {
// If the value was converted to a string then pop the string // Propagate the error
sq_pop(vm, sq_gettop(vm) - top); return sq_throwerror(vm, e.Message().c_str());
// Attempt to execute the specified query }
if ((inst.value->m_Handle = sqlite3_exec(inst.value->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK) // Do we have a valid connection instance?
{ if (!conn)
// Generate the error message and throw the resulted string {
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", inst.value->m_Handle.ErrMsg())); return sq_throwerror(vm, "Invalid SQLite connection instance");
} }
// Push the result onto the stack // Do we have a valid connection identifier?
sq_pushinteger(vm, sqlite3_changes(inst.value->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? // Do we have enough values to call the format function?
else if (top > 2) else if (top > 2)
@ -386,23 +377,36 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
SStr sql = NULL; SStr sql = NULL;
SQInteger len = 0; SQInteger len = 0;
// Attempt to generate the specified string format // Attempt to generate the specified string format
SQRESULT ret = sqstd_format(vm, 3, &len, &sql); SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
// Did the format failed? // Did the format failed?
if (SQ_FAILED(ret)) if (SQ_FAILED(ret))
return ret; // Propagate the exception
// Attempt to execute the resulted query
if ((inst.value->m_Handle = sqlite3_exec(inst.value->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK)
{ {
// Generate the error message and throw the resulted string return ret; // Propagate the exception
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", inst.value->m_Handle.ErrMsg())); }
// Attempt to execute the specified query
else if ((conn->m_Handle = sqlite3_exec(conn->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK)
{
return sq_throwerror(vm, FmtStr("Unable to execute query [%s]", conn->m_Handle.ErrMsg()));
} }
// Push the result onto the stack
sq_pushinteger(vm, sqlite3_changes(inst.value->m_Handle));
} }
// All methods of retrieving the string value failed
else else
return sq_throwerror(vm, "Unable to extract the query string"); {
// At this point we should have a return value on the stack // 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)
{
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));
// This function returned a value
return 1; return 1;
} }
@ -410,41 +414,32 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
SQInteger Connection::QueueF(HSQUIRRELVM vm) SQInteger Connection::QueueF(HSQUIRRELVM vm)
{ {
const Int32 top = sq_gettop(vm); const Int32 top = sq_gettop(vm);
// Do we even have enough arguments? // Was the query value specified?
if (top <= 1) if (top <= 1)
return sq_throwerror(vm, "Missing the query string");
// Obtain the connection instance
Var< Connection * > inst(vm, 1);
// Do we have a valid connection instance?
if (!inst.value)
return sq_throwerror(vm, "Invalid connection instance");
// Do we have a valid connection reference?
else if (!inst.value->m_Handle)
return sq_throwerror(vm, "Invalid SQLite connection reference");
// Is the specified message value a string or something convertible to string?
else if (top == 2 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1))))
{ {
CCStr sql = NULL; return sq_throwerror(vm, "Missing query value");
// Attempt to retrieve the string from the stack }
if (SQ_FAILED(sq_getstring(vm, -1, &sql))) // The connection instance
{ Connection * conn = nullptr;
// If the value was converted to a string then pop the string // Attempt to extract the argument values
sq_pop(vm, sq_gettop(vm) - top); try
// Now we can throw the error message {
return sq_throwerror(vm, "Unable to retrieve the query"); conn = Var< Connection * >(vm, 1).value;
} }
// Is there even a query to queue? catch (const Sqrat::Exception & e)
else if (IsQueryEmpty(sql)) {
{ // Propagate the error
// If the value was converted to a string then pop the string return sq_throwerror(vm, e.Message().c_str());
sq_pop(vm, sq_gettop(vm) - top); }
// Now we can throw the error message // Do we have a valid connection instance?
return sq_throwerror(vm,"No query to queue"); if (!conn)
} {
// Attempt to queue the specified query return sq_throwerror(vm, "Invalid SQLite connection instance");
inst.value->m_Handle->mQueue.push_back(sql); }
// If the value was converted to a string then pop the string // Do we have a valid connection identifier?
sq_pop(vm, sq_gettop(vm) - top); else if (!conn->m_Handle)
{
return sq_throwerror(vm, "Invalid SQLite connection reference");
} }
// Do we have enough values to call the format function? // Do we have enough values to call the format function?
else if (top > 2) else if (top > 2)
@ -452,19 +447,27 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
SStr sql = NULL; SStr sql = NULL;
SQInteger len = 0; SQInteger len = 0;
// Attempt to generate the specified string format // Attempt to generate the specified string format
SQRESULT ret = sqstd_format(vm, 3, &len, &sql); SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
// Did the format failed? // Did the format failed?
if (SQ_FAILED(ret)) if (SQ_FAILED(ret))
{
return ret; // Propagate the exception return ret; // Propagate the exception
// Is there even a query to queue? }
else if (IsQueryEmpty(sql))
return sq_throwerror(vm,"No query to queue");
// Attempt to queue the specified query // Attempt to queue the specified query
inst.value->m_Handle->mQueue.push_back(sql); conn->m_Handle->mQueue.emplace_back(sql);
} }
// All methods of retrieving the string value failed
else else
return sq_throwerror(vm, "Unable to extract the query string"); {
// 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);
}
// This function does not return a value // This function does not return a value
return 0; return 0;
} }
@ -473,42 +476,32 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
SQInteger Connection::QueryF(HSQUIRRELVM vm) SQInteger Connection::QueryF(HSQUIRRELVM vm)
{ {
const Int32 top = sq_gettop(vm); const Int32 top = sq_gettop(vm);
// Do we even have enough arguments? // Was the query value specified?
if (top <= 1) if (top <= 1)
return sq_throwerror(vm, "Missing the query string");
// Obtain the connection instance
Var< Connection * > inst(vm, 1);
// Do we have a valid connection instance?
if (!inst.value)
return sq_throwerror(vm, "Invalid connection instance");
// Do we have a valid connection reference?
else if (!inst.value->m_Handle)
return sq_throwerror(vm, "Invalid SQLite connection reference");
// Is the specified message value a string or something convertible to string?
else if (top == 2 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1))))
{ {
CCStr sql = NULL; return sq_throwerror(vm, "Missing query value");
// Attempt to retrieve the string from the stack }
if (SQ_FAILED(sq_getstring(vm, -1, &sql))) // The connection instance
{ Connection * conn = nullptr;
// If the value was converted to a string then pop the string // Attempt to extract the argument values
sq_pop(vm, sq_gettop(vm) - top); try
// Now we can throw the error message {
return sq_throwerror(vm, "Unable to retrieve the query"); conn = Var< Connection * >(vm, 1).value;
} }
// Prevent the object from being destroyed once we pop it catch (const Sqrat::Exception & e)
Var< Object > obj(vm, -1); {
// If the value was converted to a string then pop the string // Propagate the error
sq_pop(vm, sq_gettop(vm) - top); return sq_throwerror(vm, e.Message().c_str());
// Attempt to create a statement with the specified query }
try // Do we have a valid connection instance?
{ if (!conn)
ClassType< Statement >::PushInstance(vm, new Statement(inst.value->m_Handle, sql)); {
} return sq_throwerror(vm, "Invalid SQLite connection instance");
catch (const Sqrat::Exception & e) }
{ // Do we have a valid connection identifier?
return sq_throwerror(vm, e.Message().c_str()); else if (!conn->m_Handle)
} {
return sq_throwerror(vm, "Invalid SQLite connection reference");
} }
// Do we have enough values to call the format function? // Do we have enough values to call the format function?
else if (top > 2) else if (top > 2)
@ -516,24 +509,42 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
SStr sql = NULL; SStr sql = NULL;
SQInteger len = 0; SQInteger len = 0;
// Attempt to generate the specified string format // Attempt to generate the specified string format
SQRESULT ret = sqstd_format(vm, 3, &len, &sql); SQRESULT ret = sqstd_format(vm, 2, &len, &sql);
// Did the format failed? // Did the format failed?
if (SQ_FAILED(ret)) if (SQ_FAILED(ret))
{
return ret; // Propagate the exception return ret; // Propagate the exception
}
// Attempt to create a statement with the specified query // Attempt to create a statement with the specified query
try try
{ {
ClassType< Statement >::PushInstance(vm, new Statement(inst.value->m_Handle, sql)); ClassType< Statement >::PushInstance(vm, new Statement(conn->m_Handle, sql));
} }
catch (const Sqrat::Exception & e) catch (const Sqrat::Exception & e)
{ {
return sq_throwerror(vm, e.Message().c_str()); return sq_throwerror(vm, e.Message().c_str());
} }
} }
// All methods of retrieving the string value failed
else else
return sq_throwerror(vm, "Unable to extract the query string"); {
// At this point we should have a return value on the stack // 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());
}
}
// This function returned a value
return 1; return 1;
} }