mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / test / src / HugoOperations.cpp
blobb8499114c974035061484307999fbd21b0d22e57
1 /* Copyright (c) 2003-2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <HugoOperations.hpp>
18 int HugoOperations::startTransaction(Ndb* pNdb,
19 const NdbDictionary::Table *table,
20 const char *keyData, Uint32 keyLen){
22 if (pTrans != NULL){
23 ndbout << "HugoOperations::startTransaction, pTrans != NULL" << endl;
24 return NDBT_FAILED;
26 pTrans = pNdb->startTransaction(table, keyData, keyLen);
27 if (pTrans == NULL) {
28 const NdbError err = pNdb->getNdbError();
29 ERR(err);
30 return NDBT_FAILED;
32 return NDBT_OK;
35 int HugoOperations::setTransaction(NdbTransaction* new_trans, bool not_null_ok){
37 if (pTrans != NULL && !not_null_ok){
38 ndbout << "HugoOperations::startTransaction, pTrans != NULL" << endl;
39 return NDBT_FAILED;
41 pTrans = new_trans;
42 if (pTrans == NULL) {
43 return NDBT_FAILED;
45 return NDBT_OK;
48 void
49 HugoOperations::setTransactionId(Uint64 id){
50 if (pTrans != NULL){
51 pTrans->setTransactionId(id);
55 int HugoOperations::closeTransaction(Ndb* pNdb){
57 UtilTransactions::closeTransaction(pNdb);
59 m_result_sets.clear();
60 m_executed_result_sets.clear();
62 return NDBT_OK;
65 NdbConnection* HugoOperations::getTransaction(){
66 return pTrans;
69 int HugoOperations::pkReadRecord(Ndb* pNdb,
70 int recordNo,
71 int numRecords,
72 NdbOperation::LockMode lm){
73 int a;
74 allocRows(numRecords);
75 int check;
77 NdbOperation* pOp = 0;
78 pIndexScanOp = 0;
80 for(int r=0; r < numRecords; r++){
82 if(pOp == 0)
84 pOp = getOperation(pTrans, NdbOperation::ReadRequest);
86 if (pOp == NULL) {
87 ERR(pTrans->getNdbError());
88 return NDBT_FAILED;
91 rand_lock_mode:
92 switch(lm){
93 case NdbOperation::LM_Read:
94 case NdbOperation::LM_Exclusive:
95 case NdbOperation::LM_CommittedRead:
96 case NdbOperation::LM_SimpleRead:
97 if(idx && idx->getType() == NdbDictionary::Index::OrderedIndex &&
98 pIndexScanOp == 0)
100 pIndexScanOp = ((NdbIndexScanOperation*)pOp);
101 check = pIndexScanOp->readTuples(lm);
103 else
104 check = pOp->readTuple(lm);
105 break;
106 default:
107 lm = (NdbOperation::LockMode)((rand() >> 16) & 3);
108 goto rand_lock_mode;
111 if( check == -1 ) {
112 ERR(pTrans->getNdbError());
113 return NDBT_FAILED;
116 // Define primary keys
117 if (equalForRow(pOp, r+recordNo) != 0)
118 return NDBT_FAILED;
120 if(pIndexScanOp)
121 pIndexScanOp->end_of_bound(r);
123 if(r == 0 || pIndexScanOp == 0)
125 // Define attributes to read
126 for(a = 0; a<tab.getNoOfColumns(); a++){
127 if((rows[r]->attributeStore(a) =
128 pOp->getValue(tab.getColumn(a)->getName())) == 0) {
129 ERR(pTrans->getNdbError());
130 return NDBT_FAILED;
134 pOp = pIndexScanOp;
136 return NDBT_OK;
139 int HugoOperations::pkUpdateRecord(Ndb* pNdb,
140 int recordNo,
141 int numRecords,
142 int updatesValue){
143 allocRows(numRecords);
144 int check;
145 for(int r=0; r < numRecords; r++){
146 NdbOperation* pOp = getOperation(pTrans, NdbOperation::UpdateRequest);
147 if (pOp == NULL) {
148 ERR(pTrans->getNdbError());
149 return NDBT_FAILED;
152 check = pOp->updateTuple();
153 if( check == -1 ) {
154 ERR(pTrans->getNdbError());
155 return NDBT_FAILED;
158 if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
160 return NDBT_FAILED;
163 return NDBT_OK;
166 int
167 HugoOperations::setValues(NdbOperation* pOp, int rowId, int updateId)
169 // Define primary keys
170 int a;
171 if (equalForRow(pOp, rowId) != 0)
172 return NDBT_FAILED;
174 for(a = 0; a<tab.getNoOfColumns(); a++){
175 if (tab.getColumn(a)->getPrimaryKey() == false){
176 if(setValueForAttr(pOp, a, rowId, updateId ) != 0){
177 ERR(pTrans->getNdbError());
178 return NDBT_FAILED;
183 return NDBT_OK;
186 int HugoOperations::pkInsertRecord(Ndb* pNdb,
187 int recordNo,
188 int numRecords,
189 int updatesValue){
191 int check;
192 for(int r=0; r < numRecords; r++){
193 NdbOperation* pOp = getOperation(pTrans, NdbOperation::InsertRequest);
194 if (pOp == NULL) {
195 ERR(pTrans->getNdbError());
196 return NDBT_FAILED;
199 check = pOp->insertTuple();
200 if( check == -1 ) {
201 ERR(pTrans->getNdbError());
202 return NDBT_FAILED;
205 if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
207 return NDBT_FAILED;
210 return NDBT_OK;
213 int HugoOperations::pkWriteRecord(Ndb* pNdb,
214 int recordNo,
215 int numRecords,
216 int updatesValue){
218 int a, check;
219 for(int r=0; r < numRecords; r++){
220 NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
221 if (pOp == NULL) {
222 ERR(pTrans->getNdbError());
223 return NDBT_FAILED;
226 check = pOp->writeTuple();
227 if( check == -1 ) {
228 ERR(pTrans->getNdbError());
229 return NDBT_FAILED;
232 // Define primary keys
233 if (equalForRow(pOp, r+recordNo) != 0)
234 return NDBT_FAILED;
236 // Define attributes to update
237 for(a = 0; a<tab.getNoOfColumns(); a++){
238 if (tab.getColumn(a)->getPrimaryKey() == false){
239 if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){
240 ERR(pTrans->getNdbError());
241 return NDBT_FAILED;
246 return NDBT_OK;
249 int HugoOperations::pkWritePartialRecord(Ndb* pNdb,
250 int recordNo,
251 int numRecords){
253 int check;
254 for(int r=0; r < numRecords; r++){
255 NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
256 if (pOp == NULL) {
257 ERR(pTrans->getNdbError());
258 return NDBT_FAILED;
261 check = pOp->writeTuple();
262 if( check == -1 ) {
263 ERR(pTrans->getNdbError());
264 return NDBT_FAILED;
267 // Define primary keys
268 if (equalForRow(pOp, r+recordNo) != 0)
269 return NDBT_FAILED;
271 return NDBT_OK;
274 int HugoOperations::pkDeleteRecord(Ndb* pNdb,
275 int recordNo,
276 int numRecords){
278 int check;
279 for(int r=0; r < numRecords; r++){
280 NdbOperation* pOp = getOperation(pTrans, NdbOperation::DeleteRequest);
281 if (pOp == NULL) {
282 ERR(pTrans->getNdbError());
283 return NDBT_FAILED;
286 check = pOp->deleteTuple();
287 if( check == -1 ) {
288 ERR(pTrans->getNdbError());
289 return NDBT_FAILED;
292 // Define primary keys
293 if (equalForRow(pOp, r+recordNo) != 0)
294 return NDBT_FAILED;
296 return NDBT_OK;
299 int HugoOperations::execute_Commit(Ndb* pNdb,
300 AbortOption eao){
302 int check = 0;
303 check = pTrans->execute(Commit, eao);
305 const NdbError err = pTrans->getNdbError();
306 if( check == -1 || err.code) {
307 ERR(err);
308 NdbOperation* pOp = pTrans->getNdbErrorOperation();
309 if (pOp != NULL){
310 const NdbError err2 = pOp->getNdbError();
311 ERR(err2);
313 if (err.code == 0)
314 return NDBT_FAILED;
315 return err.code;
318 for(int i = 0; i<m_result_sets.size(); i++){
319 m_executed_result_sets.push_back(m_result_sets[i]);
321 int rows = m_result_sets[i].records;
322 NdbScanOperation* rs = m_result_sets[i].m_result_set;
323 int res = rs->nextResult();
324 switch(res){
325 case 1:
326 return 626;
327 case -1:
328 const NdbError err = pTrans->getNdbError();
329 ERR(err);
330 return (err.code > 0 ? err.code : NDBT_FAILED);
333 // A row found
335 switch(rows){
336 case 0:
337 return 4000;
338 default:
339 m_result_sets[i].records--;
340 break;
344 m_result_sets.clear();
346 return NDBT_OK;
349 int HugoOperations::execute_NoCommit(Ndb* pNdb, AbortOption eao){
351 int check;
352 check = pTrans->execute(NoCommit, eao);
354 const NdbError err = pTrans->getNdbError();
355 if( check == -1 || err.code) {
356 ERR(err);
357 const NdbOperation* pOp = pTrans->getNdbErrorOperation();
358 while (pOp != NULL)
360 const NdbError err2 = pOp->getNdbError();
361 if (err2.code)
362 ERR(err2);
363 pOp = pTrans->getNextCompletedOperation(pOp);
365 if (err.code == 0)
366 return NDBT_FAILED;
367 return err.code;
370 for(int i = 0; i<m_result_sets.size(); i++){
371 m_executed_result_sets.push_back(m_result_sets[i]);
373 int rows = m_result_sets[i].records;
374 NdbScanOperation* rs = m_result_sets[i].m_result_set;
375 int res = rs->nextResult();
376 switch(res){
377 case 1:
378 return 626;
379 case -1:
380 const NdbError err = pTrans->getNdbError();
381 ERR(err);
382 return (err.code > 0 ? err.code : NDBT_FAILED);
385 // A row found
387 switch(rows){
388 case 0:
389 return 4000;
390 default:
391 case 1:
392 break;
396 m_result_sets.clear();
398 return NDBT_OK;
401 int HugoOperations::execute_Rollback(Ndb* pNdb){
402 int check;
403 check = pTrans->execute(Rollback);
404 if( check == -1 ) {
405 const NdbError err = pTrans->getNdbError();
406 ERR(err);
407 return NDBT_FAILED;
409 return NDBT_OK;
412 void
413 HugoOperations_async_callback(int res, NdbTransaction* pCon, void* ho)
415 ((HugoOperations*)ho)->callback(res, pCon);
418 void
419 HugoOperations::callback(int res, NdbTransaction* pCon)
421 assert(pCon == pTrans);
422 m_async_reply= 1;
423 if(res)
425 m_async_return = pCon->getNdbError().code;
427 else
429 m_async_return = 0;
433 int
434 HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
435 NdbOperation::AbortOption eao){
437 m_async_reply= 0;
438 pTrans->executeAsynchPrepare(et,
439 HugoOperations_async_callback,
440 this,
441 eao);
443 pNdb->sendPreparedTransactions();
445 return NDBT_OK;
448 int
449 HugoOperations::execute_async_prepare(Ndb* pNdb, NdbTransaction::ExecType et,
450 NdbOperation::AbortOption eao){
452 m_async_reply= 0;
453 pTrans->executeAsynchPrepare(et,
454 HugoOperations_async_callback,
455 this,
456 eao);
458 return NDBT_OK;
462 HugoOperations::wait_async(Ndb* pNdb, int timeout)
464 volatile int * wait = &m_async_reply;
465 while (!* wait)
467 pNdb->sendPollNdb(1000);
469 if(* wait)
471 if(m_async_return)
472 ndbout << "ERROR: " << pNdb->getNdbError(m_async_return) << endl;
473 return m_async_return;
476 ndbout_c("wait returned nothing...");
477 return -1;
480 HugoOperations::HugoOperations(const NdbDictionary::Table& _tab,
481 const NdbDictionary::Index* idx):
482 UtilTransactions(_tab, idx),
483 calc(_tab)
487 HugoOperations::~HugoOperations(){
488 deallocRows();
489 if (pTrans != NULL)
491 pTrans->close();
492 pTrans = NULL;
497 HugoOperations::equalForRow(NdbOperation* pOp, int row)
499 for(int a = 0; a<tab.getNoOfColumns(); a++)
501 if (tab.getColumn(a)->getPrimaryKey() == true)
503 if(equalForAttr(pOp, a, row) != 0)
505 ERR(pOp->getNdbError());
506 return NDBT_FAILED;
510 return NDBT_OK;
513 int HugoOperations::equalForAttr(NdbOperation* pOp,
514 int attrId,
515 int rowId){
516 int check = -1;
517 const NdbDictionary::Column* attr = tab.getColumn(attrId);
518 if (attr->getPrimaryKey() == false){
519 g_info << "Can't call equalForAttr on non PK attribute" << endl;
520 return NDBT_FAILED;
523 int len = attr->getSizeInBytes();
524 char buf[8000];
525 memset(buf, 0, sizeof(buf));
526 Uint32 real_len;
527 const char * value = calc.calcValue(rowId, attrId, 0, buf, len, &real_len);
528 return pOp->equal( attr->getName(), value, real_len);
531 int HugoOperations::setValueForAttr(NdbOperation* pOp,
532 int attrId,
533 int rowId,
534 int updateId){
535 int check = -1;
536 const NdbDictionary::Column* attr = tab.getColumn(attrId);
538 int len = attr->getSizeInBytes();
539 char buf[8000];
540 memset(buf, 0, sizeof(buf));
541 Uint32 real_len;
542 const char * value = calc.calcValue(rowId, attrId,
543 updateId, buf, len, &real_len);
544 return pOp->setValue( attr->getName(), value, real_len);
548 HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){
549 _numRows = (_numRows == 0 ? rows.size() : _numRows);
551 int result = NDBT_OK;
553 for(int i = 0; i<_numRows; i++){
554 if(calc.verifyRowValues(rows[i]) != NDBT_OK){
555 g_err << "Inconsistent row"
556 << endl << "\t" << rows[i]->c_str().c_str() << endl;
557 result = NDBT_FAILED;
558 continue;
561 if(calc.getUpdatesValue(rows[i]) != updatesValue){
562 result = NDBT_FAILED;
563 g_err << "Invalid updates value for row " << i << endl
564 << " updatesValue: " << updatesValue << endl
565 << " calc.getUpdatesValue: " << calc.getUpdatesValue(rows[i]) << endl
566 << rows[i]->c_str().c_str() << endl;
567 continue;
571 if(_numRows == 0){
572 g_err << "No rows -> Invalid updates value" << endl;
573 return NDBT_FAILED;
576 return result;
579 void HugoOperations::allocRows(int _numRows){
580 if(_numRows <= 0){
581 g_info << "Illegal value for num rows : " << _numRows << endl;
582 abort();
585 for(int b=rows.size(); b<_numRows; b++){
586 rows.push_back(new NDBT_ResultRow(tab));
590 void HugoOperations::deallocRows(){
591 while(rows.size() > 0){
592 delete rows.back();
593 rows.erase(rows.size() - 1);
597 int HugoOperations::saveCopyOfRecord(int numRecords ){
599 if (numRecords > (int)rows.size())
600 return NDBT_FAILED;
602 for (int i = 0; i < numRecords; i++){
603 savedRecords.push_back(rows[i]->c_str());
605 return NDBT_OK;
608 BaseString HugoOperations::getRecordStr(int recordNum){
609 if (recordNum > (int)rows.size())
610 return NULL;
611 return rows[recordNum]->c_str();
614 int HugoOperations::getRecordGci(int recordNum){
615 return pTrans->getGCI();
619 int HugoOperations::compareRecordToCopy(int numRecords ){
620 if (numRecords > (int)rows.size())
621 return NDBT_FAILED;
622 if ((unsigned)numRecords > savedRecords.size())
623 return NDBT_FAILED;
625 int result = NDBT_OK;
626 for (int i = 0; i < numRecords; i++){
627 BaseString str = rows[i]->c_str();
628 ndbout << "row["<<i<<"]: " << str << endl;
629 ndbout << "sav["<<i<<"]: " << savedRecords[i] << endl;
630 if (savedRecords[i] == str){
632 } else {
633 result = NDBT_FAILED;
636 return result;
639 void
640 HugoOperations::refresh() {
641 NdbTransaction * t = getTransaction();
642 if(t)
643 t->refresh();
646 int HugoOperations::indexReadRecords(Ndb*, const char * idxName, int recordNo,
647 bool exclusive,
648 int numRecords){
650 int a;
651 allocRows(numRecords);
652 int check;
653 for(int r=0; r < numRecords; r++){
654 NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
655 if (pOp == NULL) {
656 ERR(pTrans->getNdbError());
657 return NDBT_FAILED;
660 if (exclusive == true)
661 check = pOp->readTupleExclusive();
662 else
663 check = pOp->readTuple();
664 if( check == -1 ) {
665 ERR(pTrans->getNdbError());
666 return NDBT_FAILED;
669 // Define primary keys
670 if (equalForRow(pOp, r+recordNo) != 0)
671 return NDBT_FAILED;
673 // Define attributes to read
674 for(a = 0; a<tab.getNoOfColumns(); a++){
675 if((rows[r]->attributeStore(a) =
676 pOp->getValue(tab.getColumn(a)->getName())) == 0) {
677 ERR(pTrans->getNdbError());
678 return NDBT_FAILED;
682 return NDBT_OK;
685 int
686 HugoOperations::indexUpdateRecord(Ndb*,
687 const char * idxName,
688 int recordNo,
689 int numRecords,
690 int updatesValue){
691 int a;
692 allocRows(numRecords);
693 int check;
694 for(int r=0; r < numRecords; r++){
695 NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
696 if (pOp == NULL) {
697 ERR(pTrans->getNdbError());
698 return NDBT_FAILED;
701 check = pOp->updateTuple();
702 if( check == -1 ) {
703 ERR(pTrans->getNdbError());
704 return NDBT_FAILED;
707 // Define primary keys
708 if (equalForRow(pOp, r+recordNo) != 0)
709 return NDBT_FAILED;
711 // Define attributes to update
712 for(a = 0; a<tab.getNoOfColumns(); a++){
713 if (tab.getColumn(a)->getPrimaryKey() == false){
714 if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){
715 ERR(pTrans->getNdbError());
716 return NDBT_FAILED;
721 return NDBT_OK;
724 int
725 HugoOperations::scanReadRecords(Ndb* pNdb, NdbScanOperation::LockMode lm,
726 int records){
728 allocRows(records);
729 NdbScanOperation * pOp = pTrans->getNdbScanOperation(tab.getName());
731 if(!pOp)
732 return -1;
734 if(pOp->readTuples(lm, 0, 1)){
735 return -1;
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;
746 RsPair p = {pOp, records};
747 m_result_sets.push_back(p);
749 return 0;
752 template class Vector<HugoOperations::RsPair>;