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

Async callback.

This commit is contained in:
Sandu Liviu Catalin 2021-02-08 12:11:47 +02:00
parent d853e86d18
commit 2bbbfd69e6
3 changed files with 144 additions and 2 deletions

View File

@ -48,6 +48,7 @@ extern void TerminatePrivileges();
extern void TerminateRoutines();
extern void TerminateCommands();
extern void TerminateSignals();
extern void TerminatePocoData();
// ------------------------------------------------------------------------------------------------
extern Buffer GetRealFilePath(const SQChar * path);
@ -504,6 +505,8 @@ void Core::Terminate(bool shutdown)
TerminatePrivileges();
// Release announcers
AnnounceTerminate();
// Release Poco statement results
TerminatePocoData();
// Release ZMQ sockets
ZmqTerminate();
// In case there's a payload for reload

View File

@ -27,6 +27,7 @@ SQMOD_DECL_TYPENAME(SqBoolBinding, _SC("SqBoolBinding"))
SQMOD_DECL_TYPENAME(SqPcDataSession, _SC("SqDataSession"))
SQMOD_DECL_TYPENAME(SqPcDataStatement, _SC("SqDataStatement"))
SQMOD_DECL_TYPENAME(SqPcDataRecordSet, _SC("SqDataRecordSet"))
SQMOD_DECL_TYPENAME(SqPcDataStatementResult, _SC("SqDataStatementResult"))
// ------------------------------------------------------------------------------------------------
static const Poco::Data::NullData g_NullData{Poco::NULL_GENERIC};
@ -425,6 +426,39 @@ static void Register_POCO_Data_Binding(HSQUIRRELVM vm, Table & ns, const SQChar
);
}
// ------------------------------------------------------------------------------------------------
static void ProcessPocoData(SQInteger ms)
{
// Go over all statement results and try to update them
for (SqDataStatementResult * inst = SqDataStatementResult::sHead; inst && inst->mNext != SqDataStatementResult::sHead; inst = inst->mNext)
{
if (inst->mRes.tryWait(static_cast< long >(ms)))
{
// Forward the callback with the result
inst->mFunc(inst->mStmt, inst->mRes.data());
// Stop processing this result
inst->UnchainInstance();
// Release script resources
inst->mFunc.Release();
inst->mStmt.Release();
inst->mSelf.Release();
}
}
}
// ------------------------------------------------------------------------------------------------
void TerminatePocoData()
{
// Go over all statement results and try to update them
for (SqDataStatementResult * inst = SqDataStatementResult::sHead; inst && inst->mNext != SqDataStatementResult::sHead; inst = inst->mNext)
{
// Release associated resources
inst->mFunc.Release();
inst->mStmt.Release();
inst->mSelf.Release();
}
}
// ================================================================================================
void Register_POCO_Data(HSQUIRRELVM vm, Table &)
{
@ -475,6 +509,14 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.SetStaticValue(_SC("TransactionSerializable"), static_cast< SQInteger >(Session::TRANSACTION_SERIALIZABLE))
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("StatementResult"),
Class< SqDataStatementResult, NoConstructor< SqDataStatementResult > >(vm, SqPcDataStatementResult::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqPcDataStatementResult::Fn)
// Member Methods
.Func(_SC("Bind"), &SqDataStatementResult::Bind)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Statement"),
Class< SqDataStatement >(vm, SqPcDataStatement::Str)
// Constructors
@ -521,6 +563,8 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.Overload(_SC("Execute_"), &SqDataStatement::ExecuteChained_)
.Overload(_SC("ExecuteAsync"), &SqDataStatement::ExecuteAsync)
.Overload(_SC("ExecuteAsync"), &SqDataStatement::ExecuteAsync_)
.Overload(_SC("ExecuteAsync_"), &SqDataStatement::ExecuteAsyncChained)
.Overload(_SC("ExecuteAsync_"), &SqDataStatement::ExecuteAsyncChained_)
.Overload(_SC("Into"), &SqDataStatement::Into)
.Overload(_SC("Into"), &SqDataStatement::Into_)
.Overload(_SC("Limit"), &SqDataStatement::Limit1)
@ -572,6 +616,8 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.Overload(_SC("Value"), &SqDataRecordSet::GetValueOr)
);
// --------------------------------------------------------------------------------------------
ns.Func(_SC("Process"), ProcessPocoData);
// --------------------------------------------------------------------------------------------
Register_POCO_Data_Binding< SQInteger, SqIntegerBinding >(vm, ns, _SC("IntBind"));
Register_POCO_Data_Binding< String, SqStringBinding >(vm, ns, _SC("StrBind"));
Register_POCO_Data_Binding< SQFloat, SqFloatBinding >(vm, ns, _SC("FloatBind"));

View File

@ -806,6 +806,83 @@ struct SqDataSession : public Session
SqDataSession & ExecuteAsync(StackStrF & query);
};
/* ------------------------------------------------------------------------------------------------
* Statement is used to execute SQL statements.
*/
struct SqDataStatementResult : public SqChainedInstances< SqDataStatementResult >
{
/* --------------------------------------------------------------------------------------------
* Watched result.
*/
Statement::Result mRes;
/* --------------------------------------------------------------------------------------------
* Script callback.
*/
Function mFunc;
/* --------------------------------------------------------------------------------------------
* Reference to the statement.
*/
LightObj mStmt;
/* --------------------------------------------------------------------------------------------
* Reference to self.
*/
LightObj mSelf;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
explicit SqDataStatementResult(const Statement::Result & r, LightObj && stmt)
: mRes(r), mFunc(), mStmt(std::move(stmt)), mSelf()
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SqDataStatementResult(const SqDataStatementResult &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SqDataStatementResult(SqDataStatementResult &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SqDataStatementResult()
{
// Forget about this instance
UnchainInstance();
}
/* --------------------------------------------------------------------------------------------
* Assignment operator.
*/
SqDataStatementResult & operator = (const SqDataStatementResult &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment.
*/
SqDataStatementResult & operator = (SqDataStatementResult &&) = delete;
/* --------------------------------------------------------------------------------------------
* Bind a callback and wait for completion.
*/
LightObj & Bind(Function & fn)
{
mFunc = std::move(fn);
// Reference self to prevent destruction
mSelf = LightObj(this);
// Remember this instance
ChainInstance();
// Return the statement
return mStmt;
}
};
/* ------------------------------------------------------------------------------------------------
* Statement is used to execute SQL statements.
*/
@ -1057,7 +1134,23 @@ struct SqDataStatement : public Statement
/* --------------------------------------------------------------------------------------------
* Executes the statement asynchronously.
*/
SqDataStatement & ExecuteAsync()
LightObj ExecuteAsync()
{
return LightObj(SqTypeIdentity< SqDataStatementResult >{}, SqVM(), executeAsync(true), LightObj(this));
}
/* --------------------------------------------------------------------------------------------
* Executes the statement asynchronously.
*/
LightObj ExecuteAsync_(bool reset)
{
return LightObj(SqTypeIdentity< SqDataStatementResult >{}, SqVM(), executeAsync(true), LightObj(this));
}
/* --------------------------------------------------------------------------------------------
* Executes the statement asynchronously.
*/
SqDataStatement & ExecuteAsyncChained()
{
executeAsync(true);
return *this;
@ -1066,7 +1159,7 @@ struct SqDataStatement : public Statement
/* --------------------------------------------------------------------------------------------
* Executes the statement asynchronously.
*/
SqDataStatement & ExecuteAsync_(bool reset)
SqDataStatement & ExecuteAsyncChained_(bool reset)
{
executeAsync(reset);
return *this;