From 7dc20fcc0c765601dfbf9df3dbc956a191e166e7 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Tue, 19 Jul 2016 21:42:41 +0300 Subject: [PATCH] Improve type conversion in the MySQL module. Implement field wrappers and field retrieval by name. Various other fixes and adjustments. --- modules/mysql/Convert.cpp | 65 +++- modules/mysql/Convert.hpp | 8 + modules/mysql/Field.cpp | 523 +++++++++++++++++++++++++++++ modules/mysql/Field.hpp | 318 +++++++++++++++++- modules/mysql/Handle/ResultSet.cpp | 23 +- modules/mysql/Handle/ResultSet.hpp | 13 + modules/mysql/Module.cpp | 2 + modules/mysql/ResultSet.cpp | 163 +-------- modules/mysql/ResultSet.hpp | 133 ++++++-- 9 files changed, 1054 insertions(+), 194 deletions(-) diff --git a/modules/mysql/Convert.cpp b/modules/mysql/Convert.cpp index 38e80f17..d35f163d 100644 --- a/modules/mysql/Convert.cpp +++ b/modules/mysql/Convert.cpp @@ -326,7 +326,7 @@ static inline T ConvertToUInt(CSStr value, Ulong length, enum_field_types type, // ------------------------------------------------------------------------------------------------ Int8 DbConvTo< Int8 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) { - return ConvertToUInt< Int8 >(value, length, type, tn); + return ConvertToSInt< Int8 >(value, length, type, tn); } // ------------------------------------------------------------------------------------------------ @@ -338,7 +338,7 @@ Uint8 DbConvTo< Uint8 >::From(CSStr value, Ulong length, enum_field_types type, // ------------------------------------------------------------------------------------------------ Int16 DbConvTo< Int16 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) { - return ConvertToUInt< Int16 >(value, length, type, tn); + return ConvertToSInt< Int16 >(value, length, type, tn); } // ------------------------------------------------------------------------------------------------ @@ -350,7 +350,7 @@ Uint16 DbConvTo< Uint16 >::From(CSStr value, Ulong length, enum_field_types type // ------------------------------------------------------------------------------------------------ Int32 DbConvTo< Int32 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) { - return ConvertToUInt< Int32 >(value, length, type, tn); + return ConvertToSInt< Int32 >(value, length, type, tn); } // ------------------------------------------------------------------------------------------------ @@ -362,7 +362,7 @@ Uint32 DbConvTo< Uint32 >::From(CSStr value, Ulong length, enum_field_types type // ------------------------------------------------------------------------------------------------ Int64 DbConvTo< Int64 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) { - return ConvertToUInt< Int64 >(value, length, type, tn); + return ConvertToSInt< Int64 >(value, length, type, tn); } // ------------------------------------------------------------------------------------------------ @@ -390,16 +390,16 @@ Float32 DbConvTo< Float32 >::From(CSStr value, Ulong length, enum_field_types ty case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: return ConvTo< Float32 >::From(std::strtol(value, nullptr, 10)); - case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_LONGLONG: return ConvTo< Float32 >::From(std::strtoll(value, nullptr, 10)); case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: return ConvTo< Float32 >::From(std::strtoll(value, nullptr, 10)); + case MYSQL_TYPE_SET: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: case MYSQL_TYPE_FLOAT: return std::strtof(value, nullptr); - case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_DOUBLE: return ConvTo< Float32 >::From(std::strtod(value, nullptr)); case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: return ConvTo< Float32 >::From(std::strtod(value, nullptr)); + case MYSQL_TYPE_NEWDECIMAL: return std::strtof(value, nullptr); case MYSQL_TYPE_DATE: case MYSQL_TYPE_NEWDATE: return ConvTo< Float32 >::From(MySQLDateStrToSeconds(value)); case MYSQL_TYPE_TIME: return ConvTo< Float32 >::From(MySQLTimeStrToSeconds(value)); @@ -421,7 +421,54 @@ Float32 DbConvTo< Float32 >::From(CSStr value, Ulong length, enum_field_types ty // ------------------------------------------------------------------------------------------------ Float64 DbConvTo< Float64 >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) { - return 0.0; + // Is there even a value to attempt to extract? + if (!value || *value == '\0') + { + return 0; + } + // Identify the type of value that must be converted and try to at least approximate something + switch(type) + { + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_GEOMETRY: return static_cast< Float64 >(0); + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_LONG: return ConvTo< Float64 >::From(std::strtol(value, nullptr, 10)); + case MYSQL_TYPE_LONGLONG: return ConvTo< Float64 >::From(std::strtoll(value, nullptr, 10)); + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_NEWDECIMAL: return std::strtod(value, nullptr); + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: return ConvTo< Float64 >::From(MySQLDateStrToSeconds(value)); + case MYSQL_TYPE_TIME: return ConvTo< Float64 >::From(MySQLTimeStrToSeconds(value)); + case MYSQL_TYPE_TIMESTAMP: return ConvTo< Float64 >::From(MySQLTimestampStrToSeconds(value)); + case MYSQL_TYPE_DATETIME: return ConvTo< Float64 >::From(MySQLDatetimeStrToSeconds(value)); + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: return MemToNum< Float64 >(reinterpret_cast< const Uint8 * >(value), length); + default: + { + STHROWF("Unknown conversion from (%s) to (%s)", SqMySQLTypenameC(type), tn); + } break; + } + // Should not reach this point! + return 0; +} + +// ------------------------------------------------------------------------------------------------ +bool DbConvTo< bool >::From(CSStr value, Ulong length, enum_field_types type, CSStr tn) +{ + return ConvertToSInt< Int64 >(value, length, type, tn) > 0; } } // Namespace:: SqMod diff --git a/modules/mysql/Convert.hpp b/modules/mysql/Convert.hpp index 5c248ac0..d5da67f6 100644 --- a/modules/mysql/Convert.hpp +++ b/modules/mysql/Convert.hpp @@ -113,6 +113,14 @@ template<> struct DbConvTo< Float64 > static Float64 From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Float64")); }; +/* ------------------------------------------------------------------------------------------------ + * Specialization for boolean value. +*/ +template<> struct DbConvTo< bool > +{ + static bool From(CSStr value, Ulong length, enum_field_types type, CSStr tn = _SC("Boolean")); +}; + } // Namespace:: SqMod #endif // _SQMYSQL_CONVERT_HPP_ diff --git a/modules/mysql/Field.cpp b/modules/mysql/Field.cpp index 21779da3..24d4ba37 100644 --- a/modules/mysql/Field.cpp +++ b/modules/mysql/Field.cpp @@ -1,10 +1,533 @@ // ------------------------------------------------------------------------------------------------ #include "Field.hpp" +// ------------------------------------------------------------------------------------------------ +#include +#include +#include + // ------------------------------------------------------------------------------------------------ namespace SqMod { // ------------------------------------------------------------------------------------------------ +static inline bool IsDigitsOnly(CSStr str) +{ + while (std::isdigit(*str) || std::isspace(*str)) + { + ++str; + } + // Return whether we reached the end while searching + return *str == '\0'; +} +// ------------------------------------------------------------------------------------------------ +const Uint32 Field::INVALID_INDEX = std::numeric_limits< Uint32 >::max(); + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::Typename(HSQUIRRELVM vm) +{ + static const SQChar name[] = _SC("SqMySQLField"); + sq_pushstring(vm, name, sizeof(name)); + return 1; +} + +// ------------------------------------------------------------------------------------------------ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) +void Field::Validate(CCStr file, Int32 line) const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line); + } + // Are we pointing to a valid index? + else if (m_Index >= m_Handle->mFieldCount) + { + SqThrowF("Field index is out of range: %u >= %lu =>[%s:%d]", + m_Index, m_Handle->mFieldCount, file, line); + } +} +#else +void Field::Validate() const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference"); + } + // Are we pointing to a valid index? + else if (m_Index >= m_Handle->mFieldCount) + { + SqThrowF("Field index is out of range: %u >= %lu", m_Index, m_Handle->mFieldCount); + } +} +#endif // _DEBUG + +// ------------------------------------------------------------------------------------------------ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) +void Field::ValidateCreated(CCStr file, Int32 line) const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line); + } + // Are we pointing to a valid index? + m_Handle->ValidateField(m_Index, file, line); +} +#else +void Field::ValidateCreated() const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference"); + } + // Are we pointing to a valid index? + m_Handle->ValidateField(m_Index); +} +#endif // _DEBUG + +// ------------------------------------------------------------------------------------------------ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) +const ResRef & Field::GetValid(CCStr file, Int32 line) const +{ + Validate(file, line); + return m_Handle; +} +#else +const ResRef & Field::GetValid() const +{ + Validate(); + return m_Handle; +} +#endif // _DEBUG + +// ------------------------------------------------------------------------------------------------ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) +const ResRef & Field::GetCreated(CCStr file, Int32 line) const +{ + ValidateCreated(file, line); + return m_Handle; +} +#else +const ResRef & Field::GetCreated() const +{ + ValidateCreated(); + return m_Handle; +} +#endif // _DEBUG + +// ------------------------------------------------------------------------------------------------ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) +void Field::ValidateField(Uint32 idx, CCStr file, Int32 line) const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference =>[%s:%d]", file, line); + } + // Validate the specified field index + m_Handle->ValidateField(idx, file, line); +} +#else +void Field::ValidateField(Uint32 idx) const +{ + // Do we have a valid result-set handle? + if (!m_Handle) + { + SqThrowF("Invalid MySQL result-set reference"); + } + // Validate the specified field index + m_Handle->ValidateField(idx); +} +#endif // _DEBUG + +// ------------------------------------------------------------------------------------------------ +void Field::SetIndex(const Object & field) +{ + // Where the index will be extracted + Uint32 idx = INVALID_INDEX; + // Grab the object virtual machine + HSQUIRRELVM vm = field.GetVM(); + // Remember the current stack size + const StackGuard sg(vm); + // Push the specified object onto the stack + Var< const Object & >::push(vm, field); + // Identify the type of field was given + switch (field.GetType()) + { + // Is this a string value? + case OT_STRING: + { + // Obtain the object from the stack as a string + const StackStrF val(vm, -1, false); + // Validate the result + if (SQ_FAILED(val.mRes)) + { + STHROWF("%s", LastErrorString(vm).c_str()); + } + // Is the obtained string empty? + else if (val.mLen <= 0) + { + STHROWF("Cannot use an empty field name"); + } + // Attempt to find a field with the specified name + idx = m_Handle->GetFieldIndex(val.mPtr); + } break; + // Is this an integer value? (or at least can be easily converted to one) + case OT_INTEGER: + case OT_FLOAT: + case OT_BOOL: + { + idx = ConvTo< Uint32 >::From(SqMod_PopStackInteger(vm, -1)); + } break; + // Is this an instance that we can extract either a string or integer from it? + case OT_INSTANCE: + { + // Obtain the object from the stack as a string + const StackStrF val(vm, -1, false); + // Validate the result + if (SQ_FAILED(val.mRes)) + { + STHROWF("%s", LastErrorString(vm).c_str()); + } + // Is the obtained string empty? + else if (val.mLen <= 0) + { + STHROWF("Cannot use an empty field name"); + } + // Check if this value is made only of digits + else if (IsDigitsOnly(val.mPtr)) + { + idx = ConvNum< Uint32 >::FromStr(val.mPtr); + } + // Attempt to find a field with the specified name + else + { + idx = m_Handle->GetFieldIndex(val.mPtr); + } + } break; + // We don't recognize this kind of value! + default: STHROWF("Unknown field index of type (%s)", SqTypeName(field.GetType())); + } + // Validate the obtained field index + SQMOD_VALIDATE_FIELD(*this, idx); + // Assign the new index + m_Index = idx; +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetStatement() const +{ + return Object(); +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetConnection() const +{ + return Object(); +} + +// ------------------------------------------------------------------------------------------------ +bool Field::GetBoolean() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< bool >::From(m_Handle->mBinds[m_Index].mUint64); + } + // Retrieve the value directly from the row + return DbConvTo< bool >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQChar Field::GetChar() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< SQChar >::From(m_Handle->mBinds[m_Index].mInt32[0]); + } + // Retrieve the value directly from the row + return DbConvTo< SQChar >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetInteger() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { +#ifdef _SQ64 + return ConvTo< SQInteger >::From(m_Handle->mBinds[m_Index].mInt64); +#else + return ConvTo< SQInteger >::From(m_Handle->mBinds[m_Index].mInt32[0]); +#endif // _SQ64 + } + // Retrieve the value directly from the row + return DbConvTo< SQInteger >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQFloat Field::GetFloat() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { +#ifdef SQUSEDOUBLE + return ConvTo< SQFloat >::From(m_Handle->mBinds[m_Index].mFloat64); +#else + return ConvTo< SQFloat >::From(m_Handle->mBinds[m_Index].mFloat32[0]); +#endif // SQUSEDOUBLE + } + // Retrieve the value directly from the row + return DbConvTo< SQFloat >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetInt8() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Int8 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Int8 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetUint8() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Uint8 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Uint8 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetInt16() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Int16 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Int16 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetUint16() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Uint16 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Uint16 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetInt32() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Int32 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Int32 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Field::GetUint32() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Uint32 >::From(m_Handle->mBinds[m_Index].mInt64); + } + // Retrieve the value directly from the row + return DbConvTo< Uint32 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetInt64() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Obtain the initial stack size + const StackGuard sg; + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + SqMod_PushSLongObject(DefaultVM::Get(), + ConvTo< Int64 >::From(m_Handle->mBinds[m_Index].mInt64)); + } + // Retrieve the value directly from the row + else + { + SqMod_PushSLongObject(DefaultVM::Get(), + DbConvTo< Int64 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type)); + } + // Obtain the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetUint64() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Obtain the initial stack size + const StackGuard sg; + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + SqMod_PushULongObject(DefaultVM::Get(), + ConvTo< Uint64 >::From(m_Handle->mBinds[m_Index].mUint64)); + } + // Retrieve the value directly from the row + else + { + SqMod_PushULongObject(DefaultVM::Get(), + DbConvTo< Uint64 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type)); + } + // Obtain the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +SQFloat Field::GetFloat32() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Float32 >::From(m_Handle->mBinds[m_Index].mFloat32[0]); + } + // Retrieve the value directly from the row + return DbConvTo< Float32 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +SQFloat Field::GetFloat64() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Should we retrieve the value from the bind wrapper? + if (m_Handle->mStatement) + { + return ConvTo< Float64 >::From(m_Handle->mBinds[m_Index].mFloat64); + } + // Retrieve the value directly from the row + return DbConvTo< Float64 >::From(m_Handle->mRow[m_Index], + m_Handle->mLengths[m_Index], + m_Handle->mFields[m_Index].type); +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetString() const +{ + SQMOD_VALIDATE_CREATED(*this); + // Obtain the initial stack size + const StackGuard sg; + // Retrieve the value directly from the row and push it on the stack + sq_pushstring(DefaultVM::Get(), m_Handle->mRow[m_Index], m_Handle->mLengths[m_Index]); + // Obtain the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetBuffer() const +{ + return NullObject(); +} + +// ------------------------------------------------------------------------------------------------ +Object Field::GetBlob() const +{ + return NullObject(); +} + +// ================================================================================================ +void Register_Field(Table & sqlns) +{ + sqlns.Bind(_SC("Field"), + Class< Field >(sqlns.GetVM(), _SC("SqMySQLField")) + // Constructors + .Ctor() + .Ctor< const Field & >() + // Meta-methods + .Func(_SC("_cmp"), &Field::Cmp) + .SquirrelFunc(_SC("_typename"), &Field::Typename) + .Func(_SC("_tostring"), &Field::ToString) + // Properties + .Prop(_SC("IsValid"), &Field::IsValid) + .Prop(_SC("References"), &Field::GetRefCount) + .Prop(_SC("Index"), &Field::GetIndex) + .Prop(_SC("Statement"), &Field::GetStatement) + .Prop(_SC("Connection"), &Field::GetConnection) + .Prop(_SC("Bool"), &Field::GetBoolean) + .Prop(_SC("Boolean"), &Field::GetBoolean) + .Prop(_SC("Char"), &Field::GetChar) + .Prop(_SC("Integer"), &Field::GetInteger) + .Prop(_SC("Float"), &Field::GetFloat) + .Prop(_SC("Int8"), &Field::GetInt8) + .Prop(_SC("Uint8"), &Field::GetUint8) + .Prop(_SC("Int16"), &Field::GetInt16) + .Prop(_SC("Uint16"), &Field::GetUint16) + .Prop(_SC("Int32"), &Field::GetInt32) + .Prop(_SC("Uint32"), &Field::GetUint32) + .Prop(_SC("Int64"), &Field::GetInt64) + .Prop(_SC("Uint64"), &Field::GetUint64) + .Prop(_SC("Float32"), &Field::GetFloat32) + .Prop(_SC("Float64"), &Field::GetFloat64) + .Prop(_SC("String"), &Field::GetString) + .Prop(_SC("Buffer"), &Field::GetBuffer) + .Prop(_SC("Blob"), &Field::GetBlob) + // Member Methods + .Func(_SC("Release"), &Field::Release) + ); +} } // Namespace:: SqMod diff --git a/modules/mysql/Field.hpp b/modules/mysql/Field.hpp index 4b92cd93..8403371e 100644 --- a/modules/mysql/Field.hpp +++ b/modules/mysql/Field.hpp @@ -8,7 +8,7 @@ namespace SqMod { /* ------------------------------------------------------------------------------------------------ - * ... + * Used to manage and interact with fields from result-sets. */ class Field { @@ -18,21 +18,133 @@ class Field private: // -------------------------------------------------------------------------------------------- + Uint32 m_Index; // The actual index of the referenced field. ResRef m_Handle; // Reference to the actual database result-set. - Uint32 m_Index; // Index to the managed field. protected: /* -------------------------------------------------------------------------------------------- - * Handle constructor. + * Validate the associated result-set handle and field index, and throw an error if invalid. */ - Field(const ResRef & hnd, Uint32 idx) - : m_Handle(hnd), m_Index(idx) +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + void Validate(CCStr file, Int32 line) const; +#else + void Validate() const; +#endif // _DEBUG + + /* -------------------------------------------------------------------------------------------- + * Validate the associated result-set handle and field index, and throw an error if invalid. + */ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + void ValidateCreated(CCStr file, Int32 line) const; +#else + void ValidateCreated() const; +#endif // _DEBUG + + /* -------------------------------------------------------------------------------------------- + * Validate the associated result-set handle and field index, and throw an error if invalid. + */ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + const ResRef & GetValid(CCStr file, Int32 line) const; +#else + const ResRef & GetValid() const; +#endif // _DEBUG + + /* -------------------------------------------------------------------------------------------- + * Validate the associated result-set handle and field index, and throw an error if invalid. + */ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + const ResRef & GetCreated(CCStr file, Int32 line) const; +#else + const ResRef & GetCreated() const; +#endif // _DEBUG + + /* -------------------------------------------------------------------------------------------- + * Validate the associated result-set handle and field index, and throw an error if invalid. + */ +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + void ValidateField(Uint32 idx, CCStr file, Int32 line) const; +#else + void ValidateField(Uint32 idx) const; +#endif // _DEBUG + + /* -------------------------------------------------------------------------------------------- + * Modify the index to the specified value. + */ + void SetIndex(Int32 idx) + { + SQMOD_VALIDATE_FIELD(*this, idx); + // Assign the new index + m_Index = idx; + } + + /* -------------------------------------------------------------------------------------------- + * Modify the index to the specified value. + */ + void SetIndex(CSStr name) + { + SetIndex(SQMOD_GET_CREATED(*this)->GetFieldIndex(name)); + } + + /* -------------------------------------------------------------------------------------------- + * Modify the index to the specified value. + */ + void SetIndex(const Object & field); + +public: + + // -------------------------------------------------------------------------------------------- + static const Uint32 INVALID_INDEX; + + /* -------------------------------------------------------------------------------------------- + * Default constructor (null). + */ + Field() + : m_Index(INVALID_INDEX), m_Handle() { /* ... */ } -public: + /* -------------------------------------------------------------------------------------------- + * No field constructor. + */ + Field(const ResRef & rset) + : m_Index(INVALID_INDEX), m_Handle(rset) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Index constructor. + */ + Field(const ResRef & rset, Uint32 idx) + : m_Index(idx), m_Handle(rset) + { + SQMOD_VALIDATE_FIELD(*this, m_Index); + } + + /* -------------------------------------------------------------------------------------------- + * Name constructor. + */ + Field(const ResRef & rset, CSStr name) + : m_Index(rset ? rset->GetFieldIndex(name) : -1), m_Handle(rset) + { + SQMOD_VALIDATE_FIELD(*this, m_Index); + } + + /* -------------------------------------------------------------------------------------------- + * Dynamic constructor. + */ + Field(const ResRef & rset, const Object & field) + : m_Index(INVALID_INDEX), m_Handle(rset) + { + if (!m_Handle) + { + STHROWF("Invalid MySQL result-set reference"); + } + // Extract the index + SetIndex(field); + } /* -------------------------------------------------------------------------------------------- * Copy constructor. @@ -54,6 +166,200 @@ public: */ Field & operator = (Field && o) = default; + /* -------------------------------------------------------------------------------------------- + * Perform an equality comparison between two result-set field indexes. + */ + bool operator == (const Field & o) const + { + return (m_Index == o.m_Index); + } + + /* -------------------------------------------------------------------------------------------- + * Perform an inequality comparison between two result-set field indexes. + */ + bool operator != (const Field & o) const + { + return (m_Index != o.m_Index); + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to boolean for use in boolean operations. + */ + operator bool () const + { + return (m_Handle && m_Handle->CheckFieldIndex(m_Index)); + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to compare two instances of this type. + */ + Int32 Cmp(const Field & o) const + { + if (m_Index == o.m_Index) + { + return 0; + } + else if (m_Index > o.m_Index) + { + return 1; + } + else + { + return -1; + } + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to convert an instance of this type to a string. + */ + CSStr ToString() const + { + CSStr val = nullptr; + // Can we attempt to return the parameter name? + if (m_Handle && m_Handle->CheckFieldIndex(m_Index)) + { + val = m_Handle->mFields[m_Index].name; + } + else + { + val = ToStrF(_SC("%d"), m_Index); + } + // Return the value if valid + return val ? val : _SC(""); + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to retrieve the name from instances of this type. + */ + static SQInteger Typename(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * See whether the field is valid. + */ + bool IsValid() const + { + return m_Handle; // An invalid result-set means an invalid field + } + + /* -------------------------------------------------------------------------------------------- + * Return the number of active references to the associated result-set handle. + */ + Uint32 GetRefCount() const + { + return m_Handle.Count(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the referenced field index. + */ + SQInteger GetIndex() const + { + return ConvTo< SQInteger >::From(m_Index); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the referenced database statement. + */ + Object GetStatement() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the referenced database connection. + */ + Object GetConnection() const; + + /* -------------------------------------------------------------------------------------------- + * Release the reference to the referenced database statement and field index. + */ + void Release() + { + m_Handle.Reset(); + m_Index = INVALID_INDEX; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a boolean value. + */ + bool GetBoolean() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a character. + */ + SQChar GetChar() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a native script integer. + */ + SQInteger GetInteger() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a native script floating point. + */ + SQFloat GetFloat() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a signed 8 bit integer value. + */ + SQInteger GetInt8() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as an unsigned 8 bit integer value. + */ + SQInteger GetUint8() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a signed 16 bit integer value. + */ + SQInteger GetInt16() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as an unsigned 16 bit integer value. + */ + SQInteger GetUint16() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a signed 32 bit integer value. + */ + SQInteger GetInt32() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as an unsigned 32 bit integer value. + */ + SQInteger GetUint32() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a signed 64 bit integer value. + */ + Object GetInt64() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as an unsigned 64 bit integer value. + */ + Object GetUint64() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a 32 bit floating point value. + */ + SQFloat GetFloat32() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a 64 bit floating point value. + */ + SQFloat GetFloat64() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a string value. + */ + Object GetString() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a memory buffer. + */ + Object GetBuffer() const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the referenced field as a memory blob. + */ + Object GetBlob() const; }; } // Namespace:: SqMod diff --git a/modules/mysql/Handle/ResultSet.cpp b/modules/mysql/Handle/ResultSet.cpp index 8640b353..79250ddf 100644 --- a/modules/mysql/Handle/ResultSet.cpp +++ b/modules/mysql/Handle/ResultSet.cpp @@ -186,7 +186,7 @@ void ResHnd::ValidateField(Uint32 idx, CCStr file, Int32 line) const // Is the handle valid? if (mPtr == nullptr) { - STHROWF("Invalid MySQL result-set reference =>[%s:%d]", file, line); + STHROWF("Invalid MySQL result-set =>[%s:%d]", file, line); } else if (idx >= mFieldCount) { @@ -199,7 +199,7 @@ void ResHnd::ValidateField(Uint32 idx) const // Is the handle valid? if (mPtr == nullptr) { - STHROWF("Invalid MySQL result-set reference"); + STHROWF("Invalid MySQL result-set"); } else if (idx >= mFieldCount) { @@ -208,6 +208,25 @@ void ResHnd::ValidateField(Uint32 idx) const } #endif // _DEBUG +// ------------------------------------------------------------------------------------------------ +Uint32 ResHnd::GetFieldIndex(CSStr name) +{ + // Validate the handle + if (!mPtr) + { + STHROWF("Invalid MySQL result-set"); + } + // Attempt to find the specified field + const IndexMap::iterator itr = mIndexes.find(name); + // Was there a field with the specified name? + if (itr != mIndexes.end()) + { + return itr->second; + } + // No such field exists (expecting the invoker to validate the result) + return std::numeric_limits< Uint32 >::max(); +} + // ------------------------------------------------------------------------------------------------ void ResHnd::Create(const ConnRef & conn) { diff --git a/modules/mysql/Handle/ResultSet.hpp b/modules/mysql/Handle/ResultSet.hpp index ecb73e87..b593519e 100644 --- a/modules/mysql/Handle/ResultSet.hpp +++ b/modules/mysql/Handle/ResultSet.hpp @@ -192,6 +192,19 @@ public: void ValidateField(Uint32 idx) const; #endif // _DEBUG + /* -------------------------------------------------------------------------------------------- + * Check whether a specific field index is within range. + */ + bool CheckFieldIndex(Uint32 idx) const + { + return (idx < mFieldCount); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the field index associated with the specified name. + */ + Uint32 GetFieldIndex(CSStr name); + /* -------------------------------------------------------------------------------------------- * Create the result-set from a Connection. */ diff --git a/modules/mysql/Module.cpp b/modules/mysql/Module.cpp index b4706a52..201cc71a 100644 --- a/modules/mysql/Module.cpp +++ b/modules/mysql/Module.cpp @@ -11,6 +11,7 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ extern void Register_Account(Table & sqlns); extern void Register_Connection(Table & sqlns); +extern void Register_Field(Table & sqlns); extern void Register_ResultSet(Table & sqlns); extern void Register_Statement(Table & sqlns); @@ -31,6 +32,7 @@ static bool RegisterAPI(HSQUIRRELVM vm) Register_Account(sqlns); Register_Connection(sqlns); + Register_Field(sqlns); Register_ResultSet(sqlns); Register_Statement(sqlns); diff --git a/modules/mysql/ResultSet.cpp b/modules/mysql/ResultSet.cpp index 676dd8a8..797a35aa 100644 --- a/modules/mysql/ResultSet.cpp +++ b/modules/mysql/ResultSet.cpp @@ -106,157 +106,6 @@ void ResultSet::ValidateField(Int32 idx) const } #endif // _DEBUG -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetInt8(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Int8 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Int8 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetUint8(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Uint8 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Uint8 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetInt16(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Int16 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Int16 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetUint16(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Uint16 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Uint16 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetInt32(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Int32 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Int32 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ResultSet::GetUint32(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Uint32 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Uint32 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -Int64 ResultSet::GetInt64(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Int64 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Int64 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -Uint64 ResultSet::GetUint64(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Uint64 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return DbConvTo< Uint64 >::From(m_Handle->mRow[idx], m_Handle->mLengths[idx], m_Handle->mFields[idx].type); -} - -// ------------------------------------------------------------------------------------------------ -SQFloat ResultSet::GetFloat32(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Float32 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return std::strtof(m_Handle->mRow[idx], nullptr); -} - -// ------------------------------------------------------------------------------------------------ -SQFloat ResultSet::GetFloat64(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< Float64 >::From(m_Handle->mBinds[idx].mInt64); - } - // Retrieve the value directly from the row - return std::strtod(m_Handle->mRow[idx], nullptr); -} - -// ------------------------------------------------------------------------------------------------ -bool ResultSet::GetBoolean(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Should we retrieve the value from the bind wrapper? - if (m_Handle->mStatement) - { - return ConvTo< bool >::From(m_Handle->mBinds[idx].mUint64); - } - // Retrieve the value directly from the row - return ConvTo< bool >::From(std::strtol(m_Handle->mRow[idx], nullptr, 10)); -} - -// ------------------------------------------------------------------------------------------------ -CSStr ResultSet::GetString(Uint32 idx) const -{ - SQMOD_VALIDATE_FIELD(*this, idx); - // Retrieve the value directly from the row - return m_Handle->mRow[idx]; -} - // ================================================================================================ void Register_ResultSet(Table & sqlns) { @@ -275,8 +124,16 @@ void Register_ResultSet(Table & sqlns) .Prop(_SC("RowCount"), &ResultSet::RowCount) // Member Methods .Func(_SC("Next"), &ResultSet::Next) + .Func(_SC("Step"), &ResultSet::Next) .Func(_SC("SetRowIndex"), &ResultSet::SetRowIndex) .Func(_SC("SetLongRowIndex"), &ResultSet::SetLongRowIndex) + .Func(_SC("Get"), &ResultSet::GetField) + .Func(_SC("GetField"), &ResultSet::GetField) + .Func(_SC("GetBool"), &ResultSet::GetBoolean) + .Func(_SC("GetBoolean"), &ResultSet::GetBoolean) + .Func(_SC("GetChar"), &ResultSet::GetChar) + .Func(_SC("GetInteger"), &ResultSet::GetInteger) + .Func(_SC("GetFloat"), &ResultSet::GetFloat) .Func(_SC("GetInt8"), &ResultSet::GetInt8) .Func(_SC("GetUint8"), &ResultSet::GetUint8) .Func(_SC("GetInt16"), &ResultSet::GetInt16) @@ -287,9 +144,9 @@ void Register_ResultSet(Table & sqlns) .Func(_SC("GetUint64"), &ResultSet::GetUint64) .Func(_SC("GetFloat32"), &ResultSet::GetFloat32) .Func(_SC("GetFloat64"), &ResultSet::GetFloat64) - .Func(_SC("GetBool"), &ResultSet::GetBoolean) - .Func(_SC("GetBoolean"), &ResultSet::GetBoolean) .Func(_SC("GetString"), &ResultSet::GetString) + .Func(_SC("GetBuffer"), &ResultSet::GetBuffer) + .Func(_SC("GetBlob"), &ResultSet::GetBlob) ); } diff --git a/modules/mysql/ResultSet.hpp b/modules/mysql/ResultSet.hpp index c54edd7c..be6c7b64 100644 --- a/modules/mysql/ResultSet.hpp +++ b/modules/mysql/ResultSet.hpp @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------------------------------ #include "Handle/ResultSet.hpp" +#include "Field.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -214,64 +215,148 @@ public: } /* -------------------------------------------------------------------------------------------- - * Retrieve a signed 8 bit integer from a field. + * Retrieve the field with the specified name or index. */ - SQInteger GetInt8(Uint32 idx) const; + Field GetField(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field); + } /* -------------------------------------------------------------------------------------------- - * Retrieve an unsigned 8 bit integer from a field. + * Retrieve the value inside the specified field as a boolean value. */ - SQInteger GetUint8(Uint32 idx) const; + bool GetBoolean(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetBoolean(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a signed 16 bit integer from a field. + * Retrieve the value inside the specified field as a character. */ - SQInteger GetInt16(Uint32 idx) const; + SQChar GetChar(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetChar(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve an unsigned 16 bit integer from a field. + * Retrieve the value inside the specified field as a native script integer. */ - SQInteger GetUint16(Uint32 idx) const; + SQInteger GetInteger(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetInteger(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a signed 32 bit integer from a field. + * Retrieve the value inside the specified field as a native script floating point. */ - SQInteger GetInt32(Uint32 idx) const; + SQFloat GetFloat(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetFloat(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve an unsigned 32 bit integer from a field. + * Retrieve the value inside the specified field as a signed 8 bit integer value. */ - SQInteger GetUint32(Uint32 idx) const; + SQInteger GetInt8(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetInt8(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a signed 64 bit integer from a field. + * Retrieve the value inside the specified field as an unsigned 8 bit integer value. */ - Int64 GetInt64(Uint32 idx) const; + SQInteger GetUint8(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetUint8(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve an unsigned 64 bit integer from a field. + * Retrieve the value inside the specified field as a signed 16 bit integer value. */ - Uint64 GetUint64(Uint32 idx) const; + SQInteger GetInt16(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetInt16(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a 32 bit floating point from a field. + * Retrieve the value inside the specified field as an unsigned 16 bit integer value. */ - SQFloat GetFloat32(Uint32 idx) const; + SQInteger GetUint16(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetUint16(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a 64 bit floating point from a field. + * Retrieve the value inside the specified field as a signed 32 bit integer value. */ - SQFloat GetFloat64(Uint32 idx) const; + SQInteger GetInt32(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetInt32(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a boolean from a field. + * Retrieve the value inside the specified field as an unsigned 32 bit integer value. */ - bool GetBoolean(Uint32 idx) const; + SQInteger GetUint32(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetUint32(); + } /* -------------------------------------------------------------------------------------------- - * Retrieve a string from a field. + * Retrieve the value inside the specified field as a signed 64 bit integer value. */ - CSStr GetString(Uint32 idx) const; + Object GetInt64(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetInt64(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as an unsigned 64 bit integer value. + */ + Object GetUint64(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetUint64(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as a 32 bit floating point value. + */ + SQFloat GetFloat32(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetFloat32(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as a 64 bit floating point value. + */ + SQFloat GetFloat64(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetFloat64(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as a string value. + */ + Object GetString(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetString(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as a memory buffer. + */ + Object GetBuffer(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetBuffer(); + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the value inside the specified field as a memory blob. + */ + Object GetBlob(const Object & field) const + { + return Field(SQMOD_GET_CREATED(*this), field).GetBlob(); + } }; } // Namespace:: SqMod