|
From: <asf...@us...> - 2013-06-06 16:05:05
|
Revision: 58161
http://sourceforge.net/p/firebird/code/58161
Author: asfernandes
Date: 2013-06-06 16:05:02 +0000 (Thu, 06 Jun 2013)
Log Message:
-----------
UDR C++ interface and examples improvements.
Modified Paths:
--------------
firebird/trunk/examples/udr/UdrCppExample.cpp
firebird/trunk/src/include/firebird/ExternalEngine.h
firebird/trunk/src/include/firebird/UdrCppEngine.h
Modified: firebird/trunk/examples/udr/UdrCppExample.cpp
===================================================================
--- firebird/trunk/examples/udr/UdrCppExample.cpp 2013-06-06 15:07:54 UTC (rev 58160)
+++ firebird/trunk/examples/udr/UdrCppExample.cpp 2013-06-06 16:05:02 UTC (rev 58161)
@@ -194,10 +194,15 @@
engine udr;
***/
FB_UDR_BEGIN_FUNCTION(wait_event)
- FB_UDR_EXECUTE_MESSAGE_FUNCTION(
+ FB_MESSAGE(InMessage,
(FB_VARCHAR(31 * 4), name)
- ,
- (FB_INTEGER, result))
+ );
+
+ FB_MESSAGE(OutMessage,
+ (FB_INTEGER, result)
+ );
+
+ FB_UDR_EXECUTE_FUNCTION
{
char* s = new char[in->name.length + 1];
memcpy(s, in->name.str, in->name.length);
@@ -213,11 +218,11 @@
isc_db_handle dbHandle = getIscDbHandle(context);
ISC_ULONG counter = 0;
- StatusException::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
- statusVector);
+ StatusException::checkStatus(isc_wait_for_event(
+ statusVector, &dbHandle, eveLen, eveBuffer, eveResult), statusVector);
isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
- StatusException::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
- statusVector);
+ StatusException::checkStatus(isc_wait_for_event(
+ statusVector, &dbHandle, eveLen, eveBuffer, eveResult), statusVector);
isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
isc_free((char*) eveBuffer);
@@ -239,15 +244,17 @@
engine udr;
***/
FB_UDR_BEGIN_FUNCTION(sum_args)
- FB_UDR_INITIALIZE
+ // Without InMessage/OutMessage definitions, messages will be byte-based.
+
+ FB_UDR_CONSTRUCTOR
+ // , inCount(0)
{
// Get input metadata.
- AutoRelease<IMessageMetadata> inMetadata(metadata->getInputMetadata(status));
- StatusException::check(status->get());
+ AutoRelease<IMessageMetadata> inMetadata(StatusException::check(status,
+ metadata->getInputMetadata(status)));
// Get count of input parameters.
- inCount = inMetadata->getCount(status);
- StatusException::check(status->get());
+ inCount = StatusException::check(status, inMetadata->getCount(status));
inNullOffsets.reset(new unsigned[inCount]);
inOffsets.reset(new unsigned[inCount]);
@@ -255,37 +262,33 @@
for (unsigned i = 0; i < inCount; ++i)
{
// Get null offset of the i-th input parameter.
- inNullOffsets[i] = inMetadata->getNullOffset(status, i);
- StatusException::check(status->get());
+ inNullOffsets[i] = StatusException::check(status, inMetadata->getNullOffset(status, i));
// Get the offset of the i-th input parameter.
- inOffsets[i] = inMetadata->getOffset(status, i);
- StatusException::check(status->get());
+ inOffsets[i] = StatusException::check(status, inMetadata->getOffset(status, i));
}
// Get output metadata.
- AutoRelease<IMessageMetadata> outMetadata(metadata->getOutputMetadata(status));
- StatusException::check(status->get());
+ AutoRelease<IMessageMetadata> outMetadata(StatusException::check(status,
+ metadata->getOutputMetadata(status)));
// Get null offset of the return value.
- outNullOffset = outMetadata->getNullOffset(status, 0);
- StatusException::check(status->get());
+ outNullOffset = StatusException::check(status, outMetadata->getNullOffset(status, 0));
// Get offset of the return value.
- outOffset = outMetadata->getOffset(status, 0);
- StatusException::check(status->get());
+ outOffset = StatusException::check(status, outMetadata->getOffset(status, 0));
}
// This function requires the INTEGER parameters and return value, otherwise it will crash.
// Metadata is inspected dynamically (in execute). This is not the fastest method.
- FB_UDR_EXECUTE_DYNAMIC_FUNCTION
+ FB_UDR_EXECUTE_FUNCTION
{
*(ISC_SHORT*) (out + outNullOffset) = FB_FALSE;
// Get a reference to the return value.
ISC_LONG& ret = *(ISC_LONG*) (out + outOffset);
- // By default, the return value is 0.
+ // The return value is automatically initialized to 0.
///ret = 0;
for (unsigned i = 0; i < inCount; ++i)
@@ -321,38 +324,34 @@
engine udr;
***/
FB_UDR_BEGIN_PROCEDURE(gen_rows)
+ // Without InMessage/OutMessage definitions, messages will be byte-based.
+
// Procedure variables.
unsigned inOffsetStart, inOffsetEnd, outNullOffset, outOffset;
- /*** Procedure destructor.
- ~FB_UDR_PROCEDURE(gen_rows)()
- {
- }
- ***/
-
// Get offsets once per procedure.
- FB_UDR_INITIALIZE
+ FB_UDR_CONSTRUCTOR
{
- AutoRelease<IMessageMetadata> inMetadata(metadata->getInputMetadata(status));
- StatusException::check(status->get());
+ AutoRelease<IMessageMetadata> inMetadata(StatusException::check(status,
+ metadata->getInputMetadata(status)));
- inOffsetStart = inMetadata->getOffset(status, 0);
- StatusException::check(status->get());
+ inOffsetStart = StatusException::check(status, inMetadata->getOffset(status, 0));
+ inOffsetEnd = StatusException::check(status, inMetadata->getOffset(status, 1));
- inOffsetEnd = inMetadata->getOffset(status, 1);
- StatusException::check(status->get());
+ AutoRelease<IMessageMetadata> outMetadata(StatusException::check(status,
+ metadata->getOutputMetadata(status)));
- AutoRelease<IMessageMetadata> outMetadata(metadata->getOutputMetadata(status));
- StatusException::check(status->get());
+ outNullOffset = StatusException::check(status, outMetadata->getNullOffset(status, 0));
+ outOffset = StatusException::check(status, outMetadata->getOffset(status, 0));
+ }
- outNullOffset = outMetadata->getNullOffset(status, 0);
- StatusException::check(status->get());
-
- outOffset = outMetadata->getOffset(status, 0);
- StatusException::check(status->get());
+ /*** Procedure destructor.
+ FB_UDR_DESTRUCTOR
+ {
}
+ ***/
- FB_UDR_EXECUTE_DYNAMIC_PROCEDURE
+ FB_UDR_EXECUTE_PROCEDURE
{
counter = *(ISC_LONG*) (in + procedure->inOffsetStart);
end = *(ISC_LONG*) (in + procedure->inOffsetEnd);
@@ -360,13 +359,14 @@
*(ISC_SHORT*) (out + procedure->outNullOffset) = FB_FALSE;
}
+ // After procedure's execute definition, starts the result set definition.
+
FB_UDR_FETCH_PROCEDURE
{
if (counter > end)
return false;
*(ISC_LONG*) (out + procedure->outOffset) = counter++;
-
return true;
}
@@ -393,11 +393,16 @@
engine udr;
***/
FB_UDR_BEGIN_PROCEDURE(gen_rows2)
- FB_UDR_EXECUTE_MESSAGE_PROCEDURE(
+ FB_MESSAGE(InMessage,
(FB_INTEGER, start)
(FB_INTEGER, end)
- ,
- (FB_INTEGER, result))
+ );
+
+ FB_MESSAGE(OutMessage,
+ (FB_INTEGER, result)
+ );
+
+ FB_UDR_EXECUTE_PROCEDURE
{
out->resultNull = FB_FALSE;
out->result = in->start - 1;
@@ -428,33 +433,36 @@
// metadata object.
// n3 and n4 are on the ResultSet scope, i.e., each procedure execution have they own instances.
FB_UDR_BEGIN_PROCEDURE(inc)
+ FB_MESSAGE(InMessage,
+ (FB_INTEGER, count)
+ );
+
+ FB_MESSAGE(OutMessage,
+ (FB_INTEGER, n0)
+ (FB_INTEGER, n1)
+ (FB_INTEGER, n2)
+ (FB_INTEGER, n3)
+ (FB_INTEGER, n4)
+ );
+
ISC_LONG n1;
// This is how a procedure (class) initializer is written.
// ResultSet variables are not accessible here.
// If there is nothing to initialize, it can be completelly suppressed.
- FB_UDR_PROCEDURE(inc)()
- : n1(0),
+ FB_UDR_CONSTRUCTOR
+ , n1(0),
n2(0)
{
}
ISC_LONG n2;
- // FB_UDR_EXECUTE_MESSAGE_PROCEDURE or FB_UDR_EXECUTE_DYNAMIC_PROCEDURE starts the ResultSet scope.
- FB_UDR_EXECUTE_MESSAGE_PROCEDURE(
- (FB_INTEGER, count)
- ,
- (FB_INTEGER, n0)
- (FB_INTEGER, n1)
- (FB_INTEGER, n2)
- (FB_INTEGER, n3)
- (FB_INTEGER, n4))
- // This is the ResultSet (class) initializer. If there is nothing to initialize, the comma
- // should be suppressed.
- ,
- n3(procedure->n1), // n3 will start with the next value for n1 of the last execution
- n4(0)
+ // FB_UDR_EXECUTE_PROCEDURE starts the ResultSet scope.
+ FB_UDR_EXECUTE_PROCEDURE
+ // This is the ResultSet (class) initializer.
+ , n3(procedure->n1), // n3 will start with the next value for n1 of the last execution
+ n4(0)
{
out->n0Null = out->n1Null = out->n2Null = out->n3Null = out->n4Null = FB_FALSE;
@@ -472,8 +480,7 @@
ISC_LONG n3;
- // FB_UDR_FETCH must be always after FB_UDR_EXECUTE_MESSAGE_PROCEDURE or
- // FB_UDR_EXECUTE_DYNAMIC_PROCEDURE.
+ // FB_UDR_FETCH_PROCEDURE must be always after FB_UDR_EXECUTE_PROCEDURE.
FB_UDR_FETCH_PROCEDURE
{
if (out->n0++ <= in->count)
@@ -531,48 +538,27 @@
engine udr;
***/
FB_UDR_BEGIN_TRIGGER(replicate)
- /***
- FB_UDR_TRIGGER(replicate)()
- : initialized(false)
- {
- }
+ // Without FieldsMessage definition, messages will be byte-based.
- ~FB_UDR_TRIGGER(replicate)()
+ FB_UDR_CONSTRUCTOR
+ , triggerMetadata(StatusException::check(status, metadata->getTriggerMetadata(status)))
{
- if (!initialized)
- return;
- }
- ***/
-
- FB_UDR_EXECUTE_DYNAMIC_TRIGGER
- {
- ITransaction* transaction = context->getTransaction(status);
- StatusException::check(status->get());
-
- // This will not work if the table has computed fields.
- stmt->execute(status, transaction, triggerMetadata, newFields, NULL, NULL);
- StatusException::check(status->get());
- }
-
- FB_UDR_INITIALIZE
- {
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
isc_stmt_handle stmtHandle = 0;
- StatusException::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle),
- statusVector);
- StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
+ StatusException::checkStatus(isc_dsql_allocate_statement(
+ statusVector, &dbHandle, &stmtHandle), statusVector);
+ StatusException::checkStatus(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), statusVector);
- const char* table = metadata->getTriggerTable(status);
- StatusException::check(status->get());
+ const char* table = StatusException::check(status, metadata->getTriggerTable(status));
// Skip the first exclamation point, separating the module name and entry point.
- const char* info = strchr(metadata->getEntryPoint(status), '!');
- StatusException::check(status->get());
+ const char* info = StatusException::check(status,
+ strchr(metadata->getEntryPoint(status), '!'));
// Skip the second exclamation point, separating the entry point and the misc info (config).
if (info)
@@ -586,7 +572,7 @@
XSQLDA* inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
- StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle,
+ StatusException::checkStatus(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);
@@ -595,25 +581,21 @@
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
outSqlDa->version = SQLDA_VERSION1;
outSqlDa->sqln = 1;
- StatusException::check(isc_dsql_describe(statusVector, &stmtHandle,
+ StatusException::checkStatus(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';
- StatusException::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle,
+ StatusException::checkStatus(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle,
SQL_DIALECT_CURRENT, inSqlDa, outSqlDa), statusVector);
- StatusException::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare),
- statusVector);
+ StatusException::checkStatus(isc_dsql_free_statement(
+ statusVector, &stmtHandle, DSQL_unprepare), statusVector);
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
- triggerMetadata.reset(metadata->getTriggerMetadata(status));
- StatusException::check(status->get());
+ unsigned count = StatusException::check(status, triggerMetadata->getCount(status));
- unsigned count = triggerMetadata->getCount(status);
- StatusException::check(status->get());
-
char buffer[65536];
strcpy(buffer, "execute block (\n");
@@ -622,8 +604,7 @@
if (i > 0)
strcat(buffer, ",\n");
- const char* name = triggerMetadata->getField(status, i);
- StatusException::check(status->get());
+ const char* name = StatusException::check(status, triggerMetadata->getField(status, i));
strcat(buffer, " p");
sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name);
@@ -643,8 +624,7 @@
if (i > 0)
strcat(buffer, ", ");
- const char* name = triggerMetadata->getField(status, i);
- StatusException::check(status->get());
+ const char* name = StatusException::check(status, triggerMetadata->getField(status, i));
strcat(buffer, "\"");
strcat(buffer, name);
@@ -674,75 +654,65 @@
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
- IAttachment* attachment = context->getAttachment(status);
- StatusException::check(status->get());
+ IAttachment* attachment = StatusException::check(status, context->getAttachment(status));
+ ITransaction* transaction = StatusException::check(status, context->getTransaction(status));
- ITransaction* transaction = context->getTransaction(status);
- StatusException::check(status->get());
+ stmt.reset(StatusException::check(status,
+ attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0)));
- stmt.reset(attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0));
-
delete [] outSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(outSqlDa);
+ }
- ///initialized = true;
+ /***
+ FB_UDR_DESTRUCTOR
+ {
}
+ ***/
- ///bool initialized;
+ FB_UDR_EXECUTE_TRIGGER
+ {
+ ITransaction* transaction = StatusException::check(status, context->getTransaction(status));
+
+ // This will not work if the table has computed fields.
+ stmt->execute(status, transaction, triggerMetadata, newFields, NULL, NULL);
+ StatusException::check(status->get());
+ }
+
AutoRelease<IMessageMetadata> triggerMetadata;
AutoRelease<IStatement> stmt;
FB_UDR_END_TRIGGER
FB_UDR_BEGIN_TRIGGER(replicate_persons)
- /***
- FB_UDR_TRIGGER(replicate_persons)()
- : initialized(false)
- {
- }
-
- ~FB_UDR_TRIGGER(replicate_persons)()
- {
- if (!initialized)
- return;
- }
- ***/
-
// Order of fields does not need to match the fields order in the table, but it should match
// the order of fields in the SQL command constructed in the initialization.
- FB_UDR_EXECUTE_MESSAGE_TRIGGER(
+ FB_TRIGGER_MESSAGE(FieldsMessage,
(FB_INTEGER, id, "ID")
(FB_BLOB, info, "INFO")
(FB_VARCHAR(60 * 4), address, "ADDRESS")
(FB_VARCHAR(60 * 4), name, "NAME")
- )
- {
- ITransaction* transaction = context->getTransaction(status);
- StatusException::check(status->get());
+ );
- stmt->execute(status, transaction, triggerMetadata, newFields, NULL, NULL);
- StatusException::check(status->get());
- }
-
- FB_UDR_INITIALIZE
+ FB_UDR_CONSTRUCTOR
+ , triggerMetadata(StatusException::check(status, metadata->getTriggerMetadata(status)))
{
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
isc_stmt_handle stmtHandle = 0;
- StatusException::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle),
- statusVector);
- StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
+ StatusException::checkStatus(isc_dsql_allocate_statement(
+ statusVector, &dbHandle, &stmtHandle), statusVector);
+ StatusException::checkStatus(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), statusVector);
- const char* table = metadata->getTriggerTable(status);
- StatusException::check(status->get());
+ const char* table = StatusException::check(status, metadata->getTriggerTable(status));
// Skip the first exclamation point, separating the module name and entry point.
- const char* info = strchr(metadata->getEntryPoint(status), '!');
- StatusException::check(status->get());
+ const char* info = StatusException::check(status,
+ strchr(metadata->getEntryPoint(status), '!'));
// Skip the second exclamation point, separating the entry point and the misc info (config).
if (info)
@@ -756,8 +726,8 @@
XSQLDA* inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
- StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle,
- SQL_DIALECT_CURRENT, inSqlDa), statusVector);
+ StatusException::checkStatus(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);
*reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(info);
@@ -765,22 +735,19 @@
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
outSqlDa->version = SQLDA_VERSION1;
outSqlDa->sqln = 1;
- StatusException::check(isc_dsql_describe(statusVector, &stmtHandle,
- SQL_DIALECT_CURRENT, outSqlDa), statusVector);
+ StatusException::checkStatus(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';
- StatusException::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle,
+ StatusException::checkStatus(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle,
SQL_DIALECT_CURRENT, inSqlDa, outSqlDa), statusVector);
- StatusException::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare),
- statusVector);
+ StatusException::checkStatus(isc_dsql_free_statement(
+ statusVector, &stmtHandle, DSQL_unprepare), statusVector);
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
- triggerMetadata.reset(metadata->getTriggerMetadata(status));
- StatusException::check(status->get());
-
char buffer[65536];
strcpy(buffer,
"execute block (\n"
@@ -797,21 +764,30 @@
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
- IAttachment* attachment = context->getAttachment(status);
- StatusException::check(status->get());
+ IAttachment* attachment = StatusException::check(status, context->getAttachment(status));
+ ITransaction* transaction = StatusException::check(status, context->getTransaction(status));
- ITransaction* transaction = context->getTransaction(status);
- StatusException::check(status->get());
+ stmt.reset(StatusException::check(status,
+ attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0)));
- stmt.reset(attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0));
-
delete [] outSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(outSqlDa);
+ }
- ///initialized = true;
+ /***
+ FB_UDR_DESTRUCTOR
+ {
}
+ ***/
- ///bool initialized;
+ FB_UDR_EXECUTE_TRIGGER
+ {
+ ITransaction* transaction = StatusException::check(status, context->getTransaction(status));
+
+ stmt->execute(status, transaction, triggerMetadata, newFields, NULL, NULL);
+ StatusException::check(status->get());
+ }
+
AutoRelease<IMessageMetadata> triggerMetadata;
AutoRelease<IStatement> stmt;
FB_UDR_END_TRIGGER
Modified: firebird/trunk/src/include/firebird/ExternalEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/ExternalEngine.h 2013-06-06 15:07:54 UTC (rev 58160)
+++ firebird/trunk/src/include/firebird/ExternalEngine.h 2013-06-06 16:05:02 UTC (rev 58161)
@@ -81,7 +81,7 @@
class ExternalResultSet : public IDisposable
{
public:
- virtual bool FB_CARG fetch(IStatus* status) = 0;
+ virtual FB_BOOLEAN FB_CARG fetch(IStatus* status) = 0;
};
#define FB_EXTERNAL_RESULT_SET_VERSION (FB_DISPOSABLE_VERSION + 1)
Modified: firebird/trunk/src/include/firebird/UdrCppEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrCppEngine.h 2013-06-06 15:07:54 UTC (rev 58160)
+++ firebird/trunk/src/include/firebird/UdrCppEngine.h 2013-06-06 16:05:02 UTC (rev 58161)
@@ -40,51 +40,23 @@
//------------------------------------------------------------------------------
-#define FB_UDR_FUNCTION(name) Func##name
-#define FB_UDR_PROCEDURE(name) Proc##name
-#define FB_UDR_TRIGGER(name) Trig##name
-
-
#define FB_UDR_BEGIN_FUNCTION(name) \
- class FB_UDR_FUNCTION(name); \
- \
- ::Firebird::Udr::FunctionFactoryImpl<FB_UDR_FUNCTION(name)> FuncFactory##name(#name); \
- \
- class FB_UDR_FUNCTION(name) : public ::Firebird::Udr::Function<FB_UDR_FUNCTION(name)> \
+ namespace Func##name \
{ \
- public: \
- void initialize(::Firebird::IStatus* /*status*/, void*) \
+ class Impl; \
+ \
+ static ::Firebird::Udr::FunctionFactoryImpl<Impl> factory(#name); \
+ \
+ class Impl : public ::Firebird::Udr::Function<Impl> \
{ \
- }
+ public: \
+ FB__UDR_COMMON_IMPL
#define FB_UDR_END_FUNCTION \
- };
+ }; \
+ }
-#define FB_UDR_EXECUTE_DYNAMIC_FUNCTION \
- FB__UDR_DYNAMIC_TYPE(InMessage); \
- FB__UDR_DYNAMIC_TYPE(OutMessage); \
- \
- FB__UDR_EXECUTE_FUNCTION
-
-#define FB_UDR_EXECUTE_MESSAGE_FUNCTION(inputs, output) \
- FB_MESSAGE(InMessage, \
- inputs \
- ); \
- FB_MESSAGE(OutMessage, \
- output \
- ); \
- \
- FB__UDR_EXECUTE_FUNCTION
-
-#define FB_UDR_EXECUTE_MESSAGE_FUNCTION_OUT(outputs) \
- FB__UDR_DYNAMIC_TYPE(InMessage); \
- FB_MESSAGE(OutMessage, \
- outputs \
- ); \
- \
- FB__UDR_EXECUTE_FUNCTION
-
-#define FB__UDR_EXECUTE_FUNCTION \
+#define FB_UDR_EXECUTE_FUNCTION \
virtual void FB_CARG execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
void* in, void* out) \
{ \
@@ -100,56 +72,23 @@
#define FB_UDR_BEGIN_PROCEDURE(name) \
- class FB_UDR_PROCEDURE(name); \
- \
- ::Firebird::Udr::ProcedureFactoryImpl<FB_UDR_PROCEDURE(name)> ProcFactory##name(#name); \
- \
- class FB_UDR_PROCEDURE(name) : public ::Firebird::Udr::Procedure<FB_UDR_PROCEDURE(name)> \
+ namespace Proc##name \
{ \
- public: \
- typedef FB_UDR_PROCEDURE(name) This; \
+ class Impl; \
\
- void initialize(::Firebird::IStatus* /*status*/, void*) \
+ static ::Firebird::Udr::ProcedureFactoryImpl<Impl> factory(#name); \
+ \
+ class Impl : public ::Firebird::Udr::Procedure<Impl> \
{ \
- }
+ public: \
+ FB__UDR_COMMON_IMPL
#define FB_UDR_END_PROCEDURE \
+ }; \
}; \
- };
+ }
-#define FB_UDR_EXECUTE_DYNAMIC_PROCEDURE \
- FB__UDR_DYNAMIC_TYPE(InMessage); \
- FB__UDR_DYNAMIC_TYPE(OutMessage); \
- \
- FB__UDR_EXECUTE_PROCEDURE
-
-#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE(inputs, outputs) \
- FB_MESSAGE(InMessage, \
- inputs \
- ); \
- FB_MESSAGE(OutMessage, \
- outputs \
- ); \
- \
- FB__UDR_EXECUTE_PROCEDURE
-
-#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE_IN(inputs) \
- FB_MESSAGE(InMessage, \
- inputs \
- ); \
- FB__UDR_DYNAMIC_TYPE(OutMessage); \
- \
- FB__UDR_EXECUTE_PROCEDURE
-
-#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE_OUT(outputs) \
- FB__UDR_DYNAMIC_TYPE(InMessage); \
- FB_MESSAGE(OutMessage, \
- outputs \
- ); \
- \
- FB__UDR_EXECUTE_PROCEDURE
-
-#define FB__UDR_EXECUTE_PROCEDURE \
+#define FB_UDR_EXECUTE_PROCEDURE \
virtual ::Firebird::ExternalResultSet* FB_CARG open(::Firebird::IStatus* status, \
::Firebird::ExternalContext* context, void* in, void* out) \
{ \
@@ -159,61 +98,49 @@
} \
FB__UDR_CATCH \
\
- return 0; \
+ return NULL; \
} \
\
- class ResultSet : public ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage> \
+ class ResultSet : public ::Firebird::Udr::ResultSet<ResultSet, Impl, InMessage, OutMessage> \
{ \
public: \
ResultSet(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
- This* const procedure, InMessage::Type* const in, OutMessage::Type* const out) \
- : ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage>( \
+ Impl* const procedure, InMessage::Type* const in, OutMessage::Type* const out) \
+ : ::Firebird::Udr::ResultSet<ResultSet, Impl, InMessage, OutMessage>( \
context, procedure, in, out)
#define FB_UDR_FETCH_PROCEDURE \
- virtual bool FB_CARG fetch(::Firebird::IStatus* status) \
+ virtual FB_BOOLEAN FB_CARG fetch(::Firebird::IStatus* status) \
{ \
try \
{ \
- return internalFetch(status); \
+ return (FB_BOOLEAN) internalFetch(status); \
} \
FB__UDR_CATCH \
\
- return 0; \
+ return FB_FALSE; \
} \
\
bool internalFetch(::Firebird::IStatus* status)
#define FB_UDR_BEGIN_TRIGGER(name) \
- class FB_UDR_TRIGGER(name); \
- \
- ::Firebird::Udr::TriggerFactoryImpl<FB_UDR_TRIGGER(name)> TrigFactory##name(#name); \
- \
- class FB_UDR_TRIGGER(name) : public ::Firebird::Udr::Trigger<FB_UDR_TRIGGER(name)> \
+ namespace Trig##name \
{ \
- public: \
+ class Impl; \
\
- void initialize(::Firebird::IStatus* /*status*/, void*) \
+ static ::Firebird::Udr::TriggerFactoryImpl<Impl> factory(#name); \
+ \
+ class Impl : public ::Firebird::Udr::Trigger<Impl> \
{ \
- }
+ public: \
+ FB__UDR_COMMON_IMPL
#define FB_UDR_END_TRIGGER \
- };
+ }; \
+ }
-#define FB_UDR_EXECUTE_DYNAMIC_TRIGGER \
- FB__UDR_DYNAMIC_TYPE(FieldsMessage); \
- \
- FB__UDR_EXECUTE_TRIGGER
-
-#define FB_UDR_EXECUTE_MESSAGE_TRIGGER(fields) \
- FB_TRIGGER_MESSAGE(FieldsMessage, \
- fields \
- ); \
- \
- FB__UDR_EXECUTE_TRIGGER
-
-#define FB__UDR_EXECUTE_TRIGGER \
+#define FB_UDR_EXECUTE_TRIGGER \
virtual void FB_CARG execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
::Firebird::ExternalTrigger::Action action, void* oldFields, void* newFields) \
{ \
@@ -230,27 +157,34 @@
FieldsMessage::Type* oldFields, FieldsMessage::Type* newFields)
-#define FB_UDR_INITIALIZE \
- void initialize(::Firebird::IStatus* status, ExternalContext* context) \
+#define FB_UDR_CONSTRUCTOR \
+ Impl(::Firebird::IStatus* const status, ExternalContext* const context, \
+ const IRoutineMetadata* const metadata__) \
+ : master(context->getMaster()), \
+ metadata(metadata__)
+
+#define FB_UDR_DESTRUCTOR \
+ ~Impl()
+
+
+#define FB__UDR_COMMON_IMPL \
+ Impl(const void* const, ExternalContext* const context, \
+ const IRoutineMetadata* const aMetadata) \
+ : master(context->getMaster()), \
+ metadata(aMetadata) \
{ \
- try \
- { \
- internalInitialize(status, context); \
- } \
- FB__UDR_CATCH \
} \
\
- void internalInitialize(::Firebird::IStatus* status, ::Firebird::ExternalContext* context)
+ IMaster* master; \
+ const IRoutineMetadata* metadata;
-
-#define FB__UDR_DYNAMIC_TYPE(name) \
+#define FB__UDR_COMMON_TYPE(name) \
struct name \
{ \
typedef unsigned char Type; \
static void setup(::Firebird::IStatus*, ::Firebird::IMetadataBuilder*) {} \
}
-
#define FB__UDR_CATCH \
catch (const ::Firebird::Udr::StatusException& e) \
{ \
@@ -313,7 +247,7 @@
throw StatusException(vector);
}
- static void check(ISC_STATUS status, const ISC_STATUS* vector)
+ static void checkStatus(ISC_STATUS status, const ISC_STATUS* vector)
{
if (status == 0)
return;
@@ -321,6 +255,13 @@
check(vector);
}
+ template <typename T>
+ static T check(IStatus* status, T value)
+ {
+ check(status->get());
+ return value;
+ }
+
public:
const ISC_STATUS* getStatusVector() const
{
@@ -479,22 +420,13 @@
};
-// This class is used to fix an apparent bug with clang, where the object is wrongly initialized
-// and overwrites the members set in the operator new.
-template <typename T>
-class Routine : public T
-{
-public:
- Routine()
- {
- }
-};
-
-
template <typename This>
class Function : public ExternalFunction, public Helper
{
public:
+ FB__UDR_COMMON_TYPE(InMessage);
+ FB__UDR_COMMON_TYPE(OutMessage);
+
virtual int FB_CARG getVersion()
{
return FB_EXTERNAL_FUNCTION_VERSION;
@@ -514,23 +446,6 @@
Utf8* /*name*/, uint /*nameSize*/)
{
}
-
- void* operator new(size_t size, IMaster* master, const IRoutineMetadata* metadata)
- {
- Function* p = reinterpret_cast<Function*>(::new char[size]);
- p->master = master;
- p->metadata = metadata;
- return p;
- }
-
- void operator delete(void* p)
- {
- ::delete [] static_cast<char*>(p);
- }
-
-public:
- IMaster* master;
- const IRoutineMetadata* metadata;
};
@@ -538,6 +453,9 @@
class Procedure : public ExternalProcedure, public Helper
{
public:
+ FB__UDR_COMMON_TYPE(InMessage);
+ FB__UDR_COMMON_TYPE(OutMessage);
+
virtual int FB_CARG getVersion()
{
return FB_EXTERNAL_PROCEDURE_VERSION;
@@ -557,23 +475,6 @@
Utf8* /*name*/, uint /*nameSize*/)
{
}
-
- void* operator new(size_t size, IMaster* master, const IRoutineMetadata* metadata)
- {
- Procedure* p = reinterpret_cast<Procedure*>(::new char[size]);
- p->master = master;
- p->metadata = metadata;
- return p;
- }
-
- void operator delete(void* p)
- {
- ::delete [] static_cast<char*>(p);
- }
-
-public:
- IMaster* master;
- const IRoutineMetadata* metadata;
};
@@ -581,6 +482,8 @@
class Trigger : public ExternalTrigger, public Helper
{
public:
+ FB__UDR_COMMON_TYPE(FieldsMessage);
+
virtual int FB_CARG getVersion()
{
return FB_EXTERNAL_TRIGGER_VERSION;
@@ -600,23 +503,6 @@
Utf8* /*name*/, uint /*nameSize*/)
{
}
-
- void* operator new(size_t size, IMaster* master, const IRoutineMetadata* metadata)
- {
- Trigger* p = reinterpret_cast<Trigger*>(::new char[size]);
- p->master = master;
- p->metadata = metadata;
- return p;
- }
-
- void operator delete(void* p)
- {
- ::delete [] static_cast<char*>(p);
- }
-
-public:
- IMaster* master;
- const IRoutineMetadata* metadata;
};
@@ -638,9 +524,13 @@
virtual ExternalFunction* FB_CARG newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
- T* obj = new(context->getMaster(), metadata) Routine<T>;
- obj->initialize(status, context);
- return obj;
+ try
+ {
+ return new T(status, context, metadata);
+ }
+ FB__UDR_CATCH
+
+ return NULL;
}
};
@@ -663,9 +553,13 @@
virtual ExternalProcedure* FB_CARG newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
- T* obj = new(context->getMaster(), metadata) Routine<T>;
- obj->initialize(status, context);
- return obj;
+ try
+ {
+ return new T(status, context, metadata);
+ }
+ FB__UDR_CATCH
+
+ return NULL;
}
};
@@ -687,9 +581,13 @@
virtual ExternalTrigger* FB_CARG newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
- T* obj = new(context->getMaster(), metadata) Routine<T>;
- obj->initialize(status, context);
- return obj;
+ try
+ {
+ return new T(status, context, metadata);
+ }
+ FB__UDR_CATCH
+
+ return NULL;
}
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|