dba_dac.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 "dba_internal.hpp"
  14. #include <NdbSleep.h>
  15. static void
  16. DBA__ErrorMapping(const NdbError & err, DBA_Error_t * status){
  17.   switch(err.classification){
  18.   case NdbError::ConstraintViolation:
  19.     * status = DBA_CONSTRAINT_VIOLATION;
  20.     break;
  21.     
  22.   case NdbError::NoDataFound:
  23.     * status = DBA_NO_DATA;
  24.     break;
  25.     
  26.   case NdbError::TemporaryResourceError:
  27.   case NdbError::NodeRecoveryError:
  28.     * status = DBA_TEMPORARY_ERROR;
  29.     break;
  30.     
  31.   case NdbError::InsufficientSpace:
  32.     * status = DBA_INSUFFICIENT_SPACE;
  33.     break;
  34.     
  35.   case NdbError::UnknownResultError:
  36.     * status = DBA_UNKNOWN_RESULT;
  37.     break;
  38.     
  39.   case NdbError::OverloadError:
  40.     * status = DBA_OVERLOAD;
  41.     break;
  42.     
  43.   case NdbError::TimeoutExpired:
  44.     * status = DBA_TIMEOUT;
  45.     break;
  46.   case NdbError::SchemaError:
  47.     * status = DBA_SCHEMA_ERROR;
  48.     break;
  49.   case NdbError::ApplicationError:
  50.     * status = DBA_APPLICATION_ERROR;
  51.     break;
  52.   case NdbError::InternalError:
  53.   default:
  54.     * status = DBA_NDB_ERROR;
  55.     break;
  56.   }
  57. }
  58. /**
  59.  * Map between NDB error codes and DBA error codes
  60.  */
  61. static
  62. void
  63. DBA__CallbackErrorCodeMapping(int errorCode, 
  64.       NdbConnection * connection,
  65.       DBA_Error_t * status,
  66.       DBA_ErrorCode_t * errCode) {
  67.   if(errorCode == 0){
  68.     * status  = DBA_NO_ERROR;
  69.     * errCode = 0;
  70.     return;
  71.   }
  72.   const NdbError & err = connection->getNdbError();
  73.   DBA__ErrorMapping(err, status);
  74.   * errCode = err.code;
  75. }
  76. /**
  77.  * When startTransaction fails
  78.  */
  79. static
  80. void
  81. DBA__ConnectionErrorMapping(Ndb * theNdb){
  82.   const NdbError & err = theNdb->getNdbError();
  83.   DBA_Error_t status;
  84.   DBA__ErrorMapping(err, &status);
  85.   
  86.   DBA__SetLatestError(status, err.code,
  87.       err.message);
  88. }
  89. /**
  90.  * When getNdbOperation fails
  91.  */
  92. static
  93. void
  94. DBA__OperationErrorMapping(Ndb * theNdb, NdbConnection * con){
  95.   const NdbError & err = theNdb->getNdbError();
  96.   DBA_Error_t status;
  97.   DBA__ErrorMapping(err, &status);
  98.   
  99.   DBA__SetLatestError(status, err.code,
  100.       err.message);
  101. }
  102. /**
  103.  * When equal/get/set value fails
  104.  */
  105. static
  106. void
  107. DBA__EqualErrorMapping(Ndb * theNdb, NdbConnection * con, NdbOperation * op){
  108.   const NdbError & err = theNdb->getNdbError();
  109.   DBA_Error_t status;
  110.   DBA__ErrorMapping(err, &status);
  111.   
  112.   DBA__SetLatestError(status, err.code,
  113.       err.message);
  114. }
  115. static
  116. void 
  117. NewtonCallback(int errorCode,
  118.        NdbConnection * connection,
  119.        void * anyObject){
  120.   
  121.   DBA_AsyncCallbackFn_t CbFunc = (DBA_AsyncCallbackFn_t)anyObject;
  122.   DBA_ReqId_t  ReqId = (DBA_ReqId_t) connection;
  123.   
  124.   DBA_Error_t     Status = (DBA_Error_t) errorCode;
  125.   DBA_ErrorCode_t Impl_Status ;
  126.   
  127.   DBA__CallbackErrorCodeMapping(errorCode, connection, &Status, &Impl_Status);
  128.   
  129.   DBA__TheNdb->closeTransaction(connection);
  130.   
  131.   DBA__RecvTransactions++;
  132.   CbFunc(ReqId, Status, Impl_Status);
  133. }
  134. /**
  135.  * Start transaction
  136.  */
  137. NdbConnection *
  138. startTransaction(){
  139.   NdbConnection * con = DBA__TheNdb->startTransaction();
  140.   if(con != 0)
  141.     return con;
  142.   const int _t = (DBA__SentTransactions - DBA__RecvTransactions);
  143.   const int t = (_t>0?_t:-_t);
  144.   
  145.   if(!(DBA__TheNdb->getNdbError().code == 4006 && t > 1000)){
  146.     DBA_DEBUG("DBA__TheNdb->getNdbError() = " << 
  147.       DBA__TheNdb->getNdbError());
  148.   }
  149.   
  150.   int sum = 0;
  151.   int sleepTime = 10;
  152.   for(; con == 0 && sum < DBA__StartTransactionTimout; ){
  153.     NdbMutex_Unlock(DBA__TheNewtonMutex);
  154.     NdbSleep_MilliSleep(sleepTime);
  155.     NdbMutex_Lock(DBA__TheNewtonMutex);
  156.     con = DBA__TheNdb->startTransaction();
  157.     
  158.     sum       += sleepTime;
  159.     sleepTime += 10;
  160.   }
  161.   
  162.   return con;
  163. }
  164. #define CHECK_BINDINGS(Bindings) 
  165.   if(!DBA__ValidBinding(Bindings)){ 
  166.     DBA__SetLatestError(DBA_APPLICATION_ERROR, 0, "Invalid bindings"); 
  167.     return DBA_INVALID_REQID; 
  168.   } 
  169. #define CHECK_BINDINGS2(Bindings, NbBindings) 
  170.   if(!DBA__ValidBindings(Bindings, NbBindings)){ 
  171.     DBA__SetLatestError(DBA_APPLICATION_ERROR, 0, "Invalid bindings"); 
  172.     return DBA_INVALID_REQID; 
  173.   }
  174. #define CHECK_CONNECTION(Connection) 
  175.   if(Connection == 0){ 
  176.     DBA__ConnectionErrorMapping(DBA__TheNdb); 
  177.     NdbMutex_Unlock(DBA__TheNewtonMutex); 
  178.     return DBA_INVALID_REQID; 
  179.   }
  180. #define CHECK_OPERATION(Connection, Operation) 
  181.   if(Operation == 0){ 
  182.     DBA__OperationErrorMapping(DBA__TheNdb, Connection); 
  183.     DBA__TheNdb->closeTransaction(Connection); 
  184.     NdbMutex_Unlock(DBA__TheNewtonMutex); 
  185.     return DBA_INVALID_REQID; 
  186.   }
  187. #define EQUAL_ERROR(Connection, Operation) { 
  188.     DBA__EqualErrorMapping(DBA__TheNdb, Connection, Operation); 
  189.     DBA__TheNdb->closeTransaction(Connection); 
  190.     NdbMutex_Unlock(DBA__TheNewtonMutex); 
  191.     return DBA_INVALID_REQID; 
  192.   }
  193. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  194. extern "C" 
  195. DBA_ReqId_t
  196. DBA_ReadRows( const DBA_Binding_t* pBindings, void* const * _pData,
  197.       int NbRows,
  198.       DBA_AsyncCallbackFn_t CbFunc ) {
  199.   
  200.   CHECK_BINDINGS(pBindings);
  201.   
  202.   NdbMutex_Lock(DBA__TheNewtonMutex);
  203.   NdbConnection * con = startTransaction();
  204.   
  205.   CHECK_CONNECTION(con);
  206.   
  207.   for(int i = 0; i<NbRows; i++){
  208.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  209.     
  210.     CHECK_OPERATION(con, op);
  211.     
  212.     op->simpleRead();
  213.     
  214.     void * pData = _pData[i];
  215.     
  216.     if(!DBA__EqualGetValue(op, pBindings, pData)){
  217.       EQUAL_ERROR(con, op);
  218.     }
  219.   }
  220.   con->executeAsynchPrepare(Commit,
  221.     NewtonCallback,
  222.     (void*)CbFunc);
  223.   
  224.   DBA__SentTransactions++;
  225.   
  226.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  227.   return (DBA_ReqId_t) con;
  228. }
  229. extern "C"
  230. DBA_ReqId_t
  231. DBA_ArrayReadRows( const DBA_Binding_t* pBindings, void * pData,
  232.    int NbRows,
  233.    DBA_AsyncCallbackFn_t CbFunc ){
  234.   CHECK_BINDINGS(pBindings);
  235.   NdbMutex_Lock(DBA__TheNewtonMutex);
  236.   NdbConnection * con = startTransaction();
  237.   CHECK_CONNECTION(con);
  238.   
  239.   for(int i = 0; i<NbRows; i++){
  240.     NdbOperation * op  = con->getNdbOperation(pBindings->tableName);
  241.     CHECK_OPERATION(con, op);
  242.     
  243.     op->simpleRead();
  244.     
  245.     if(!DBA__EqualGetValue(op, pBindings, 
  246.    ((char*)pData)+i*pBindings->structSz)){
  247.       EQUAL_ERROR(con, op);
  248.     }
  249.   }
  250.   con->executeAsynchPrepare(Commit,
  251.     NewtonCallback,
  252.     (void*)CbFunc);
  253.   
  254.   DBA__SentTransactions++;
  255.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  256.   return (DBA_ReqId_t) con;
  257. }
  258. extern "C"
  259. DBA_ReqId_t
  260. DBA_MultiReadRow(const DBA_Binding_t * const * pBindings,
  261.  void * const * pData,
  262.  int NbBindings,
  263.  DBA_AsyncCallbackFn_t CbFunc ) {
  264.   CHECK_BINDINGS2(pBindings, NbBindings);
  265.     
  266.   NdbMutex_Lock(DBA__TheNewtonMutex);
  267.   NdbConnection * con = startTransaction();
  268.   
  269.   CHECK_CONNECTION(con);
  270.   
  271.   for(int i = 0; i<NbBindings; i++){
  272.     NdbOperation * op  = con->getNdbOperation(pBindings[i]->tableName);
  273.     
  274.     CHECK_OPERATION(con, op);
  275.     op->simpleRead();
  276.     
  277.     if(!DBA__EqualGetValue(op, pBindings[i], pData[i])){
  278.       EQUAL_ERROR(con, op);
  279.     }
  280.   }
  281.   
  282.   con->executeAsynchPrepare(Commit,
  283.     NewtonCallback,
  284.     (void*)CbFunc);
  285.   DBA__SentTransactions++;
  286.   
  287.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  288.   return (DBA_ReqId_t) con;
  289. }
  290. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  291. extern "C" 
  292. DBA_ReqId_t
  293. DBA_InsertRows( const DBA_Binding_t* pBindings, const void * const * _pData,
  294. int NbRows,
  295. DBA_AsyncCallbackFn_t CbFunc ) {
  296.   CHECK_BINDINGS(pBindings);
  297.   NdbMutex_Lock(DBA__TheNewtonMutex);
  298.   NdbConnection * con = startTransaction();
  299.   CHECK_CONNECTION(con);
  300.   
  301.   for(int i = 0; i<NbRows; i++){
  302.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  303.     CHECK_OPERATION(con, op);
  304.     op->insertTuple();
  305.     
  306.     const void * pData = _pData[i];
  307.     if(!DBA__EqualSetValue(op, pBindings, pData)){
  308.       EQUAL_ERROR(con, op);
  309.     }
  310.   }
  311.   con->executeAsynchPrepare(Commit,
  312.     NewtonCallback,
  313.     (void*)CbFunc);
  314.   
  315.   
  316.   DBA__SentTransactions++;
  317.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  318.   return (DBA_ReqId_t) con;
  319. }
  320. extern "C"
  321. DBA_ReqId_t
  322. DBA_ArrayInsertRows( const DBA_Binding_t* pBindings, const void * pData,
  323.      int NbRows,
  324.      DBA_AsyncCallbackFn_t CbFunc ){
  325.   CHECK_BINDINGS(pBindings);
  326.   NdbMutex_Lock(DBA__TheNewtonMutex);
  327.   NdbConnection * con = startTransaction();
  328.   CHECK_CONNECTION(con);
  329.   
  330.   for(int i = 0; i<NbRows; i++){
  331.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  332.     CHECK_OPERATION(con, op);
  333.     op->insertTuple();
  334.     
  335.     if(!DBA__EqualSetValue(op, pBindings, 
  336.    ((char*)pData)+i*pBindings->structSz)){
  337.       EQUAL_ERROR(con, op);
  338.     }
  339.   }
  340.   con->executeAsynchPrepare(Commit,
  341.     NewtonCallback,
  342.     (void*)CbFunc);
  343.   
  344.   DBA__SentTransactions++;
  345.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  346.   return (DBA_ReqId_t) con;
  347. }
  348. extern "C"
  349. DBA_ReqId_t
  350. DBA_MultiInsertRow(const DBA_Binding_t * const * pBindings,
  351.    const void * const * pData,
  352.    int NbBindings,
  353.    DBA_AsyncCallbackFn_t CbFunc ) {
  354.   CHECK_BINDINGS2(pBindings, NbBindings);
  355.   NdbMutex_Lock(DBA__TheNewtonMutex);
  356.   NdbConnection * con = startTransaction();
  357.   CHECK_CONNECTION(con);
  358.   
  359.   for(int i = 0; i<NbBindings; i++){
  360.     NdbOperation  * op  = con->getNdbOperation(pBindings[i]->tableName);
  361.     CHECK_OPERATION(con, op);
  362.     op->insertTuple();
  363.     if(!DBA__EqualSetValue(op, pBindings[i], pData[i])){
  364.       EQUAL_ERROR(con, op);
  365.     }
  366.   }
  367.   
  368.   con->executeAsynchPrepare(Commit,
  369.     NewtonCallback,
  370.     (void*)CbFunc);
  371.   
  372.   DBA__SentTransactions++;
  373.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  374.   return (DBA_ReqId_t) con;
  375. }
  376. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  377. extern "C" 
  378. DBA_ReqId_t
  379. DBA_UpdateRows( const DBA_Binding_t* pBindings, const void * const * _pData,
  380. int NbRows,
  381. DBA_AsyncCallbackFn_t CbFunc ) {
  382.   CHECK_BINDINGS(pBindings);
  383.   NdbMutex_Lock(DBA__TheNewtonMutex);
  384.   NdbConnection * con = startTransaction();
  385.   CHECK_CONNECTION(con);
  386.   
  387.   for(int i = 0; i<NbRows; i++){
  388.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  389.     CHECK_OPERATION(con, op);
  390.     op->updateTuple();
  391.     
  392.     const void * pData = _pData[i];
  393.     if(!DBA__EqualSetValue(op, pBindings, pData)){
  394.       EQUAL_ERROR(con, op);
  395.     }
  396.   }
  397.   con->executeAsynchPrepare(Commit,
  398.     NewtonCallback,
  399.     (void*)CbFunc);
  400.   
  401.   
  402.   DBA__SentTransactions++;
  403.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  404.   return (DBA_ReqId_t) con;
  405. }
  406. extern "C"
  407. DBA_ReqId_t
  408. DBA_ArrayUpdateRows( const DBA_Binding_t* pBindings, const void * pData,
  409.      int NbRows,
  410.      DBA_AsyncCallbackFn_t CbFunc ){
  411.   CHECK_BINDINGS(pBindings);
  412.   NdbMutex_Lock(DBA__TheNewtonMutex);
  413.   NdbConnection * con = startTransaction();
  414.   CHECK_CONNECTION(con);
  415.   
  416.   for(int i = 0; i<NbRows; i++){
  417.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  418.     CHECK_OPERATION(con, op);
  419.     op->updateTuple();
  420.     
  421.     if(!DBA__EqualSetValue(op, pBindings, 
  422.    ((char*)pData)+i*pBindings->structSz)){
  423.       EQUAL_ERROR(con, op);
  424.     }
  425.   }
  426.   con->executeAsynchPrepare(Commit,
  427.     NewtonCallback,
  428.     (void*)CbFunc);
  429.   
  430.   DBA__SentTransactions++;
  431.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  432.   return (DBA_ReqId_t) con;
  433. }
  434. extern "C"
  435. DBA_ReqId_t
  436. DBA_MultiUpdateRow(const DBA_Binding_t * const * pBindings,
  437.    const void * const * pData,
  438.    int NbBindings,
  439.    DBA_AsyncCallbackFn_t CbFunc ) {
  440.   CHECK_BINDINGS2(pBindings, NbBindings);
  441.   NdbMutex_Lock(DBA__TheNewtonMutex);
  442.   NdbConnection * con = startTransaction();
  443.   CHECK_CONNECTION(con);
  444.   
  445.   for(int i = 0; i<NbBindings; i++){
  446.     NdbOperation  * op  = con->getNdbOperation(pBindings[i]->tableName);
  447.     CHECK_OPERATION(con, op);
  448.     op->updateTuple();
  449.     
  450.     if(!DBA__EqualSetValue(op, pBindings[i], pData[i])){
  451.       EQUAL_ERROR(con, op);
  452.     }
  453.   }
  454.   
  455.   con->executeAsynchPrepare(Commit,
  456.     NewtonCallback,
  457.     (void*)CbFunc);
  458.   
  459.   DBA__SentTransactions++;
  460.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  461.   return (DBA_ReqId_t) con;
  462. }
  463. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  464. extern "C" 
  465. DBA_ReqId_t
  466. DBA_WriteRows( const DBA_Binding_t* pBindings, const void * const * _pData,
  467.        int NbRows,
  468.        DBA_AsyncCallbackFn_t CbFunc ) {
  469.   CHECK_BINDINGS(pBindings);
  470.   NdbMutex_Lock(DBA__TheNewtonMutex);
  471.   NdbConnection * con = startTransaction();
  472.   CHECK_CONNECTION(con);
  473.   
  474.   for(int i = 0; i<NbRows; i++){
  475.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  476.     CHECK_OPERATION(con, op);
  477.     op->writeTuple();
  478.     
  479.     const void * pData = _pData[i];
  480.     if(!DBA__EqualSetValue(op, pBindings, pData)){
  481.       EQUAL_ERROR(con, op);
  482.     }
  483.   }
  484.   con->executeAsynchPrepare(Commit,
  485.     NewtonCallback,
  486.     (void*)CbFunc);
  487.   
  488.   
  489.   DBA__SentTransactions++;
  490.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  491.   return (DBA_ReqId_t) con;
  492. }
  493. extern "C"
  494. DBA_ReqId_t
  495. DBA_ArrayWriteRows( const DBA_Binding_t* pBindings, const void * pData,
  496.     int NbRows,
  497.     DBA_AsyncCallbackFn_t CbFunc ){
  498.   CHECK_BINDINGS(pBindings);
  499.   NdbMutex_Lock(DBA__TheNewtonMutex);
  500.   NdbConnection * con = startTransaction();
  501.   CHECK_CONNECTION(con);
  502.   
  503.   for(int i = 0; i<NbRows; i++){
  504.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  505.     CHECK_OPERATION(con, op);
  506.     op->writeTuple();
  507.     
  508.     if(!DBA__EqualSetValue(op, pBindings, 
  509.    ((char*)pData)+i*pBindings->structSz)){
  510.       EQUAL_ERROR(con, op);
  511.     }
  512.   }
  513.   con->executeAsynchPrepare(Commit,
  514.     NewtonCallback,
  515.     (void*)CbFunc);
  516.   
  517.   DBA__SentTransactions++;
  518.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  519.   return (DBA_ReqId_t) con;
  520. }
  521. extern "C"
  522. DBA_ReqId_t
  523. DBA_MultiWriteRow(const DBA_Binding_t * const * pBindings,
  524.   const void * const * pData,
  525.   int NbBindings,
  526.   DBA_AsyncCallbackFn_t CbFunc ) {
  527.   CHECK_BINDINGS2(pBindings, NbBindings);
  528.   
  529.   NdbMutex_Lock(DBA__TheNewtonMutex);
  530.   NdbConnection * con = startTransaction();
  531.   
  532.   CHECK_CONNECTION(con);
  533.   for(int i = 0; i<NbBindings; i++){
  534.     NdbOperation  * op  = con->getNdbOperation(pBindings[i]->tableName);
  535.     CHECK_OPERATION(con, op);
  536.     op->writeTuple();
  537.     
  538.     if(!DBA__EqualSetValue(op, pBindings[i], pData[i])){
  539.       EQUAL_ERROR(con, op);
  540.     }
  541.   }
  542.   
  543.   con->executeAsynchPrepare(Commit,
  544.     NewtonCallback,
  545.     (void*)CbFunc);
  546.   
  547.   DBA__SentTransactions++;
  548.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  549.   return (DBA_ReqId_t) con;
  550. }
  551. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  552. extern "C" 
  553. DBA_ReqId_t
  554. DBA_DeleteRows( const DBA_Binding_t* pBindings, const void * const * _pData,
  555. int NbRows,
  556. DBA_AsyncCallbackFn_t CbFunc ) {
  557.   CHECK_BINDINGS(pBindings);
  558.   NdbMutex_Lock(DBA__TheNewtonMutex);
  559.   NdbConnection * con = startTransaction();
  560.   CHECK_CONNECTION(con);
  561.   for(int i = 0; i<NbRows; i++){
  562.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  563.     CHECK_OPERATION(con, op);
  564.     op->deleteTuple();
  565.     
  566.     const void * pData = _pData[i];
  567.     
  568.     if(!DBA__Equal(op, pBindings, pData)){
  569.       EQUAL_ERROR(con, op);
  570.     }
  571.   }
  572.   con->executeAsynchPrepare(Commit,
  573.     NewtonCallback,
  574.     (void*)CbFunc);
  575.   
  576.   DBA__SentTransactions++;
  577.   
  578.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  579.   return (DBA_ReqId_t) con;
  580. }
  581. extern "C"
  582. DBA_ReqId_t
  583. DBA_ArrayDeleteRows( const DBA_Binding_t* pBindings, const void * pData,
  584.      int NbRows,
  585.      DBA_AsyncCallbackFn_t CbFunc ){
  586.   CHECK_BINDINGS(pBindings);
  587.   NdbMutex_Lock(DBA__TheNewtonMutex);
  588.   NdbConnection * con = startTransaction();
  589.   CHECK_CONNECTION(con);
  590.   for(int i = 0; i<NbRows; i++){
  591.     NdbOperation  * op  = con->getNdbOperation(pBindings->tableName);
  592.     CHECK_OPERATION(con, op);
  593.     op->deleteTuple();
  594.     
  595.     if(!DBA__Equal(op, pBindings, 
  596.    ((char*)pData)+i*pBindings->structSz)){
  597.       EQUAL_ERROR(con, op);
  598.     }
  599.   }
  600.   con->executeAsynchPrepare(Commit,
  601.     NewtonCallback,
  602.     (void*)CbFunc);
  603.   
  604.   DBA__SentTransactions++;
  605.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  606.   return (DBA_ReqId_t) con;
  607. }
  608. extern "C"
  609. DBA_ReqId_t
  610. DBA_MultiDeleteRow(const DBA_Binding_t * const * pBindings,
  611.    const void * const * pData,
  612.    int NbBindings,
  613.    DBA_AsyncCallbackFn_t CbFunc ) {
  614.   CHECK_BINDINGS2(pBindings, NbBindings);
  615.   NdbMutex_Lock(DBA__TheNewtonMutex);
  616.   NdbConnection * con = startTransaction();
  617.   CHECK_CONNECTION(con);
  618.   
  619.   for(int i = 0; i<NbBindings; i++){
  620.     NdbOperation  * op  = con->getNdbOperation(pBindings[i]->tableName);
  621.     CHECK_OPERATION(con, op);
  622.     op->deleteTuple();
  623.     
  624.     if(!DBA__Equal(op, pBindings[i], pData[i])){
  625.       EQUAL_ERROR(con, op);
  626.     }
  627.   }
  628.   
  629.   con->executeAsynchPrepare(Commit,
  630.     NewtonCallback,
  631.     (void*)CbFunc);
  632.   
  633.   DBA__SentTransactions++;
  634.   NdbMutex_Unlock(DBA__TheNewtonMutex);
  635.   return (DBA_ReqId_t) con;
  636. }
  637. /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
  638. bool
  639. DBA__EqualGetValue(NdbOperation * op,
  640.    const DBA_Binding_t* pBindings,
  641.    void * pData){
  642.   for(int i = 0; i<pBindings->noOfKeys; i++){
  643.     if(op->equal(pBindings->keyIds[i], 
  644.  (const char*)pData+pBindings->keyOffsets[i]) == -1){
  645.       return false;
  646.     }
  647.   }
  648.   
  649.   for(int i = 0; i<pBindings->noOfColumns; i++){
  650.     if(op->getValue(pBindings->columnIds[i], 
  651.     (char*)pData+pBindings->columnOffsets[i]) == 0){
  652.       return false;
  653.     }
  654.   }
  655.   for(int i = 0; i<pBindings->noOfSubBindings; i++){
  656.     void * tData = *(void**)((char *)pData+pBindings->subBindingOffsets[i]);
  657.     const DBA_Binding_t * tBinding = pBindings->subBindings[i];
  658.     if(!DBA__EqualGetValue(op, tBinding, tData))
  659.       return false;
  660.   }
  661.   
  662.   return true;
  663. }
  664. bool
  665. DBA__EqualSetValue(NdbOperation * op,
  666.    const DBA_Binding_t* pBindings,
  667.    const void * pData){
  668.   
  669.   for(int i = 0; i<pBindings->noOfKeys; i++){
  670.     if(op->equal(pBindings->keyIds[i], 
  671.  (const char*)pData+pBindings->keyOffsets[i]) == -1){
  672.       return false;
  673.     }
  674.   }
  675.   
  676.   for(int i = 0; i<pBindings->noOfColumns; i++){
  677.     if(op->setValue(pBindings->columnIds[i], 
  678.     (char*)pData+pBindings->columnOffsets[i]) == -1){
  679.       return false;
  680.     }
  681.   }
  682.   for(int i = 0; i<pBindings->noOfSubBindings; i++){
  683.     void * tData = * (void**)((char *)pData+pBindings->subBindingOffsets[i]);
  684.     const DBA_Binding_t * tBinding = pBindings->subBindings[i];
  685.     if(!DBA__EqualSetValue(op, tBinding, tData))
  686.       return false;
  687.   }
  688.   
  689.   return true;
  690. }
  691. bool
  692. DBA__Equal(NdbOperation * op,
  693.    const DBA_Binding_t* pBindings,
  694.    const void * pData){
  695.   
  696.   for(int i = 0; i<pBindings->noOfKeys; i++)
  697.     if(op->equal(pBindings->keyIds[i], 
  698.  (const char*)pData+pBindings->keyOffsets[i]) == -1){
  699.       return false;
  700.     }
  701.   
  702.   for(int i = 0; i<pBindings->noOfSubBindings; i++){
  703.     void * tData = *(void**)((char *)pData+pBindings->subBindingOffsets[i]);
  704.     const DBA_Binding_t * tBinding = pBindings->subBindings[i];
  705.     if(!DBA__Equal(op, tBinding, tData))
  706.       return false;
  707.   }
  708.   
  709.   return true;
  710. }