mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 16:57:16 +01:00
140 lines
4.4 KiB
C++
140 lines
4.4 KiB
C++
// ------------------------------------------------------------------------------------------------
|
|
#include "Handle/Statement.hpp"
|
|
#include "Handle/Connection.hpp"
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
namespace SqMod {
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
StmtHnd::StmtHnd(const ConnRef & conn)
|
|
: mPtr(nullptr)
|
|
, mStatus(SQLITE_OK)
|
|
, mConn(conn)
|
|
, mQuery()
|
|
, mColumns(0)
|
|
, mParameters(0)
|
|
, mIndexes()
|
|
, mGood(false)
|
|
, mDone(false)
|
|
{
|
|
/* ... */
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
StmtHnd::~StmtHnd()
|
|
{
|
|
// Is there anything to finalize?
|
|
if (mPtr != nullptr)
|
|
{
|
|
// Attempt to finalize the statement
|
|
if ((sqlite3_finalize(mPtr)) != SQLITE_OK)
|
|
{
|
|
SqMod_LogErr("Unable to finalize SQLite statement [%s]", mConn->ErrMsg());
|
|
}
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
void StmtHnd::Create(CSStr query)
|
|
{
|
|
// Make sure a previous statement doesn't exist
|
|
if (mPtr)
|
|
{
|
|
STHROWF("Unable to prepare statement. Statement already prepared");
|
|
}
|
|
// Is the specified database connection is valid?
|
|
else if (!mConn)
|
|
{
|
|
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())
|
|
{
|
|
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->mPtr, mQuery.c_str(), (Int32)mQuery.size(),
|
|
&mPtr, nullptr)) != SQLITE_OK)
|
|
{
|
|
// Clear the query string since it failed
|
|
mQuery.clear();
|
|
// 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());
|
|
}
|
|
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::GetColumnIndex(CSStr name)
|
|
{
|
|
// Validate the handle
|
|
if (!mPtr)
|
|
{
|
|
STHROWF("Invalid SQLite statement");
|
|
}
|
|
// Are the names cached?
|
|
else if (mIndexes.empty())
|
|
{
|
|
for (Int32 i = 0; i < mColumns; ++i)
|
|
{
|
|
// Get the column name at the current index
|
|
CSStr name = static_cast< CSStr >(sqlite3_column_name(mPtr, i));
|
|
// Validate the name
|
|
if (!name)
|
|
{
|
|
STHROWF("Unable to retrieve column name for index (%d)", i);
|
|
}
|
|
// Save it to guarantee the same lifetime as this instance
|
|
else
|
|
{
|
|
mIndexes[name] = i;
|
|
}
|
|
}
|
|
}
|
|
// Attempt to find the specified column
|
|
const Indexes::iterator itr = mIndexes.find(name);
|
|
// Was there a column with the specified name?
|
|
if (itr != mIndexes.end())
|
|
{
|
|
return itr->second;
|
|
}
|
|
// No such column exists (expecting the invoker to validate the result)
|
|
return -1;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
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
|