mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:40:38 +01:00
Added IRoutineMetadata to external engines.
Not well tested: 1) EE is broken after shared page cache. 2) Semantics of addRef/release still keeps changing in developers minds.
This commit is contained in:
parent
9083c98e8b
commit
983686d71c
@ -30,6 +30,8 @@ using namespace Firebird;
|
|||||||
using namespace Firebird::Udr;
|
using namespace Firebird::Udr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef IMaster* (ISC_EXPORT *FuncGetMasterInterface)();
|
||||||
|
|
||||||
typedef ISC_LONG (ISC_EXPORT_VARARG *FuncEventBlock)(ISC_UCHAR**, ISC_UCHAR**, ISC_USHORT, ...);
|
typedef ISC_LONG (ISC_EXPORT_VARARG *FuncEventBlock)(ISC_UCHAR**, ISC_UCHAR**, ISC_USHORT, ...);
|
||||||
typedef ISC_STATUS (ISC_EXPORT *FuncWaitForEvent)(ISC_STATUS*, isc_db_handle*,
|
typedef ISC_STATUS (ISC_EXPORT *FuncWaitForEvent)(ISC_STATUS*, isc_db_handle*,
|
||||||
short, const ISC_UCHAR*, ISC_UCHAR*);
|
short, const ISC_UCHAR*, ISC_UCHAR*);
|
||||||
@ -50,6 +52,87 @@ typedef ISC_STATUS (ISC_EXPORT *FuncDsqlPrepare)(ISC_STATUS*, isc_tr_handle*, is
|
|||||||
unsigned short, const ISC_SCHAR*, unsigned short, XSQLDA*);
|
unsigned short, const ISC_SCHAR*, unsigned short, XSQLDA*);
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
class AutoDispose
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoDispose<T>(T* aPtr = NULL)
|
||||||
|
: ptr(aPtr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoDispose()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoDispose<T>& operator =(T* aPtr)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
ptr = aPtr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T*()
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const T*() const
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !() const
|
||||||
|
{
|
||||||
|
return !ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasData() const
|
||||||
|
{
|
||||||
|
return ptr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator ->()
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* release()
|
||||||
|
{
|
||||||
|
T* tmp = ptr;
|
||||||
|
ptr = NULL;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(T* aPtr = NULL)
|
||||||
|
{
|
||||||
|
if (aPtr != ptr)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
ptr = aPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
ptr->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not implemented
|
||||||
|
AutoDispose<T>(AutoDispose<T>&);
|
||||||
|
void operator =(AutoDispose<T>&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* ptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
create function wait_event (
|
create function wait_event (
|
||||||
event_name varchar(31) character set ascii
|
event_name varchar(31) character set ascii
|
||||||
@ -135,6 +218,7 @@ private:
|
|||||||
isc_stmt_handle stmtHandle;
|
isc_stmt_handle stmtHandle;
|
||||||
|
|
||||||
// ISC entry points
|
// ISC entry points
|
||||||
|
FuncGetMasterInterface funcGetMasterInterface;
|
||||||
FuncDsqlAllocateStatement funcDsqlAllocateStatement;
|
FuncDsqlAllocateStatement funcDsqlAllocateStatement;
|
||||||
FuncDsqlDescribe funcDsqlDescribe;
|
FuncDsqlDescribe funcDsqlDescribe;
|
||||||
FuncDsqlDescribeBind funcDsqlDescribeBind;
|
FuncDsqlDescribeBind funcDsqlDescribeBind;
|
||||||
@ -246,6 +330,7 @@ void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context, Values* val
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// ISC entry points
|
// ISC entry points
|
||||||
|
funcGetMasterInterface = (FuncGetMasterInterface) getEntryPoint(context, "fb_get_master_interface");
|
||||||
funcDsqlAllocateStatement = (FuncDsqlAllocateStatement)
|
funcDsqlAllocateStatement = (FuncDsqlAllocateStatement)
|
||||||
getEntryPoint(context, "isc_dsql_allocate_statement");
|
getEntryPoint(context, "isc_dsql_allocate_statement");
|
||||||
funcDsqlDescribe = (FuncDsqlDescribe) getEntryPoint(context, "isc_dsql_describe");
|
funcDsqlDescribe = (FuncDsqlDescribe) getEntryPoint(context, "isc_dsql_describe");
|
||||||
@ -265,14 +350,33 @@ void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context, Values* val
|
|||||||
"select data_source from replicate_config where name = ?",
|
"select data_source from replicate_config where name = ?",
|
||||||
SQL_DIALECT_CURRENT, NULL), statusVector);
|
SQL_DIALECT_CURRENT, NULL), statusVector);
|
||||||
|
|
||||||
|
AutoDispose<IMaster> master(funcGetMasterInterface());
|
||||||
|
AutoDispose<IStatus> status(master->getStatus());
|
||||||
|
|
||||||
|
const char* table = metadata->getTriggerTable(status);
|
||||||
|
ThrowError::check(status->get());
|
||||||
|
|
||||||
|
// Skip the first exclamation point, separing the module name and entry point.
|
||||||
|
const char* info = strchr(metadata->getEntryPoint(status), '!');
|
||||||
|
ThrowError::check(status->get());
|
||||||
|
|
||||||
|
// Skip the second exclamation point, separing the entry point and the misc info (config).
|
||||||
|
if (info)
|
||||||
|
info = strchr(info + 1, '!');
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
++info;
|
||||||
|
else
|
||||||
|
info = "";
|
||||||
|
|
||||||
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
||||||
inSqlDa->version = SQLDA_VERSION1;
|
inSqlDa->version = SQLDA_VERSION1;
|
||||||
inSqlDa->sqln = 1;
|
inSqlDa->sqln = 1;
|
||||||
ThrowError::check(funcDsqlDescribeBind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
|
ThrowError::check(funcDsqlDescribeBind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
|
||||||
statusVector);
|
statusVector);
|
||||||
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
|
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
|
||||||
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), metaInfo->info, inSqlDa->sqlvar[0].sqllen);
|
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), info, inSqlDa->sqlvar[0].sqllen);
|
||||||
*reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(metaInfo->info);
|
*reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(info);
|
||||||
|
|
||||||
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
||||||
outSqlDa->version = SQLDA_VERSION1;
|
outSqlDa->version = SQLDA_VERSION1;
|
||||||
@ -304,7 +408,7 @@ void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context, Values* val
|
|||||||
const char* name = val->getName(ThrowError());
|
const char* name = val->getName(ThrowError());
|
||||||
|
|
||||||
strcat(buffer, " p");
|
strcat(buffer, " p");
|
||||||
sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, metaInfo->table, name);
|
sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(buffer,
|
strcat(buffer,
|
||||||
@ -313,7 +417,7 @@ void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context, Values* val
|
|||||||
"begin\n"
|
"begin\n"
|
||||||
" execute statement ('insert into \"");
|
" execute statement ('insert into \"");
|
||||||
|
|
||||||
strcat(buffer, metaInfo->table);
|
strcat(buffer, table);
|
||||||
strcat(buffer, "\" (");
|
strcat(buffer, "\" (");
|
||||||
|
|
||||||
for (int i = 1; i <= count; ++i)
|
for (int i = 1; i <= count; ++i)
|
||||||
@ -449,7 +553,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
|
|||||||
{
|
{
|
||||||
case SQL_VARYING:
|
case SQL_VARYING:
|
||||||
{
|
{
|
||||||
uint len;
|
unsigned len;
|
||||||
const char* s = val->getString(ThrowError(), &len);
|
const char* s = val->getString(ThrowError(), &len);
|
||||||
*reinterpret_cast<unsigned short*>(var->sqldata) = len;
|
*reinterpret_cast<unsigned short*>(var->sqldata) = len;
|
||||||
memcpy(var->sqldata + sizeof(unsigned short), s, len);
|
memcpy(var->sqldata + sizeof(unsigned short), s, len);
|
||||||
|
@ -152,6 +152,19 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class IRoutineMetadata // : public IVersioned
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* FB_CARG getPackage(IStatus* status) const = 0;
|
||||||
|
virtual const char* FB_CARG getName(IStatus* status) const = 0;
|
||||||
|
virtual const char* FB_CARG getEntryPoint(IStatus* status) const = 0;
|
||||||
|
virtual const char* FB_CARG getBody(IStatus* status) const = 0;
|
||||||
|
virtual const char* FB_CARG getTriggerTable(IStatus* status) const = 0;
|
||||||
|
virtual ExternalTrigger::Type FB_CARG getTriggerType(IStatus* status) const = 0;
|
||||||
|
};
|
||||||
|
// #define FB_I_ROUTINE_METADATA_VERSION (FB_VERSIONED_VERSION + 6)
|
||||||
|
|
||||||
|
|
||||||
// In SuperServer, shared by all attachments to one database and disposed when last (non-external)
|
// In SuperServer, shared by all attachments to one database and disposed when last (non-external)
|
||||||
// user attachment to the database is closed.
|
// user attachment to the database is closed.
|
||||||
class ExternalEngine : public IPluginBase
|
class ExternalEngine : public IPluginBase
|
||||||
@ -175,12 +188,11 @@ public:
|
|||||||
// Called when engine wants to load object in the cache. Objects are disposed when
|
// Called when engine wants to load object in the cache. Objects are disposed when
|
||||||
// going out of the cache.
|
// going out of the cache.
|
||||||
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body) = 0;
|
const IRoutineMetadata* metadata) = 0;
|
||||||
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body) = 0;
|
const IRoutineMetadata* metadata) = 0;
|
||||||
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
||||||
const char* name, const char* entryPoint, const char* body,
|
const IRoutineMetadata* metadata) = 0;
|
||||||
const char* table, ExternalTrigger::Type type) = 0;
|
|
||||||
};
|
};
|
||||||
#define FB_EXTERNAL_ENGINE_VERSION (FB_PLUGIN_VERSION + 7)
|
#define FB_EXTERNAL_ENGINE_VERSION (FB_PLUGIN_VERSION + 7)
|
||||||
|
|
||||||
|
@ -34,24 +34,6 @@ namespace Firebird
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// Metadata information passed from the UDR engine to user's routines factories when asking to
|
|
||||||
// create routines instances.
|
|
||||||
struct MetaInfo
|
|
||||||
{
|
|
||||||
const char* package; // package name - NULL from triggers
|
|
||||||
const char* name; // metadata object name
|
|
||||||
const char* entryPoint; // external routine's name
|
|
||||||
const char* info; // misc. info encoded on the external name
|
|
||||||
const char* body; // body text
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TriggerMetaInfo : public MetaInfo
|
|
||||||
{
|
|
||||||
ExternalTrigger::Type type; // trigger type
|
|
||||||
const char* table; // table name
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Factory classes. They should be singletons instances created by user's modules and
|
// Factory classes. They should be singletons instances created by user's modules and
|
||||||
// registered. When UDR engine is going to load a routine, it calls newItem.
|
// registered. When UDR engine is going to load a routine, it calls newItem.
|
||||||
|
|
||||||
@ -59,21 +41,21 @@ class FunctionFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const char* FB_CALL getName() = 0;
|
virtual const char* FB_CALL getName() = 0;
|
||||||
virtual ExternalFunction* FB_CALL newItem(MetaInfo* metaInfo) = 0;
|
virtual ExternalFunction* FB_CALL newItem(const IRoutineMetadata* metadata) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProcedureFactory
|
class ProcedureFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const char* FB_CALL getName() = 0;
|
virtual const char* FB_CALL getName() = 0;
|
||||||
virtual ExternalProcedure* FB_CALL newItem(MetaInfo* metaInfo) = 0;
|
virtual ExternalProcedure* FB_CALL newItem(const IRoutineMetadata* metadata) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TriggerFactory
|
class TriggerFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const char* FB_CALL getName() = 0;
|
virtual const char* FB_CALL getName() = 0;
|
||||||
virtual ExternalTrigger* FB_CALL newItem(TriggerMetaInfo* metaInfo) = 0;
|
virtual ExternalTrigger* FB_CALL newItem(const IRoutineMetadata* metadata) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MetaInfo* metaInfo;
|
const IRoutineMetadata* metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MetaInfo* metaInfo;
|
const IRoutineMetadata* metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -547,7 +547,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TriggerMetaInfo* metaInfo;
|
const IRoutineMetadata* metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -566,10 +566,10 @@ public:
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ExternalFunction* FB_CALL newItem(MetaInfo* metaInfo)
|
virtual ExternalFunction* FB_CALL newItem(const IRoutineMetadata* metadata)
|
||||||
{
|
{
|
||||||
Function* function = new T();
|
Function* function = new T();
|
||||||
function->metaInfo = metaInfo;
|
function->metadata = metadata;
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,10 +593,10 @@ public:
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ExternalProcedure* FB_CALL newItem(MetaInfo* metaInfo)
|
virtual ExternalProcedure* FB_CALL newItem(const IRoutineMetadata* metadata)
|
||||||
{
|
{
|
||||||
Procedure* procedure = new T();
|
Procedure* procedure = new T();
|
||||||
procedure->metaInfo = metaInfo;
|
procedure->metadata = metadata;
|
||||||
return procedure;
|
return procedure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,10 +620,10 @@ public:
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ExternalTrigger* FB_CALL newItem(TriggerMetaInfo* metaInfo)
|
virtual ExternalTrigger* FB_CALL newItem(const IRoutineMetadata* metadata)
|
||||||
{
|
{
|
||||||
Trigger* trigger = new T();
|
Trigger* trigger = new T();
|
||||||
trigger->metaInfo = metaInfo;
|
trigger->metadata = metadata;
|
||||||
return trigger;
|
return trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,10 +286,11 @@ void* FB_CALL ExtEngineManager::ExternalContextImpl::setInfo(int code, void* val
|
|||||||
|
|
||||||
|
|
||||||
ExtEngineManager::Function::Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
ExtEngineManager::Function::Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
ExternalEngine* aEngine, ExternalFunction* aFunction,
|
ExternalEngine* aEngine, RoutineMetadata* aMetadata, ExternalFunction* aFunction,
|
||||||
const Jrd::Function* aUdf)
|
const Jrd::Function* aUdf)
|
||||||
: extManager(aExtManager),
|
: extManager(aExtManager),
|
||||||
engine(aEngine),
|
engine(aEngine),
|
||||||
|
metadata(aMetadata),
|
||||||
function(aFunction),
|
function(aFunction),
|
||||||
udf(aUdf),
|
udf(aUdf),
|
||||||
database(tdbb->getDatabase())
|
database(tdbb->getDatabase())
|
||||||
@ -384,10 +385,11 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, const NestValueArray&
|
|||||||
|
|
||||||
|
|
||||||
ExtEngineManager::Procedure::Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
ExtEngineManager::Procedure::Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
ExternalEngine* aEngine, ExternalProcedure* aProcedure,
|
ExternalEngine* aEngine, RoutineMetadata* aMetadata, ExternalProcedure* aProcedure,
|
||||||
const jrd_prc* aPrc)
|
const jrd_prc* aPrc)
|
||||||
: extManager(aExtManager),
|
: extManager(aExtManager),
|
||||||
engine(aEngine),
|
engine(aEngine),
|
||||||
|
metadata(aMetadata),
|
||||||
procedure(aProcedure),
|
procedure(aProcedure),
|
||||||
prc(aPrc),
|
prc(aPrc),
|
||||||
database(tdbb->getDatabase())
|
database(tdbb->getDatabase())
|
||||||
@ -467,10 +469,11 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
|
|||||||
|
|
||||||
|
|
||||||
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
ExternalEngine* aEngine, ExternalTrigger* aTrigger,
|
ExternalEngine* aEngine, RoutineMetadata* aMetadata, ExternalTrigger* aTrigger,
|
||||||
const Jrd::Trigger* aTrg)
|
const Jrd::Trigger* aTrg)
|
||||||
: extManager(aExtManager),
|
: extManager(aExtManager),
|
||||||
engine(aEngine),
|
engine(aEngine),
|
||||||
|
metadata(aMetadata),
|
||||||
trigger(aTrigger),
|
trigger(aTrigger),
|
||||||
trg(aTrg),
|
trg(aTrg),
|
||||||
database(tdbb->getDatabase())
|
database(tdbb->getDatabase())
|
||||||
@ -651,14 +654,19 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
|||||||
CallerName(obj_udf, udf->getName().identifier) :
|
CallerName(obj_udf, udf->getName().identifier) :
|
||||||
CallerName(obj_package_header, udf->getName().package)));
|
CallerName(obj_package_header, udf->getName().package)));
|
||||||
|
|
||||||
|
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||||
|
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
|
||||||
|
metadata->package = udf->getName().package;
|
||||||
|
metadata->name = udf->getName().identifier;
|
||||||
|
metadata->entryPoint = entryPointTrimmed;
|
||||||
|
metadata->body = body;
|
||||||
|
|
||||||
ExternalFunction* externalFunction;
|
ExternalFunction* externalFunction;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
Attachment::Checkout attCout(tdbb->getAttachment());
|
Attachment::Checkout attCout(tdbb->getAttachment());
|
||||||
|
|
||||||
externalFunction = attInfo->engine->makeFunction(RaiseError(),
|
externalFunction = attInfo->engine->makeFunction(RaiseError(), attInfo->context, metadata);
|
||||||
attInfo->context, udf->getName().package.nullStr(), udf->getName().identifier.c_str(),
|
|
||||||
entryPointTrimmed.nullStr(), body.nullStr());
|
|
||||||
|
|
||||||
if (!externalFunction)
|
if (!externalFunction)
|
||||||
{
|
{
|
||||||
@ -670,7 +678,8 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return FB_NEW(getPool()) Function(tdbb, this, attInfo->engine, externalFunction, udf);
|
return FB_NEW(getPool()) Function(tdbb, this, attInfo->engine, metadata.release(),
|
||||||
|
externalFunction, udf);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -693,14 +702,19 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
|||||||
CallerName(obj_procedure, prc->getName().identifier) :
|
CallerName(obj_procedure, prc->getName().identifier) :
|
||||||
CallerName(obj_package_header, prc->getName().package)));
|
CallerName(obj_package_header, prc->getName().package)));
|
||||||
|
|
||||||
|
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||||
|
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
|
||||||
|
metadata->package = prc->getName().package;
|
||||||
|
metadata->name = prc->getName().identifier;
|
||||||
|
metadata->entryPoint = entryPointTrimmed;
|
||||||
|
metadata->body = body;
|
||||||
|
|
||||||
ExternalProcedure* externalProcedure;
|
ExternalProcedure* externalProcedure;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
Attachment::Checkout attCout(tdbb->getAttachment());
|
Attachment::Checkout attCout(tdbb->getAttachment());
|
||||||
|
|
||||||
externalProcedure = attInfo->engine->makeProcedure(RaiseError(),
|
externalProcedure = attInfo->engine->makeProcedure(RaiseError(), attInfo->context, metadata);
|
||||||
attInfo->context, prc->getName().package.nullStr(), prc->getName().identifier.c_str(),
|
|
||||||
entryPointTrimmed.nullStr(), body.nullStr());
|
|
||||||
|
|
||||||
if (!externalProcedure)
|
if (!externalProcedure)
|
||||||
{
|
{
|
||||||
@ -712,7 +726,8 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, externalProcedure, prc);
|
return FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, metadata.release(),
|
||||||
|
externalProcedure, prc);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -729,22 +744,25 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
|
|||||||
string entryPointTrimmed = entryPoint;
|
string entryPointTrimmed = entryPoint;
|
||||||
entryPointTrimmed.trim();
|
entryPointTrimmed.trim();
|
||||||
|
|
||||||
MetaName relationNameTrimmed;
|
|
||||||
if (trg->relation)
|
|
||||||
relationNameTrimmed = trg->relation->rel_name;
|
|
||||||
|
|
||||||
EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine);
|
EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine);
|
||||||
ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, attInfo->adminCharSet,
|
ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, attInfo->adminCharSet,
|
||||||
CallerName(obj_trigger, trg->name));
|
CallerName(obj_trigger, trg->name));
|
||||||
|
|
||||||
|
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||||
|
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
|
||||||
|
metadata->name = trg->name;
|
||||||
|
metadata->entryPoint = entryPointTrimmed;
|
||||||
|
metadata->body = body;
|
||||||
|
metadata->triggerType = type;
|
||||||
|
if (trg->relation)
|
||||||
|
metadata->triggerTable = trg->relation->rel_name;
|
||||||
|
|
||||||
ExternalTrigger* externalTrigger;
|
ExternalTrigger* externalTrigger;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
Attachment::Checkout attCout(tdbb->getAttachment());
|
Attachment::Checkout attCout(tdbb->getAttachment());
|
||||||
|
|
||||||
externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context,
|
externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context, metadata);
|
||||||
trg->name.c_str(), entryPointTrimmed.nullStr(), body.nullStr(),
|
|
||||||
relationNameTrimmed.c_str(), type);
|
|
||||||
|
|
||||||
if (!externalTrigger)
|
if (!externalTrigger)
|
||||||
{
|
{
|
||||||
@ -755,7 +773,8 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return FB_NEW(getPool()) Trigger(tdbb, this, attInfo->engine, externalTrigger, trg);
|
return FB_NEW(getPool()) Trigger(tdbb, this, attInfo->engine, metadata.release(),
|
||||||
|
externalTrigger, trg);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -61,6 +61,59 @@ private:
|
|||||||
template <typename T> class ContextManager;
|
template <typename T> class ContextManager;
|
||||||
class TransactionImpl;
|
class TransactionImpl;
|
||||||
|
|
||||||
|
class RoutineMetadata : public Firebird::IRoutineMetadata, public Firebird::PermanentStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RoutineMetadata(MemoryPool& pool)
|
||||||
|
: PermanentStorage(pool),
|
||||||
|
package(pool),
|
||||||
|
name(pool),
|
||||||
|
entryPoint(pool),
|
||||||
|
body(pool),
|
||||||
|
triggerTable(pool),
|
||||||
|
triggerType(Firebird::ExternalTrigger::Type(0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* FB_CARG getPackage(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return package.nullStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* FB_CARG getName(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* FB_CARG getEntryPoint(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return entryPoint.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* FB_CARG getBody(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return body.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* FB_CARG getTriggerTable(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return triggerTable.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Firebird::ExternalTrigger::Type FB_CARG getTriggerType(Firebird::IStatus* /*status*/) const
|
||||||
|
{
|
||||||
|
return triggerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Firebird::MetaName package;
|
||||||
|
Firebird::MetaName name;
|
||||||
|
Firebird::string entryPoint;
|
||||||
|
Firebird::string body;
|
||||||
|
Firebird::MetaName triggerTable;
|
||||||
|
Firebird::ExternalTrigger::Type triggerType;
|
||||||
|
};
|
||||||
|
|
||||||
class ExternalContextImpl : public Firebird::ExternalContext
|
class ExternalContextImpl : public Firebird::ExternalContext
|
||||||
{
|
{
|
||||||
friend class AttachmentImpl;
|
friend class AttachmentImpl;
|
||||||
@ -130,6 +183,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
Firebird::ExternalEngine* aEngine,
|
Firebird::ExternalEngine* aEngine,
|
||||||
|
RoutineMetadata* aMetadata,
|
||||||
Firebird::ExternalFunction* aFunction,
|
Firebird::ExternalFunction* aFunction,
|
||||||
const Jrd::Function* aUdf);
|
const Jrd::Function* aUdf);
|
||||||
~Function();
|
~Function();
|
||||||
@ -140,6 +194,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ExtEngineManager* extManager;
|
ExtEngineManager* extManager;
|
||||||
Firebird::ExternalEngine* engine;
|
Firebird::ExternalEngine* engine;
|
||||||
|
Firebird::AutoPtr<RoutineMetadata> metadata;
|
||||||
Firebird::ExternalFunction* function;
|
Firebird::ExternalFunction* function;
|
||||||
const Jrd::Function* udf;
|
const Jrd::Function* udf;
|
||||||
Database* database;
|
Database* database;
|
||||||
@ -152,6 +207,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
Firebird::ExternalEngine* aEngine,
|
Firebird::ExternalEngine* aEngine,
|
||||||
|
RoutineMetadata* aMetadata,
|
||||||
Firebird::ExternalProcedure* aProcedure,
|
Firebird::ExternalProcedure* aProcedure,
|
||||||
const jrd_prc* aPrc);
|
const jrd_prc* aPrc);
|
||||||
~Procedure();
|
~Procedure();
|
||||||
@ -161,6 +217,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ExtEngineManager* extManager;
|
ExtEngineManager* extManager;
|
||||||
Firebird::ExternalEngine* engine;
|
Firebird::ExternalEngine* engine;
|
||||||
|
Firebird::AutoPtr<RoutineMetadata> metadata;
|
||||||
Firebird::ExternalProcedure* procedure;
|
Firebird::ExternalProcedure* procedure;
|
||||||
const jrd_prc* prc;
|
const jrd_prc* prc;
|
||||||
Database* database;
|
Database* database;
|
||||||
@ -191,6 +248,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||||
Firebird::ExternalEngine* aEngine,
|
Firebird::ExternalEngine* aEngine,
|
||||||
|
RoutineMetadata* aMetadata,
|
||||||
Firebird::ExternalTrigger* aTrigger,
|
Firebird::ExternalTrigger* aTrigger,
|
||||||
const Jrd::Trigger* aTrg);
|
const Jrd::Trigger* aTrg);
|
||||||
~Trigger();
|
~Trigger();
|
||||||
@ -205,6 +263,7 @@ public:
|
|||||||
|
|
||||||
ExtEngineManager* extManager;
|
ExtEngineManager* extManager;
|
||||||
Firebird::ExternalEngine* engine;
|
Firebird::ExternalEngine* engine;
|
||||||
|
Firebird::AutoPtr<RoutineMetadata> metadata;
|
||||||
Firebird::ExternalTrigger* trigger;
|
Firebird::ExternalTrigger* trigger;
|
||||||
const Jrd::Trigger* trg;
|
const Jrd::Trigger* trg;
|
||||||
Database* database;
|
Database* database;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "../common/os/mod_loader.h"
|
#include "../common/os/mod_loader.h"
|
||||||
#include "../common/os/path_utils.h"
|
#include "../common/os/path_utils.h"
|
||||||
#include "../common/classes/ImplementHelper.h"
|
#include "../common/classes/ImplementHelper.h"
|
||||||
|
#include "../common/StatusHolder.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Firebird
|
namespace Firebird
|
||||||
@ -130,7 +131,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadModule(const string& str, PathName* moduleName, string* entryPoint, string* info);
|
void loadModule(const IRoutineMetadata* metadata, PathName* moduleName, string* entryPoint);
|
||||||
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
|
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
|
||||||
GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children, SharedObjType* sharedObj,
|
GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children, SharedObjType* sharedObj,
|
||||||
ExternalContext* context, NodeType* nodes, SortedArray<SharedObjType*>& sharedObjs,
|
ExternalContext* context, NodeType* nodes, SortedArray<SharedObjType*>& sharedObjs,
|
||||||
@ -138,12 +139,12 @@ public:
|
|||||||
template <typename ObjType> void deleteChildren(
|
template <typename ObjType> void deleteChildren(
|
||||||
GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children);
|
GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children);
|
||||||
|
|
||||||
template <typename T, typename T2> T* findNode(T* nodes, const PathName& moduleName,
|
template <typename T> T* findNode(T* nodes, const PathName& moduleName,
|
||||||
T2* metaInfo);
|
const string& entryPoint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T, typename T2, typename T3> T2* getNode(T* nodes, const PathName& moduleName,
|
template <typename T, typename T2> T2* getNode(T* nodes, const PathName& moduleName,
|
||||||
T3* metaInfo);
|
const IRoutineMetadata* metadata, const string& entryPoint);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int FB_CALL getVersion(Error* error);
|
virtual int FB_CALL getVersion(Error* error);
|
||||||
@ -151,12 +152,11 @@ public:
|
|||||||
virtual void FB_CALL openAttachment(Error* error, ExternalContext* context);
|
virtual void FB_CALL openAttachment(Error* error, ExternalContext* context);
|
||||||
virtual void FB_CALL closeAttachment(Error* error, ExternalContext* context);
|
virtual void FB_CALL closeAttachment(Error* error, ExternalContext* context);
|
||||||
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body);
|
const IRoutineMetadata* metadata);
|
||||||
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body);
|
const IRoutineMetadata* metadata);
|
||||||
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
||||||
const char* name, const char* entryPoint, const char* body, const char* table,
|
const IRoutineMetadata* metadata);
|
||||||
ExternalTrigger::Type type);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void FB_CALL dispose(Error* error);
|
virtual void FB_CALL dispose(Error* error);
|
||||||
@ -205,25 +205,16 @@ static TriggerNode* registeredTriggers = NULL;
|
|||||||
class SharedFunction : public ExternalFunction
|
class SharedFunction : public ExternalFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SharedFunction(Engine* aEngine, const string& aPackage, const string& aName,
|
SharedFunction(Engine* aEngine, const IRoutineMetadata* aMetadata)
|
||||||
const string& aEntryPoint, const string& aBody)
|
|
||||||
: engine(aEngine),
|
: engine(aEngine),
|
||||||
package(*getDefaultMemoryPool(), aPackage),
|
metadata(aMetadata),
|
||||||
name(*getDefaultMemoryPool(), aName),
|
|
||||||
entryPoint(*getDefaultMemoryPool()),
|
|
||||||
body(*getDefaultMemoryPool(), aBody),
|
|
||||||
moduleName(*getDefaultMemoryPool()),
|
moduleName(*getDefaultMemoryPool()),
|
||||||
|
entryPoint(*getDefaultMemoryPool()),
|
||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(aEntryPoint, &moduleName, &entryPoint, &info);
|
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||||
metaInfo.package = package.nullStr();
|
engine->findNode<FunctionNode>(registeredFunctions, moduleName, entryPoint);
|
||||||
metaInfo.name = name.c_str();
|
|
||||||
metaInfo.entryPoint = entryPoint.c_str();
|
|
||||||
metaInfo.body = body.c_str();
|
|
||||||
metaInfo.info = info.c_str();
|
|
||||||
|
|
||||||
engine->findNode<FunctionNode, MetaInfo>(registeredFunctions, moduleName, &metaInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SharedFunction()
|
virtual ~SharedFunction()
|
||||||
@ -266,13 +257,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MetaInfo metaInfo;
|
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
string package;
|
const IRoutineMetadata* metadata;
|
||||||
string name;
|
|
||||||
string entryPoint;
|
|
||||||
string body;
|
|
||||||
PathName moduleName;
|
PathName moduleName;
|
||||||
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
GenericMap<Pair<NonPooled<ExternalContext*, ExternalFunction*> > > children;
|
GenericMap<Pair<NonPooled<ExternalContext*, ExternalFunction*> > > children;
|
||||||
};
|
};
|
||||||
@ -284,25 +272,15 @@ public:
|
|||||||
class SharedProcedure : public ExternalProcedure
|
class SharedProcedure : public ExternalProcedure
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SharedProcedure(Engine* aEngine, const string& aPackage, const string& aName,
|
SharedProcedure(Engine* aEngine, const IRoutineMetadata* aMetadata)
|
||||||
const string& aEntryPoint, const string& aBody)
|
|
||||||
: engine(aEngine),
|
: engine(aEngine),
|
||||||
package(*getDefaultMemoryPool(), aPackage),
|
|
||||||
name(*getDefaultMemoryPool(), aName),
|
|
||||||
entryPoint(*getDefaultMemoryPool(), aEntryPoint),
|
|
||||||
body(*getDefaultMemoryPool(), aBody),
|
|
||||||
moduleName(*getDefaultMemoryPool()),
|
moduleName(*getDefaultMemoryPool()),
|
||||||
|
entryPoint(*getDefaultMemoryPool()),
|
||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(aEntryPoint, &moduleName, &entryPoint, &info);
|
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||||
metaInfo.package = package.nullStr();
|
engine->findNode<ProcedureNode>(registeredProcedures, moduleName, entryPoint);
|
||||||
metaInfo.name = name.c_str();
|
|
||||||
metaInfo.entryPoint = entryPoint.c_str();
|
|
||||||
metaInfo.body = body.c_str();
|
|
||||||
metaInfo.info = info.c_str();
|
|
||||||
|
|
||||||
engine->findNode<ProcedureNode, MetaInfo>(registeredProcedures, moduleName, &metaInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SharedProcedure()
|
virtual ~SharedProcedure()
|
||||||
@ -352,13 +330,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MetaInfo metaInfo;
|
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
string package;
|
const IRoutineMetadata* metadata;
|
||||||
string name;
|
|
||||||
string entryPoint;
|
|
||||||
string body;
|
|
||||||
PathName moduleName;
|
PathName moduleName;
|
||||||
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
GenericMap<Pair<NonPooled<ExternalContext*, ExternalProcedure*> > > children;
|
GenericMap<Pair<NonPooled<ExternalContext*, ExternalProcedure*> > > children;
|
||||||
};
|
};
|
||||||
@ -370,28 +345,16 @@ public:
|
|||||||
class SharedTrigger : public ExternalTrigger
|
class SharedTrigger : public ExternalTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SharedTrigger(Engine* aEngine, const string& aName, const string& aEntryPoint,
|
SharedTrigger(Engine* aEngine, const IRoutineMetadata* aMetadata)
|
||||||
const string& aBody, const string& aTable, ExternalTrigger::Type aType)
|
|
||||||
: engine(aEngine),
|
: engine(aEngine),
|
||||||
name(*getDefaultMemoryPool(), aName),
|
metadata(aMetadata),
|
||||||
entryPoint(*getDefaultMemoryPool(), aEntryPoint),
|
|
||||||
body(*getDefaultMemoryPool(), aBody),
|
|
||||||
moduleName(*getDefaultMemoryPool()),
|
moduleName(*getDefaultMemoryPool()),
|
||||||
|
entryPoint(*getDefaultMemoryPool()),
|
||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
table(*getDefaultMemoryPool(), aTable),
|
|
||||||
type(aType),
|
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(aEntryPoint, &moduleName, &entryPoint, &info);
|
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||||
metaInfo.package = NULL;
|
engine->findNode<TriggerNode>(registeredTriggers, moduleName, entryPoint);
|
||||||
metaInfo.name = name.c_str();
|
|
||||||
metaInfo.entryPoint = entryPoint.c_str();
|
|
||||||
metaInfo.body = body.c_str();
|
|
||||||
metaInfo.info = info.c_str();
|
|
||||||
metaInfo.type = type;
|
|
||||||
metaInfo.table = table.nullStr();
|
|
||||||
|
|
||||||
engine->findNode<TriggerNode, TriggerMetaInfo>(registeredTriggers, moduleName, &metaInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SharedTrigger()
|
virtual ~SharedTrigger()
|
||||||
@ -434,15 +397,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TriggerMetaInfo metaInfo;
|
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
string name;
|
const IRoutineMetadata* metadata;
|
||||||
string entryPoint;
|
|
||||||
string body;
|
|
||||||
PathName moduleName;
|
PathName moduleName;
|
||||||
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
string table;
|
|
||||||
ExternalTrigger::Type type;
|
|
||||||
GenericMap<Pair<NonPooled<ExternalContext*, ExternalTrigger*> > > children;
|
GenericMap<Pair<NonPooled<ExternalContext*, ExternalTrigger*> > > children;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -530,8 +489,12 @@ ModulesMap::~ModulesMap()
|
|||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void Engine::loadModule(const string& str, PathName* moduleName, string* entryPoint, string* info)
|
void Engine::loadModule(const IRoutineMetadata* metadata, PathName* moduleName, string* entryPoint)
|
||||||
{
|
{
|
||||||
|
LocalStatus status;
|
||||||
|
const string str(metadata->getEntryPoint(&status));
|
||||||
|
ThrowError::check(status.get());
|
||||||
|
|
||||||
const size_t pos = str.find('!');
|
const size_t pos = str.find('!');
|
||||||
if (pos == string::npos)
|
if (pos == string::npos)
|
||||||
{
|
{
|
||||||
@ -562,7 +525,6 @@ void Engine::loadModule(const string& str, PathName* moduleName, string* entryPo
|
|||||||
*entryPoint = str.substr(pos + 1);
|
*entryPoint = str.substr(pos + 1);
|
||||||
|
|
||||||
size_t n = entryPoint->find('!');
|
size_t n = entryPoint->find('!');
|
||||||
*info = (n == string::npos ? "" : entryPoint->substr(n + 1));
|
|
||||||
*entryPoint = (n == string::npos ? *entryPoint : entryPoint->substr(0, n));
|
*entryPoint = (n == string::npos ? *entryPoint : entryPoint->substr(0, n));
|
||||||
|
|
||||||
MutexLockGuard guard(modulesMutex);
|
MutexLockGuard guard(modulesMutex);
|
||||||
@ -612,7 +574,7 @@ template <typename NodeType, typename ObjType, typename SharedObjType> ObjType*
|
|||||||
ObjType* obj;
|
ObjType* obj;
|
||||||
if (!children.get(context, obj))
|
if (!children.get(context, obj))
|
||||||
{
|
{
|
||||||
obj = getNode<NodeType, ObjType>(nodes, moduleName, &sharedObj->metaInfo);
|
obj = getNode<NodeType, ObjType>(nodes, moduleName, sharedObj->metadata, sharedObj->entryPoint);
|
||||||
if (obj)
|
if (obj)
|
||||||
children.put(context, obj);
|
children.put(context, obj);
|
||||||
}
|
}
|
||||||
@ -634,11 +596,9 @@ template <typename ObjType> void Engine::deleteChildren(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename T2> T* Engine::findNode(T* nodes,
|
template <typename T> T* Engine::findNode(T* nodes, const PathName& moduleName,
|
||||||
const PathName& moduleName, T2* params)
|
const string& entryPoint)
|
||||||
{
|
{
|
||||||
const string entryPoint(params->entryPoint);
|
|
||||||
|
|
||||||
for (T* node = nodes; node; node = node->next)
|
for (T* node = nodes; node; node = node->next)
|
||||||
{
|
{
|
||||||
if (node->module == moduleName && entryPoint == node->factory->getName())
|
if (node->module == moduleName && entryPoint == node->factory->getName())
|
||||||
@ -658,11 +618,11 @@ template <typename T, typename T2> T* Engine::findNode(T* nodes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename T2, typename T3> T2* Engine::getNode(T* nodes,
|
template <typename T, typename T2> T2* Engine::getNode(T* nodes, const PathName& moduleName,
|
||||||
const PathName& moduleName, T3* params)
|
const IRoutineMetadata* metadata, const string& entryPoint)
|
||||||
{
|
{
|
||||||
T* node = findNode<T, T3>(nodes, moduleName, params);
|
T* node = findNode<T>(nodes, moduleName, entryPoint);
|
||||||
return node->factory->newItem(params);
|
return node->factory->newItem(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -720,12 +680,11 @@ void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
|
|||||||
|
|
||||||
|
|
||||||
ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* /*context*/,
|
ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* /*context*/,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body)
|
const IRoutineMetadata* metadata)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new SharedFunction(this, (package ? package : ""), name,
|
return new SharedFunction(this, metadata);
|
||||||
(entryPoint ? entryPoint : ""), (body ? body : ""));
|
|
||||||
}
|
}
|
||||||
catch (const ThrowError::Exception& e)
|
catch (const ThrowError::Exception& e)
|
||||||
{
|
{
|
||||||
@ -736,12 +695,11 @@ ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* /*
|
|||||||
|
|
||||||
|
|
||||||
ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext* /*context*/,
|
ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext* /*context*/,
|
||||||
const char* package, const char* name, const char* entryPoint, const char* body)
|
const IRoutineMetadata* metadata)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new SharedProcedure(this, (package ? package : ""), name,
|
return new SharedProcedure(this, metadata);
|
||||||
(entryPoint ? entryPoint : ""), (body ? body : ""));
|
|
||||||
}
|
}
|
||||||
catch (const ThrowError::Exception& e)
|
catch (const ThrowError::Exception& e)
|
||||||
{
|
{
|
||||||
@ -752,13 +710,11 @@ ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext*
|
|||||||
|
|
||||||
|
|
||||||
ExternalTrigger* FB_CALL Engine::makeTrigger(Error* error, ExternalContext* /*context*/,
|
ExternalTrigger* FB_CALL Engine::makeTrigger(Error* error, ExternalContext* /*context*/,
|
||||||
const char* name, const char* entryPoint, const char* body, const char* table,
|
const IRoutineMetadata* metadata)
|
||||||
ExternalTrigger::Type type)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new SharedTrigger(this, name, (entryPoint ? entryPoint : ""), (body ? body : ""),
|
return new SharedTrigger(this, metadata);
|
||||||
table, type);
|
|
||||||
}
|
}
|
||||||
catch (const ThrowError::Exception& e)
|
catch (const ThrowError::Exception& e)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user