|
From: <asf...@us...> - 2011-06-01 01:45:03
|
Revision: 53068
http://firebird.svn.sourceforge.net/firebird/?rev=53068&view=rev
Author: asfernandes
Date: 2011-06-01 01:44:54 +0000 (Wed, 01 Jun 2011)
Log Message:
-----------
Work in progress on the external engines API changes.
Modified Paths:
--------------
firebird/trunk/builds/posix/Makefile.in.plugins_examples
firebird/trunk/builds/win32/msvc10/engine.vcxproj
firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters
firebird/trunk/builds/win32/msvc8/engine.vcproj
firebird/trunk/builds/win32/msvc9/engine.vcproj
firebird/trunk/examples/udr/UdrCppExample.cpp
firebird/trunk/src/common/dsc.cpp
firebird/trunk/src/common/dsc.h
firebird/trunk/src/dsql/dsql.cpp
firebird/trunk/src/include/FirebirdApi.h
firebird/trunk/src/include/FirebirdExternalApi.h
firebird/trunk/src/include/FirebirdUdrCpp.h
firebird/trunk/src/jrd/ExtEngineManager.cpp
firebird/trunk/src/jrd/ExtEngineManager.h
firebird/trunk/src/jrd/Function.epp
firebird/trunk/src/jrd/cmp.cpp
firebird/trunk/src/jrd/exe.cpp
firebird/trunk/src/jrd/req.h
firebird/trunk/src/plugins/udr_engine/UdrEngine.cpp
firebird/trunk/src/yvalve/YObjects.h
Removed Paths:
-------------
firebird/trunk/src/jrd/ValueImpl.cpp
firebird/trunk/src/jrd/ValueImpl.h
firebird/trunk/src/jrd/ValuesImpl.cpp
firebird/trunk/src/jrd/ValuesImpl.h
Modified: firebird/trunk/builds/posix/Makefile.in.plugins_examples
===================================================================
--- firebird/trunk/builds/posix/Makefile.in.plugins_examples 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/builds/posix/Makefile.in.plugins_examples 2011-06-01 01:44:54 UTC (rev 53068)
@@ -59,10 +59,12 @@
$(PLUGINS)/udr/$(LIB_PREFIX)udrcpp_example.$(SHRLIB_EXT): $(UDR_Objects)
ifeq ($(PLATFORM),DARWIN)
- $(LIB_LINK) $(LIB_BUNDLE_OPTIONS) -o $@ $^ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+ $(LIB_LINK) $(LIB_BUNDLE_OPTIONS) -o $@ $^ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ \
+ $(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) $(PLUGINS)/$(LIB_PREFIX)udr_engine.$(SHRLIB_EXT) \
+ $(FIREBIRD_LIBRARY_LINK)
endif
include $(ROOT)/gen/make.shared.targets
Modified: firebird/trunk/builds/win32/msvc10/engine.vcxproj
===================================================================
--- firebird/trunk/builds/win32/msvc10/engine.vcxproj 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/builds/win32/msvc10/engine.vcxproj 2011-06-01 01:44:54 UTC (rev 53068)
@@ -153,8 +153,6 @@
<ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp" />
<ClCompile Include="..\..\..\src\jrd\UserManagement.cpp" />
<ClCompile Include="..\..\..\src\jrd\validation.cpp" />
- <ClCompile Include="..\..\..\src\jrd\ValueImpl.cpp" />
- <ClCompile Include="..\..\..\src\jrd\ValuesImpl.cpp" />
<ClCompile Include="..\..\..\src\jrd\vio.cpp" />
<ClCompile Include="..\..\..\src\jrd\VirtualTable.cpp" />
<ClCompile Include="..\..\..\src\lock\lock.cpp" />
@@ -339,8 +337,6 @@
<ClInclude Include="..\..\..\src\jrd\types.h" />
<ClInclude Include="..\..\..\src\jrd\UserManagement.h" />
<ClInclude Include="..\..\..\src\jrd\val.h" />
- <ClInclude Include="..\..\..\src\jrd\ValueImpl.h" />
- <ClInclude Include="..\..\..\src\jrd\ValuesImpl.h" />
<ClInclude Include="..\..\..\src\jrd\val_proto.h" />
<ClInclude Include="..\..\..\src\jrd\vio_debug.h" />
<ClInclude Include="..\..\..\src\jrd\vio_proto.h" />
@@ -562,4 +558,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
Modified: firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters
===================================================================
--- firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters 2011-06-01 01:44:54 UTC (rev 53068)
@@ -384,12 +384,6 @@
<ClCompile Include="..\..\..\src\jrd\validation.cpp">
<Filter>JRD files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\src\jrd\ValueImpl.cpp">
- <Filter>JRD files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\src\jrd\ValuesImpl.cpp">
- <Filter>JRD files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\src\jrd\vio.cpp">
<Filter>JRD files</Filter>
</ClCompile>
@@ -1001,12 +995,6 @@
<ClInclude Include="..\..\..\src\jrd\val_proto.h">
<Filter>Header files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\src\jrd\ValueImpl.h">
- <Filter>Header files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\src\jrd\ValuesImpl.h">
- <Filter>Header files</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\src\jrd\vio_debug.h">
<Filter>Header files</Filter>
</ClInclude>
@@ -1082,4 +1070,4 @@
<Filter>Resource files</Filter>
</ResourceCompile>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
Modified: firebird/trunk/builds/win32/msvc8/engine.vcproj
===================================================================
--- firebird/trunk/builds/win32/msvc8/engine.vcproj 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/builds/win32/msvc8/engine.vcproj 2011-06-01 01:44:54 UTC (rev 53068)
@@ -588,14 +588,6 @@
>
</File>
<File
- RelativePath="..\..\..\src\jrd\ValueImpl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\..\src\jrd\ValuesImpl.cpp"
- >
- </File>
- <File
RelativePath="..\..\..\src\jrd\vio.cpp"
>
</File>
@@ -1668,14 +1660,6 @@
>
</File>
<File
- RelativePath="..\..\..\src\jrd\ValueImpl.h"
- >
- </File>
- <File
- RelativePath="..\..\..\src\jrd\ValuesImpl.h"
- >
- </File>
- <File
RelativePath="..\..\..\src\jrd\vio_debug.h"
>
</File>
Modified: firebird/trunk/builds/win32/msvc9/engine.vcproj
===================================================================
--- firebird/trunk/builds/win32/msvc9/engine.vcproj 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/builds/win32/msvc9/engine.vcproj 2011-06-01 01:44:54 UTC (rev 53068)
@@ -588,14 +588,6 @@
>
</File>
<File
- RelativePath="..\..\..\src\jrd\ValueImpl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\..\src\jrd\ValuesImpl.cpp"
- >
- </File>
- <File
RelativePath="..\..\..\src\jrd\vio.cpp"
>
</File>
@@ -1668,14 +1660,6 @@
>
</File>
<File
- RelativePath="..\..\..\src\jrd\ValueImpl.h"
- >
- </File>
- <File
- RelativePath="..\..\..\src\jrd\ValuesImpl.h"
- >
- </File>
- <File
RelativePath="..\..\..\src\jrd\vio_debug.h"
>
</File>
Modified: firebird/trunk/examples/udr/UdrCppExample.cpp
===================================================================
--- firebird/trunk/examples/udr/UdrCppExample.cpp 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/examples/udr/UdrCppExample.cpp 2011-06-01 01:44:54 UTC (rev 53068)
@@ -30,28 +30,6 @@
using namespace Firebird::Udr;
-typedef IMaster* (ISC_EXPORT *FuncGetMasterInterface)();
-
-typedef ISC_LONG (ISC_EXPORT_VARARG *FuncEventBlock)(ISC_UCHAR**, ISC_UCHAR**, ISC_USHORT, ...);
-typedef ISC_STATUS (ISC_EXPORT *FuncWaitForEvent)(ISC_STATUS*, isc_db_handle*,
- short, const ISC_UCHAR*, ISC_UCHAR*);
-typedef void (ISC_EXPORT *FuncEventCounts)(ISC_ULONG*, short, ISC_UCHAR*, const ISC_UCHAR*);
-
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlAllocateStatement)(ISC_STATUS*, isc_db_handle*,
- isc_stmt_handle*);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlDescribe)(ISC_STATUS*, isc_stmt_handle*, unsigned short,
- XSQLDA*);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlDescribeBind)(ISC_STATUS*, isc_stmt_handle*, unsigned short,
- XSQLDA*);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlExecute)(ISC_STATUS*, isc_tr_handle*, isc_stmt_handle*,
- unsigned short, XSQLDA*);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlExecute2)(ISC_STATUS*, isc_tr_handle*, isc_stmt_handle*,
- unsigned short, XSQLDA*, XSQLDA*);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlFreeStatement)(ISC_STATUS*, isc_stmt_handle*, unsigned short);
-typedef ISC_STATUS (ISC_EXPORT *FuncDsqlPrepare)(ISC_STATUS*, isc_tr_handle*, isc_stmt_handle*,
- unsigned short, const ISC_SCHAR*, unsigned short, XSQLDA*);
-
-
namespace
{
template <typename T>
@@ -133,10 +111,461 @@
}
+static IMaster* master = fb_get_master_interface();
+
+
+//------------------------------------------------------------------------------
+
+
+class MessageImpl;
+
+class ParamDescBase
+{
+public:
+ ParamDescBase()
+ : pos(0),
+ nullPos(0)
+ {
+ }
+
+ unsigned pos;
+ unsigned nullPos;
+};
+
+template <class T>
+class ParamDesc : public ParamDescBase
+{
+};
+
+template <>
+class ParamDesc<void*> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message, const Firebird::IParametersMetadata* aParams);
+
+ unsigned align(unsigned size, unsigned aIndex)
+ {
+ index = aIndex;
+
+ AutoDispose<IStatus> status(master->getStatus());
+
+ switch ((type = params->getType(status, index)))
+ {
+ case SQL_SHORT:
+ size = FB_ALIGN(size, sizeof(ISC_SHORT));
+ break;
+
+ case SQL_LONG:
+ size = FB_ALIGN(size, sizeof(ISC_LONG));
+ break;
+
+ case SQL_INT64:
+ size = FB_ALIGN(size, sizeof(ISC_INT64));
+ break;
+
+ case SQL_FLOAT:
+ size = FB_ALIGN(size, sizeof(float));
+ break;
+
+ case SQL_DOUBLE:
+ size = FB_ALIGN(size, sizeof(double));
+ break;
+
+ case SQL_BLOB:
+ size = FB_ALIGN(size, sizeof(ISC_QUAD));
+ break;
+
+ case SQL_TEXT:
+ case SQL_VARYING:
+ size = FB_ALIGN(size, sizeof(ISC_USHORT));
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ return size;
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ AutoDispose<IStatus> status(master->getStatus());
+ unsigned ret;
+
+ switch (type)
+ {
+ case SQL_SHORT:
+ {
+ unsigned scale = params->getScale(status, index);
+ *blr++ = blr_short;
+ *blr++ = scale;
+ ret = sizeof(ISC_SHORT);
+ break;
+ }
+
+ case SQL_LONG:
+ {
+ unsigned scale = params->getScale(status, index);
+ *blr++ = blr_long;
+ *blr++ = scale;
+ ret = sizeof(ISC_LONG);
+ break;
+ }
+
+ case SQL_INT64:
+ {
+ unsigned scale = params->getScale(status, index);
+ *blr++ = blr_int64;
+ *blr++ = scale;
+ ret = sizeof(ISC_INT64);
+ break;
+ }
+
+ case SQL_FLOAT:
+ *blr++ = blr_float;
+ ret = sizeof(float);
+ break;
+
+ case SQL_DOUBLE:
+ *blr++ = blr_double;
+ ret = sizeof(double);
+ break;
+
+ case SQL_BLOB:
+ *blr++ = blr_blob2;
+ *blr++ = 0;
+ *blr++ = 0;
+ *blr++ = 0;
+ *blr++ = 0;
+ ret = sizeof(ISC_QUAD);
+ break;
+
+ case SQL_TEXT:
+ case SQL_VARYING:
+ {
+ unsigned length = params->getLength(status, index);
+ *blr++ = blr_varying;
+ *blr++ = length & 0xFF;
+ *blr++ = (length >> 8) & 0xFF;
+ ret = sizeof(ISC_USHORT) + length;
+ break;
+ }
+
+ default:
+ assert(false);
+ ret = 0;
+ break;
+ }
+
+ return ret;
+ }
+
+ unsigned getType() const
+ {
+ return type;
+ }
+
+private:
+ const Firebird::IParametersMetadata* params;
+ unsigned type;
+ unsigned index;
+};
+
+class MessageImpl : public Firebird::FbMessage
+{
+public:
+ MessageImpl(unsigned aItemCount, ISC_UCHAR* aBuffer = NULL)
+ : itemCount(aItemCount * 2),
+ freeBuffer(!aBuffer),
+ items(0)
+ {
+ static const ISC_UCHAR HEADER[] = {
+ blr_version5,
+ blr_begin,
+ blr_message, 0, 0, 0
+ };
+
+ blrLength = 0;
+ blr = blrPos = new ISC_UCHAR[sizeof(HEADER) + 10 * itemCount + 2];
+ bufferLength = 0;
+ buffer = aBuffer;
+
+ memcpy(blrPos, HEADER, sizeof(HEADER));
+ blrPos += sizeof(HEADER);
+ }
+
+ ~MessageImpl()
+ {
+ if (freeBuffer && buffer)
+ delete [] buffer;
+
+ if (blr)
+ delete [] blr;
+ }
+
+ template <typename T>
+ void add(ParamDesc<T>& paramDesc)
+ {
+ if (items >= itemCount)
+ return; // return an error, this is already constructed message
+
+ bufferLength = paramDesc.align(bufferLength, items / 2);
+ paramDesc.pos = bufferLength;
+ bufferLength += paramDesc.addBlr(blrPos);
+
+ bufferLength = FB_ALIGN(bufferLength, sizeof(ISC_SHORT));
+ paramDesc.nullPos = bufferLength;
+ bufferLength += sizeof(ISC_SHORT);
+
+ *blrPos++ = blr_short;
+ *blrPos++ = 0;
+
+ items += 2;
+
+ if (items == itemCount)
+ {
+ *blrPos++ = blr_end;
+ *blrPos++ = blr_eoc;
+
+ blrLength = blrPos - blr;
+
+ ISC_UCHAR* blrStart = blrPos - blrLength;
+ blrStart[4] = items & 0xFF;
+ blrStart[5] = (items >> 8) & 0xFF;
+
+ if (!buffer)
+ {
+ buffer = new ISC_UCHAR[bufferLength];
+ memset(buffer, 0, bufferLength);
+ }
+ }
+ }
+
+ bool isNull(const ParamDescBase& index)
+ {
+ return *(ISC_SHORT*) (buffer + index.nullPos);
+ }
+
+ void setNull(const ParamDescBase& index, bool null)
+ {
+ *(ISC_SHORT*) (buffer + index.nullPos) = (ISC_SHORT) null;
+ }
+
+ template <typename T> T& operator [](const ParamDesc<T>& index)
+ {
+ return *(T*) (buffer + index.pos);
+ }
+
+ void* operator [](const ParamDesc<void*>& index)
+ {
+ return buffer + index.pos;
+ }
+
+public:
+ unsigned itemCount;
+ bool freeBuffer;
+ unsigned items;
+ ISC_UCHAR* blrPos;
+};
+
+template <>
+class ParamDesc<ISC_SHORT> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message, ISC_UCHAR aScale = 0)
+ : scale(aScale)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(ISC_SHORT));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_short;
+ *blr++ = scale;
+ return sizeof(ISC_SHORT);
+ }
+
+private:
+ ISC_UCHAR scale;
+};
+
+template <>
+class ParamDesc<ISC_LONG> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message, ISC_UCHAR aScale = 0)
+ : scale(aScale)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(ISC_LONG));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_long;
+ *blr++ = scale;
+ return sizeof(ISC_LONG);
+ }
+
+private:
+ ISC_UCHAR scale;
+};
+
+template <>
+class ParamDesc<ISC_INT64> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message, ISC_UCHAR aScale = 0)
+ : scale(aScale)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(ISC_INT64));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_int64;
+ *blr++ = scale;
+ return sizeof(ISC_INT64);
+ }
+
+private:
+ ISC_UCHAR scale;
+};
+
+template <>
+class ParamDesc<float> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(float));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_float;
+ return sizeof(float);
+ }
+};
+
+template <>
+class ParamDesc<double> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(double));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_double;
+ return sizeof(double);
+ }
+};
+
+template <>
+class ParamDesc<ISC_QUAD> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(ISC_QUAD));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_blob2;
+ *blr++ = 0;
+ *blr++ = 0;
+ *blr++ = 0;
+ *blr++ = 0;
+ return sizeof(ISC_QUAD);
+ }
+};
+
+struct FbString
+{
+ ISC_USHORT length;
+ char str[1];
+};
+
+template <>
+class ParamDesc<FbString> : public ParamDescBase
+{
+public:
+ ParamDesc(MessageImpl& message, ISC_USHORT aLength)
+ : length(aLength)
+ {
+ message.add(*this);
+ }
+
+ unsigned align(unsigned size, unsigned /*index*/)
+ {
+ return FB_ALIGN(size, sizeof(ISC_USHORT));
+ }
+
+ unsigned addBlr(ISC_UCHAR*& blr)
+ {
+ *blr++ = blr_varying;
+ *blr++ = length & 0xFF;
+ *blr++ = (length >> 8) & 0xFF;
+ return sizeof(ISC_USHORT) + length;
+ }
+
+private:
+ ISC_USHORT length;
+};
+
+//// TODO: boolean, date, time, timestamp
+
+//--------------------------------------
+
+inline ParamDesc<void*>::ParamDesc(MessageImpl& message, const Firebird::IParametersMetadata* aParams)
+ : params(aParams),
+ type(0)
+{
+ message.add(*this);
+}
+
+
+//------------------------------------------------------------------------------
+
+
/***
create function wait_event (
- event_name varchar(31) character set ascii
-) returns integer
+ event_name varchar(31) character set ascii not null
+) returns integer not null
external name 'udrcpp_example!wait_event'
engine udr;
***/
@@ -211,91 +640,110 @@
~FB_UDR_TRIGGER(replicate)();
private:
- void initialize(ExternalContext* context, Values* values);
+ void initialize(ExternalContext* context);
bool initialized;
XSQLDA* inSqlDa;
isc_stmt_handle stmtHandle;
-
- // ISC entry points
- FuncGetMasterInterface funcGetMasterInterface;
- FuncDsqlAllocateStatement funcDsqlAllocateStatement;
- FuncDsqlDescribe funcDsqlDescribe;
- FuncDsqlDescribeBind funcDsqlDescribeBind;
- FuncDsqlExecute funcDsqlExecute;
- FuncDsqlExecute2 funcDsqlExecute2;
- FuncDsqlFreeStatement funcDsqlFreeStatement;
- FuncDsqlPrepare funcDsqlPrepare;
+#if 0
+ IStatement* stmt;
+#endif
FB_UDR_END_DECLARE_TRIGGER(replicate)
FB_UDR_BEGIN_FUNCTION(wait_event)
{
- // ISC entry points
- FuncEventBlock funcEventBlock = (FuncEventBlock) getEntryPoint(context, "isc_event_block");
- FuncWaitForEvent funcWaitForEvent = (FuncWaitForEvent) getEntryPoint(context, "isc_wait_for_event");
- FuncEventCounts funcEventCounts = (FuncEventCounts) getEntryPoint(context, "isc_event_counts");
+ MessageImpl inMessage(1, inMsg);
+ ParamDesc<FbString> nameDesc(inMessage, 31);
- Value* val = params->getValue(ThrowError(), 1);
+ FbString& name = inMessage[nameDesc];
- const char* s = val->getString(ThrowError());
+ char* s = new char[name.length + 1];
+ memcpy(s, name.str, name.length);
+ s[name.length] = '\0';
unsigned char* eveBuffer;
unsigned char* eveResult;
- int eveLen = funcEventBlock(&eveBuffer, &eveResult, 1, s);
+ int eveLen = isc_event_block(&eveBuffer, &eveResult, 1, s);
+ delete [] s;
+
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle dbHandle = getIscDbHandle(context);
ISC_ULONG counter = 0;
- ThrowError::check(funcWaitForEvent(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
+ ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
statusVector);
- funcEventCounts(&counter, eveLen, eveBuffer, eveResult);
- ThrowError::check(funcWaitForEvent(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
+ isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
+ ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
statusVector);
- funcEventCounts(&counter, eveLen, eveBuffer, eveResult);
+ isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
isc_free((char*) eveBuffer);
isc_free((char*) eveResult);
- // returns the counter
- result->setInt(ThrowError(), counter);
+ MessageImpl outMessage(1, outMsg);
+ ParamDesc<ISC_LONG> retDesc(outMessage);
+
+ outMessage[retDesc] = counter;
}
FB_UDR_END_FUNCTION(wait_event)
FB_UDR_BEGIN_FUNCTION(sum_args)
{
- unsigned count = params->getCount();
+ AutoDispose<IStatus> status(master->getStatus());
+
+ const IParametersMetadata* params = metadata->getInputParameters(status);
+ ThrowError::check(status->get());
+
+ unsigned count = params->getCount(status);
+ ThrowError::check(status->get());
+
+ MessageImpl inMessage(count, inMsg);
+
+ MessageImpl outMessage(1, outMsg);
+ ParamDesc<ISC_LONG> retDesc(outMessage);
+
int ret = 0;
for (unsigned i = 0; i < count; ++i)
{
- Value* val = params->getValue(ThrowError(), i + 1);
- ret += val->getInt(ThrowError());
+ ParamDesc<ISC_LONG> numDesc(inMessage);
+
+ if (inMessage.isNull(numDesc))
+ {
+ outMessage.setNull(retDesc, true);
+ return;
+ }
+ else
+ ret += inMessage[numDesc];
}
- result->setInt(ThrowError(), ret);
+ outMessage[retDesc] = ret;
}
FB_UDR_END_FUNCTION(sum_args)
FB_UDR_BEGIN_PROCEDURE(gen_rows)
{
- Value* valStart = params->getValue(ThrowError(), 1);
- Value* valEnd = params->getValue(ThrowError(), 2);
+ MessageImpl inMessage(2, inMsg);
+ ParamDesc<ISC_LONG> startDesc(inMessage);
+ ParamDesc<ISC_LONG> endDesc(inMessage);
- counter = valStart->getInt(ThrowError());
- end = valEnd->getInt(ThrowError());
+ counter = inMessage[startDesc];
+ end = inMessage[endDesc];
}
FB_UDR_FETCH_PROCEDURE(gen_rows)
{
if (counter > end)
return false;
- Value* ret = results->getValue(ThrowError(), 1);
- ret->setInt(ThrowError(), counter++);
+ MessageImpl outMessage(1, outMsg);
+ ParamDesc<ISC_LONG> retDesc(outMessage);
+ outMessage[retDesc] = counter++;
+
return true;
}
FB_UDR_END_PROCEDURE(gen_rows)
@@ -321,36 +769,24 @@
delete [] reinterpret_cast<char*>(inSqlDa);
ISC_STATUS_ARRAY statusVector = {0};
- funcDsqlFreeStatement(statusVector, &stmtHandle, DSQL_drop);
+ isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_drop);
}
-void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context, Values* values)
+void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context)
{
if (initialized)
return;
- // ISC entry points
- funcGetMasterInterface = (FuncGetMasterInterface) getEntryPoint(context, "fb_get_master_interface");
- funcDsqlAllocateStatement = (FuncDsqlAllocateStatement)
- getEntryPoint(context, "isc_dsql_allocate_statement");
- funcDsqlDescribe = (FuncDsqlDescribe) getEntryPoint(context, "isc_dsql_describe");
- funcDsqlDescribeBind = (FuncDsqlDescribeBind) getEntryPoint(context, "isc_dsql_describe_bind");
- funcDsqlExecute = (FuncDsqlExecute) getEntryPoint(context, "isc_dsql_execute");
- funcDsqlExecute2 = (FuncDsqlExecute2) getEntryPoint(context, "isc_dsql_execute2");
- funcDsqlFreeStatement = (FuncDsqlFreeStatement) getEntryPoint(context, "isc_dsql_free_statement");
- funcDsqlPrepare = (FuncDsqlPrepare) getEntryPoint(context, "isc_dsql_prepare");
-
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
stmtHandle = 0;
- ThrowError::check(funcDsqlAllocateStatement(statusVector, &dbHandle, &stmtHandle), statusVector);
- ThrowError::check(funcDsqlPrepare(statusVector, &trHandle, &stmtHandle, 0,
+ ThrowError::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
+ ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), statusVector);
- IMaster* master(funcGetMasterInterface());
AutoDispose<IStatus> status(master->getStatus());
const char* table = metadata->getTriggerTable(status);
@@ -372,7 +808,7 @@
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
- ThrowError::check(funcDsqlDescribeBind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
+ ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), info, inSqlDa->sqlvar[0].sqllen);
@@ -381,31 +817,35 @@
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
outSqlDa->version = SQLDA_VERSION1;
outSqlDa->sqln = 1;
- ThrowError::check(funcDsqlDescribe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
+ ThrowError::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
statusVector);
outSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + outSqlDa->sqlvar[0].sqllen + 1];
outSqlDa->sqlvar[0].sqldata[sizeof(short) + outSqlDa->sqlvar[0].sqllen] = '\0';
- ThrowError::check(funcDsqlExecute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
+ ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa, outSqlDa), statusVector);
- ThrowError::check(funcDsqlFreeStatement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
+ ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
inSqlDa = NULL;
- int count = values->getCount();
+ const IParametersMetadata* fields = metadata->getTriggerFields(status);
+ ThrowError::check(status->get());
+ unsigned count = fields->getCount(status);
+ ThrowError::check(status->get());
+
char buffer[65536];
strcpy(buffer, "execute block (\n");
- for (int i = 1; i <= count; ++i)
+ for (unsigned i = 0; i < count; ++i)
{
- if (i > 1)
+ if (i > 0)
strcat(buffer, ",\n");
- Value* val = values->getValue(ThrowError(), i);
- const char* name = val->getName(ThrowError());
+ const char* name = fields->getField(status, i);
+ ThrowError::check(status->get());
strcat(buffer, " p");
sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name);
@@ -420,13 +860,13 @@
strcat(buffer, table);
strcat(buffer, "\" (");
- for (int i = 1; i <= count; ++i)
+ for (unsigned i = 0; i < count; ++i)
{
- if (i > 1)
+ if (i > 0)
strcat(buffer, ", ");
- Value* val = values->getValue(ThrowError(), i);
- const char* name = val->getName(ThrowError());
+ const char* name = fields->getField(status, i);
+ ThrowError::check(status->get());
strcat(buffer, "\"");
strcat(buffer, name);
@@ -435,18 +875,18 @@
strcat(buffer, ") values (");
- for (int i = 1; i <= count; ++i)
+ for (unsigned i = 0; i < count; ++i)
{
- if (i > 1)
+ if (i > 0)
strcat(buffer, ", ");
strcat(buffer, "?");
}
strcat(buffer, ")') (");
- for (int i = 1; i <= count; ++i)
+ for (unsigned i = 0; i < count; ++i)
{
- if (i > 1)
+ if (i > 0)
strcat(buffer, ", ");
strcat(buffer, ":p");
sprintf(buffer + strlen(buffer), "%d", i);
@@ -456,27 +896,28 @@
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
- ThrowError::check(funcDsqlPrepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
+ ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
SQL_DIALECT_CURRENT, NULL), statusVector);
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(count))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = count;
- ThrowError::check(funcDsqlDescribeBind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
+ ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
- for (int i = 0; i < count; ++i)
+ for (unsigned i = 0; i < count; ++i)
{
XSQLVAR* var = &inSqlDa->sqlvar[i];
switch (var->sqltype & ~1)
{
case SQL_TEXT:
- var->sqltype = SQL_VARYING | (var->sqltype & 1);
- // fall into
+ var->sqldata = new char[var->sqllen];
+ break;
case SQL_VARYING:
- var->sqldata = new char[sizeof(short) + var->sqllen];
+ var->sqldata = new char[var->sqllen];
+ var->sqllen += sizeof(short);
break;
case SQL_SHORT:
@@ -493,6 +934,7 @@
case SQL_FLOAT:
var->sqltype = SQL_DOUBLE | (var->sqltype & 1);
+ var->sqllen = sizeof(double);
// fall into
case SQL_DOUBLE:
@@ -526,75 +968,38 @@
FB_UDR_BEGIN_TRIGGER(replicate)
{
- Values* values = newValues;
+ initialize(context);
- initialize(context, values);
+ AutoDispose<IStatus> status(master->getStatus());
- int count = values->getCount();
+ const IParametersMetadata* fields = metadata->getTriggerFields(status);
+ ThrowError::check(status->get());
+ unsigned fieldsCount = fields->getCount(status);
+ ThrowError::check(status->get());
+
+ MessageImpl message(fieldsCount, newMsg);
+
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
- for (int i = 1; i <= count; ++i)
+ for (unsigned i = 1; i <= fieldsCount; ++i)
{
+ ParamDesc<void*> field(message, fields);
+
XSQLVAR* var = &inSqlDa->sqlvar[i - 1];
- Value* val = values->getValue(ThrowError(), i);
- if (val->isNull())
- {
+ if (message.isNull(field))
*var->sqlind = -1;
- continue;
- }
else
+ {
*var->sqlind = 0;
-
- switch (var->sqltype & ~1)
- {
- case SQL_VARYING:
- {
- unsigned len;
- const char* s = val->getString(ThrowError(), &len);
- *reinterpret_cast<unsigned short*>(var->sqldata) = len;
- memcpy(var->sqldata + sizeof(unsigned short), s, len);
- break;
- }
-
- case SQL_SHORT:
- *reinterpret_cast<short*>(var->sqldata) = (short) val->getInt(
- ThrowError(), var->sqlscale);
- break;
-
- case SQL_LONG:
- *reinterpret_cast<int32*>(var->sqldata) = val->getInt(ThrowError(), var->sqlscale);
- break;
-
- case SQL_INT64:
- *reinterpret_cast<int64*>(var->sqldata) = val->getBigInt(ThrowError(), var->sqlscale);
- break;
-
- case SQL_DOUBLE:
- *reinterpret_cast<double*>(var->sqldata) = val->getDouble(ThrowError());
- break;
-
- case SQL_BLOB:
- {
- int64 blobId = val->getBlobId(ThrowError());
- ISC_QUAD quad;
- quad.gds_quad_low = ISC_ULONG(blobId);
- quad.gds_quad_high = ISC_ULONG(blobId >> 32);
- *reinterpret_cast<ISC_QUAD*>(var->sqldata) = quad;
- break;
- }
-
- //// TODO: SQL_TYPE_DATE, SQL_TIMESTAMP, SQL_TYPE_TIME
-
- default:
- assert(false);
+ memcpy(var->sqldata, message[field], var->sqllen);
}
}
- ThrowError::check(funcDsqlExecute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
+ ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa), statusVector);
}
FB_UDR_END_TRIGGER(replicate)
Modified: firebird/trunk/src/common/dsc.cpp
===================================================================
--- firebird/trunk/src/common/dsc.cpp 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/common/dsc.cpp 2011-06-01 01:44:54 UTC (rev 53068)
@@ -34,7 +34,9 @@
#include "../common/gdsassert.h"
#include "../common/dsc_proto.h"
+using namespace Firebird;
+
// When converting non-text values to text, how many bytes to allocate
// for holding the text image of the value.
@@ -1171,6 +1173,96 @@
}
+void dsc::getSqlInfo(SLONG* sqlLength, SLONG* sqlSubType, SLONG* sqlScale, SLONG* sqlType) const
+{
+ *sqlLength = dsc_length;
+ *sqlSubType = 0;
+ *sqlScale = 0;
+ *sqlType = 0;
+
+ switch (dsc_dtype)
+ {
+ case dtype_real:
+ *sqlType = SQL_FLOAT;
+ break;
+
+ case dtype_array:
+ *sqlType = SQL_ARRAY;
+ break;
+
+ case dtype_timestamp:
+ *sqlType = SQL_TIMESTAMP;
+ break;
+
+ case dtype_sql_date:
+ *sqlType = SQL_TYPE_DATE;
+ break;
+
+ case dtype_sql_time:
+ *sqlType = SQL_TYPE_TIME;
+ break;
+
+ case dtype_double:
+ *sqlType = SQL_DOUBLE;
+ *sqlScale = dsc_scale;
+ break;
+
+ case dtype_text:
+ *sqlType = SQL_TEXT;
+ *sqlSubType = dsc_sub_type;
+ break;
+
+ case dtype_blob:
+ *sqlType = SQL_BLOB;
+ *sqlSubType = dsc_sub_type;
+ *sqlScale = dsc_scale;
+ break;
+
+ case dtype_varying:
+ *sqlType = SQL_VARYING;
+ *sqlLength -= sizeof(USHORT);
+ *sqlSubType = dsc_sub_type;
+ break;
+
+ case dtype_short:
+ case dtype_long:
+ case dtype_int64:
+ switch (dsc_dtype)
+ {
+ case dtype_short:
+ *sqlType = SQL_SHORT;
+ break;
+
+ case dtype_long:
+ *sqlType = SQL_LONG;
+ break;
+
+ default:
+ *sqlType = SQL_INT64;
+ }
+
+ *sqlScale = dsc_scale;
+ if (dsc_sub_type)
+ *sqlSubType = dsc_sub_type;
+ break;
+
+ case dtype_quad:
+ *sqlType = SQL_QUAD;
+ *sqlScale = dsc_scale;
+ break;
+
+ case dtype_boolean:
+ *sqlType = SQL_BOOLEAN;
+ break;
+
+ default:
+ status_exception::raise(
+ Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
+ Arg::Gds(isc_dsql_datatype_err));
+ }
+}
+
+
#ifdef DEV_BUILD
void dsc::address32bit() const
{
Modified: firebird/trunk/src/common/dsc.h
===================================================================
--- firebird/trunk/src/common/dsc.h 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/common/dsc.h 2011-06-01 01:44:54 UTC (rev 53068)
@@ -348,6 +348,7 @@
#endif
const char* typeToText() const;
+ void getSqlInfo(SLONG* sqlLength, SLONG* sqlSubType, SLONG* sqlScale, SLONG* sqlType) const;
#endif // __cpluplus
} DSC;
Modified: firebird/trunk/src/dsql/dsql.cpp
===================================================================
--- firebird/trunk/src/dsql/dsql.cpp 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/dsql/dsql.cpp 2011-06-01 01:44:54 UTC (rev 53068)
@@ -2621,95 +2621,21 @@
if (param->par_index >= first_index)
{
- SLONG sql_len = param->par_desc.dsc_length;
- SLONG sql_sub_type = 0;
- SLONG sql_scale = 0;
- SLONG sql_type = 0;
+ SLONG sql_len, sql_sub_type, sql_scale, sql_type;
+ param->par_desc.getSqlInfo(&sql_len, &sql_sub_type, &sql_scale, &sql_type);
- switch (param->par_desc.dsc_dtype)
+ if (input_message && param->par_desc.dsc_dtype == dtype_text &&
+ (param->par_desc.dsc_flags & DSC_null))
{
- case dtype_real:
- sql_type = SQL_FLOAT;
- break;
- case dtype_array:
- sql_type = SQL_ARRAY;
- break;
-
- case dtype_timestamp:
- sql_type = SQL_TIMESTAMP;
- break;
- case dtype_sql_date:
- sql_type = SQL_TYPE_DATE;
- break;
- case dtype_sql_time:
- sql_type = SQL_TYPE_TIME;
- break;
-
- case dtype_double:
- sql_type = SQL_DOUBLE;
- sql_scale = param->par_desc.dsc_scale;
- break;
-
- case dtype_text:
- if (input_message && (param->par_desc.dsc_flags & DSC_null))
- {
- sql_type = SQL_NULL;
- sql_len = 0;
- }
- else
- {
- sql_type = SQL_TEXT;
- sql_sub_type = param->par_desc.dsc_sub_type;
- }
- break;
-
- case dtype_blob:
- sql_type = SQL_BLOB;
- sql_sub_type = param->par_desc.dsc_sub_type;
- sql_scale = param->par_desc.dsc_scale;
- break;
-
- case dtype_varying:
- sql_type = param->par_is_text ? SQL_TEXT : SQL_VARYING;
- sql_len -= sizeof(USHORT);
- sql_sub_type = param->par_desc.dsc_sub_type;
- break;
-
- case dtype_short:
- case dtype_long:
- case dtype_int64:
- switch (param->par_desc.dsc_dtype)
- {
- case dtype_short:
- sql_type = SQL_SHORT;
- break;
- case dtype_long:
- sql_type = SQL_LONG;
- break;
- default:
- sql_type = SQL_INT64;
- }
- sql_scale = param->par_desc.dsc_scale;
- if (param->par_desc.dsc_sub_type)
- sql_sub_type = param->par_desc.dsc_sub_type;
- break;
-
- case dtype_quad:
- sql_type = SQL_QUAD;
- sql_scale = param->par_desc.dsc_scale;
- break;
-
- case dtype_boolean:
- sql_type = SQL_BOOLEAN;
- break;
-
- default:
- ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
- Arg::Gds(isc_dsql_datatype_err));
+ sql_type = SQL_NULL;
+ sql_len = 0;
+ sql_sub_type = 0;
}
+ else if (param->par_desc.dsc_dtype == dtype_varying && param->par_is_text)
+ sql_type = SQL_TEXT;
if (sql_type && (param->par_desc.dsc_flags & DSC_nullable))
- sql_type++;
+ sql_type |= 0x1;
for (const UCHAR* describe = items; describe < end_describe;)
{
Modified: firebird/trunk/src/include/FirebirdApi.h
===================================================================
--- firebird/trunk/src/include/FirebirdApi.h 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/include/FirebirdApi.h 2011-06-01 01:44:54 UTC (rev 53068)
@@ -61,30 +61,6 @@
#endif
-struct Date
-{
- int year;
- int month;
- int day;
-};
-
-
-struct Time
-{
- int hours;
- int minutes;
- int seconds;
- int fractions;
-};
-
-
-struct DateTime //// FIXME: rename to TimeStamp
-{
- Date date;
- Time time;
-};
-
-
class Error
{
public:
@@ -102,102 +78,6 @@
};
-// Represents a parameter or column.
-class Value
-{
-public:
- // data types
- enum Type
- {
- TYPE_SMALLINT = 1,
- TYPE_INTEGER,
- TYPE_BIGINT,
- TYPE_DOUBLE,
- TYPE_CHAR,
- TYPE_VARCHAR,
- TYPE_BLOB,
- TYPE_DATE,
- TYPE_TIME,
- TYPE_TIMESTAMP
- };
-
-public:
- // Get parameter or column name.
- virtual const char* FB_CALL getName(Error* error) const = 0;
-
- virtual Type FB_CALL getType(Error* error) const = 0;
- virtual const char* FB_CALL getCharSet(Error* error) const = 0;
-
- // Get BLOB sub-type.
- virtual int FB_CALL getSubType(Error* error) const = 0;
-
- // Get numeric precision or maximum string length.
- virtual int FB_CALL getPrecision(Error* error) const = 0;
-
- virtual int FB_CALL getScale(Error* error) const = 0;
- virtual bool FB_CALL isNullable(Error* error) const = 0;
-
- virtual bool FB_CALL isNull() const = 0;
- virtual void FB_CALL setNull(Error* error) = 0;
-
- virtual void FB_CALL copyFrom(Error* error, const Value* from) = 0;
-
- virtual int16 FB_CALL getSmallInt(Error* error, int scale = 0, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setSmallInt(Error* error, int16 value, int scale = 0) = 0;
-
- virtual int32 FB_CALL getInt(Error* error, int scale = 0, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setInt(Error* error, int32 value, int scale = 0) = 0;
-
- virtual int64 FB_CALL getBigInt(Error* error, int scale = 0, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setBigInt(Error* error, int64 value, int scale = 0) = 0;
-
- virtual double FB_CALL getDouble(Error* error, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setDouble(Error* error, double value) = 0;
-
- virtual const char* FB_CALL getString(Error* error, uint* strLength = FB_NULL,
- bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setString(Error* error, const char* str, uint strLength) = 0;
-
- virtual int64 FB_CALL getBlobId(Error* error, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setBlobId(Error* error, int64 value) = 0;
-
- virtual void FB_CALL getDate(Error* error, Date* value, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setDate(Error* error, const Date* value) = 0;
-
- virtual void FB_CALL getTime(Error* error, Time* value, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setTime(Error* error, const Time* value) = 0;
-
- virtual void FB_CALL getTimeStamp(Error* error, DateTime* value, bool* isNull = FB_NULL) const = 0;
- virtual void FB_CALL setTimeStamp(Error* error, const DateTime* value) = 0;
-};
-
-
-// A queue associated with a Values. Could be used for batching processing.
-class ValuesQueue : public Disposable
-{
-public:
- virtual void FB_CALL enqueue(Error* error) = 0; // Enqueue the current Values.
- virtual bool FB_CALL dequeue(Error* error) = 0; // Dequeue in Values.
-};
-
-
-// Represents a group of parameters or columns.
-class Values
-{
-public:
- virtual uint FB_CALL getCount() const = 0;
- virtual uint FB_CALL getIndexByName(Error* error, const char* name) const = 0;
-
- // Get a given value. The first value is at index 1.
- virtual Value* FB_CALL getValue(Error* error, uint index) const = 0;
-
- virtual Value* FB_CALL getValueByName(Error* error, const char* name) const = 0;
-
- // Creates a queue associated with this Values.
- virtual ValuesQueue* FB_CALL createQueue(Error* error) = 0;
-};
-
-
} // namespace Firebird
Modified: firebird/trunk/src/include/FirebirdExternalApi.h
===================================================================
--- firebird/trunk/src/include/FirebirdExternalApi.h 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/include/FirebirdExternalApi.h 2011-06-01 01:44:54 UTC (rev 53068)
@@ -95,8 +95,8 @@
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
Utf8* name, uint nameSize) = 0;
- virtual void FB_CALL execute(Error* error, ExternalContext* context, Values* params,
- Value* result) = 0;
+ virtual void FB_CALL execute(Error* error, ExternalContext* context,
+ UCHAR* inMsg, UCHAR* outMsg) = 0;
};
@@ -113,7 +113,7 @@
// Returning NULL results in a result set of one record.
// Procedures without output parameters should return NULL.
virtual ExternalResultSet* FB_CALL open(Error* error, ExternalContext* context,
- Values* params, Values* results) = 0;
+ UCHAR* inMsg, UCHAR* outMsg) = 0;
};
@@ -148,7 +148,7 @@
Utf8* name, uint nameSize) = 0;
virtual void FB_CALL execute(Error* error, ExternalContext* context,
- Action action, const Values* oldValues, Values* newValues) = 0;
+ Action action, UCHAR* oldMsg, UCHAR* newMsg) = 0;
};
@@ -159,10 +159,13 @@
virtual const char* FB_CARG getName(IStatus* status) const = 0;
virtual const char* FB_CARG getEntryPoint(IStatus* status) const = 0;
virtual const char* FB_CARG getBody(IStatus* status) const = 0;
+ virtual const IParametersMetadata* FB_CARG getInputParameters(IStatus* status) const = 0;
+ virtual const IParametersMetadata* FB_CARG getOutputParameters(IStatus* status) const = 0;
+ virtual const IParametersMetadata* FB_CARG getTriggerFields(IStatus* status) const = 0;
virtual const char* FB_CARG getTriggerTable(IStatus* status) const = 0;
virtual ExternalTrigger::Type FB_CARG getTriggerType(IStatus* status) const = 0;
};
-#define FB_ROUTINE_METADATA_VERSION (FB_VERSIONED_VERSION + 6)
+#define FB_ROUTINE_METADATA_VERSION (FB_VERSIONED_VERSION + 9)
// In SuperServer, shared by all attachments to one database and disposed when last (non-external)
Modified: firebird/trunk/src/include/FirebirdUdrCpp.h
===================================================================
--- firebird/trunk/src/include/FirebirdUdrCpp.h 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/include/FirebirdUdrCpp.h 2011-06-01 01:44:54 UTC (rev 53068)
@@ -50,7 +50,7 @@
{ \
public: \
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::Values* params, ::Firebird::Value* result); \
+ UCHAR* inMsg, UCHAR* outMsg); \
private:
#define FB_UDR_END_DECLARE_FUNCTION(name) \
@@ -62,7 +62,7 @@
#define FB_UDR_BEGIN_FUNCTION(name) \
void FB_CALL FB_UDR_FUNCTION(name)::execute(::Firebird::Error* error, \
- ::Firebird::ExternalContext* context, ::Firebird::Values* params, ::Firebird::Value* result) \
+ ::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg) \
{ \
try \
{
@@ -90,8 +90,7 @@
{ \
public: \
virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::Error* error, \
- ::Firebird::ExternalContext* context, ::Firebird::Values* params, \
- ::Firebird::Values* results); \
+ ::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg); \
#define FB_UDR_END_DECLARE_PROCEDURE(name) \
};
@@ -104,8 +103,8 @@
class ResultSet##name : public ::Firebird::Udr::ResultSet \
{ \
public: \
- ResultSet##name(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::Values* params, ::Firebird::Values* results); \
+ ResultSet##name(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
+ ::Firebird::Udr::Procedure* procedure, UCHAR* inMsg, UCHAR* outMsg); \
\
public: \
virtual bool FB_CALL fetch(::Firebird::Error* error); \
@@ -125,15 +124,14 @@
#define FB_UDR_BEGIN_PROCEDURE(name) \
::Firebird::ExternalResultSet* FB_CALL Proc##name::open(::Firebird::Error* error, \
- ::Firebird::ExternalContext* context, ::Firebird::Values* params, \
- ::Firebird::Values* results) \
+ ::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg) \
{ \
- return new ResultSet##name(error, context, params, results); \
+ return new ResultSet##name(error, context, this, inMsg, outMsg); \
} \
\
ResultSet##name::ResultSet##name(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::Values* params, ::Firebird::Values* results) \
- : ResultSet(context, params, results) \
+ ::Firebird::Udr::Procedure* procedure, UCHAR* inMsg, UCHAR* outMsg) \
+ : ResultSet(context, procedure, inMsg, outMsg) \
{ \
try \
{
@@ -183,8 +181,7 @@
{ \
public: \
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::ExternalTrigger::Action action, const ::Firebird::Values* oldValues, \
- ::Firebird::Values* newValues); \
+ ::Firebird::ExternalTrigger::Action action, UCHAR* oldMsg, UCHAR* newMsg); \
private:
#define FB_UDR_END_DECLARE_TRIGGER(name) \
@@ -197,7 +194,7 @@
#define FB_UDR_BEGIN_TRIGGER(name) \
void FB_CALL FB_UDR_TRIGGER(name)::execute(::Firebird::Error* error, \
::Firebird::ExternalContext* context, ::Firebird::ExternalTrigger::Action action, \
- const ::Firebird::Values* oldValues, ::Firebird::Values* newValues) \
+ UCHAR* oldMsg, UCHAR* newMsg) \
{ \
try \
{
@@ -429,6 +426,9 @@
};
+class Procedure;
+
+
class Helper
{
public:
@@ -460,11 +460,12 @@
class ResultSet : public ExternalResultSet, public Helper
{
public:
- ResultSet(Firebird::ExternalContext* aContext, Firebird::Values* aParams,
- Firebird::Values* aResults)
+ ResultSet(Firebird::ExternalContext* aContext, Firebird::Udr::Procedure* aProcedure,
+ UCHAR* aInMsg, UCHAR* aOutMsg)
: context(aContext),
- params(aParams),
- results(aResults)
+ procedure(aProcedure),
+ inMsg(aInMsg),
+ outMsg(aOutMsg)
{
}
@@ -480,8 +481,9 @@
protected:
Firebird::ExternalContext* context;
- Firebird::Values* params;
- Firebird::Values* results;
+ Firebird::Udr::Procedure* procedure;
+ UCHAR* inMsg;
+ UCHAR* outMsg;
};
Modified: firebird/trunk/src/jrd/ExtEngineManager.cpp
===================================================================
--- firebird/trunk/src/jrd/ExtEngineManager.cpp 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/jrd/ExtEngineManager.cpp 2011-06-01 01:44:54 UTC (rev 53068)
@@ -26,10 +26,9 @@
#include "inf_pub.h"
#include "../jrd/ExtEngineManager.h"
#include "../jrd/ErrorImpl.h"
-#include "../jrd/ValueImpl.h"
-#include "../jrd/ValuesImpl.h"
#include "../dsql/sqlda_pub.h"
#include "../common/dsc.h"
+#include "../jrd/align.h"
#include "../jrd/jrd.h"
#include "../jrd/exe.h"
#include "../jrd/req.h"
@@ -305,8 +304,7 @@
}
-void ExtEngineManager::Function::execute(thread_db* tdbb, const NestValueArray& args,
- impure_value* impure) const
+void ExtEngineManager::Function::execute(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const
{
EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine);
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, function,
@@ -314,70 +312,9 @@
CallerName(obj_udf, udf->getName().identifier) :
CallerName(obj_package_header, udf->getName().package)));
- impure->vlu_desc.dsc_flags = DSC_null;
- MemoryPool& pool = *tdbb->getDefaultPool();
- ValueImpl result(pool, &impure->vlu_desc, "", true);
+ Attachment::Checkout attCout(tdbb->getAttachment());
- HalfStaticArray<impure_value, 32> impureArgs;
-
- jrd_req* request = tdbb->getRequest();
- impure_value* impureArgsPtr = impureArgs.getBuffer(args.getCount());
-
- try
- {
- ValuesImpl params(pool, args.getCount());
-
- for (size_t i = 0; i < args.getCount(); ++i)
- {
- impureArgsPtr->vlu_desc = udf->fun_args[i + 1].fun_parameter->prm_desc;
-
- if (impureArgsPtr->vlu_desc.isText())
- {
- impureArgsPtr->vlu_string =
- FB_NEW_RPT(pool, impureArgsPtr->vlu_desc.getStringLength()) VaryingString();
- impureArgsPtr->vlu_desc.dsc_address = (UCHAR*) impureArgsPtr->vlu_string;
- }
- else
- {
- impureArgsPtr->vlu_string = NULL;
- impureArgsPtr->vlu_desc.dsc_address = (UCHAR*) &impureArgsPtr->vlu_misc;
- }
-
- dsc* arg = EVL_expr(tdbb, request, args[i]);
-
- if (request->req_flags & req_null)
- impureArgsPtr->vlu_desc.dsc_flags = DSC_null;
- else
- {
- MOV_move(tdbb, arg, &impureArgsPtr->vlu_desc);
- INTL_adjust_text_descriptor(tdbb, &impureArgsPtr->vlu_desc);
- }
-
- params.getValue(i + 1)->make(&impureArgsPtr->vlu_desc, "", true);
-
- ++impureArgsPtr;
- }
-
- { // scope
- Attachment::Checkout attCout(tdbb->getAttachment());
- function->execute(RaiseError(), attInfo->context, ¶ms, &result);
- }
- }
- catch (...)
- {
- for (size_t i = 0; i < args.getCount(); ++i)
- delete impureArgs[i].vlu_string;
-
- throw;
- }
-
- for (size_t i = 0; i < args.getCount(); ++i)
- delete impureArgs[i].vlu_string;
-
- if (result.isNull())
- request->req_flags |= req_null;
- else
- request->req_flags &= ~req_null;
+ function->execute(RaiseError(), attInfo->context, inMsg, outMsg);
}
@@ -405,17 +342,17 @@
ExtEngineManager::ResultSet* ExtEngineManager::Procedure::open(thread_db* tdbb,
- ValuesImpl* inputParams, ValuesImpl* outputParams) const
+ UCHAR* inMsg, UCHAR* outMsg) const
{
- return FB_NEW(*tdbb->getDefaultPool()) ResultSet(tdbb, inputParams, outputParams, this);
+ return FB_NEW(*tdbb->getDefaultPool()) ResultSet(tdbb, inMsg, outMsg, this);
}
//---------------------
-ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, ValuesImpl* inputParams,
- ValuesImpl* outputParams, const ExtEngineManager::Procedure* aProcedure)
+ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg,
+ const ExtEngineManager::Procedure* aProcedure)
: procedure(aProcedure),
attachment(tdbb->getAttachment()),
firstFetch(true)
@@ -430,8 +367,7 @@
Attachment::Checkout attCout(attachment);
- resultSet = procedure->procedure->open(RaiseError(), attInfo->context, inputParams,
- outputParams);
+ resultSet = procedure->procedure->open(RaiseError(), attInfo->context, inMsg, outMsg);
}
@@ -494,82 +430,95 @@
ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, trigger,
CallerName(obj_trigger, trg->name));
- Array<dsc*> descs;
- try
+ // ASF: Using Array instead of HalfStaticArray to not need to do alignment hacks here.
+ Array<UCHAR> oldMsg;
+ Array<UCHAR> newMsg;
+
+ if (oldRpb)
+ setValues(tdbb, oldMsg, oldRpb);
+
+ if (newRpb)
+ setValues(tdbb, newMsg, newRpb);
+
+ Attachment::Checkout attCout(tdbb->getAttachment());
+
+ trigger->execute(RaiseError(), attInfo->context, action,
+ (oldRpb ? oldMsg.begin() : NULL), (newRpb ? newMsg.begin() : NULL));
+
+ if (newRpb)
{
- MemoryPool& pool = *tdbb->getDefaultPool();
- AutoPtr<ValuesImpl> oldValues, newValues;
- int valueOldCount = 0;
- int valueNewCount = 0;
+ Record* record = newRpb->rpb_record;
+ const Format* format = record->rec_format;
+ const UCHAR* msg = newMsg.begin();
+ unsigned pos = 0;
- if (oldRpb)
- valueOldCount = setValues(tdbb, pool, oldValues, descs, oldRpb);
+ for (unsigned i = 0; i < format->fmt_count; ++i)
+ {
+ if (format->fmt_desc[i].dsc_dtype == dtype_unknown)
+ continue;
- if (newRpb)
- valueNewCount = setValues(tdbb, pool, newValues, descs, newRpb);
+ dsc desc;
+ bool readonly = !EVL_field(newRpb->rpb_relation, record, i, &desc) &&
+ desc.dsc_address && !(desc.dsc_flags & DSC_null);
- { // scope
- Attachment::Checkout attCout(tdbb->getAttachment());
+ unsigned align = type_alignments[desc.dsc_dtype];
+ if (align)
+ pos = FB_ALIGN(pos, align);
- trigger->execute(RaiseError(), attInfo->context, action, oldValues, newValues);
+ unsigned dataPos = pos;
+ pos += desc.dsc_length;
- for (int i = 1; i <= valueNewCount; ++i)
+ align = type_alignments[dtype_short];
+ if (align)
+ pos = FB_ALIGN(pos, align);
+
+ if (!readonly)
{
- ValueImpl* val = newValues->getValue(i);
-
- if (val->isNull())
- SET_NULL(newRpb->rpb_record, val->getFieldNumber());
+ if (*(USHORT*) &msg[pos])
+ SET_NULL(record, i);
else
- CLEAR_NULL(newRpb->rpb_record, val->getFieldNumber());
+ {
+ memcpy(desc.dsc_address, msg + dataPos, desc.dsc_length);
+ CLEAR_NULL(record, i);
+ }
}
+
+ pos += sizeof(USHORT);
}
}
- catch (...)
- {
- for (size_t i = 0; i < descs.getCount(); ++i)
- delete descs[i];
- throw;
- }
-
- for (size_t i = 0; i < descs.getCount(); ++i)
- delete descs[i];
}
-int ExtEngineManager::Trigger::setValues(thread_db* /*tdbb*/, MemoryPool& pool,
- AutoPtr<ValuesImpl>& values, Array<dsc*>& descs,
+void ExtEngineManager::Trigger::setValues(thread_db* /*tdbb*/, Array<UCHAR>& msgBuffer,
record_param* rpb) const
{
if (!rpb || !rpb->rpb_record)
- return 0;
+ return;
Record* record = rpb->rpb_record;
const Format* format = record->rec_format;
- values = FB_NEW(pool) ValuesImpl(pool, format->fmt_count);
+ for (unsigned i = 0; i < format->fmt_count; ++i)
+ {
+ if (format->fmt_desc[i].dsc_dtype == dtype_unknown)
+ continue;
- int start = descs.getCount();
- descs.resize(start + format->fmt_count);
+ dsc desc;
+ EVL_field(rpb->rpb_relation, record, i, &desc);
- int j = 0;
+ unsigned align = type_alignments[desc.dsc_dtype];
+ if (align)
+ msgBuffer.resize(FB_ALIGN(msgBuffer.getCount(), align));
- for (int i = 0; i < format->fmt_count; ++i)
- {
- descs[start + i] = FB_NEW(pool) dsc;
+ msgBuffer.add(desc.dsc_address, desc.dsc_length);
- if (format->fmt_desc[i].dsc_dtype != dtype_unknown)
- {
- EVL_field(rpb->rpb_relation, record, i, descs[start + i]);
+ align = type_alignments[dtype_short];
+ if (align)
+ msgBuffer.resize(FB_ALIGN(msgBuffer.getCount(), align));
- jrd_fld* field = (*rpb->rpb_relation->rel_fields)[i];
- fb_assert(field);
-
- values->getValue(j + 1)->make(descs[start + i], field->fld_name, true, i);
- ++j;
- }
+ USHORT nullFlag = (desc.dsc_flags & DSC_null) != 0;
+ msgBuffer.add((UCHAR*) &nullFlag, sizeof(nullFlag));
}
-
- return j;
}
@@ -654,13 +603,36 @@
CallerName(obj_udf, udf->getName().identifier) :
CallerName(obj_package_header, udf->getName().package)));
- MemoryPool& pool = *tdbb->getDefaultPool();
+ ///MemoryPool& pool = *tdbb->getDefaultPool();
+ MemoryPool& pool = *getDefaultMemoryPool();
+
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
metadata->package = udf->getName().package;
metadata->name = udf->getName().identifier;
metadata->entryPoint = entryPointTrimmed;
metadata->body = body;
+ metadata->inputParameters = FB_NEW(pool) StatementMetadata::Parameters(pool);
+ metadata->outputParameters = FB_NEW(pool) StatementMetadata::Parameters(pool);
+ for (Array<Jrd::Function::Argument>::const_iterator i = udf->fun_args.begin();
+ i != udf->fun_args.end();
+ ++i)
+ {
+ SLONG sqlLen, sqlSubType, sqlScale, sqlType;
+ i->fun_parameter->prm_desc.getSqlInfo(&sqlLen, &sqlSubType, &sqlScale, &sqlType);
+
+ StatementMetadata::Parameters::Item& item = i == udf->fun_args.begin() ?
+ metadata->outputParameters->items.add() :
+ metadata->inputParameters->items.add();
+
+ item.field = i->fun_parameter->prm_name.c_str();
+ item.type = sqlType;
+ item.subType = sqlSubType;
+ item.length = sqlLen;
+ item.scale = sqlScale;
+ item.nullable = i->fun_parameter->prm_nullable;
+ }
+
ExternalFunction* externalFunction;
{ // scope
@@ -702,13 +674,41 @@
CallerName(obj_procedure, prc->getName().identifier) :
CallerName(obj_package_header, prc->getName().package)));
- MemoryPool& pool = *tdbb->getDefaultPool();
+ ///MemoryPool& pool = *tdbb->getDefaultPool();
+ MemoryPool& pool = *getDefaultMemoryPool();
+
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
metadata->package = prc->getName().package;
metadata->name = prc->getName().identifier;
metadata->entryPoint = entryPointTrimmed;
metadata->body = body;
+ metadata->inputParameters = FB_NEW(pool) StatementMetadata::Parameters(pool);
+ metadata->outputParameters = FB_NEW(pool) StatementMetadata::Parameters(pool);
+ const Array<NestConst<Parameter> >* parameters[] = {&prc->prc_input_fields, &prc->prc_output_fields};
+
+ for (unsigned i = 0; i < 2; ++i)
+ {
+ for (Array<NestConst<Parameter> >::const_iterator j = parameters[i]->begin();
+ j != parameters[i]->end();
+ ++j)
+ {
+ SLONG sqlLen, sqlSubType, sqlScale, sqlType;
+ (*j)->prm_desc.getSqlInfo(&sqlLen, &sqlSubType, &sqlScale, &sqlType);
+
+ StatementMetadata::Parameters::Item& item = i == 1 ?
+ metadata->outputParameters->items.add() :
+ metadata->inputParameters->items.add();
+
+ item.field = (*j)->prm_name.c_str();
+ item.type = sqlType;
+ item.subType = sqlSubType;
+ item.length = sqlLen;
+ item.scale = sqlScale;
+ item.nullable = (*j)->prm_nullable;
+ }
+ }
+
ExternalProcedure* externalProcedure;
{ // scope
@@ -748,7 +748,9 @@
ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, attInfo->adminCharSet,
CallerName(obj_trigger, trg->name));
- MemoryPool& pool = *tdbb->getDefaultPool();
+ ///MemoryPool& pool = *tdbb->getDefaultPool();
+ MemoryPool& pool = *getDefaultMemoryPool();
+
AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool));
metadata->name = trg->name;
metadata->entryPoint = entryPointTrimmed;
@@ -756,7 +758,29 @@
metadata->triggerType = type;
if (trg->relation)
metadata->triggerTable = trg->relation->rel_name;
+ metadata->triggerFields = FB_NEW(pool) StatementMetadata::Parameters(pool);
+ jrd_rel* relation = trg->relation;
+ Format* relFormat = relation->rel_current_format;
+
+ for (size_t i = 0; i < relation->rel_fields->count(); ++i)
+ {
+ jrd_fld* field = (*relation->rel_fields)[i];
+ if (!field)
+ continue;
+
+ SLONG sqlLen, sqlSubType, sqlScale, sqlType;
+ relFormat->fmt_desc[i].getSqlInfo(&sqlLen, &sqlSubType, &sqlScale, &sqlType);
+
+ StatementMetadata::Parameters::Item& item = metadata->triggerFields->items.add();
+ item.field = field->fld_name.c_str();
+ item.type = sqlType;
+ item.subType = sqlSubType;
+ item.length = sqlLen;
+ item.scale = sqlScale;
+ item.nullable = !field->fld_not_null;
+ }
+
ExternalTrigger* externalTrigger;
{ // scope
Modified: firebird/trunk/src/jrd/ExtEngineManager.h
===================================================================
--- firebird/trunk/src/jrd/ExtEngineManager.h 2011-05-31 16:19:47 UTC (rev 53067)
+++ firebird/trunk/src/jrd/ExtEngineManager.h 2011-06-01 01:44:54 UTC (rev 53068)
@@ -34,7 +34,7 @@
#include "../common/classes/auto.h"
#include "../common/classes/rwlock.h"
#include "../common/classes/ImplementHelper.h"
-///#include "../dsql/Nodes.h"
+#include "../common/StatementMetadata.h"
struct dsc;
@@ -49,8 +49,6 @@
class Trigger;
class Function;
class ValueExprNode;
-class ValueImpl;
-class ValuesImpl;
struct impure_value;
struct record_param;
@@ -97,6 +95,24 @@
return body.c_str();
}
+ virtual const Firebird::IParametersMetadata* FB_CARG getInputParameters(
+ Firebird::IStatus* /*status*/) const
+ {
+ return inputParameters;
+ }
+
+ virtual const Firebird::IParametersMetadata* FB_CARG getOutputParameters(
+ Firebird::IStatus* /*status*/) const
+ {
+ return outputParameters;
+ }
+
+ virtual const Firebird::IParametersMetadata* FB_CARG getTriggerFields(
+ Firebird::IStatus* /*status*/) const
+ {
+ return triggerFields;
+ }
+
virtual const char* FB_CARG getTriggerTable(Firebird::IStatus* /*status*/) const
{
return triggerTable.c_str();
@@ -112,6 +128,9 @@
Firebird::MetaName name;
Firebird::string entryPoint;
Firebird::string body;
+ Firebird::AutoPtr<Firebird::StatementMetadata::Parameters> inputParameters;
+ Firebird::AutoPtr<Firebird::StatementMetadata::Parameters> outputParameters;
+ Firebird::AutoPtr<Firebird::StatementMetadata::Parameters> triggerFields;
Firebird::MetaName triggerTable;
Firebird::ExternalTrigger::Type triggerType;
};
@@ -190,8 +209,7 @@
const Jrd::Function* aUdf);
~Function();
- void execute(thread_db* tdbb, const Firebird::Array<NestConst<ValueExprNode> >& args,
- impure_value* impure) const;
+ void execute(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const;
private:
ExtEngineManager* extManager;
@@ -214,7 +232,7 @@
const jrd_prc* aPrc);
~Procedure();
- ResultSet* open(thread_db* tdbb, ValuesImpl* inputParams, ValuesImpl* outputParams) const;
+ ResultSet* open(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const;
private:
ExtEngineManager* extManager;
@@ -230,8 +248,7 @@
class ResultSet
{
public:
- Re...
[truncated message content] |