/* 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 */ #ifdef MYSQL5.1.8 #define attrSize get_size_in_bytes #endif /* * 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 * */ #define myUint8 unsigned char #define myUint16 unsigned short #define setlongBufSize(_buffer,size_) *(myUint16*)_buffer = (myUint16) size_; #define setshortBufSize(_buffer,size_) *(myUint8*)_buffer = (myUint8) size_; #include #include // Used for cout #include #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_min(Ndb &); static void do_insert_max(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_min(myNdb); // do_insert_max(myNdb); do_update(myNdb); do_delete(myNdb); do_read(myNdb); } /********************************************************* * Create a table named MYTABLENAME if it does not exist * *********************************************************/ static void create_table(MYSQL &mysql) { /* if (mysql_query(&mysql, "CREATE TABLE" " IMSI " " ( " "MCC INT UNSIGNED NOT NULL," "mainMSISDN VARCHAR(255)," " PRIMARY KEY USING HASH (MCC) ) engine=ndb PARTITION BY KEY (MCC)")) MYSQLERROR(mysql); */ } /***************************************************************** * 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("IMSI"); char buff[300]; char buff1[300]; char buff2[300]; char buff3[300]; char buff4[300]; char buff5[300]; char buff6[300]; char buff7[300]; char buff8[300]; char buff9[300]; char buff10[300]; char buff11[300]; char buff12[300]; char buff13[300]; char buff14[300]; 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("mykey", i); setshortBufSize(buff,1); buff[1]='u'; myOperation->setValue("vvchar",buff); setshortBufSize(buff1,1); buff1[1]='u'; myOperation->setValue("vvBin",buff1); setlongBufSize(buff2,1) buff2[2]='u'; myOperation->setValue("vvlchar",buff2); setlongBufSize(buff3,1) buff3[2]='u'; myOperation->setValue("vvlBin",buff3); myOperation->setValue("vchar","u"); myOperation->setValue("vbinary","u"); (unsigned int )*buff4=(unsigned int)5; myOperation->setValue("vUnsigned",buff4); (Uint64)*buff5=(Uint64)5; myOperation->setValue("vBigunsigned",buff5); (unsigned int)*buff6=(unsigned int)5; myOperation->setValue("vMediumunsigned",buff6); (unsigned char)*buff7=(unsigned char)5; myOperation->setValue("vTinyunsigned",buff7); (unsigned short)*buff8=(unsigned short)5; myOperation->setValue("vSmallunsigned",buff8); (Int64)*buff9=(Int64)5; myOperation->setValue("vBigint",buff9); (int)*buff10=(int)5; myOperation->setValue("vMediumint",buff10); (int)*buff11=(int)5; myOperation->setValue("vInt",buff11); (short)*buff12=(short)5; myOperation->setValue("vSmallint",buff12); *buff13=5; myOperation->setValue("vTinyint",buff13); (Uint64)*buff14=(Uint64)5; myOperation->setValue("vBit",buff14); if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } for(int i=5000;i<5010;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("mykey", i); setshortBufSize(buff,1); buff[1]='v'; myOperation->setValue("vvchar",buff); setshortBufSize(buff1,1); buff1[1]='v'; myOperation->setValue("vvBin",buff1); setlongBufSize(buff2,1) buff2[2]='v'; myOperation->setValue("vvlchar",buff2); setlongBufSize(buff3,1) buff3[2]='v'; myOperation->setValue("vvlBin",buff3); myOperation->setValue("vchar","v"); myOperation->setValue("vbinary","v"); (unsigned int )*buff4=(unsigned int)8; myOperation->setValue("vUnsigned",buff4); (Uint64)*buff5=(Uint64)8; myOperation->setValue("vBigunsigned",buff5); (unsigned int)*buff6=(unsigned int)8; myOperation->setValue("vMediumunsigned",buff6); (unsigned char)*buff7=(unsigned char)8; myOperation->setValue("vTinyunsigned",buff7); (unsigned short)*buff8=(unsigned short)8; myOperation->setValue("vSmallunsigned",buff8); (Int64)*buff9=(Int64)8; myOperation->setValue("vBigint",buff9); (int)*buff10=(int)8; myOperation->setValue("vMediumint",buff10); (int)*buff11=(int)8; myOperation->setValue("vInt",buff11); (short)*buff12=(short)8; myOperation->setValue("vSmallint",buff12); *buff13=8; myOperation->setValue("vTinyint",buff13); (Uint64)*buff14=(Uint64)8; myOperation->setValue("vBit",buff14); 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("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->deleteTuple(); myOperation->equal("mykey", 5); if (myTransaction->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); NdbTransaction *myTransaction1= myNdb.startTransaction(); if (myTransaction1 == NULL) APIERROR(myNdb.getNdbError()); NdbOperation *myOperation1= myTransaction1->getNdbOperation(myTable); if (myOperation1 == NULL) APIERROR(myTransaction1->getNdbError()); myOperation1->deleteTuple(); myOperation1->equal("mykey", 5005); if (myTransaction1->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction1->getNdbError()); } /***************************** * Read and print all tuples * *****************************/ static void do_read(Ndb &myNdb) { const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("IMSI"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for (int i = 0; i < 10000; 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("mykey", i); NdbRecAttr *vvcharRecAttr= myOperation->getValue("vvchar", NULL); NdbRecAttr *vvBinRecAttr= myOperation->getValue("vvBin", NULL); NdbRecAttr *vvlcharRecAttr= myOperation->getValue("vvlchar", NULL); NdbRecAttr *vvlBinRecAttr= myOperation->getValue("vvlBin", NULL); NdbRecAttr *vcharRecAttr= myOperation->getValue("vchar", NULL); NdbRecAttr *vbinaryRecAttr= myOperation->getValue("vbinary", NULL); NdbRecAttr *vUnsignedRecAttr= myOperation->getValue("vUnsigned", NULL); NdbRecAttr *vBigunsignedRecAttr= myOperation->getValue("vBigunsigned", NULL); NdbRecAttr *vMediumunsignedRecAttr= myOperation->getValue("vMediumunsigned", NULL); NdbRecAttr *vTinyunsignedRecAttr= myOperation->getValue("vTinyunsigned", NULL); NdbRecAttr *vSmallunsignedRecAttr= myOperation->getValue("vSmallunsigned", NULL); NdbRecAttr *vBigintRecAttr= myOperation->getValue("vBigint", NULL); NdbRecAttr *vMediumintRecAttr= myOperation->getValue("vMediumint", NULL); NdbRecAttr *vIntRecAttr= myOperation->getValue("vInt", NULL); NdbRecAttr *vSmallintRecAttr= myOperation->getValue("vSmallint", NULL); NdbRecAttr *vTinyintRecAttr= myOperation->getValue("vTinyint", NULL); NdbRecAttr *vBitRecAttr= myOperation->getValue("vBit", NULL); if (vvcharRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vvBinRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vvlcharRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vvlBinRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vcharRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vbinaryRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vUnsignedRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vBigunsignedRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vMediumunsignedRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vTinyunsignedRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vSmallunsignedRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vBigintRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vMediumintRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vIntRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vSmallintRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vTinyintRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if (vBitRecAttr== NULL) APIERROR(myTransaction->getNdbError()); if(myTransaction->execute( NdbTransaction::Commit ) == -1){ if (i == 5 || i==5005) { std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; } else { APIERROR(myTransaction->getNdbError()); } }else{ printf("--------------key %d\n",i); if(vvcharRecAttr->getType()==NdbDictionary::Column::Varchar){ char buffer[500]; int size; char *p; memcpy(buffer,vvcharRecAttr->aRef(),1); size=*(Uint8*)buffer; memcpy(buffer,vvcharRecAttr->aRef(),size+1); p=buffer+1; for(int i=0;igetType()==NdbDictionary::Column::Varbinary){ char buffer[500]; int size; char *p; memcpy(buffer,vvBinRecAttr->aRef(),1); size=*(Uint8*)buffer; memcpy(buffer,vvBinRecAttr->aRef(),size+1); p=buffer+1; for(int i=0;igetType()==NdbDictionary::Column::Longvarchar){ char buffer[500]; int size; char *p; memcpy(buffer,vvlcharRecAttr->aRef(),2); size=*(Uint16*)buffer; memcpy(buffer,vvlBinRecAttr->aRef(),size+2); p=buffer+2; for(int i=0;igetType()==NdbDictionary::Column::Longvarbinary){ char buffer[500]; int size; char *p; memcpy(buffer,vvlBinRecAttr->aRef(),2); size=*(Uint16*)buffer; memcpy(buffer,vvlBinRecAttr->aRef(),size+2); p=buffer+2; for(int i=0;igetType()==NdbDictionary::Column::Char){ char buffer[500]; memcpy(buffer,vcharRecAttr->aRef(),256); printf("%s\n",buffer); } if(vbinaryRecAttr->getType()==NdbDictionary::Column::Binary){ char buffer[500]; memcpy(buffer,vbinaryRecAttr->aRef(),256); printf("%s\n",buffer); } if (vUnsignedRecAttr->getType()==NdbDictionary::Column::Unsigned){ unsigned int x=*(unsigned int*)(vUnsignedRecAttr->aRef()); printf("%u\n",x); } if (vBigunsignedRecAttr->getType()==NdbDictionary::Column::Bigunsigned){ unsigned long long x=(unsigned long long)*(vBigunsignedRecAttr->aRef()); printf("%Lu\n",x); } if (vMediumunsignedRecAttr->getType()==NdbDictionary::Column::Mediumunsigned){ unsigned int x=0; memcpy(&x,vMediumunsignedRecAttr->aRef(),3); //x=(unsigned int)*(vMediumunsignedRecAttr->aRef()); printf("%lu\n",x); } if (vTinyunsignedRecAttr->getType()==NdbDictionary::Column::Tinyunsigned){ unsigned char x=(unsigned char)*(vTinyunsignedRecAttr->aRef()); printf("%u\n",x); } if (vSmallunsignedRecAttr->getType()==NdbDictionary::Column::Smallunsigned){ unsigned short x=(unsigned short)*(vSmallunsignedRecAttr->aRef()); printf("%u\n",x); } if (vBigintRecAttr->getType()==NdbDictionary::Column::Bigint){ long long x=0; memcpy(&x,vBigintRecAttr->aRef(),8); printf("%Ld\n",x); } if (vMediumintRecAttr->getType()==NdbDictionary::Column::Mediumint){ unsigned int x= *(unsigned int*)vMediumintRecAttr->aRef(); printf("%d\n",x); } if (vIntRecAttr->getType()==NdbDictionary::Column::Int){ int x=0; memcpy(&x,vIntRecAttr->aRef(),4); printf("%d\n",x); } if (vSmallintRecAttr->getType()==NdbDictionary::Column::Smallint){ short x=0; memcpy(&x,vSmallintRecAttr->aRef(),2); printf("%d\n",x); } if (vTinyintRecAttr->getType()==NdbDictionary::Column::Tinyint){ char x=0; x=*(char*)vTinyintRecAttr->aRef(); printf("%d\n",x); } if (vBitRecAttr->getType()==NdbDictionary::Column::Bit){ Uint64 x= *(Uint64*)vBitRecAttr->aRef(); printf("%Lu\n",x); } /* case NdbDictionary::Column::Bit: return new (ac_) MysBitAttribute(this); break; */ } myNdb.closeTransaction(myTransaction); } }