MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
main.cpp
1 /*
2  Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 //
19 // ndbapi_simple_index.cpp: Using secondary indexes in NDB API
20 //
21 // Correct output from this program is:
22 //
23 // ATTR1 ATTR2
24 // 0 0
25 // 1 1
26 // 2 2
27 // 3 3
28 // 4 4
29 // 5 5
30 // 6 6
31 // 7 7
32 // 8 8
33 // 9 9
34 // ATTR1 ATTR2
35 // 0 10
36 // 1 1
37 // 2 12
38 // Detected that deleted tuple doesn't exist!
39 // 4 14
40 // 5 5
41 // 6 16
42 // 7 7
43 // 8 18
44 // 9 9
45 
46 #include <mysql.h>
47 #include <mysqld_error.h>
48 #include <NdbApi.hpp>
49 
50 // Used for cout
51 #include <stdio.h>
52 #include <iostream>
53 
54 #define PRINT_ERROR(code,msg) \
55  std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \
56  << ", code: " << code \
57  << ", msg: " << msg << "." << std::endl
58 #define MYSQLERROR(mysql) { \
59  PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \
60  exit(-1); }
61 #define APIERROR(error) { \
62  PRINT_ERROR(error.code,error.message); \
63  exit(-1); }
64 
65 int main(int argc, char** argv)
66 {
67  if (argc != 3)
68  {
69  std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n";
70  exit(-1);
71  }
72  char * mysqld_sock = argv[1];
73  const char *connectstring = argv[2];
74  ndb_init();
75  MYSQL mysql;
76 
77  /**************************************************************
78  * Connect to mysql server and create table *
79  **************************************************************/
80  {
81  if ( !mysql_init(&mysql) ) {
82  std::cout << "mysql_init failed\n";
83  exit(-1);
84  }
85  if ( !mysql_real_connect(&mysql, "localhost", "root", "", "",
86  0, mysqld_sock, 0) )
87  MYSQLERROR(mysql);
88 
89  mysql_query(&mysql, "CREATE DATABASE ndb_examples_1");
90  if (mysql_query(&mysql, "USE ndb_examples") != 0) MYSQLERROR(mysql);
91 
92  while (mysql_query(&mysql,
93  "CREATE TABLE"
94  " api_simple_index"
95  " (ATTR1 INT UNSIGNED,"
96  " ATTR2 INT UNSIGNED NOT NULL,"
97  " PRIMARY KEY USING HASH (ATTR1),"
98  " UNIQUE MYINDEXNAME USING HASH (ATTR2))"
99  " ENGINE=NDB"))
100  {
101  if (mysql_errno(&mysql) == ER_TABLE_EXISTS_ERROR)
102  {
103  std::cout << "MySQL Cluster already has example table: api_scan. "
104  << "Dropping it..." << std::endl;
105  mysql_query(&mysql, "DROP TABLE api_simple_index");
106  }
107  else MYSQLERROR(mysql);
108  }
109  }
110 
111  /**************************************************************
112  * Connect to ndb cluster *
113  **************************************************************/
114 
115  Ndb_cluster_connection *cluster_connection=
116  new Ndb_cluster_connection(connectstring); // Object representing the cluster
117 
118  if (cluster_connection->connect(5,3,1))
119  {
120  std::cout << "Connect to cluster management server failed.\n";
121  exit(-1);
122  }
123 
124  if (cluster_connection->wait_until_ready(30,30))
125  {
126  std::cout << "Cluster was not ready within 30 secs.\n";
127  exit(-1);
128  }
129 
130  Ndb* myNdb = new Ndb( cluster_connection,
131  "ndb_examples" ); // Object representing the database
132  if (myNdb->init() == -1) {
133  APIERROR(myNdb->getNdbError());
134  exit(-1);
135  }
136 
137  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
138  const NdbDictionary::Table *myTable= myDict->getTable("api_simple_index");
139  if (myTable == NULL)
140  APIERROR(myDict->getNdbError());
141  const NdbDictionary::Index *myIndex= myDict->getIndex("MYINDEXNAME$unique","api_simple_index");
142  if (myIndex == NULL)
143  APIERROR(myDict->getNdbError());
144 
145  /**************************************************************************
146  * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) *
147  **************************************************************************/
148  for (int i = 0; i < 5; i++) {
149  NdbTransaction *myTransaction= myNdb->startTransaction();
150  if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
151 
152  NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
153  if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
154 
155  myOperation->insertTuple();
156  myOperation->equal("ATTR1", i);
157  myOperation->setValue("ATTR2", i);
158 
159  myOperation = myTransaction->getNdbOperation(myTable);
160  if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
161 
162  myOperation->insertTuple();
163  myOperation->equal("ATTR1", i+5);
164  myOperation->setValue("ATTR2", i+5);
165 
166  if (myTransaction->execute( NdbTransaction::Commit ) == -1)
167  APIERROR(myTransaction->getNdbError());
168 
169  myNdb->closeTransaction(myTransaction);
170  }
171 
172  /*****************************************
173  * Read and print all tuples using index *
174  *****************************************/
175  std::cout << "ATTR1 ATTR2" << std::endl;
176 
177  for (int i = 0; i < 10; i++) {
178  NdbTransaction *myTransaction= myNdb->startTransaction();
179  if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
180 
181  NdbIndexOperation *myIndexOperation=
182  myTransaction->getNdbIndexOperation(myIndex);
183  if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
184 
185  myIndexOperation->readTuple(NdbOperation::LM_Read);
186  myIndexOperation->equal("ATTR2", i);
187 
188  NdbRecAttr *myRecAttr= myIndexOperation->getValue("ATTR1", NULL);
189  if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());
190 
191  if(myTransaction->execute( NdbTransaction::Commit,
193  printf(" %2d %2d\n", myRecAttr->u_32_value(), i);
194 
195  myNdb->closeTransaction(myTransaction);
196  }
197 
198  /*****************************************************************
199  * Update the second attribute in half of the tuples (adding 10) *
200  *****************************************************************/
201  for (int i = 0; i < 10; i+=2) {
202  NdbTransaction *myTransaction= myNdb->startTransaction();
203  if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
204 
205  NdbIndexOperation *myIndexOperation=
206  myTransaction->getNdbIndexOperation(myIndex);
207  if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
208 
209  myIndexOperation->updateTuple();
210  myIndexOperation->equal( "ATTR2", i );
211  myIndexOperation->setValue( "ATTR2", i+10);
212 
213  if( myTransaction->execute( NdbTransaction::Commit ) == -1 )
214  APIERROR(myTransaction->getNdbError());
215 
216  myNdb->closeTransaction(myTransaction);
217  }
218 
219  /*************************************************
220  * Delete one tuple (the one with primary key 3) *
221  *************************************************/
222  {
223  NdbTransaction *myTransaction= myNdb->startTransaction();
224  if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
225 
226  NdbIndexOperation *myIndexOperation=
227  myTransaction->getNdbIndexOperation(myIndex);
228  if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError());
229 
230  myIndexOperation->deleteTuple();
231  myIndexOperation->equal( "ATTR2", 3 );
232 
233  if (myTransaction->execute(NdbTransaction::Commit) == -1)
234  APIERROR(myTransaction->getNdbError());
235 
236  myNdb->closeTransaction(myTransaction);
237  }
238 
239  /*****************************
240  * Read and print all tuples *
241  *****************************/
242  {
243  std::cout << "ATTR1 ATTR2" << std::endl;
244 
245  for (int i = 0; i < 10; i++) {
246  NdbTransaction *myTransaction= myNdb->startTransaction();
247  if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
248 
249  NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
250  if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
251 
252  myOperation->readTuple(NdbOperation::LM_Read);
253  myOperation->equal("ATTR1", i);
254 
255  NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL);
256  if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError());
257 
258  if(myTransaction->execute( NdbTransaction::Commit,
260  if (i == 3) {
261  std::cout << "Detected that deleted tuple doesn't exist!\n";
262  } else {
263  APIERROR(myTransaction->getNdbError());
264  }
265 
266  if (i != 3) {
267  printf(" %2d %2d\n", i, myRecAttr->u_32_value());
268  }
269  myNdb->closeTransaction(myTransaction);
270  }
271  }
272 
273  delete myNdb;
274  delete cluster_connection;
275 
276  ndb_end(0);
277  return 0;
278 }