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

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. #include <HugoOperations.hpp>
  14. int HugoOperations::startTransaction(Ndb* pNdb){
  15.   
  16.   if (pTrans != NULL){
  17.     ndbout << "HugoOperations::startTransaction, pTrans != NULL" << endl;
  18.     return NDBT_FAILED;
  19.   }
  20.   pTrans = pNdb->startTransaction();
  21.   if (pTrans == NULL) {
  22.     const NdbError err = pNdb->getNdbError();
  23.     ERR(err);
  24.     return NDBT_FAILED;
  25.   }
  26.   return NDBT_OK;
  27. }
  28. void 
  29. HugoOperations::setTransactionId(Uint64 id){
  30.   if (pTrans != NULL){
  31.     pTrans->setTransactionId(id);
  32.   }
  33. }
  34. int HugoOperations::closeTransaction(Ndb* pNdb){
  35.   if (pTrans != NULL){
  36.     pNdb->closeTransaction(pTrans);
  37.     pTrans = NULL;
  38.   }
  39.   pTrans = NULL;
  40.   m_result_sets.clear();
  41.   m_executed_result_sets.clear();
  42.   return NDBT_OK;
  43. }
  44. NdbConnection* HugoOperations::getTransaction(){
  45.   return pTrans;
  46. }
  47. int HugoOperations::pkReadRecord(Ndb* pNdb,
  48.  int recordNo,
  49.  int numRecords,
  50.  NdbOperation::LockMode lm){
  51.   int a;  
  52.   allocRows(numRecords);
  53.   int check;
  54.   for(int r=0; r < numRecords; r++){
  55.     NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
  56.     if (pOp == NULL) {
  57.       ERR(pTrans->getNdbError());
  58.       return NDBT_FAILED;
  59.     }
  60.     
  61. rand_lock_mode:
  62.     switch(lm){
  63.     case NdbOperation::LM_Read:
  64.       check = pOp->readTuple();
  65.       break;
  66.     case NdbOperation::LM_Exclusive:
  67.       check = pOp->readTupleExclusive();
  68.       break;
  69.     case NdbOperation::LM_CommittedRead:
  70.       check = pOp->dirtyRead();
  71.       break;
  72.     default:
  73.       lm = (NdbOperation::LockMode)((rand() >> 16) & 3);
  74.       goto rand_lock_mode;
  75.     }
  76.     
  77.     if( check == -1 ) {
  78.       ERR(pTrans->getNdbError());
  79.       return NDBT_FAILED;
  80.     }
  81.     
  82.     // Define primary keys
  83.     for(a = 0; a<tab.getNoOfColumns(); a++){
  84.       if (tab.getColumn(a)->getPrimaryKey() == true){
  85. if(equalForAttr(pOp, a, r+recordNo) != 0){
  86.   ERR(pTrans->getNdbError());
  87.   return NDBT_FAILED;
  88. }
  89.       }
  90.     }
  91.     
  92.     // Define attributes to read  
  93.     for(a = 0; a<tab.getNoOfColumns(); a++){
  94.       if((rows[r]->attributeStore(a) = 
  95.   pOp->getValue(tab.getColumn(a)->getName())) == 0) {
  96. ERR(pTrans->getNdbError());
  97. return NDBT_FAILED;
  98.       }
  99.     } 
  100.   }
  101.   return NDBT_OK;
  102. }
  103. int HugoOperations::pkUpdateRecord(Ndb* pNdb,
  104.    int recordNo,
  105.    int numRecords,
  106.    int updatesValue){
  107.   int a; 
  108.   allocRows(numRecords);
  109.   int check;
  110.   for(int r=0; r < numRecords; r++){
  111.     NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
  112.     if (pOp == NULL) {
  113.       ERR(pTrans->getNdbError());
  114.       return NDBT_FAILED;
  115.     }
  116.     
  117.     check = pOp->updateTuple();
  118.     if( check == -1 ) {
  119.       ERR(pTrans->getNdbError());
  120.       return NDBT_FAILED;
  121.     }
  122.     
  123.     // Define primary keys
  124.     for(a = 0; a<tab.getNoOfColumns(); a++){
  125.       if (tab.getColumn(a)->getPrimaryKey() == true){
  126. if(equalForAttr(pOp, a, r+recordNo) != 0){
  127.   ERR(pTrans->getNdbError());
  128.   return NDBT_FAILED;
  129. }
  130.       }
  131.     }
  132.     
  133.     // Define attributes to update
  134.     for(a = 0; a<tab.getNoOfColumns(); a++){
  135.       if (tab.getColumn(a)->getPrimaryKey() == false){
  136. if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ 
  137.   ERR(pTrans->getNdbError());
  138.   return NDBT_FAILED;
  139. }
  140.       }
  141.     } 
  142.   }
  143.   return NDBT_OK;
  144. }
  145. int HugoOperations::pkInsertRecord(Ndb* pNdb,
  146.    int recordNo,
  147.    int numRecords,
  148.    int updatesValue){
  149.   
  150.   int a, check;
  151.   for(int r=0; r < numRecords; r++){
  152.     NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
  153.     if (pOp == NULL) {
  154.       ERR(pTrans->getNdbError());
  155.       return NDBT_FAILED;
  156.     }
  157.     
  158.     check = pOp->insertTuple();
  159.     if( check == -1 ) {
  160.       ERR(pTrans->getNdbError());
  161.       return NDBT_FAILED;
  162.     }
  163.     
  164.     // Define primary keys
  165.     for(a = 0; a<tab.getNoOfColumns(); a++){
  166.       if (tab.getColumn(a)->getPrimaryKey() == true){
  167. if(equalForAttr(pOp, a, r+recordNo) != 0){
  168.   ERR(pTrans->getNdbError());
  169.   return NDBT_FAILED;
  170. }
  171.       }
  172.     }
  173.     
  174.     // Define attributes to update
  175.     for(a = 0; a<tab.getNoOfColumns(); a++){
  176.       if (tab.getColumn(a)->getPrimaryKey() == false){
  177. if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ 
  178.   ERR(pTrans->getNdbError());
  179.   return NDBT_FAILED;
  180. }
  181.       }
  182.     } 
  183.   }
  184.   return NDBT_OK;
  185. }
  186. int HugoOperations::pkWriteRecord(Ndb* pNdb,
  187.   int recordNo,
  188.   int numRecords,
  189.   int updatesValue){
  190.   
  191.   int a, check;
  192.   for(int r=0; r < numRecords; r++){
  193.     NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
  194.     if (pOp == NULL) {
  195.       ERR(pTrans->getNdbError());
  196.       return NDBT_FAILED;
  197.     }
  198.     
  199.     check = pOp->writeTuple();
  200.     if( check == -1 ) {
  201.       ERR(pTrans->getNdbError());
  202.       return NDBT_FAILED;
  203.     }
  204.     
  205.     // Define primary keys
  206.     for(a = 0; a<tab.getNoOfColumns(); a++){
  207.       if (tab.getColumn(a)->getPrimaryKey() == true){
  208. if(equalForAttr(pOp, a, r+recordNo) != 0){
  209.   ERR(pTrans->getNdbError());
  210.   return NDBT_FAILED;
  211. }
  212.       }
  213.     }
  214.     
  215.     // Define attributes to update
  216.     for(a = 0; a<tab.getNoOfColumns(); a++){
  217.       if (tab.getColumn(a)->getPrimaryKey() == false){
  218. if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ 
  219.   ERR(pTrans->getNdbError());
  220.   return NDBT_FAILED;
  221. }
  222.       }
  223.     } 
  224.   }
  225.   return NDBT_OK;
  226. }
  227. int HugoOperations::pkDeleteRecord(Ndb* pNdb,
  228.    int recordNo,
  229.    int numRecords){
  230.   
  231.   int a, check;
  232.   for(int r=0; r < numRecords; r++){
  233.     NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
  234.     if (pOp == NULL) {
  235.       ERR(pTrans->getNdbError());
  236.       return NDBT_FAILED;
  237.     }
  238.     
  239.     check = pOp->deleteTuple();
  240.     if( check == -1 ) {
  241.       ERR(pTrans->getNdbError());
  242.       return NDBT_FAILED;
  243.     }
  244.     
  245.     // Define primary keys
  246.     for(a = 0; a<tab.getNoOfColumns(); a++){
  247.       if (tab.getColumn(a)->getPrimaryKey() == true){
  248. if(equalForAttr(pOp, a, r+recordNo) != 0){
  249.   ERR(pTrans->getNdbError());
  250.   return NDBT_FAILED;
  251. }
  252.       }
  253.     }
  254.   }
  255.   return NDBT_OK;
  256. }
  257. #if 0
  258. NdbResultSet*
  259. HugoOperations::scanReadRecords(Ndb* pNdb, ScanLock lock){
  260.   
  261.   NDBT_ResultRow * m_tmpRow = new NDBT_ResultRow(tab);
  262.   NdbScanOperation* pOp = pTrans->getNdbScanOperation(tab.getName());
  263.   if (pOp == NULL) {
  264.     ERR(pTrans->getNdbError());
  265.     return 0;
  266.   }
  267.   
  268.   int check = 0;
  269.   NdbResultSet * rs = 0;
  270.   switch(lock){
  271.   case SL_ReadHold:
  272.     rs = pOp->readTuples(NdbScanOperation::LM_Read, 1, 1);
  273.     break;
  274.   case SL_Exclusive:
  275.     rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, 1, 1);
  276.     break;
  277.   case SL_Read:
  278.   default:
  279.     rs = pOp->readTuples(NdbScanOperation::LM_Dirty, 1, 1);
  280.   }
  281.   
  282.   if( rs == 0) {
  283.     ERR(pTrans->getNdbError());
  284.     return 0;
  285.   }
  286.   
  287.   check = pOp->interpret_exit_ok();
  288.   if( check == -1 ) {
  289.     ERR(pTrans->getNdbError());
  290.     return 0;
  291.   }
  292.   
  293.   // Define attributes to read  
  294.   for(int a = 0; a<tab.getNoOfColumns(); a++){
  295.     if((m_tmpRow->attributeStore(a) = 
  296. pOp->getValue(tab.getColumn(a)->getName())) == 0) {
  297.       ERR(pTrans->getNdbError());
  298.       return 0;
  299.     }
  300.   } 
  301.   return rs;
  302. }
  303. int
  304. HugoOperations::readTuples(NdbResultSet* rs){
  305.   int res = 0;
  306.   while((res = rs->nextResult()) == 0){
  307.   }
  308.   if(res != 1)
  309.     return NDBT_FAILED;
  310.   return NDBT_OK;
  311. }
  312. #endif
  313. int HugoOperations::execute_Commit(Ndb* pNdb,
  314.    AbortOption eao){
  315.   int check = 0;
  316.   check = pTrans->execute(Commit, eao);   
  317.   if( check == -1 ) {
  318.     const NdbError err = pTrans->getNdbError();
  319.     ERR(err);
  320.     NdbOperation* pOp = pTrans->getNdbErrorOperation();
  321.     if (pOp != NULL){
  322.       const NdbError err2 = pOp->getNdbError();
  323.       ERR(err2);
  324.     }
  325.     if (err.code == 0)
  326.       return NDBT_FAILED;
  327.     return err.code;
  328.   }
  329.   for(int i = 0; i<m_result_sets.size(); i++){
  330.     m_executed_result_sets.push_back(m_result_sets[i]);
  331.     int rows = m_result_sets[i].records;
  332.     NdbResultSet* rs = m_result_sets[i].m_result_set;
  333.     int res = rs->nextResult();
  334.     switch(res){
  335.     case 1:
  336.       return 626;
  337.     case -1:
  338.       const NdbError err = pTrans->getNdbError();
  339.       ERR(err);
  340.       return (err.code > 0 ? err.code : NDBT_FAILED);
  341.     }
  342.     // A row found
  343.     switch(rows){
  344.     case 0:
  345.       return 4000;
  346.     default:
  347.       m_result_sets[i].records--;
  348.       break;
  349.     }
  350.   }
  351.   m_result_sets.clear();
  352.   
  353.   return NDBT_OK;
  354. }
  355. int HugoOperations::execute_NoCommit(Ndb* pNdb, AbortOption eao){
  356.   int check;
  357.   check = pTrans->execute(NoCommit, eao);   
  358.   if( check == -1 ) {
  359.     const NdbError err = pTrans->getNdbError();
  360.     ERR(err);
  361.     NdbOperation* pOp;
  362.     while ((pOp = pTrans->getNdbErrorOperation()) != NULL){
  363.       const NdbError err2 = pOp->getNdbError();
  364.       ERR(err2);
  365.     }
  366.     if (err.code == 0)
  367.       return NDBT_FAILED;
  368.     return err.code;
  369.   }
  370.   for(int i = 0; i<m_result_sets.size(); i++){
  371.     m_executed_result_sets.push_back(m_result_sets[i]);
  372.     int rows = m_result_sets[i].records;
  373.     NdbResultSet* rs = m_result_sets[i].m_result_set;
  374.     int res = rs->nextResult();
  375.     switch(res){
  376.     case 1:
  377.       return 626;
  378.     case -1:
  379.       const NdbError err = pTrans->getNdbError();
  380.       ERR(err);
  381.       return (err.code > 0 ? err.code : NDBT_FAILED);
  382.     }
  383.     // A row found
  384.     switch(rows){
  385.     case 0:
  386.       return 4000;
  387.     default:
  388.     case 1:
  389.       break;
  390.     }
  391.   }
  392.   m_result_sets.clear();
  393.   return NDBT_OK;
  394. }
  395. int HugoOperations::execute_Rollback(Ndb* pNdb){
  396.   int check;
  397.   check = pTrans->execute(Rollback);   
  398.   if( check == -1 ) {
  399.     const NdbError err = pTrans->getNdbError();
  400.     ERR(err);
  401.     return NDBT_FAILED;
  402.   }
  403.   return NDBT_OK;
  404. }
  405. void
  406. HugoOperations_async_callback(int res, NdbConnection* pCon, void* ho)
  407. {
  408.   ((HugoOperations*)ho)->callback(res, pCon);
  409. }
  410. void
  411. HugoOperations::callback(int res, NdbConnection* pCon)
  412. {
  413.   assert(pCon == pTrans);
  414.   m_async_reply= 1;
  415.   m_async_return= res;
  416. }
  417. int 
  418. HugoOperations::execute_async(Ndb* pNdb, ExecType et, AbortOption eao){
  419.   
  420.   m_async_reply= 0;
  421.   pTrans->executeAsynchPrepare(et,
  422.        HugoOperations_async_callback,
  423.        this,
  424.        eao);
  425.   
  426.   pNdb->sendPreparedTransactions();
  427.   
  428.   return NDBT_OK;
  429. }
  430. int
  431. HugoOperations::wait_async(Ndb* pNdb, int timeout)
  432. {
  433.   pNdb->pollNdb(1000);
  434.   if(m_async_reply)
  435.   {
  436.     return m_async_return;
  437.   }
  438.   ndbout_c("wait returned nothing...");
  439.   return -1;
  440. }
  441. HugoOperations::HugoOperations(const NdbDictionary::Table& _tab):
  442.   UtilTransactions(_tab),
  443.   calc(_tab),
  444.   pTrans(NULL)
  445. {
  446. }
  447. HugoOperations::~HugoOperations(){
  448.   deallocRows();
  449.   if (pTrans != NULL)
  450.   {
  451.     pTrans->close();
  452.     pTrans = NULL;
  453.   }
  454. }
  455. int HugoOperations::equalForAttr(NdbOperation* pOp,
  456.    int attrId, 
  457.    int rowId){
  458.   int check = 0;
  459.   const NdbDictionary::Column* attr = tab.getColumn(attrId);  
  460.   if (attr->getPrimaryKey() == false){
  461.     g_info << "Can't call equalForAttr on non PK attribute" << endl;
  462.     return NDBT_FAILED;
  463.   }
  464.     
  465.   switch (attr->getType()){
  466.   case NdbDictionary::Column::Char:
  467.   case NdbDictionary::Column::Varchar:
  468.   case NdbDictionary::Column::Binary:
  469.   case NdbDictionary::Column::Varbinary:{
  470.     char buf[8000];
  471.     memset(buf, 0, sizeof(buf));
  472.     check = pOp->equal( attr->getName(), calc.calcValue(rowId, attrId, 0, buf));
  473.     break;
  474.   }
  475.   case NdbDictionary::Column::Int:
  476.     check = pOp->equal( attr->getName(), (Int32)calc.calcValue(rowId, attrId, 0));
  477.     break;
  478.   case NdbDictionary::Column::Unsigned:
  479.     check = pOp->equal( attr->getName(), (Uint32)calc.calcValue(rowId, attrId, 0));
  480.     break;
  481.   case NdbDictionary::Column::Bigint:
  482.     check = pOp->equal( attr->getName(), (Int64)calc.calcValue(rowId, attrId, 0));
  483.     break;
  484.   case NdbDictionary::Column::Bigunsigned:    
  485.     check = pOp->equal( attr->getName(), (Uint64)calc.calcValue(rowId, attrId, 0));
  486.     break;
  487.   case NdbDictionary::Column::Float:
  488.     g_info << "Float not allowed as PK value" << endl;
  489.     check = -1;
  490.     break;
  491.     
  492.   default:
  493.     g_info << "default" << endl;
  494.     check = -1;
  495.     break;
  496.   }
  497.   return check;
  498. }
  499. int HugoOperations::setValueForAttr(NdbOperation* pOp,
  500.       int attrId, 
  501.       int rowId,
  502.       int updateId){
  503.   int check = 0;
  504.   const NdbDictionary::Column* attr = tab.getColumn(attrId);     
  505.   if (attr->getTupleKey()){
  506.     // Don't set values for TupleId PKs
  507.     return check;
  508.   }
  509.   
  510.   switch (attr->getType()){
  511.   case NdbDictionary::Column::Char:
  512.   case NdbDictionary::Column::Varchar:
  513.   case NdbDictionary::Column::Binary:
  514.   case NdbDictionary::Column::Varbinary:{
  515.     char buf[8000];
  516.     check = pOp->setValue( attr->getName(), 
  517.    calc.calcValue(rowId, attrId, updateId, buf));
  518.     break;
  519.   }
  520.   case NdbDictionary::Column::Int:{
  521.     Int32 val = calc.calcValue(rowId, attrId, updateId);
  522.     check = pOp->setValue( attr->getName(), val);
  523.   }
  524.     break;
  525.   case NdbDictionary::Column::Bigint:{
  526.     Int64 val = calc.calcValue(rowId, attrId, updateId);
  527.     check = pOp->setValue( attr->getName(), 
  528.    val);
  529.   }
  530.     break;
  531.   case NdbDictionary::Column::Unsigned:{
  532.     Uint32 val = calc.calcValue(rowId, attrId, updateId);
  533.     check = pOp->setValue( attr->getName(), val);
  534.   }
  535.     break;
  536.   case NdbDictionary::Column::Bigunsigned:{
  537.     Uint64 val = calc.calcValue(rowId, attrId, updateId);
  538.     check = pOp->setValue( attr->getName(), 
  539.    val);
  540.   }
  541.     break;
  542.   case NdbDictionary::Column::Float:
  543.     check = pOp->setValue( attr->getName(), 
  544.    (float)calc.calcValue(rowId, attrId, updateId));
  545.     break;
  546.   default:
  547.     check = -1;
  548.     break;
  549.   }
  550.   return check;
  551. }
  552. int
  553. HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){
  554.   _numRows = (_numRows == 0 ? rows.size() : _numRows);
  555.   
  556.   int result = NDBT_OK;
  557.   
  558.   for(int i = 0; i<_numRows; i++){
  559.     if(calc.verifyRowValues(rows[i]) != NDBT_OK){
  560.       g_err << "Inconsistent row" 
  561.     << endl << "t" << rows[i]->c_str().c_str() << endl;
  562.       result = NDBT_FAILED;
  563.       continue;
  564.     }
  565.     if(calc.getUpdatesValue(rows[i]) != updatesValue){
  566.       result = NDBT_FAILED;
  567.       g_err << "Invalid updates value for row " << i << endl
  568.     << " updatesValue: " << updatesValue << endl
  569.     << " calc.getUpdatesValue: " << calc.getUpdatesValue(rows[i]) << endl 
  570.     << rows[i]->c_str().c_str() << endl;
  571.       continue;
  572.     }
  573.   }
  574.   if(_numRows == 0){
  575.     g_err << "No rows -> Invalid updates value" << endl;
  576.     return NDBT_FAILED;
  577.   }
  578.   return result;
  579. }
  580. void HugoOperations::allocRows(int _numRows){
  581.   deallocRows();
  582.   if(_numRows <= 0){
  583.     g_info << "Illegal value for num rows : " << _numRows << endl;
  584.     abort();
  585.   }
  586.   
  587.   for(int b=0; b<_numRows; b++){
  588.     rows.push_back(new NDBT_ResultRow(tab));
  589.   }
  590. }
  591. void HugoOperations::deallocRows(){
  592.   while(rows.size() > 0){
  593.     delete rows.back();
  594.     rows.erase(rows.size() - 1);
  595.   }
  596. }
  597. int HugoOperations::saveCopyOfRecord(int numRecords ){
  598.   if (numRecords > (int)rows.size())
  599.     return NDBT_FAILED;
  600.   for (int i = 0; i < numRecords; i++){
  601.     savedRecords.push_back(rows[i]->c_str());    
  602.   }
  603.   return NDBT_OK;  
  604. }
  605. BaseString HugoOperations::getRecordStr(int recordNum){
  606.   if (recordNum > (int)rows.size())
  607.     return NULL;
  608.   return rows[recordNum]->c_str();
  609. }
  610. int HugoOperations::getRecordGci(int recordNum){
  611.   return pTrans->getGCI();
  612. }
  613. int HugoOperations::compareRecordToCopy(int numRecords ){
  614.   if (numRecords > (int)rows.size())
  615.     return NDBT_FAILED;
  616.   if ((unsigned)numRecords > savedRecords.size())
  617.     return NDBT_FAILED;
  618.   int result = NDBT_OK;
  619.   for (int i = 0; i < numRecords; i++){
  620.     BaseString str = rows[i]->c_str();
  621.     ndbout << "row["<<i<<"]: " << str << endl;
  622.     ndbout << "sav["<<i<<"]: " << savedRecords[i] << endl;
  623.     if (savedRecords[i] == str){
  624.       ;
  625.     } else {
  626.       result = NDBT_FAILED;
  627.     }    
  628.   }
  629.   return result;
  630. }
  631. void
  632. HugoOperations::refresh() {
  633.   NdbConnection* t = getTransaction(); 
  634.   if(t)
  635.     t->refresh();
  636. }
  637. int HugoOperations::indexReadRecords(Ndb*, const char * idxName, int recordNo,
  638.      bool exclusive,
  639.      int numRecords){
  640.     
  641.   int a;
  642.   allocRows(numRecords);
  643.   int check;
  644.   for(int r=0; r < numRecords; r++){
  645.     NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
  646.     if (pOp == NULL) {
  647.       ERR(pTrans->getNdbError());
  648.       return NDBT_FAILED;
  649.     }
  650.     
  651.     if (exclusive == true)
  652.       check = pOp->readTupleExclusive();
  653.     else
  654.       check = pOp->readTuple();
  655.     if( check == -1 ) {
  656.       ERR(pTrans->getNdbError());
  657.       return NDBT_FAILED;
  658.     }
  659.     
  660.     // Define primary keys
  661.     for(a = 0; a<tab.getNoOfColumns(); a++){
  662.       if (tab.getColumn(a)->getPrimaryKey() == true){
  663. if(equalForAttr(pOp, a, r+recordNo) != 0){
  664.   ERR(pTrans->getNdbError());
  665.   return NDBT_FAILED;
  666. }
  667.       }
  668.     }
  669.     
  670.     // Define attributes to read  
  671.     for(a = 0; a<tab.getNoOfColumns(); a++){
  672.       if((rows[r]->attributeStore(a) = 
  673.   pOp->getValue(tab.getColumn(a)->getName())) == 0) {
  674. ERR(pTrans->getNdbError());
  675. return NDBT_FAILED;
  676.       }
  677.     } 
  678.   }
  679.   return NDBT_OK;
  680. }
  681. int 
  682. HugoOperations::indexUpdateRecord(Ndb*,
  683.   const char * idxName, 
  684.   int recordNo,
  685.   int numRecords,
  686.   int updatesValue){
  687.   int a; 
  688.   allocRows(numRecords);
  689.   int check;
  690.   for(int r=0; r < numRecords; r++){
  691.     NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
  692.     if (pOp == NULL) {
  693.       ERR(pTrans->getNdbError());
  694.       return NDBT_FAILED;
  695.     }
  696.     
  697.     check = pOp->updateTuple();
  698.     if( check == -1 ) {
  699.       ERR(pTrans->getNdbError());
  700.       return NDBT_FAILED;
  701.     }
  702.     
  703.     // Define primary keys
  704.     for(a = 0; a<tab.getNoOfColumns(); a++){
  705.       if (tab.getColumn(a)->getPrimaryKey() == true){
  706. if(equalForAttr(pOp, a, r+recordNo) != 0){
  707.   ERR(pTrans->getNdbError());
  708.   return NDBT_FAILED;
  709. }
  710.       }
  711.     }
  712.     
  713.     // Define attributes to update
  714.     for(a = 0; a<tab.getNoOfColumns(); a++){
  715.       if (tab.getColumn(a)->getPrimaryKey() == false){
  716. if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ 
  717.   ERR(pTrans->getNdbError());
  718.   return NDBT_FAILED;
  719. }
  720.       }
  721.     } 
  722.   }
  723.   return NDBT_OK;
  724. }
  725. int 
  726. HugoOperations::scanReadRecords(Ndb* pNdb, NdbScanOperation::LockMode lm,
  727. int records){
  728.   allocRows(records);
  729.   NdbScanOperation * pOp = pTrans->getNdbScanOperation(tab.getName());
  730.   
  731.   if(!pOp)
  732.     return -1;
  733.   NdbResultSet * rs = pOp->readTuples(lm, 1, 1);
  734.   
  735.   if(!rs){
  736.     return -1;
  737.   }
  738.   for(int a = 0; a<tab.getNoOfColumns(); a++){
  739.     if((rows[0]->attributeStore(a) = 
  740. pOp->getValue(tab.getColumn(a)->getName())) == 0) {
  741.       ERR(pTrans->getNdbError());
  742.       return NDBT_FAILED;
  743.     }
  744.   } 
  745.   RsPair p = {rs, records};
  746.   m_result_sets.push_back(p);
  747.   
  748.   return 0;
  749. }
  750. template class Vector<HugoOperations::RsPair>;