|
From: <ale...@us...> - 2014-12-18 16:54:53
|
Revision: 60389
http://sourceforge.net/p/firebird/code/60389
Author: alexpeshkoff
Date: 2014-12-18 16:54:44 +0000 (Thu, 18 Dec 2014)
Log Message:
-----------
Changed struct DtcStart to interface. Make external programs build again with minimum changes.
Modified Paths:
--------------
firebird/trunk/examples/interfaces/01.create.cpp
firebird/trunk/examples/interfaces/02.update.cpp
firebird/trunk/examples/interfaces/03.select.cpp
firebird/trunk/examples/interfaces/04.print_table.cpp
firebird/trunk/src/include/firebird/FirebirdInterface.idl
firebird/trunk/src/include/firebird/IdlFbInterfaces.h
firebird/trunk/src/include/firebird/Interface.h
firebird/trunk/src/include/firebird/Message.h
firebird/trunk/src/include/firebird/UdrEngine.h
firebird/trunk/src/yvalve/DistributedTransaction.cpp
firebird/trunk/src/yvalve/MasterImplementation.h
firebird/trunk/src/yvalve/PluginManager.cpp
firebird/trunk/src/yvalve/why.cpp
Added Paths:
-----------
firebird/trunk/examples/interfaces/ifaceExamples.h
Modified: firebird/trunk/examples/interfaces/01.create.cpp
===================================================================
--- firebird/trunk/examples/interfaces/01.create.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/examples/interfaces/01.create.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -33,26 +33,12 @@
* Contributor(s): ______________________________________.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "ifaceExamples.h"
-#include <ibase.h>
-#include <firebird/Interface.h>
-
-using namespace Firebird;
-
// Here we get access to master interface. This is main interface of firebird,
// and the only one for getting which there is special function in our API.
static IMaster* master = fb_get_master_interface();
-// Probably not best way of error processing, but it's OK for a sample
-static void check(IStatus* s, const char* text)
-{
- if (s->getStatus() & IStatus::FB_HAS_ERRORS)
- throw text;
-}
-
int main()
{
int rc = 0;
Modified: firebird/trunk/examples/interfaces/02.update.cpp
===================================================================
--- firebird/trunk/examples/interfaces/02.update.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/examples/interfaces/02.update.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -35,15 +35,8 @@
* Alex Peshkov, 2013
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "ifaceExamples.h"
-#include <ibase.h>
-#include <firebird/Interface.h>
-
-using namespace Firebird;
-
static IMaster* master = fb_get_master_interface();
int get_input(char*, double*);
@@ -53,12 +46,6 @@
{0.05, 1.00, 0.075, 0.10, 0};
int Input_ptr = 0;
-static void check(IStatus* s, const char* text)
-{
- if (s->getStatus() & IStatus::FB_HAS_ERRORS)
- throw text;
-}
-
int main()
{
int rc = 0;
Modified: firebird/trunk/examples/interfaces/03.select.cpp
===================================================================
--- firebird/trunk/examples/interfaces/03.select.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/examples/interfaces/03.select.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -33,23 +33,10 @@
* Contributor(s): ______________________________________.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "ifaceExamples.h"
-#include <ibase.h>
-#include <firebird/Interface.h>
-
-using namespace Firebird;
-
static IMaster* master = fb_get_master_interface();
-static void check(IStatus* s, const char* text)
-{
- if (s->getStatus() & IStatus::FB_HAS_ERRORS)
- throw text;
-}
-
int main()
{
int rc = 0;
Modified: firebird/trunk/examples/interfaces/04.print_table.cpp
===================================================================
--- firebird/trunk/examples/interfaces/04.print_table.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/examples/interfaces/04.print_table.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -32,23 +32,11 @@
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ibase.h>
-#include <firebird/Interface.h>
+#include "ifaceExamples.h"
-using namespace Firebird;
-
static IMaster* master = fb_get_master_interface();
-static void check(IStatus* s, const char* text)
-{
- if (s->getStatus() & IStatus::FB_HAS_ERRORS)
- throw text;
-}
-
struct MyField
{
const char* name;
Added: firebird/trunk/examples/interfaces/ifaceExamples.h
===================================================================
--- firebird/trunk/examples/interfaces/ifaceExamples.h (rev 0)
+++ firebird/trunk/examples/interfaces/ifaceExamples.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -0,0 +1,60 @@
+/*
+ * PROGRAM: Object oriented API samples.
+ * MODULE: ifaceExamples.h
+ * DESCRIPTION: A number of common defines for all samples.
+ *
+ * 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 Alexander Peshkoff
+ * for the Firebird Open Source RDBMS project.
+ *
+ * Copyright (c) 2014 Alexander Peshkoff <pes...@ma...>
+ * and all contributors signed below.
+ *
+ * All Rights Reserved.
+ * Contributor(s): ______________________________________.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <ibase.h>
+#include <firebird/Interface.h>
+
+using namespace Firebird;
+
+typedef FirebirdApi<class ExamplesPolicy> Api;
+FB_USE_API(Api, I)
+
+// Dummy policy - to be enhanced
+class ExamplesPolicy
+{
+public:
+ template <unsigned V, typename T>
+ static inline bool checkVersion(T* versioned, IStatus* status)
+ { return true; }
+ static void checkException(Api::Status*) { }
+ static void catchException(Api::Status*) { }
+ typedef Api::Status* Status;
+};
+
+
+// Declare function to get access to master interface.
+DECLARE_GET_MASTER(ExamplesPolicy);
+
+// Probably not best way of error processing, but it's OK for a sample
+static void check(IStatus* s, const char* text)
+{
+ if (s->getStatus() & IStatus::FB_HAS_ERRORS)
+ throw text;
+}
Property changes on: firebird/trunk/examples/interfaces/ifaceExamples.h
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/x-chdr
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: firebird/trunk/src/include/firebird/FirebirdInterface.idl
===================================================================
--- firebird/trunk/src/include/firebird/FirebirdInterface.idl 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/include/firebird/FirebirdInterface.idl 2014-12-18 16:54:44 UTC (rev 60389)
@@ -533,21 +533,22 @@
void setDbCryptCallback(Status status, CryptKeyCallback cryptCallback);
}
-/*** FIXME:
-// DtcStart - structure to start transaction over >1 attachments (former TEB)
-struct DtcStart
+// Helper to start transaction over >1 attachments (former TEB)
+interface DtcStart : Disposable
{
- Attachment attachment;
- const uchar* tpb;
- uint tpbLength;
+ void setComponent(Status status, Attachment att);
+ void setWithParam(Status status, Attachment att, uint length, const uchar* tpb);
+ uint getCount(Status status);
+ Attachment getAttachment(Status status, uint pos);
+ const uchar* getTpb(Status status, uint pos, uint* length);
}
-***/
// Distributed transactions coordinator
interface Dtc : Versioned
{
- Transaction start(Status status, uint cnt, DtcStart* components);
+ Transaction start(Status status, DtcStart components);
Transaction join(Status status, Transaction one, Transaction two);
+ DtcStart startBuilder(Status status);
}
Modified: firebird/trunk/src/include/firebird/IdlFbInterfaces.h
===================================================================
--- firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -56,6 +56,7 @@
class Attachment;
class Service;
class Provider;
+ class DtcStart;
class Dtc;
class Auth;
class Writer;
@@ -2009,13 +2010,78 @@
}
};
+ class DtcStart : public Disposable
+ {
+ public:
+ struct VTable : public Disposable::VTable
+ {
+ void (CLOOP_CARG *setComponent)(DtcStart* self, Status* status, Attachment* att) throw();
+ void (CLOOP_CARG *setWithParam)(DtcStart* self, Status* status, Attachment* att, unsigned length, const unsigned char* tpb) throw();
+ unsigned (CLOOP_CARG *getCount)(DtcStart* self, Status* status) throw();
+ Attachment* (CLOOP_CARG *getAttachment)(DtcStart* self, Status* status, unsigned pos) throw();
+ const unsigned char* (CLOOP_CARG *getTpb)(DtcStart* self, Status* status, unsigned pos, unsigned* length) throw();
+ };
+
+ protected:
+ DtcStart(DoNotInherit)
+ : Disposable(DoNotInherit())
+ {
+ }
+
+ ~DtcStart()
+ {
+ }
+
+ public:
+ static const unsigned VERSION = 3;
+
+ void setComponent(Status* status, Attachment* att)
+ {
+ typename Policy::Status status2(status);
+ static_cast<VTable*>(this->cloopVTable)->setComponent(this, status2, att);
+ Policy::checkException(status2);
+ }
+
+ void setWithParam(Status* status, Attachment* att, unsigned length, const unsigned char* tpb)
+ {
+ typename Policy::Status status2(status);
+ static_cast<VTable*>(this->cloopVTable)->setWithParam(this, status2, att, length, tpb);
+ Policy::checkException(status2);
+ }
+
+ unsigned getCount(Status* status)
+ {
+ typename Policy::Status status2(status);
+ unsigned ret = static_cast<VTable*>(this->cloopVTable)->getCount(this, status2);
+ Policy::checkException(status2);
+ return ret;
+ }
+
+ Attachment* getAttachment(Status* status, unsigned pos)
+ {
+ typename Policy::Status status2(status);
+ Attachment* ret = static_cast<VTable*>(this->cloopVTable)->getAttachment(this, status2, pos);
+ Policy::checkException(status2);
+ return ret;
+ }
+
+ const unsigned char* getTpb(Status* status, unsigned pos, unsigned* length)
+ {
+ typename Policy::Status status2(status);
+ const unsigned char* ret = static_cast<VTable*>(this->cloopVTable)->getTpb(this, status2, pos, length);
+ Policy::checkException(status2);
+ return ret;
+ }
+ };
+
class Dtc : public Versioned
{
public:
struct VTable : public Versioned::VTable
{
- Transaction* (CLOOP_CARG *start)(Dtc* self, Status* status, unsigned cnt, DtcStart* components) throw();
+ Transaction* (CLOOP_CARG *start)(Dtc* self, Status* status, DtcStart* components) throw();
Transaction* (CLOOP_CARG *join)(Dtc* self, Status* status, Transaction* one, Transaction* two) throw();
+ DtcStart* (CLOOP_CARG *startBuilder)(Dtc* self, Status* status) throw();
};
protected:
@@ -2031,10 +2097,10 @@
public:
static const unsigned VERSION = 2;
- Transaction* start(Status* status, unsigned cnt, DtcStart* components)
+ Transaction* start(Status* status, DtcStart* components)
{
typename Policy::Status status2(status);
- Transaction* ret = static_cast<VTable*>(this->cloopVTable)->start(this, status2, cnt, components);
+ Transaction* ret = static_cast<VTable*>(this->cloopVTable)->start(this, status2, components);
Policy::checkException(status2);
return ret;
}
@@ -2046,6 +2112,14 @@
Policy::checkException(status2);
return ret;
}
+
+ DtcStart* startBuilder(Status* status)
+ {
+ typename Policy::Status status2(status);
+ DtcStart* ret = static_cast<VTable*>(this->cloopVTable)->startBuilder(this, status2);
+ Policy::checkException(status2);
+ return ret;
+ }
};
class Auth : public PluginBase
@@ -8636,6 +8710,141 @@
};
template <typename Name, typename Base>
+ class DtcStartBaseImpl : public Base
+ {
+ public:
+ typedef DtcStart Declaration;
+
+ DtcStartBaseImpl(DoNotInherit = DoNotInherit())
+ {
+ static struct VTableImpl : Base::VTable
+ {
+ VTableImpl()
+ {
+ this->version = Base::VERSION;
+ this->getModule = &Name::cloopgetModuleDispatcher;
+ this->dispose = &Name::cloopdisposeDispatcher;
+ this->setComponent = &Name::cloopsetComponentDispatcher;
+ this->setWithParam = &Name::cloopsetWithParamDispatcher;
+ this->getCount = &Name::cloopgetCountDispatcher;
+ this->getAttachment = &Name::cloopgetAttachmentDispatcher;
+ this->getTpb = &Name::cloopgetTpbDispatcher;
+ }
+ } vTable;
+
+ this->cloopVTable = &vTable;
+ }
+
+ static void CLOOP_CARG cloopsetComponentDispatcher(DtcStart* self, Status* status, Attachment* att) throw()
+ {
+ try
+ {
+ static_cast<Name*>(self)->Name::setComponent(status, att);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ }
+ }
+
+ static void CLOOP_CARG cloopsetWithParamDispatcher(DtcStart* self, Status* status, Attachment* att, unsigned length, const unsigned char* tpb) throw()
+ {
+ try
+ {
+ static_cast<Name*>(self)->Name::setWithParam(status, att, length, tpb);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ }
+ }
+
+ static unsigned CLOOP_CARG cloopgetCountDispatcher(DtcStart* self, Status* status) throw()
+ {
+ try
+ {
+ return static_cast<Name*>(self)->Name::getCount(status);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ return static_cast<unsigned>(0);
+ }
+ }
+
+ static Attachment* CLOOP_CARG cloopgetAttachmentDispatcher(DtcStart* self, Status* status, unsigned pos) throw()
+ {
+ try
+ {
+ return static_cast<Name*>(self)->Name::getAttachment(status, pos);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ return static_cast<Attachment*>(0);
+ }
+ }
+
+ static const unsigned char* CLOOP_CARG cloopgetTpbDispatcher(DtcStart* self, Status* status, unsigned pos, unsigned* length) throw()
+ {
+ try
+ {
+ return static_cast<Name*>(self)->Name::getTpb(status, pos, length);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ return static_cast<const unsigned char*>(0);
+ }
+ }
+
+ static void CLOOP_CARG cloopdisposeDispatcher(Disposable* self) throw()
+ {
+ try
+ {
+ static_cast<Name*>(self)->Name::dispose();
+ }
+ catch (...)
+ {
+ Policy::catchException(0);
+ }
+ }
+
+ static PluginModule* CLOOP_CARG cloopgetModuleDispatcher(Versioned* self) throw()
+ {
+ try
+ {
+ return static_cast<Name*>(self)->Name::getModule();
+ }
+ catch (...)
+ {
+ Policy::catchException(0);
+ return static_cast<PluginModule*>(0);
+ }
+ }
+ };
+
+ template <typename Name, typename Base = DisposableImpl<Name, Inherit<VersionedImpl<Name, Inherit<DtcStart> > > > >
+ class DtcStartImpl : public DtcStartBaseImpl<Name, Base>
+ {
+ protected:
+ DtcStartImpl(DoNotInherit = DoNotInherit())
+ {
+ }
+
+ public:
+ virtual ~DtcStartImpl()
+ {
+ }
+
+ virtual void setComponent(Status* status, Attachment* att) = 0;
+ virtual void setWithParam(Status* status, Attachment* att, unsigned length, const unsigned char* tpb) = 0;
+ virtual unsigned getCount(Status* status) = 0;
+ virtual Attachment* getAttachment(Status* status, unsigned pos) = 0;
+ virtual const unsigned char* getTpb(Status* status, unsigned pos, unsigned* length) = 0;
+ };
+
+ template <typename Name, typename Base>
class DtcBaseImpl : public Base
{
public:
@@ -8651,17 +8860,18 @@
this->getModule = &Name::cloopgetModuleDispatcher;
this->start = &Name::cloopstartDispatcher;
this->join = &Name::cloopjoinDispatcher;
+ this->startBuilder = &Name::cloopstartBuilderDispatcher;
}
} vTable;
this->cloopVTable = &vTable;
}
- static Transaction* CLOOP_CARG cloopstartDispatcher(Dtc* self, Status* status, unsigned cnt, DtcStart* components) throw()
+ static Transaction* CLOOP_CARG cloopstartDispatcher(Dtc* self, Status* status, DtcStart* components) throw()
{
try
{
- return static_cast<Name*>(self)->Name::start(status, cnt, components);
+ return static_cast<Name*>(self)->Name::start(status, components);
}
catch (...)
{
@@ -8683,6 +8893,19 @@
}
}
+ static DtcStart* CLOOP_CARG cloopstartBuilderDispatcher(Dtc* self, Status* status) throw()
+ {
+ try
+ {
+ return static_cast<Name*>(self)->Name::startBuilder(status);
+ }
+ catch (...)
+ {
+ Policy::catchException(status);
+ return static_cast<DtcStart*>(0);
+ }
+ }
+
static PluginModule* CLOOP_CARG cloopgetModuleDispatcher(Versioned* self) throw()
{
try
@@ -8710,8 +8933,9 @@
{
}
- virtual Transaction* start(Status* status, unsigned cnt, DtcStart* components) = 0;
+ virtual Transaction* start(Status* status, DtcStart* components) = 0;
virtual Transaction* join(Status* status, Transaction* one, Transaction* two) = 0;
+ virtual DtcStart* startBuilder(Status* status) = 0;
};
template <typename Name, typename Base>
Modified: firebird/trunk/src/include/firebird/Interface.h
===================================================================
--- firebird/trunk/src/include/firebird/Interface.h 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/include/firebird/Interface.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -42,12 +42,10 @@
{
struct FbCryptKey;
-struct DtcStart;
#include "IdlFbInterfaces.h"
#define FB_USE_API(name, prefix) \
- /* awk <FirebirdInterface.idl '($1 == "interface") {printf "\t\ttypedef name::%s prefix##%s;\n", $2, $2;}' */ \
typedef name::Versioned prefix##Versioned; \
typedef name::ReferenceCounted prefix##ReferenceCounted; \
typedef name::Disposable prefix##Disposable; \
@@ -75,6 +73,7 @@
typedef name::Attachment prefix##Attachment; \
typedef name::Service prefix##Service; \
typedef name::Provider prefix##Provider; \
+ typedef name::DtcStart prefix##DtcStart; \
typedef name::Dtc prefix##Dtc; \
typedef name::Auth prefix##Auth; \
typedef name::Writer prefix##Writer; \
@@ -174,15 +173,6 @@
unsigned decryptLength; // Ignored when decryptKey is NULL
};
-struct DtcStart
-{
- IAttachment* attachment;
- const unsigned char* tpb;
- unsigned tpbLength;
-};
-
-typedef void PluginEntrypoint(IMaster* masterInterface);
-
#ifdef INCLUDE_Firebird_H // Building internal module
// This item is for ISC API emulation only
@@ -196,12 +186,13 @@
#define FB_PLUGIN_ENTRY_POINT firebird_plugin
-extern "C"
-{
- // Additional API function.
- // Should be used only in non-plugin modules.
- // All plugins including providers should use passed at init time interface instead.
- Firebird::IMaster* ISC_EXPORT fb_get_master_interface();
-}
+// Additional API function.
+// Should be used only in non-plugin modules.
+// All plugins including providers should use passed at init time interface instead.
+#define DECLARE_GET_MASTER(P) extern "C" Firebird::FirebirdApi<P>::Master* ISC_EXPORT fb_get_master_interface();
+#ifdef INCLUDE_Firebird_H // Building internal module
+DECLARE_GET_MASTER(Firebird::FirebirdPolicy)
+#endif //INCLUDE_Firebird_H
+
#endif // FB_INCLUDE_INTERFACE
Modified: firebird/trunk/src/include/firebird/Message.h
===================================================================
--- firebird/trunk/src/include/firebird/Message.h 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/include/firebird/Message.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -30,6 +30,33 @@
#include <time.h>
#include <string.h>
+//----------------------------------------------------------------
+// This ifdef is a dirty hack to make tests (fbstuff) to compile
+#ifndef INCLUDE_Firebird_H
+
+namespace Firebird
+{
+typedef FirebirdApi<class TempPolicy> Api;
+FB_USE_API(Api, I)
+
+class TempPolicy
+{
+public:
+ template <unsigned V, typename T>
+ static inline bool checkVersion(T* versioned, IStatus* status)
+ { return true; }
+ static void checkException(Api::Status*) { }
+ static void catchException(Api::Status*) { }
+ typedef Api::Status* Status;
+};
+} //namespace Firebird
+
+DECLARE_GET_MASTER(Firebird::TempPolicy)
+#define INCLUDE_Firebird_H
+
+#endif
+//- END OF HACK --------------------------------------------------
+
#define FB_MESSAGE(name, fields) \
FB__MESSAGE_I(name, 2, FB_BOOST_PP_CAT(FB__MESSAGE_X fields, 0), )
Modified: firebird/trunk/src/include/firebird/UdrEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrEngine.h 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/include/firebird/UdrEngine.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -25,6 +25,34 @@
#include "./Interface.h"
+//----------------------------------------------------------------
+// This ifdef is a dirty hack to make tests (fbstuff) to compile
+#ifndef INCLUDE_Firebird_H
+
+namespace Firebird
+{
+typedef FirebirdApi<class TempPolicy> Api;
+FB_USE_API(Api, I)
+
+class TempPolicy
+{
+public:
+ template <unsigned V, typename T>
+ static inline bool checkVersion(T* versioned, IStatus* status)
+ { return true; }
+ static void checkException(Api::Status*) { }
+ static void catchException(Api::Status*) { }
+ typedef Api::Status* Status;
+};
+} //namespace Firebird
+
+DECLARE_GET_MASTER(Firebird::TempPolicy)
+#define INCLUDE_Firebird_H
+
+#endif
+//- END OF HACK --------------------------------------------------
+
+
#ifndef FB_EXPORTED
#if defined(DARWIN)
#define FB_EXPORTED __attribute__((visibility("default")))
Modified: firebird/trunk/src/yvalve/DistributedTransaction.cpp
===================================================================
--- firebird/trunk/src/yvalve/DistributedTransaction.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/yvalve/DistributedTransaction.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -498,7 +498,7 @@
namespace Why {
-YTransaction* Dtc::start(IStatus* status, unsigned int cnt, DtcStart* components)
+YTransaction* Dtc::start(IStatus* status, IDtcStart* components)
{
try
{
@@ -506,26 +506,37 @@
RefPtr<DTransaction> dtransaction(new DTransaction);
- for (unsigned int i = 0; i < cnt; ++i)
+ unsigned cnt = components->getCount(status);
+ if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
+ status_exception::raise(status);
+
+ for (unsigned i = 0; i < cnt; ++i)
{
- RefPtr<ITransaction> transaction(components[i].attachment->
- startTransaction(status, components[i].tpbLength, components[i].tpb));
+ RefPtr<IAttachment> att(REF_NO_INCR, components->getAttachment(status, i));
+ if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
+ status_exception::raise(status);
+ unsigned tpbLen;
+ const unsigned char* tpb = components->getTpb(status, i, &tpbLen);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
- return NULL;
+ status_exception::raise(status);
- dtransaction->join(status, transaction);
+ ITransaction* started = att->startTransaction(status, tpbLen, tpb);
+ if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
+ status_exception::raise(status);
+ dtransaction->join(status, started);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
{
- LocalStatus tmp;
- dtransaction->rollback(&tmp);
- return NULL;
+ started->release();
+ status_exception::raise(status);
}
}
+ YTransaction* rc = new YTransaction(NULL, dtransaction);
dtransaction->addRef();
- return new YTransaction(NULL, dtransaction);
+ components->dispose();
+ return rc;
}
catch (const Exception& ex)
{
@@ -564,4 +575,114 @@
return NULL;
}
+class DtcStart : public DisposeIface<Api::DtcStartImpl<DtcStart> >
+{
+public:
+ DtcStart()
+ : components(getPool())
+ { }
+
+ // IDtcStart implementation
+ void setComponent(IStatus* status, IAttachment* att)
+ {
+ this->setWithParam(status, att, 0, NULL);
+ }
+
+ void setWithParam(IStatus* status, IAttachment* att, unsigned length, const unsigned char* tpb)
+ {
+ try
+ {
+ Component toAdd;
+ toAdd.att = att;
+ toAdd.tpbLen = length;
+ toAdd.tpb = tpb;
+
+ components.add(toAdd);
+ att->addRef();
+ }
+ catch (const Exception& ex)
+ {
+ ex.stuffException(status);
+ }
+ }
+
+ unsigned getCount(IStatus*)
+ {
+ return components.getCount();
+ }
+
+ IAttachment* getAttachment(IStatus* status, unsigned pos)
+ {
+ try
+ {
+ errorOver(pos);
+
+ components[pos].att->addRef();
+ return components[pos].att;
+ }
+ catch (const Exception& ex)
+ {
+ ex.stuffException(status);
+ }
+ return NULL;
+ }
+
+ const unsigned char* getTpb(IStatus* status, unsigned pos, unsigned* length)
+ {
+ try
+ {
+ errorOver(pos);
+
+ *length = components[pos].tpbLen;
+ return components[pos].tpb;
+ }
+ catch (const Exception& ex)
+ {
+ ex.stuffException(status);
+ }
+ return NULL;
+ }
+
+ void dispose()
+ {
+ for (unsigned i = 0; i < components.getCount(); ++i)
+ components[i].att->release();
+
+ delete this;
+ }
+
+private:
+ struct Component
+ {
+ IAttachment* att;
+ unsigned tpbLen;
+ const unsigned char* tpb;
+ };
+
+ HalfStaticArray<Component, 16> components;
+
+ void errorOver(unsigned n)
+ {
+ // TODO: add component num & limit to the message
+ if (n >= components.getCount())
+ (Arg::Gds(isc_random) << "Access to invalid component number in DtcStart").raise();
+ }
+};
+
+IDtcStart* Dtc::startBuilder(IStatus* status)
+{
+ try
+ {
+ status->init();
+
+ return new DtcStart;
+ }
+ catch (const Exception& ex)
+ {
+ ex.stuffException(status);
+ }
+
+ return NULL;
+}
+
} // namespace Why
Modified: firebird/trunk/src/yvalve/MasterImplementation.h
===================================================================
--- firebird/trunk/src/yvalve/MasterImplementation.h 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/yvalve/MasterImplementation.h 2014-12-18 16:54:44 UTC (rev 60389)
@@ -45,10 +45,10 @@
{
public:
// IDtc implementation
- YTransaction* start(Firebird::IStatus* status,
- unsigned int cnt, Firebird::DtcStart* components);
+ YTransaction* start(Firebird::IStatus* status, Firebird::IDtcStart* components);
YTransaction* join(Firebird::IStatus* status,
Firebird::ITransaction* one, Firebird::ITransaction* two);
+ Firebird::IDtcStart* startBuilder(Firebird::IStatus* status);
};
class MasterImplementation : public Firebird::AutoIface<Firebird::Api::MasterImpl<MasterImplementation> >
Modified: firebird/trunk/src/yvalve/PluginManager.cpp
===================================================================
--- firebird/trunk/src/yvalve/PluginManager.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/yvalve/PluginManager.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -946,6 +946,7 @@
}
RefPtr<PluginModule> rc(new PluginModule(module, info.curModule));
+ typedef void PluginEntrypoint(IMaster* masterInterface);
PluginEntrypoint* startModule;
if (module->findSymbol(STRINGIZE(FB_PLUGIN_ENTRY_POINT), startModule))
{
Modified: firebird/trunk/src/yvalve/why.cpp
===================================================================
--- firebird/trunk/src/yvalve/why.cpp 2014-12-18 16:23:03 UTC (rev 60388)
+++ firebird/trunk/src/yvalve/why.cpp 2014-12-18 16:54:44 UTC (rev 60389)
@@ -3407,7 +3407,6 @@
StatusVector status(userStatus);
TEB* vector = (TEB*) vec;
YTransaction* multiTrans = NULL;
- DtcStart* ds = NULL;
try
{
@@ -3429,22 +3428,20 @@
return status[1];
}
- HalfStaticArray<DtcStart, 16> dtcStartBuffer;
- ds = dtcStartBuffer.getBuffer(count);
- memset(ds, 0, sizeof(DtcStart) * count);
- DtcStart* const end = ds + count;
+ IDtcStart* ds = MasterImplementation::dtc->startBuilder(&status);
+ if (status.getStatus() & IStatus::FB_HAS_ERRORS)
+ return status[1];
- for (DtcStart* p = ds; p < end; ++p, ++vector)
+ for (unsigned u = 0; u < count; ++u)
{
RefPtr<YAttachment> attachment(translateHandle(attachments, vector->teb_database));
- p->attachment = attachment;
- attachment->addRef();
- p->tpbLength = vector->teb_tpb_length;
- p->tpb = reinterpret_cast<const unsigned char*>(vector->teb_tpb);
+ ds->setWithParam(&status, attachment, vector->teb_tpb_length,
+ reinterpret_cast<const unsigned char*>(vector->teb_tpb));
+ if (status.getStatus() & IStatus::FB_HAS_ERRORS)
+ return status[1];
}
- multiTrans = MasterImplementation::dtc->start(&status, count, ds);
-
+ multiTrans = MasterImplementation::dtc->start(&status, ds);
if (multiTrans)
*traHandle = multiTrans->getHandle();
}
@@ -3458,17 +3455,6 @@
e.stuffException(&status);
}
- if (ds)
- {
- DtcStart* const end = ds + count;
-
- for (DtcStart* p = ds; p < end; ++p)
- {
- if (p->attachment)
- p->attachment->release();
- }
- }
-
return status[1];
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|