PageRenderTime 39ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/release/src/router/mysql/storage/ndb/ndbapi-examples/ndbapi_scan/ndbapi_scan.cpp

https://gitlab.com/envieidoc/advancedtomato2
C++ | 844 lines | 490 code | 101 blank | 253 comment | 119 complexity | 5d1dc60391a0e96a2495f58ce2d6231b MD5 | raw file
  1. /* Copyright (c) 2003, 2005, 2006 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; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software
  11. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
  12. /*
  13. * ndbapi_scan.cpp:
  14. * Illustrates how to use the scan api in the NDBAPI.
  15. * The example shows how to do scan, scan for update and scan for delete
  16. * using NdbScanFilter and NdbScanOperation
  17. *
  18. * Classes and methods used in this example:
  19. *
  20. * Ndb_cluster_connection
  21. * connect()
  22. * wait_until_ready()
  23. *
  24. * Ndb
  25. * init()
  26. * getDictionary()
  27. * startTransaction()
  28. * closeTransaction()
  29. *
  30. * NdbTransaction
  31. * getNdbScanOperation()
  32. * execute()
  33. *
  34. * NdbScanOperation
  35. * getValue()
  36. * readTuples()
  37. * nextResult()
  38. * deleteCurrentTuple()
  39. * updateCurrentTuple()
  40. *
  41. * const NdbDictionary::Dictionary
  42. * getTable()
  43. *
  44. * const NdbDictionary::Table
  45. * getColumn()
  46. *
  47. * const NdbDictionary::Column
  48. * getLength()
  49. *
  50. * NdbOperation
  51. * insertTuple()
  52. * equal()
  53. * setValue()
  54. *
  55. * NdbScanFilter
  56. * begin()
  57. * eq()
  58. * end()
  59. *
  60. */
  61. #include <mysql.h>
  62. #include <mysqld_error.h>
  63. #include <NdbApi.hpp>
  64. // Used for cout
  65. #include <iostream>
  66. #include <stdio.h>
  67. /**
  68. * Helper sleep function
  69. */
  70. static void
  71. milliSleep(int milliseconds){
  72. struct timeval sleeptime;
  73. sleeptime.tv_sec = milliseconds / 1000;
  74. sleeptime.tv_usec = (milliseconds - (sleeptime.tv_sec * 1000)) * 1000000;
  75. select(0, 0, 0, 0, &sleeptime);
  76. }
  77. /**
  78. * Helper sleep function
  79. */
  80. #define PRINT_ERROR(code,msg) \
  81. std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \
  82. << ", code: " << code \
  83. << ", msg: " << msg << "." << std::endl
  84. #define MYSQLERROR(mysql) { \
  85. PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
  86. exit(-1); }
  87. #define APIERROR(error) { \
  88. PRINT_ERROR(error.code,error.message); \
  89. exit(-1); }
  90. struct Car
  91. {
  92. /**
  93. * Note memset, so that entire char-fields are cleared
  94. * as all 20 bytes are significant (as type is char)
  95. */
  96. Car() { memset(this, 0, sizeof(* this)); }
  97. unsigned int reg_no;
  98. char brand[20];
  99. char color[20];
  100. };
  101. /**
  102. * Function to drop table
  103. */
  104. void drop_table(MYSQL &mysql)
  105. {
  106. if (mysql_query(&mysql, "DROP TABLE GARAGE"))
  107. MYSQLERROR(mysql);
  108. }
  109. /**
  110. * Function to create table
  111. */
  112. void create_table(MYSQL &mysql)
  113. {
  114. while (mysql_query(&mysql,
  115. "CREATE TABLE"
  116. " GARAGE"
  117. " (REG_NO INT UNSIGNED NOT NULL,"
  118. " BRAND CHAR(20) NOT NULL,"
  119. " COLOR CHAR(20) NOT NULL,"
  120. " PRIMARY KEY USING HASH (REG_NO))"
  121. " ENGINE=NDB"))
  122. {
  123. if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR)
  124. MYSQLERROR(mysql);
  125. std::cout << "MySQL Cluster already has example table: GARAGE. "
  126. << "Dropping it..." << std::endl;
  127. /******************
  128. * Recreate table *
  129. ******************/
  130. drop_table(mysql);
  131. create_table(mysql);
  132. }
  133. }
  134. int populate(Ndb * myNdb)
  135. {
  136. int i;
  137. Car cars[15];
  138. const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  139. const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
  140. if (myTable == NULL)
  141. APIERROR(myDict->getNdbError());
  142. /**
  143. * Five blue mercedes
  144. */
  145. for (i = 0; i < 5; i++)
  146. {
  147. cars[i].reg_no = i;
  148. sprintf(cars[i].brand, "Mercedes");
  149. sprintf(cars[i].color, "Blue");
  150. }
  151. /**
  152. * Five black bmw
  153. */
  154. for (i = 5; i < 10; i++)
  155. {
  156. cars[i].reg_no = i;
  157. sprintf(cars[i].brand, "BMW");
  158. sprintf(cars[i].color, "Black");
  159. }
  160. /**
  161. * Five pink toyotas
  162. */
  163. for (i = 10; i < 15; i++)
  164. {
  165. cars[i].reg_no = i;
  166. sprintf(cars[i].brand, "Toyota");
  167. sprintf(cars[i].color, "Pink");
  168. }
  169. NdbTransaction* myTrans = myNdb->startTransaction();
  170. if (myTrans == NULL)
  171. APIERROR(myNdb->getNdbError());
  172. for (i = 0; i < 15; i++)
  173. {
  174. NdbOperation* myNdbOperation = myTrans->getNdbOperation(myTable);
  175. if (myNdbOperation == NULL)
  176. APIERROR(myTrans->getNdbError());
  177. myNdbOperation->insertTuple();
  178. myNdbOperation->equal("REG_NO", cars[i].reg_no);
  179. myNdbOperation->setValue("BRAND", cars[i].brand);
  180. myNdbOperation->setValue("COLOR", cars[i].color);
  181. }
  182. int check = myTrans->execute(NdbTransaction::Commit);
  183. myTrans->close();
  184. return check != -1;
  185. }
  186. int scan_delete(Ndb* myNdb,
  187. int column,
  188. const char * color)
  189. {
  190. // Scan all records exclusive and delete
  191. // them one by one
  192. int retryAttempt = 0;
  193. const int retryMax = 10;
  194. int deletedRows = 0;
  195. int check;
  196. NdbError err;
  197. NdbTransaction *myTrans;
  198. NdbScanOperation *myScanOp;
  199. const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  200. const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
  201. if (myTable == NULL)
  202. APIERROR(myDict->getNdbError());
  203. /**
  204. * Loop as long as :
  205. * retryMax not reached
  206. * failed operations due to TEMPORARY erros
  207. *
  208. * Exit loop;
  209. * retyrMax reached
  210. * Permanent error (return -1)
  211. */
  212. while (true)
  213. {
  214. if (retryAttempt >= retryMax)
  215. {
  216. std::cout << "ERROR: has retried this operation " << retryAttempt
  217. << " times, failing!" << std::endl;
  218. return -1;
  219. }
  220. myTrans = myNdb->startTransaction();
  221. if (myTrans == NULL)
  222. {
  223. const NdbError err = myNdb->getNdbError();
  224. if (err.status == NdbError::TemporaryError)
  225. {
  226. milliSleep(50);
  227. retryAttempt++;
  228. continue;
  229. }
  230. std::cout << err.message << std::endl;
  231. return -1;
  232. }
  233. /**
  234. * Get a scan operation.
  235. */
  236. myScanOp = myTrans->getNdbScanOperation(myTable);
  237. if (myScanOp == NULL)
  238. {
  239. std::cout << myTrans->getNdbError().message << std::endl;
  240. myNdb->closeTransaction(myTrans);
  241. return -1;
  242. }
  243. /**
  244. * Define a result set for the scan.
  245. */
  246. if(myScanOp->readTuples(NdbOperation::LM_Exclusive) != 0)
  247. {
  248. std::cout << myTrans->getNdbError().message << std::endl;
  249. myNdb->closeTransaction(myTrans);
  250. return -1;
  251. }
  252. /**
  253. * Use NdbScanFilter to define a search critera
  254. */
  255. NdbScanFilter filter(myScanOp) ;
  256. if(filter.begin(NdbScanFilter::AND) < 0 ||
  257. filter.cmp(NdbScanFilter::COND_EQ, column, color) < 0 ||
  258. filter.end() < 0)
  259. {
  260. std::cout << myTrans->getNdbError().message << std::endl;
  261. myNdb->closeTransaction(myTrans);
  262. return -1;
  263. }
  264. /**
  265. * Start scan (NoCommit since we are only reading at this stage);
  266. */
  267. if(myTrans->execute(NdbTransaction::NoCommit) != 0){
  268. err = myTrans->getNdbError();
  269. if(err.status == NdbError::TemporaryError){
  270. std::cout << myTrans->getNdbError().message << std::endl;
  271. myNdb->closeTransaction(myTrans);
  272. milliSleep(50);
  273. continue;
  274. }
  275. std::cout << err.code << std::endl;
  276. std::cout << myTrans->getNdbError().code << std::endl;
  277. myNdb->closeTransaction(myTrans);
  278. return -1;
  279. }
  280. /**
  281. * start of loop: nextResult(true) means that "parallelism" number of
  282. * rows are fetched from NDB and cached in NDBAPI
  283. */
  284. while((check = myScanOp->nextResult(true)) == 0){
  285. do
  286. {
  287. if (myScanOp->deleteCurrentTuple() != 0)
  288. {
  289. std::cout << myTrans->getNdbError().message << std::endl;
  290. myNdb->closeTransaction(myTrans);
  291. return -1;
  292. }
  293. deletedRows++;
  294. /**
  295. * nextResult(false) means that the records
  296. * cached in the NDBAPI are modified before
  297. * fetching more rows from NDB.
  298. */
  299. } while((check = myScanOp->nextResult(false)) == 0);
  300. /**
  301. * Commit when all cached tuple have been marked for deletion
  302. */
  303. if(check != -1)
  304. {
  305. check = myTrans->execute(NdbTransaction::Commit);
  306. }
  307. if(check == -1)
  308. {
  309. /**
  310. * Create a new transaction, while keeping scan open
  311. */
  312. check = myTrans->restart();
  313. }
  314. /**
  315. * Check for errors
  316. */
  317. err = myTrans->getNdbError();
  318. if(check == -1)
  319. {
  320. if(err.status == NdbError::TemporaryError)
  321. {
  322. std::cout << myTrans->getNdbError().message << std::endl;
  323. myNdb->closeTransaction(myTrans);
  324. milliSleep(50);
  325. continue;
  326. }
  327. }
  328. /**
  329. * End of loop
  330. */
  331. }
  332. std::cout << myTrans->getNdbError().message << std::endl;
  333. myNdb->closeTransaction(myTrans);
  334. return 0;
  335. }
  336. if(myTrans!=0)
  337. {
  338. std::cout << myTrans->getNdbError().message << std::endl;
  339. myNdb->closeTransaction(myTrans);
  340. }
  341. return -1;
  342. }
  343. int scan_update(Ndb* myNdb,
  344. int update_column,
  345. const char * before_color,
  346. const char * after_color)
  347. {
  348. // Scan all records exclusive and update
  349. // them one by one
  350. int retryAttempt = 0;
  351. const int retryMax = 10;
  352. int updatedRows = 0;
  353. int check;
  354. NdbError err;
  355. NdbTransaction *myTrans;
  356. NdbScanOperation *myScanOp;
  357. const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  358. const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
  359. if (myTable == NULL)
  360. APIERROR(myDict->getNdbError());
  361. /**
  362. * Loop as long as :
  363. * retryMax not reached
  364. * failed operations due to TEMPORARY erros
  365. *
  366. * Exit loop;
  367. * retyrMax reached
  368. * Permanent error (return -1)
  369. */
  370. while (true)
  371. {
  372. if (retryAttempt >= retryMax)
  373. {
  374. std::cout << "ERROR: has retried this operation " << retryAttempt
  375. << " times, failing!" << std::endl;
  376. return -1;
  377. }
  378. myTrans = myNdb->startTransaction();
  379. if (myTrans == NULL)
  380. {
  381. const NdbError err = myNdb->getNdbError();
  382. if (err.status == NdbError::TemporaryError)
  383. {
  384. milliSleep(50);
  385. retryAttempt++;
  386. continue;
  387. }
  388. std::cout << err.message << std::endl;
  389. return -1;
  390. }
  391. /**
  392. * Get a scan operation.
  393. */
  394. myScanOp = myTrans->getNdbScanOperation(myTable);
  395. if (myScanOp == NULL)
  396. {
  397. std::cout << myTrans->getNdbError().message << std::endl;
  398. myNdb->closeTransaction(myTrans);
  399. return -1;
  400. }
  401. /**
  402. * Define a result set for the scan.
  403. */
  404. if( myScanOp->readTuples(NdbOperation::LM_Exclusive) )
  405. {
  406. std::cout << myTrans->getNdbError().message << std::endl;
  407. myNdb->closeTransaction(myTrans);
  408. return -1;
  409. }
  410. /**
  411. * Use NdbScanFilter to define a search critera
  412. */
  413. NdbScanFilter filter(myScanOp) ;
  414. if(filter.begin(NdbScanFilter::AND) < 0 ||
  415. filter.cmp(NdbScanFilter::COND_EQ, update_column, before_color) <0||
  416. filter.end() <0)
  417. {
  418. std::cout << myTrans->getNdbError().message << std::endl;
  419. myNdb->closeTransaction(myTrans);
  420. return -1;
  421. }
  422. /**
  423. * Start scan (NoCommit since we are only reading at this stage);
  424. */
  425. if(myTrans->execute(NdbTransaction::NoCommit) != 0)
  426. {
  427. err = myTrans->getNdbError();
  428. if(err.status == NdbError::TemporaryError){
  429. std::cout << myTrans->getNdbError().message << std::endl;
  430. myNdb->closeTransaction(myTrans);
  431. milliSleep(50);
  432. continue;
  433. }
  434. std::cout << myTrans->getNdbError().code << std::endl;
  435. myNdb->closeTransaction(myTrans);
  436. return -1;
  437. }
  438. /**
  439. * start of loop: nextResult(true) means that "parallelism" number of
  440. * rows are fetched from NDB and cached in NDBAPI
  441. */
  442. while((check = myScanOp->nextResult(true)) == 0){
  443. do {
  444. /**
  445. * Get update operation
  446. */
  447. NdbOperation * myUpdateOp = myScanOp->updateCurrentTuple();
  448. if (myUpdateOp == 0)
  449. {
  450. std::cout << myTrans->getNdbError().message << std::endl;
  451. myNdb->closeTransaction(myTrans);
  452. return -1;
  453. }
  454. updatedRows++;
  455. /**
  456. * do the update
  457. */
  458. myUpdateOp->setValue(update_column, after_color);
  459. /**
  460. * nextResult(false) means that the records
  461. * cached in the NDBAPI are modified before
  462. * fetching more rows from NDB.
  463. */
  464. } while((check = myScanOp->nextResult(false)) == 0);
  465. /**
  466. * NoCommit when all cached tuple have been updated
  467. */
  468. if(check != -1)
  469. {
  470. check = myTrans->execute(NdbTransaction::NoCommit);
  471. }
  472. /**
  473. * Check for errors
  474. */
  475. err = myTrans->getNdbError();
  476. if(check == -1)
  477. {
  478. if(err.status == NdbError::TemporaryError){
  479. std::cout << myTrans->getNdbError().message << std::endl;
  480. myNdb->closeTransaction(myTrans);
  481. milliSleep(50);
  482. continue;
  483. }
  484. }
  485. /**
  486. * End of loop
  487. */
  488. }
  489. /**
  490. * Commit all prepared operations
  491. */
  492. if(myTrans->execute(NdbTransaction::Commit) == -1)
  493. {
  494. if(err.status == NdbError::TemporaryError){
  495. std::cout << myTrans->getNdbError().message << std::endl;
  496. myNdb->closeTransaction(myTrans);
  497. milliSleep(50);
  498. continue;
  499. }
  500. }
  501. std::cout << myTrans->getNdbError().message << std::endl;
  502. myNdb->closeTransaction(myTrans);
  503. return 0;
  504. }
  505. if(myTrans!=0)
  506. {
  507. std::cout << myTrans->getNdbError().message << std::endl;
  508. myNdb->closeTransaction(myTrans);
  509. }
  510. return -1;
  511. }
  512. int scan_print(Ndb * myNdb)
  513. {
  514. // Scan all records exclusive and update
  515. // them one by one
  516. int retryAttempt = 0;
  517. const int retryMax = 10;
  518. int fetchedRows = 0;
  519. int check;
  520. NdbError err;
  521. NdbTransaction *myTrans;
  522. NdbScanOperation *myScanOp;
  523. /* Result of reading attribute value, three columns:
  524. REG_NO, BRAND, and COLOR
  525. */
  526. NdbRecAttr * myRecAttr[3];
  527. const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
  528. const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
  529. if (myTable == NULL)
  530. APIERROR(myDict->getNdbError());
  531. /**
  532. * Loop as long as :
  533. * retryMax not reached
  534. * failed operations due to TEMPORARY erros
  535. *
  536. * Exit loop;
  537. * retyrMax reached
  538. * Permanent error (return -1)
  539. */
  540. while (true)
  541. {
  542. if (retryAttempt >= retryMax)
  543. {
  544. std::cout << "ERROR: has retried this operation " << retryAttempt
  545. << " times, failing!" << std::endl;
  546. return -1;
  547. }
  548. myTrans = myNdb->startTransaction();
  549. if (myTrans == NULL)
  550. {
  551. const NdbError err = myNdb->getNdbError();
  552. if (err.status == NdbError::TemporaryError)
  553. {
  554. milliSleep(50);
  555. retryAttempt++;
  556. continue;
  557. }
  558. std::cout << err.message << std::endl;
  559. return -1;
  560. }
  561. /*
  562. * Define a scan operation.
  563. * NDBAPI.
  564. */
  565. myScanOp = myTrans->getNdbScanOperation(myTable);
  566. if (myScanOp == NULL)
  567. {
  568. std::cout << myTrans->getNdbError().message << std::endl;
  569. myNdb->closeTransaction(myTrans);
  570. return -1;
  571. }
  572. /**
  573. * Read without locks, without being placed in lock queue
  574. */
  575. if( myScanOp->readTuples(NdbOperation::LM_CommittedRead) == -1)
  576. {
  577. std::cout << myTrans->getNdbError().message << std::endl;
  578. myNdb->closeTransaction(myTrans);
  579. return -1;
  580. }
  581. /**
  582. * Define storage for fetched attributes.
  583. * E.g., the resulting attributes of executing
  584. * myOp->getValue("REG_NO") is placed in myRecAttr[0].
  585. * No data exists in myRecAttr until transaction has commited!
  586. */
  587. myRecAttr[0] = myScanOp->getValue("REG_NO");
  588. myRecAttr[1] = myScanOp->getValue("BRAND");
  589. myRecAttr[2] = myScanOp->getValue("COLOR");
  590. if(myRecAttr[0] ==NULL || myRecAttr[1] == NULL || myRecAttr[2]==NULL)
  591. {
  592. std::cout << myTrans->getNdbError().message << std::endl;
  593. myNdb->closeTransaction(myTrans);
  594. return -1;
  595. }
  596. /**
  597. * Start scan (NoCommit since we are only reading at this stage);
  598. */
  599. if(myTrans->execute(NdbTransaction::NoCommit) != 0){
  600. err = myTrans->getNdbError();
  601. if(err.status == NdbError::TemporaryError){
  602. std::cout << myTrans->getNdbError().message << std::endl;
  603. myNdb->closeTransaction(myTrans);
  604. milliSleep(50);
  605. continue;
  606. }
  607. std::cout << err.code << std::endl;
  608. std::cout << myTrans->getNdbError().code << std::endl;
  609. myNdb->closeTransaction(myTrans);
  610. return -1;
  611. }
  612. /**
  613. * start of loop: nextResult(true) means that "parallelism" number of
  614. * rows are fetched from NDB and cached in NDBAPI
  615. */
  616. while((check = myScanOp->nextResult(true)) == 0){
  617. do {
  618. fetchedRows++;
  619. /**
  620. * print REG_NO unsigned int
  621. */
  622. std::cout << myRecAttr[0]->u_32_value() << "\t";
  623. /**
  624. * print BRAND character string
  625. */
  626. std::cout << myRecAttr[1]->aRef() << "\t";
  627. /**
  628. * print COLOR character string
  629. */
  630. std::cout << myRecAttr[2]->aRef() << std::endl;
  631. /**
  632. * nextResult(false) means that the records
  633. * cached in the NDBAPI are modified before
  634. * fetching more rows from NDB.
  635. */
  636. } while((check = myScanOp->nextResult(false)) == 0);
  637. }
  638. myNdb->closeTransaction(myTrans);
  639. return 1;
  640. }
  641. return -1;
  642. }
  643. int main(int argc, char** argv)
  644. {
  645. if (argc != 3)
  646. {
  647. std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
  648. exit(-1);
  649. }
  650. char * mysqld_sock = argv[1];
  651. const char *connectstring = argv[2];
  652. ndb_init();
  653. MYSQL mysql;
  654. /**************************************************************
  655. * Connect to mysql server and create table *
  656. **************************************************************/
  657. {
  658. if ( !mysql_init(&mysql) ) {
  659. std::cout << "mysql_init failed\n";
  660. exit(-1);
  661. }
  662. if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
  663. 0, mysqld_sock, 0) )
  664. MYSQLERROR(mysql);
  665. mysql_query(&mysql, "CREATE DATABASE TEST_DB");
  666. if (mysql_query(&mysql, "USE TEST_DB") != 0) MYSQLERROR(mysql);
  667. create_table(mysql);
  668. }
  669. /**************************************************************
  670. * Connect to ndb cluster *
  671. **************************************************************/
  672. Ndb_cluster_connection cluster_connection(connectstring);
  673. if (cluster_connection.connect(4, 5, 1))
  674. {
  675. std::cout << "Unable to connect to cluster within 30 secs." << std::endl;
  676. exit(-1);
  677. }
  678. // Optionally connect and wait for the storage nodes (ndbd's)
  679. if (cluster_connection.wait_until_ready(30,0) < 0)
  680. {
  681. std::cout << "Cluster was not ready within 30 secs.\n";
  682. exit(-1);
  683. }
  684. Ndb myNdb(&cluster_connection,"TEST_DB");
  685. if (myNdb.init(1024) == -1) { // Set max 1024 parallel transactions
  686. APIERROR(myNdb.getNdbError());
  687. exit(-1);
  688. }
  689. /*******************************************
  690. * Check table definition *
  691. *******************************************/
  692. int column_color;
  693. {
  694. const NdbDictionary::Dictionary* myDict= myNdb.getDictionary();
  695. const NdbDictionary::Table *t= myDict->getTable("GARAGE");
  696. Car car;
  697. if (t->getColumn("COLOR")->getLength() != sizeof(car.color) ||
  698. t->getColumn("BRAND")->getLength() != sizeof(car.brand))
  699. {
  700. std::cout << "Wrong table definition" << std::endl;
  701. exit(-1);
  702. }
  703. column_color= t->getColumn("COLOR")->getColumnNo();
  704. }
  705. if(populate(&myNdb) > 0)
  706. std::cout << "populate: Success!" << std::endl;
  707. if(scan_print(&myNdb) > 0)
  708. std::cout << "scan_print: Success!" << std::endl << std::endl;
  709. std::cout << "Going to delete all pink cars!" << std::endl;
  710. {
  711. /**
  712. * Note! color needs to be of exact the same size as column defined
  713. */
  714. Car tmp;
  715. sprintf(tmp.color, "Pink");
  716. if(scan_delete(&myNdb, column_color, tmp.color) > 0)
  717. std::cout << "scan_delete: Success!" << std::endl << std::endl;
  718. }
  719. if(scan_print(&myNdb) > 0)
  720. std::cout << "scan_print: Success!" << std::endl << std::endl;
  721. {
  722. /**
  723. * Note! color1 & 2 need to be of exact the same size as column defined
  724. */
  725. Car tmp1, tmp2;
  726. sprintf(tmp1.color, "Blue");
  727. sprintf(tmp2.color, "Black");
  728. std::cout << "Going to update all " << tmp1.color
  729. << " cars to " << tmp2.color << " cars!" << std::endl;
  730. if(scan_update(&myNdb, column_color, tmp1.color, tmp2.color) > 0)
  731. std::cout << "scan_update: Success!" << std::endl << std::endl;
  732. }
  733. if(scan_print(&myNdb) > 0)
  734. std::cout << "scan_print: Success!" << std::endl << std::endl;
  735. /**
  736. * Drop table
  737. */
  738. drop_table(mysql);
  739. return 0;
  740. }