#At https://bazaar.launchpad.net/~ndb-bindings/ndb-bindings/trunk
412 Monty Taylor 2008-06-19
Added ndbapi_scan example program.
added:
cpp/ndbapi_scan.cpp
modified:
.bzrignore
cpp/Makefile.am
=== modified file '.bzrignore'
--- a/.bzrignore 2008-05-08 19:23:13 +0000
+++ b/.bzrignore 2008-06-19 17:54:46 +0000
@@ -301,3 +301,4 @@ mgmpp/.libs
mgmpp/.deps
perl/lib
java/.settings
+cpp/ndbapi_scan
=== modified file 'cpp/Makefile.am'
--- a/cpp/Makefile.am 2008-04-29 02:06:37 +0000
+++ b/cpp/Makefile.am 2008-06-19 17:54:46 +0000
@@ -1,4 +1,5 @@
bin_PROGRAMS = ndbapi_simple_index \
+ ndbapi_scan \
testchars \
teststrins \
testdateins \
@@ -10,6 +11,7 @@ bin_PROGRAMS = ndbapi_simple_index \
LDADD = -lmysqlclient_r
ndbapi_simple_index_SOURCES = ndbapi_simple_index.cpp
+ndbapi_scan_SOURCES = ndbapi_scan.cpp
testchars_SOURCES = testchars.cpp
teststrins_SOURCES = teststrins.cpp
testdateins_SOURCES = testdateins.cpp
=== added file 'cpp/ndbapi_scan.cpp'
--- a/cpp/ndbapi_scan.cpp 1970-01-01 00:00:00 +0000
+++ b/cpp/ndbapi_scan.cpp 2008-06-19 17:54:46 +0000
@@ -0,0 +1,847 @@
+
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ * ndbapi_scan.cpp:
+ * Illustrates how to use the scan api in the NDBAPI.
+ * The example shows how to do scan, scan for update and scan for delete
+ * using NdbScanFilter and NdbScanOperation
+ *
+ * Classes and methods used in this example:
+ *
+ * Ndb_cluster_connection
+ * connect()
+ * wait_until_ready()
+ *
+ * Ndb
+ * init()
+ * getDictionary()
+ * startTransaction()
+ * closeTransaction()
+ *
+ * NdbTransaction
+ * getNdbScanOperation()
+ * execute()
+ *
+ * NdbScanOperation
+ * getValue()
+ * readTuples()
+ * nextResult()
+ * deleteCurrentTuple()
+ * updateCurrentTuple()
+ *
+ * const NdbDictionary::Dictionary
+ * getTable()
+ *
+ * const NdbDictionary::Table
+ * getColumn()
+ *
+ * const NdbDictionary::Column
+ * getLength()
+ *
+ * NdbOperation
+ * insertTuple()
+ * equal()
+ * setValue()
+ *
+ * NdbScanFilter
+ * begin()
+ * eq()
+ * end()
+ *
+ */
+
+
+#include <mysql.h>
+#include <mysqld_error.h>
+#include <NdbApi.hpp>
+// Used for cout
+#include <iostream>
+#include <stdio.h>
+
+/**
+ * Helper sleep function
+ */
+static void
+milliSleep(int milliseconds){
+ struct timeval sleeptime;
+ sleeptime.tv_sec = milliseconds / 1000;
+ sleeptime.tv_usec = (milliseconds - (sleeptime.tv_sec * 1000)) * 1000000;
+ select(0, 0, 0, 0, &sleeptime);
+}
+
+
+/**
+ * Helper debugging macros
+ */
+#define PRINT_ERROR(code,msg) \
+ std::cout << "Error in " << __FILE__ << ", line: " << __LINE__
\
+ << ", code: " << code \
+ << ", msg: " << msg << "." << std::endl
+#define MYSQLERROR(mysql) { \
+ PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
+ exit(-1); }
+#define APIERROR(error) { \
+ PRINT_ERROR(error.code,error.message); \
+ exit(-1); }
+
+struct Car
+{
+ /**
+ * Note memset, so that entire char-fields are cleared
+ * as all 20 bytes are significant (as type is char)
+ */
+ Car() { memset(this, 0, sizeof(* this)); }
+
+ unsigned int reg_no;
+ char brand[20];
+ char color[20];
+};
+
+/**
+ * Function to drop table
+ */
+void drop_table(MYSQL &mysql)
+{
+ if (mysql_query(&mysql, "DROP TABLE GARAGE"))
+ MYSQLERROR(mysql);
+}
+
+
+/**
+ * Function to create table
+ */
+void create_table(MYSQL &mysql)
+{
+ while (mysql_query(&mysql,
+ "CREATE TABLE"
+ " GARAGE"
+ " (REG_NO INT UNSIGNED NOT NULL,"
+ " BRAND CHAR(20) NOT NULL,"
+ " COLOR CHAR(20) NOT NULL,"
+ " PRIMARY KEY USING HASH (REG_NO))"
+ " ENGINE=NDB"))
+ {
+ if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR)
+ MYSQLERROR(mysql);
+ std::cout << "MySQL Cluster already has example table: GARAGE. "
+ << "Dropping it..." << std::endl;
+ /******************
+ * Drop table *
+ ******************/
+ drop_table(mysql);
+ }
+}
+
+int populate(Ndb * myNdb)
+{
+ int i;
+ Car cars[15];
+
+ const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
+ const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
+
+ if (myTable == NULL)
+ APIERROR(myDict->getNdbError());
+
+ /**
+ * Five blue mercedes
+ */
+ for (i = 0; i < 5; i++)
+ {
+ cars[i].reg_no = i;
+ sprintf(cars[i].brand, "Mercedes");
+ sprintf(cars[i].color, "Blue");
+ }
+
+ /**
+ * Five black bmw
+ */
+ for (i = 5; i < 10; i++)
+ {
+ cars[i].reg_no = i;
+ sprintf(cars[i].brand, "BMW");
+ sprintf(cars[i].color, "Black");
+ }
+
+ /**
+ * Five pink toyotas
+ */
+ for (i = 10; i < 15; i++)
+ {
+ cars[i].reg_no = i;
+ sprintf(cars[i].brand, "Toyota");
+ sprintf(cars[i].color, "Pink");
+ }
+
+ NdbTransaction* myTrans = myNdb->startTransaction();
+ if (myTrans == NULL)
+ APIERROR(myNdb->getNdbError());
+
+ for (i = 0; i < 15; i++)
+ {
+ NdbOperation* myNdbOperation = myTrans->getNdbOperation(myTable);
+ if (myNdbOperation == NULL)
+ APIERROR(myTrans->getNdbError());
+ myNdbOperation->insertTuple();
+ myNdbOperation->equal("REG_NO", cars[i].reg_no);
+ myNdbOperation->setValue("BRAND", cars[i].brand);
+ myNdbOperation->setValue("COLOR", cars[i].color);
+ }
+
+ int check = myTrans->execute(NdbTransaction::Commit);
+
+ myTrans->close();
+
+ return check != -1;
+}
+
+int scan_delete(Ndb* myNdb,
+ const NdbDictionary::Column * 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->getColumnNo(),
+ color, column->getLength()) < 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;
+}
+
+
+int scan_update(Ndb* myNdb,
+ const NdbDictionary::Column * update_column,
+ const char * before_color,
+ const char * after_color)
+
+{
+
+ // Scan all records exclusive and update
+ // them one by one
+ int retryAttempt = 0;
+ const int retryMax = 10;
+ int updatedRows = 0;
+ int check;
+ NdbError err;
+ NdbTransaction *myTrans;
+ NdbScanOperation *myScanOp;
+
+ const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
+ const NdbDictionary::Table *myTable= myDict->getTable("GARAGE");
+
+ Uint32 update_column_id = update_column->getColumnNo();
+
+ 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) )
+ {
+ 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, update_column_id,
+ before_color, update_column->getLength()) <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 << 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 {
+ /**
+ * Get update operation
+ */
+ NdbOperation * myUpdateOp = myScanOp->updateCurrentTuple();
+ if (myUpdateOp == 0)
+ {
+ std::cout << myTrans->getNdbError().message << std::endl;
+ myNdb->closeTransaction(myTrans);
+ return -1;
+ }
+ updatedRows++;
+
+ /**
+ * do the update
+ */
+ myUpdateOp->setValue(update_column_id, after_color);
+ /**
+ * nextResult(false) means that the records
+ * cached in the NDBAPI are modified before
+ * fetching more rows from NDB.
+ */
+ } while((check = myScanOp->nextResult(false)) == 0);
+
+ /**
+ * NoCommit when all cached tuple have been updated
+ */
+ if(check != -1)
+ {
+ check = myTrans->execute(NdbTransaction::NoCommit);
+ }
+
+ /**
+ * 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
+ */
+ }
+
+ /**
+ * Commit all prepared operations
+ */
+ if(myTrans->execute(NdbTransaction::Commit) == -1)
+ {
+ if(err.status == NdbError::TemporaryError){
+ std::cout << myTrans->getNdbError().message << std::endl;
+ myNdb->closeTransaction(myTrans);
+ milliSleep(50);
+ continue;
+ }
+ }
+
+ 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;
+}
+
+
+
+int scan_print(Ndb * myNdb)
+{
+// Scan all records exclusive and update
+ // them one by one
+ int retryAttempt = 0;
+ const int retryMax = 10;
+ int fetchedRows = 0;
+ int check;
+ NdbError err;
+ NdbTransaction *myTrans;
+ NdbScanOperation *myScanOp;
+ /* Result of reading attribute value, three columns:
+ REG_NO, BRAND, and COLOR
+ */
+ NdbRecAttr * myRecAttr[3];
+
+ 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;
+ }
+ /*
+ * Define a scan operation.
+ * NDBAPI.
+ */
+ myScanOp = myTrans->getNdbScanOperation(myTable);
+ if (myScanOp == NULL)
+ {
+ std::cout << myTrans->getNdbError().message << std::endl;
+ myNdb->closeTransaction(myTrans);
+ return -1;
+ }
+
+ /**
+ * Read without locks, without being placed in lock queue
+ */
+ if( myScanOp->readTuples(NdbOperation::LM_CommittedRead) == -1)
+ {
+ std::cout << myTrans->getNdbError().message << std::endl;
+ myNdb->closeTransaction(myTrans);
+ return -1;
+ }
+
+ /**
+ * Define storage for fetched attributes.
+ * E.g., the resulting attributes of executing
+ * myOp->getValue("REG_NO") is placed in myRecAttr[0].
+ * No data exists in myRecAttr until transaction has commited!
+ */
+ myRecAttr[0] = myScanOp->getValue("REG_NO");
+ myRecAttr[1] = myScanOp->getValue("BRAND");
+ myRecAttr[2] = myScanOp->getValue("COLOR");
+ if(myRecAttr[0] ==NULL || myRecAttr[1] == NULL || myRecAttr[2]==NULL)
+ {
+ 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 {
+
+ fetchedRows++;
+ /**
+ * print REG_NO unsigned int
+ */
+ std::cout << myRecAttr[0]->u_32_value() << "\t";
+
+ /**
+ * print BRAND character string
+ */
+ std::cout << myRecAttr[1]->aRef() << "\t";
+
+ /**
+ * print COLOR character string
+ */
+ std::cout << myRecAttr[2]->aRef() << std::endl;
+
+ /**
+ * nextResult(false) means that the records
+ * cached in the NDBAPI are modified before
+ * fetching more rows from NDB.
+ */
+ } while((check = myScanOp->nextResult(false)) == 0);
+
+ }
+ myNdb->closeTransaction(myTrans);
+ return 1;
+ }
+ return -1;
+
+}
+
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ std::cout << "Arguments are <socket mysqld> <connect_string
cluster>.\n";
+ exit(-1);
+ }
+ char * mysqld_sock = argv[1];
+ const char *connectstring = argv[2];
+ ndb_init();
+ MYSQL mysql;
+
+ /**************************************************************
+ * Connect to mysql server and create table *
+ **************************************************************/
+ {
+ if ( !mysql_init(&mysql) ) {
+ std::cout << "mysql_init failed\n";
+ exit(-1);
+ }
+ if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
+ 0, mysqld_sock, 0) )
+ MYSQLERROR(mysql);
+
+ mysql_query(&mysql, "CREATE DATABASE TEST_DB");
+ if (mysql_query(&mysql, "USE TEST_DB") != 0) MYSQLERROR(mysql);
+
+ create_table(mysql);
+ }
+
+ /**************************************************************
+ * Connect to ndb cluster *
+ **************************************************************/
+
+ Ndb_cluster_connection cluster_connection(connectstring);
+ if (cluster_connection.connect(4, 5, 1))
+ {
+ std::cout << "Unable to connect to cluster within 30 secs." << std::endl;
+ exit(-1);
+ }
+ // Optionally connect and wait for the storage nodes (ndbd's)
+ if (cluster_connection.wait_until_ready(30,0) < 0)
+ {
+ std::cout << "Cluster was not ready within 30 secs.\n";
+ exit(-1);
+ }
+
+ Ndb myNdb(&cluster_connection,"TEST_DB");
+ if (myNdb.init(1024) == -1) { // Set max 1024 parallel transactions
+ APIERROR(myNdb.getNdbError());
+ exit(-1);
+ }
+
+ const NdbDictionary::Dictionary* myDict= myNdb.getDictionary();
+ const NdbDictionary::Table *t= myDict->getTable("GARAGE");
+ const NdbDictionary::Column * column_color = t->getColumn("COLOR");
+ const NdbDictionary::Column * column_brand = t->getColumn("BRAND");
+
+ /*******************************************
+ * Check table definition *
+ *******************************************/
+ {
+ Car car;
+ if (column_color->getLength() != sizeof(car.color) ||
+ column_brand->getLength() != sizeof(car.brand))
+ {
+ std::cout << "Wrong table definition" << std::endl;
+ exit(-1);
+ }
+ }
+
+ if(populate(&myNdb) > 0)
+ std::cout << "populate: Success!" << std::endl;
+
+ if(scan_print(&myNdb) > 0)
+ std::cout << "scan_print: Success!" << std::endl << std::endl;
+
+ std::cout << "Going to delete all pink cars!" << std::endl;
+
+ {
+ /**
+ * Note! color needs to be of exact the same size as column defined
+ */
+ Car tmp;
+ sprintf(tmp.color, "Pink");
+ if(scan_delete(&myNdb, column_color, tmp.color) > 0)
+ std::cout << "scan_delete: Success!" << std::endl << std::endl;
+ }
+
+ if(scan_print(&myNdb) > 0)
+ std::cout << "scan_print: Success!" << std::endl << std::endl;
+
+ {
+ /**
+ * Note! color1 & 2 need to be of exact the same size as column defined
+ */
+ Car tmp1, tmp2;
+ sprintf(tmp1.color, "Blue");
+ sprintf(tmp2.color, "Black");
+ std::cout << "Going to update all " << tmp1.color
+ << " cars to " << tmp2.color << " cars!" << std::endl;
+ if(scan_update(&myNdb, column_color, tmp1.color, tmp2.color) > 0)
+ std::cout << "scan_update: Success!" << std::endl << std::endl;
+ }
+ if(scan_print(&myNdb) > 0)
+ std::cout << "scan_print: Success!" << std::endl << std::endl;
+
+ /**
+ * Drop table
+ */
+ drop_table(mysql);
+
+ return 0;
+}
| Thread |
|---|
| • bzr commit into NDB/Bindings:trunk branch (monty:412) | Monty Taylor | 20 Jun |