1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Implement SessionPool.

This commit is contained in:
Sandu Liviu Catalin 2021-03-04 22:41:18 +02:00
parent c4c88fd97c
commit f7ec3594eb
2 changed files with 308 additions and 0 deletions

View File

@ -27,6 +27,7 @@ SQMOD_DECL_TYPENAME(SqBoolBinding, _SC("SqBoolBinding"))
SQMOD_DECL_TYPENAME(SqPcDataSession, _SC("SqDataSession")) SQMOD_DECL_TYPENAME(SqPcDataSession, _SC("SqDataSession"))
SQMOD_DECL_TYPENAME(SqPcDataStatement, _SC("SqDataStatement")) SQMOD_DECL_TYPENAME(SqPcDataStatement, _SC("SqDataStatement"))
SQMOD_DECL_TYPENAME(SqPcDataRecordSet, _SC("SqDataRecordSet")) SQMOD_DECL_TYPENAME(SqPcDataRecordSet, _SC("SqDataRecordSet"))
SQMOD_DECL_TYPENAME(SqPcDataSessionPool, _SC("SqDataSessionPool"))
SQMOD_DECL_TYPENAME(SqPcDataStatementResult, _SC("SqDataStatementResult")) SQMOD_DECL_TYPENAME(SqPcDataStatementResult, _SC("SqDataStatementResult"))
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -393,6 +394,45 @@ SqDataStatement & SqDataStatement::Into_(LightObj & obj, LightObj & def)
return *this; return *this;
} }
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::GetProperty(StackStrF & name)
{
HSQUIRRELVM vm = name.mVM;
// Preserve stack
const StackGuard sg(vm);
// Retrieve the property value
Poco::Any a = getProperty(name.ToStr());
// Retrieve the value type
const auto & ti = a.type();
// Identify the stored value
if (a.empty() || ti == typeid(void) || ti == typeid(nullptr)) sq_pushnull(vm);
else if (ti == typeid(bool)) sq_pushbool(vm, Poco::AnyCast< bool >(a));
else if (ti == typeid(char)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< char >(a)));
else if (ti == typeid(wchar_t)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< wchar_t >(a)));
else if (ti == typeid(signed char)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< signed char >(a)));
else if (ti == typeid(unsigned char)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< unsigned char >(a)));
else if (ti == typeid(short int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< short int >(a)));
else if (ti == typeid(unsigned short int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< unsigned short int >(a)));
else if (ti == typeid(int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< int >(a)));
else if (ti == typeid(unsigned int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< unsigned int >(a)));
else if (ti == typeid(long int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< long int >(a)));
else if (ti == typeid(unsigned long int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< unsigned long int >(a)));
else if (ti == typeid(long long int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< long long int >(a)));
else if (ti == typeid(unsigned long long int)) sq_pushinteger(vm, ConvTo< SQInteger >::From(Poco::AnyCast< unsigned long long int >(a)));
else if (ti == typeid(float)) sq_pushfloat(vm, ConvTo< SQFloat >::From(Poco::AnyCast< float >(a)));
else if (ti == typeid(double)) sq_pushfloat(vm, ConvTo< SQFloat >::From(Poco::AnyCast< double >(a)));
else if (ti == typeid(long double)) sq_pushfloat(vm, ConvTo< SQFloat >::From(Poco::AnyCast< long double >(a)));
else if (ti == typeid(std::string)) {
const auto & s = Poco::RefAnyCast< std::string >(a);
sq_pushstring(vm, s.data(), ConvTo< SQFloat >::From(s.size()));
} else {
sq_throwerrorf(vm, "Unable to convert value of type (%s) to squirrel.", a.type().name());
sq_pushnull(vm);
}
// Return the object from the stack
return Var< LightObj >(vm, -1).value;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template < class T, class U > template < class T, class U >
static void Register_POCO_Data_Binding(HSQUIRRELVM vm, Table & ns, const SQChar * name) static void Register_POCO_Data_Binding(HSQUIRRELVM vm, Table & ns, const SQChar * name)
@ -613,6 +653,35 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.Overload(_SC("Value"), &SqDataRecordSet::GetValueOr) .Overload(_SC("Value"), &SqDataRecordSet::GetValueOr)
); );
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
ns.Bind(_SC("SessionPool"),
Class< SqDataSessionPool, NoCopy< SqDataSessionPool > >(vm, SqPcDataSessionPool::Str)
// Constructors
.Ctor< StackStrF &, StackStrF & >()
.Ctor< StackStrF &, int, int, int, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqPcDataSessionPool::Fn)
// Properties
.Prop(_SC("Capacity"), &SqDataSessionPool::GetCapacity)
.Prop(_SC("Used"), &SqDataSessionPool::GetUsed)
.Prop(_SC("Idle"), &SqDataSessionPool::GetIdle)
.Prop(_SC("Dead"), &SqDataSessionPool::GetDead)
.Prop(_SC("Allocated"), &SqDataSessionPool::GetAllocated)
.Prop(_SC("Available"), &SqDataSessionPool::GetAvailable)
.Prop(_SC("Name"), &SqDataSessionPool::GetName)
.Prop(_SC("IsActive"), &SqDataSessionPool::IsActive)
// Member Methods
.Func(_SC("Get"), &SqDataSessionPool::Get)
.FmtFunc(_SC("GetWithProperty"), &SqDataSessionPool::GetWithProperty)
.FmtFunc(_SC("GetWithFeature"), &SqDataSessionPool::GetWithFeature)
.FmtFunc(_SC("SetFeature"), &SqDataSessionPool::SetFeature)
.FmtFunc(_SC("GetFeature"), &SqDataSessionPool::GetFeature)
.FmtFunc(_SC("SetProperty"), &SqDataSessionPool::SetProperty)
.FmtFunc(_SC("GetProperty"), &SqDataSessionPool::GetProperty)
.Func(_SC("Shutdown"), &SqDataSessionPool::Shutdown)
// Static Functions
.StaticFunc(_SC("GetName"), &SqDataSessionPool::GetName_)
);
// --------------------------------------------------------------------------------------------
ns.Func(_SC("Process"), ProcessPocoData); ns.Func(_SC("Process"), ProcessPocoData);
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
Register_POCO_Data_Binding< SQInteger, SqIntegerBinding >(vm, ns, _SC("IntBind")); Register_POCO_Data_Binding< SQInteger, SqIntegerBinding >(vm, ns, _SC("IntBind"));

View File

@ -8,6 +8,7 @@
#include <Poco/Data/Session.h> #include <Poco/Data/Session.h>
#include <Poco/Data/Statement.h> #include <Poco/Data/Statement.h>
#include <Poco/Data/RecordSet.h> #include <Poco/Data/RecordSet.h>
#include <Poco/Data/SessionPool.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace std { // NOLINT(cert-dcl58-cpp) namespace std { // NOLINT(cert-dcl58-cpp)
@ -471,6 +472,7 @@ using namespace Poco::Data::Keywords;
using Poco::Data::Session; using Poco::Data::Session;
using Poco::Data::Statement; using Poco::Data::Statement;
using Poco::Data::RecordSet; using Poco::Data::RecordSet;
using Poco::Data::SessionPool;
using Poco::Data::ReferenceBinding; using Poco::Data::ReferenceBinding;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -652,6 +654,22 @@ struct SqDataSession : public Session
*/ */
SqDataSession(SqDataSession &&) noexcept = default; SqDataSession(SqDataSession &&) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Creates a session by copying another one.
*/
SqDataSession(const Session & s)
: Session(s)
{
}
/* --------------------------------------------------------------------------------------------
* Creates a session by moving another one.
*/
SqDataSession(Session && s) noexcept
: Session(std::move(s))
{
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Destroys the Session. * Destroys the Session.
*/ */
@ -1677,4 +1695,225 @@ protected:
} }
}; };
/* ------------------------------------------------------------------------------------------------
* SessionPool implements session pooling for POCO Data.
*/
struct SqDataSessionPool : public SessionPool
{
/* --------------------------------------------------------------------------------------------
* Creates the SessionPool for sessions with the given connector and connection string.
*/
SqDataSessionPool(StackStrF & connector, StackStrF & connection)
: SessionPool(connector.ToStr(), connection.ToStr())
{
}
/* --------------------------------------------------------------------------------------------
* Creates the SessionPool for sessions with the given connector and connection string.
*/
SqDataSessionPool(StackStrF & connector, int min_ses, int max_ses, int idle_time, StackStrF & connection)
: SessionPool(connector.ToStr(), connection.ToStr(), min_ses, max_ses, idle_time)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
SqDataSessionPool(const SqDataSessionPool &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled).
*/
SqDataSessionPool(SqDataSessionPool &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Destroys the SessionPool.
*/
~SqDataSessionPool() = default;
/* --------------------------------------------------------------------------------------------
* Assignment operator (disabled).
*/
SqDataSessionPool & operator = (const SqDataSessionPool &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment (disabled).
*/
SqDataSessionPool & operator = (SqDataSessionPool &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Retrieve a Session.
*/
LightObj Get()
{
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get());
}
/* --------------------------------------------------------------------------------------------
* Retrieve a Session with requested property set.
*/
LightObj GetWithProperty(const LightObj & value, StackStrF & name)
{
switch (value.GetType())
{
case OT_NULL: {
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), nullptr));
} break;
case OT_INTEGER: {
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), value.Cast< SQInteger >()));
} break;
case OT_FLOAT: {
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), value.Cast< SQFloat >()));
} break;
case OT_BOOL: {
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), value.Cast< bool >()));
} break;
case OT_STRING: {
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), value.Cast< std::string >()));
} break;
default: STHROWF("Unsupported property value type");
}
// Should never get here
SQ_UNREACHABLE
}
/* --------------------------------------------------------------------------------------------
* Retrieve a Session with requested feature set.
*/
LightObj GetWithFeature(bool value, StackStrF & name)
{
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get(name.ToStr(), value));
}
/* --------------------------------------------------------------------------------------------
* Returns the maximum number of sessions the SessionPool will manage.
*/
SQInteger GetCapacity() const
{
return capacity();
}
/* --------------------------------------------------------------------------------------------
* Returns the number of sessions currently in use.
*/
SQInteger GetUsed() const
{
return used();
}
/* --------------------------------------------------------------------------------------------
* Returns the number of idle sessions.
*/
SQInteger GetIdle() const
{
return idle();
}
/* --------------------------------------------------------------------------------------------
* Returns the number of not connected active sessions.
*/
SQInteger GetDead()
{
return dead();
}
/* --------------------------------------------------------------------------------------------
* Returns the number of allocated sessions.
*/
SQInteger GetAllocated() const
{
return allocated();
}
/* --------------------------------------------------------------------------------------------
* Returns the number of available (idle + remaining capacity) sessions.
*/
SQInteger GetAvailable() const
{
return available();
}
/* --------------------------------------------------------------------------------------------
* Returns the name for this pool.
*/
String GetName() const
{
return name();
}
/* --------------------------------------------------------------------------------------------
* Returns the name formatted from supplied arguments as "connector:///connection".
*/
static String GetName_(StackStrF & connector, StackStrF & connection)
{
return name(connector.ToStr(), connection.ToStr());
}
/* --------------------------------------------------------------------------------------------
* Sets feature for all the sessions.
*/
SqDataSessionPool & SetFeature(StackStrF & name, bool state)
{
setFeature(name.ToStr(), state);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Returns the requested feature.
*/
bool GetFeature(StackStrF & name)
{
return getFeature(name.ToStr());
}
/* --------------------------------------------------------------------------------------------
* Sets property for all sessions.
*/
SqDataSessionPool & SetProperty(const LightObj & value, StackStrF & name)
{
switch (value.GetType())
{
case OT_NULL: {
setProperty(name.ToStr(), Poco::Any(nullptr));
} break;
case OT_INTEGER: {
setProperty(name.ToStr(), Poco::Any(value.Cast< SQInteger >()));
} break;
case OT_FLOAT: {
setProperty(name.ToStr(), Poco::Any(value.Cast< SQFloat >()));
} break;
case OT_BOOL: {
setProperty(name.ToStr(), Poco::Any(value.Cast<bool>()));
} break;
case OT_STRING: {
setProperty(name.ToStr(), Poco::Any(value.Cast<std::string>()));
} break;
default: STHROWF("Unsupported property value type");
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Returns the requested property.
*/
LightObj GetProperty(StackStrF & name);
/* --------------------------------------------------------------------------------------------
* Shuts down the session pool.
*/
void Shutdown()
{
shutdown();
}
/* --------------------------------------------------------------------------------------------
* Returns true if session pool is active (not shut down).
*/
bool IsActive() const
{
return isActive();
}
};
} // Namespace:: SqMod } // Namespace:: SqMod