Ndb.hpp 63.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/**
   @mainpage                            NDB API Programmers' Guide

unknown's avatar
unknown committed
20 21 22 23
   This guide assumes a basic familiarity with MySQL Cluster concepts found
   on http://dev.mysql.com/doc/mysql/en/NDBCluster.html .
   Some of the fundamental ones are also described in section @ref secConcepts.

24
   The <em>NDB API</em> is a MySQL Cluster application interface 
unknown's avatar
unknown committed
25
   that implements transactions.
26
   The NDB API consists of the following fundamental classes:
27
   - Ndb_cluster_connection, representing a connection to a cluster, 
unknown's avatar
unknown committed
28
   - Ndb is the main class, representing a connection to a database, 
29 30 31 32 33
   - NdbTransaction represents a transaction, 
   - NdbOperation represents an operation using a primary key,
   - NdbScanOperation represents an operation performing a full table scan.
   - NdbIndexOperation represents an operation using a unique hash index,
   - NdbIndexScanOperation represents an operation performing a scan using
unknown's avatar
unknown committed
34
     an ordered index,
35 36 37
   - NdbRecAttr represents an attribute value
   - NdbDictionary represents meta information about tables and attributes.
   - NdbError contains the specification for an error.
unknown's avatar
unknown committed
38 39 40 41

   It is also possible to receive "events" on changed data in the database.
   This is done through the NdbEventOperation class.

42 43 44
   There are also some auxiliary classes.
     
   The main structure of an application program is as follows:
45
   -# Construct and connect to a cluster using the Ndb_cluster_connection
unknown's avatar
unknown committed
46
      object.
unknown's avatar
unknown committed
47 48 49 50
   -# Construct and initialize Ndb object(s) to connect to a database.
   -# Define and execute transactions using NdbTransaction.
   -# Delete Ndb objects.
   -# Delete cluster connection.
51 52

   The main structure of a transaction is as follows:
53
   -# Start transaction (an NdbTransaction)
54
   -# Add and define operations associated with the transaction using
unknown's avatar
unknown committed
55
      NdbOperation, NdbScanOperation, NdbIndexOperation, NdbIndexScanOperation
56 57
   -# Execute transaction

58 59 60
   The execution can be of two different types, 
   <var>Commit</var> or <var>NoCommit</var>.
   If the execution is of type <var>NoCommit</var>, 
61 62
   then the application program executes part of a transaction,
   but without committing the transaction.
63
   After executing a <var>NoCommit</var> transaction, the program can continue 
64 65 66
   to add and define more operations to the transaction
   for later execution.

67
   If the execute is of type <var>Commit</var>, then the transaction is
unknown's avatar
unknown committed
68 69 70
   committed. The transaction <em>must</em> be closed after it has been 
   commited (event if commit fails), and no further addition or definition of 
   operations is allowed.
71 72 73 74


   @section secSync                     Synchronous Transactions
  
75
   Synchronous transactions are defined and executed as follows:
76
  
77
    -# Start (create) the transaction, which is
78 79
       referenced by an NdbTransaction object 
       (typically created using Ndb::startTransaction()).
80 81
       At this point, the transaction is only being defined,
       and is not yet sent to the NDB kernel.
unknown's avatar
unknown committed
82 83 84 85 86 87
    -# Define operations and add them to the transaction, using 
       NdbTransaction::getNdbOperation(),
       NdbTransaction::getNdbScanOperation(),
       NdbTransaction::getNdbIndexOperation(), or
       NdbTransaction::getNdbIndexScanOperation(),
       and methods of the respective NdbOperation class.
88
       Note that the transaction has still not yet been sent to the NDB kernel.
89 90
    -# Execute the transaction, using the NdbTransaction::execute() method.
    -# Close the transaction (using Ndb::closeTransaction()).
91
  
unknown's avatar
unknown committed
92 93
   For an example of this process, see the program listing in 
   @ref ndbapi_simple.cpp.
94 95

   To execute several parallel synchronous transactions, one can either 
96
   use multiple Ndb objects in several threads, or start multiple 
97
   applications programs.  
98

99 100
   @section secNdbOperations            Operations

unknown's avatar
unknown committed
101 102 103
   Each NdbTransaction consists of a list of operations which are represented 
   by instances of NdbOperation, NdbScanOperation, NdbIndexOperation, and/or
   NdbIndexScanOperation.
104

unknown's avatar
unknown committed
105
   <h3>Single row operations</h3>
106 107
   After the operation is created using NdbTransaction::getNdbOperation()
   (or NdbTransaction::getNdbIndexOperation()), it is defined in the following 
108
   three steps:
109 110 111
   -# Define the standard operation type, using NdbOperation::readTuple()
   -# Specify search conditions, using NdbOperation::equal()
   -# Specify attribute actions, using NdbOperation::getValue()
112

unknown's avatar
unknown committed
113 114
   Here are two brief examples illustrating this process. For the sake of 
   brevity, we omit error-handling.
115
   
116
   This first example uses an NdbOperation:
117
   @code
unknown's avatar
unknown committed
118
     // 1. Create
119
     MyOperation= MyTransaction->getNdbOperation("MYTABLENAME");
120
    
unknown's avatar
unknown committed
121 122 123 124 125
     // 2. Define type of operation and lock mode
     MyOperation->readTuple(NdbOperation::LM_Read);

     // 3. Specify Search Conditions
     MyOperation->equal("ATTR1", i);
126
    
unknown's avatar
unknown committed
127 128
     // 4. Attribute Actions
     MyRecAttr= MyOperation->getValue("ATTR2", NULL);
129
   @endcode
unknown's avatar
unknown committed
130
   For additional examples of this sort, see @ref ndbapi_simple.cpp.
131

132
   The second example uses an NdbIndexOperation:
133
   @code
unknown's avatar
unknown committed
134
     // 1. Create
unknown's avatar
unknown committed
135
     MyOperation= MyTransaction->getNdbIndexOperation("MYINDEX","MYTABLENAME");
unknown's avatar
unknown committed
136 137 138

     // 2. Define type of operation and lock mode
     MyOperation->readTuple(NdbOperation::LM_Read);
139

unknown's avatar
unknown committed
140 141
     // 3. Specify Search Conditions
     MyOperation->equal("ATTR1", i);
142

unknown's avatar
unknown committed
143 144
     // 4. Attribute Actions 
     MyRecAttr = MyOperation->getValue("ATTR2", NULL);
145
   @endcode
unknown's avatar
unknown committed
146 147
   Another example of this second type can be found in 
   @ref ndbapi_simple_index.cpp.
148

unknown's avatar
unknown committed
149 150
   We will now discuss in somewhat greater detail each step involved in the 
   creation and use of synchronous transactions.
151

unknown's avatar
unknown committed
152 153
   <h4>Step 1: Define single row operation type</h4>
   The following types of operations exist:
154 155 156 157 158 159 160 161 162 163
    -# NdbOperation::insertTuple : 
       inserts a non-existing tuple
    -# NdbOperation::writeTuple : 
       updates an existing tuple if is exists,
       otherwise inserts a new tuple
    -# NdbOperation::updateTuple : 
       updates an existing tuple
    -# NdbOperation::deleteTuple : 
       deletes an existing tuple
    -# NdbOperation::readTuple : 
unknown's avatar
unknown committed
164
       reads an existing tuple with specified lock mode
165 166 167

   All of these operations operate on the unique tuple key.
   (When NdbIndexOperation is used then all of these operations 
unknown's avatar
unknown committed
168
   operate on a defined unique hash index.)
169 170

   @note If you want to define multiple operations within the same transaction,
unknown's avatar
unknown committed
171 172
         then you need to call NdbTransaction::getNdbOperation() or
	 NdbTransaction::getNdbIndexOperation() for each operation.
173 174

   <h4>Step 2: Specify Search Conditions</h4>
unknown's avatar
unknown committed
175
   The search condition is used to select tuples using NdbOperation::equal()
176 177 178 179 180 181 182 183 184

   <h4>Step 3: Specify Attribute Actions</h4>
   Now it is time to define which attributes should be read or updated.
   Deletes can neither read nor set values, read can only read values and
   updates can only set values.
   Normally the attribute is defined by its name but it is
   also possible to use the attribute identity to define the
   attribute.

unknown's avatar
unknown committed
185
   NdbOperation::getValue() returns an NdbRecAttr object
186 187 188 189
   containing the read value.
   To get the value, there is actually two methods.
   The application can either
   - use its own memory (passed through a pointer aValue) to
unknown's avatar
unknown committed
190
     NdbOperation::getValue(), or
191 192 193
   - receive the attribute value in an NdbRecAttr object allocated
     by the NDB API.

unknown's avatar
unknown committed
194
   The NdbRecAttr object is released when Ndb::closeTransaction()
195 196
   is called.
   Thus, the application can not reference this object after
unknown's avatar
unknown committed
197
   Ndb::closeTransaction() have been called.
198
   The result of reading data from an NdbRecAttr object before
unknown's avatar
unknown committed
199
   calling NdbTransaction::execute() is undefined.
200 201


202 203 204
   @subsection secScan              Scan Operations 
   
   Scans are roughly the equivalent of SQL cursors.
205

206 207
   Scans can either be performed on a table (@ref NdbScanOperation) or 
   on an ordered index (@ref NdbIndexScanOperation).
208

209 210 211 212 213
   Scan operation are characteriesed by the following:
   - They can only perform reads (shared, exclusive or dirty)
   - They can potentially work with multiple rows
   - They can be used to update or delete multiple rows
   - They can operate on several nodes in parallell
214

215
   After the operation is created using NdbTransaction::getNdbScanOperation()
unknown's avatar
unknown committed
216 217
   (or NdbTransaction::getNdbIndexScanOperation()), 
   it is defined in the following three steps:
218
   -# Define the standard operation type, using NdbScanOperation::readTuples()
unknown's avatar
unknown committed
219 220
   -# Specify search conditions, using @ref NdbScanFilter and/or 
      @ref NdbIndexScanOperation::setBound()
221 222
   -# Specify attribute actions, using NdbOperation::getValue()
   -# Executing the transaction, using NdbTransaction::execute()
unknown's avatar
unknown committed
223
   -# Iterating through the result set using NdbScanOperation::nextResult()
224

unknown's avatar
unknown committed
225 226
   Here are two brief examples illustrating this process. For the sake of 
   brevity, we omit error-handling.
227
   
228
   This first example uses an NdbScanOperation:
229 230 231 232 233 234
   @code
     // 1. Create
     MyOperation= MyTransaction->getNdbScanOperation("MYTABLENAME");
    
     // 2. Define type of operation and lock mode
     MyOperation->readTuples(NdbOperation::LM_Read);
235

236 237 238 239 240 241
     // 3. Specify Search Conditions
     NdbScanFilter sf(MyOperation);
     sf.begin(NdbScanFilter::OR);
     sf.eq(0, i);   // Return rows with column 0 equal to i or
     sf.eq(1, i+1); // column 1 equal to (i+1)
     sf.end();
242

243 244 245
     // 4. Attribute Actions
     MyRecAttr= MyOperation->getValue("ATTR2", NULL);
   @endcode
246

247
   The second example uses an NdbIndexScanOperation:
248 249 250
   @code
     // 1. Create
     MyOperation= MyTransaction->getNdbIndexScanOperation("MYORDEREDINDEX", "MYTABLENAME");
251

252 253
     // 2. Define type of operation and lock mode
     MyOperation->readTuples(NdbOperation::LM_Read);
254

255 256 257 258
     // 3. Specify Search Conditions
     // All rows with ATTR1 between i and (i+1)
     MyOperation->setBound("ATTR1", NdbIndexScanOperation::BoundGE, i);
     MyOperation->setBound("ATTR1", NdbIndexScanOperation::BoundLE, i+1);    
259

260 261 262
     // 4. Attribute Actions 
     MyRecAttr = MyOperation->getValue("ATTR2", NULL);
   @endcode
263

264
   <h4>Step 1: Define scan operation operation type</h4>
unknown's avatar
unknown committed
265 266 267
   Scan operations only support 1 operation, 
   @ref NdbScanOperation::readTuples() 
   or @ref NdbIndexScanOperation::readTuples()
268

unknown's avatar
unknown committed
269 270 271 272
   @note If you want to define multiple scan operations within the same 
         transaction, then you need to call 
	 NdbTransaction::getNdbScanOperation() or 
	 NdbTransaction::getNdbIndexScanOperation() for each operation.
273

274 275 276 277
   <h4>Step 2: Specify Search Conditions</h4>
   The search condition is used to select tuples.
   If no search condition is specified, the scan will return all rows
   in the table.
278

279 280 281 282
   Search condition can be @ref NdbScanFilter which can be used on both
   @ref NdbScanOperation and @ref NdbIndexScanOperation or bounds which
   can only be used on index scans, @ref NdbIndexScanOperation::setBound.
   An index scan can have both NdbScanFilter and bounds
283

284 285
   @note When NdbScanFilter is used each row is examined but maybe not 
   returned. But when using bounds, only rows within bounds will be examined.
286

287
   <h4>Step 3: Specify Attribute Actions</h4>
288

289 290 291 292 293
   Now it is time to define which attributes should be read.
   Normally the attribute is defined by its name but it is
   also possible to use the attribute identity to define the
   attribute.

unknown's avatar
unknown committed
294
   NdbOperation::getValue() returns an NdbRecAttr object
295 296 297 298
   containing the read value.
   To get the value, there is actually two methods.
   The application can either
   - use its own memory (passed through a pointer aValue) to
unknown's avatar
unknown committed
299
     NdbOperation::getValue(), or
300 301 302
   - receive the attribute value in an NdbRecAttr object allocated
     by the NDB API.

unknown's avatar
unknown committed
303 304 305
   The NdbRecAttr object is released when Ndb::closeTransaction()
   is called. Thus, the application can not reference this object after
   Ndb::closeTransaction() have been called.
306
   The result of reading data from an NdbRecAttr object before
unknown's avatar
unknown committed
307
   calling NdbTransaction::execute() is undefined.
308 309 310 311 312 313

   <h3> Using Scan to update/delete </h3>
   Scanning can also be used to update/delete rows.
   This is performed by
   -# Scan using exclusive locks, NdbOperation::LM_Exclusive
   -# When iterating through the result set, for each row optionally call 
unknown's avatar
unknown committed
314 315 316 317 318 319
      either NdbScanOperation::updateCurrentTuple() or 
      NdbScanOperation::deleteCurrentTuple()
   -# If performing NdbScanOperation::updateCurrentTuple(), 
      set new values on record using ordinary @ref NdbOperation::setValue().
      NdbOperation::equal() should <em>not</em> be called as the primary 
      key is retreived from the scan.
320 321 322 323 324 325 326 327

   @note that the actual update/delete will not be performed until next 
   NdbTransaction::execute (as with single row operations), 
   NdbTransaction::execute needs to be called before locks are released,
     see @ref secScanLocks

   <h4> Index scans specific features </h4> 
   The following features are available when performing an index scan
unknown's avatar
unknown committed
328 329 330
   - Scan subset of table using @ref NdbIndexScanOperation::setBound()
   - Ordering result set ascending or descending, 
     @ref NdbIndexScanOperation::readTuples()
331 332
   - When using NdbIndexScanOperation::BoundEQ on partition key 
     only fragments containing rows will be scanned.
333
   
334
   Rows are returned unordered unless sorted is set to true.
unknown's avatar
unknown committed
335

336 337
   @note When performing sorted scan, parameter parallelism to 
   NdbIndexScanOperation::readTuples() will
338
   be ignored and max parallelism will be used instead. 
unknown's avatar
unknown committed
339

340
   @subsection secScanLocks Lock handling with scans
341

342 343 344 345 346
   When scanning a table or an index potentially 
   a lot of records will be returned.

   But Ndb will only lock a batch of rows per fragment at a time.
   How many rows will be locked per fragment is controlled by the 
347
   batch parameter to NdbScanOperation::readTuples().
348 349

   To let the application handle how locks are released 
350
   NdbScanOperation::nextResult() have a parameter fetch_allow.
unknown's avatar
unknown committed
351
   If NdbScanOperation::nextResult() is called with fetch_allow = false, no
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
   locks may be released as result of the function call. Otherwise the locks
   for the current batch may be released.

   This example shows scan delete, handling locks in an efficient manner.
   For the sake of brevity, we omit error-handling.
   @code
     int check;

     // Outer loop for each batch of rows
     while((check = MyScanOperation->nextResult(true)) == 0)
     {
       do
       {
         // Inner loop for each row within batch
         MyScanOperation->deleteCurrentTuple();
       } while((check = MyScanOperation->nextResult(false) == 0));

       // When no more rows in batch, exeute all defined deletes       
       MyTransaction->execute(NoCommit);
     }
   @endcode

   See @ref ndbapi_scan.cpp for full example of scan.
375 376 377 378 379 380 381 382 383

   @section secError                    Error Handling

   Errors can occur when
   -# operations are being defined, or when the
   -# transaction is being executed.

   One recommended way to handle a transaction failure 
   (i.e. an error is reported) is to:
384
   -# Rollback transaction (NdbTransaction::execute() with a special parameter)
385 386 387
   -# Close transaction
   -# Restart transaction (if the error was temporary)

388 389
   @note Transactions are not automatically closed when an error occur. Call
   Ndb::closeTransaction() to close.
390 391 392 393 394 395 396

   Several errors can occur when a transaction holds multiple 
   operations which are simultaneously executed.
   In this case the application has to go through the operation
   objects and query for their NdbError objects to find out what really
   happened.

397
   NdbTransaction::getNdbErrorOperation() returns a reference to the 
398
   operation causing the latest error.
399
   NdbTransaction::getNdbErrorLine() delivers the method number of the 
400 401 402
   erroneous method in the operation.

   @code
403 404
     theTransaction = theNdb->startTransaction();
     theOperation = theTransaction->getNdbOperation("TEST_TABLE");
405
     if (theOperation == NULL) goto error;
406
     theOperation->readTuple(NdbOperation::LM_Read);
407 408 409 410 411
     theOperation->setValue("ATTR_1", at1);
     theOperation->setValue("ATTR_2", at1); //Here an error occurs
     theOperation->setValue("ATTR_3", at1);
     theOperation->setValue("ATTR_4", at1);
    
412 413 414
     if (theTransaction->execute(Commit) == -1) {
       errorLine = theTransaction->getNdbErrorLine();
       errorOperation = theTransaction->getNdbErrorOperation();
415 416 417 418 419 420 421
   @endcode

   Here errorLine will be 3 as the error occurred in the third method 
   on the operation object.
   Getting errorLine == 0 means that the error occurred when executing the 
   operations.
   Here errorOperation will be a pointer to the theOperation object.
422
   NdbTransaction::getNdbError() will return the NdbError object 
423 424 425
   including holding information about the error.

   Since errors could have occurred even when a commit was reported,
426
   there is also a special method, NdbTransaction::commitStatus(),
427 428
   to check the commit status of the transaction.

429
******************************************************************************/
430 431

/**
unknown's avatar
unknown committed
432 433
 * @page ndbapi_simple.cpp ndbapi_simple.cpp
 * @include ndbapi_simple.cpp 
434 435
 */

unknown's avatar
unknown committed
436
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
437
/**
unknown's avatar
unknown committed
438 439
 * @page ndbapi_async1.cpp ndbapi_async1.cpp
 * @include ndbapi_async1.cpp 
440
 */
unknown's avatar
unknown committed
441
#endif
442 443

/**
unknown's avatar
unknown committed
444 445
 * @page ndbapi_retries.cpp ndbapi_retries.cpp
 * @include ndbapi_retries.cpp 
446 447 448
 */

/**
unknown's avatar
unknown committed
449 450
 * @page ndbapi_simple_index.cpp ndbapi_simple_index.cpp
 * @include ndbapi_simple_index.cpp 
451 452 453 454 455 456 457 458 459 460 461 462
 */

/**
 * @page ndbapi_scan.cpp ndbapi_scan.cpp
 * @include ndbapi_scan.cpp
 */


/**
   @page secAdapt  Adaptive Send Algorithm

   At the time of "sending" the transaction 
463
   (using NdbTransaction::execute()), the transactions 
464 465 466 467 468 469
   are in reality <em>not</em> immediately transfered to the NDB Kernel.  
   Instead, the "sent" transactions are only kept in a 
   special send list (buffer) in the Ndb object to which they belong.
   The adaptive send algorithm decides when transactions should
   be transfered to the NDB kernel.
  
470
   The NDB API is designed as a multi-threaded interface and
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
   it is desirable to transfer database operations from more than 
   one thread at a time. 
   The NDB API keeps track of which Ndb objects are active in transfering
   information to the NDB kernel and the expected amount of threads to 
   interact with the NDB kernel.
   Note that an Ndb object should be used in at most one thread. 
   Two different threads should <em>not</em> use the same Ndb object.
  
   There are four reasons leading to transfering of database 
   operations:
   -# The NDB Transporter (TCP/IP, OSE, SCI or shared memory)
      decides that a buffer is full and sends it off. 
      The buffer size is implementation dependent and
      might change between NDB Cluster releases.
      On TCP/IP the buffer size is usually around 64 kByte and 
      on OSE/Delta it is usually less than 2000 bytes. 
      In each Ndb object there is one buffer per DB node, 
      so this criteria of a full buffer is only 
      local to the connection to one DB node.
   -# Statistical information on the transfered information
      may force sending of buffers to all DB nodes.
   -# Every 10 ms a special send-thread checks whether 
      any send activity has occurred.  If not, then the thread will 
      force sending to all nodes. 
      This means that 20 ms is the maximum time database operations 
      are waiting before being sent off. The 10 millisecond limit 
      is likely to become a configuration parameter in
      later releases of NDB Cluster.
      However, to support faster than 10 ms checks, 
      there has to be support from the operating system.
501 502 503
   -# When methods that are affected by the adaptive send alorithm,
      e.g. NdbTransaction::execute(), there is a force parameter 
      that overrides it forces the send to all nodes.
504

505
   @note The reasons mentioned above are examples.  These might 
506 507 508
         change in later releases of NDB Cluster.
*/

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**

   For each of these "sent" transactions, there are three 
   possible states:
   -# Waiting to be transferred to NDB Kernel.
   -# Has been transferred to the NDB Kernel and is currently 
      being processed.
   -# Has been transferred to the NDB Kernel and has 
      finished processing.
      Now it is waiting for a call to a poll method.  
      (When the poll method is invoked, 
      then the transaction callback method will be executed.)
      
   The poll method invoked (either Ndb::pollNdb() or Ndb::sendPollNdb())
   will return when:
   -# at least 'minNoOfEventsToWakeup' of the transactions
      in the send list have transitioned to state 3 as described above, and 
   -# all of these transactions have executed their callback methods.
*/
#endif

531 532 533
/**
   @page secConcepts  NDB Cluster Concepts

unknown's avatar
unknown committed
534
   The <em>NDB Kernel</em> is the collection of storage nodes
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
   belonging to an NDB Cluster.
   The application programmer can for most purposes view the
   set of all DB nodes as one entity.
   Each DB node has three main components:
   - TC : The transaction coordinator
   - ACC : The index storage
   - TUP : The data storage

   When the application program executes a transaction,
   it connects to one TC on one DB node.  
   Usually, the programmer does not need to specify which TC to use, 
   but some cases when performance is important,
   transactions can be hinted to use a certain TC.  
   (If the node with the TC is down, then another TC will 
   automatically take over the work.)

   Every DB node has an ACC and a TUP which stores 
   the index and the data part of the database.
   Even though one TC is responsible for the transaction,
   several ACCs and TUPs on other DB nodes might be involved in the 
   execution of the transaction.


   @section secNdbKernelConnection   Selecting Transaction Coordinator 
559 560 561 562 563 564 565 566 567

   The default method is to select the transaction coordinator (TC) as being
   the "closest" DB node.  There is a heuristics for closeness based on
   the type of transporter connection. In order of closest first, we have
   SCI, SHM, TCP/IP (localhost), and TCP/IP (remote host). If there are several
   connections available with the same "closeness", they will each be 
   selected in a round robin fashion for every transaction. Optionally
   one may set the methos for  TC selection round robin over all available
   connections, where each new set of transactions
568 569 570 571
   is placed on the next DB node.
   
   The application programmer can however hint the NDB API which 
   transaction coordinator to use
572 573
   by providing a <em>partition key</em> (usually the primary key).
   By using the primary key as partition key, 
574 575 576 577 578
   the transaction will be placed on the node where the primary replica
   of that record resides.
   Note that this is only a hint, the system can be 
   reconfigured and then the NDB API will choose a transaction
   coordinator without using the hint.
579 580 581 582
   For more information, see NdbDictionary::Column::getPartitionKey(),
   Ndb::startTransaction().  The application programmer can specify
   the partition key from SQL by using the construct, 
   "CREATE TABLE ... ENGINE=NDB PARTITION BY KEY (<attribute list>)".
583 584 585 586 587 588 589 590 591


   @section secRecordStruct          Record Structure 
   NDB Cluster is a relational database with tables of records.
   Table rows represent tuples of relational data stored as records.
   When created, the attribute schema of the table is specified,
   and thus each record of the table has the same schema.
   

592 593
   @subsection secKeys               Primary Keys
   Each record has from 1 up to 32 attributes which belong
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
   to the primary key of the table.
   
   @section secTrans                 Transactions

   Transactions are committed to main memory, 
   and are committed to disk after a global checkpoint, GCP.
   Since all data is (in most NDB Cluster configurations) 
   synchronously replicated and stored on multiple NDB nodes,
   the system can still handle processor failures without loss 
   of data.
   However, in the case of a system failure (e.g. the whole system goes down), 
   then all (committed or not) transactions after the latest GCP are lost.


   @subsection secConcur                Concurrency Control
   NDB Cluster uses pessimistic concurrency control based on locking.
   If a requested lock (implicit and depending on database operation)
   cannot be attained within a specified time, 
   then a timeout error occurs.

   Concurrent transactions (parallel application programs, thread-based 
unknown's avatar
unknown committed
615
   applications)
616 617 618 619 620
   sometimes deadlock when they try to access the same information.
   Applications need to be programmed so that timeout errors
   occurring due to deadlocks are handled.  This generally
   means that the transaction encountering timeout
   should be rolled back and restarted.
unknown's avatar
unknown committed
621 622


623
   @section secHint                 Hints and performance
unknown's avatar
unknown committed
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650

   Placing the transaction coordinator close
   to the actual data used in the transaction can in many cases
   improve performance significantly. This is particularly true for
   systems using TCP/IP. A system using Solaris and a 500 MHz processor
   has a cost model for TCP/IP communication which is:

     30 microseconds + (100 nanoseconds * no of Bytes)

   This means that if we can ensure that we use "popular" links we increase
   buffering and thus drastically reduce the communication cost.
   Systems using SCI has a different cost model which is:

     5 microseconds + (10 nanoseconds *  no of Bytes)

   Thus SCI systems are much less dependent on selection of 
   transaction coordinators. 
   Typically TCP/IP systems spend 30-60% of the time during communication,
   whereas SCI systems typically spend 5-10% of the time during
   communication. 
   Thus SCI means that less care from the NDB API programmer is
   needed and great scalability can be achieved even for applications using
   data from many parts of the database.

   A simple example is an application that uses many simple updates where
   a transaction needs to update one record. 
   This record has a 32 bit primary key, 
651
   which is also the partition key. 
unknown's avatar
unknown committed
652 653
   Then the keyData will be the address of the integer 
   of the primary key and keyLen will be 4.
654 655
*/

656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   (A transaction's execution can also be divided into three 
   steps: prepare, send, and poll. This allows us to perform asynchronous
   transactions.  More about this later.)
*/
#endif
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   Another way to execute several parallel transactions is to use
   asynchronous transactions.
*/
#endif  
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   Operations are of two different kinds:
   -# standard operations, and
   -# interpreted program operations.
*/
#endif
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   <h3>Interpreted Program Operations</h3>
   The following types of interpreted program operations exist:
    -# NdbOperation::interpretedUpdateTuple :
       updates a tuple using an interpreted program
    -# NdbOperation::interpretedDeleteTuple :
       delete a tuple using an interpreted program

   The operations interpretedUpdateTuple and interpretedDeleteTuple both
   work using the unique tuple key.

   These <em>interpreted programs</em> 
   make it possible to perform computations
   inside the NDB Cluster Kernel instead of in the application
   program.
   This is sometimes very effective, since no intermediate results
   are sent to the application, only the final result.


  <h3>Interpreted Update and Delete</h3>

   Operations for interpreted updates and deletes must follow a
   certain order when defining operations on a tuple.
   As for read and write operations,
   one must first define the operation type and then the search key.
   -# The first step is to define the initial readings.
      In this phase it is only allowed to use the
      NdbOperation::getValue method.
      This part might be empty.
   -# The second step is to define the interpreted part.
      The methods supported are the methods listed below except
      NdbOperation::def_subroutine and NdbOperation::ret_sub
      which can only be used in a subroutine.
      NdbOperation::incValue and NdbOperation::subValue
      increment and decrement attributes
      (currently only unsigned integers supported).
      This part can also be empty since interpreted updates
      can be used for reading and updating the same tuple.
      <p>
      Even though getValue and setValue are not really interpreted
      program instructions, it is still allowed to use them as
      the last instruction of the program.
      (If a getValue or setValue is found when an interpret_exit_ok
      could have been issued then the interpreted_exit_ok
      will be inserted.
      A interpret_exit_ok should be viewed as a jump to the first
      instruction after the interpreted instructions.)
   -# The third step is to define all updates without any
      interpreted program instructions.
      Here a set of NdbOperation::setValue methods are called.
      There might be zero such calls.
   -# The fourth step is the final readings.
      The initial readings reads the initial value of attributes
      and the final readings reads them after their updates.
      There might be zero NdbOperation::getValue calls.
   -# The fifth step is possible subroutine definitions using
      NdbOperation::def_subroutine and NdbOperation::ret_sub.
*/
#endif
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   <h3>Interpreted Programs</h3>
   Interpretation programs are executed in a
   register-based virtual machine.
   The virtual machine has eight 64 bit registers numbered 0-7.
   Each register contains type information which is used both
   for type conversion and for type checking.

   @note Arrays are currently <b>not</b> supported in the virtual machine.
         Currently only unsigned integers are supported and of size
         maximum 64 bits.

   All errors in the interpretation program will cause a
   transaction abort, but will not affect any other transactions.

   The following are legal interpreted program instructions:
   -# incValue        : Add to an attribute
   -# subValue        : Subtract from an attribute
   -# def_label       : Define a label in the interpreted program
   -# add_reg         : Add two registers
   -# sub_reg         : Subtract one register from another
   -# load_const_u32  : Load an unsigned 32 bit value into a register
   -# load_const_u64  : Load an unsigned 64 bit value into a register
   -# load_const_null : Load a NULL value into a register
   -# read_attr       : Read attribute value into a register
   -# write_attr      : Write a register value into an attribute
   -# branch_ge       : Compares registers and possibly jumps to specified label
   -# branch_gt       : Compares registers and possibly jumps to specified label
   -# branch_le       : Compares registers and possibly jumps to specified label
   -# branch_lt       : Compares registers and possibly jumps to specified label
   -# branch_eq       : Compares registers and possibly jumps to specified label
   -# branch_ne       : Compares registers and possibly jumps to specified label
   -# branch_ne_null  : Jumps if register does not contain NULL value
   -# branch_eq_null  : Jumps if register contains NULL value
   -# branch_label    : Unconditional jump to label
   -# interpret_exit_ok  : Exit interpreted program
                           (approving tuple if used in scan)
   -# interpret_exit_nok : Exit interpreted program
                           (disqualifying tuple if used in scan)

   There are also three instructions for subroutines, which
   are described in the next section.

   @subsection subsubSub                Interpreted Programs: Subroutines

   The following are legal interpreted program instructions for
   subroutines:
   -# NdbOperation::def_subroutine : 
      Defines start of subroutine in interpreted program code
   -# NdbOperation::call_sub : 
      Calls a subroutine
   -# NdbOperation::ret_sub : 
      Return from subroutine

   The virtual machine executes subroutines using a stack for
   its operation.
   The stack allows for up to 24 subroutine calls in succession.
   Deeper subroutine nesting will cause an abort of the transaction.

   All subroutines starts with the instruction
   NdbOperation::def_subroutine and ends with the instruction
   NdbOperation::ret_sub.
   If it is necessary to return earlier in the subroutine
   it has to be done using a branch_label instruction
   to a label defined right before the 
   NdbOperation::ret_sub instruction.

   @note The subroutines are automatically numbered starting with 0.
         The parameter used by NdbOperation::def_subroutine 
	 should match the automatic numbering to make it easier to 
	 debug the interpreted program.
*/
#endif

#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
   @section secAsync                    Asynchronous Transactions
   The asynchronous interface is used to increase the speed of
   transaction executing by better utilizing the connection
   between the application and the NDB Kernel.
   The interface is used to send many transactions 
   at the same time to the NDB kernel.  
   This is often much more efficient than using synchronous transactions.
   The main reason for using this method is to ensure that 
   Sending many transactions at the same time ensures that bigger 
   chunks of data are sent when actually sending and thus decreasing 
   the operating system overhead.

   The synchronous call to NdbTransaction::execute 
   normally performs three main steps:<br>
   -# <b>Prepare</b> 
      Check transaction status
      - if problems, abort the transaction
      - if ok, proceed
   -# <b>Send</b> 
      Send the defined operations since last execute
      or since start of transaction.
   -# <b>Poll</b>
      Wait for response from NDB kernel.

   The asynchronous method NdbTransaction::executeAsynchPrepare 
   only perform step 1.
   (The abort part in step 1 is only prepared for.  The actual 
   aborting of the transaction is performed in a later step.)

   Asynchronous transactions are defined and executed 
   in the following way.
   -# Start (create) transactions (same way as for the 
       synchronous transactions)
   -# Add and define operations (also as in the synchronous case)
   -# <b>Prepare</b> transactions 
       (using NdbTransaction::executeAsynchPrepare or 
       NdbTransaction::executeAsynch)
   -# <b>Send</b> transactions to NDB Kernel
       (using Ndb::sendPreparedTransactions, 
       NdbTransaction::executeAsynch, or Ndb::sendPollNdb)
   -# <b>Poll</b> NDB kernel to find completed transactions 
       (using Ndb::pollNdb or Ndb::sendPollNdb)
   -# Close transactions (same way as for the synchronous transactions)

   See example program in section @ref ndbapi_example2.cpp.
   
   This prepare-send-poll protocol actually exists in four variants:
   - (Prepare-Send-Poll).  This is the one-step variant provided
     by synchronous transactions.
   - (Prepare-Send)-Poll.  This is the two-step variant using
     NdbTransaction::executeAsynch and Ndb::pollNdb.
   - Prepare-(Send-Poll).  This is the two-step variant using
     NdbTransaction::executeAsynchPrepare and Ndb::sendPollNdb.
   - Prepare-Send-Poll.  This is the three-step variant using
     NdbTransaction::executeAsynchPrepare, Ndb::sendPreparedTransactions, and
     Ndb::pollNdb.
  
   Transactions first has to be prepared by using method
   NdbTransaction::executeAsynchPrepare or NdbTransaction::executeAsynch.
   The difference between these is that 
   NdbTransaction::executeAsynch also sends the transaction to 
   the NDB kernel.
   One of the arguments to these methods is a callback method.
   The callback method is executed during polling (item 5 above).
  
   Note that NdbTransaction::executeAsynchPrepare does not 
   send the transaction to the NDB kernel.  When using 
   NdbTransaction::executeAsynchPrepare, you either have to call 
   Ndb::sendPreparedTransactions or Ndb::sendPollNdb to send the 
   database operations.
   (Ndb::sendPollNdb also polls Ndb for completed transactions.)
  
   The methods Ndb::pollNdb and Ndb::sendPollNdb checks if any 
   sent transactions are completed.  The method Ndb::sendPollNdb 
   also send all prepared transactions before polling NDB.
   Transactions still in the definition phase (i.e. items 1-3 above, 
   transactions which has not yet been sent to the NDB kernel) are not 
   affected by poll-calls.
   The poll method invoked (either Ndb::pollNdb or Ndb::sendPollNdb)
   will return when:
    -# at least 'minNoOfEventsToWakeup' of the transactions
       are finished processing, and
    -# all of these transactions have executed their 
       callback methods.
  
   The poll method returns the number of transactions that 
   have finished processing and executed their callback methods.

   @note When an asynchronous transaction has been started and sent to
         the NDB kernel, it is not allowed to execute any methods on
         objects belonging to this transaction until the transaction
         callback method have been executed.
         (The transaction is stated and sent by either
	 NdbTransaction::executeAsynch or through the combination of
         NdbTransaction::executeAsynchPrepare and either
         Ndb::sendPreparedTransactions or Ndb::sendPollNdb).

   More about how transactions are sent the NDB Kernel is 
   available in section @ref secAdapt.
*/
#endif


/**
   
   Put this back when real array ops are supported
   i.e. get/setValue("kalle[3]");

   @subsection secArrays             Array Attributes
   A table attribute in NDB Cluster can be of <em>array type</em>.
   This means that the attribute consists of an array of 
   <em>elements</em>.  The <em>attribute size</em> is the size
   of one element of the array (expressed in bits) and the 
   <em>array size</em> is the number of elements of the array.

*/

930 931 932 933 934
#ifndef Ndb_H
#define Ndb_H

#include <ndb_types.h>
#include <ndbapi_limits.h>
935
#include <ndb_cluster_connection.hpp>
936
#include <NdbError.hpp>
937
#include <NdbDictionary.hpp>
938 939 940 941 942

class NdbObjectIdMap;
class NdbOperation;
class NdbEventOperationImpl;
class NdbScanOperation;
unknown's avatar
unknown committed
943
class NdbIndexScanOperation;
944
class NdbIndexOperation;
945
class NdbTransaction;
946 947 948 949 950 951 952 953 954
class NdbApiSignal;
class NdbRecAttr;
class NdbLabel;
class NdbBranch;
class NdbSubroutine;
class NdbCall;
class Table;
class BaseString;
class NdbEventOperation;
unknown's avatar
unknown committed
955
class NdbBlob;
unknown's avatar
unknown committed
956
class NdbReceiver;
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002

typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);


#if defined NDB_OSE
/**
 * Default time to wait for response after request has been sent to 
 * NDB Cluster (Set to 10 seconds usually, but to 100 s in 
 * the OSE operating system)
 */
#define WAITFOR_RESPONSE_TIMEOUT 100000 // Milliseconds
#else
#define WAITFOR_RESPONSE_TIMEOUT 120000 // Milliseconds
#endif

#define NDB_MAX_INTERNAL_TABLE_LENGTH NDB_MAX_DATABASE_NAME_SIZE + \
                                      NDB_MAX_SCHEMA_NAME_SIZE + \
                                      NDB_MAX_TAB_NAME_SIZE*2

/**
 * @class Ndb 
 * @brief Represents the NDB kernel and is the main class of the NDB API.
 *
 * Always start your application program by creating an Ndb object. 
 * By using several Ndb objects it is possible to design 
 * a multi-threaded application, but note that Ndb objects 
 * cannot be shared by several threads. 
 * Different threads should use different Ndb objects. 
 * A thread might however use multiple Ndb objects.
 * Currently there is a limit of maximum 128 Ndb objects 
 * per application process.
 *
 * @note It is not allowed to call methods in the NDB API 
 *       on the same Ndb object in different threads 
 *       simultaneously (without special handling of the 
 *       Ndb object).
 *
 * @note The Ndb object is multi-thread safe in the following manner. 
 *       Each Ndb object can ONLY be handled in one thread. 
 *       If an Ndb object is handed over to another thread then the 
 *       application must ensure that a memory barrier is used to 
 *       ensure that the new thread see all updates performed by 
 *       the previous thread. 
 *       Semaphores, mutexes and so forth are easy ways of issuing memory 
 *       barriers without having to bother about the memory barrier concept.
 *
unknown's avatar
unknown committed
1003 1004 1005 1006 1007
 */

#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
// to be documented later
/*
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
 * If one Ndb object is used to handle parallel transactions through the 
 * asynchronous programming interface, please read the notes regarding
 * asynchronous transactions (Section @ref secAsync).
 * The asynchronous interface provides much higher performance 
 * in some situations, but is more complicated for the application designer. 
 *
 * @note Each Ndb object should either use the methods for 
 *       asynchronous transaction or the methods for 
 *       synchronous transactions but not both.
 */
unknown's avatar
unknown committed
1018 1019
#endif

1020 1021
class Ndb
{
1022
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1023 1024 1025
  friend class NdbReceiver;
  friend class NdbOperation;
  friend class NdbEventOperationImpl;
1026
  friend class NdbTransaction;
1027 1028 1029
  friend class Table;
  friend class NdbApiSignal;
  friend class NdbIndexOperation;
unknown's avatar
unknown committed
1030 1031
  friend class NdbScanOperation;
  friend class NdbIndexScanOperation;
1032 1033
  friend class NdbDictionaryImpl;
  friend class NdbDictInterface;
unknown's avatar
unknown committed
1034
  friend class NdbBlob;
1035
#endif
1036 1037 1038 1039 1040 1041 1042

public:
  /** 
   * @name General 
   * @{
   */
  /**
unknown's avatar
unknown committed
1043 1044 1045
   * The Ndb object represents a connection to a database.
   *
   * @note the init() method must be called before it may be used
1046
   *
unknown's avatar
unknown committed
1047 1048
   * @param ndb_cluster_connection is a connection to a cluster containing
   *        the database to be used
1049 1050 1051 1052
   * @param aCatalogName is the name of the catalog you want to use.
   * @note The catalog name provides a name space for the tables and
   *       indexes created in any connection from the Ndb object.
   * @param aSchemaName is the name of the schema you 
unknown's avatar
unknown committed
1053
   *        want to use.
1054 1055 1056
   * @note The schema name provides an additional name space 
   *       for the tables and indexes created in a given catalog.
   */
1057 1058
  Ndb(Ndb_cluster_connection *ndb_cluster_connection,
      const char* aCatalogName = "", const char* aSchemaName = "def");
1059 1060 1061

  ~Ndb();

unknown's avatar
unknown committed
1062
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
  /**
   * The current catalog name can be fetched by getCatalogName.
   *
   * @return the current catalog name
   */
  const char * getCatalogName() const;

  /**
   * The current catalog name can be set by setCatalogName.
   *
   * @param aCatalogName is the new name of the current catalog
   */
  void setCatalogName(const char * aCatalogName);

  /**
   * The current schema name can be fetched by getSchemaName.
   *
   * @return the current schema name
   */
  const char * getSchemaName() const;

  /**
   * The current schema name can be set by setSchemaName.
   *
   * @param aSchemaName is the new name of the current schema
   */
  void setSchemaName(const char * aSchemaName);
unknown's avatar
unknown committed
1090
#endif
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120

  /**
   * The current database name can be fetched by getDatabaseName.
   *
   * @return the current database name
   */
  const char * getDatabaseName() const;

  /**
   * The current database name can be set by setDatabaseName.
   *
   * @param aDatabaseName is the new name of the current database
   */
  void setDatabaseName(const char * aDatabaseName);

  /**
   * The current database schema name can be fetched by getDatabaseSchemaName.
   *
   * @return the current database schema name
   */
  const char * getDatabaseSchemaName() const;

  /**
   * The current database schema name can be set by setDatabaseSchemaName.
   *
   * @param aDatabaseSchemaName is the new name of the current database schema
   */
  void setDatabaseSchemaName(const char * aDatabaseSchemaName);

  /**
unknown's avatar
unknown committed
1121
   * Initializes the Ndb object
1122 1123 1124
   *
   * @param  maxNoOfTransactions 
   *         Maximum number of parallel 
1125
   *         NdbTransaction objects that can be handled by the Ndb object.
unknown's avatar
unknown committed
1126 1127 1128
   *         Maximum value is 1024.
   *
   * @note each scan or index scan operation uses one extra
1129
   *       NdbTransaction object
1130
   *
unknown's avatar
unknown committed
1131
   * @return 0 if successful, -1 otherwise.
1132 1133 1134
   */
  int init(int maxNoOfTransactions = 4);

1135
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
  /**
   * Wait for Ndb object to successfully set-up connections to 
   * the NDB kernel. 
   * Starting to use the Ndb object without using this method 
   * gives unspecified behavior. 
   * 
   * @param  timeout  The maximum time we will wait for 
   *                  the initiation process to finish.
   *                  Timeout is expressed in seconds.
   * @return  0: Ndb is ready and timeout has not occurred.<br>
   *          -1: Timeout has expired
   */
  int waitUntilReady(int timeout = 60);
unknown's avatar
unknown committed
1149
#endif
1150

1151 1152 1153 1154 1155 1156 1157 1158
  /** @} *********************************************************************/

  /** 
   * @name Meta Information
   * @{
   */

  /**
unknown's avatar
unknown committed
1159 1160 1161
   * Get an object for retrieving or manipulating database schema information 
   *
   * @note this object operates outside any transaction
1162 1163 1164 1165 1166 1167
   *
   * @return Object containing meta information about all tables 
   *         in NDB Cluster.
   */
  class NdbDictionary::Dictionary* getDictionary() const;
  
unknown's avatar
unknown committed
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181

  /** @} *********************************************************************/

  /** 
   * @name Event subscriptions
   * @{
   */

  /**
   * Create a subcription to an event defined in the database
   *
   * @param eventName
   *        unique identifier of the event
   * @param bufferLength
unknown's avatar
unknown committed
1182
   *        circular buffer size for storing event data
unknown's avatar
unknown committed
1183 1184 1185
   *
   * @return Object representing an event, NULL on failure
   */
1186 1187
  NdbEventOperation* createEventOperation(const char* eventName,
					  const int bufferLength);
unknown's avatar
unknown committed
1188 1189 1190 1191 1192 1193 1194 1195 1196
  /**
   * Drop a subscription to an event
   *
   * @param eventName
   *        unique identifier of the event
   *
   * @return 0 on success
   */
  int dropEventOperation(NdbEventOperation* eventName);
1197 1198

  /**
unknown's avatar
unknown committed
1199 1200
   * Wait for an event to occur. Will return as soon as an event
   * is detected on any of the created events.
1201
   *
unknown's avatar
unknown committed
1202 1203
   * @param aMillisecondNumber
   *        maximum time to wait
1204
   *
unknown's avatar
unknown committed
1205
   * @return the number of events that has occured, -1 on failure
1206
   */
unknown's avatar
unknown committed
1207
  int pollEvents(int aMillisecondNumber);
1208 1209 1210 1211 1212 1213 1214 1215 1216

  /** @} *********************************************************************/

  /** 
   * @name Starting and Closing Transactions
   * @{
   */

  /**
unknown's avatar
unknown committed
1217
   * Start a transaction
1218
   *
unknown's avatar
unknown committed
1219
   * @note When the transaction is completed it must be closed using
1220
   *       Ndb::closeTransaction or NdbTransaction::close. 
unknown's avatar
unknown committed
1221 1222
   *       The transaction must be closed independent of its outcome, i.e.
   *       even if there is an error.
1223
   *
unknown's avatar
unknown committed
1224 1225 1226 1227
   * @param  prio     Not implemented
   * @param  keyData  Pointer to partition key to be used for deciding
   *                  which node to run the Transaction Coordinator on
   * @param  keyLen   Length of partition key expressed in bytes
1228
   * 
1229
   * @return NdbTransaction object, or NULL on failure.
1230
   */
1231
  NdbTransaction* startTransaction(Uint32        prio = 0, 
1232 1233 1234 1235
				  const char *  keyData = 0, 
				  Uint32        keyLen = 0);

  /**
unknown's avatar
unknown committed
1236 1237 1238 1239
   * Close a transaction.
   *
   * @note should be called after the transaction has completed, irrespective
   *       of success or failure
1240
   */
1241
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1242
  /**
1243 1244 1245 1246 1247 1248 1249 1250 1251
   * @note It is not allowed to call Ndb::closeTransaction after sending the
   *       transaction asynchronously with either 
   *       Ndb::sendPreparedTransactions or
   *       Ndb::sendPollNdb before the callback method has been called.
   *       (The application should keep track of the number of 
   *       outstanding transactions and wait until all of them 
   *       has completed before calling Ndb::closeTransaction).
   *       If the transaction is not committed it will be aborted.
   */
1252
#endif
1253
  void closeTransaction(NdbTransaction*);
1254 1255 1256

  /** @} *********************************************************************/

unknown's avatar
unknown committed
1257 1258
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
  // to be documented later
1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
  /** 
   * @name Asynchronous Transactions
   * @{
   */

  /**
   * Wait for prepared transactions.
   * Will return as soon as at least 'minNoOfEventsToWakeUp' 
   * of them have completed, or the maximum time given as timeout has passed.
   *
unknown's avatar
unknown committed
1269 1270 1271 1272
   * @param aMillisecondNumber 
   *        Maximum time to wait for transactions to complete. Polling 
   *        without wait is achieved by setting the timer to zero.
   *        Time is expressed in milliseconds.
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333
   * @param minNoOfEventsToWakeup Minimum number of transactions 
   *            which has to wake up before the poll-call will return.
   *            If minNoOfEventsToWakeup is
   *            set to a value larger than 1 then this is the minimum 
   *            number of transactions that need to complete before the 
   *            poll will return.
   *            Setting it to zero means that one should wait for all
   *            outstanding transactions to return before waking up.
   * @return Number of transactions polled.
   */
  int  pollNdb(int aMillisecondNumber = WAITFOR_RESPONSE_TIMEOUT,
	      int minNoOfEventsToWakeup = 1);

  /**
   * This send method will send all prepared database operations. 
   * The default method is to do it non-force and instead
   * use the adaptive algorithm.  (See Section @ref secAdapt.)
   * The second option is to force the sending and 
   * finally there is the third alternative which is 
   * also non-force but also making sure that the 
   * adaptive algorithm do not notice the send. 
   * In this case the sending will be performed on a 
   * cyclical 10 millisecond event.
   *
   * @param forceSend When operations should be sent to NDB Kernel.
   *                  (See @ref secAdapt.)
   *                  - 0: non-force, adaptive algorithm notices it (default); 
   *                  - 1: force send, adaptive algorithm notices it; 
   *                  - 2: non-force, adaptive algorithm do not notice the send.
   */
  void sendPreparedTransactions(int forceSend = 0);

  /**
   * This is a send-poll variant that first calls 
   * Ndb::sendPreparedTransactions and then Ndb::pollNdb. 
   * It is however somewhat faster than calling the methods 
   * separately, since some mutex-operations are avoided. 
   * See documentation of Ndb::pollNdb and Ndb::sendPreparedTransactions
   * for more details.
   *
   * @param aMillisecondNumber Timeout specifier
   *            Polling without wait is achieved by setting the 
   *            millisecond timer to zero.
   * @param minNoOfEventsToWakeup Minimum number of transactions 
   *            which has to wake up before the poll-call will return.
   *            If minNoOfEventsToWakeup is
   *            set to a value larger than 1 then this is the minimum 
   *            number of transactions that need to complete before the 
   *            poll-call will return.
   *            Setting it to zero means that one should wait for all
   *            outstanding transactions to return before waking up.
   * @param forceSend When operations should be sent to NDB Kernel.
   *                  (See @ref secAdapt.)
   * - 0: non-force, adaptive algorithm notices it (default); 
   * - 1: force send, adaptive algorithm notices it; 
   * - 2: non-force, adaptive algorithm does not notice the send.
   * @return Number of transactions polled.
   */
  int  sendPollNdb(int aMillisecondNumber = WAITFOR_RESPONSE_TIMEOUT,
		   int minNoOfEventsToWakeup = 1,
		   int forceSend = 0);
unknown's avatar
unknown committed
1334
#endif
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
  
  /** @} *********************************************************************/

  /** 
   * @name Error Handling
   * @{
   */

  /**
   * Get the NdbError object
   *
unknown's avatar
unknown committed
1346
   * @note The NdbError object is valid until a new NDB API method is called.
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
   */
  const NdbError & getNdbError() const;
  
  /**
   * Get a NdbError object for a specific error code
   *
   * The NdbError object is valid until you call a new NDB API method.
   */
  const NdbError & getNdbError(int errorCode);


unknown's avatar
unknown committed
1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
  /** @} *********************************************************************/

#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
  /**
   * Get the application node identity.  
   *
   * @return Node id of this application.
   */
  int getNodeId();

1368
  bool usingFullyQualifiedNames();
1369

1370 1371 1372 1373 1374
  /**
   * Different types of tampering with the NDB Cluster.
   * <b>Only for debugging purposes only.</b>
   */
  enum TamperType	{ 
unknown's avatar
unknown committed
1375 1376 1377 1378 1379 1380
    LockGlbChp = 1,           ///< Lock GCP
    UnlockGlbChp,             ///< Unlock GCP
    CrashNode,                ///< Crash an NDB node
    ReadRestartGCI,           ///< Request the restart GCI id from NDB Cluster
    InsertError               ///< Execute an error in NDB Cluster 
                              ///< (may crash system)
1381 1382
  };

1383 1384 1385 1386 1387 1388 1389
  /**
   * For testing purposes it is possible to tamper with the NDB Cluster
   * (i.e. send a special signal to DBDIH, the NDB distribution handler).
   * <b>This feature should only used for debugging purposes.</b>
   * In a release versions of NDB Cluster,
   * this call always return -1 and does nothing.
   * 
1390
   * @param aAction Action to be taken according to TamperType above
1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409
   *
   * @param aNode  Which node the action will be taken
   *              -1:   Master DIH.
   *            0-16:   Nodnumber.
   * @return -1 indicates error, other values have meaning dependent 
   *          on type of tampering.
   */
  int NdbTamper(TamperType aAction, int aNode);  

  /**
   * Return a unique tuple id for a table.  The id sequence is
   * ascending but may contain gaps.
   *
   * @param aTableName table name
   *
   * @param cacheSize number of values to cache in this Ndb object
   *
   * @return tuple id or 0 on error
   */
unknown's avatar
unknown committed
1410 1411
  Uint64 getAutoIncrementValue(const char* aTableName, 
			       Uint32 cacheSize = 1);
unknown's avatar
unknown committed
1412
  Uint64 getAutoIncrementValue(const NdbDictionary::Table * aTable, 
1413
			       Uint32 cacheSize = 1);
unknown's avatar
unknown committed
1414
  Uint64 readAutoIncrementValue(const char* aTableName);
unknown's avatar
unknown committed
1415
  Uint64 readAutoIncrementValue(const NdbDictionary::Table * aTable);
unknown's avatar
unknown committed
1416 1417
  bool setAutoIncrementValue(const char* aTableName, Uint64 val, 
			     bool increase = false);
unknown's avatar
unknown committed
1418
  bool setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, 
1419
			     bool increase = false);
unknown's avatar
unknown committed
1420 1421 1422 1423 1424 1425 1426 1427
  Uint64 getTupleIdFromNdb(const char* aTableName, 
			   Uint32 cacheSize = 1000);
  Uint64 getTupleIdFromNdb(Uint32 aTableId, 
			   Uint32 cacheSize = 1000);
  Uint64 readTupleIdFromNdb(Uint32 aTableId);
  bool setTupleIdInNdb(const char* aTableName, Uint64 val, 
		       bool increase);
  bool setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase);
1428 1429 1430 1431
  Uint64 opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op);

  /**
   */
1432
  NdbTransaction* hupp( NdbTransaction* );
1433 1434 1435 1436 1437 1438 1439 1440
  Uint32 getReference() const { return theMyRef;}
#endif

/*****************************************************************************
 *	These are service routines used by the other classes in the NDBAPI.
 ****************************************************************************/
private:
  
1441 1442 1443
  void setup(Ndb_cluster_connection *ndb_cluster_connection,
	     const char* aCatalogName, const char* aSchemaName);

unknown's avatar
unknown committed
1444 1445 1446
  void connected(Uint32 block_reference);
 

1447
  NdbTransaction*  startTransactionLocal(Uint32 aPrio, Uint32 aFragmentId); 
1448 1449 1450

// Connect the connection object to the Database.
  int NDB_connect(Uint32 tNode);
1451
  NdbTransaction* doConnect(Uint32 nodeId); 
1452 1453
  void    doDisconnect();	 
  
unknown's avatar
unknown committed
1454
  NdbReceiver*	        getNdbScanRec();// Get a NdbScanReceiver from idle list
1455 1456 1457 1458 1459 1460 1461 1462
  NdbLabel*		getNdbLabel();	// Get a NdbLabel from idle list
  NdbBranch*            getNdbBranch();	// Get a NdbBranch from idle list
  NdbSubroutine*	getNdbSubroutine();// Get a NdbSubroutine from idle
  NdbCall*		getNdbCall();	// Get a NdbCall from idle list
  NdbApiSignal*	        getSignal();	// Get an operation from idle list
  NdbRecAttr*	        getRecAttr();	// Get a receeive attribute object from
					// idle list of the Ndb object.
  NdbOperation* 	getOperation();	// Get an operation from idle list
unknown's avatar
unknown committed
1463
  NdbIndexScanOperation* getScanOperation(); // Get a scan operation from idle
1464 1465 1466
  NdbIndexOperation* 	getIndexOperation();// Get an index operation from idle

  class NdbGlobalEventBufferHandle* getGlobalEventBufferHandle();
unknown's avatar
unknown committed
1467
  NdbBlob*              getNdbBlob();// Get a blob handle etc
1468 1469 1470

  void			releaseSignal(NdbApiSignal* anApiSignal);
  void                  releaseSignalsInList(NdbApiSignal** pList);
unknown's avatar
unknown committed
1471
  void			releaseNdbScanRec(NdbReceiver* aNdbScanRec);
1472 1473 1474 1475 1476 1477
  void			releaseNdbLabel(NdbLabel* anNdbLabel);
  void			releaseNdbBranch(NdbBranch* anNdbBranch);
  void			releaseNdbSubroutine(NdbSubroutine* anNdbSubroutine);
  void			releaseNdbCall(NdbCall* anNdbCall);
  void			releaseRecAttr (NdbRecAttr* aRecAttr);	
  void		 	releaseOperation(NdbOperation* anOperation);	
unknown's avatar
unknown committed
1478
  void		 	releaseScanOperation(NdbIndexScanOperation*);
unknown's avatar
unknown committed
1479
  void                  releaseNdbBlob(NdbBlob* aBlob);
1480 1481 1482

  void                  check_send_timeout();
  void                  remove_sent_list(Uint32);
1483 1484
  Uint32                insert_completed_list(NdbTransaction*);
  Uint32                insert_sent_list(NdbTransaction*);
1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521

  // Handle a received signal. Used by both
  // synchronous and asynchronous interface
  void handleReceivedSignal(NdbApiSignal* anApiSignal, struct LinearSectionPtr ptr[3]);
  
  // Receive response signals
  int			receiveResponse(int waitTime = WAITFOR_RESPONSE_TIMEOUT);

  int			sendRecSignal(Uint16 aNodeId,
				      Uint32 aWaitState,
				      NdbApiSignal* aSignal,
                                      Uint32 nodeSequence);
  
  // Sets Restart GCI in Ndb object
  void			RestartGCI(int aRestartGCI);

  // Get block number of this NDBAPI object
  int			getBlockNumber();
  
  /****************************************************************************
   *	These are local service routines used by this class.	
   ***************************************************************************/
  
  int			createConIdleList(int aNrOfCon);
  int 		createOpIdleList( int nrOfOp );	

  void	freeOperation();          // Free the first idle operation.
  void	freeScanOperation();      // Free the first idle scan operation.
  void	freeIndexOperation();     // Free the first idle index operation.
  void	freeNdbCon();	// Free the first idle connection.
  void	freeSignal();	// Free the first idle signal	
  void	freeRecAttr();	// Free the first idle receive attr obj	
  void	freeNdbLabel();	// Free the first idle NdbLabel obj
  void	freeNdbBranch();// Free the first idle NdbBranch obj
  void	freeNdbSubroutine();// Free the first idle NdbSubroutine obj
  void	freeNdbCall();	    // Free the first idle NdbCall obj
  void	freeNdbScanRec();   // Free the first idle NdbScanRec obj
unknown's avatar
unknown committed
1522
  void  freeNdbBlob();      // Free the first etc
1523

1524
  NdbTransaction* getNdbCon();	// Get a connection from idle list
1525 1526
  
  /**
1527
   * Get a connected NdbTransaction to nodeId
1528 1529
   *   Returns NULL if none found
   */
1530
  NdbTransaction* getConnectedNdbTransaction(Uint32 nodeId);
1531 1532 1533

  // Release and disconnect from DBTC a connection
  // and seize it to theConIdleList
1534
  void	releaseConnectToNdb (NdbTransaction*);
1535 1536

  // Release a connection to idle list
1537
  void 	releaseNdbCon (NdbTransaction*);
1538 1539 1540 1541 1542 1543 1544 1545 1546
  
  int	checkInitState();		// Check that we are initialized
  void	report_node_failure(Uint32 node_id);           // Report Failed node
  void	report_node_failure_completed(Uint32 node_id); // Report Failed node(NF comp.)

  void	checkFailedNode();		// Check for failed nodes

  int   NDB_connect();     // Perform connect towards NDB Kernel

1547
  // Release arrays of NdbTransaction pointers
1548 1549
  void  releaseTransactionArrays();     

1550
  Uint32  pollCompleted(NdbTransaction** aCopyArray);
1551
  void    sendPrepTrans(int forceSend);
1552
  void    reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfComplTrans);
1553
  void    waitCompletedTransactions(int milliSecs, int noOfEventsToWaitFor);
1554 1555
  void    completedTransaction(NdbTransaction* aTransaction);
  void    completedScanTransaction(NdbTransaction* aTransaction);
1556 1557 1558 1559

  void    abortTransactionsAfterNodeFailure(Uint16 aNodeId);

  static
1560
  const char * externalizeTableName(const char * internalTableName, bool fullyQualifiedNames);
1561 1562 1563 1564
  const char * externalizeTableName(const char * internalTableName);
  const char * internalizeTableName(const char * externalTableName);

  static
1565
  const char * externalizeIndexName(const char * internalIndexName, bool fullyQualifiedNames);
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
  const char * externalizeIndexName(const char * internalIndexName);
  const char * internalizeIndexName(const NdbTableImpl * table,
				    const char * externalIndexName);

  static
  const BaseString getDatabaseFromInternalName(const char * internalName);
  static 
  const BaseString getSchemaFromInternalName(const char * internalName);

  void*              int2void     (Uint32 val);
  NdbReceiver*       void2rec     (void* val);
1577
  NdbTransaction*     void2con     (void* val);
1578 1579 1580 1581 1582 1583
  NdbOperation*      void2rec_op  (void* val);
  NdbIndexOperation* void2rec_iop (void* val);

/******************************************************************************
 *	These are the private variables in this class.	
 *****************************************************************************/
1584 1585 1586
  NdbTransaction**       thePreparedTransactionsArray;
  NdbTransaction**       theSentTransactionsArray;
  NdbTransaction**       theCompletedTransactionsArray;
1587 1588 1589 1590 1591 1592 1593 1594 1595 1596

  Uint32                theNoOfPreparedTransactions;
  Uint32                theNoOfSentTransactions;
  Uint32                theNoOfCompletedTransactions;
  Uint32                theNoOfAllocatedTransactions;
  Uint32                theMaxNoOfTransactions;
  Uint32                theMinNoOfEventsToWakeUp;

  Uint32                theNextConnectNode;

1597 1598
  bool fullyQualifiedNames;

1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
  // Ndb database name.
  char                  theDataBase[NDB_MAX_DATABASE_NAME_SIZE];
  // Ndb database schema name.  
  char                  theDataBaseSchema[NDB_MAX_SCHEMA_NAME_SIZE];
  char                  prefixName[NDB_MAX_INTERNAL_TABLE_LENGTH];
  char *                prefixEnd;		

  class NdbImpl * theImpl;
  class NdbDictionaryImpl* theDictionary;
  class NdbGlobalEventBufferHandle* theGlobalEventBufferHandle;

1610
  NdbTransaction*	theConIdleList;	// First connection in idle list.
1611 1612 1613

  NdbOperation*		theOpIdleList;	// First operation in the idle list. 

unknown's avatar
unknown committed
1614
  NdbIndexScanOperation* theScanOpIdleList;	// First scan operation in the idle list. 
1615
  NdbIndexOperation*	theIndexOpIdleList;	// First index operation in the idle list. 
1616 1617
  NdbTransaction*	theTransactionList;
  NdbTransaction**      theConnectionArray;
1618 1619 1620 1621 1622 1623
  NdbRecAttr*		theRecAttrIdleList;  
  NdbApiSignal*		theSignalIdleList;   // First signal in idlelist.
  NdbLabel*		theLabelList;	     // First label descriptor in list
  NdbBranch*		theBranchList;	     // First branch descriptor in list
  NdbSubroutine*	theSubroutineList;   // First subroutine descriptor in
  NdbCall*		theCallList;	     // First call descriptor in list
1624
  NdbReceiver*          theScanList;
unknown's avatar
unknown committed
1625
  NdbBlob*              theNdbBlobIdleList;
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642

  Uint32   theMyRef;        // My block reference  
  Uint32   theNode;         // The node number of our node
  
  Uint64               the_last_check_time;
  Uint64               theFirstTransId;
  
  // The tupleId is retreived from DB the 
  // tupleId is unique for each tableid. 
  Uint64               theFirstTupleId[2048]; 
  Uint64               theLastTupleId[2048];           

  Uint32		theRestartGCI;	// the Restart GCI used by DIHNDBTAMPER
  
  NdbError              theError;

  Int32        	        theNdbBlockNumber;
1643 1644 1645 1646 1647 1648 1649 1650

  enum InitType {
    NotConstructed,
    NotInitialised,
    StartingInit,
    Initialised,
    InitConfigError
  } theInitState;
1651 1652 1653

  NdbApiSignal* theCommitAckSignal;

unknown's avatar
unknown committed
1654 1655

#ifdef POORMANSPURIFY
1656 1657 1658 1659
  int cfreeSignals;
  int cnewSignals;
  int cgetSignals;
  int creleaseSignals;
unknown's avatar
unknown committed
1660
#endif
1661 1662 1663

  static void executeMessage(void*, NdbApiSignal *, 
			     struct LinearSectionPtr ptr[3]);
1664
  static void statusMessage(void*, Uint32, bool, bool);
1665 1666 1667 1668 1669 1670
#ifdef VM_TRACE
  void printState(const char* fmt, ...);
#endif
};

#endif