ndbapi_scan.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:21k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /*
  14.  * ndbapi_scan.cpp: 
  15.  * Illustrates how to use the scan api in the NDBAPI.
  16.  * The example shows how to do scan, scan for update and scan for delete
  17.  * using NdbScanFilter and NdbScanOperation
  18.  *
  19.  * Classes and methods used in this example:
  20.  *
  21.  *  Ndb
  22.  *       init()
  23.  *       waitUntilRead()
  24.  *       getDictionary()
  25.  *       startTransaction()
  26.  *       closeTransaction()
  27.  *       sendPreparedTransactions()
  28.  *       pollNdb()
  29.  *
  30.  *  NdbConnection
  31.  *       getNdbOperation()
  32.  *       executeAsynchPrepare()
  33.  *       getNdbError()
  34.  *       executeScan()
  35.  *       nextScanResult()
  36.  *
  37.  *  NdbDictionary::Dictionary
  38.  *       getTable()
  39.  *       dropTable()
  40.  *       createTable()
  41.  *
  42.  *  NdbDictionary::Column
  43.  *       setName()
  44.  *       setType()
  45.  *       setLength()
  46.  *       setPrimaryKey()
  47.  *       setNullable()
  48.  *
  49.  *  NdbDictionary::Table
  50.  *       setName()
  51.  *       addColumn()
  52.  *
  53.  *  NdbOperation
  54.  *       insertTuple()
  55.  *       equal()
  56.  *       setValue()
  57.  *       openScanRead()
  58.  *       openScanExclusive()
  59.  *
  60.  *  NdbRecAttr
  61.  *       aRef()
  62.  *       u_32_value()
  63.  *
  64.  *  NdbResultSet
  65.  *       nextResult()
  66.  *       deleteTuple()
  67.  *       updateTuple()
  68.  *
  69.  *  NdbScanOperation
  70.  *       getValue() 
  71.  *       readTuplesExclusive()
  72.  *
  73.  *  NdbScanFilter
  74.  *       begin()
  75.  *  eq()
  76.  *  end()
  77.  *
  78.  *       
  79.  */
  80. #include <ndb_global.h>
  81. #include <NdbApi.hpp>
  82. #include <NdbScanFilter.hpp>
  83. // Used for cout
  84. #include <iostream>
  85. /**
  86.  * Helper sleep function
  87.  */
  88. int
  89. milliSleep(int milliseconds){
  90.   int result = 0;
  91.   struct timespec sleeptime;
  92.   sleeptime.tv_sec = milliseconds / 1000;
  93.   sleeptime.tv_nsec = (milliseconds - (sleeptime.tv_sec * 1000)) * 1000000;
  94.   result = nanosleep(&sleeptime, NULL);
  95.   return result;
  96. }
  97. /**
  98.  * Helper sleep function
  99.  */
  100. #define APIERROR(error) 
  101.   { std::cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" 
  102.               << error.code << ", msg: " << error.message << "." << std::endl; 
  103.     exit(-1); }
  104. /*
  105.  *   callback : This is called when the transaction is polled
  106.  *              
  107.  *   (This function must have three arguments: 
  108.  *   - The result of the transaction, 
  109.  *   - The NdbConnection object, and 
  110.  *   - A pointer to an arbitrary object.)
  111.  */
  112. static void
  113. callback(int result, NdbConnection* myTrans, void* aObject)
  114. {
  115.   if (result == -1) {
  116.     std::cout << "In callback: " << std::endl;     
  117.     /**
  118.      * Put error checking code here (see ndb_async_example)
  119.      */
  120.     APIERROR(myTrans->getNdbError());
  121.   } else {
  122.     /**
  123.      * Ok!
  124.      */
  125.     return;
  126.   }
  127. }
  128. /**
  129.  * Function to create table
  130.  */
  131. int create_table(Ndb * myNdb) 
  132. {
  133.   NdbDictionary::Table myTable;
  134.   NdbDictionary::Column myColumn;
  135.   
  136.   NdbDictionary::Dictionary* myDict = myNdb->getDictionary();
  137.   
  138.   /*********************************************************
  139.    * Create a table named GARAGE if it does not exist *
  140.    *********************************************************/
  141.   if (myDict->getTable("GARAGE") != NULL) {
  142.     std::cout << "NDB already has example table: GARAGE. "
  143.       << "Dropping it..." << std::endl; 
  144.     if(myDict->dropTable("GARAGE") == -1)
  145.     {
  146.       std::cout << "Failed to drop: GARAGE." << std::endl; 
  147.       exit(1);
  148.     }
  149.   } 
  150.   myTable.setName("GARAGE");
  151.   
  152.   myColumn.setName("REG_NO");
  153.   myColumn.setType(NdbDictionary::Column::Unsigned);
  154.   myColumn.setLength(1);
  155.   myColumn.setPrimaryKey(true);
  156.   myColumn.setNullable(false);
  157.   myTable.addColumn(myColumn);
  158.   myColumn.setName("BRAND");
  159.   myColumn.setType(NdbDictionary::Column::Char);
  160.   myColumn.setLength(20);
  161.   myColumn.setPrimaryKey(false);
  162.   myColumn.setNullable(false);
  163.   myTable.addColumn(myColumn);
  164.   myColumn.setName("COLOR");
  165.   myColumn.setType(NdbDictionary::Column::Char);
  166.   myColumn.setLength(20);
  167.   myColumn.setPrimaryKey(false);
  168.   myColumn.setNullable(false);
  169.   myTable.addColumn(myColumn);
  170.   if (myDict->createTable(myTable) == -1) {
  171.       APIERROR(myDict->getNdbError());
  172.       return -1;
  173.   }
  174.   return 1;
  175. }
  176. int populate(Ndb * myNdb)
  177. {
  178.   NdbConnection*  myNdbConnection[15];   // For transactions
  179.   NdbOperation*   myNdbOperation;       // For operations
  180.   /******************************************************
  181.    * Insert (we do 15 insert transactions in parallel) *
  182.    ******************************************************/
  183.   /**
  184.    * Five blue mercedes
  185.    */
  186.   for (int i = 0; i < 5; i++) 
  187.   {
  188.     myNdbConnection[i] = myNdb->startTransaction();
  189.     if (myNdbConnection[i] == NULL) 
  190.       APIERROR(myNdb->getNdbError());
  191.     myNdbOperation = myNdbConnection[i]->getNdbOperation("GARAGE");
  192.     // Error check. If error, then maybe table GARAGE is not in database
  193.     if (myNdbOperation == NULL) 
  194.       APIERROR(myNdbConnection[i]->getNdbError());
  195.     myNdbOperation->insertTuple();
  196.     myNdbOperation->equal("REG_NO", i);
  197.     myNdbOperation->setValue("BRAND", "Mercedes");
  198.     myNdbOperation->setValue("COLOR", "Blue");
  199.     // Prepare transaction (the transaction is NOT yet sent to NDB)
  200.     myNdbConnection[i]->executeAsynchPrepare(Commit, &callback, NULL);
  201.   }
  202.   /**
  203.    * Five black bmw
  204.    */
  205.   for (int i = 5; i < 10; i++) 
  206.   {
  207.     myNdbConnection[i] = myNdb->startTransaction();
  208.     if (myNdbConnection[i] == NULL)
  209.       APIERROR(myNdb->getNdbError());
  210.     myNdbOperation = myNdbConnection[i]->getNdbOperation("GARAGE");
  211.     // Error check. If error, then maybe table MYTABLENAME is not in database
  212.     if (myNdbOperation == NULL) 
  213.       APIERROR(myNdbConnection[i]->getNdbError());
  214.     myNdbOperation->insertTuple();
  215.     myNdbOperation->equal("REG_NO", i);
  216.     myNdbOperation->setValue("BRAND", "BMW");
  217.     myNdbOperation->setValue("COLOR", "Black");
  218.     // Prepare transaction (the transaction is NOT yet sent to NDB)
  219.     myNdbConnection[i]->executeAsynchPrepare(Commit, &callback, NULL);
  220.   }
  221.   /**
  222.    * Five pink toyotas
  223.    */
  224.   for (int i = 10; i < 15; i++) {
  225.     myNdbConnection[i] = myNdb->startTransaction();
  226.     if (myNdbConnection[i] == NULL) APIERROR(myNdb->getNdbError());
  227.     myNdbOperation = myNdbConnection[i]->getNdbOperation("GARAGE");
  228.     // Error check. If error, then maybe table MYTABLENAME is not in database
  229.     if (myNdbOperation == NULL) APIERROR(myNdbConnection[i]->getNdbError());
  230.     myNdbOperation->insertTuple();
  231.     myNdbOperation->equal("REG_NO", i);
  232.     myNdbOperation->setValue("BRAND", "Toyota");
  233.     myNdbOperation->setValue("COLOR", "Pink");
  234.     // Prepare transaction (the transaction is NOT yet sent to NDB)
  235.     myNdbConnection[i]->executeAsynchPrepare(Commit, &callback, NULL);
  236.   }
  237.   // Send all transactions to NDB 
  238.   myNdb->sendPreparedTransactions(0);
  239.   // Poll all transactions
  240.   myNdb->pollNdb(3000, 0);
  241.   //  it is also possible to use sendPollNdb instead of
  242.   //  myNdb->sendPreparedTransactions(0); and myNdb->pollNdb(3000, 15);  above.
  243.   //  myNdb->sendPollNdb(3000,0);
  244.   //  Note! Neither sendPollNdb or pollNdb returs until all 15 callbacks have 
  245.   //  executed.
  246.   //  Close all transactions. It is also possible to close transactions
  247.   //  in the callback.
  248.   for (int i = 0; i < 15; i++) 
  249.     myNdb->closeTransaction(myNdbConnection[i]);
  250.   return 1;
  251. }
  252. int scan_delete(Ndb* myNdb, 
  253. int parallelism,
  254. int column,
  255. int column_len,
  256. const char * color)
  257. {
  258.   
  259.   // Scan all records exclusive and delete 
  260.   // them one by one
  261.   int                  retryAttempt = 0;
  262.   const int            retryMax = 10;
  263.   int deletedRows = 0;
  264.   int check;
  265.   NdbError              err;
  266.   NdbConnection *myTrans;
  267.   NdbScanOperation *myScanOp;
  268.   /**
  269.    * Loop as long as :
  270.    *  retryMax not reached
  271.    *  failed operations due to TEMPORARY erros
  272.    *
  273.    * Exit loop;
  274.    *  retyrMax reached
  275.    *  Permanent error (return -1)
  276.    */
  277.   while (true)
  278.   {
  279.     if (retryAttempt >= retryMax)
  280.     {
  281.       std::cout << "ERROR: has retried this operation " << retryAttempt 
  282. << " times, failing!" << std::endl;
  283.       return -1;
  284.     }
  285.     myTrans = myNdb->startTransaction();
  286.     if (myTrans == NULL) 
  287.     {
  288.       const NdbError err = myNdb->getNdbError();
  289.       if (err.status == NdbError::TemporaryError)
  290.       {
  291. milliSleep(50);
  292. retryAttempt++;
  293. continue;
  294.       }
  295.       std::cout <<  err.message << std::endl;
  296.       return -1;
  297.     }
  298.    /**
  299.     * Get a scan operation.
  300.     */
  301.     myScanOp = myTrans->getNdbScanOperation("GARAGE");
  302.     if (myScanOp == NULL) 
  303.     {
  304.       std::cout << myTrans->getNdbError().message << std::endl;
  305.       myNdb->closeTransaction(myTrans);
  306.       return -1;
  307.     }
  308.     /**
  309.      * Define a result set for the scan.
  310.      */ 
  311.     NdbResultSet * rs = myScanOp->readTuplesExclusive(parallelism);
  312.     if( rs == 0 ) {
  313.       std::cout << myTrans->getNdbError().message << std::endl;
  314.       myNdb->closeTransaction(myTrans);
  315.       return -1;
  316.     } 
  317.     /**
  318.      * Use NdbScanFilter to define a search critera
  319.      */ 
  320.     NdbScanFilter filter(myScanOp) ;   
  321.     if(filter.begin(NdbScanFilter::AND) < 0  || 
  322.        filter.eq(column, color, column_len, false) <0||
  323.        filter.end() <0)
  324.     {
  325.       std::cout <<  myTrans->getNdbError().message << std::endl;
  326.       myNdb->closeTransaction(myTrans);
  327.       return -1;
  328.     }    
  329.     
  330.     /**
  331.      * Start scan    (NoCommit since we are only reading at this stage);
  332.      */     
  333.     if(myTrans->execute(NoCommit) != 0){      
  334.       err = myTrans->getNdbError();    
  335.       if(err.status == NdbError::TemporaryError){
  336. std::cout << myTrans->getNdbError().message << std::endl;
  337. myNdb->closeTransaction(myTrans);
  338. milliSleep(50);
  339. continue;
  340.       }
  341.       std::cout << err.code << std::endl;
  342.       std::cout << myTrans->getNdbError().code << std::endl;
  343.       myNdb->closeTransaction(myTrans);
  344.       return -1;
  345.     }
  346.    /**
  347.     * start of loop: nextResult(true) means that "parallelism" number of
  348.     * rows are fetched from NDB and cached in NDBAPI
  349.     */    
  350.     while((check = rs->nextResult(true)) == 0){
  351.       do {
  352. if (rs->deleteTuple() != 0){
  353.   std::cout << myTrans->getNdbError().message << std::endl;
  354.   myNdb->closeTransaction(myTrans);
  355.   return -1;
  356. }
  357. deletedRows++;
  358. /**
  359.  * nextResult(false) means that the records 
  360.  * cached in the NDBAPI are modified before
  361.  * fetching more rows from NDB.
  362.  */    
  363.       } while((check = rs->nextResult(false)) == 0);
  364.       
  365.       /**
  366.        * Commit when all cached tuple have been marked for deletion
  367.        */    
  368.       if(check != -1){
  369. check = myTrans->execute(Commit);   
  370. myTrans->releaseCompletedOperations();
  371.       }
  372.       /**
  373.        * Check for errors
  374.        */
  375.       err = myTrans->getNdbError();    
  376.       if(check == -1){
  377. if(err.status == NdbError::TemporaryError){
  378.   std::cout << myTrans->getNdbError().message << std::endl;
  379.   myNdb->closeTransaction(myTrans);
  380.   milliSleep(50);
  381.   continue;
  382. }
  383.       }
  384.       /**
  385.        * End of loop 
  386.        */
  387.     }
  388.     std::cout << myTrans->getNdbError().message << std::endl;
  389.     myNdb->closeTransaction(myTrans);
  390.     return 0;
  391.     
  392.   }
  393.   if(myTrans!=0) {
  394.     std::cout << myTrans->getNdbError().message << std::endl;
  395.     myNdb->closeTransaction(myTrans);
  396.   }
  397.   return -1;
  398. }
  399. int scan_update(Ndb* myNdb, 
  400. int parallelism,
  401. int column_len,
  402. int update_column,
  403. const char * column_name,
  404. const char * before_color,
  405. const char * after_color)
  406. {
  407.   
  408.   // Scan all records exclusive and update
  409.   // them one by one
  410.   int                  retryAttempt = 0;
  411.   const int            retryMax = 10;
  412.   int updatedRows = 0;
  413.   int check;
  414.   NdbError              err;
  415.   NdbConnection *myTrans;
  416.   NdbScanOperation *myScanOp;
  417.   /**
  418.    * Loop as long as :
  419.    *  retryMax not reached
  420.    *  failed operations due to TEMPORARY erros
  421.    *
  422.    * Exit loop;
  423.    *  retyrMax reached
  424.    *  Permanent error (return -1)
  425.    */
  426.   while (true)
  427.   {
  428.     if (retryAttempt >= retryMax)
  429.     {
  430.       std::cout << "ERROR: has retried this operation " << retryAttempt 
  431. << " times, failing!" << std::endl;
  432.       return -1;
  433.     }
  434.     myTrans = myNdb->startTransaction();
  435.     if (myTrans == NULL) 
  436.     {
  437.       const NdbError err = myNdb->getNdbError();
  438.       if (err.status == NdbError::TemporaryError)
  439.       {
  440. milliSleep(50);
  441. retryAttempt++;
  442. continue;
  443.       }
  444.       std::cout <<  err.message << std::endl;
  445.       return -1;
  446.     }
  447.    /**
  448.     * Get a scan operation.
  449.     */
  450.     myScanOp = myTrans->getNdbScanOperation("GARAGE");
  451.     if (myScanOp == NULL) 
  452.     {
  453.       std::cout << myTrans->getNdbError().message << std::endl;
  454.       myNdb->closeTransaction(myTrans);
  455.       return -1;
  456.     }
  457.     /**
  458.      * Define a result set for the scan.
  459.      */ 
  460.     NdbResultSet * rs = myScanOp->readTuplesExclusive(parallelism);
  461.     if( rs == 0 ) {
  462.       std::cout << myTrans->getNdbError().message << std::endl;
  463.       myNdb->closeTransaction(myTrans);
  464.       return -1;
  465.     } 
  466.     /**
  467.      * Use NdbScanFilter to define a search critera
  468.      */ 
  469.     NdbScanFilter filter(myScanOp) ;   
  470.     if(filter.begin(NdbScanFilter::AND) < 0  || 
  471.        filter.eq(update_column, before_color, column_len, false) <0||
  472.        filter.end() <0)
  473.     {
  474.       std::cout <<  myTrans->getNdbError().message << std::endl;
  475.       myNdb->closeTransaction(myTrans);
  476.       return -1;
  477.     }    
  478.     
  479.     /**
  480.      * Start scan    (NoCommit since we are only reading at this stage);
  481.      */     
  482.     if(myTrans->execute(NoCommit) != 0){      
  483.       err = myTrans->getNdbError();    
  484.       if(err.status == NdbError::TemporaryError){
  485. std::cout << myTrans->getNdbError().message << std::endl;
  486. myNdb->closeTransaction(myTrans);
  487. milliSleep(50);
  488. continue;
  489.       }
  490.       std::cout << myTrans->getNdbError().code << std::endl;
  491.       myNdb->closeTransaction(myTrans);
  492.       return -1;
  493.     }
  494.    /**
  495.     * Define an update operation
  496.     */    
  497.     NdbOperation * myUpdateOp;
  498.    /**
  499.     * start of loop: nextResult(true) means that "parallelism" number of
  500.     * rows are fetched from NDB and cached in NDBAPI
  501.     */    
  502.     while((check = rs->nextResult(true)) == 0){
  503.       do {
  504. /**
  505.  * Get update operation
  506.  */    
  507. myUpdateOp = rs->updateTuple();
  508. if (myUpdateOp == 0){
  509.   std::cout << myTrans->getNdbError().message << std::endl;
  510.   myNdb->closeTransaction(myTrans);
  511.   return -1;
  512. }
  513. updatedRows++;
  514. /**
  515.  * do the update
  516.  */    
  517. myUpdateOp->setValue(update_column,after_color);
  518. /**
  519.  * nextResult(false) means that the records 
  520.  * cached in the NDBAPI are modified before
  521.  * fetching more rows from NDB.
  522.  */    
  523.       } while((check = rs->nextResult(false)) == 0);
  524.       
  525.       /**
  526.        * Commit when all cached tuple have been updated
  527.        */    
  528.       if(check != -1){
  529. check = myTrans->execute(Commit);   
  530. myTrans->releaseCompletedOperations();
  531.       }
  532.       /**
  533.        * Check for errors
  534.        */
  535.       err = myTrans->getNdbError();    
  536.       if(check == -1){
  537. if(err.status == NdbError::TemporaryError){
  538.   std::cout << myTrans->getNdbError().message << std::endl;
  539.   myNdb->closeTransaction(myTrans);
  540.   milliSleep(50);
  541.   continue;
  542. }
  543.       }
  544.       /**
  545.        * End of loop 
  546.        */
  547.     }
  548.     std::cout << myTrans->getNdbError().message << std::endl;
  549.     myNdb->closeTransaction(myTrans);
  550.     return 0;
  551.     
  552.   }
  553.   if(myTrans!=0) {
  554.     std::cout << myTrans->getNdbError().message << std::endl;
  555.     myNdb->closeTransaction(myTrans);
  556.   }
  557.   return -1;
  558. }
  559. int scan_print(Ndb * myNdb, int parallelism, 
  560.        int column_len_brand, 
  561.        int column_len_color) 
  562. {
  563. // Scan all records exclusive and update
  564.   // them one by one
  565.   int                  retryAttempt = 0;
  566.   const int            retryMax = 10;
  567.   int fetchedRows = 0;
  568.   int check;
  569.   NdbError              err;
  570.   NdbConnection *myTrans;
  571.   NdbScanOperation *myScanOp;
  572.   /* Result of reading attribute value, three columns:
  573.      REG_NO, BRAND, and COLOR
  574.    */
  575.   NdbRecAttr *     myRecAttr[3];   
  576.   /**
  577.    * Loop as long as :
  578.    *  retryMax not reached
  579.    *  failed operations due to TEMPORARY erros
  580.    *
  581.    * Exit loop;
  582.    *  retyrMax reached
  583.    *  Permanent error (return -1)
  584.    */
  585.   while (true)
  586.   {
  587.     if (retryAttempt >= retryMax)
  588.     {
  589.       std::cout << "ERROR: has retried this operation " << retryAttempt 
  590. << " times, failing!" << std::endl;
  591.       return -1;
  592.     }
  593.     myTrans = myNdb->startTransaction();
  594.     if (myTrans == NULL) 
  595.     {
  596.       const NdbError err = myNdb->getNdbError();
  597.       if (err.status == NdbError::TemporaryError)
  598.       {
  599. milliSleep(50);
  600. retryAttempt++;
  601. continue;
  602.       }
  603.      std::cout << err.message << std::endl;
  604.       return -1;
  605.     }
  606.     /*
  607.      * Define a scan operation. 
  608.      * NDBAPI.
  609.      */
  610.     myScanOp = myTrans->getNdbScanOperation("GARAGE");
  611.     if (myScanOp == NULL) 
  612.     {
  613.       std::cout << myTrans->getNdbError().message << std::endl;
  614.       myNdb->closeTransaction(myTrans);
  615.       return -1;
  616.     }
  617.     /**
  618.      * Define a result set for the scan.
  619.      */ 
  620.     NdbResultSet * rs = myScanOp->readTuplesExclusive(parallelism);
  621.     if( rs == 0 ) {
  622.       std::cout << myTrans->getNdbError().message << std::endl;
  623.       myNdb->closeTransaction(myTrans);
  624.       return -1;
  625.     } 
  626.     /**
  627.      * Define storage for fetched attributes.
  628.      * E.g., the resulting attributes of executing
  629.      * myOp->getValue("REG_NO") is placed in myRecAttr[0].
  630.      * No data exists in myRecAttr until transaction has commited!
  631.      */
  632.     myRecAttr[0] = myScanOp->getValue("REG_NO");
  633.     myRecAttr[1] = myScanOp->getValue("BRAND");
  634.     myRecAttr[2] = myScanOp->getValue("COLOR");
  635.     if(myRecAttr[0] ==NULL || myRecAttr[1] == NULL || myRecAttr[2]==NULL) 
  636.     {
  637. std::cout << myTrans->getNdbError().message << std::endl;
  638. myNdb->closeTransaction(myTrans);
  639. return -1;
  640.     }
  641.     /**
  642.      * Start scan   (NoCommit since we are only reading at this stage);
  643.      */     
  644.     if(myTrans->execute(NoCommit) != 0){      
  645.       err = myTrans->getNdbError();    
  646.       if(err.status == NdbError::TemporaryError){
  647. std::cout << myTrans->getNdbError().message << std::endl;
  648. myNdb->closeTransaction(myTrans);
  649. milliSleep(50);
  650. continue;
  651.       }
  652.       std::cout << err.code << std::endl;
  653.       std::cout << myTrans->getNdbError().code << std::endl;
  654.       myNdb->closeTransaction(myTrans);
  655.       return -1;
  656.     }
  657.     
  658.     /**
  659.      * start of loop: nextResult(true) means that "parallelism" number of
  660.      * rows are fetched from NDB and cached in NDBAPI
  661.      */    
  662.     while((check = rs->nextResult(true)) == 0){
  663.       do {
  664. fetchedRows++;
  665. /**
  666.  * print  REG_NO unsigned int
  667.  */
  668. std::cout << myRecAttr[0]->u_32_value() << "t";
  669. char * buf_brand = new char[column_len_brand+1];
  670. char * buf_color = new char[column_len_color+1];
  671. /**
  672.  * print  BRAND character string
  673.  */
  674. memcpy(buf_brand, myRecAttr[1]->aRef(), column_len_brand);
  675. buf_brand[column_len_brand] = 0;
  676. std::cout << buf_brand << "t";
  677. delete [] buf_brand;
  678. /**
  679.  * print  COLOR character string
  680.  */
  681. memcpy(buf_color, myRecAttr[2]->aRef(), column_len_color);
  682. buf_brand[column_len_color] = 0;
  683. std::cout << buf_color << std::endl;
  684. delete [] buf_color;
  685. /**
  686.  * nextResult(false) means that the records 
  687.  * cached in the NDBAPI are modified before
  688.  * fetching more rows from NDB.
  689.  */    
  690.       } while((check = rs->nextResult(false)) == 0);
  691.     }    
  692.     myNdb->closeTransaction(myTrans);
  693.     return 1;
  694.   }
  695.   return -1;
  696. }
  697. int main()
  698. {
  699.   ndb_init();
  700.   Ndb* myNdb = new Ndb( "TEST_DB" );  // Object representing the database
  701.   
  702.   
  703.   /*******************************************
  704.    * Initialize NDB and wait until its ready *
  705.    *******************************************/
  706.   if (myNdb->init(1024) == -1) {          // Set max 1024  parallel transactions
  707.     APIERROR(myNdb->getNdbError());
  708.     exit(-1);
  709.   }
  710.   if (myNdb->waitUntilReady(30) != 0) {
  711.     std::cout << "NDB was not ready within 30 secs." << std::endl;
  712.     exit(-1);
  713.   }
  714.   create_table(myNdb);
  715.   
  716.   NdbDictionary::Dictionary* myDict = myNdb->getDictionary();
  717.   int column_color = myDict->getTable("GARAGE")->getColumn("COLOR")->getColumnNo();
  718.   int column_len_color = 
  719.     myDict->getTable("GARAGE")->getColumn("COLOR")->getLength();
  720.   int column_len_brand = 
  721.     myDict->getTable("GARAGE")->getColumn("BRAND")->getLength();
  722.   int parallelism = 16;
  723.   
  724.   if(populate(myNdb) > 0)
  725.     std::cout << "populate: Success!" << std::endl;
  726.   if(scan_print(myNdb, parallelism, column_len_brand, column_len_color) > 0)
  727.     std::cout << "scan_print: Success!" << std::endl  << std::endl;
  728.   
  729.   std::cout << "Going to delete all pink cars!" << std::endl;
  730.   if(scan_delete(myNdb, parallelism, column_color,
  731.  column_len_color, "Pink") > 0)
  732.     std::cout << "scan_delete: Success!" << std::endl  << std::endl;
  733.   if(scan_print(myNdb, parallelism, column_len_brand, column_len_color) > 0)
  734.     std::cout << "scan_print: Success!" << std::endl  << std::endl;
  735.   
  736.   std::cout << "Going to update all blue cars to black cars!" << std::endl;
  737.   if(scan_update(myNdb, parallelism, column_len_color, column_color, 
  738.  "COLOR", "Blue", "Black") > 0) 
  739.   {
  740.     std::cout << "scan_update: Success!" << std::endl  << std::endl;
  741.   }
  742.   if(scan_print(myNdb, parallelism, column_len_brand, column_len_color) > 0)
  743.     std::cout << "scan_print: Success!" << std::endl  << std::endl;
  744.   delete myNdb; 
  745. }