int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, bool fetch_across_commit, int parallelism) { // Scan all records exclusive and delete // them one by one int retryAttempt = 0; const int retryMax = 10; int deletedRows = 0; int check; NdbTransaction *pTrans; NdbScanOperation *pOp; NdbError err; int par = parallelism; while (true){ restart: if (retryAttempt++ >= retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); continue; } goto failed; } pOp = pTrans->getNdbScanOperation(pTab->getName()); if (pOp == NULL) { goto failed; } int flags = 0; flags |= _tupscan ? NdbScanOperation::SF_TupScan : 0; flags |= _diskscan ? NdbScanOperation::SF_DiskScan : 0; if( pOp->readTuples(NdbOperation::LM_Exclusive, flags, par) ) { goto failed; } if(pTrans->execute(NdbTransaction::NoCommit) != 0){ err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); continue; } goto failed; } while((check = pOp->nextResult(true)) == 0){ do { if (pOp->deleteCurrentTuple() != 0){ goto failed; } deletedRows++; } while((check = pOp->nextResult(false)) == 0); if(check != -1){ if (fetch_across_commit) { check = pTrans->execute(NdbTransaction::Commit); pTrans->restart(); // new tx id } else { check = pTrans->execute(NdbTransaction::NoCommit); } } err = pTrans->getNdbError(); if(check == -1){ if(err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } } if(check == -1){ err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } if (! fetch_across_commit && pTrans->execute(NdbTransaction::Commit) != 0) { err = pTrans->getNdbError(); goto failed; } pNdb->closeTransaction(pTrans); return NDBT_OK; } return NDBT_FAILED; failed: if(pTrans != 0) pNdb->closeTransaction(pTrans); ERR(err); return (err.code != 0 ? err.code : NDBT_FAILED); }
int scan_delete(Ndb* myNdb, int column, const char * color) { // Scan all records exclusive and delete // them one by one int retryAttempt = 0; const int retryMax = 10; int deletedRows = 0; int check; NdbError err; NdbTransaction *myTrans; NdbScanOperation *myScanOp; const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("GARAGE"); if (myTable == NULL) APIERROR(myDict->getNdbError()); /** * Loop as long as : * retryMax not reached * failed operations due to TEMPORARY erros * * Exit loop; * retyrMax reached * Permanent error (return -1) */ while (true) { if (retryAttempt >= retryMax) { std::cout << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << std::endl; return -1; } myTrans = myNdb->startTransaction(); if (myTrans == NULL) { const NdbError err = myNdb->getNdbError(); if (err.status == NdbError::TemporaryError) { milliSleep(50); retryAttempt++; continue; } std::cout << err.message << std::endl; return -1; } /** * Get a scan operation. */ myScanOp = myTrans->getNdbScanOperation(myTable); if (myScanOp == NULL) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Define a result set for the scan. */ if(myScanOp->readTuples(NdbOperation::LM_Exclusive) != 0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Use NdbScanFilter to define a search critera */ NdbScanFilter filter(myScanOp) ; if(filter.begin(NdbScanFilter::AND) < 0 || filter.cmp(NdbScanFilter::COND_EQ, column, color) < 0 || filter.end() < 0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Start scan (NoCommit since we are only reading at this stage); */ if(myTrans->execute(NdbTransaction::NoCommit) != 0){ err = myTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); milliSleep(50); continue; } std::cout << err.code << std::endl; std::cout << myTrans->getNdbError().code << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * start of loop: nextResult(true) means that "parallelism" number of * rows are fetched from NDB and cached in NDBAPI */ while((check = myScanOp->nextResult(true)) == 0){ do { if (myScanOp->deleteCurrentTuple() != 0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } deletedRows++; /** * nextResult(false) means that the records * cached in the NDBAPI are modified before * fetching more rows from NDB. */ } while((check = myScanOp->nextResult(false)) == 0); /** * Commit when all cached tuple have been marked for deletion */ if(check != -1) { check = myTrans->execute(NdbTransaction::Commit); } if(check == -1) { /** * Create a new transaction, while keeping scan open */ check = myTrans->restart(); } /** * Check for errors */ err = myTrans->getNdbError(); if(check == -1) { if(err.status == NdbError::TemporaryError) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); milliSleep(50); continue; } } /** * End of loop */ } std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return 0; } if(myTrans!=0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); } return -1; }