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. |