1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
// ndbapi_simple_index.cpp: Using secondary indexes in NDB API
19
// Correct output from this program is:
36
// Detected that deleted tuple doesn't exist!
51
#define PRINT_ERROR(code,msg) \
52
std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \
53
<< ", code: " << code \
54
<< ", msg: " << msg << "." << std::endl
55
#define MYSQLERROR(mysql) { \
56
PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
58
#define APIERROR(error) { \
59
PRINT_ERROR(error.code,error.message); \
62
int main(int argc, char** argv)
66
std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
69
char * mysqld_sock = argv[1];
70
const char *connectstring = argv[2];
74
/**************************************************************
75
* Connect to mysql server and create table *
76
**************************************************************/
78
if ( !mysql_init(&mysql) ) {
79
std::cout << "mysql_init failed\n";
82
if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
86
mysql_query(&mysql, "CREATE DATABASE TEST_DB_1");
87
if (mysql_query(&mysql, "USE TEST_DB_1") != 0) MYSQLERROR(mysql);
89
if (mysql_query(&mysql,
92
" (ATTR1 INT UNSIGNED,"
93
" ATTR2 INT UNSIGNED NOT NULL,"
94
" PRIMARY KEY USING HASH (ATTR1),"
95
" UNIQUE MYINDEXNAME USING HASH (ATTR2))"
100
/**************************************************************
101
* Connect to ndb cluster *
102
**************************************************************/
104
Ndb_cluster_connection *cluster_connection=
105
new Ndb_cluster_connection(connectstring); // Object representing the cluster
107
if (cluster_connection->connect(5,3,1))
109
std::cout << "Connect to cluster management server failed.\n";
113
if (cluster_connection->wait_until_ready(30,30))
115
std::cout << "Cluster was not ready within 30 secs.\n";
119
Ndb* myNdb = new Ndb( cluster_connection,
120
"TEST_DB_1" ); // Object representing the database
121
if (myNdb->init() == -1) {
122
APIERROR(myNdb->getNdbError());
126
const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
127
const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME");
129
APIERROR(myDict->getNdbError());
130
const NdbDictionary::Index *myIndex= myDict->getIndex("MYINDEXNAME$unique","MYTABLENAME");
132
APIERROR(myDict->getNdbError());
134
/**************************************************************************
135
* Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) *
136
**************************************************************************/
137
for (int i = 0; i < 5; i++) {
138
NdbTransaction *myTransaction= myNdb->startTransaction();
139
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
141
NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
142
if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
144
myOperation->insertTuple();
145
myOperation->equal("ATTR1", i);
146
myOperation->setValue("ATTR2", i);
148
myOperation = myTransaction->getNdbOperation(myTable);
149
if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
151
myOperation->insertTuple();
152
myOperation->equal("ATTR1", i+5);
153
myOperation->setValue("ATTR2", i+5);
155
if (myTransaction->execute( NdbTransaction::Commit ) == -1)
156
APIERROR(myTransaction->getNdbError());
158
myNdb->closeTransaction(myTransaction);
161
/*****************************************
162
* Read and print all tuples using index *
163
*****************************************/
164
std::cout << "ATTR1 ATTR2" << std::endl;
166
for (int i = 0; i < 10; i++) {
167
NdbTransaction *myTransaction= myNdb->startTransaction();
168
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
170
NdbIndexOperation *myIndexOperation=
171
myTransaction->getNdbIndexOperation(myIndex);
172
if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
174
myIndexOperation->readTuple(NdbOperation::LM_Read);
175
myIndexOperation->equal("ATTR2", i);
177
NdbRecAttr *myRecAttr= myIndexOperation->getValue("ATTR1", NULL);
178
if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());
180
if(myTransaction->execute( NdbTransaction::Commit,
181
NdbOperation::AbortOnError ) != -1)
182
printf(" %2d %2d\n", myRecAttr->u_32_value(), i);
184
myNdb->closeTransaction(myTransaction);
187
/*****************************************************************
188
* Update the second attribute in half of the tuples (adding 10) *
189
*****************************************************************/
190
for (int i = 0; i < 10; i+=2) {
191
NdbTransaction *myTransaction= myNdb->startTransaction();
192
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
194
NdbIndexOperation *myIndexOperation=
195
myTransaction->getNdbIndexOperation(myIndex);
196
if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
198
myIndexOperation->updateTuple();
199
myIndexOperation->equal( "ATTR2", i );
200
myIndexOperation->setValue( "ATTR2", i+10);
202
if( myTransaction->execute( NdbTransaction::Commit ) == -1 )
203
APIERROR(myTransaction->getNdbError());
205
myNdb->closeTransaction(myTransaction);
208
/*************************************************
209
* Delete one tuple (the one with primary key 3) *
210
*************************************************/
212
NdbTransaction *myTransaction= myNdb->startTransaction();
213
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
215
NdbIndexOperation *myIndexOperation=
216
myTransaction->getNdbIndexOperation(myIndex);
217
if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
219
myIndexOperation->deleteTuple();
220
myIndexOperation->equal( "ATTR2", 3 );
222
if (myTransaction->execute(NdbTransaction::Commit) == -1)
223
APIERROR(myTransaction->getNdbError());
225
myNdb->closeTransaction(myTransaction);
228
/*****************************
229
* Read and print all tuples *
230
*****************************/
232
std::cout << "ATTR1 ATTR2" << std::endl;
234
for (int i = 0; i < 10; i++) {
235
NdbTransaction *myTransaction= myNdb->startTransaction();
236
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
238
NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
239
if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
241
myOperation->readTuple(NdbOperation::LM_Read);
242
myOperation->equal("ATTR1", i);
244
NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL);
245
if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());
247
if(myTransaction->execute( NdbTransaction::Commit,
248
NdbOperation::AbortOnError ) == -1)
250
std::cout << "Detected that deleted tuple doesn't exist!\n";
252
APIERROR(myTransaction->getNdbError());
256
printf(" %2d %2d\n", i, myRecAttr->u_32_value());
258
myNdb->closeTransaction(myTransaction);
265
if (mysql_query(&mysql, "DROP TABLE MYTABLENAME"))
269
delete cluster_connection;