mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:03:04 +01:00
Improvements to the UDR plugin.
This commit is contained in:
parent
f9dff2cfdc
commit
e9f74f04d1
@ -67,7 +67,7 @@ ifeq ($(PLATFORM),DARWIN)
|
|||||||
$(FIREBIRD_LIBRARY_LINK)
|
$(FIREBIRD_LIBRARY_LINK)
|
||||||
else
|
else
|
||||||
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(LIB_LINK_SONAME)udrcpp_example.$(SHRLIB_EXT) \
|
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(LIB_LINK_SONAME)udrcpp_example.$(SHRLIB_EXT) \
|
||||||
$(LIB_PATH_OPTS) -o $@ $^ $(THR_LIBS) $(PLUGINS)/$(LIB_PREFIX)udr_engine.$(SHRLIB_EXT) \
|
$(LIB_PATH_OPTS) -o $@ $^ $(THR_LIBS) \
|
||||||
$(FIREBIRD_LIBRARY_LINK)
|
$(FIREBIRD_LIBRARY_LINK)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -207,12 +207,6 @@
|
|||||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="udr_engine.vcxproj">
|
|
||||||
<Project>{20debf08-ef0a-4c94-adeb-fe9bba14588b}</Project>
|
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -211,12 +211,6 @@
|
|||||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="udr_engine.vcxproj">
|
|
||||||
<Project>{20debf08-ef0a-4c94-adeb-fe9bba14588b}</Project>
|
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -12,7 +12,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intlbuild", "intlbuild.vcpr
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udrcpp_example", "udrcpp_example.vcproj", "{FF0FD8DF-1E5C-486E-B395-A620376A4633}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udrcpp_example", "udrcpp_example.vcproj", "{FF0FD8DF-1E5C-486E-B395-A620376A4633}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B} = {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}
|
|
||||||
{4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
|
{4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -783,3 +783,6 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
|
|||||||
AutoRelease<IMessageMetadata> triggerMetadata;
|
AutoRelease<IMessageMetadata> triggerMetadata;
|
||||||
AutoRelease<IStatement> stmt;
|
AutoRelease<IStatement> stmt;
|
||||||
FB_UDR_END_TRIGGER
|
FB_UDR_END_TRIGGER
|
||||||
|
|
||||||
|
|
||||||
|
FB_UDR_IMPLEMENT_ENTRY_POINT
|
||||||
|
@ -1216,23 +1216,32 @@ interface TraceFactory : PluginBase
|
|||||||
// UDR Factory interfaces. They should be singletons instances created by user's modules and
|
// UDR Factory interfaces. 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.
|
||||||
|
|
||||||
interface UdrFunctionFactory : Versioned
|
interface UdrFunctionFactory : Disposable
|
||||||
{
|
{
|
||||||
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
||||||
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
|
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
|
||||||
ExternalFunction newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
ExternalFunction newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UdrProcedureFactory : Versioned
|
interface UdrProcedureFactory : Disposable
|
||||||
{
|
{
|
||||||
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
||||||
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
|
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
|
||||||
ExternalProcedure newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
ExternalProcedure newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UdrTriggerFactory : Versioned
|
interface UdrTriggerFactory : Disposable
|
||||||
{
|
{
|
||||||
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
|
||||||
MetadataBuilder fieldsBuilder);
|
MetadataBuilder fieldsBuilder);
|
||||||
ExternalTrigger newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
ExternalTrigger newItem(Status status, ExternalContext context, RoutineMetadata metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UdrPlugin : Versioned
|
||||||
|
{
|
||||||
|
Master getMaster();
|
||||||
|
|
||||||
|
void registerFunction(Status status, const string name, UdrFunctionFactory factory);
|
||||||
|
void registerProcedure(Status status, const string name, UdrProcedureFactory factory);
|
||||||
|
void registerTrigger(Status status, const string name, UdrTriggerFactory factory);
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#ifndef IDL_FB_INTERFACES_H
|
#ifndef IDL_FB_INTERFACES_H
|
||||||
#define IDL_FB_INTERFACES_H
|
#define IDL_FB_INTERFACES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef CLOOP_CARG
|
#ifndef CLOOP_CARG
|
||||||
#define CLOOP_CARG
|
#define CLOOP_CARG
|
||||||
#endif
|
#endif
|
||||||
@ -106,6 +108,7 @@ namespace Firebird
|
|||||||
class IUdrFunctionFactory;
|
class IUdrFunctionFactory;
|
||||||
class IUdrProcedureFactory;
|
class IUdrProcedureFactory;
|
||||||
class IUdrTriggerFactory;
|
class IUdrTriggerFactory;
|
||||||
|
class IUdrPlugin;
|
||||||
|
|
||||||
// Interfaces declarations
|
// Interfaces declarations
|
||||||
|
|
||||||
@ -4401,10 +4404,10 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IUdrFunctionFactory : public IVersioned
|
class IUdrFunctionFactory : public IDisposable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct VTable : public IVersioned::VTable
|
struct VTable : public IDisposable::VTable
|
||||||
{
|
{
|
||||||
void (CLOOP_CARG *setup)(IUdrFunctionFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) throw();
|
void (CLOOP_CARG *setup)(IUdrFunctionFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) throw();
|
||||||
IExternalFunction* (CLOOP_CARG *newItem)(IUdrFunctionFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
IExternalFunction* (CLOOP_CARG *newItem)(IUdrFunctionFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
||||||
@ -4412,7 +4415,7 @@ namespace Firebird
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
IUdrFunctionFactory(DoNotInherit)
|
IUdrFunctionFactory(DoNotInherit)
|
||||||
: IVersioned(DoNotInherit())
|
: IDisposable(DoNotInherit())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4421,7 +4424,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 2;
|
static const unsigned VERSION = 3;
|
||||||
|
|
||||||
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder)
|
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder)
|
||||||
{
|
{
|
||||||
@ -4437,10 +4440,10 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IUdrProcedureFactory : public IVersioned
|
class IUdrProcedureFactory : public IDisposable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct VTable : public IVersioned::VTable
|
struct VTable : public IDisposable::VTable
|
||||||
{
|
{
|
||||||
void (CLOOP_CARG *setup)(IUdrProcedureFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) throw();
|
void (CLOOP_CARG *setup)(IUdrProcedureFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) throw();
|
||||||
IExternalProcedure* (CLOOP_CARG *newItem)(IUdrProcedureFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
IExternalProcedure* (CLOOP_CARG *newItem)(IUdrProcedureFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
||||||
@ -4448,7 +4451,7 @@ namespace Firebird
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
IUdrProcedureFactory(DoNotInherit)
|
IUdrProcedureFactory(DoNotInherit)
|
||||||
: IVersioned(DoNotInherit())
|
: IDisposable(DoNotInherit())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4457,7 +4460,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 2;
|
static const unsigned VERSION = 3;
|
||||||
|
|
||||||
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder)
|
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder)
|
||||||
{
|
{
|
||||||
@ -4473,10 +4476,10 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IUdrTriggerFactory : public IVersioned
|
class IUdrTriggerFactory : public IDisposable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct VTable : public IVersioned::VTable
|
struct VTable : public IDisposable::VTable
|
||||||
{
|
{
|
||||||
void (CLOOP_CARG *setup)(IUdrTriggerFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) throw();
|
void (CLOOP_CARG *setup)(IUdrTriggerFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) throw();
|
||||||
IExternalTrigger* (CLOOP_CARG *newItem)(IUdrTriggerFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
IExternalTrigger* (CLOOP_CARG *newItem)(IUdrTriggerFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
|
||||||
@ -4484,7 +4487,7 @@ namespace Firebird
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
IUdrTriggerFactory(DoNotInherit)
|
IUdrTriggerFactory(DoNotInherit)
|
||||||
: IVersioned(DoNotInherit())
|
: IDisposable(DoNotInherit())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4493,7 +4496,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 2;
|
static const unsigned VERSION = 3;
|
||||||
|
|
||||||
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder)
|
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder)
|
||||||
{
|
{
|
||||||
@ -4509,6 +4512,55 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IUdrPlugin : public IVersioned
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct VTable : public IVersioned::VTable
|
||||||
|
{
|
||||||
|
IMaster* (CLOOP_CARG *getMaster)(IUdrPlugin* self) throw();
|
||||||
|
void (CLOOP_CARG *registerFunction)(IUdrPlugin* self, IStatus* status, const char* name, IUdrFunctionFactory* factory) throw();
|
||||||
|
void (CLOOP_CARG *registerProcedure)(IUdrPlugin* self, IStatus* status, const char* name, IUdrProcedureFactory* factory) throw();
|
||||||
|
void (CLOOP_CARG *registerTrigger)(IUdrPlugin* self, IStatus* status, const char* name, IUdrTriggerFactory* factory) throw();
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IUdrPlugin(DoNotInherit)
|
||||||
|
: IVersioned(DoNotInherit())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~IUdrPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const unsigned VERSION = 2;
|
||||||
|
|
||||||
|
IMaster* getMaster()
|
||||||
|
{
|
||||||
|
IMaster* ret = static_cast<VTable*>(this->cloopVTable)->getMaster(this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StatusType> void registerFunction(StatusType* status, const char* name, IUdrFunctionFactory* factory)
|
||||||
|
{
|
||||||
|
static_cast<VTable*>(this->cloopVTable)->registerFunction(this, status, name, factory);
|
||||||
|
StatusType::checkException(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StatusType> void registerProcedure(StatusType* status, const char* name, IUdrProcedureFactory* factory)
|
||||||
|
{
|
||||||
|
static_cast<VTable*>(this->cloopVTable)->registerProcedure(this, status, name, factory);
|
||||||
|
StatusType::checkException(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StatusType> void registerTrigger(StatusType* status, const char* name, IUdrTriggerFactory* factory)
|
||||||
|
{
|
||||||
|
static_cast<VTable*>(this->cloopVTable)->registerTrigger(this, status, name, factory);
|
||||||
|
StatusType::checkException(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Interfaces implementations
|
// Interfaces implementations
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base>
|
template <typename Name, typename StatusType, typename Base>
|
||||||
@ -14377,6 +14429,7 @@ namespace Firebird
|
|||||||
VTableImpl()
|
VTableImpl()
|
||||||
{
|
{
|
||||||
this->version = Base::VERSION;
|
this->version = Base::VERSION;
|
||||||
|
this->dispose = &Name::cloopdisposeDispatcher;
|
||||||
this->setup = &Name::cloopsetupDispatcher;
|
this->setup = &Name::cloopsetupDispatcher;
|
||||||
this->newItem = &Name::cloopnewItemDispatcher;
|
this->newItem = &Name::cloopnewItemDispatcher;
|
||||||
}
|
}
|
||||||
@ -14413,9 +14466,21 @@ namespace Firebird
|
|||||||
return static_cast<IExternalFunction*>(0);
|
return static_cast<IExternalFunction*>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopdisposeDispatcher(IDisposable* self) throw()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::dispose();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUdrFunctionFactory> > >
|
template <typename Name, typename StatusType, typename Base = IDisposableImpl<Name, StatusType, Inherit<IVersionedImpl<Name, StatusType, Inherit<IUdrFunctionFactory> > > > >
|
||||||
class IUdrFunctionFactoryImpl : public IUdrFunctionFactoryBaseImpl<Name, StatusType, Base>
|
class IUdrFunctionFactoryImpl : public IUdrFunctionFactoryBaseImpl<Name, StatusType, Base>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -14445,6 +14510,7 @@ namespace Firebird
|
|||||||
VTableImpl()
|
VTableImpl()
|
||||||
{
|
{
|
||||||
this->version = Base::VERSION;
|
this->version = Base::VERSION;
|
||||||
|
this->dispose = &Name::cloopdisposeDispatcher;
|
||||||
this->setup = &Name::cloopsetupDispatcher;
|
this->setup = &Name::cloopsetupDispatcher;
|
||||||
this->newItem = &Name::cloopnewItemDispatcher;
|
this->newItem = &Name::cloopnewItemDispatcher;
|
||||||
}
|
}
|
||||||
@ -14481,9 +14547,21 @@ namespace Firebird
|
|||||||
return static_cast<IExternalProcedure*>(0);
|
return static_cast<IExternalProcedure*>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopdisposeDispatcher(IDisposable* self) throw()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::dispose();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUdrProcedureFactory> > >
|
template <typename Name, typename StatusType, typename Base = IDisposableImpl<Name, StatusType, Inherit<IVersionedImpl<Name, StatusType, Inherit<IUdrProcedureFactory> > > > >
|
||||||
class IUdrProcedureFactoryImpl : public IUdrProcedureFactoryBaseImpl<Name, StatusType, Base>
|
class IUdrProcedureFactoryImpl : public IUdrProcedureFactoryBaseImpl<Name, StatusType, Base>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -14513,6 +14591,7 @@ namespace Firebird
|
|||||||
VTableImpl()
|
VTableImpl()
|
||||||
{
|
{
|
||||||
this->version = Base::VERSION;
|
this->version = Base::VERSION;
|
||||||
|
this->dispose = &Name::cloopdisposeDispatcher;
|
||||||
this->setup = &Name::cloopsetupDispatcher;
|
this->setup = &Name::cloopsetupDispatcher;
|
||||||
this->newItem = &Name::cloopnewItemDispatcher;
|
this->newItem = &Name::cloopnewItemDispatcher;
|
||||||
}
|
}
|
||||||
@ -14549,9 +14628,21 @@ namespace Firebird
|
|||||||
return static_cast<IExternalTrigger*>(0);
|
return static_cast<IExternalTrigger*>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopdisposeDispatcher(IDisposable* self) throw()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::dispose();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUdrTriggerFactory> > >
|
template <typename Name, typename StatusType, typename Base = IDisposableImpl<Name, StatusType, Inherit<IVersionedImpl<Name, StatusType, Inherit<IUdrTriggerFactory> > > > >
|
||||||
class IUdrTriggerFactoryImpl : public IUdrTriggerFactoryBaseImpl<Name, StatusType, Base>
|
class IUdrTriggerFactoryImpl : public IUdrTriggerFactoryBaseImpl<Name, StatusType, Base>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -14567,6 +14658,104 @@ namespace Firebird
|
|||||||
virtual void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) = 0;
|
virtual void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) = 0;
|
||||||
virtual IExternalTrigger* newItem(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata) = 0;
|
virtual IExternalTrigger* newItem(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Name, typename StatusType, typename Base>
|
||||||
|
class IUdrPluginBaseImpl : public Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef IUdrPlugin Declaration;
|
||||||
|
|
||||||
|
IUdrPluginBaseImpl(DoNotInherit = DoNotInherit())
|
||||||
|
{
|
||||||
|
static struct VTableImpl : Base::VTable
|
||||||
|
{
|
||||||
|
VTableImpl()
|
||||||
|
{
|
||||||
|
this->version = Base::VERSION;
|
||||||
|
this->getMaster = &Name::cloopgetMasterDispatcher;
|
||||||
|
this->registerFunction = &Name::cloopregisterFunctionDispatcher;
|
||||||
|
this->registerProcedure = &Name::cloopregisterProcedureDispatcher;
|
||||||
|
this->registerTrigger = &Name::cloopregisterTriggerDispatcher;
|
||||||
|
}
|
||||||
|
} vTable;
|
||||||
|
|
||||||
|
this->cloopVTable = &vTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IMaster* CLOOP_CARG cloopgetMasterDispatcher(IUdrPlugin* self) throw()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return static_cast<Name*>(self)->Name::getMaster();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(0);
|
||||||
|
return static_cast<IMaster*>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopregisterFunctionDispatcher(IUdrPlugin* self, IStatus* status, const char* name, IUdrFunctionFactory* factory) throw()
|
||||||
|
{
|
||||||
|
StatusType status2(status);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::registerFunction(&status2, name, factory);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(&status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopregisterProcedureDispatcher(IUdrPlugin* self, IStatus* status, const char* name, IUdrProcedureFactory* factory) throw()
|
||||||
|
{
|
||||||
|
StatusType status2(status);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::registerProcedure(&status2, name, factory);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(&status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CLOOP_CARG cloopregisterTriggerDispatcher(IUdrPlugin* self, IStatus* status, const char* name, IUdrTriggerFactory* factory) throw()
|
||||||
|
{
|
||||||
|
StatusType status2(status);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<Name*>(self)->Name::registerTrigger(&status2, name, factory);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
StatusType::catchException(&status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUdrPlugin> > >
|
||||||
|
class IUdrPluginImpl : public IUdrPluginBaseImpl<Name, StatusType, Base>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
IUdrPluginImpl(DoNotInherit = DoNotInherit())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~IUdrPluginImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual IMaster* getMaster() = 0;
|
||||||
|
virtual void registerFunction(StatusType* status, const char* name, IUdrFunctionFactory* factory) = 0;
|
||||||
|
virtual void registerProcedure(StatusType* status, const char* name, IUdrProcedureFactory* factory) = 0;
|
||||||
|
virtual void registerTrigger(StatusType* status, const char* name, IUdrTriggerFactory* factory) = 0;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,5 +239,6 @@ namespace Firebird
|
|||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
|
||||||
#define FB_PLUGIN_ENTRY_POINT firebird_plugin
|
#define FB_PLUGIN_ENTRY_POINT firebird_plugin
|
||||||
|
#define FB_UDR_PLUGIN_ENTRY_POINT firebird_udr_plugin
|
||||||
|
|
||||||
#endif // FB_INTERFACE_H
|
#endif // FB_INTERFACE_H
|
||||||
|
@ -27,20 +27,51 @@
|
|||||||
#error FB_UDR_STATUS_TYPE must be defined with the Status class before UdrCppEngine.h inclusion.
|
#error FB_UDR_STATUS_TYPE must be defined with the Status class before UdrCppEngine.h inclusion.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "./UdrEngine.h"
|
|
||||||
#include "./Message.h"
|
#include "./Message.h"
|
||||||
#ifndef JRD_IBASE_H
|
|
||||||
#include "ibase.h"
|
|
||||||
#include "iberror.h"
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Firebird
|
#define FB_UDR_IMPLEMENT_ENTRY_POINT \
|
||||||
{
|
namespace Firebird \
|
||||||
namespace Udr
|
{ \
|
||||||
{
|
namespace Udr \
|
||||||
//------------------------------------------------------------------------------
|
{ \
|
||||||
|
RegistrationNode<IUdrFunctionFactory>* regFunctions = NULL; \
|
||||||
|
RegistrationNode<IUdrProcedureFactory>* regProcedures = NULL; \
|
||||||
|
RegistrationNode<IUdrTriggerFactory>* regTriggers = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
extern "C" FB_BOOLEAN* FB_UDR_PLUGIN_ENTRY_POINT(IStatus* status, FB_BOOLEAN* theirUnloadFlag, \
|
||||||
|
IUdrPlugin* udrPlugin) \
|
||||||
|
{ \
|
||||||
|
::Firebird::Udr::FactoryRegistration::finish(status, udrPlugin); \
|
||||||
|
\
|
||||||
|
class UnloadDetector \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
UnloadDetector(FB_BOOLEAN* aTheirUnloadFlag, IUdrPlugin* aUdrPlugin) \
|
||||||
|
: myUnloadFlag(FB_FALSE), \
|
||||||
|
theirUnloadFlag(aTheirUnloadFlag), \
|
||||||
|
udrPlugin(aUdrPlugin) \
|
||||||
|
{ \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
~UnloadDetector() \
|
||||||
|
{ \
|
||||||
|
if (!myUnloadFlag) \
|
||||||
|
*theirUnloadFlag = FB_TRUE; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
FB_BOOLEAN myUnloadFlag; \
|
||||||
|
FB_BOOLEAN* theirUnloadFlag; \
|
||||||
|
IUdrPlugin* udrPlugin; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static UnloadDetector unloadDetector(theirUnloadFlag, udrPlugin); \
|
||||||
|
\
|
||||||
|
return &unloadDetector.myUnloadFlag; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define FB_UDR_BEGIN_FUNCTION(name) \
|
#define FB_UDR_BEGIN_FUNCTION(name) \
|
||||||
@ -176,6 +207,13 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Firebird
|
||||||
|
{
|
||||||
|
namespace Udr
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename StatusType> class Procedure;
|
template <typename T, typename StatusType> class Procedure;
|
||||||
|
|
||||||
|
|
||||||
@ -311,13 +349,76 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T> struct RegistrationNode
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
T* factory;
|
||||||
|
RegistrationNode<T>* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern RegistrationNode<IUdrFunctionFactory>* regFunctions;
|
||||||
|
extern RegistrationNode<IUdrProcedureFactory>* regProcedures;
|
||||||
|
extern RegistrationNode<IUdrTriggerFactory>* regTriggers;
|
||||||
|
|
||||||
|
class FactoryRegistration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename T> static void schedule(const char* name, T* factory,
|
||||||
|
RegistrationNode<T>** list)
|
||||||
|
{
|
||||||
|
RegistrationNode<T>* node = new RegistrationNode<T>();
|
||||||
|
node->name = name;
|
||||||
|
node->factory = factory;
|
||||||
|
node->next = *list;
|
||||||
|
|
||||||
|
*list = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void finish(IStatus* status, IUdrPlugin* plugin)
|
||||||
|
{
|
||||||
|
CheckStatusWrapper statusWrapper(status);
|
||||||
|
|
||||||
|
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerFunction, regFunctions))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerProcedure, regProcedures))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerTrigger, regTriggers))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static bool run(CheckStatusWrapper* statusWrapper, IUdrPlugin* plugin,
|
||||||
|
void (IUdrPlugin::*routine)(CheckStatusWrapper* status, const char* name, T* factory),
|
||||||
|
RegistrationNode<T>* list)
|
||||||
|
{
|
||||||
|
for (RegistrationNode<T>* node = list; node; node = node->next)
|
||||||
|
{
|
||||||
|
(plugin->*routine)(statusWrapper, node->name, node->factory);
|
||||||
|
|
||||||
|
if (statusWrapper->getStatus() & IStatus::FB_HAS_ERRORS)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename StatusType> class FunctionFactoryImpl :
|
template <typename T, typename StatusType> class FunctionFactoryImpl :
|
||||||
public IUdrFunctionFactoryImpl<FunctionFactoryImpl<T, StatusType>, StatusType>
|
public IUdrFunctionFactoryImpl<FunctionFactoryImpl<T, StatusType>, StatusType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit FunctionFactoryImpl(const char* name)
|
explicit FunctionFactoryImpl(const char* name)
|
||||||
{
|
{
|
||||||
fbUdrRegFunction(name, this);
|
FactoryRegistration::schedule<IUdrFunctionFactory>(name, this, ®Functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose()
|
||||||
|
{
|
||||||
|
// Do not delete this. The instances are statically allocated.
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(StatusType* status, IExternalContext* /*context*/,
|
void setup(StatusType* status, IExternalContext* /*context*/,
|
||||||
@ -341,7 +442,12 @@ template <typename T, typename StatusType> class ProcedureFactoryImpl :
|
|||||||
public:
|
public:
|
||||||
explicit ProcedureFactoryImpl(const char* name)
|
explicit ProcedureFactoryImpl(const char* name)
|
||||||
{
|
{
|
||||||
fbUdrRegProcedure(name, this);
|
FactoryRegistration::schedule<IUdrProcedureFactory>(name, this, ®Procedures);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose()
|
||||||
|
{
|
||||||
|
// Do not delete this. The instances are statically allocated.
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(StatusType* status, IExternalContext* /*context*/,
|
void setup(StatusType* status, IExternalContext* /*context*/,
|
||||||
@ -365,7 +471,12 @@ template <typename T, typename StatusType> class TriggerFactoryImpl :
|
|||||||
public:
|
public:
|
||||||
explicit TriggerFactoryImpl(const char* name)
|
explicit TriggerFactoryImpl(const char* name)
|
||||||
{
|
{
|
||||||
fbUdrRegTrigger(name, this);
|
FactoryRegistration::schedule<IUdrTriggerFactory>(name, this, ®Triggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose()
|
||||||
|
{
|
||||||
|
// Do not delete this. The instances are statically allocated.
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(StatusType* status, IExternalContext* /*context*/,
|
void setup(StatusType* status, IExternalContext* /*context*/,
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* The contents of this file are subject to the Initial
|
|
||||||
* Developer's Public License Version 1.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at
|
|
||||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed AS IS,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing rights
|
|
||||||
* and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code was created by Adriano dos Santos Fernandes
|
|
||||||
* for the Firebird Open Source RDBMS project.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
|
|
||||||
* and all contributors signed below.
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
* Contributor(s): ______________________________________.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FIREBIRD_UDR_H
|
|
||||||
#define FIREBIRD_UDR_H
|
|
||||||
|
|
||||||
#include "./Interface.h"
|
|
||||||
|
|
||||||
#ifndef FB_EXPORTED
|
|
||||||
#if defined(DARWIN)
|
|
||||||
#define FB_EXPORTED __attribute__((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define FB_EXPORTED
|
|
||||||
#endif // OS choice (DARWIN)
|
|
||||||
#endif // FB_EXPORTED
|
|
||||||
|
|
||||||
|
|
||||||
namespace Firebird
|
|
||||||
{
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
//// TODO: review
|
|
||||||
// Routine registration functions.
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegFunction(const char* name, IUdrFunctionFactory* factory);
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegProcedure(const char* name, IUdrProcedureFactory* factory);
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegTrigger(const char* name, IUdrTriggerFactory* factory);
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
} // namespace Firebird
|
|
||||||
|
|
||||||
#endif // FIREBIRD_UDR_H
|
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
#include "../jrd/ibase.h"
|
#include "../jrd/ibase.h"
|
||||||
#include "firebird/UdrEngine.h"
|
|
||||||
#include "firebird/Interface.h"
|
#include "firebird/Interface.h"
|
||||||
#include "../common/classes/alloc.h"
|
#include "../common/classes/alloc.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
@ -43,35 +42,7 @@ namespace Firebird
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
struct Node
|
class UdrPluginImpl;
|
||||||
{
|
|
||||||
Node()
|
|
||||||
: name(*getDefaultMemoryPool()),
|
|
||||||
module(*getDefaultMemoryPool())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
string name;
|
|
||||||
PathName module;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FunctionNode : public Node
|
|
||||||
{
|
|
||||||
IUdrFunctionFactory* factory;
|
|
||||||
FunctionNode* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ProcedureNode : public Node
|
|
||||||
{
|
|
||||||
IUdrProcedureFactory* factory;
|
|
||||||
ProcedureNode* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TriggerNode : public Node
|
|
||||||
{
|
|
||||||
IUdrTriggerFactory* factory;
|
|
||||||
TriggerNode* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static GlobalPtr<ObjectsArray<PathName> > paths;
|
static GlobalPtr<ObjectsArray<PathName> > paths;
|
||||||
@ -129,24 +100,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
UdrPluginImpl* loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
||||||
PathName* moduleName, string* entryPoint);
|
PathName* moduleName, string* entryPoint);
|
||||||
|
|
||||||
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
|
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
|
||||||
ThrowStatusWrapper* status, GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
|
ThrowStatusWrapper* status,
|
||||||
SharedObjType* sharedObj, IExternalContext* context, NodeType* nodes,
|
GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
|
||||||
|
SharedObjType* sharedObj, IExternalContext* context,
|
||||||
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName);
|
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName);
|
||||||
|
|
||||||
template <typename ObjType> void deleteChildren(
|
template <typename ObjType> void deleteChildren(
|
||||||
GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children);
|
GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children);
|
||||||
|
|
||||||
template <typename T> T* findNode(ThrowStatusWrapper* status, T* nodes,
|
template <typename T> T* findNode(ThrowStatusWrapper* status,
|
||||||
const PathName& moduleName, const string& entryPoint);
|
const GenericMap<Pair<Left<string, T*> > >& nodes, const string& entryPoint);
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename T, typename T2> T2* getNode(ThrowStatusWrapper* status, T* nodes,
|
|
||||||
const PathName& moduleName, IExternalContext* context, IRoutineMetadata* metadata,
|
|
||||||
const string& entryPoint);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void open(ThrowStatusWrapper* status, IExternalContext* context, char* name, unsigned nameSize);
|
void open(ThrowStatusWrapper* status, IExternalContext* context, char* name, unsigned nameSize);
|
||||||
@ -172,11 +139,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ModulesMap : public GenericMap<Pair<Left<PathName, ModuleLoader::Module*> > >
|
class ModulesMap : public GenericMap<Pair<Left<PathName, UdrPluginImpl*> > >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ModulesMap(MemoryPool& p)
|
explicit ModulesMap(MemoryPool& p)
|
||||||
: GenericMap<Pair<Left<PathName, ModuleLoader::Module*> > >(p)
|
: GenericMap<Pair<Left<PathName, UdrPluginImpl*> > >(p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,15 +157,125 @@ public:
|
|||||||
static GlobalPtr<Mutex> modulesMutex;
|
static GlobalPtr<Mutex> modulesMutex;
|
||||||
static GlobalPtr<ModulesMap> modules;
|
static GlobalPtr<ModulesMap> modules;
|
||||||
|
|
||||||
static InitInstance<PathName> loadingModule;
|
|
||||||
static FunctionNode* registeredFunctions = NULL;
|
|
||||||
static ProcedureNode* registeredProcedures = NULL;
|
|
||||||
static TriggerNode* registeredTriggers = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class UdrPluginImpl : public VersionedIface<IUdrPluginImpl<UdrPluginImpl, ThrowStatusWrapper> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UdrPluginImpl(const PathName& aModuleName, ModuleLoader::Module* aModule)
|
||||||
|
: moduleName(*getDefaultMemoryPool(), aModuleName),
|
||||||
|
module(aModule),
|
||||||
|
myUnloadFlag(FB_FALSE),
|
||||||
|
theirUnloadFlag(NULL),
|
||||||
|
functionsMap(*getDefaultMemoryPool()),
|
||||||
|
proceduresMap(*getDefaultMemoryPool()),
|
||||||
|
triggersMap(*getDefaultMemoryPool())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~UdrPluginImpl()
|
||||||
|
{
|
||||||
|
if (myUnloadFlag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*theirUnloadFlag = FB_TRUE;
|
||||||
|
|
||||||
|
{
|
||||||
|
GenericMap<Pair<Left<string, IUdrFunctionFactory*> > >::Accessor accessor(&functionsMap);
|
||||||
|
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
|
||||||
|
accessor.current()->second->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
GenericMap<Pair<Left<string, IUdrProcedureFactory*> > >::Accessor accessor(&proceduresMap);
|
||||||
|
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
|
||||||
|
accessor.current()->second->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
GenericMap<Pair<Left<string, IUdrTriggerFactory*> > >::Accessor accessor(&triggersMap);
|
||||||
|
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
|
||||||
|
accessor.current()->second->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
IMaster* getMaster()
|
||||||
|
{
|
||||||
|
return MasterInterfacePtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerFunction(ThrowStatusWrapper* status, const char* name,
|
||||||
|
IUdrFunctionFactory* factory)
|
||||||
|
{
|
||||||
|
if (functionsMap.exist(name))
|
||||||
|
{
|
||||||
|
static const ISC_STATUS statusVector[] = {
|
||||||
|
isc_arg_gds, isc_random,
|
||||||
|
isc_arg_string, (ISC_STATUS) "Duplicate UDR function",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) name,
|
||||||
|
isc_arg_end
|
||||||
|
};
|
||||||
|
|
||||||
|
throw FbException(status, statusVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
functionsMap.put(name, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerProcedure(ThrowStatusWrapper* status, const char* name,
|
||||||
|
IUdrProcedureFactory* factory)
|
||||||
|
{
|
||||||
|
if (proceduresMap.exist(name))
|
||||||
|
{
|
||||||
|
static const ISC_STATUS statusVector[] = {
|
||||||
|
isc_arg_gds, isc_random,
|
||||||
|
isc_arg_string, (ISC_STATUS) "Duplicate UDR procedure",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) name,
|
||||||
|
isc_arg_end
|
||||||
|
};
|
||||||
|
|
||||||
|
throw FbException(status, statusVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
proceduresMap.put(name, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerTrigger(ThrowStatusWrapper* status, const char* name,
|
||||||
|
IUdrTriggerFactory* factory)
|
||||||
|
{
|
||||||
|
if (triggersMap.exist(name))
|
||||||
|
{
|
||||||
|
static const ISC_STATUS statusVector[] = {
|
||||||
|
isc_arg_gds, isc_random,
|
||||||
|
isc_arg_string, (ISC_STATUS) "Duplicate UDR trigger",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) name,
|
||||||
|
isc_arg_end
|
||||||
|
};
|
||||||
|
|
||||||
|
throw FbException(status, statusVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
triggersMap.put(name, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PathName moduleName;
|
||||||
|
ModuleLoader::Module* module;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB_BOOLEAN myUnloadFlag;
|
||||||
|
FB_BOOLEAN* theirUnloadFlag;
|
||||||
|
GenericMap<Pair<Left<string, IUdrFunctionFactory*> > > functionsMap;
|
||||||
|
GenericMap<Pair<Left<string, IUdrProcedureFactory*> > > proceduresMap;
|
||||||
|
GenericMap<Pair<Left<string, IUdrTriggerFactory*> > > triggersMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class SharedFunction : public DisposeIface<IExternalFunctionImpl<SharedFunction, ThrowStatusWrapper> >
|
class SharedFunction : public DisposeIface<IExternalFunctionImpl<SharedFunction, ThrowStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -212,10 +289,12 @@ public:
|
|||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
||||||
FunctionNode* node = engine->findNode<FunctionNode>(
|
|
||||||
status, registeredFunctions, moduleName, entryPoint);
|
IUdrFunctionFactory* factory = engine->findNode<IUdrFunctionFactory>(
|
||||||
node->factory->setup(status, context, metadata, inBuilder, outBuilder);
|
status, module->functionsMap, entryPoint);
|
||||||
|
|
||||||
|
factory->setup(status, context, metadata, inBuilder, outBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SharedFunction()
|
~SharedFunction()
|
||||||
@ -235,8 +314,8 @@ public:
|
|||||||
{
|
{
|
||||||
strncpy(name, context->getClientCharSet(), nameSize);
|
strncpy(name, context->getClientCharSet(), nameSize);
|
||||||
|
|
||||||
IExternalFunction* function = engine->getChild<FunctionNode, IExternalFunction>(status,
|
IExternalFunction* function = engine->getChild<IUdrFunctionFactory, IExternalFunction>(
|
||||||
children, this, context, registeredFunctions, engine->functions, moduleName);
|
status, children, this, context, engine->functions, moduleName);
|
||||||
|
|
||||||
if (function)
|
if (function)
|
||||||
function->getCharSet(status, context, name, nameSize);
|
function->getCharSet(status, context, name, nameSize);
|
||||||
@ -244,8 +323,9 @@ public:
|
|||||||
|
|
||||||
void execute(ThrowStatusWrapper* status, IExternalContext* context, void* inMsg, void* outMsg)
|
void execute(ThrowStatusWrapper* status, IExternalContext* context, void* inMsg, void* outMsg)
|
||||||
{
|
{
|
||||||
IExternalFunction* function = engine->getChild<FunctionNode, IExternalFunction>(status,
|
IExternalFunction* function = engine->getChild<IUdrFunctionFactory, IExternalFunction>(
|
||||||
children, this, context, registeredFunctions, engine->functions, moduleName);
|
status, children, this, context, engine->functions, moduleName);
|
||||||
|
|
||||||
if (function)
|
if (function)
|
||||||
function->execute(status, context, inMsg, outMsg);
|
function->execute(status, context, inMsg, outMsg);
|
||||||
}
|
}
|
||||||
@ -257,6 +337,7 @@ public:
|
|||||||
string entryPoint;
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
GenericMap<Pair<NonPooled<IExternalContext*, IExternalFunction*> > > children;
|
GenericMap<Pair<NonPooled<IExternalContext*, IExternalFunction*> > > children;
|
||||||
|
UdrPluginImpl* module;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -276,10 +357,12 @@ public:
|
|||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
||||||
ProcedureNode* node = engine->findNode<ProcedureNode>(
|
|
||||||
status, registeredProcedures, moduleName, entryPoint);
|
IUdrProcedureFactory* factory = engine->findNode<IUdrProcedureFactory>(
|
||||||
node->factory->setup(status, context, metadata, inBuilder, outBuilder);
|
status, module->proceduresMap, entryPoint);
|
||||||
|
|
||||||
|
factory->setup(status, context, metadata, inBuilder, outBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SharedProcedure()
|
~SharedProcedure()
|
||||||
@ -299,8 +382,8 @@ public:
|
|||||||
{
|
{
|
||||||
strncpy(name, context->getClientCharSet(), nameSize);
|
strncpy(name, context->getClientCharSet(), nameSize);
|
||||||
|
|
||||||
IExternalProcedure* procedure = engine->getChild<ProcedureNode, IExternalProcedure>(status,
|
IExternalProcedure* procedure = engine->getChild<IUdrProcedureFactory, IExternalProcedure>(
|
||||||
children, this, context, registeredProcedures, engine->procedures, moduleName);
|
status, children, this, context, engine->procedures, moduleName);
|
||||||
|
|
||||||
if (procedure)
|
if (procedure)
|
||||||
procedure->getCharSet(status, context, name, nameSize);
|
procedure->getCharSet(status, context, name, nameSize);
|
||||||
@ -309,8 +392,8 @@ public:
|
|||||||
IExternalResultSet* open(ThrowStatusWrapper* status, IExternalContext* context,
|
IExternalResultSet* open(ThrowStatusWrapper* status, IExternalContext* context,
|
||||||
void* inMsg, void* outMsg)
|
void* inMsg, void* outMsg)
|
||||||
{
|
{
|
||||||
IExternalProcedure* procedure = engine->getChild<ProcedureNode, IExternalProcedure>(status,
|
IExternalProcedure* procedure = engine->getChild<IUdrProcedureFactory, IExternalProcedure>(
|
||||||
children, this, context, registeredProcedures, engine->procedures, moduleName);
|
status, children, this, context, engine->procedures, moduleName);
|
||||||
|
|
||||||
return procedure ? procedure->open(status, context, inMsg, outMsg) : NULL;
|
return procedure ? procedure->open(status, context, inMsg, outMsg) : NULL;
|
||||||
}
|
}
|
||||||
@ -322,6 +405,7 @@ public:
|
|||||||
string entryPoint;
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
GenericMap<Pair<NonPooled<IExternalContext*, IExternalProcedure*> > > children;
|
GenericMap<Pair<NonPooled<IExternalContext*, IExternalProcedure*> > > children;
|
||||||
|
UdrPluginImpl* module;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -340,12 +424,12 @@ public:
|
|||||||
info(*getDefaultMemoryPool()),
|
info(*getDefaultMemoryPool()),
|
||||||
children(*getDefaultMemoryPool())
|
children(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
|
||||||
|
|
||||||
TriggerNode* node = engine->findNode<TriggerNode>(status,
|
IUdrTriggerFactory* factory = engine->findNode<IUdrTriggerFactory>(
|
||||||
registeredTriggers, moduleName, entryPoint);
|
status, module->triggersMap, entryPoint);
|
||||||
|
|
||||||
node->factory->setup(status, context, metadata, fieldsBuilder);
|
factory->setup(status, context, metadata, fieldsBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SharedTrigger()
|
~SharedTrigger()
|
||||||
@ -365,8 +449,8 @@ public:
|
|||||||
{
|
{
|
||||||
strncpy(name, context->getClientCharSet(), nameSize);
|
strncpy(name, context->getClientCharSet(), nameSize);
|
||||||
|
|
||||||
IExternalTrigger* trigger = engine->getChild<TriggerNode, IExternalTrigger>(status,
|
IExternalTrigger* trigger = engine->getChild<IUdrTriggerFactory, IExternalTrigger>(
|
||||||
children, this, context, registeredTriggers, engine->triggers, moduleName);
|
status, children, this, context, engine->triggers, moduleName);
|
||||||
|
|
||||||
if (trigger)
|
if (trigger)
|
||||||
trigger->getCharSet(status, context, name, nameSize);
|
trigger->getCharSet(status, context, name, nameSize);
|
||||||
@ -375,8 +459,9 @@ public:
|
|||||||
void execute(ThrowStatusWrapper* status, IExternalContext* context,
|
void execute(ThrowStatusWrapper* status, IExternalContext* context,
|
||||||
unsigned action, void* oldMsg, void* newMsg)
|
unsigned action, void* oldMsg, void* newMsg)
|
||||||
{
|
{
|
||||||
IExternalTrigger* trigger = engine->getChild<TriggerNode, IExternalTrigger>(status,
|
IExternalTrigger* trigger = engine->getChild<IUdrTriggerFactory, IExternalTrigger>(
|
||||||
children, this, context, registeredTriggers, engine->triggers, moduleName);
|
status, children, this, context, engine->triggers, moduleName);
|
||||||
|
|
||||||
if (trigger)
|
if (trigger)
|
||||||
trigger->execute(status, context, action, oldMsg, newMsg);
|
trigger->execute(status, context, action, oldMsg, newMsg);
|
||||||
}
|
}
|
||||||
@ -388,68 +473,43 @@ public:
|
|||||||
string entryPoint;
|
string entryPoint;
|
||||||
string info;
|
string info;
|
||||||
GenericMap<Pair<NonPooled<IExternalContext*, IExternalTrigger*> > > children;
|
GenericMap<Pair<NonPooled<IExternalContext*, IExternalTrigger*> > > children;
|
||||||
|
UdrPluginImpl* module;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|
||||||
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegFunction(const char* name, IUdrFunctionFactory* factory)
|
template <typename FactoryType> GenericMap<Pair<Left<string, FactoryType*> > >& getFactoryMap(
|
||||||
|
UdrPluginImpl* udrPlugin)
|
||||||
{
|
{
|
||||||
FunctionNode* node = new FunctionNode();
|
fb_assert(false);
|
||||||
node->name = name;
|
}
|
||||||
node->module = loadingModule();
|
|
||||||
node->factory = factory;
|
template <> GenericMap<Pair<Left<string, IUdrFunctionFactory*> > >& getFactoryMap(
|
||||||
node->next = registeredFunctions;
|
UdrPluginImpl* udrPlugin)
|
||||||
registeredFunctions = node;
|
{
|
||||||
|
return udrPlugin->functionsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> GenericMap<Pair<Left<string, IUdrProcedureFactory*> > >& getFactoryMap(
|
||||||
|
UdrPluginImpl* udrPlugin)
|
||||||
|
{
|
||||||
|
return udrPlugin->proceduresMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> GenericMap<Pair<Left<string, IUdrTriggerFactory*> > >& getFactoryMap(
|
||||||
|
UdrPluginImpl* udrPlugin)
|
||||||
|
{
|
||||||
|
return udrPlugin->triggersMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegProcedure(const char* name, IUdrProcedureFactory* factory)
|
//--------------------------------------
|
||||||
{
|
|
||||||
ProcedureNode* node = new ProcedureNode();
|
|
||||||
node->name = name;
|
|
||||||
node->module = loadingModule();
|
|
||||||
node->factory = factory;
|
|
||||||
node->next = registeredProcedures;
|
|
||||||
registeredProcedures = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void FB_EXPORTED fbUdrRegTrigger(const char* name, IUdrTriggerFactory* factory)
|
|
||||||
{
|
|
||||||
TriggerNode* node = new TriggerNode();
|
|
||||||
node->name = name;
|
|
||||||
node->module = loadingModule();
|
|
||||||
node->factory = factory;
|
|
||||||
node->next = registeredTriggers;
|
|
||||||
registeredTriggers = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ModulesMap::~ModulesMap()
|
ModulesMap::~ModulesMap()
|
||||||
{
|
{
|
||||||
while (registeredFunctions)
|
|
||||||
{
|
|
||||||
FunctionNode* del = registeredFunctions;
|
|
||||||
registeredFunctions = registeredFunctions->next;
|
|
||||||
delete del;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (registeredProcedures)
|
|
||||||
{
|
|
||||||
ProcedureNode* del = registeredProcedures;
|
|
||||||
registeredProcedures = registeredProcedures->next;
|
|
||||||
delete del;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (registeredTriggers)
|
|
||||||
{
|
|
||||||
TriggerNode* del = registeredTriggers;
|
|
||||||
registeredTriggers = registeredTriggers->next;
|
|
||||||
delete del;
|
|
||||||
}
|
|
||||||
|
|
||||||
Accessor accessor(this);
|
Accessor accessor(this);
|
||||||
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
|
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
|
||||||
delete accessor.current()->second;
|
delete accessor.current()->second;
|
||||||
@ -459,7 +519,7 @@ ModulesMap::~ModulesMap()
|
|||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
UdrPluginImpl* Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
||||||
PathName* moduleName, string* entryPoint)
|
PathName* moduleName, string* entryPoint)
|
||||||
{
|
{
|
||||||
const string str(metadata->getEntryPoint(status));
|
const string str(metadata->getEntryPoint(status));
|
||||||
@ -468,9 +528,9 @@ void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
|||||||
if (pos == string::npos)
|
if (pos == string::npos)
|
||||||
{
|
{
|
||||||
static const ISC_STATUS statusVector[] = {
|
static const ISC_STATUS statusVector[] = {
|
||||||
isc_arg_gds,
|
isc_arg_gds, isc_random,
|
||||||
isc_random,
|
|
||||||
isc_arg_string, (ISC_STATUS) "Invalid entry point",
|
isc_arg_string, (ISC_STATUS) "Invalid entry point",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) entryPoint.c_str(),
|
||||||
isc_arg_end
|
isc_arg_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -482,9 +542,9 @@ void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
|||||||
if (moduleName->find_first_of("/\\") != string::npos)
|
if (moduleName->find_first_of("/\\") != string::npos)
|
||||||
{
|
{
|
||||||
static const ISC_STATUS statusVector[] = {
|
static const ISC_STATUS statusVector[] = {
|
||||||
isc_arg_gds,
|
isc_arg_gds, isc_random,
|
||||||
isc_random,
|
|
||||||
isc_arg_string, (ISC_STATUS) "Invalid module name",
|
isc_arg_string, (ISC_STATUS) "Invalid module name",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) moduleName->c_str(),
|
||||||
isc_arg_end
|
isc_arg_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -498,10 +558,10 @@ void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
|||||||
|
|
||||||
MutexLockGuard guard(modulesMutex, FB_FUNCTION);
|
MutexLockGuard guard(modulesMutex, FB_FUNCTION);
|
||||||
|
|
||||||
if (modules->exist(*moduleName))
|
UdrPluginImpl* ret;
|
||||||
return;
|
|
||||||
|
|
||||||
loadingModule() = *moduleName;
|
if (modules->get(*moduleName, ret))
|
||||||
|
return ret;
|
||||||
|
|
||||||
for (ObjectsArray<PathName>::iterator i = paths->begin(); i != paths->end(); ++i)
|
for (ObjectsArray<PathName>::iterator i = paths->begin(); i != paths->end(); ++i)
|
||||||
{
|
{
|
||||||
@ -512,27 +572,59 @@ void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
|
|||||||
|
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
modules->put(*moduleName, module);
|
FB_BOOLEAN* (*entryPoint)(IStatus*, FB_BOOLEAN*, IUdrPlugin*);
|
||||||
break;
|
|
||||||
|
if (!module->findSymbol(STRINGIZE(FB_UDR_PLUGIN_ENTRY_POINT), entryPoint))
|
||||||
|
{
|
||||||
|
static const ISC_STATUS statusVector[] = {
|
||||||
|
isc_arg_gds, isc_random,
|
||||||
|
isc_arg_string, (ISC_STATUS) "UDR plugin entry point not found",
|
||||||
|
isc_arg_end
|
||||||
|
};
|
||||||
|
|
||||||
|
throw FbException(status, statusVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
UdrPluginImpl* udrPlugin = new UdrPluginImpl(*moduleName, module);
|
||||||
|
udrPlugin->theirUnloadFlag = entryPoint(status, &udrPlugin->myUnloadFlag, udrPlugin);
|
||||||
|
|
||||||
|
if (status->getStatus() & IStatus::FB_HAS_ERRORS)
|
||||||
|
{
|
||||||
|
delete udrPlugin;
|
||||||
|
ThrowStatusWrapper::checkException(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
modules->put(*moduleName, udrPlugin);
|
||||||
|
|
||||||
|
return udrPlugin;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const ISC_STATUS statusVector[] = {
|
static const ISC_STATUS statusVector[] = {
|
||||||
isc_arg_gds,
|
isc_arg_gds, isc_random,
|
||||||
isc_random,
|
|
||||||
isc_arg_string, (ISC_STATUS) "Module not found",
|
isc_arg_string, (ISC_STATUS) "Module not found",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) moduleName->c_str(),
|
||||||
isc_arg_end
|
isc_arg_end
|
||||||
};
|
};
|
||||||
|
|
||||||
throw FbException(status, statusVector);
|
throw FbException(status, statusVector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const ISC_STATUS statusVector[] = {
|
||||||
|
isc_arg_gds, isc_random,
|
||||||
|
isc_arg_string, (ISC_STATUS) "No UDR module path was configured",
|
||||||
|
isc_arg_end
|
||||||
|
};
|
||||||
|
|
||||||
|
throw FbException(status, statusVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* Engine::getChild(
|
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* Engine::getChild(
|
||||||
ThrowStatusWrapper* status, GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
|
ThrowStatusWrapper* status,
|
||||||
SharedObjType* sharedObj, IExternalContext* context, NodeType* nodes,
|
GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children, SharedObjType* sharedObj,
|
||||||
|
IExternalContext* context,
|
||||||
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName)
|
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName)
|
||||||
{
|
{
|
||||||
MutexLockGuard guard(childrenMutex, FB_FUNCTION);
|
MutexLockGuard guard(childrenMutex, FB_FUNCTION);
|
||||||
@ -543,8 +635,11 @@ 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>(status, nodes, moduleName, context, sharedObj->metadata,
|
GenericMap<Pair<Left<string, NodeType*> > >& nodes = getFactoryMap<NodeType>(
|
||||||
sharedObj->entryPoint);
|
sharedObj->module);
|
||||||
|
|
||||||
|
NodeType* factory = findNode<NodeType>(status, nodes, sharedObj->entryPoint);
|
||||||
|
obj = factory->newItem(status, context, sharedObj->metadata);
|
||||||
|
|
||||||
if (obj)
|
if (obj)
|
||||||
children.put(context, obj);
|
children.put(context, obj);
|
||||||
@ -567,19 +662,18 @@ template <typename ObjType> void Engine::deleteChildren(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T> T* Engine::findNode(ThrowStatusWrapper* status, T* nodes,
|
template <typename T> T* Engine::findNode(ThrowStatusWrapper* status,
|
||||||
const PathName& moduleName, const string& entryPoint)
|
const GenericMap<Pair<Left<string, T*> > >& nodes, const string& entryPoint)
|
||||||
{
|
{
|
||||||
for (T* node = nodes; node; node = node->next)
|
T* factory;
|
||||||
{
|
|
||||||
if (node->module == moduleName && entryPoint == node->name)
|
if (nodes.get(entryPoint, factory))
|
||||||
return node;
|
return factory;
|
||||||
}
|
|
||||||
|
|
||||||
static const ISC_STATUS statusVector[] = {
|
static const ISC_STATUS statusVector[] = {
|
||||||
isc_arg_gds,
|
isc_arg_gds, isc_random,
|
||||||
isc_random,
|
|
||||||
isc_arg_string, (ISC_STATUS) "Entry point not found",
|
isc_arg_string, (ISC_STATUS) "Entry point not found",
|
||||||
|
//// TODO: isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) entryPoint.c_str(),
|
||||||
isc_arg_end
|
isc_arg_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -589,15 +683,6 @@ template <typename T> T* Engine::findNode(ThrowStatusWrapper* status, T* nodes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename T2> T2* Engine::getNode(ThrowStatusWrapper* status, T* nodes,
|
|
||||||
const PathName& moduleName, IExternalContext* context, IRoutineMetadata* metadata,
|
|
||||||
const string& entryPoint)
|
|
||||||
{
|
|
||||||
T* node = findNode<T>(status, nodes, moduleName, entryPoint);
|
|
||||||
return node->factory->newItem(status, context, metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Engine::open(ThrowStatusWrapper* /*status*/, IExternalContext* /*context*/, char* name, unsigned nameSize)
|
void Engine::open(ThrowStatusWrapper* /*status*/, IExternalContext* /*context*/, char* name, unsigned nameSize)
|
||||||
{
|
{
|
||||||
strncpy(name, "UTF-8", nameSize);
|
strncpy(name, "UTF-8", nameSize);
|
||||||
|
Loading…
Reference in New Issue
Block a user