29 #include <ndb_global.h>
31 #include <mysqld_error.h>
42 #define PRINT_ERROR(code,msg) \
43 std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \
44 << ", code: " << code \
45 << ", msg: " << msg << "." << std::endl
46 #define MYSQLERROR(mysql) { \
47 PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
49 #define APIERROR(error) { \
50 PRINT_ERROR(error.code,error.message); \
54 const char *text_quote=
55 "Just at this moment, somehow or other, they began to run.\n"
57 " Alice never could quite make out, in thinking it over\n"
58 "afterwards, how it was that they began: all she remembers is,\n"
59 "that they were running hand in hand, and the Queen went so fast\n"
60 "that it was all she could do to keep up with her: and still the\n"
61 "Queen kept crying 'Faster! Faster!' but Alice felt she COULD NOT\n"
62 "go faster, though she had not breath left to say so.\n"
64 " The most curious part of the thing was, that the trees and the\n"
65 "other things round them never changed their places at all:\n"
66 "however fast they went, they never seemed to pass anything. 'I\n"
67 "wonder if all the things move along with us?' thought poor\n"
68 "puzzled Alice. And the Queen seemed to guess her thoughts, for\n"
69 "she cried, 'Faster! Don't try to talk!'\n"
71 " Not that Alice had any idea of doing THAT. She felt as if she\n"
72 "would never be able to talk again, she was getting so much out of\n"
73 "breath: and still the Queen cried 'Faster! Faster!' and dragged\n"
74 "her along. 'Are we nearly there?' Alice managed to pant out at\n"
77 " 'Nearly there!' the Queen repeated. 'Why, we passed it ten\n"
78 "minutes ago! Faster!' And they ran on for a time in silence,\n"
79 "with the wind whistling in Alice's ears, and almost blowing her\n"
80 "hair off her head, she fancied.\n"
82 " 'Now! Now!' cried the Queen. 'Faster! Faster!' And they\n"
83 "went so fast that at last they seemed to skim through the air,\n"
84 "hardly touching the ground with their feet, till suddenly, just\n"
85 "as Alice was getting quite exhausted, they stopped, and she found\n"
86 "herself sitting on the ground, breathless and giddy.\n"
88 " The Queen propped her up against a tree, and said kindly, 'You\n"
89 "may rest a little now.'\n"
91 " Alice looked round her in great surprise. 'Why, I do believe\n"
92 "we've been under this tree the whole time! Everything's just as\n"
95 " 'Of course it is,' said the Queen, 'what would you have it?'\n"
97 " 'Well, in OUR country,' said Alice, still panting a little,\n"
98 "'you'd generally get to somewhere else--if you ran very fast\n"
99 "for a long time, as we've been doing.'\n"
101 " 'A slow sort of country!' said the Queen. 'Now, HERE, you see,\n"
102 "it takes all the running YOU can do, to keep in the same place.\n"
103 "If you want to get somewhere else, you must run at least twice as\n"
106 " 'I'd rather not try, please!' said Alice. 'I'm quite content\n"
107 "to stay here--only I AM so hot and thirsty!'\n"
109 " -- Lewis Carroll, 'Through the Looking-Glass'.";
130 static void setup_records(
Ndb *myNdb)
145 spec[0].column= col1;
146 spec[0].offset= offsetof(
MyRow, myId);
147 spec[0].nullbit_byte_offset= 0;
148 spec[0].nullbit_bit_in_byte= 0;
149 spec[1].column= col2;
150 spec[1].offset= offsetof(
MyRow, myText);
151 spec[1].nullbit_byte_offset= 0;
152 spec[1].nullbit_bit_in_byte= 0;
154 key_record= myDict->createRecord(myTable, &spec[0], 1,
sizeof(spec[0]));
155 if (key_record == NULL)
157 blob_record= myDict->createRecord(myTable, &spec[1], 1,
sizeof(spec[0]));
158 if (blob_record == NULL)
160 full_record= myDict->createRecord(myTable, &spec[0], 2,
sizeof(spec[0]));
161 if (full_record == NULL)
168 void drop_table(
MYSQL &mysql)
170 if (mysql_query(&mysql,
"DROP TABLE api_blob_ndbrecord"))
178 int try_create_table(
MYSQL &mysql)
180 return mysql_query(&mysql,
182 " api_blob_ndbrecord"
183 " (my_id INT UNSIGNED NOT NULL,"
184 " my_text TEXT NOT NULL,"
185 " PRIMARY KEY USING HASH (my_id))"
191 if (try_create_table(mysql))
193 if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR)
195 std::cout <<
"MySQL Cluster already has example table: api_blob_ndbrecord. "
196 <<
"Dropping it..." << std::endl;
201 if (try_create_table(mysql))
206 int populate(
Ndb *myNdb)
215 const NdbOperation *myNdbOperation= myTrans->insertTuple(full_record, (
const char*) &row);
216 if (myNdbOperation == NULL)
220 if (myBlobHandle == NULL)
222 myBlobHandle->setValue(text_quote, strlen(text_quote));
230 int update_key(
Ndb *myNdb)
247 myTrans->updateTuple(key_record,
251 if (myNdbOperation == NULL)
255 if (myBlobHandle == NULL)
265 if (-1 == myBlobHandle->getLength(length))
266 APIERROR(myBlobHandle->getNdbError());
273 #define CHUNK_SIZE 100
275 char buffer[CHUNK_SIZE];
276 for (chunk= (length-1)/CHUNK_SIZE; chunk >=0; chunk--)
278 Uint64 pos= chunk*CHUNK_SIZE;
279 Uint32 chunk_length= CHUNK_SIZE;
280 if (pos + chunk_length > length)
281 chunk_length= length - pos;
284 if (-1 == myBlobHandle->setPos(pos))
285 APIERROR(myBlobHandle->getNdbError());
286 if (-1 == myBlobHandle->readData(buffer, chunk_length))
287 APIERROR(myBlobHandle->getNdbError());
293 for (Uint64 j= 0; j < chunk_length; j++)
294 buffer[j]= toupper(buffer[j]);
296 if (-1 == myBlobHandle->setPos(pos))
297 APIERROR(myBlobHandle->getNdbError());
298 if (-1 == myBlobHandle->writeData(buffer, chunk_length))
299 APIERROR(myBlobHandle->getNdbError());
301 if (-1 == myTrans->
execute(chunk ?
313 int update_scan(
Ndb *myNdb)
327 if (myScanOp == NULL)
329 NdbBlob *myBlobHandle= myScanOp->getBlobHandle(
"my_text");
330 if (myBlobHandle == NULL)
331 APIERROR(myScanOp->getNdbError());
332 if (myBlobHandle->getValue(buffer,
sizeof(buffer)))
333 APIERROR(myBlobHandle->getNdbError());
339 const MyRow *out_row;
343 res= myScanOp->nextResult((
const char**)&out_row,
true,
false);
347 APIERROR(myScanOp->getNdbError());
350 if (myBlobHandle->getLength(length) == -1)
351 APIERROR(myBlobHandle->getNdbError());
354 for (Uint64 j= 0; j < length; j++)
355 buffer[j]= tolower(buffer[j]);
361 myScanOp->updateCurrentTuple(myTrans,
363 (
const char*)out_row);
364 if (myUpdateOp == NULL)
367 if (myBlobHandle2 == NULL)
369 if (myBlobHandle2->setValue(buffer, length))
370 APIERROR(myBlobHandle2->getNdbError());
376 if (-1 == myTrans->
execute(NdbTransaction::Commit))
390 int myFetchHook(
NdbBlob* myBlobHandle,
void* arg)
394 ahd->readLength=
sizeof(ahd->buffer) - 1;
395 return myBlobHandle->
readData(ahd->buffer, ahd->readLength);
398 int fetch_key(
Ndb *myNdb)
422 out_row.myText= NULL;
424 myTrans->readTuple(key_record,
425 (
const char*) &key_row,
428 if (myNdbOperation == NULL)
435 NdbBlob *myBlobHandle= out_row.myText;
436 if (myBlobHandle == NULL)
439 if (myBlobHandle->setActiveHook(myFetchHook, &ahd) == -1)
440 APIERROR(myBlobHandle->getNdbError());
446 if (-1 == myTrans->
execute(NdbTransaction::Commit))
452 ahd.buffer[ahd.readLength]=
'\0';
453 std::cout <<
"Fetched data:" << std::endl << ahd.buffer << std::endl;
459 int update2_key(
Ndb *myNdb)
474 myTrans->updateTuple(key_record,
478 if (myNdbOperation == NULL)
481 if (myBlobHandle == NULL)
483 memset(buffer,
' ',
sizeof(buffer));
484 if (myBlobHandle->setValue(buffer,
sizeof(buffer)) == -1)
485 APIERROR(myBlobHandle->getNdbError());
487 if (-1 == myTrans->
execute(NdbTransaction::Commit))
495 int delete_key(
Ndb *myNdb)
506 const NdbOperation *myNdbOperation= myTrans->deleteTuple(key_record,
509 if (myNdbOperation == NULL)
512 if (-1 == myTrans->
execute(NdbTransaction::Commit))
520 int main(
int argc,
char**argv)
524 std::cout <<
"Arguments are <socket mysqld> <connect_string cluster>.\n";
527 char *mysqld_sock = argv[1];
528 const char *connectstring = argv[2];
534 if ( !mysql_init(&mysql) ) {
535 std::cout <<
"mysql_init failed.\n";
538 if ( !mysql_real_connect(&mysql,
"localhost",
"root",
"",
"",
542 mysql_query(&mysql,
"CREATE DATABASE ndb_examples");
543 if (mysql_query(&mysql,
"USE ndb_examples") != 0)
552 if (cluster_connection.connect(4, 5, 1))
554 std::cout <<
"Unable to connect to cluster within 30 secs." << std::endl;
558 if (cluster_connection.wait_until_ready(30,0) < 0)
560 std::cout <<
"Cluster was not ready within 30 secs.\n";
564 Ndb myNdb(&cluster_connection,
"ndb_examples");
565 if (myNdb.
init(1024) == -1) {
570 setup_records(&myNdb);
572 if(populate(&myNdb) > 0)
573 std::cout <<
"populate: Success!" << std::endl;
575 if(update_key(&myNdb) > 0)
576 std::cout <<
"update_key: Success!" << std::endl;
578 if(update_scan(&myNdb) > 0)
579 std::cout <<
"update_scan: Success!" << std::endl;
581 if(fetch_key(&myNdb) > 0)
582 std::cout <<
"fetch_key: Success!" << std::endl;
584 if(update2_key(&myNdb) > 0)
585 std::cout <<
"update2_key: Success!" << std::endl;
587 if(delete_key(&myNdb) > 0)
588 std::cout <<
"delete_key: Success!" << std::endl;