diff --git a/builds/posix/Makefile.in.plugins_examples b/builds/posix/Makefile.in.plugins_examples index 6c4f398ac2..a6cfcefab2 100644 --- a/builds/posix/Makefile.in.plugins_examples +++ b/builds/posix/Makefile.in.plugins_examples @@ -55,7 +55,10 @@ LINK_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,../$(PLUGIN_VERS)) all: udrcpp_example dc_example kh_example -UDR_Objects = $(call makeObjects,../examples/udr,UdrCppExample.cpp) +UDR_Objects = $(call makeObjects,../examples/udr,Functions.cpp) \ + $(call makeObjects,../examples/udr,Procedures.cpp) \ + $(call makeObjects,../examples/udr,Triggers.cpp) + UDR_Plugin = $(PLUGINS)/udr/$(LIB_PREFIX)udrcpp_example.$(SHRLIB_EXT) AllObjects = $(UDR_Objects) diff --git a/builds/win32/msvc10/udrcpp_example.vcxproj b/builds/win32/msvc10/udrcpp_example.vcxproj index 526668b476..50831ea7c2 100644 --- a/builds/win32/msvc10/udrcpp_example.vcxproj +++ b/builds/win32/msvc10/udrcpp_example.vcxproj @@ -194,10 +194,13 @@ - + - + + + + diff --git a/builds/win32/msvc10/udrcpp_example.vcxproj.filters b/builds/win32/msvc10/udrcpp_example.vcxproj.filters index e19830b6b1..a8a401974c 100644 --- a/builds/win32/msvc10/udrcpp_example.vcxproj.filters +++ b/builds/win32/msvc10/udrcpp_example.vcxproj.filters @@ -14,18 +14,23 @@ - + Source files - - Header files - + + Source files + + + + + Source files + Resource files - \ No newline at end of file + diff --git a/builds/win32/msvc12/udrcpp_example.vcxproj b/builds/win32/msvc12/udrcpp_example.vcxproj index e25e985cef..62a7fb760f 100644 --- a/builds/win32/msvc12/udrcpp_example.vcxproj +++ b/builds/win32/msvc12/udrcpp_example.vcxproj @@ -198,10 +198,13 @@ - + - + + + + diff --git a/builds/win32/msvc12/udrcpp_example.vcxproj.filters b/builds/win32/msvc12/udrcpp_example.vcxproj.filters index e19830b6b1..a8a401974c 100644 --- a/builds/win32/msvc12/udrcpp_example.vcxproj.filters +++ b/builds/win32/msvc12/udrcpp_example.vcxproj.filters @@ -14,18 +14,23 @@ - + Source files - - Header files - + + Source files + + + + + Source files + Resource files - \ No newline at end of file + diff --git a/builds/win32/msvc8/udrcpp_example.vcproj b/builds/win32/msvc8/udrcpp_example.vcproj index 58119937af..eee7f32717 100644 --- a/builds/win32/msvc8/udrcpp_example.vcproj +++ b/builds/win32/msvc8/udrcpp_example.vcproj @@ -330,16 +330,15 @@ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > - - + + diff --git a/builds/win32/msvc9/udrcpp_example.vcproj b/builds/win32/msvc9/udrcpp_example.vcproj index 95dfea3198..720c9b54db 100644 --- a/builds/win32/msvc9/udrcpp_example.vcproj +++ b/builds/win32/msvc9/udrcpp_example.vcproj @@ -327,16 +327,15 @@ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > - - + + diff --git a/examples/udr/Functions.cpp b/examples/udr/Functions.cpp new file mode 100644 index 0000000000..5c77e40bcd --- /dev/null +++ b/examples/udr/Functions.cpp @@ -0,0 +1,160 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2008 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "UdrCppExample.h" + +using namespace Firebird; + + +//------------------------------------------------------------------------------ + + +/*** +create function wait_event ( + event_name varchar(31) character set utf8 not null +) returns integer not null + external name 'udrcpp_example!wait_event' + engine udr; +***/ +FB_UDR_BEGIN_FUNCTION(wait_event) + FB_UDR_MESSAGE(InMessage, + (FB_VARCHAR(31 * 4), name) + ); + + FB_UDR_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); + s[in->name.length] = '\0'; + + unsigned char* eveBuffer; + unsigned char* eveResult; + int eveLen = isc_event_block(&eveBuffer, &eveResult, 1, s); + + delete [] s; + + ISC_STATUS_ARRAY statusVector = {0}; + isc_db_handle dbHandle = getIscDbHandle(status, context); + ISC_ULONG counter = 0; + + FbException::check(isc_wait_for_event( + statusVector, &dbHandle, eveLen, eveBuffer, eveResult), status, statusVector); + isc_event_counts(&counter, eveLen, eveBuffer, eveResult); + FbException::check(isc_wait_for_event( + statusVector, &dbHandle, eveLen, eveBuffer, eveResult), status, statusVector); + isc_event_counts(&counter, eveLen, eveBuffer, eveResult); + + isc_free((char*) eveBuffer); + isc_free((char*) eveResult); + + out->resultNull = FB_FALSE; + out->result = counter; + } +FB_UDR_END_FUNCTION + + +/*** +create function sum_args ( + n1 integer, + n2 integer, + n3 integer +) returns integer + external name 'udrcpp_example!sum_args' + engine udr; +***/ +FB_UDR_BEGIN_FUNCTION(sum_args) + // Without InMessage/OutMessage definitions, messages will be byte-based. + + FB_UDR_CONSTRUCTOR + // , inCount(0) + { + // Get input metadata. + AutoRelease inMetadata(metadata->getInputMetadata(status)); + + // Get count of input parameters. + inCount = inMetadata->getCount(status); + + inNullOffsets.reset(new unsigned[inCount]); + inOffsets.reset(new unsigned[inCount]); + + for (unsigned i = 0; i < inCount; ++i) + { + // Get null offset of the i-th input parameter. + inNullOffsets[i] = inMetadata->getNullOffset(status, i); + + // Get the offset of the i-th input parameter. + inOffsets[i] = inMetadata->getOffset(status, i); + } + + // Get output metadata. + AutoRelease outMetadata(metadata->getOutputMetadata(status)); + + // Get null offset of the return value. + outNullOffset = outMetadata->getNullOffset(status, 0); + + // Get offset of the return value. + outOffset = 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_FUNCTION + { + *(ISC_SHORT*) (out + outNullOffset) = FB_FALSE; + + // Get a reference to the return value. + ISC_LONG& ret = *(ISC_LONG*) (out + outOffset); + + // The return value is automatically initialized to 0. + ///ret = 0; + + for (unsigned i = 0; i < inCount; ++i) + { + // If the i-th input parameter is NULL, set the output to NULL and finish. + if (*(ISC_SHORT*) (in + inNullOffsets[i])) + { + *(ISC_SHORT*) (out + outNullOffset) = FB_TRUE; + return; + } + + // Read the i-th input parameter value and sum it in the referenced return value. + ret += *(ISC_LONG*) (in + inOffsets[i]); + } + } + + unsigned inCount; + AutoArrayDelete inNullOffsets; + AutoArrayDelete inOffsets; + unsigned outNullOffset; + unsigned outOffset; +FB_UDR_END_FUNCTION + + +//------------------------------------------------------------------------------ + + +// This should be used in only one of the UDR library files. +FB_UDR_IMPLEMENT_ENTRY_POINT diff --git a/examples/udr/Procedures.cpp b/examples/udr/Procedures.cpp new file mode 100644 index 0000000000..ea65e456c8 --- /dev/null +++ b/examples/udr/Procedures.cpp @@ -0,0 +1,212 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2008 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "UdrCppExample.h" + +using namespace Firebird; + + +//------------------------------------------------------------------------------ + + +/*** +create procedure gen_rows ( + start_n integer not null, + end_n integer not null +) returns ( + n integer not null +) + external name 'udrcpp_example!gen_rows' + engine udr; +***/ +FB_UDR_BEGIN_PROCEDURE(gen_rows) + // Without InMessage/OutMessage definitions, messages will be byte-based. + + // Procedure variables. + unsigned inOffsetStart, inOffsetEnd, outNullOffset, outOffset; + + // Get offsets once per procedure. + FB_UDR_CONSTRUCTOR + { + AutoRelease inMetadata(metadata->getInputMetadata(status)); + + inOffsetStart = inMetadata->getOffset(status, 0); + inOffsetEnd = inMetadata->getOffset(status, 1); + + AutoRelease outMetadata(metadata->getOutputMetadata(status)); + + outNullOffset = outMetadata->getNullOffset(status, 0); + outOffset = outMetadata->getOffset(status, 0); + } + + /*** Procedure destructor. + FB_UDR_DESTRUCTOR + { + } + ***/ + + FB_UDR_EXECUTE_PROCEDURE + { + counter = *(ISC_LONG*) (in + procedure->inOffsetStart); + end = *(ISC_LONG*) (in + procedure->inOffsetEnd); + + *(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; + } + + /*** ResultSet destructor. + ~ResultSet() + { + } + ***/ + + // ResultSet variables. + ISC_LONG counter; + ISC_LONG end; +FB_UDR_END_PROCEDURE + + +/*** +create procedure gen_rows2 ( + start_n integer not null, + end_n integer not null +) returns ( + n integer not null +) + external name 'udrcpp_example!gen_rows2' + engine udr; +***/ +FB_UDR_BEGIN_PROCEDURE(gen_rows2) + FB_UDR_MESSAGE(InMessage, + (FB_INTEGER, start) + (FB_INTEGER, end) + ); + + FB_UDR_MESSAGE(OutMessage, + (FB_INTEGER, result) + ); + + FB_UDR_EXECUTE_PROCEDURE + { + out->resultNull = FB_FALSE; + out->result = in->start - 1; + } + + FB_UDR_FETCH_PROCEDURE + { + return out->result++ < in->end; + } +FB_UDR_END_PROCEDURE + + +/*** +create procedure inc ( + count_n integer not null +) returns ( + n0 integer not null, + n1 integer not null, + n2 integer not null, + n3 integer not null, + n4 integer not null +) + external name 'udrcpp_example!inc' + engine udr; +***/ +// This is a sample procedure demonstrating how the scopes of variables works. +// n1 and n2 are on the Procedure scope, i.e., they're shared for each execution of the same cached +// 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_UDR_MESSAGE(InMessage, + (FB_INTEGER, count) + ); + + FB_UDR_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_CONSTRUCTOR + , n1(0), + n2(0) + { + } + + ISC_LONG n2; + + // 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; + + out->n0 = 0; + + // In the execute method, the procedure scope must be accessed using the 'procedure' pointer. + procedure->n1 = 0; + + // We don't touch n2 here, so it incremented counter will be kept after each execution. + + // The ResultSet scope must be accessed directly, i.e., they're member variables of the + // 'this' pointer. + ++n4; + } + + ISC_LONG n3; + + // FB_UDR_FETCH_PROCEDURE must be always after FB_UDR_EXECUTE_PROCEDURE. + FB_UDR_FETCH_PROCEDURE + { + if (out->n0++ <= in->count) + { + out->n1 = ++procedure->n1; + out->n2 = ++procedure->n2; + out->n3 = ++n3; + out->n4 = ++n4; + return true; + } + + return false; + } + + ISC_LONG n4; +FB_UDR_END_PROCEDURE diff --git a/examples/udr/UdrCppExample.cpp b/examples/udr/Triggers.cpp similarity index 50% rename from examples/udr/UdrCppExample.cpp rename to examples/udr/Triggers.cpp index 079de7dbfc..fe0562f19a 100644 --- a/examples/udr/UdrCppExample.cpp +++ b/examples/udr/Triggers.cpp @@ -13,490 +13,21 @@ * The Original Code was created by Adriano dos Santos Fernandes * for the Firebird Open Source RDBMS project. * - * Copyright (c) 2008 Adriano dos Santos Fernandes + * Copyright (c) 2008 Adriano dos Santos Fernandes * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. */ -#define FB_UDR_STATUS_TYPE ::Firebird::ThrowStatusWrapper - -#include "ibase.h" -#include "firebird/UdrCppEngine.h" -#include -#include - +#include "UdrCppExample.h" using namespace Firebird; -using namespace Firebird::Udr; - - -namespace -{ - template - class AutoReleaseClear - { - public: - static void clear(T* ptr) - { - if (ptr) - ptr->release(); - } - }; - - template - class AutoDisposeClear - { - public: - static void clear(T* ptr) - { - if (ptr) - ptr->dispose(); - } - }; - - template - class AutoDeleteClear - { - public: - static void clear(T* ptr) - { - delete ptr; - } - }; - - template - class AutoArrayDeleteClear - { - public: - static void clear(T* ptr) - { - delete [] ptr; - } - }; - - template - class AutoImpl - { - public: - AutoImpl(T* aPtr = NULL) - : ptr(aPtr) - { - } - - ~AutoImpl() - { - Clear::clear(ptr); - } - - AutoImpl& operator =(T* aPtr) - { - Clear::clear(ptr); - ptr = aPtr; - return *this; - } - - operator T*() - { - return ptr; - } - - operator const T*() const - { - return ptr; - } - - bool operator !() const - { - return !ptr; - } - - bool hasData() const - { - return ptr != NULL; - } - - T* operator ->() - { - return ptr; - } - - T* release() - { - T* tmp = ptr; - ptr = NULL; - return tmp; - } - - void reset(T* aPtr = NULL) - { - if (aPtr != ptr) - { - Clear::clear(ptr); - ptr = aPtr; - } - } - - private: - // not implemented - AutoImpl(AutoImpl&); - void operator =(AutoImpl&); - - private: - T* ptr; - }; - - template class AutoDispose : public AutoImpl > - { - public: - AutoDispose(T* ptr = NULL) - : AutoImpl >(ptr) - { - } - }; - - template class AutoRelease : public AutoImpl > - { - public: - AutoRelease(T* ptr = NULL) - : AutoImpl >(ptr) - { - } - }; - - template class AutoDelete : public AutoImpl > - { - public: - AutoDelete(T* ptr = NULL) - : AutoImpl >(ptr) - { - } - }; - - template class AutoArrayDelete : public AutoImpl > - { - public: - AutoArrayDelete(T* ptr = NULL) - : AutoImpl >(ptr) - { - } - }; -} //------------------------------------------------------------------------------ -/*** -create function wait_event ( - event_name varchar(31) character set utf8 not null -) returns integer not null - external name 'udrcpp_example!wait_event' - engine udr; -***/ -FB_UDR_BEGIN_FUNCTION(wait_event) - FB_UDR_MESSAGE(InMessage, - (FB_VARCHAR(31 * 4), name) - ); - - FB_UDR_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); - s[in->name.length] = '\0'; - - unsigned char* eveBuffer; - unsigned char* eveResult; - int eveLen = isc_event_block(&eveBuffer, &eveResult, 1, s); - - delete [] s; - - ISC_STATUS_ARRAY statusVector = {0}; - isc_db_handle dbHandle = getIscDbHandle(status, context); - ISC_ULONG counter = 0; - - FbException::check(isc_wait_for_event( - statusVector, &dbHandle, eveLen, eveBuffer, eveResult), status, statusVector); - isc_event_counts(&counter, eveLen, eveBuffer, eveResult); - FbException::check(isc_wait_for_event( - statusVector, &dbHandle, eveLen, eveBuffer, eveResult), status, statusVector); - isc_event_counts(&counter, eveLen, eveBuffer, eveResult); - - isc_free((char*) eveBuffer); - isc_free((char*) eveResult); - - out->resultNull = FB_FALSE; - out->result = counter; - } -FB_UDR_END_FUNCTION - - -/*** -create function sum_args ( - n1 integer, - n2 integer, - n3 integer -) returns integer - external name 'udrcpp_example!sum_args' - engine udr; -***/ -FB_UDR_BEGIN_FUNCTION(sum_args) - // Without InMessage/OutMessage definitions, messages will be byte-based. - - FB_UDR_CONSTRUCTOR - // , inCount(0) - { - // Get input metadata. - AutoRelease inMetadata(metadata->getInputMetadata(status)); - - // Get count of input parameters. - inCount = inMetadata->getCount(status); - - inNullOffsets.reset(new unsigned[inCount]); - inOffsets.reset(new unsigned[inCount]); - - for (unsigned i = 0; i < inCount; ++i) - { - // Get null offset of the i-th input parameter. - inNullOffsets[i] = inMetadata->getNullOffset(status, i); - - // Get the offset of the i-th input parameter. - inOffsets[i] = inMetadata->getOffset(status, i); - } - - // Get output metadata. - AutoRelease outMetadata(metadata->getOutputMetadata(status)); - - // Get null offset of the return value. - outNullOffset = outMetadata->getNullOffset(status, 0); - - // Get offset of the return value. - outOffset = 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_FUNCTION - { - *(ISC_SHORT*) (out + outNullOffset) = FB_FALSE; - - // Get a reference to the return value. - ISC_LONG& ret = *(ISC_LONG*) (out + outOffset); - - // The return value is automatically initialized to 0. - ///ret = 0; - - for (unsigned i = 0; i < inCount; ++i) - { - // If the i-th input parameter is NULL, set the output to NULL and finish. - if (*(ISC_SHORT*) (in + inNullOffsets[i])) - { - *(ISC_SHORT*) (out + outNullOffset) = FB_TRUE; - return; - } - - // Read the i-th input parameter value and sum it in the referenced return value. - ret += *(ISC_LONG*) (in + inOffsets[i]); - } - } - - unsigned inCount; - AutoArrayDelete inNullOffsets; - AutoArrayDelete inOffsets; - unsigned outNullOffset; - unsigned outOffset; -FB_UDR_END_FUNCTION - - -/*** -create procedure gen_rows ( - start_n integer not null, - end_n integer not null -) returns ( - n integer not null -) - external name 'udrcpp_example!gen_rows' - engine udr; -***/ -FB_UDR_BEGIN_PROCEDURE(gen_rows) - // Without InMessage/OutMessage definitions, messages will be byte-based. - - // Procedure variables. - unsigned inOffsetStart, inOffsetEnd, outNullOffset, outOffset; - - // Get offsets once per procedure. - FB_UDR_CONSTRUCTOR - { - AutoRelease inMetadata(metadata->getInputMetadata(status)); - - inOffsetStart = inMetadata->getOffset(status, 0); - inOffsetEnd = inMetadata->getOffset(status, 1); - - AutoRelease outMetadata(metadata->getOutputMetadata(status)); - - outNullOffset = outMetadata->getNullOffset(status, 0); - outOffset = outMetadata->getOffset(status, 0); - } - - /*** Procedure destructor. - FB_UDR_DESTRUCTOR - { - } - ***/ - - FB_UDR_EXECUTE_PROCEDURE - { - counter = *(ISC_LONG*) (in + procedure->inOffsetStart); - end = *(ISC_LONG*) (in + procedure->inOffsetEnd); - - *(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; - } - - /*** ResultSet destructor. - ~ResultSet() - { - } - ***/ - - // ResultSet variables. - ISC_LONG counter; - ISC_LONG end; -FB_UDR_END_PROCEDURE - - -/*** -create procedure gen_rows2 ( - start_n integer not null, - end_n integer not null -) returns ( - n integer not null -) - external name 'udrcpp_example!gen_rows2' - engine udr; -***/ -FB_UDR_BEGIN_PROCEDURE(gen_rows2) - FB_UDR_MESSAGE(InMessage, - (FB_INTEGER, start) - (FB_INTEGER, end) - ); - - FB_UDR_MESSAGE(OutMessage, - (FB_INTEGER, result) - ); - - FB_UDR_EXECUTE_PROCEDURE - { - out->resultNull = FB_FALSE; - out->result = in->start - 1; - } - - FB_UDR_FETCH_PROCEDURE - { - return out->result++ < in->end; - } -FB_UDR_END_PROCEDURE - - -/*** -create procedure inc ( - count_n integer not null -) returns ( - n0 integer not null, - n1 integer not null, - n2 integer not null, - n3 integer not null, - n4 integer not null -) - external name 'udrcpp_example!inc' - engine udr; -***/ -// This is a sample procedure demonstrating how the scopes of variables works. -// n1 and n2 are on the Procedure scope, i.e., they're shared for each execution of the same cached -// 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_UDR_MESSAGE(InMessage, - (FB_INTEGER, count) - ); - - FB_UDR_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_CONSTRUCTOR - , n1(0), - n2(0) - { - } - - ISC_LONG n2; - - // 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; - - out->n0 = 0; - - // In the execute method, the procedure scope must be accessed using the 'procedure' pointer. - procedure->n1 = 0; - - // We don't touch n2 here, so it incremented counter will be kept after each execution. - - // The ResultSet scope must be accessed directly, i.e., they're member variables of the - // 'this' pointer. - ++n4; - } - - ISC_LONG n3; - - // FB_UDR_FETCH_PROCEDURE must be always after FB_UDR_EXECUTE_PROCEDURE. - FB_UDR_FETCH_PROCEDURE - { - if (out->n0++ <= in->count) - { - out->n1 = ++procedure->n1; - out->n2 = ++procedure->n2; - out->n3 = ++n3; - out->n4 = ++n4; - return true; - } - - return false; - } - - ISC_LONG n4; -FB_UDR_END_PROCEDURE - - /*** Sample usage: @@ -783,6 +314,3 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons) AutoRelease triggerMetadata; AutoRelease stmt; FB_UDR_END_TRIGGER - - -FB_UDR_IMPLEMENT_ENTRY_POINT diff --git a/examples/udr/UdrCppExample.h b/examples/udr/UdrCppExample.h new file mode 100644 index 0000000000..f2a77ff069 --- /dev/null +++ b/examples/udr/UdrCppExample.h @@ -0,0 +1,186 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2015 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef UDR_CPP_EXAMPLE_H +#define UDR_CPP_EXAMPLE_H + +#define FB_UDR_STATUS_TYPE ::Firebird::ThrowStatusWrapper + +#include "ibase.h" +#include "firebird/UdrCppEngine.h" +#include +#include + + +namespace +{ + template + class AutoReleaseClear + { + public: + static void clear(T* ptr) + { + if (ptr) + ptr->release(); + } + }; + + template + class AutoDisposeClear + { + public: + static void clear(T* ptr) + { + if (ptr) + ptr->dispose(); + } + }; + + template + class AutoDeleteClear + { + public: + static void clear(T* ptr) + { + delete ptr; + } + }; + + template + class AutoArrayDeleteClear + { + public: + static void clear(T* ptr) + { + delete [] ptr; + } + }; + + template + class AutoImpl + { + public: + AutoImpl(T* aPtr = NULL) + : ptr(aPtr) + { + } + + ~AutoImpl() + { + Clear::clear(ptr); + } + + AutoImpl& operator =(T* aPtr) + { + Clear::clear(ptr); + ptr = aPtr; + return *this; + } + + operator T*() + { + return ptr; + } + + operator const T*() const + { + return ptr; + } + + bool operator !() const + { + return !ptr; + } + + bool hasData() const + { + return ptr != NULL; + } + + T* operator ->() + { + return ptr; + } + + T* release() + { + T* tmp = ptr; + ptr = NULL; + return tmp; + } + + void reset(T* aPtr = NULL) + { + if (aPtr != ptr) + { + Clear::clear(ptr); + ptr = aPtr; + } + } + + private: + // not implemented + AutoImpl(AutoImpl&); + void operator =(AutoImpl&); + + private: + T* ptr; + }; + + template class AutoDispose : public AutoImpl > + { + public: + AutoDispose(T* ptr = NULL) + : AutoImpl >(ptr) + { + } + }; + + template class AutoRelease : public AutoImpl > + { + public: + AutoRelease(T* ptr = NULL) + : AutoImpl >(ptr) + { + } + }; + + template class AutoDelete : public AutoImpl > + { + public: + AutoDelete(T* ptr = NULL) + : AutoImpl >(ptr) + { + } + }; + + template class AutoArrayDelete : public AutoImpl > + { + public: + AutoArrayDelete(T* ptr = NULL) + : AutoImpl >(ptr) + { + } + }; +} + +#endif // UDR_CPP_EXAMPLE_H