#include #include // Used for cout #include #include namespace std {} using namespace std; static void run_application(MYSQL &, Ndb_cluster_connection &); #define PRINT_ERROR(code,msg) \ cout << "Error in " << __FILE__ << ", line: " << __LINE__ \ << ", code: " << code \ << ", msg: " << msg << "." << 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); } int main() { // ndb_init must be called first ndb_init(); // connect to mysql server and cluster and run application { // Object representing the cluster Ndb_cluster_connection cluster_connection; // Connect to cluster management server (ndb_mgmd) if (cluster_connection.connect(4 /* retries */, 5 /* delay between retries */, 1 /* verbose */)) { cout << "Cluster management server was not ready within 30 secs.\n"; exit(-1); } // Optionally connect and wait for the storage nodes (ndbd's) if (cluster_connection.wait_until_ready(30,0) < 0) { cout << "Cluster was not ready within 30 secs.\n"; exit(-1); } // connect to mysql server MYSQL mysql; if ( !mysql_init(&mysql) ) { cout << "mysql_init failed\n"; exit(-1); } if ( !mysql_real_connect(&mysql, "localhost", "root", "", "", 3306, "/tmp/mysql.sock", 0) ) MYSQLERROR(mysql); // run the application code run_application(mysql, cluster_connection); } ndb_end(0); cout << "\nTo drop created table use:\n" << "echo \"drop table mytablename\" | mysql test_db_1 -u root\n"; return 0; } static void create_table(MYSQL &); static void run_application(MYSQL &mysql, Ndb_cluster_connection &cluster_connection) { /******************************************** * Connect to database via mysql-c * ********************************************/ mysql_query(&mysql, "CREATE DATABASE test_db_1"); if (mysql_query(&mysql, "USE test_db_1") != 0) MYSQLERROR(mysql); create_table(mysql); /******************************************** * Connect to database via NdbApi * ********************************************/ // Object representing the database Ndb myNdb( &cluster_connection, "test_db_1" ); if (myNdb.init()) APIERROR(myNdb.getNdbError()); const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("mytablename"); if (myTable == NULL) APIERROR(myDict->getNdbError()); // Populate table for (int i = 0; i < 10; i++) { NdbTransaction *myTransaction= myNdb.startTransaction(); if (myTransaction == NULL) APIERROR(myNdb.getNdbError()); NdbOperation *myOperation= myTransaction->getNdbOperation(myTable); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->insertTuple(); myOperation->equal("ATTR1", i); myOperation->setValue("ATTR2", 0); if (myTransaction->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } // Do interpretedUpdateTuple with interpret_exit_nok operation { for (int i = 0; i < 10; i++) { NdbTransaction *updateTrans = myNdb.startTransaction(); if (updateTrans == NULL) APIERROR(myNdb.getNdbError()); NdbOperation *updateOp = updateTrans->getNdbOperation(myTable); if (updateTrans == NULL) APIERROR(updateTrans->getNdbError()); if (updateOp->interpretedUpdateTuple() < 0) APIERROR(updateOp->getNdbError()); if (updateOp->equal("ATTR1", i) < 0) APIERROR(updateOp->getNdbError()); if (updateOp->interpret_exit_nok() < 0) APIERROR(updateOp->getNdbError()); // The following execute always returns -1 because of the interpret_exit_nok, so, do not check the return code here. updateTrans->execute(NdbTransaction::Commit); //if (updateTrans->execute(NdbTransaction::Commit) == -1) // APIERROR(updateTrans->getNdbError()); myNdb.closeTransaction(updateTrans); } } // Clean table { for (int i = 0; i < 10; i++) { NdbTransaction *myTransaction= myNdb.startTransaction(); if (myTransaction == NULL) APIERROR(myNdb.getNdbError()); NdbOperation *myOperation= myTransaction->getNdbOperation(myTable); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->deleteTuple(); myOperation->equal("ATTR1", i); if (myTransaction->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } } } /********************************************************* * Create a table named mytablename if it does not exist * *********************************************************/ static void create_table(MYSQL &mysql) { if (mysql_query(&mysql, "CREATE TABLE" " mytablename" " (ATTR1 INT UNSIGNED NOT NULL PRIMARY KEY," " ATTR2 INT UNSIGNED NOT NULL)" " ENGINE=NDB")) MYSQLERROR(mysql); }