From: <asf...@us...> - 2012-05-29 16:02:48
|
Revision: 54564 http://firebird.svn.sourceforge.net/firebird/?rev=54564&view=rev Author: asfernandes Date: 2012-05-29 16:02:39 +0000 (Tue, 29 May 2012) Log Message: ----------- 1) Change UdrCpp triggers macros to match procedures and functions - first phase. 2) Adjustments to procedures and functions. Modified Paths: -------------- firebird/trunk/examples/udr/UdrCppExample.cpp firebird/trunk/src/include/firebird/UdrCppEngine.h Modified: firebird/trunk/examples/udr/UdrCppExample.cpp =================================================================== --- firebird/trunk/examples/udr/UdrCppExample.cpp 2012-05-29 12:30:32 UTC (rev 54563) +++ firebird/trunk/examples/udr/UdrCppExample.cpp 2012-05-29 16:02:39 UTC (rev 54564) @@ -829,271 +829,263 @@ external name 'udrcpp_example!replicate!ds1' engine udr; ***/ -FB_UDR_BEGIN_DECLARE_TRIGGER(replicate) -public: - FB_UDR_TRIGGER(replicate)(); - ~FB_UDR_TRIGGER(replicate)(); - -private: - void initialize(ExternalContext* context); - - bool initialized; - XSQLDA* inSqlDa; - isc_stmt_handle stmtHandle; -FB_UDR_END_DECLARE_TRIGGER(replicate) - - -FB_UDR_TRIGGER(replicate)::FB_UDR_TRIGGER(replicate)() - : initialized(false) -{ -} - -FB_UDR_TRIGGER(replicate)::~FB_UDR_TRIGGER(replicate)() -{ - if (!initialized) - return; - - for (int i = 0; i < inSqlDa->sqln; ++i) +FB_UDR_BEGIN_TRIGGER(replicate) + FB_UDR_TRIGGER(replicate)() + : initialized(false) { - XSQLVAR* var = &inSqlDa->sqlvar[i]; - delete [] var->sqldata; - delete var->sqlind; } - delete [] reinterpret_cast<char*>(inSqlDa); + ~FB_UDR_TRIGGER(replicate)() + { + if (!initialized) + return; - ISC_STATUS_ARRAY statusVector = {0}; - isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_drop); -} + for (int i = 0; i < inSqlDa->sqln; ++i) + { + XSQLVAR* var = &inSqlDa->sqlvar[i]; + delete [] var->sqldata; + delete var->sqlind; + } -void FB_UDR_TRIGGER(replicate)::initialize(ExternalContext* context) -{ - if (initialized) - return; + delete [] reinterpret_cast<char*>(inSqlDa); - ISC_STATUS_ARRAY statusVector = {0}; - isc_db_handle dbHandle = getIscDbHandle(context); - isc_tr_handle trHandle = getIscTrHandle(context); + ISC_STATUS_ARRAY statusVector = {0}; + isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_drop); + } - 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); + FB_UDR_EXECUTE_DYNAMIC_TRIGGER + { + initialize(context); - AutoDispose<IStatus> status(master->getStatus()); + AutoDispose<IStatus> status(master->getStatus()); - const char* table = metadata->getTriggerTable(status); - ThrowError::check(status->get()); + const IParametersMetadata* fields = metadata->getTriggerFields(status); + ThrowError::check(status->get()); - // Skip the first exclamation point, separing the module name and entry point. - const char* info = strchr(metadata->getEntryPoint(status), '!'); - ThrowError::check(status->get()); + unsigned fieldsCount = fields->getCount(status); + ThrowError::check(status->get()); - // Skip the second exclamation point, separing the entry point and the misc info (config). - if (info) - info = strchr(info + 1, '!'); + MessageImpl message(fieldsCount, newMsg); - if (info) - ++info; - else - info = ""; + ISC_STATUS_ARRAY statusVector = {0}; + isc_db_handle dbHandle = getIscDbHandle(context); + isc_tr_handle trHandle = getIscTrHandle(context); - inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]); - inSqlDa->version = SQLDA_VERSION1; - inSqlDa->sqln = 1; - 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); - *reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(info); + for (unsigned i = 1; i <= fieldsCount; ++i) + { + ParamDesc<void*> field(message, fields); - XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]); - outSqlDa->version = SQLDA_VERSION1; - outSqlDa->sqln = 1; - 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'; + XSQLVAR* var = &inSqlDa->sqlvar[i - 1]; - ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT, - inSqlDa, outSqlDa), statusVector); - ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector); + if (message.isNull(field)) + *var->sqlind = -1; + else + { + *var->sqlind = 0; + memcpy(var->sqldata, message[field], var->sqllen); + } + } - delete [] inSqlDa->sqlvar[0].sqldata; - delete [] reinterpret_cast<char*>(inSqlDa); - inSqlDa = NULL; + ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT, + inSqlDa), statusVector); + } - const IParametersMetadata* fields = metadata->getTriggerFields(status); - ThrowError::check(status->get()); +private: + void initialize(ExternalContext* context) + { + if (initialized) + return; - unsigned count = fields->getCount(status); - ThrowError::check(status->get()); + ISC_STATUS_ARRAY statusVector = {0}; + isc_db_handle dbHandle = getIscDbHandle(context); + isc_tr_handle trHandle = getIscTrHandle(context); - char buffer[65536]; - strcpy(buffer, "execute block (\n"); + 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); - for (unsigned i = 0; i < count; ++i) - { - if (i > 0) - strcat(buffer, ",\n"); + AutoDispose<IStatus> status(master->getStatus()); - const char* name = fields->getField(status, i); + const char* table = metadata->getTriggerTable(status); ThrowError::check(status->get()); - strcat(buffer, " p"); - sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name); - } + // Skip the first exclamation point, separing the module name and entry point. + const char* info = strchr(metadata->getEntryPoint(status), '!'); + ThrowError::check(status->get()); - strcat(buffer, - ")\n" - "as\n" - "begin\n" - " execute statement ('insert into \""); + // Skip the second exclamation point, separing the entry point and the misc info (config). + if (info) + info = strchr(info + 1, '!'); - strcat(buffer, table); - strcat(buffer, "\" ("); + if (info) + ++info; + else + info = ""; - for (unsigned i = 0; i < count; ++i) - { - if (i > 0) - strcat(buffer, ", "); + inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]); + inSqlDa->version = SQLDA_VERSION1; + inSqlDa->sqln = 1; + 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); + *reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(info); - const char* name = fields->getField(status, i); - ThrowError::check(status->get()); + XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]); + outSqlDa->version = SQLDA_VERSION1; + outSqlDa->sqln = 1; + 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'; - strcat(buffer, "\""); - strcat(buffer, name); - strcat(buffer, "\""); - } + ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT, + inSqlDa, outSqlDa), statusVector); + ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector); - strcat(buffer, ") values ("); + delete [] inSqlDa->sqlvar[0].sqldata; + delete [] reinterpret_cast<char*>(inSqlDa); + inSqlDa = NULL; - for (unsigned i = 0; i < count; ++i) - { - if (i > 0) - strcat(buffer, ", "); - strcat(buffer, "?"); - } + const IParametersMetadata* fields = metadata->getTriggerFields(status); + ThrowError::check(status->get()); - strcat(buffer, ")') ("); + unsigned count = fields->getCount(status); + ThrowError::check(status->get()); - for (unsigned i = 0; i < count; ++i) - { - if (i > 0) - strcat(buffer, ", "); - strcat(buffer, ":p"); - sprintf(buffer + strlen(buffer), "%d", i); - } + char buffer[65536]; + strcpy(buffer, "execute block (\n"); - strcat(buffer, ")\n on external data source '"); - strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short)); - strcat(buffer, "';\nend"); + for (unsigned i = 0; i < count; ++i) + { + if (i > 0) + strcat(buffer, ",\n"); - ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer, - SQL_DIALECT_CURRENT, NULL), statusVector); + const char* name = fields->getField(status, i); + ThrowError::check(status->get()); - inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(count))]); - inSqlDa->version = SQLDA_VERSION1; - inSqlDa->sqln = count; - ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa), - statusVector); + strcat(buffer, " p"); + sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name); + } - for (unsigned i = 0; i < count; ++i) - { - XSQLVAR* var = &inSqlDa->sqlvar[i]; + strcat(buffer, + ")\n" + "as\n" + "begin\n" + " execute statement ('insert into \""); - switch (var->sqltype & ~1) + strcat(buffer, table); + strcat(buffer, "\" ("); + + for (unsigned i = 0; i < count; ++i) { - case SQL_TEXT: - var->sqldata = new char[var->sqllen]; - break; + if (i > 0) + strcat(buffer, ", "); - case SQL_VARYING: - var->sqldata = new char[var->sqllen]; - var->sqllen += sizeof(short); - break; + const char* name = fields->getField(status, i); + ThrowError::check(status->get()); - case SQL_SHORT: - var->sqldata = new char[sizeof(short)]; - break; + strcat(buffer, "\""); + strcat(buffer, name); + strcat(buffer, "\""); + } - case SQL_LONG: - var->sqldata = new char[sizeof(int32)]; - break; + strcat(buffer, ") values ("); - case SQL_INT64: - var->sqldata = new char[sizeof(int64)]; - break; + for (unsigned i = 0; i < count; ++i) + { + if (i > 0) + strcat(buffer, ", "); + strcat(buffer, "?"); + } - case SQL_FLOAT: - var->sqltype = SQL_DOUBLE | (var->sqltype & 1); - var->sqllen = sizeof(double); - // fall into + strcat(buffer, ")') ("); - case SQL_DOUBLE: - var->sqldata = new char[sizeof(double)]; - break; + for (unsigned i = 0; i < count; ++i) + { + if (i > 0) + strcat(buffer, ", "); + strcat(buffer, ":p"); + sprintf(buffer + strlen(buffer), "%d", i); + } - case SQL_TYPE_DATE: - var->sqldata = new char[sizeof(ISC_DATE)]; - break; + strcat(buffer, ")\n on external data source '"); + strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short)); + strcat(buffer, "';\nend"); - //// TODO: SQL_TIMESTAMP, SQL_TYPE_TIME + ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer, + SQL_DIALECT_CURRENT, NULL), statusVector); - case SQL_BLOB: - var->sqldata = new char[sizeof(ISC_QUAD)]; - break; + inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(count))]); + inSqlDa->version = SQLDA_VERSION1; + inSqlDa->sqln = count; + ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa), + statusVector); - default: - assert(false); - } + for (unsigned i = 0; i < count; ++i) + { + XSQLVAR* var = &inSqlDa->sqlvar[i]; - var->sqltype |= 1; - var->sqlind = new short; - *reinterpret_cast<short*>(var->sqlind) = -1; - } + switch (var->sqltype & ~1) + { + case SQL_TEXT: + var->sqldata = new char[var->sqllen]; + break; - delete [] outSqlDa->sqlvar[0].sqldata; - delete [] reinterpret_cast<char*>(outSqlDa); + case SQL_VARYING: + var->sqldata = new char[var->sqllen]; + var->sqllen += sizeof(short); + break; - initialized = true; -} + case SQL_SHORT: + var->sqldata = new char[sizeof(short)]; + break; -FB_UDR_BEGIN_TRIGGER(replicate) -{ - initialize(context); + case SQL_LONG: + var->sqldata = new char[sizeof(int32)]; + break; - AutoDispose<IStatus> status(master->getStatus()); + case SQL_INT64: + var->sqldata = new char[sizeof(int64)]; + break; - const IParametersMetadata* fields = metadata->getTriggerFields(status); - ThrowError::check(status->get()); + case SQL_FLOAT: + var->sqltype = SQL_DOUBLE | (var->sqltype & 1); + var->sqllen = sizeof(double); + // fall into - unsigned fieldsCount = fields->getCount(status); - ThrowError::check(status->get()); + case SQL_DOUBLE: + var->sqldata = new char[sizeof(double)]; + break; - MessageImpl message(fieldsCount, newMsg); + case SQL_TYPE_DATE: + var->sqldata = new char[sizeof(ISC_DATE)]; + break; - ISC_STATUS_ARRAY statusVector = {0}; - isc_db_handle dbHandle = getIscDbHandle(context); - isc_tr_handle trHandle = getIscTrHandle(context); + //// TODO: SQL_TIMESTAMP, SQL_TYPE_TIME - for (unsigned i = 1; i <= fieldsCount; ++i) - { - ParamDesc<void*> field(message, fields); + case SQL_BLOB: + var->sqldata = new char[sizeof(ISC_QUAD)]; + break; - XSQLVAR* var = &inSqlDa->sqlvar[i - 1]; + default: + assert(false); + } - if (message.isNull(field)) - *var->sqlind = -1; - else - { - *var->sqlind = 0; - memcpy(var->sqldata, message[field], var->sqllen); + var->sqltype |= 1; + var->sqlind = new short; + *reinterpret_cast<short*>(var->sqlind) = -1; } + + delete [] outSqlDa->sqlvar[0].sqldata; + delete [] reinterpret_cast<char*>(outSqlDa); + + initialized = true; } - ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT, - inSqlDa), statusVector); -} -FB_UDR_END_TRIGGER(replicate) + bool initialized; + XSQLDA* inSqlDa; + isc_stmt_handle stmtHandle; +FB_UDR_END_TRIGGER Modified: firebird/trunk/src/include/firebird/UdrCppEngine.h =================================================================== --- firebird/trunk/src/include/firebird/UdrCppEngine.h 2012-05-29 12:30:32 UTC (rev 54563) +++ firebird/trunk/src/include/firebird/UdrCppEngine.h 2012-05-29 16:02:39 UTC (rev 54564) @@ -87,7 +87,7 @@ { \ try \ { \ - execute(error, context, (InMessage*) inMsg, (OutMessage*) outMsg); \ + internalExecute(error, context, (InMessage*) inMsg, (OutMessage*) outMsg); \ } \ catch (const ::Firebird::Udr::ThrowError::Exception& e) \ { \ @@ -103,7 +103,7 @@ } \ } \ \ - virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \ + void FB_CALL internalExecute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \ InMessage* in, OutMessage* out) @@ -190,7 +190,7 @@ { \ try \ { \ - return fetch0(error); \ + return internalFetch(error); \ } \ catch (const ::Firebird::Udr::ThrowError::Exception& e) \ { \ @@ -208,32 +208,31 @@ return 0; \ } \ \ - bool FB_CALL fetch0(::Firebird::Error* error) + bool FB_CALL internalFetch(::Firebird::Error* error) -#define FB_UDR_BEGIN_DECLARE_TRIGGER(name) \ +#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)> \ { \ - public: \ - virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \ - ::Firebird::ExternalTrigger::Action action, void* oldMsg, void* newMsg); + public: -#define FB_UDR_END_DECLARE_TRIGGER(name) \ +#define FB_UDR_END_TRIGGER \ }; -#define FB_UDR_DECLARE_TRIGGER(name) \ - FB_UDR_BEGIN_DECLARE_TRIGGER(name) \ - FB_UDR_END_DECLARE_TRIGGER(name) +#define FB_UDR_EXECUTE_DYNAMIC_TRIGGER \ + FB_UDR_EXECUTE__TRIGGER -#define FB_UDR_BEGIN_TRIGGER(name) \ - void FB_CALL FB_UDR_TRIGGER(name)::execute(::Firebird::Error* error, \ - ::Firebird::ExternalContext* context, ::Firebird::ExternalTrigger::Action action, \ - void* oldMsg, void* newMsg) \ +#define FB_UDR_EXECUTE__TRIGGER \ + virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \ + ::Firebird::ExternalTrigger::Action action, void* oldMsg, void* newMsg) \ { \ try \ - { - -#define FB_UDR_END_TRIGGER(name) \ + { \ + internalExecute(error, context, action, oldMsg, newMsg); \ } \ catch (const ::Firebird::Udr::ThrowError::Exception& e) \ { \ @@ -248,7 +247,9 @@ strlen(FB_UDR_UNRECOGNIZED_EXCEPTION)); \ } \ } \ - ::Firebird::Udr::TriggerFactoryImpl<FB_UDR_TRIGGER(name)> TrigFactory##name(#name); + \ + void FB_CALL internalExecute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \ + ::Firebird::ExternalTrigger::Action action, void* oldMsg, void* newMsg) #define FB_UDR_UNRECOGNIZED_EXCEPTION "Unrecognized C++ exception" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |