mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-02-23 05:07:13 +01:00
Fixed asserts in connection and statement handles to check the correct property. Switched various methods to return objects instead of direct types. Various other fixes and improvements on the SQLite module.
265 lines
8.2 KiB
C++
265 lines
8.2 KiB
C++
// ------------------------------------------------------------------------------------------------
|
|
#include "Column.hpp"
|
|
#include "Connection.hpp"
|
|
#include "Statement.hpp"
|
|
#include "Module.hpp"
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#include <sqrat.h>
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
namespace SqMod {
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
SQInteger Column::Typename(HSQUIRRELVM vm)
|
|
{
|
|
static SQChar name[] = _SC("SqSQLiteColumn");
|
|
sq_pushstring(vm, name, sizeof(name));
|
|
return 1;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
bool Column::Validate() const
|
|
{
|
|
// Are we pointing to a valid index?
|
|
if (m_Index < 0)
|
|
_SqMod->SqThrow("Invalid column index");
|
|
// Do we belong to a valid statement?
|
|
else if (!m_Stmt)
|
|
_SqMod->SqThrow("Invalid SQLite statement reference");
|
|
// Requirements satisfied
|
|
else
|
|
return true;
|
|
// Validation failed
|
|
return false;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
bool Column::RowAvailable() const
|
|
{
|
|
// Are we pointing to a valid index?
|
|
if (m_Index < 0)
|
|
_SqMod->SqThrow("Invalid column index");
|
|
// Do we belong to a valid statement?
|
|
else if (!m_Stmt)
|
|
_SqMod->SqThrow("Invalid SQLite statement reference");
|
|
// Do we have any rows available?
|
|
else if (!m_Stmt->mGood)
|
|
_SqMod->SqThrow("No row available");
|
|
// Requirements satisfied
|
|
else
|
|
return true;
|
|
// Validation failed
|
|
return false;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Object Column::GetStatement() const
|
|
{
|
|
// Validate the handle
|
|
if (Validate())
|
|
return Object(new Statement(m_Stmt));
|
|
// Request failed
|
|
return Object(new Statement());
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Object Column::GetConnection() const
|
|
{
|
|
// Validate the handle
|
|
if (Validate())
|
|
return Object(new Connection(m_Stmt->mConn));
|
|
// Request failed
|
|
return Object(new Connection());
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Int32 Column::GetNumber() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
return sqlite3_column_int(m_Stmt, m_Index);
|
|
// Request failed
|
|
return 0;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
SQInteger Column::GetInteger() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
#ifdef _SQ64
|
|
return sqlite3_column_int64(m_Stmt, m_Index);
|
|
#else
|
|
return sqlite3_column_int(m_Stmt, m_Index);
|
|
#endif
|
|
// Request failed
|
|
return 0;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
SQFloat Column::GetFloat() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
return (SQFloat)sqlite3_column_double(m_Stmt, m_Index);
|
|
// Request failed
|
|
return SQFloat(0.0);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Object Column::GetLong() const
|
|
{
|
|
// Validate the handle and index
|
|
if (!RowAvailable())
|
|
return Object(); // Request failed
|
|
// Obtain the initial stack size
|
|
const Int32 top = sq_gettop(_SqVM);
|
|
// Push a long integer instance with the requested value on the stack
|
|
_SqMod->PushSLongObject(_SqVM, sqlite3_column_int64(m_Stmt, m_Index));
|
|
// Obtain the object from the stack
|
|
Var< Object > inst(_SqVM, -1);
|
|
// Remove an pushed values (if any) to restore the stack
|
|
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
// Return the long integer instance
|
|
return inst.value;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Object Column::GetString() const
|
|
{
|
|
// Validate the handle and index
|
|
if (!RowAvailable())
|
|
return Object(); // Request failed
|
|
// Obtain the initial stack size
|
|
const Int32 top = sq_gettop(_SqVM);
|
|
// Push the column text on the stack
|
|
sq_pushstring(_SqVM, (CSStr)sqlite3_column_text(m_Stmt, m_Index),
|
|
sqlite3_column_bytes(m_Stmt, m_Index));
|
|
// Obtain the object from the stack
|
|
Var< Object > inst(_SqVM, -1);
|
|
// Remove an pushed values (if any) to restore the stack
|
|
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
// Return the long integer instance
|
|
return inst.value;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
bool Column::GetBoolean() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
return sqlite3_column_int(m_Stmt, m_Index) > 0;
|
|
// Request failed
|
|
return false;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Object Column::GetBlob() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
return Object(); // Request failed
|
|
// Obtain the initial stack size
|
|
const Int32 top = sq_gettop(_SqVM);
|
|
// Obtain the size of the data
|
|
const Int32 sz = sqlite3_column_bytes(m_Stmt, 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);
|
|
// Could the memory blob be allocated?
|
|
if (!p)
|
|
{
|
|
_SqMod->SqThrow("Unable to allocate space for column blob value");
|
|
// Request failed
|
|
return Object();
|
|
}
|
|
// Is there any data to read?
|
|
else if (!b)
|
|
{
|
|
// Pop the memory blob from the stack
|
|
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
// Now throw the error
|
|
_SqMod->SqThrow("Unable to read data from column blob value");
|
|
// Request failed
|
|
return Object();
|
|
}
|
|
// Copy the data into the memory blob
|
|
else
|
|
memcpy(p, b, sz);
|
|
// Obtain the object from the stack
|
|
Var< Object > inst(_SqVM, -1);
|
|
// Remove an pushed values (if any) to restore the stack
|
|
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
|
|
// Return the long integer instance
|
|
return inst.value;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
SQChar Column::GetChar() const
|
|
{
|
|
// Validate the handle and index
|
|
if (RowAvailable())
|
|
return (SQChar)sqlite3_column_int(m_Stmt, m_Index);
|
|
// Request failed
|
|
return 0;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
bool Column::IsNull() const
|
|
{
|
|
// Can we make the request?
|
|
if (Validate())
|
|
return (sqlite3_column_type(m_Stmt, m_Index) == SQLITE_NULL);
|
|
// Request failed
|
|
return true;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
CSStr Column::GetName() const
|
|
{
|
|
// Can we make the request?
|
|
if (Validate())
|
|
return sqlite3_column_name(m_Stmt, m_Index);
|
|
// Request failed
|
|
return _SC("");
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
CSStr Column::GetOriginName() const
|
|
{
|
|
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
|
// Can we make the request?
|
|
if (Validate())
|
|
return sqlite3_column_origin_name(m_Stmt, m_Index);
|
|
#else
|
|
_SqMod->SqThrow("The module was compiled without this feature");
|
|
#endif
|
|
// Request failed
|
|
return _SC("");
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Int32 Column::GetType() const
|
|
{
|
|
// Can we make the request?
|
|
if (Validate())
|
|
return sqlite3_column_type(m_Stmt, m_Index);
|
|
// Request failed
|
|
return -1;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Int32 Column::GetBytes() const
|
|
{
|
|
// Can we make the request?
|
|
if (Validate())
|
|
return sqlite3_column_bytes(m_Stmt, m_Index);
|
|
// Request failed
|
|
return -1;
|
|
}
|
|
|
|
|
|
} // Namespace:: SqMod
|