|
From: <asf...@us...> - 2011-06-26 15:58:02
|
Revision: 53242
http://firebird.svn.sourceforge.net/firebird/?rev=53242&view=rev
Author: asfernandes
Date: 2011-06-26 15:57:55 +0000 (Sun, 26 Jun 2011)
Log Message:
-----------
Work in progress on message-based external functions and procedures.
Modified Paths:
--------------
firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln
firebird/trunk/examples/udr/UdrCppExample.cpp
firebird/trunk/src/include/firebird/UdrCppEngine.h
firebird/trunk/src/misc/copy-boost.sh
Added Paths:
-----------
firebird/trunk/src/include/firebird/Message.h
firebird/trunk/src/include/ibase.h
Modified: firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln
===================================================================
--- firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln 2011-06-26 15:56:56 UTC (rev 53241)
+++ firebird/trunk/builds/win32/msvc9/Firebird3_Examples.sln 2011-06-26 15:57:55 UTC (rev 53242)
@@ -13,12 +13,13 @@
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udrcpp_example", "udrcpp_example.vcproj", "{FF0FD8DF-1E5C-486E-B395-A620376A4633}"
ProjectSection(ProjectDependencies) = postProject
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B} = {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}
+ {4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udr_engine", "udr_engine.vcproj", "{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}"
ProjectSection(ProjectDependencies) = postProject
+ {4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
{15605F44-BFFD-444F-AD4C-55DC9D704465} = {15605F44-BFFD-444F-AD4C-55DC9D704465}
- {4FE03933-98CD-4879-A135-FD9430087A6B} = {4FE03933-98CD-4879-A135-FD9430087A6B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common.vcproj", "{15605F44-BFFD-444F-AD4C-55DC9D704465}"
@@ -52,25 +53,33 @@
{9546EF04-1326-464B-A6ED-395C60DD63CC}.Debug|x64.ActiveCfg = Debug|x64
{9546EF04-1326-464B-A6ED-395C60DD63CC}.Debug|x64.Build.0 = Debug|x64
{9546EF04-1326-464B-A6ED-395C60DD63CC}.Release|Win32.ActiveCfg = Release|Win32
+ {9546EF04-1326-464B-A6ED-395C60DD63CC}.Release|Win32.Build.0 = Release|Win32
{9546EF04-1326-464B-A6ED-395C60DD63CC}.Release|x64.ActiveCfg = Release|x64
+ {9546EF04-1326-464B-A6ED-395C60DD63CC}.Release|x64.Build.0 = Release|x64
{FF0FD8DF-1E5C-486E-B395-A620376A4633}.Debug|Win32.ActiveCfg = Debug|Win32
{FF0FD8DF-1E5C-486E-B395-A620376A4633}.Debug|Win32.Build.0 = Debug|Win32
- {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Debug|x64.ActiveCfg = Debug|Win32
+ {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Debug|x64.ActiveCfg = Debug|x64
+ {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Debug|x64.Build.0 = Debug|x64
{FF0FD8DF-1E5C-486E-B395-A620376A4633}.Release|Win32.ActiveCfg = Release|Win32
{FF0FD8DF-1E5C-486E-B395-A620376A4633}.Release|Win32.Build.0 = Release|Win32
- {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Release|x64.ActiveCfg = Release|Win32
+ {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Release|x64.ActiveCfg = Release|x64
+ {FF0FD8DF-1E5C-486E-B395-A620376A4633}.Release|x64.Build.0 = Release|x64
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Debug|Win32.ActiveCfg = Debug|Win32
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Debug|Win32.Build.0 = Debug|Win32
- {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Debug|x64.ActiveCfg = Debug|Win32
+ {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Debug|x64.ActiveCfg = Debug|x64
+ {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Debug|x64.Build.0 = Debug|x64
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Release|Win32.ActiveCfg = Release|Win32
{20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Release|Win32.Build.0 = Release|Win32
- {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Release|x64.ActiveCfg = Release|Win32
+ {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Release|x64.ActiveCfg = Release|x64
+ {20DEBF08-EF0A-4C94-ADEB-FE9BBA14588B}.Release|x64.Build.0 = Release|x64
{15605F44-BFFD-444F-AD4C-55DC9D704465}.Debug|Win32.ActiveCfg = Debug|Win32
{15605F44-BFFD-444F-AD4C-55DC9D704465}.Debug|Win32.Build.0 = Debug|Win32
- {15605F44-BFFD-444F-AD4C-55DC9D704465}.Debug|x64.ActiveCfg = Debug|Win32
+ {15605F44-BFFD-444F-AD4C-55DC9D704465}.Debug|x64.ActiveCfg = Debug|x64
+ {15605F44-BFFD-444F-AD4C-55DC9D704465}.Debug|x64.Build.0 = Debug|x64
{15605F44-BFFD-444F-AD4C-55DC9D704465}.Release|Win32.ActiveCfg = Release|Win32
{15605F44-BFFD-444F-AD4C-55DC9D704465}.Release|Win32.Build.0 = Release|Win32
- {15605F44-BFFD-444F-AD4C-55DC9D704465}.Release|x64.ActiveCfg = Release|Win32
+ {15605F44-BFFD-444F-AD4C-55DC9D704465}.Release|x64.ActiveCfg = Release|x64
+ {15605F44-BFFD-444F-AD4C-55DC9D704465}.Release|x64.Build.0 = Release|x64
{4FE03933-98CD-4879-A135-FD9430087A6B}.Debug|Win32.ActiveCfg = Debug|Win32
{4FE03933-98CD-4879-A135-FD9430087A6B}.Debug|Win32.Build.0 = Debug|Win32
{4FE03933-98CD-4879-A135-FD9430087A6B}.Debug|x64.ActiveCfg = Debug|x64
Modified: firebird/trunk/examples/udr/UdrCppExample.cpp
===================================================================
--- firebird/trunk/examples/udr/UdrCppExample.cpp 2011-06-26 15:56:56 UTC (rev 53241)
+++ firebird/trunk/examples/udr/UdrCppExample.cpp 2011-06-26 15:57:55 UTC (rev 53242)
@@ -275,7 +275,7 @@
class MessageImpl : public Firebird::FbMessage
{
public:
- MessageImpl(unsigned aItemCount, ISC_UCHAR* aBuffer = NULL)
+ MessageImpl(unsigned aItemCount, void* aBuffer = NULL)
: itemCount(aItemCount * 2),
freeBuffer(!aBuffer),
items(0)
@@ -289,7 +289,7 @@
blrLength = 0;
blr = blrPos = new ISC_UCHAR[sizeof(HEADER) + 10 * itemCount + 2];
bufferLength = 0;
- buffer = aBuffer;
+ buffer = (ISC_UCHAR*) aBuffer;
memcpy(blrPos, HEADER, sizeof(HEADER));
blrPos += sizeof(HEADER);
@@ -564,14 +564,46 @@
/***
create function wait_event (
- event_name varchar(31) character set ascii not null
+ event_name varchar(31) character set utf8 not null
) returns integer not null
external name 'udrcpp_example!wait_event'
engine udr;
***/
-FB_UDR_DECLARE_FUNCTION(wait_event)
+FB_UDR_BEGIN_FUNCTION(wait_event)
+ FB_UDR_EXECUTE_MESSAGE_FUNCTION(
+ (FB_VARCHAR(31 * 4), name)
+ ,
+ (FB_INTEGER, result))
+ {
+ 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(context);
+ ISC_ULONG counter = 0;
+
+ ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
+ statusVector);
+ isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
+ ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
+ statusVector);
+ isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
+
+ isc_free((char*) eveBuffer);
+ isc_free((char*) eveResult);
+
+ out->result = counter;
+ }
+FB_UDR_END_FUNCTION
+
+
/***
create function sum_args (
n1 integer,
@@ -581,9 +613,42 @@
external name 'udrcpp_example!sum_args'
engine udr;
***/
-FB_UDR_DECLARE_FUNCTION(sum_args)
+FB_UDR_BEGIN_FUNCTION(sum_args)
+ FB_UDR_EXECUTE_DYNAMIC_FUNCTION
+ {
+ AutoDispose<IStatus> status(master->getStatus());
+ const IParametersMetadata* params = metadata->getInputParameters(status);
+ ThrowError::check(status->get());
+ unsigned count = params->getCount(status);
+ ThrowError::check(status->get());
+
+ MessageImpl inMessage(count, in);
+
+ MessageImpl outMessage(1, out);
+ ParamDesc<ISC_LONG> retDesc(outMessage);
+
+ int ret = 0;
+
+ for (unsigned i = 0; i < count; ++i)
+ {
+ ParamDesc<ISC_LONG> numDesc(inMessage);
+
+ if (inMessage.isNull(numDesc))
+ {
+ outMessage.setNull(retDesc, true);
+ return;
+ }
+ else
+ ret += inMessage[numDesc];
+ }
+
+ outMessage[retDesc] = ret;
+ }
+FB_UDR_END_FUNCTION
+
+
/***
create procedure gen_rows (
start_n integer not null,
@@ -594,14 +659,143 @@
external name 'udrcpp_example!gen_rows'
engine udr;
***/
-FB_UDR_DECLARE_PROCEDURE(gen_rows)
-FB_UDR_BEGIN_DECLARE_FETCH_PROCEDURE(gen_rows)
- int counter;
- int end;
-FB_UDR_END_DECLARE_FETCH_PROCEDURE(gen_rows)
+FB_UDR_BEGIN_PROCEDURE(gen_rows)
+ FB_UDR_EXECUTE_DYNAMIC_PROCEDURE
+ {
+ MessageImpl inMessage(2, inMsg);
+ ParamDesc<ISC_LONG> startDesc(inMessage);
+ ParamDesc<ISC_LONG> endDesc(inMessage);
+ counter = inMessage[startDesc];
+ end = inMessage[endDesc];
+ }
+ FB_UDR_FETCH_PROCEDURE
+ {
+ if (counter > end)
+ return false;
+
+ MessageImpl outMessage(1, out);
+ ParamDesc<ISC_LONG> retDesc(outMessage);
+
+ outMessage[retDesc] = counter++;
+
+ return true;
+ }
+
+ 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_EXECUTE_MESSAGE_PROCEDURE(
+ (FB_INTEGER, start)
+ (FB_INTEGER, end)
+ ,
+ (FB_INTEGER, result))
+ {
+ 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)
+ 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),
+ 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)
+ {
+ 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 must be always after FB_UDR_EXECUTE_MESSAGE_PROCEDURE or
+ // FB_UDR_EXECUTE_DYNAMIC_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:
create database 'c:\temp\slave.fdb';
@@ -645,110 +839,9 @@
bool initialized;
XSQLDA* inSqlDa;
isc_stmt_handle stmtHandle;
-#if 0
- IStatement* stmt;
-#endif
FB_UDR_END_DECLARE_TRIGGER(replicate)
-FB_UDR_BEGIN_FUNCTION(wait_event)
-{
- MessageImpl inMessage(1, inMsg);
- ParamDesc<FbString> nameDesc(inMessage, 31);
-
- FbString& name = inMessage[nameDesc];
-
- char* s = new char[name.length + 1];
- memcpy(s, name.str, name.length);
- s[name.length] = '\0';
-
- unsigned char* eveBuffer;
- unsigned char* eveResult;
- int eveLen = isc_event_block(&eveBuffer, &eveResult, 1, s);
-
- delete [] s;
-
- ISC_STATUS_ARRAY statusVector = {0};
- isc_db_handle dbHandle = getIscDbHandle(context);
- ISC_ULONG counter = 0;
-
- ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
- statusVector);
- isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
- ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
- statusVector);
- isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
-
- isc_free((char*) eveBuffer);
- isc_free((char*) eveResult);
-
- MessageImpl outMessage(1, outMsg);
- ParamDesc<ISC_LONG> retDesc(outMessage);
-
- outMessage[retDesc] = counter;
-}
-FB_UDR_END_FUNCTION(wait_event)
-
-
-FB_UDR_BEGIN_FUNCTION(sum_args)
-{
- AutoDispose<IStatus> status(master->getStatus());
-
- const IParametersMetadata* params = metadata->getInputParameters(status);
- ThrowError::check(status->get());
-
- unsigned count = params->getCount(status);
- ThrowError::check(status->get());
-
- MessageImpl inMessage(count, inMsg);
-
- MessageImpl outMessage(1, outMsg);
- ParamDesc<ISC_LONG> retDesc(outMessage);
-
- int ret = 0;
-
- for (unsigned i = 0; i < count; ++i)
- {
- ParamDesc<ISC_LONG> numDesc(inMessage);
-
- if (inMessage.isNull(numDesc))
- {
- outMessage.setNull(retDesc, true);
- return;
- }
-
- ret += inMessage[numDesc];
- }
-
- outMessage[retDesc] = ret;
-}
-FB_UDR_END_FUNCTION(sum_args)
-
-
-FB_UDR_BEGIN_PROCEDURE(gen_rows)
-{
- MessageImpl inMessage(2, inMsg);
- ParamDesc<ISC_LONG> startDesc(inMessage);
- ParamDesc<ISC_LONG> endDesc(inMessage);
-
- counter = inMessage[startDesc];
- end = inMessage[endDesc];
-}
-FB_UDR_FETCH_PROCEDURE(gen_rows)
-{
- if (counter > end)
- return false;
-
- MessageImpl outMessage(1, outMsg);
- ParamDesc<ISC_LONG> retDesc(outMessage);
-
- outMessage[retDesc] = counter++;
-
- return true;
-}
-FB_UDR_END_PROCEDURE(gen_rows)
-
-
FB_UDR_TRIGGER(replicate)::FB_UDR_TRIGGER(replicate)()
: initialized(false)
{
Added: firebird/trunk/src/include/firebird/Message.h
===================================================================
--- firebird/trunk/src/include/firebird/Message.h (rev 0)
+++ firebird/trunk/src/include/firebird/Message.h 2011-06-26 15:57:55 UTC (rev 53242)
@@ -0,0 +1,112 @@
+/*
+ * 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) 2011 Adriano dos Santos Fernandes <adr...@uo...>
+ * and all contributors signed below.
+ *
+ * All Rights Reserved.
+ * Contributor(s): ______________________________________.
+ */
+
+#ifndef FIREBIRD_MESSAGE_H
+#define FIREBIRD_MESSAGE_H
+
+#include "ibase.h"
+#include "firebird/impl/boost/preprocessor/seq/for_each_i.hpp"
+
+#define FB_MESSAGE(name, fields) \
+ FB_MESSAGE_I(name, FB_BOOST_PP_CAT(FB_MESSAGE_X fields, 0))
+
+#define FB_MESSAGE_X(x, y) ((x, y)) FB_MESSAGE_Y
+#define FB_MESSAGE_Y(x, y) ((x, y)) FB_MESSAGE_X
+#define FB_MESSAGE_X0
+#define FB_MESSAGE_Y0
+
+#define FB_MESSAGE_I(name, fields) \
+ struct name \
+ { \
+ /* TODO: use it */ \
+ static const unsigned char* BLR() \
+ { \
+ static const unsigned char blr[] = { \
+ blr_version5, \
+ blr_begin, \
+ blr_message, 0, \
+ (2 * (FB_BOOST_PP_SEQ_SIZE(fields))) & 0xFF, \
+ (2 * (FB_BOOST_PP_SEQ_SIZE(fields))) >> 8, \
+ FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_BLR, _, fields) \
+ blr_end, \
+ blr_eoc \
+ }; \
+ return blr; \
+ } \
+ \
+ static unsigned SIZE() \
+ { \
+ return (unsigned)(size_t) (&((name*) 0)->FB_BOOST_PP_CAT( \
+ FB_BOOST_PP_TUPLE_ELEM(2, 1, \
+ FB_BOOST_PP_SEQ_ELEM(FB_BOOST_PP_DEC(FB_BOOST_PP_SEQ_SIZE(fields)), fields)), \
+ Null) - 0) + sizeof(ISC_SHORT); \
+ } \
+ \
+ FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_FIELD, _, fields) \
+ };
+
+#define FB_MESSAGE_FIELD(r, _, i, xy) \
+ FB_BOOST_PP_CAT(FB_TYPE_, FB_BOOST_PP_TUPLE_ELEM(2, 0, xy)) FB_BOOST_PP_TUPLE_ELEM(2, 1, xy); \
+ ISC_SHORT FB_BOOST_PP_CAT(FB_BOOST_PP_TUPLE_ELEM(2, 1, xy), Null);
+
+#define FB_MESSAGE_BLR(r, _, i, xy) \
+ FB_BOOST_PP_CAT(FB_BLR_, FB_BOOST_PP_TUPLE_ELEM(2, 0, xy)), \
+ FB_BLR_FB_SMALLINT,
+
+//// TODO: more types
+#define FB_BLR_FB_SCALED_SMALLINT(scale) blr_short, (scale)
+#define FB_BLR_FB_SCALED_INTEGER(scale) blr_long, (scale)
+#define FB_BLR_FB_SCALED_BIGINT(scale) blr_int64, (scale)
+#define FB_BLR_FB_SMALLINT FB_BLR_FB_SCALED_SMALLINT(0)
+#define FB_BLR_FB_INTEGER FB_BLR_FB_SCALED_INTEGER(0)
+#define FB_BLR_FB_BIGINT FB_BLR_FB_SCALED_BIGINT(0)
+#define FB_BLR_FB_VARCHAR(len) blr_varying, (len) & 0xFF, (len) >> 8
+
+#define FB_TYPE_FB_SCALED_SMALLINT(x) ISC_SHORT
+#define FB_TYPE_FB_SCALED_INTEGER(x) ISC_LONG
+#define FB_TYPE_FB_SCALED_BIGINT(x) ISC_INT64
+#define FB_TYPE_FB_SMALLINT ISC_SHORT
+#define FB_TYPE_FB_INTEGER ISC_LONG
+#define FB_TYPE_FB_BIGINT ISC_INT64
+#define FB_TYPE_FB_VARCHAR(len) FbVarChar<(len)>
+
+
+namespace Firebird {
+
+
+template <unsigned N>
+struct FbVarChar
+{
+ ISC_USHORT length;
+ char str[N];
+
+ void set(const char* s)
+ {
+ length = strlen(s);
+ memcpy(str, s, length);
+ }
+};
+
+
+} // namespace Firebird
+
+#endif // FIREBIRD_MESSAGE_H
Property changes on: firebird/trunk/src/include/firebird/Message.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Modified: firebird/trunk/src/include/firebird/UdrCppEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrCppEngine.h 2011-06-26 15:56:56 UTC (rev 53241)
+++ firebird/trunk/src/include/firebird/UdrCppEngine.h 2011-06-26 15:57:55 UTC (rev 53242)
@@ -20,11 +20,12 @@
* Contributor(s): ______________________________________.
*/
-#ifndef FIREBIRD_PLUGIN_UDR_CPP
-#define FIREBIRD_PLUGIN_UDR_CPP
+#ifndef FIREBIRD_UDR_CPP_ENGINE
+#define FIREBIRD_UDR_CPP_ENGINE
#include "./ExternalEngine.h"
#include "./UdrEngine.h"
+#include "./Message.h"
#ifndef JRD_IBASE_H
#include "ibase.h"
#include "iberror.h"
@@ -44,29 +45,41 @@
#define FB_UDR_TRIGGER(name) Trig##name
-#define FB_UDR_BEGIN_DECLARE_FUNCTION(name) \
- class FB_UDR_FUNCTION(name) : public ::Firebird::Udr::Function \
+#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)> \
{ \
- public: \
- virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- UCHAR* inMsg, UCHAR* outMsg); \
- private:
+ public:
-#define FB_UDR_END_DECLARE_FUNCTION(name) \
+#define FB_UDR_END_FUNCTION \
};
-#define FB_UDR_DECLARE_FUNCTION(name) \
- FB_UDR_BEGIN_DECLARE_FUNCTION(name) \
- FB_UDR_END_DECLARE_FUNCTION(name)
+#define FB_UDR_EXECUTE_DYNAMIC_FUNCTION \
+ typedef void* InMessage; \
+ typedef void* OutMessage; \
+ \
+ FB_UDR_EXECUTE__FUNCTION
-#define FB_UDR_BEGIN_FUNCTION(name) \
- void FB_CALL FB_UDR_FUNCTION(name)::execute(::Firebird::Error* error, \
- ::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg) \
+#define FB_UDR_EXECUTE_MESSAGE_FUNCTION(inputs, output) \
+ FB_MESSAGE(InMessage, \
+ inputs \
+ ) \
+ FB_MESSAGE(OutMessage, \
+ output \
+ ) \
+ \
+ FB_UDR_EXECUTE__FUNCTION
+
+#define FB_UDR_EXECUTE__FUNCTION \
+ virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
+ UCHAR* inMsg, UCHAR* outMsg) \
{ \
try \
- {
-
-#define FB_UDR_END_FUNCTION(name) \
+ { \
+ execute(error, context, (InMessage*) inMsg, (OutMessage*) outMsg); \
} \
catch (const ::Firebird::Udr::ThrowError::Exception& e) \
{ \
@@ -81,61 +94,48 @@
strlen(FB_UDR_UNRECOGNIZED_EXCEPTION)); \
} \
} \
- ::Firebird::Udr::FunctionFactoryImpl<FB_UDR_FUNCTION(name)> FuncFactory##name(#name);
+ \
+ virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
+ InMessage* in, OutMessage* out)
-#define FB_UDR_BEGIN_DECLARE_PROCEDURE(name) \
- class FB_UDR_PROCEDURE(name) : public ::Firebird::Udr::Procedure \
+#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)> \
{ \
public: \
- virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::Error* error, \
- ::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg); \
+ typedef FB_UDR_PROCEDURE(name) This;
-#define FB_UDR_END_DECLARE_PROCEDURE(name) \
+#define FB_UDR_END_PROCEDURE \
+ }; \
};
-#define FB_UDR_DECLARE_PROCEDURE(name) \
- FB_UDR_BEGIN_DECLARE_PROCEDURE(name) \
- FB_UDR_END_DECLARE_PROCEDURE(name)
+#define FB_UDR_EXECUTE_DYNAMIC_PROCEDURE \
+ typedef void* InMessage; \
+ typedef void* OutMessage; \
+ \
+ FB_UDR_EXECUTE__PROCEDURE
-#define FB_UDR_BEGIN_DECLARE_FETCH_PROCEDURE(name) \
- class ResultSet##name : public ::Firebird::Udr::ResultSet \
- { \
- public: \
- ResultSet##name(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::Udr::Procedure* procedure, UCHAR* inMsg, UCHAR* outMsg); \
+#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE(inputs, outputs) \
+ FB_MESSAGE(InMessage, \
+ inputs \
+ ) \
+ FB_MESSAGE(OutMessage, \
+ outputs \
+ ) \
\
- public: \
- virtual bool FB_CALL fetch(::Firebird::Error* error); \
- \
- private:
+ FB_UDR_EXECUTE__PROCEDURE
-#define FB_UDR_END_DECLARE_FETCH_PROCEDURE(name) \
- };
-
-#define FB_UDR_DECLARE_FETCH_PROCEDURE(name) \
- FB_UDR_BEGIN_DECLARE_FETCH_PROCEDURE(name) \
- FB_UDR_END_DECLARE_FETCH_PROCEDURE(name)
-
-#define FB_UDR_DECLARE_PROCEDURE(name) \
- FB_UDR_BEGIN_DECLARE_PROCEDURE(name) \
- FB_UDR_END_DECLARE_PROCEDURE(name)
-
-#define FB_UDR_BEGIN_PROCEDURE(name) \
- ::Firebird::ExternalResultSet* FB_CALL Proc##name::open(::Firebird::Error* error, \
+#define FB_UDR_EXECUTE__PROCEDURE \
+ virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::Error* error, \
::Firebird::ExternalContext* context, UCHAR* inMsg, UCHAR* outMsg) \
{ \
- return new ResultSet##name(error, context, this, inMsg, outMsg); \
- } \
- \
- ResultSet##name::ResultSet##name(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
- ::Firebird::Udr::Procedure* procedure, UCHAR* inMsg, UCHAR* outMsg) \
- : ResultSet(context, procedure, inMsg, outMsg) \
- { \
try \
- {
-
-#define FB_UDR_FETCH_PROCEDURE(name) \
+ { \
+ return new ResultSet(error, context, this, (InMessage*) inMsg, (OutMessage*) outMsg); \
} \
catch (const ::Firebird::Udr::ThrowError::Exception& e) \
{ \
@@ -149,14 +149,24 @@
FB_UDR_UNRECOGNIZED_EXCEPTION, \
strlen(FB_UDR_UNRECOGNIZED_EXCEPTION)); \
} \
+ \
+ return 0; \
} \
\
- bool FB_CALL ResultSet##name::fetch(::Firebird::Error* error) \
+ class ResultSet : public ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage> \
{ \
+ public: \
+ ResultSet(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
+ This* procedure, InMessage* inMsg, OutMessage* outMsg) \
+ : ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage>( \
+ context, procedure, inMsg, outMsg)
+
+#define FB_UDR_FETCH_PROCEDURE \
+ virtual bool FB_CALL fetch(::Firebird::Error* error) \
+ { \
try \
- {
-
-#define FB_UDR_END_PROCEDURE(name) \
+ { \
+ return fetch0(error); \
} \
catch (const ::Firebird::Udr::ThrowError::Exception& e) \
{ \
@@ -170,18 +180,19 @@
FB_UDR_UNRECOGNIZED_EXCEPTION, \
strlen(FB_UDR_UNRECOGNIZED_EXCEPTION)); \
} \
- return false; \
+ \
+ return 0; \
} \
- ::Firebird::Udr::ProcedureFactoryImpl<FB_UDR_PROCEDURE(name)> ProcFactory##name(#name);
+ \
+ bool FB_CALL fetch0(::Firebird::Error* error)
#define FB_UDR_BEGIN_DECLARE_TRIGGER(name) \
- class FB_UDR_TRIGGER(name) : public ::Firebird::Udr::Trigger \
+ 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, UCHAR* oldMsg, UCHAR* newMsg); \
- private:
+ ::Firebird::ExternalTrigger::Action action, UCHAR* oldMsg, UCHAR* newMsg);
#define FB_UDR_END_DECLARE_TRIGGER(name) \
};
@@ -425,7 +436,7 @@
};
-class Procedure;
+template <typename T> class Procedure;
class Helper
@@ -456,97 +467,133 @@
};
+template <typename This, typename Procedure, typename InMessage, typename OutMessage>
class ResultSet : public ExternalResultSet, public Helper
{
public:
- ResultSet(Firebird::ExternalContext* aContext, Firebird::Udr::Procedure* aProcedure,
- UCHAR* aInMsg, UCHAR* aOutMsg)
+ ResultSet(Firebird::ExternalContext* aContext, Procedure* aProcedure,
+ InMessage* aIn, OutMessage* aOut)
: context(aContext),
procedure(aProcedure),
- inMsg(aInMsg),
- outMsg(aOutMsg)
+ in(aIn),
+ out(aOut)
{
}
- virtual ~ResultSet()
- {
- }
-
public:
virtual void FB_CALL dispose(Firebird::Error* /*error*/)
{
- delete this;
+ delete static_cast<This*>(this);
}
protected:
Firebird::ExternalContext* context;
- Firebird::Udr::Procedure* procedure;
- UCHAR* inMsg;
- UCHAR* outMsg;
+ Procedure* procedure;
+ InMessage* in;
+ OutMessage* out;
};
-class Function : public ExternalFunction, public Helper
+// 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:
- virtual ~Function()
+ Routine()
{
}
+};
+
+template <typename This>
+class Function : public ExternalFunction, public Helper
+{
public:
virtual void FB_CALL dispose(Error* /*error*/)
{
- delete this;
+ delete static_cast<This*>(this);
}
- void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/, Utf8* /*name*/, uint /*nameSize*/)
+ virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
+ Utf8* /*name*/, uint /*nameSize*/)
{
}
+ void* operator new(size_t size, const IRoutineMetadata* metadata)
+ {
+ Function* p = reinterpret_cast<Function*>(::new char[size]);
+ p->metadata = metadata;
+ return p;
+ }
+
+ void operator delete(void* p)
+ {
+ ::delete [] static_cast<char*>(p);
+ }
+
public:
const IRoutineMetadata* metadata;
};
+template <typename This>
class Procedure : public ExternalProcedure, public Helper
{
public:
- virtual ~Procedure()
+ virtual void FB_CALL dispose(Error* /*error*/)
{
+ delete static_cast<This*>(this);
}
-public:
- virtual void FB_CALL dispose(Error* /*error*/)
+ virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
+ Utf8* /*name*/, uint /*nameSize*/)
{
- delete this;
}
- void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/, Utf8* /*name*/, uint /*nameSize*/)
+ void* operator new(size_t size, const IRoutineMetadata* metadata)
{
+ Procedure* p = reinterpret_cast<Procedure*>(::new char[size]);
+ p->metadata = metadata;
+ return p;
}
+ void operator delete(void* p)
+ {
+ ::delete [] static_cast<char*>(p);
+ }
+
public:
const IRoutineMetadata* metadata;
};
+template <typename This>
class Trigger : public ExternalTrigger, public Helper
{
public:
- virtual ~Trigger()
+ virtual void FB_CALL dispose(Error* /*error*/)
{
+ delete static_cast<This*>(this);
}
-public:
- virtual void FB_CALL dispose(Error* /*error*/)
+ virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
+ Utf8* /*name*/, uint /*nameSize*/)
{
- delete this;
}
- void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/, Utf8* /*name*/, uint /*nameSize*/)
+ void* operator new(size_t size, const IRoutineMetadata* metadata)
{
+ Trigger* p = reinterpret_cast<Trigger*>(::new char[size]);
+ p->metadata = metadata;
+ return p;
}
+ void operator delete(void* p)
+ {
+ ::delete [] static_cast<char*>(p);
+ }
+
public:
const IRoutineMetadata* metadata;
};
@@ -569,9 +616,7 @@
virtual ExternalFunction* FB_CALL newItem(const IRoutineMetadata* metadata)
{
- Function* function = new T();
- function->metadata = metadata;
- return function;
+ return new(metadata) Routine<T>;
}
private:
@@ -596,9 +641,7 @@
virtual ExternalProcedure* FB_CALL newItem(const IRoutineMetadata* metadata)
{
- Procedure* procedure = new T();
- procedure->metadata = metadata;
- return procedure;
+ return new(metadata) Routine<T>;
}
private:
@@ -623,9 +666,7 @@
virtual ExternalTrigger* FB_CALL newItem(const IRoutineMetadata* metadata)
{
- Trigger* trigger = new T();
- trigger->metadata = metadata;
- return trigger;
+ return new(metadata) Routine<T>;
}
private:
@@ -637,4 +678,4 @@
} // namespace Udr
} // namespace Firebird
-#endif // FIREBIRD_PLUGIN_UDR_CPP
+#endif // FIREBIRD_UDR_CPP_ENGINE
Added: firebird/trunk/src/include/ibase.h
===================================================================
--- firebird/trunk/src/include/ibase.h (rev 0)
+++ firebird/trunk/src/include/ibase.h 2011-06-26 15:57:55 UTC (rev 53242)
@@ -0,0 +1 @@
+#include "../jrd/ibase.h"
Property changes on: firebird/trunk/src/include/ibase.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Modified: firebird/trunk/src/misc/copy-boost.sh
===================================================================
--- firebird/trunk/src/misc/copy-boost.sh 2011-06-26 15:56:56 UTC (rev 53241)
+++ firebird/trunk/src/misc/copy-boost.sh 2011-06-26 15:57:55 UTC (rev 53242)
@@ -15,6 +15,7 @@
git add src/include/firebird/impl/boost/preprocessor/repetition/detail
rm gen/boost
-#git commit src/include/firebird/impl/boost
-#rm -rf src/include/firebird/impl/boost
-#git checkout -- src/include/firebird
+echo Now run this:
+echo git commit src/include/firebird/impl/boost
+echo rm -rf src/include/firebird/impl/boost
+echo git checkout -- src/include/firebird
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|