/* 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; either version 2 of the License, or (at your option) any later version. 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_simple.cpp: Using synchronous transactions in NDB API * * Correct output from this program is: * * ATTR1 ATTR2 * 0 10 * 1 1 * 2 12 * Detected that deleted tuple doesn't exist! * 4 14 * 5 5 * 6 16 * 7 7 * 8 18 * 9 9 * */ #include #include // Used for cout #include #include static void run_application(MYSQL &, Ndb_cluster_connection &); #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); } 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 */)) { std::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) { std::cout << "Cluster was not ready within 30 secs.\n"; exit(-1); } // connect to mysql server MYSQL mysql; if ( !mysql_init(&mysql) ) { std::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); std::cout << "\nTo drop created table use:\n" << "echo \"drop table IMSI\" | mysql hlr -u root\n"; return 0; } static void create_table(MYSQL &); static void do_insert(Ndb &); static void do_update(Ndb &); static void do_delete(Ndb &); static void do_read(Ndb &); static void run_application(MYSQL &mysql, Ndb_cluster_connection &cluster_connection) { /******************************************** * Connect to database via mysql-c * ********************************************/ if (mysql_query(&mysql, "USE hlr") != 0) MYSQLERROR(mysql); /******************************************** * Connect to database via NdbApi * ********************************************/ // Object representing the database Ndb myNdb( &cluster_connection, "hlr" ); if (myNdb.init()) APIERROR(myNdb.getNdbError()); /* * Do different operations on database */ //create_table(mysql); do_insert(myNdb); } /********************************************************* * Create a table named MYTABLENAME if it does not exist * *********************************************************/ static void create_table(MYSQL &mysql) { /* if (mysql_query(&mysql, "CREATE TABLE" " IMSI " " ( " "MSIN CHAR(11) NOT NULL," "MNC CHAR(4) NOT NULL," "MCC CHAR(4) NOT NULL," "mainMSISDN VARBINARY(21)," "alertMSISDN VARBINARY(21)," "associatedMSISDN VARBINARY(151)," "bitAttr BIT(1)," "bit33Attr BIT(33)," "charAttr CHAR(1)," "shortAttr SMALLINT," "int32Attr INT UNSIGNED," "int64Attr BIGINT UNSIGNED," "stringAttr CHAR(16)," "bcdAttr BINARY(10)," "binAttr BINARY(16)," "bcdset BINARY(35)," "bcdarr BINARY(35)," "binset BINARY(21)," "binarr BINARY(31)," "crossJoinIdx VARBINARY(7)," "suMSubscriptionProfileId INT," "suMSubscriberProfileId CHAR(12)," " PRIMARY KEY USING HASH (MSIN,MNC,MCC) ) engine=ndb PARTITION BY KEY (MSIN)")) MYSQLERROR(mysql); */ } /************************************************************************** * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) * **************************************************************************/ static void do_insert(Ndb &myNdb) { char buff[100]; char buff1[100]; const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("IMSI"); if (myTable == NULL) APIERROR(myDict->getNdbError()); 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("MSIN", "888889"); myOperation->equal("MNC", "1"); myOperation->equal("MCC", "1"); buff[0]=1; buff[1]=2; buff1[0]=1; buff1[1]=3; myOperation->setValue("mainMSISDN",buff); myOperation->setValue("alertMSISDN",buff1); if (myTransaction->execute( NdbTransaction::Commit ) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } /***************************************************************** * Update the second attribute in half of the tuples (adding 10) * *****************************************************************/ static void do_update(Ndb &myNdb) { const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for (int i = 0; i < 10; i+=2) { NdbTransaction *myTransaction= myNdb.startTransaction(); if (myTransaction == NULL) APIERROR(myNdb.getNdbError()); NdbOperation *myOperation= myTransaction->getNdbOperation(myTable); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->updateTuple(); myOperation->equal( "ATTR1", i ); myOperation->setValue( "ATTR2", i+10); if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } } /************************************************* * Delete one tuple (the one with primary key 3) * *************************************************/ static void do_delete(Ndb &myNdb) { const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME"); if (myTable == NULL) APIERROR(myDict->getNdbError()); 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", 3 ); if (myTransaction->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } /***************************** * Read and print all tuples * *****************************/ static void do_read(Ndb &myNdb) { const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME"); if (myTable == NULL) APIERROR(myDict->getNdbError()); std::cout << "ATTR1 ATTR2" << std::endl; 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->readTuple(NdbOperation::LM_Read); myOperation->equal("ATTR1", i); NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL); if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); if(myTransaction->execute( NdbTransaction::Commit ) == -1) if (i == 3) { std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; } else { APIERROR(myTransaction->getNdbError()); } if (i != 3) { printf(" %2d %2d\n", i, myRecAttr->u_32_value()); } myNdb.closeTransaction(myTransaction); } }