1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-23 05:07:13 +01:00
SqMod/modules/sqlite/Column.cpp
Sandu Liviu Catalin a867bfd84d Fixed various issues with Sqrat thinking the type wasn't registered if an error is thrown in the constructor.
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.
2016-02-27 13:51:14 +02:00

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