1 /* Copyright (c) 2003-2006 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 #include <ndb_global.h>
19 #include "NdbApiSignal.hpp"
20 #include "NdbImpl.hpp"
21 #include <NdbOperation.hpp>
22 #include <NdbTransaction.hpp>
23 #include <NdbRecAttr.hpp>
24 #include <IPCConfig.hpp>
25 #include "TransporterFacade.hpp"
26 #include <ConfigRetriever.hpp>
27 #include <ndb_limits.h>
30 #include "ObjectMap.hpp"
31 #include <NdbIndexScanOperation.hpp>
32 #include <NdbIndexOperation.hpp>
33 #include "NdbUtil.hpp"
34 #include <NdbBlob.hpp>
35 #include "NdbEventOperationImpl.hpp"
37 #include <EventLogger.hpp>
38 extern EventLogger g_eventLogger
;
40 Ndb::Ndb( Ndb_cluster_connection
*ndb_cluster_connection
,
41 const char* aDataBase
, const char* aSchema
)
44 DBUG_ENTER("Ndb::Ndb()");
45 DBUG_PRINT("enter",("Ndb::Ndb this: 0x%lx", (long) this));
46 setup(ndb_cluster_connection
, aDataBase
, aSchema
);
50 void Ndb::setup(Ndb_cluster_connection
*ndb_cluster_connection
,
51 const char* aDataBase
, const char* aSchema
)
53 DBUG_ENTER("Ndb::setup");
55 assert(theImpl
== NULL
);
56 theImpl
= new NdbImpl(ndb_cluster_connection
,*this);
57 theDictionary
= &(theImpl
->m_dictionary
);
59 thePreparedTransactionsArray
= NULL
;
60 theSentTransactionsArray
= NULL
;
61 theCompletedTransactionsArray
= NULL
;
62 theNoOfPreparedTransactions
= 0;
63 theNoOfSentTransactions
= 0;
64 theNoOfCompletedTransactions
= 0;
65 theRemainingStartTransactions
= 0;
66 theMaxNoOfTransactions
= 0;
67 theMinNoOfEventsToWakeUp
= 0;
68 theTransactionList
= NULL
;
69 theConnectionArray
= NULL
;
70 the_last_check_time
= 0;
73 theNdbBlockNumber
= -1;
74 theInitState
= NotConstructed
;
80 cond_wait_index
= TransporterFacade::MAX_NO_THREADS
;
81 cond_signal_ndb
= NULL
;
83 fullyQualifiedNames
= true;
94 theConnectionArray
= new NdbConnection
* [MAX_NDB_NODES
];
95 theCommitAckSignal
= NULL
;
98 for (i
= 0; i
< MAX_NDB_NODES
; i
++) {
99 theConnectionArray
[i
] = NULL
;
103 theImpl
->m_dbname
.assign(aDataBase
);
104 theImpl
->m_schemaname
.assign(aSchema
);
105 theImpl
->update_prefix();
107 theImpl
->theWaiter
.m_mutex
= theImpl
->m_transporter_facade
->theMutexPtr
;
109 // Signal that the constructor has finished OK
110 if (theInitState
== NotConstructed
)
111 theInitState
= NotInitialised
;
114 // theImpl->theWaiter.m_mutex must be set before this
115 theEventBuffer
= new NdbEventBuffer(this);
116 if (theEventBuffer
== NULL
) {
117 ndbout_c("Failed NdbEventBuffer()");
126 /*****************************************************************************
129 * Remark: Disconnect with the database.
130 *****************************************************************************/
133 DBUG_ENTER("Ndb::~Ndb()");
134 DBUG_PRINT("enter",("this: 0x%lx", (long) this));
137 getDictionary()->removeTableGlobal(*m_sys_tab_0
, 0);
139 assert(theImpl
->m_ev_op
== 0); // user should return NdbEventOperation's
140 for (NdbEventOperationImpl
*op
= theImpl
->m_ev_op
; op
; op
=op
->m_next
)
142 if (op
->m_state
== NdbEventOperation::EO_EXECUTING
&& op
->stop())
143 g_eventLogger
.error("stopping NdbEventOperation failed in Ndb destructor");
144 op
->m_magic_number
= 0;
148 /* Disconnect from transporter to stop signals from coming in */
149 if (theImpl
->m_transporter_facade
!= NULL
&& theNdbBlockNumber
> 0){
150 theImpl
->m_transporter_facade
->close(theNdbBlockNumber
, theFirstTransId
);
153 delete theEventBuffer
;
155 releaseTransactionArrays();
157 delete []theConnectionArray
;
158 if(theCommitAckSignal
!= NULL
){
159 delete theCommitAckSignal
;
160 theCommitAckSignal
= NULL
;
165 #ifdef POORMANSPURIFY
167 ndbout
<< "cnewSignals=" << cnewSignals
<< endl
;
168 ndbout
<< "cfreeSignals=" << cfreeSignals
<< endl
;
169 ndbout
<< "cgetSignals=" << cgetSignals
<< endl
;
170 ndbout
<< "creleaseSignals=" << creleaseSignals
<< endl
;
172 // Poor mans purifier
173 assert(cnewSignals
== cfreeSignals
);
174 assert(cgetSignals
== creleaseSignals
);
179 NdbWaiter::NdbWaiter(){
184 m_cond_wait_index
= TransporterFacade::MAX_NO_THREADS
;
185 m_condition
= NdbCondition_Create();
188 NdbWaiter::~NdbWaiter(){
189 NdbCondition_Destroy(m_condition
);
192 NdbImpl::NdbImpl(Ndb_cluster_connection
*ndb_cluster_connection
,
195 m_ndb_cluster_connection(ndb_cluster_connection
->m_impl
),
196 m_transporter_facade(ndb_cluster_connection
->m_impl
.m_transporter_facade
),
198 theCurrentConnectIndex(0),
199 theNdbObjectIdMap(m_transporter_facade
->theMutexPtr
,
205 for (i
= 0; i
< MAX_NDB_NODES
; i
++) {
206 the_release_ind
[i
] = 0;
208 m_optimized_node_selection
=
209 m_ndb_cluster_connection
.m_optimized_node_selection
;
211 m_systemPrefix
.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE
, table_name_separator
,
212 NDB_SYSTEM_SCHEMA
, table_name_separator
);