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

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.        INDEX TEST 1
  15.        Test index functionality of NDB
  16.        Arguments:
  17.         -T create table
  18.         -L include a long attribute in key or index
  19.         -2 define primary key with two attributes
  20.         -c create index
  21. -p make index unique (include primary key attribute)
  22.         -r read using index
  23. -u update using index
  24. -d delete using index
  25. -n<no operations> do n operations (for -I -r -u -d -R -U -D)
  26. -o<no parallel operations> (for -I -r -u -d -R -U -D)
  27. -m<no indexes>
  28.        Returns:
  29.         0 - Test passed
  30.        -1 - Test failed
  31.         1 - Invalid arguments
  32.  * *************************************************** */
  33. #include <ndb_global.h>
  34. #include <NdbApi.hpp>
  35. #include <NdbOut.hpp>
  36. #include <NdbTick.h>
  37. #include <NdbMain.h>
  38. #include <NdbTest.hpp>
  39. #include <NDBT_Error.hpp>
  40. #ifndef MIN
  41. #define MIN(x,y) (((x)<(y))?(x):(y))
  42. #endif
  43. #define MAX_NO_PARALLEL_OPERATIONS 100
  44. bool testPassed = true;
  45. static void
  46. error_handler(const NdbError & err)
  47. {
  48.   // Test failed 
  49.   ndbout << endl << err << endl;
  50.   testPassed = false;
  51. }
  52. static void
  53. error_handler4(int line, const NdbError & err){
  54.   ndbout << endl << "Line " << line << endl;
  55.   // Test failed 
  56.   ndbout << err << endl;
  57.   testPassed = false;
  58. }
  59. static char *longName, *sixtysix, *ninetynine, *hundred;
  60. static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey)
  61. {
  62.   NdbDictionary::Dictionary* dict = myNdb.getDictionary();
  63.   NdbDictionary::Table table("PERSON");
  64.   //NdbDictionary::Column column(); // Bug
  65.   NdbDictionary::Column column;
  66.   int res;
  67.   column.setName("NAME");
  68.   column.setType(NdbDictionary::Column::Char);
  69.   column.setLength((longKey)?
  70.    1024       // 1KB => long key
  71.    :12);
  72.   column.setPrimaryKey(true);
  73.   column.setNullable(false);
  74.   table.addColumn(column);
  75.   if (twoKey) {
  76.     column.setName("KEY2");
  77.     column.setType(NdbDictionary::Column::Unsigned);
  78.     column.setLength(1);
  79.     column.setPrimaryKey(true);
  80.     column.setNullable(false);
  81.     table.addColumn(column);
  82.   }
  83.   column.setName("PNUM1");
  84.   column.setType(NdbDictionary::Column::Unsigned);
  85.   column.setLength(1);
  86.   column.setPrimaryKey(false);
  87.   column.setNullable(false);
  88.   table.addColumn(column);
  89.   column.setName("PNUM2");
  90.   column.setType(NdbDictionary::Column::Unsigned);
  91.   column.setLength(1);
  92.   column.setPrimaryKey(false);
  93.   column.setNullable(false);
  94.   table.addColumn(column);
  95.   column.setName("PNUM3");
  96.   column.setType(NdbDictionary::Column::Unsigned);
  97.   column.setLength(1);
  98.   column.setPrimaryKey(false);
  99.   column.setNullable(false);
  100.   table.addColumn(column);
  101.   column.setName("PNUM4");
  102.   column.setType(NdbDictionary::Column::Unsigned);
  103.   column.setLength(1);
  104.   column.setPrimaryKey(false);
  105.   column.setNullable(false);
  106.   table.addColumn(column);
  107.   column.setName("AGE");
  108.   column.setType(NdbDictionary::Column::Unsigned);
  109.   column.setLength(1);
  110.   column.setPrimaryKey(false);
  111.   column.setNullable(false);
  112.   table.addColumn(column);
  113.   column.setName("STRING_AGE");
  114.   column.setType(NdbDictionary::Column::Char);
  115.   column.setLength(1);
  116.   column.setLength(256);
  117.   column.setPrimaryKey(false);
  118.   column.setNullable(false);
  119.   table.addColumn(column);
  120.   if ((res = dict->createTable(table)) == -1) {
  121.     error_handler(dict->getNdbError());
  122.   }
  123.   else
  124.       ndbout << "Created table" << ((longKey)?" with long key":"") <<endl;
  125. }
  126. static void createIndex(Ndb &myNdb, bool includePrimary, unsigned int noOfIndexes)
  127. {
  128.   Uint64 before, after;
  129.   NdbDictionary::Dictionary* dict = myNdb.getDictionary();
  130.   char indexName[] = "PNUMINDEX0000";
  131.   int res;
  132.   for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
  133.     sprintf(indexName, "PNUMINDEX%.4u", indexNum);
  134.     NdbDictionary::Index index(indexName);
  135.     index.setTable("PERSON");
  136.     index.setType(NdbDictionary::Index::UniqueHashIndex);
  137.     if (includePrimary) {
  138.       const char* attr_arr[] = {"NAME", "PNUM1", "PNUM3"};
  139.       index.addIndexColumns(3, attr_arr);
  140.     }
  141.     else {
  142.       const char* attr_arr[] = {"PNUM1", "PNUM3"};
  143.       index.addIndexColumns(2, attr_arr);
  144.     }
  145.     before = NdbTick_CurrentMillisecond();
  146.     if ((res = dict->createIndex(index)) == -1) {
  147.       error_handler(dict->getNdbError());
  148.     }    
  149.     after = NdbTick_CurrentMillisecond();
  150.     ndbout << "Created index " << indexName << ", " << after - before << " msec" << endl;
  151.   }
  152. }
  153.   
  154. static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
  155. {
  156.   Uint64 tbefore, tafter, before, after;
  157.   NdbConnection  *myTrans;  
  158.   NdbOperation   *myOp;   
  159.   char name[] = "Kalle0000000";
  160.   
  161.   tbefore = NdbTick_CurrentMillisecond();
  162.   if (oneTrans) myTrans = myNdb.startTransaction();
  163.   for (unsigned int i = 0; i<noOfTuples; i++) {
  164.     if (!oneTrans) myTrans = myNdb.startTransaction();
  165.     for(unsigned int j = 1; 
  166. ((j<=noOfOperations)&&(i<noOfTuples)); 
  167. (++j<=noOfOperations)?i++:i) { 
  168.       if (myTrans == NULL) 
  169. error_handler4(__LINE__, myNdb.getNdbError());
  170.       
  171.       myOp = myTrans->getNdbOperation("PERSON"); 
  172.       if (myOp == NULL) 
  173. error_handler4(__LINE__, myTrans->getNdbError());
  174.       
  175.       myOp->insertTuple();
  176.       sprintf(name, "Kalle%.7i", i);
  177.       if (longKey)
  178. memcpy(longName, name, strlen(name)); 
  179.       if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  180. error_handler4(__LINE__, myTrans->getNdbError());
  181. myNdb.closeTransaction(myTrans);
  182. break;
  183.       }      
  184.       if (twoKey)
  185. if (myOp->equal("KEY2", i) == -1) {
  186.   error_handler4(__LINE__, myTrans->getNdbError());
  187.   myNdb.closeTransaction(myTrans);
  188.   break;
  189. }      
  190.       if (myOp->setValue("PNUM1", 17) == -1) {
  191. error_handler4(__LINE__, myTrans->getNdbError());
  192. myNdb.closeTransaction(myTrans);
  193. break;
  194.       }      
  195.       if (myOp->setValue("PNUM2", 18)) {
  196. error_handler4(__LINE__, myTrans->getNdbError());
  197. myNdb.closeTransaction(myTrans);
  198. break;
  199.       }      
  200.       if (myOp->setValue("PNUM3", 19)) {
  201. error_handler4(__LINE__, myTrans->getNdbError());
  202. myNdb.closeTransaction(myTrans);
  203. break;
  204.       }      
  205.       if (myOp->setValue("PNUM4", 20)) {
  206. error_handler4(__LINE__, myTrans->getNdbError());
  207. myNdb.closeTransaction(myTrans);
  208. break;
  209.       }      
  210.       if (myOp->setValue("AGE", ((i % 2) == 0)?66:99) == -1) {
  211. error_handler4(__LINE__, myTrans->getNdbError());
  212. myNdb.closeTransaction(myTrans);
  213. break;
  214.       }      
  215.       if (myOp->setValue("STRING_AGE", ((i % 2) == 0)?sixtysix:ninetynine) == -1) {
  216. error_handler4(__LINE__, myTrans->getNdbError());
  217. myNdb.closeTransaction(myTrans);
  218. break;
  219.       }      
  220.     }
  221.     if (noOfOperations == 1)
  222.       printf("Trying to insert person %sn", name);
  223.     else
  224.       printf("Trying to insert %u personsn", noOfOperations);
  225.     before = NdbTick_CurrentMillisecond();
  226.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  227.       {
  228.         error_handler4(__LINE__, myTrans->getNdbError());
  229.         myNdb.closeTransaction(myTrans);
  230.         break;
  231.       }
  232.     after = NdbTick_CurrentMillisecond();
  233.     if (noOfOperations == 1)
  234.       printf("Inserted person %s, %u msecn", name, (Uint32) after - before);
  235.     else
  236.       printf("Inserted %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  237.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  238.   }
  239.   if (oneTrans) {
  240.     if (myTrans->execute( Commit ) == -1) {
  241.       error_handler4(__LINE__, myTrans->getNdbError());
  242.     }
  243.     myNdb.closeTransaction(myTrans);
  244.   }
  245.   tafter = NdbTick_CurrentMillisecond();
  246.   ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  247. }
  248.  
  249. static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
  250. {
  251.   Uint64 tbefore, tafter, before, after;
  252.   NdbConnection  *myTrans;  
  253.   NdbOperation   *myOp;   
  254.   char name[] = "Kalle0000000";
  255.   
  256.   tbefore = NdbTick_CurrentMillisecond();
  257.   if (oneTrans) myTrans = myNdb.startTransaction();
  258.   for (unsigned int i = 0; i<noOfTuples; i++) {
  259.     if (!oneTrans) myTrans = myNdb.startTransaction();
  260.     for(unsigned int j = 1; 
  261. ((j<=noOfOperations)&&(i<noOfTuples)); 
  262. (++j<=noOfOperations)?i++:i) { 
  263.       if (myTrans == NULL) 
  264. error_handler4(__LINE__, myNdb.getNdbError());
  265.       
  266.       myOp = myTrans->getNdbOperation("PERSON"); 
  267.       if (myOp == NULL) 
  268. error_handler4(__LINE__, myTrans->getNdbError());
  269.       
  270.       myOp->updateTuple();
  271.       sprintf(name, "Kalle%.7i", i);
  272.       if (longKey)
  273. memcpy(longName, name, strlen(name)); 
  274.       if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  275. error_handler4(__LINE__, myTrans->getNdbError());
  276. myNdb.closeTransaction(myTrans);
  277. break;
  278.       }      
  279.       if (twoKey)
  280. if (myOp->equal("KEY2", i) == -1) {
  281.   error_handler4(__LINE__, myTrans->getNdbError());
  282.   myNdb.closeTransaction(myTrans);
  283.   break;
  284. }      
  285.       if (myOp->setValue("PNUM1", 77) == -1) {
  286. error_handler4(__LINE__, myTrans->getNdbError());
  287. myNdb.closeTransaction(myTrans);
  288. break;
  289.       }      
  290.       if (myOp->setValue("PNUM2", 88)) {
  291. error_handler4(__LINE__, myTrans->getNdbError());
  292. myNdb.closeTransaction(myTrans);
  293. break;
  294.       }      
  295.       if (myOp->setValue("PNUM4", 99)) {
  296. error_handler4(__LINE__, myTrans->getNdbError());
  297. myNdb.closeTransaction(myTrans);
  298. break;
  299.       }      
  300.       if (myOp->setValue("AGE", 100) == -1) {
  301. error_handler4(__LINE__, myTrans->getNdbError());
  302. myNdb.closeTransaction(myTrans);
  303. break;
  304.       }      
  305.       if (myOp->setValue("STRING_AGE", hundred) == -1) {
  306. error_handler4(__LINE__, myTrans->getNdbError());
  307. myNdb.closeTransaction(myTrans);
  308. break;
  309.       }
  310.     }
  311.     if (noOfOperations == 1)
  312.       printf("Trying to update person %sn", name);
  313.     else
  314.       printf("Trying to update %u personsn", noOfOperations);
  315.       before = NdbTick_CurrentMillisecond();
  316.       if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  317. {
  318.   error_handler4(__LINE__, myTrans->getNdbError());
  319.   myNdb.closeTransaction(myTrans);
  320.   break;
  321. }
  322.       after = NdbTick_CurrentMillisecond();
  323.       if (noOfOperations == 1)
  324. printf("Updated person %s, %u msecn", name, (Uint32) after - before);
  325.       else
  326. printf("Update %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  327.       if (!oneTrans) myNdb.closeTransaction(myTrans);
  328.   }     
  329.   if (oneTrans) {
  330.     if (myTrans->execute( Commit ) == -1) {
  331.       error_handler4(__LINE__, myTrans->getNdbError());
  332.     }
  333.     myNdb.closeTransaction(myTrans);
  334.   }
  335.   tafter = NdbTick_CurrentMillisecond();
  336.   
  337.   ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  338. }
  339. static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
  340. {
  341.   Uint64 tbefore, tafter, before, after;
  342.   NdbConnection  *myTrans;  
  343.   NdbOperation   *myOp;   
  344.   char name[] = "Kalle0000000";
  345.   
  346.   tbefore = NdbTick_CurrentMillisecond();
  347.   if (oneTrans) myTrans = myNdb.startTransaction();
  348.   for (unsigned int i = 0; i<noOfTuples; i++) {
  349.     if (!oneTrans) myTrans = myNdb.startTransaction();
  350.     for(unsigned int j = 1; 
  351. ((j<=noOfOperations)&&(i<noOfTuples)); 
  352. (++j<=noOfOperations)?i++:i) { 
  353.       if (myTrans == NULL) 
  354.         error_handler4(__LINE__, myNdb.getNdbError());
  355.       
  356.       myOp = myTrans->getNdbOperation("PERSON"); 
  357.       if (myOp == NULL) 
  358.         error_handler4(__LINE__, myTrans->getNdbError());
  359.       
  360.       myOp->deleteTuple();
  361.       sprintf(name, "Kalle%.7i", i);
  362.       if (longKey)
  363.         memcpy(longName, name, strlen(name)); 
  364.       if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  365.         error_handler4(__LINE__, myTrans->getNdbError());
  366.         myNdb.closeTransaction(myTrans);
  367.         break;
  368.       }      
  369.       if (twoKey)
  370.         if (myOp->equal("KEY2", i) == -1) {
  371.           error_handler4(__LINE__, myTrans->getNdbError());
  372.           myNdb.closeTransaction(myTrans);
  373.           break;
  374.         }      
  375.     }
  376.     if (noOfOperations == 1)
  377.       printf("Trying to delete person %sn", name);
  378.     else
  379.       printf("Trying to delete %u personsn", noOfOperations);
  380.     before = NdbTick_CurrentMillisecond();
  381.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  382.       {
  383.         error_handler4(__LINE__, myTrans->getNdbError());
  384.         myNdb.closeTransaction(myTrans);
  385.         break;
  386.       }
  387.     after = NdbTick_CurrentMillisecond();
  388.     if (noOfOperations == 1)
  389.       printf("Deleted person %s, %u msecn", name, (Uint32) after - before);
  390.     else
  391.       printf("Deleted %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  392.     
  393.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  394.   }
  395.   if (oneTrans) {
  396.     if (myTrans->execute( Commit ) == -1) {
  397.       error_handler4(__LINE__, myTrans->getNdbError());
  398.     }
  399.     myNdb.closeTransaction(myTrans);
  400.   }
  401.   tafter = NdbTick_CurrentMillisecond();
  402.   ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  403. }
  404. static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
  405. {
  406.   Uint64 tbefore, tafter, before, after;
  407.   NdbConnection  *myTrans;  
  408.   NdbOperation   *myOp;   
  409.   char name[] = "Kalle0000000";
  410.   NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
  411.   
  412.   tbefore = NdbTick_CurrentMillisecond();
  413.   if (oneTrans) myTrans = myNdb.startTransaction();
  414.   for (unsigned int i = 0; i<noOfTuples; i++) {
  415.     if (!oneTrans) myTrans = myNdb.startTransaction();
  416.     for(unsigned int j = 1; 
  417. ((j<=noOfOperations)&&(i<noOfTuples)); 
  418. (++j<=noOfOperations)?i++:i) { 
  419.       if (myTrans == NULL) 
  420.         error_handler4(__LINE__, myNdb.getNdbError());
  421.       
  422.       myOp = myTrans->getNdbOperation("PERSON"); 
  423.       if (myOp == NULL) 
  424.         error_handler4(__LINE__, myTrans->getNdbError());
  425.       
  426.       myOp->readTuple();
  427.       sprintf(name, "Kalle%.7i", i);
  428.       if (longKey)
  429.         memcpy(longName, name, strlen(name)); 
  430.       if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  431.         error_handler4(__LINE__, myTrans->getNdbError());
  432.         myNdb.closeTransaction(myTrans);
  433.         break;
  434.       }         
  435.       if (twoKey)
  436.         if (myOp->equal("KEY2", i) == -1) {
  437.           error_handler4(__LINE__, myTrans->getNdbError());
  438.           myNdb.closeTransaction(myTrans);
  439.           break;
  440.         }      
  441.       myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL);
  442.     }
  443.     if (noOfOperations == 1)
  444.       printf("Trying to read person %sn", name);
  445.     else
  446.       printf("Trying to read %u personsn", noOfOperations);
  447.     before = NdbTick_CurrentMillisecond();
  448.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  449.       {
  450.         error_handler4(__LINE__, myTrans->getNdbError());
  451.         myNdb.closeTransaction(myTrans);
  452.         break;
  453.       }
  454.     after = NdbTick_CurrentMillisecond();
  455.     if (noOfOperations == 1)
  456.       printf("Read person %s, %u msecn", name, (Uint32) after - before);
  457.     else
  458.       printf("Read %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  459.     for(unsigned int j = 0; j<noOfOperations; j++)
  460.       printf("PNUM2 = %un", myRecAttrArr[j]->u_32_value());
  461.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  462.   }
  463.   if (oneTrans) {
  464.     if (myTrans->execute( Commit ) == -1) {
  465.       error_handler4(__LINE__, myTrans->getNdbError());
  466.     }
  467.     myNdb.closeTransaction(myTrans);
  468.   }
  469.   tafter = NdbTick_CurrentMillisecond();
  470.   ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  471. }
  472. static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
  473. {
  474.   Uint64 tbefore, tafter, before, after;
  475.   NdbConnection  *myTrans;  
  476.   NdbIndexOperation   *myOp; 
  477.   char indexName[] = "PNUMINDEX0000";
  478.   char name[] = "Kalle0000000";
  479.   NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
  480.   
  481.   tbefore = NdbTick_CurrentMillisecond();
  482.   if (oneTrans) myTrans = myNdb.startTransaction();
  483.   for (unsigned int i = 0; i<noOfTuples; i++) {
  484.     if (!oneTrans) myTrans = myNdb.startTransaction();
  485.     for(unsigned int j = 1; 
  486. ((j<=noOfOperations)&&(i<noOfTuples)); 
  487. (++j<=noOfOperations)?i++:i) { 
  488.       if (myTrans == NULL) 
  489.         error_handler4(__LINE__, myNdb.getNdbError());
  490.       
  491.       myOp = myTrans->getNdbIndexOperation(indexName, "PERSON"); 
  492.       if (myOp == NULL) 
  493.         error_handler4(__LINE__, myTrans->getNdbError());
  494.       
  495.       myOp->readTuple();
  496.       if (includePrimary) {
  497.         sprintf(name, "Kalle%.7i", i);
  498.         if (longKey)
  499.           memcpy(longName, name, strlen(name)); 
  500.         if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  501.           error_handler4(__LINE__, myTrans->getNdbError());
  502.           myNdb.closeTransaction(myTrans);
  503.           break;
  504.         }         
  505.       } 
  506.       if (myOp->equal("PNUM1", 17) == -1) {
  507.         error_handler4(__LINE__, myTrans->getNdbError());
  508.         myNdb.closeTransaction(myTrans);
  509.         break;
  510.       }          
  511.       if (myOp->equal("PNUM3", 19) == -1) {
  512.         error_handler4(__LINE__, myTrans->getNdbError());
  513.         myNdb.closeTransaction(myTrans);
  514.         break;
  515.       }          
  516.       myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL);
  517.     }
  518.     if (noOfOperations == 1)
  519.       printf("Trying to read person %sn", name);
  520.     else
  521.       printf("Trying to read %u personsn", noOfOperations);
  522.     before = NdbTick_CurrentMillisecond();
  523.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  524.       {
  525.         error_handler4(__LINE__, myTrans->getNdbError());
  526.         myNdb.closeTransaction(myTrans);
  527.         break;
  528.       }
  529.     after = NdbTick_CurrentMillisecond();
  530.     if (noOfOperations == 1)
  531.       printf("Read person %s, %u msecn", name, (Uint32) after - before);
  532.     else
  533.       printf("Read %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  534.     for(unsigned int j = 0; j<noOfOperations; j++)
  535.       printf("PNUM2 = %un", myRecAttrArr[j]->u_32_value());
  536.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  537.   }
  538.   if (oneTrans) {
  539.     if (myTrans->execute( Commit ) == -1) {
  540.       error_handler4(__LINE__, myTrans->getNdbError());
  541.     }
  542.     myNdb.closeTransaction(myTrans);
  543.   }
  544.   tafter = NdbTick_CurrentMillisecond();
  545.   ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  546. }
  547. static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
  548. {
  549.   Uint64 tbefore, tafter, before, after;
  550.   NdbConnection  *myTrans;  
  551.   NdbIndexOperation   *myOp;   
  552.   char indexName[] = "PNUMINDEX0000";
  553.   char name[] = "Kalle0000000";
  554.   
  555.   tbefore = NdbTick_CurrentMillisecond();
  556.   if (oneTrans) myTrans = myNdb.startTransaction();
  557.   for (unsigned int i = 0; i<noOfTuples; i++) {
  558.     if (!oneTrans) myTrans = myNdb.startTransaction();
  559.     for(unsigned int j = 1; 
  560. ((j<=noOfOperations)&&(i<noOfTuples)); 
  561. (++j<=noOfOperations)?i++:i) { 
  562.       if (myTrans == NULL) 
  563.         error_handler4(__LINE__, myNdb.getNdbError());
  564.       
  565.       myOp = myTrans->getNdbIndexOperation(indexName, "PERSON"); 
  566.       if (myOp == NULL) 
  567.         error_handler4(__LINE__, myTrans->getNdbError());
  568.       
  569.       myOp->updateTuple();
  570.       if (includePrimary) {
  571.         sprintf(name, "Kalle%.7i", i);
  572.         if (longKey)
  573.           memcpy(longName, name, strlen(name)); 
  574.         if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  575.           error_handler4(__LINE__, myTrans->getNdbError());
  576.           myNdb.closeTransaction(myTrans);
  577.           break;
  578.         }         
  579.       } 
  580.       if (myOp->equal("PNUM1", 17) == -1) {
  581.         error_handler4(__LINE__, myTrans->getNdbError());
  582.         myNdb.closeTransaction(myTrans);
  583.         break;
  584.       } 
  585.       if (myOp->equal("PNUM3", 19) == -1) {
  586.         error_handler4(__LINE__, myTrans->getNdbError());
  587.         myNdb.closeTransaction(myTrans);
  588.         break;
  589.       }          
  590.       // Update index itself, should be possible
  591.       if (myOp->setValue("PNUM1", 77) == -1) {
  592.         error_handler4(__LINE__, myTrans->getNdbError());
  593.         myNdb.closeTransaction(myTrans);
  594.         break;
  595.       }      
  596.       if (myOp->setValue("PNUM2", 88)) {
  597.         error_handler4(__LINE__, myTrans->getNdbError());
  598.         myNdb.closeTransaction(myTrans);
  599.         break;
  600.       }      
  601.       if (myOp->setValue("PNUM4", 99)) {
  602.         error_handler4(__LINE__, myTrans->getNdbError());
  603.         myNdb.closeTransaction(myTrans);
  604.         break;
  605.       }      
  606.       if (myOp->setValue("AGE", 100) == -1) {
  607.         error_handler4(__LINE__, myTrans->getNdbError());
  608.         myNdb.closeTransaction(myTrans);
  609.         break;
  610.       }      
  611.       if (myOp->setValue("STRING_AGE", hundred) == -1) {
  612.         error_handler4(__LINE__, myTrans->getNdbError());
  613.         myNdb.closeTransaction(myTrans);
  614.         break;
  615.       }      
  616.     }
  617.     if (noOfOperations == 1)
  618.       printf("Trying to update person %sn", name);
  619.     else
  620.       printf("Trying to update %u personsn", noOfOperations);
  621.     before = NdbTick_CurrentMillisecond();
  622.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  623.       {
  624.         error_handler4(__LINE__, myTrans->getNdbError());
  625.         myNdb.closeTransaction(myTrans);
  626.         break;
  627.       }
  628.     after = NdbTick_CurrentMillisecond();
  629.     if (noOfOperations == 1)
  630.       printf("Updated person %s, %u msecn", name, (Uint32) after - before);
  631.     else
  632.       printf("Updated %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  633.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  634.   }
  635.   if (oneTrans) {
  636.     if (myTrans->execute( Commit ) == -1) {
  637.       error_handler4(__LINE__, myTrans->getNdbError());
  638.     }
  639.     myNdb.closeTransaction(myTrans);
  640.   }
  641.   tafter = NdbTick_CurrentMillisecond();
  642.   
  643.   ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  644. }
  645. static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
  646. {
  647.   Uint64 tbefore, tafter, before, after;
  648.   NdbConnection  *myTrans;  
  649.   NdbIndexOperation   *myOp;   
  650.   char indexName[] = "PNUMINDEX0000";
  651.   char name[] = "Kalle0000000";
  652.   
  653.   tbefore = NdbTick_CurrentMillisecond();
  654.   if (oneTrans) myTrans = myNdb.startTransaction();
  655.   for (unsigned int i = 0; i<noOfTuples; i++) {
  656.     for(unsigned int j = 1; 
  657. ((j<=noOfOperations)&&(i<noOfTuples)); 
  658. (++j<=noOfOperations)?i++:i) { 
  659.       if (!oneTrans) myTrans = myNdb.startTransaction();
  660.       if (myTrans == NULL) 
  661.         error_handler4(__LINE__, myNdb.getNdbError());
  662.       
  663.       myOp = myTrans->getNdbIndexOperation(indexName, "PERSON"); 
  664.       if (myOp == NULL) 
  665.         error_handler4(__LINE__, myTrans->getNdbError());
  666.       
  667.       myOp->deleteTuple();
  668.       if (includePrimary) {
  669.         sprintf(name, "Kalle%.7i", i);
  670.         if (longKey)
  671.           memcpy(longName, name, strlen(name)); 
  672.         if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
  673.           error_handler4(__LINE__, myTrans->getNdbError());
  674.           myNdb.closeTransaction(myTrans);
  675.           break;
  676.         }         
  677.       } 
  678.       if (myOp->equal("PNUM1", 17) == -1) {
  679.         error_handler4(__LINE__, myTrans->getNdbError());
  680.       myNdb.closeTransaction(myTrans);
  681.       break;
  682.       }          
  683.       if (myOp->equal("PNUM3", 19) == -1) {
  684.         error_handler4(__LINE__, myTrans->getNdbError());
  685.         myNdb.closeTransaction(myTrans);
  686.         break;
  687.       }       
  688.     }
  689.     if (noOfOperations == 1)
  690.       printf("Trying to delete person %sn", name);
  691.     else
  692.       printf("Trying to delete %u personsn", noOfOperations);
  693.     before = NdbTick_CurrentMillisecond();
  694.     if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
  695.       {
  696.         error_handler4(__LINE__, myTrans->getNdbError());
  697.         myNdb.closeTransaction(myTrans);
  698.         break;
  699.       }
  700.     after = NdbTick_CurrentMillisecond();
  701.     if (noOfOperations == 1)
  702.       printf("Deleted person %s, %u msecn", name, (Uint32) after - before);
  703.     else
  704.       printf("Deleted %u persons, %u msecn", noOfOperations, (Uint32) after - before);
  705.     if (!oneTrans) myNdb.closeTransaction(myTrans);
  706.   }
  707.   if (oneTrans) {
  708.     if (myTrans->execute( Commit ) == -1) {
  709.       error_handler4(__LINE__, myTrans->getNdbError());
  710.     }
  711.     myNdb.closeTransaction(myTrans);
  712.   }
  713.   tafter = NdbTick_CurrentMillisecond();
  714.   ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;        
  715. }
  716. static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes)
  717. {
  718.   for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
  719.     char indexName[255];
  720.     sprintf(indexName, "PNUMINDEX%.4u", indexNum);
  721.     const Uint64 before = NdbTick_CurrentMillisecond();
  722.     const int retVal = myNdb.getDictionary()->dropIndex(indexName, "PERSON");
  723.     const Uint64 after = NdbTick_CurrentMillisecond();
  724.     
  725.     if(retVal == 0){
  726.       ndbout << "Dropped index " << indexName << ", " 
  727.      << after - before << " msec" << endl;
  728.     } else {
  729.       ndbout << "Failed to drop index " << indexName << endl;
  730.       ndbout << myNdb.getDictionary()->getNdbError() << endl;
  731.     }
  732.   }
  733. }
  734. NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535)
  735. {
  736.   ndb_init();
  737.   bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey;
  738.   unsigned int noOfTuples = 1;
  739.   unsigned int noOfOperations = 1;
  740.   unsigned int noOfIndexes = 1;
  741.   int i = 1;
  742.   Ndb myNdb( "TEST_DB" );
  743.   int check;
  744.   bool storeInACC = false;
  745.   bool includePrimary = false;
  746.   bool oneTransaction = false;
  747.   createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false;
  748.   // Read arguments
  749.   if (argc > 1)
  750.     while (argc > 1)
  751.       {
  752. if (strcmp(argv[i], "-T") == 0)
  753.   {
  754.     createTableOp = true;
  755.     argc -= 1;
  756.     i++;
  757.   }
  758. else if (strcmp(argv[i], "-c") == 0)
  759.   {
  760.     createIndexOp = true;
  761.     argc -= 1;
  762.     i++;
  763.   }
  764. else if (strcmp(argv[i], "-X") == 0)
  765.   {
  766.     dropIndexOp = true;
  767.     argc -= 1;
  768.     i++;
  769.   }
  770. else if (strcmp(argv[i], "-I") == 0)
  771.   {
  772.     insertOp = true;
  773.     argc -= 1;
  774.     i++;
  775.   }
  776. else if (strcmp(argv[i], "-D") == 0)
  777.   {
  778.     deleteOp = true;
  779.     argc -= 1;
  780.     i++;
  781.   }
  782. else if (strcmp(argv[i], "-U") == 0)
  783.   {
  784.     updateOp = true;
  785.     argc -= 1;
  786.     i++;
  787.   }
  788. else if (strcmp(argv[i], "-R") == 0)
  789.   {
  790.     readOp = true;
  791.     argc -= 1;
  792.     i++;
  793.   }
  794. else if (strcmp(argv[i], "-r") == 0)
  795.   {
  796.     readIndexOp = true;
  797.     argc -= 1;
  798.     i++;
  799.   }
  800. else if (strcmp(argv[i], "-u") == 0)
  801.   {
  802.     updateIndexOp = true;
  803.     argc -= 1;
  804.     i++;
  805.   }
  806. else if (strcmp(argv[i], "-d") == 0)
  807.   {
  808.     deleteIndexOp = true;
  809.     argc -= 1;
  810.     i++;
  811.   }
  812. else if (strcmp(argv[i], "-s") == 0)
  813.   {
  814.     storeInACC = true;
  815.     argc -= 1;
  816.     i++;
  817.   }
  818. else if (strcmp(argv[i], "-p") == 0)
  819.   {
  820.     includePrimary = true;
  821.     argc -= 1;
  822.     i++;
  823.   }
  824. else if (strcmp(argv[i], "-L") == 0)
  825.   {
  826.     longKey = true;
  827.     argc -= 1;
  828.     i++;
  829.   }
  830.   else if (strcmp(argv[i], "-1") == 0)
  831.   {
  832.     oneTransaction = true;
  833.     argc -= 1;
  834.     i++;
  835.   }       
  836.   else if (strcmp(argv[i], "-2") == 0)
  837.   {
  838.     twoKey = true;
  839.     argc -= 1;
  840.     i++;
  841.   }       
  842.         else if (strstr(argv[i], "-n") != 0)
  843.           {
  844.             noOfTuples = atoi(argv[i]+2);
  845.             argc -= 1;
  846.             i++;
  847.           }
  848.         else if (strstr(argv[i], "-o") != 0)
  849.           {
  850.             noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2));
  851.             argc -= 1;
  852.             i++;
  853.           }
  854.         else if (strstr(argv[i], "-m") != 0)
  855.           {
  856.             noOfIndexes = atoi(argv[i]+2);
  857.             argc -= 1;
  858.             i++;
  859.           }
  860. else if (strstr(argv[i], "-h") != 0)
  861.           {
  862.     printf("Synopsis:n");
  863.     printf("indexn");
  864.     printf("t-T create tablen");
  865.             printf("t-L include a long attribute in key or indexn");
  866.             printf("t-2 define primary key with two attributesn");
  867.             printf("t-c create indexn");
  868.     printf("t-p make index unique (include primary key attribute)n");
  869.             printf("t-r read using indexn");
  870.     printf("t-u update using indexn");
  871.     printf("t-d delete using indexn");
  872.     printf("t-n<no operations> do n operations (for -I -r -u -d -R -U -D)n");
  873.     printf("t-o<no parallel operations> (for -I -r -u -d -R -U -D)n");
  874.     printf("t-m<no indexes>n");
  875.             argc -= 1;
  876.             i++;
  877.   }
  878. else {
  879.   char errStr[256];
  880.   printf(errStr, "Illegal argument: %s", argv[i]);
  881.   exit(-1);
  882. }
  883.       }
  884.   else
  885.     {
  886.       createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true;
  887.     }
  888.   if (longKey) {
  889.     longName = (char *)  malloc(1024);
  890.     for (int i = 0; i < 1023; i++)
  891.       longName[i] = 'x'; 
  892.     longName[1023] = '';
  893.   }
  894.   sixtysix = (char *)  malloc(256);
  895.   for (int i = 0; i < 255; i++)
  896.     sixtysix[i] = ' '; 
  897.   sixtysix[255] = '';
  898.   strncpy(sixtysix, "sixtysix", strlen("sixtysix"));
  899.   ninetynine = (char *)  malloc(256);
  900.   for (int i = 0; i < 255; i++)
  901.     ninetynine[i] = ' '; 
  902.   ninetynine[255] = '';
  903.   strncpy(ninetynine, "ninetynine", strlen("ninetynine"));
  904.   hundred = (char *)  malloc(256);
  905.   for (int i = 0; i < 255; i++)
  906.     hundred[i] = ' '; 
  907.   hundred[255] = '';
  908.   strncpy(hundred, "hundred", strlen("hundred"));
  909.   myNdb.init();
  910.   // Wait for Ndb to become ready
  911.   if (myNdb.waitUntilReady(30) == 0)
  912.   {
  913.     if (createTableOp)
  914.       createTable(myNdb, storeInACC, twoKey, longKey);
  915.     if (createIndexOp)
  916.       createIndex(myNdb, includePrimary, noOfIndexes);
  917.     if (insertOp)
  918.       insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
  919.     if (updateOp)
  920.       updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
  921.     if (deleteOp)
  922.       deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
  923.     if (readOp)
  924.       readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
  925.     if (readIndexOp)
  926.       readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
  927.     if (updateIndexOp)
  928.       updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
  929.     if (deleteIndexOp)
  930.       deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
  931.     if (dropIndexOp)
  932.       dropIndex(myNdb, noOfIndexes);
  933.   }
  934.   
  935.   if (testPassed)
  936.     {
  937.       // Test passed
  938.       ndbout << "OK - Test passed" << endl;
  939.     }
  940.   else
  941.     {
  942.       // Test failed
  943.       ndbout << "FAIL - Test failed" << endl;
  944.       exit(-1);
  945.     }
  946.   return 0;
  947. }