/* 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); */ } static void do_insert_max(Ndb &myNdb) { char buff[300]; char buff1[300]; char buff2[300]; char buff3[300]; char buff4[300]; char buff5[300]; char *t255=\ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ 0123456789012345678901234567890123456789012345678901234"; char *t256=\ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ 01234567890123456789012345678901234567890123456789012345"; const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("IMSI"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for(int i=5000;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->insertTuple(); myOperation->equal("mykey", i); // setshortBufSize(buff,255) memcpy((char *)(buff+1),t255,256); myOperation->setValue("vvchar",buff); setshortBufSize(buff1,255) memcpy((char *)(buff1+1),t255,256); myOperation->setValue("vvBin",buff1); setlongBufSize(buff2,256) memcpy((char *)(buff2+2),t256,257); myOperation->setValue("vvlchar",buff2); setlongBufSize(buff3,256) memcpy((char *)(buff3+2),t256,257); myOperation->setValue("vvlBin",buff3); // memcpy(buff4,t255,255); buff4[255]='\0'; myOperation->setValue("vchar",buff4); memcpy(buff5,t255,255); buff5[255]='\0'; myOperation->setValue("vbinary",buff5); unsigned int buff4=4294967295; myOperation->setValue("vUnsigned",(char *)&buff4); Uint64 buff5=18446744073709551615; myOperation->setValue("vBigunsigned",(char *)&buff5); unsigned int buff6=16777215; myOperation->setValue("vMediumunsigned",(char *)&buff6); unsigned char buff7=255; myOperation->setValue("vTinyunsigned",(char *)&buff7); unsigned short buff8=65535; myOperation->setValue("vSmallunsigned",(char *)&buff8); Int64 buff9=9223372036854775807; myOperation->setValue("vBigint",(char *)&buff9); int buff10=8388607; myOperation->setValue("vMediumint",(char *)&buff10); int buff11=2147483647; myOperation->setValue("vInt",(char *)&buff11); short buff12=32767; myOperation->setValue("vSmallint",(char *)&buff12); char buff13=127; myOperation->setValue("vTinyint",(char *)&buff13); Uint64 buff14=1023; myOperation->setValue("vBit",(char *)&buff14); if (myTransaction->execute( NdbTransaction::Commit ) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } } /************************************************************************** * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) * **************************************************************************/ static void do_insert_min(Ndb &myNdb) { char buff[300]; char buff1[300]; char buff2[300]; char buff3[300]; char buff4[300]; char buff5[300]; const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("IMSI"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for(int i=0;i<5000;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("mykey", i); // // setshortBufSize(buff,1); buff[1]=65; myOperation->setValue("vvchar",buff); setshortBufSize(buff1,1); buff1[1]=65; myOperation->setValue("vvBin",buff1); setlongBufSize(buff2,1) buff2[2]=65; myOperation->setValue("vvlchar",buff2); setlongBufSize(buff3,1) buff3[2]=65; myOperation->setValue("vvlBin",buff3); buff4[0]='1'; buff4[1]='\0'; myOperation->setValue("vchar",buff4); buff5[0]='1'; buff5[1]='\0'; myOperation->setValue("vbinary",buff5); unsigned int buff4=0; myOperation->setValue("vUnsigned",(char *)&buff4); Uint64 buff5=0; myOperation->setValue("vBigunsigned",(char *)&buff5); unsigned int buff6=0; myOperation->setValue("vMediumunsigned",(char *)&buff6); unsigned char buff7=0; myOperation->setValue("vTinyunsigned",(char *)&buff7); unsigned short buff8=0; myOperation->setValue("vSmallunsigned",(char *)&buff8); Int64 buff9=-9223372036854775808; myOperation->setValue("vBigint",(char *)&buff9); int buff10=-8388608; myOperation->setValue("vMediumint",(char *)&buff10); int buff11=-2147483648; myOperation->setValue("vInt",(char *)&buff11); short buff12=-32768; myOperation->setValue("vSmallint",(char *)&buff12); char buff13=-128; myOperation->setValue("vTinyint",(char *)&buff13); Uint64 buff14=0; myOperation->setValue("vBit",(char *)&buff14); 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("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]; char buff15[300]; char buff16[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); buff15[0]='u'; buff15[1]='\0'; myOperation->setValue("vchar",buff15); buff16[0]='u'; buff16[1]='\0'; myOperation->setValue("vbinary",buff16); (Uint32)*buff4=(Uint32)5; myOperation->setValue("vUnsigned",buff4); (Uint64)*buff5=(Uint64)5; myOperation->setValue("vBigunsigned",buff5); (Uint32)*buff6=(Uint32)5; myOperation->setValue("vMediumunsigned",buff6); (Uint32)*buff7=(Uint32)5; myOperation->setValue("vTinyunsigned",buff7); (Uint32)*buff8=(Uint32)5; myOperation->setValue("vSmallunsigned",buff8); (Int64)*buff9=(Int64)5;; myOperation->setValue("vBigint",buff9); (Uint32)*buff10=(Uint32)5; myOperation->setValue("vMediumint",buff10); (Uint32)*buff11=(Uint32)5; myOperation->setValue("vInt",buff11); (Uint32)*buff12=(Uint32)5; myOperation->setValue("vSmallint",buff12); (Uint32)*buff13=(Uint32)5; myOperation->setValue("vTinyint",buff13); (Uint64)*buff14=(Uint64)5; if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); } for(int i=10;i<20;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); buff15[0]='v'; buff15[1]='\0'; myOperation->setValue("vchar","v"); buff16[0]='v'; buff16[1]='\0'; myOperation->setValue("vbinary","v"); (Uint32)*buff4=(Uint32)8; myOperation->setValue("vUnsigned",buff4); (Uint64)*buff5=(Uint64)8; myOperation->setValue("vBigunsigned",buff5); (Uint32)*buff6=(Uint32)8; myOperation->setValue("vMediumunsigned",buff6); (Uint32)*buff7=(Uint32)8; myOperation->setValue("vTinyunsigned",buff7); (Uint32)*buff8=(Uint32)8; myOperation->setValue("vSmallunsigned",buff8); (Int64)*buff9=(Int64)8; myOperation->setValue("vBigint",buff9); (Uint32)*buff10=(Uint32)8; myOperation->setValue("vMediumint",buff10); (Uint32)*buff11=(Uint32)8; myOperation->setValue("vInt",buff11); (Uint32)*buff12=(Uint32)8; myOperation->setValue("vSmallint",buff12); (Uint32)*buff13=(Uint32)8; myOperation->setValue("vTinyint",buff13); (Uint64)*buff14=(Uint64)8; /* myOperation->setValue("vUnsigned",8); myOperation->setValue("vBigunsigned",(Uint64)8); myOperation->setValue("vMediumunsigned",8); myOperation->setValue("vTinyunsigned",8); myOperation->setValue("vSmallunsigned",8); myOperation->setValue("vBigint",(long long)8); myOperation->setValue("vMediumint",(int)8); myOperation->setValue((const char *)"vInt",(long long int)8); myOperation->setValue("vSmallint",8); myOperation->setValue("vTinyint",8); myOperation->setValue("vBit",8); */ 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); /* myOperation->deleteTuple(); myOperation->equal("mykey", 16); */ 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("IMSI"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for (int i = 0; i < 20; 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==16) { 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; printf("%d ",vvcharRecAttr->attrSize()); memcpy(buffer,vvcharRecAttr->aRef(),vvcharRecAttr->attrSize()); size=*(Uint8*)buffer; p=buffer+1; printf("%d ",size); for(int i=0;igetType()==NdbDictionary::Column::Varbinary){ char buffer[500]; int size; char *p; printf("%d ",vvBinRecAttr->attrSize()); memcpy(buffer,vvBinRecAttr->aRef(),vvBinRecAttr->attrSize()); size=*(Uint8*)buffer; p=buffer+1; printf("%d ",size); for(int i=0;igetType()==NdbDictionary::Column::Longvarchar){ char buffer[500]; int size; char *p; printf("%d ",vvlcharRecAttr->attrSize()); memcpy(buffer,vvlcharRecAttr->aRef(),vvlcharRecAttr->attrSize()); size=*(Uint16*)buffer; p=buffer+2; printf("%d ",size); for(int i=0;igetType()==NdbDictionary::Column::Longvarbinary){ char buffer[500]; int size; char *p; printf("%d ",vvlBinRecAttr->attrSize()); memcpy(buffer,vvlBinRecAttr->aRef(),vvlBinRecAttr->attrSize()); size=*(Uint16*)buffer; p=buffer+2; printf("%d ",size); for(int i=0;igetType()==NdbDictionary::Column::Char){ char buffer[500]; printf("%d ",vcharRecAttr->attrSize()); memcpy(buffer,vcharRecAttr->aRef(),vcharRecAttr->attrSize()); buffer[vcharRecAttr->attrSize()]='\0'; printf("%s\n",buffer); } if(vbinaryRecAttr->getType()==NdbDictionary::Column::Binary){ char buffer[500]; printf("%d ",vbinaryRecAttr->attrSize()); memcpy(buffer,vbinaryRecAttr->aRef(),vbinaryRecAttr->attrSize()); buffer[vcharRecAttr->attrSize()]='\0'; 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); } }