From 15532298dce8514c3401e11b52f38d57d625f095 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 10 Apr 2020 10:12:05 +0300 Subject: [PATCH] Implement field selection in the MySQL library. --- module/Library/MySQL.cpp | 52 +++++++++++++++++++++++++++++++++++++++ module/Library/MySQL.hpp | 10 ++++++++ module/Misc/Areas.cpp | 4 +-- sqrat/sqrat/sqratObject.h | 11 ++++++--- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/module/Library/MySQL.cpp b/module/Library/MySQL.cpp index 34724951..581f62b2 100644 --- a/module/Library/MySQL.cpp +++ b/module/Library/MySQL.cpp @@ -2652,6 +2652,30 @@ Array ResultSet::GetFieldsArray() const return arr; } +// ------------------------------------------------------------------------------------------------ +Array ResultSet::FetchFieldsArray(Array & fields) const +{ + SQMOD_VALIDATE_CREATED(*this); + // Is there even something to process? + if (!m_Handle->mFieldCount || fields.Length() == 0) + { + return Array(DefaultVM::Get(), 0); + } + // Create a field instance to insert as copy + Field field(m_Handle); + // Allocate an array with the same amount of elements as the number of fields + Array arr(DefaultVM::Get(), fields.Length()); + // Iterate the specified fields array + fields.Foreach([&field, &arr](HSQUIRRELVM vm, SQInteger i) -> SQRESULT { + // Update the field index + field.SetIndex(Object(-1, vm)); + // Insert a copy of the field instance into the array + arr.SetValue(i, field); + }); + // Return the resulted array + return arr; +} + // ------------------------------------------------------------------------------------------------ Table ResultSet::GetFieldsTable() const { @@ -2681,6 +2705,32 @@ Table ResultSet::GetFieldsTable() const return tbl; } +// ------------------------------------------------------------------------------------------------ +Table ResultSet::FetchFieldsTable(Array & fields) const +{ + SQMOD_VALIDATE_CREATED(*this); + // Is there even something to process? + if (!m_Handle->mFieldCount || fields.Length() == 0) + { + return Table(); + } + // Create a field instance to insert as copy + Field field(m_Handle); + // Allocate a table to be populated with field instances + Table tbl(DefaultVM::Get(), fields.Length()); + // Grab the array with field instances + const ResHnd::FieldType * pfields = m_Handle->mFields; + // Iterate the specified fields array + fields.Foreach([&field, &tbl, pfields](HSQUIRRELVM vm, SQInteger i) -> SQRESULT { + // Update the field index + field.SetIndex(Object(-1, vm)); + // Insert a copy of the field instance into the table + tbl.SetValue((pfields[field.GetIndex()].name == nullptr) ? ToStrF("", field.GetIndex()) : pfields[field.GetIndex()].name, field); + }); + // Return the resulted array + return tbl; +} + // ------------------------------------------------------------------------------------------------ SQInteger Statement::Typename(HSQUIRRELVM vm) { @@ -3254,6 +3304,8 @@ void Register_MySQL(HSQUIRRELVM vm) .Func(_SC("GetString"), &ResultSet::GetString) .Func(_SC("GetBuffer"), &ResultSet::GetBuffer) .Func(_SC("GetBlob"), &ResultSet::GetBlob) + .Func(_SC("GetFieldsArray"), &ResultSet::FetchFieldsArray) + .Func(_SC("GetFieldsTable"), &ResultSet::FetchFieldsTable) ); sqlns.Bind(_SC("Statement") diff --git a/module/Library/MySQL.hpp b/module/Library/MySQL.hpp index 6919ab09..f6fb09d4 100644 --- a/module/Library/MySQL.hpp +++ b/module/Library/MySQL.hpp @@ -2082,11 +2082,21 @@ public: */ Array GetFieldsArray() const; + /* -------------------------------------------------------------------------------------------- + * Returns an array with wrapper instances for the specified fields in the managed result set. + */ + Array FetchFieldsArray(Array & fields) const; + /* -------------------------------------------------------------------------------------------- * Returns a table with wrapper instances for all the field available in the managed result set. */ Table GetFieldsTable() const; + /* -------------------------------------------------------------------------------------------- + * Returns a table with wrapper instances for all the specified fields in the managed result set. + */ + Table FetchFieldsTable(Array & fields) const; + /* -------------------------------------------------------------------------------------------- * Returns the current position of the row cursor for the last Next(). */ diff --git a/module/Misc/Areas.cpp b/module/Misc/Areas.cpp index e04def0d..f47a7702 100644 --- a/module/Misc/Areas.cpp +++ b/module/Misc/Areas.cpp @@ -20,7 +20,7 @@ void Area::AddArray(const Sqrat::Array & a) { float values[2]; - a.Foreach([this, &values, n = int(0)](HSQUIRRELVM vm) mutable -> bool { + a.Foreach([this, &values, n = int(0)](HSQUIRRELVM vm, SQInteger i) mutable -> SQRESULT { // Retrieve the type of the value const SQObjectType type = sq_gettype(vm, -1); // Are we dealing with a vector? @@ -44,7 +44,7 @@ void Area::AddArray(const Sqrat::Array & a) } } // Ignore anything else - return true; + return SQ_OK; }); } #pragma clang diagnostic pop diff --git a/sqrat/sqrat/sqratObject.h b/sqrat/sqrat/sqratObject.h index dcad1a23..1d190bc4 100644 --- a/sqrat/sqrat/sqratObject.h +++ b/sqrat/sqrat/sqratObject.h @@ -540,19 +540,22 @@ public: /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template - void Foreach(F&& func) const + SQRESULT Foreach(F&& func) const { const StackGuard sg(vm); sq_pushobject(vm,obj); sq_pushnull(vm); - while(SQ_SUCCEEDED(sq_next(vm,-2))) + SQRESULT res = SQ_OK; + for(SQInteger i = 0; SQ_SUCCEEDED(sq_next(vm,-2)); ++i) { - if (!func(vm)) + res = func(vm, i); + if (SQ_FAILED(res)) { - return; + break; } sq_pop(vm,2); } + return res; } protected: