|
From: <asf...@us...> - 2015-01-25 20:27:56
|
Revision: 60551
http://sourceforge.net/p/firebird/code/60551
Author: asfernandes
Date: 2015-01-25 20:27:46 +0000 (Sun, 25 Jan 2015)
Log Message:
-----------
Improvements to the UDR plugin.
Modified Paths:
--------------
firebird/trunk/builds/posix/Makefile.in.plugins_examples
firebird/trunk/builds/win32/msvc10/udrcpp_example.vcxproj
firebird/trunk/builds/win32/msvc12/udrcpp_example.vcxproj
firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln
firebird/trunk/examples/udr/UdrCppExample.cpp
firebird/trunk/src/include/firebird/FirebirdInterface.idl
firebird/trunk/src/include/firebird/IdlFbInterfaces.h
firebird/trunk/src/include/firebird/Interface.h
firebird/trunk/src/include/firebird/UdrCppEngine.h
firebird/trunk/src/plugins/udr_engine/UdrEngine.cpp
Removed Paths:
-------------
firebird/trunk/src/include/firebird/UdrEngine.h
Modified: firebird/trunk/builds/posix/Makefile.in.plugins_examples
===================================================================
--- firebird/trunk/builds/posix/Makefile.in.plugins_examples 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/builds/posix/Makefile.in.plugins_examples 2015-01-25 20:27:46 UTC (rev 60551)
@@ -67,7 +67,7 @@
$(FIREBIRD_LIBRARY_LINK)
else
$(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)
endif
Modified: firebird/trunk/builds/win32/msvc10/udrcpp_example.vcxproj
===================================================================
--- firebird/trunk/builds/win32/msvc10/udrcpp_example.vcxproj 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/builds/win32/msvc10/udrcpp_example.vcxproj 2015-01-25 20:27:46 UTC (rev 60551)
@@ -207,13 +207,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
</ResourceCompile>
</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" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
Modified: firebird/trunk/builds/win32/msvc12/udrcpp_example.vcxproj
===================================================================
--- firebird/trunk/builds/win32/msvc12/udrcpp_example.vcxproj 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/builds/win32/msvc12/udrcpp_example.vcxproj 2015-01-25 20:27:46 UTC (rev 60551)
@@ -211,13 +211,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\src\jrd</AdditionalIncludeDirectories>
</ResourceCompile>
</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" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
Modified: firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln
===================================================================
--- firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln 2015-01-25 20:27:46 UTC (rev 60551)
@@ -12,7 +12,6 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udrcpp_example", "udrcpp_example.vcproj", "{FF0FD8DF-1E5C-486E-B395-A620376A4633}"
ProjectSection(ProjectDependencies) = postProject
- {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B} = {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}
{4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
EndProjectSection
EndProject
Modified: firebird/trunk/examples/udr/UdrCppExample.cpp
===================================================================
--- firebird/trunk/examples/udr/UdrCppExample.cpp 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/examples/udr/UdrCppExample.cpp 2015-01-25 20:27:46 UTC (rev 60551)
@@ -783,3 +783,6 @@
AutoRelease<IMessageMetadata> triggerMetadata;
AutoRelease<IStatement> stmt;
FB_UDR_END_TRIGGER
+
+
+FB_UDR_IMPLEMENT_ENTRY_POINT
Modified: firebird/trunk/src/include/firebird/FirebirdInterface.idl
===================================================================
--- firebird/trunk/src/include/firebird/FirebirdInterface.idl 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/include/firebird/FirebirdInterface.idl 2015-01-25 20:27:46 UTC (rev 60551)
@@ -1216,23 +1216,32 @@
// 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.
-interface UdrFunctionFactory : Versioned
+interface UdrFunctionFactory : Disposable
{
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
ExternalFunction newItem(Status status, ExternalContext context, RoutineMetadata metadata);
}
-interface UdrProcedureFactory : Versioned
+interface UdrProcedureFactory : Disposable
{
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
MetadataBuilder inBuilder, MetadataBuilder outBuilder);
ExternalProcedure newItem(Status status, ExternalContext context, RoutineMetadata metadata);
}
-interface UdrTriggerFactory : Versioned
+interface UdrTriggerFactory : Disposable
{
void setup(Status status, ExternalContext context, RoutineMetadata metadata,
MetadataBuilder fieldsBuilder);
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);
+}
Modified: firebird/trunk/src/include/firebird/IdlFbInterfaces.h
===================================================================
--- firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2015-01-25 20:27:46 UTC (rev 60551)
@@ -3,6 +3,8 @@
#ifndef IDL_FB_INTERFACES_H
#define IDL_FB_INTERFACES_H
+#include <stdint.h>
+
#ifndef CLOOP_CARG
#define CLOOP_CARG
#endif
@@ -106,6 +108,7 @@
class IUdrFunctionFactory;
class IUdrProcedureFactory;
class IUdrTriggerFactory;
+ class IUdrPlugin;
// Interfaces declarations
@@ -4401,10 +4404,10 @@
}
};
- class IUdrFunctionFactory : public IVersioned
+ class IUdrFunctionFactory : public IDisposable
{
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();
IExternalFunction* (CLOOP_CARG *newItem)(IUdrFunctionFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
@@ -4412,7 +4415,7 @@
protected:
IUdrFunctionFactory(DoNotInherit)
- : IVersioned(DoNotInherit())
+ : IDisposable(DoNotInherit())
{
}
@@ -4421,7 +4424,7 @@
}
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)
{
@@ -4437,10 +4440,10 @@
}
};
- class IUdrProcedureFactory : public IVersioned
+ class IUdrProcedureFactory : public IDisposable
{
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();
IExternalProcedure* (CLOOP_CARG *newItem)(IUdrProcedureFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
@@ -4448,7 +4451,7 @@
protected:
IUdrProcedureFactory(DoNotInherit)
- : IVersioned(DoNotInherit())
+ : IDisposable(DoNotInherit())
{
}
@@ -4457,7 +4460,7 @@
}
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)
{
@@ -4473,10 +4476,10 @@
}
};
- class IUdrTriggerFactory : public IVersioned
+ class IUdrTriggerFactory : public IDisposable
{
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();
IExternalTrigger* (CLOOP_CARG *newItem)(IUdrTriggerFactory* self, IStatus* status, IExternalContext* context, IRoutineMetadata* metadata) throw();
@@ -4484,7 +4487,7 @@
protected:
IUdrTriggerFactory(DoNotInherit)
- : IVersioned(DoNotInherit())
+ : IDisposable(DoNotInherit())
{
}
@@ -4493,7 +4496,7 @@
}
public:
- static const unsigned VERSION = 2;
+ static const unsigned VERSION = 3;
template <typename StatusType> void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder)
{
@@ -4509,6 +4512,55 @@
}
};
+ 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
template <typename Name, typename StatusType, typename Base>
@@ -14377,6 +14429,7 @@
VTableImpl()
{
this->version = Base::VERSION;
+ this->dispose = &Name::cloopdisposeDispatcher;
this->setup = &Name::cloopsetupDispatcher;
this->newItem = &Name::cloopnewItemDispatcher;
}
@@ -14413,9 +14466,21 @@
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>
{
protected:
@@ -14445,6 +14510,7 @@
VTableImpl()
{
this->version = Base::VERSION;
+ this->dispose = &Name::cloopdisposeDispatcher;
this->setup = &Name::cloopsetupDispatcher;
this->newItem = &Name::cloopnewItemDispatcher;
}
@@ -14481,9 +14547,21 @@
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>
{
protected:
@@ -14513,6 +14591,7 @@
VTableImpl()
{
this->version = Base::VERSION;
+ this->dispose = &Name::cloopdisposeDispatcher;
this->setup = &Name::cloopsetupDispatcher;
this->newItem = &Name::cloopnewItemDispatcher;
}
@@ -14549,9 +14628,21 @@
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>
{
protected:
@@ -14567,6 +14658,104 @@
virtual void setup(StatusType* status, IExternalContext* context, IRoutineMetadata* metadata, IMetadataBuilder* fieldsBuilder) = 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;
+ };
};
Modified: firebird/trunk/src/include/firebird/Interface.h
===================================================================
--- firebird/trunk/src/include/firebird/Interface.h 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/include/firebird/Interface.h 2015-01-25 20:27:46 UTC (rev 60551)
@@ -239,5 +239,6 @@
} // namespace Firebird
#define FB_PLUGIN_ENTRY_POINT firebird_plugin
+#define FB_UDR_PLUGIN_ENTRY_POINT firebird_udr_plugin
#endif // FB_INTERFACE_H
Modified: firebird/trunk/src/include/firebird/UdrCppEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrCppEngine.h 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/include/firebird/UdrCppEngine.h 2015-01-25 20:27:46 UTC (rev 60551)
@@ -27,20 +27,51 @@
#error FB_UDR_STATUS_TYPE must be defined with the Status class before UdrCppEngine.h inclusion.
#endif
-#include "./UdrEngine.h"
#include "./Message.h"
-#ifndef JRD_IBASE_H
-#include "ibase.h"
-#include "iberror.h"
-#endif
#include <string.h>
-namespace Firebird
-{
- namespace Udr
- {
-//------------------------------------------------------------------------------
+#define FB_UDR_IMPLEMENT_ENTRY_POINT \
+ namespace Firebird \
+ { \
+ 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) \
@@ -176,6 +207,13 @@
}
+namespace Firebird
+{
+ namespace Udr
+ {
+//------------------------------------------------------------------------------
+
+
template <typename T, typename StatusType> class Procedure;
@@ -311,15 +349,78 @@
};
+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 :
public IUdrFunctionFactoryImpl<FunctionFactoryImpl<T, StatusType>, StatusType>
{
public:
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*/,
IRoutineMetadata* /*metadata*/, IMetadataBuilder* in, IMetadataBuilder* out)
{
@@ -341,9 +442,14 @@
public:
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*/,
IRoutineMetadata* /*metadata*/, IMetadataBuilder* in, IMetadataBuilder* out)
{
@@ -365,9 +471,14 @@
public:
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*/,
IRoutineMetadata* /*metadata*/, IMetadataBuilder* fields)
{
Deleted: firebird/trunk/src/include/firebird/UdrEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrEngine.h 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/include/firebird/UdrEngine.h 2015-01-25 20:27:46 UTC (rev 60551)
@@ -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 <adr...@uo...>
- * 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
Modified: firebird/trunk/src/plugins/udr_engine/UdrEngine.cpp
===================================================================
--- firebird/trunk/src/plugins/udr_engine/UdrEngine.cpp 2015-01-25 20:27:18 UTC (rev 60550)
+++ firebird/trunk/src/plugins/udr_engine/UdrEngine.cpp 2015-01-25 20:27:46 UTC (rev 60551)
@@ -22,7 +22,6 @@
#include "firebird.h"
#include "../jrd/ibase.h"
-#include "firebird/UdrEngine.h"
#include "firebird/Interface.h"
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
@@ -43,37 +42,9 @@
//------------------------------------------------------------------------------
-struct Node
-{
- Node()
- : name(*getDefaultMemoryPool()),
- module(*getDefaultMemoryPool())
- {
- }
+class UdrPluginImpl;
- 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;
class Engine : public StdPlugin<IExternalEngineImpl<Engine, ThrowStatusWrapper> >
@@ -129,25 +100,21 @@
}
public:
- void loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
+ UdrPluginImpl* loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
PathName* moduleName, string* entryPoint);
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
- ThrowStatusWrapper* status, GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
- SharedObjType* sharedObj, IExternalContext* context, NodeType* nodes,
+ ThrowStatusWrapper* status,
+ GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
+ SharedObjType* sharedObj, IExternalContext* context,
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName);
template <typename ObjType> void deleteChildren(
GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children);
- template <typename T> T* findNode(ThrowStatusWrapper* status, T* nodes,
- const PathName& moduleName, const string& entryPoint);
+ template <typename T> T* findNode(ThrowStatusWrapper* status,
+ 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:
void open(ThrowStatusWrapper* status, IExternalContext* context, char* name, unsigned nameSize);
void openAttachment(ThrowStatusWrapper* status, IExternalContext* context);
@@ -172,11 +139,11 @@
};
-class ModulesMap : public GenericMap<Pair<Left<PathName, ModuleLoader::Module*> > >
+class ModulesMap : public GenericMap<Pair<Left<PathName, UdrPluginImpl*> > >
{
public:
explicit ModulesMap(MemoryPool& p)
- : GenericMap<Pair<Left<PathName, ModuleLoader::Module*> > >(p)
+ : GenericMap<Pair<Left<PathName, UdrPluginImpl*> > >(p)
{
}
@@ -190,15 +157,125 @@
static GlobalPtr<Mutex> modulesMutex;
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> >
{
public:
@@ -212,10 +289,12 @@
info(*getDefaultMemoryPool()),
children(*getDefaultMemoryPool())
{
- engine->loadModule(status, metadata, &moduleName, &entryPoint);
- FunctionNode* node = engine->findNode<FunctionNode>(
- status, registeredFunctions, moduleName, entryPoint);
- node->factory->setup(status, context, metadata, inBuilder, outBuilder);
+ module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
+
+ IUdrFunctionFactory* factory = engine->findNode<IUdrFunctionFactory>(
+ status, module->functionsMap, entryPoint);
+
+ factory->setup(status, context, metadata, inBuilder, outBuilder);
}
~SharedFunction()
@@ -235,8 +314,8 @@
{
strncpy(name, context->getClientCharSet(), nameSize);
- IExternalFunction* function = engine->getChild<FunctionNode, IExternalFunction>(status,
- children, this, context, registeredFunctions, engine->functions, moduleName);
+ IExternalFunction* function = engine->getChild<IUdrFunctionFactory, IExternalFunction>(
+ status, children, this, context, engine->functions, moduleName);
if (function)
function->getCharSet(status, context, name, nameSize);
@@ -244,8 +323,9 @@
void execute(ThrowStatusWrapper* status, IExternalContext* context, void* inMsg, void* outMsg)
{
- IExternalFunction* function = engine->getChild<FunctionNode, IExternalFunction>(status,
- children, this, context, registeredFunctions, engine->functions, moduleName);
+ IExternalFunction* function = engine->getChild<IUdrFunctionFactory, IExternalFunction>(
+ status, children, this, context, engine->functions, moduleName);
+
if (function)
function->execute(status, context, inMsg, outMsg);
}
@@ -257,6 +337,7 @@
string entryPoint;
string info;
GenericMap<Pair<NonPooled<IExternalContext*, IExternalFunction*> > > children;
+ UdrPluginImpl* module;
};
@@ -276,10 +357,12 @@
info(*getDefaultMemoryPool()),
children(*getDefaultMemoryPool())
{
- engine->loadModule(status, metadata, &moduleName, &entryPoint);
- ProcedureNode* node = engine->findNode<ProcedureNode>(
- status, registeredProcedures, moduleName, entryPoint);
- node->factory->setup(status, context, metadata, inBuilder, outBuilder);
+ module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
+
+ IUdrProcedureFactory* factory = engine->findNode<IUdrProcedureFactory>(
+ status, module->proceduresMap, entryPoint);
+
+ factory->setup(status, context, metadata, inBuilder, outBuilder);
}
~SharedProcedure()
@@ -299,8 +382,8 @@
{
strncpy(name, context->getClientCharSet(), nameSize);
- IExternalProcedure* procedure = engine->getChild<ProcedureNode, IExternalProcedure>(status,
- children, this, context, registeredProcedures, engine->procedures, moduleName);
+ IExternalProcedure* procedure = engine->getChild<IUdrProcedureFactory, IExternalProcedure>(
+ status, children, this, context, engine->procedures, moduleName);
if (procedure)
procedure->getCharSet(status, context, name, nameSize);
@@ -309,8 +392,8 @@
IExternalResultSet* open(ThrowStatusWrapper* status, IExternalContext* context,
void* inMsg, void* outMsg)
{
- IExternalProcedure* procedure = engine->getChild<ProcedureNode, IExternalProcedure>(status,
- children, this, context, registeredProcedures, engine->procedures, moduleName);
+ IExternalProcedure* procedure = engine->getChild<IUdrProcedureFactory, IExternalProcedure>(
+ status, children, this, context, engine->procedures, moduleName);
return procedure ? procedure->open(status, context, inMsg, outMsg) : NULL;
}
@@ -322,6 +405,7 @@
string entryPoint;
string info;
GenericMap<Pair<NonPooled<IExternalContext*, IExternalProcedure*> > > children;
+ UdrPluginImpl* module;
};
@@ -340,12 +424,12 @@
info(*getDefaultMemoryPool()),
children(*getDefaultMemoryPool())
{
- engine->loadModule(status, metadata, &moduleName, &entryPoint);
+ module = engine->loadModule(status, metadata, &moduleName, &entryPoint);
- TriggerNode* node = engine->findNode<TriggerNode>(status,
- registeredTriggers, moduleName, entryPoint);
+ IUdrTriggerFactory* factory = engine->findNode<IUdrTriggerFactory>(
+ status, module->triggersMap, entryPoint);
- node->factory->setup(status, context, metadata, fieldsBuilder);
+ factory->setup(status, context, metadata, fieldsBuilder);
}
~SharedTrigger()
@@ -365,8 +449,8 @@
{
strncpy(name, context->getClientCharSet(), nameSize);
- IExternalTrigger* trigger = engine->getChild<TriggerNode, IExternalTrigger>(status,
- children, this, context, registeredTriggers, engine->triggers, moduleName);
+ IExternalTrigger* trigger = engine->getChild<IUdrTriggerFactory, IExternalTrigger>(
+ status, children, this, context, engine->triggers, moduleName);
if (trigger)
trigger->getCharSet(status, context, name, nameSize);
@@ -375,8 +459,9 @@
void execute(ThrowStatusWrapper* status, IExternalContext* context,
unsigned action, void* oldMsg, void* newMsg)
{
- IExternalTrigger* trigger = engine->getChild<TriggerNode, IExternalTrigger>(status,
- children, this, context, registeredTriggers, engine->triggers, moduleName);
+ IExternalTrigger* trigger = engine->getChild<IUdrTriggerFactory, IExternalTrigger>(
+ status, children, this, context, engine->triggers, moduleName);
+
if (trigger)
trigger->execute(status, context, action, oldMsg, newMsg);
}
@@ -388,68 +473,43 @@
string entryPoint;
string info;
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();
- node->name = name;
- node->module = loadingModule();
- node->factory = factory;
- node->next = registeredFunctions;
- registeredFunctions = node;
+ fb_assert(false);
}
+template <> GenericMap<Pair<Left<string, IUdrFunctionFactory*> > >& getFactoryMap(
+ UdrPluginImpl* udrPlugin)
+{
+ return udrPlugin->functionsMap;
+}
-extern "C" void FB_EXPORTED fbUdrRegProcedure(const char* name, IUdrProcedureFactory* factory)
+template <> GenericMap<Pair<Left<string, IUdrProcedureFactory*> > >& getFactoryMap(
+ UdrPluginImpl* udrPlugin)
{
- ProcedureNode* node = new ProcedureNode();
- node->name = name;
- node->module = loadingModule();
- node->factory = factory;
- node->next = registeredProcedures;
- registeredProcedures = node;
+ return udrPlugin->proceduresMap;
}
-
-extern "C" void FB_EXPORTED fbUdrRegTrigger(const char* name, IUdrTriggerFactory* factory)
+template <> GenericMap<Pair<Left<string, IUdrTriggerFactory*> > >& getFactoryMap(
+ UdrPluginImpl* udrPlugin)
{
- TriggerNode* node = new TriggerNode();
- node->name = name;
- node->module = loadingModule();
- node->factory = factory;
- node->next = registeredTriggers;
- registeredTriggers = node;
+ return udrPlugin->triggersMap;
}
+//--------------------------------------
+
+
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);
for (bool cont = accessor.getFirst(); cont; cont = accessor.getNext())
delete accessor.current()->second;
@@ -459,7 +519,7 @@
//--------------------------------------
-void Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
+UdrPluginImpl* Engine::loadModule(ThrowStatusWrapper* status, IRoutineMetadata* metadata,
PathName* moduleName, string* entryPoint)
{
const string str(metadata->getEntryPoint(status));
@@ -468,9 +528,9 @@
if (pos == string::npos)
{
static const ISC_STATUS statusVector[] = {
- isc_arg_gds,
- isc_random,
+ isc_arg_gds, isc_random,
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
};
@@ -482,9 +542,9 @@
if (moduleName->find_first_of("/\\") != string::npos)
{
static const ISC_STATUS statusVector[] = {
- isc_arg_gds,
- isc_random,
+ isc_arg_gds, isc_random,
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
};
@@ -498,10 +558,10 @@
MutexLockGuard guard(modulesMutex, FB_FUNCTION);
- if (modules->exist(*moduleName))
- return;
+ UdrPluginImpl* ret;
- loadingModule() = *moduleName;
+ if (modules->get(*moduleName, ret))
+ return ret;
for (ObjectsArray<PathName>::iterator i = paths->begin(); i != paths->end(); ++i)
{
@@ -512,27 +572,59 @@
if (module)
{
- modules->put(*moduleName, module);
- break;
+ FB_BOOLEAN* (*entryPoint)(IStatus*, FB_BOOLEAN*, IUdrPlugin*);
+
+ 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
{
static const ISC_STATUS statusVector[] = {
- isc_arg_gds,
- isc_random,
+ isc_arg_gds, isc_random,
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
};
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(
- ThrowStatusWrapper* status, GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children,
- SharedObjType* sharedObj, IExternalContext* context, NodeType* nodes,
+ ThrowStatusWrapper* status,
+ GenericMap<Pair<NonPooled<IExternalContext*, ObjType*> > >& children, SharedObjType* sharedObj,
+ IExternalContext* context,
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName)
{
MutexLockGuard guard(childrenMutex, FB_FUNCTION);
@@ -543,9 +635,12 @@
ObjType* obj;
if (!children.get(context, obj))
{
- obj = getNode<NodeType, ObjType>(status, nodes, moduleName, context, sharedObj->metadata,
- sharedObj->entryPoint);
+ GenericMap<Pair<Left<string, NodeType*> > >& nodes = getFactoryMap<NodeType>(
+ sharedObj->module);
+ NodeType* factory = findNode<NodeType>(status, nodes, sharedObj->entryPoint);
+ obj = factory->newItem(status, context, sharedObj->metadata);
+
if (obj)
children.put(context, obj);
}
@@ -567,19 +662,18 @@
}
-template <typename T> T* Engine::findNode(ThrowStatusWrapper* status, T* nodes,
- const PathName& moduleName, const string& entryPoint)
+template <typename T> T* Engine::findNode(ThrowStatusWrapper* status,
+ const GenericMap<Pair<Left<string, T*> > >& nodes, const string& entryPoint)
{
- for (T* node = nodes; node; node = node->next)
- {
- if (node->module == moduleName && entryPoint == node->name)
- return node;
- }
+ T* factory;
+ if (nodes.get(entryPoint, factory))
+ return factory;
+
static const ISC_STATUS statusVector[] = {
- isc_arg_gds,
- isc_random,
+ isc_arg_gds, isc_random,
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
};
@@ -589,15 +683,6 @@
}
-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)
{
strncpy(name, "UTF-8", nameSize);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|