1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
3     All rights reserved. Use is subject to license terms.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 */
25 
26 
27 /* ***************************************************
28        INITRONJA
29        Initialise benchmark for Ronja Database
30  * *************************************************** */
31 
32 #include "NdbApi.hpp"
33 #include "NdbSchemaCon.hpp"
34 #include <NdbOut.hpp>
35 #include <NdbMain.h>
36 #include <NdbTest.hpp>
37 #include <string.h>
38 
39 #define MAXSTRLEN 16
40 #define MAXATTR 64
41 #define MAXTABLES 64
42 #define NDB_MAXTHREADS 256
43 /*
44   NDB_MAXTHREADS used to be just MAXTHREADS, which collides with a
45   #define from <sys/thread.h> on AIX (IBM compiler).  We explicitly
46   #undef it here lest someone use it by habit and get really funny
47   results.  K&R says we may #undef non-existent symbols, so let's go.
48 */
49 #undef MAXTHREADS
50 #define MAXATTRSIZE 8000
51 
52 static unsigned int tNoOfRecords;
53 static unsigned int tNoOfLoops;
54 static unsigned int tNoOfTables;
55 static int tAttributeSize;
56 static int tNodeId;
57 static unsigned int tValue;
58 static unsigned int tNoOfOperations;
59 static char tableName[MAXTABLES][MAXSTRLEN];
60 static char attrName[MAXATTR][MAXSTRLEN];
61 
62 inline int InsertRecords(Ndb*, int) ;
63 
64 NDB_COMMAND(initronja, "initronja", "initronja", "initronja", 65535){
65   ndb_init();
66 
67   Ndb*			 pNdb = NULL ;
68   NdbSchemaCon	*MySchemaTransaction = NULL ;
69   NdbSchemaOp	*MySchemaOp = NULL ;
70 
71 
72   int check, status, i, j, cont ;
73   check = status = i = j = cont = 0 ;
74   tNoOfRecords = 500 ;
75   tNoOfLoops = tNoOfRecords / 10;
76 
77   i = 1;
78   while (argc > 1){
79 
80     if (strcmp(argv[i], "-r") == 0){
81 	  if( NULL == argv[i+1] ) goto error_input ;
82 	  tNoOfRecords = atoi(argv[i+1]);
83       tNoOfRecords = tNoOfRecords - (tNoOfRecords % 10);
84       tNoOfLoops = tNoOfRecords / 10;
85       if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input;
86     }else{
87       goto error_input;
88     }
89 
90     argc -= 2;
91     i = i + 2; //
92   }
93 
94   pNdb = new Ndb( "TEST_DB" ) ;
95   ndbout << "Initialisation started. " << endl;
96   pNdb->init();
97   ndbout << "Initialisation completed. " << endl;
98 
99   tNodeId = pNdb->getNodeId();
100   ndbout << endl << "Initial loading of Ronja Database" << endl;
101   ndbout << "  NdbAPI node with id = " << tNodeId << endl;
102 
103   if (pNdb->waitUntilReady(30) != 0) {
104     ndbout << "Benchmark failed - NDB is not ready" << endl;
105 	delete pNdb ;
106     return NDBT_ProgramExit(NDBT_FAILED) ;
107   }//if
108 
109   ndbout << endl << "Creating the table SHORT_REC" << "..." << endl;
110 
111   MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb);
112   if(!MySchemaTransaction) goto error_handler;
113   MySchemaOp = MySchemaTransaction->getNdbSchemaOp();
114   if(!MySchemaOp) goto error_handler;
115   check = MySchemaOp->createTable( "SHORT_REC"
116 				   ,8		// Table Size
117 				   ,TupleKey	// Key Type
118 				   ,40		// Nr of Pages
119 				   );
120   if (check == -1) goto error_handler;
121 
122   ndbout << "Key attribute..." ;
123   check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1,
124 					     UnSigned, MMBased, NotNullAttribute );
125   if (check == -1) goto error_handler;
126   ndbout << "\t\tOK" << endl ;
127 
128   ndbout << "Flip attribute..." ;
129   check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1,
130 						       UnSigned, MMBased, NotNullAttribute );
131   if (check == -1) goto error_handler;
132    ndbout << "\t\tOK" << endl ;
133 
134   ndbout << "Count attribute..." ;
135   check = MySchemaOp->createAttribute("Count", NoKey, 32, 1,
136 						       UnSigned, MMBased, NotNullAttribute );
137   if (check == -1) goto error_handler;
138   ndbout << "\t\tOK" << endl ;
139 
140   ndbout << "Placeholder attribute..." ;
141   check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 90,
142 						       UnSigned, MMBased, NotNullAttribute );
143   if (check == -1) goto error_handler;
144   ndbout << "\tOK" << endl ;
145 
146   if (MySchemaTransaction->execute() == -1) {
147 	  if(721 == MySchemaOp->getNdbError().code){
148 		  ndbout << "Table SHORT_REC already exists" << endl ;
149 	  }else{
150 		  ndbout << MySchemaTransaction->getNdbError() << endl;
151 	  }
152   }else{
153 	  ndbout << "SHORT_REC created " << endl;
154   }// if
155 
156   NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
157 
158   ndbout << endl << "Creating the table LONG_REC..." << endl;
159 
160   MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb);
161   if(!MySchemaTransaction) goto error_handler;
162 
163   MySchemaOp = MySchemaTransaction->getNdbSchemaOp();
164   if(!MySchemaOp) goto error_handler;
165   check = MySchemaOp->createTable( "LONG_REC"
166 				       ,8		// Table Size
167 				       ,TupleKey	// Key Type
168 				       ,40		// Nr of Pages
169 				       );
170 
171   if (check == -1) goto error_handler;
172 
173   ndbout << "Key attribute..." ;
174   check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1,
175 					     UnSigned, MMBased, NotNullAttribute );
176   if (check == -1) goto error_handler;
177   ndbout << "\t\tOK" << endl ;
178 
179   ndbout << "Flip attribute..." ;
180   check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1,
181 						       UnSigned, MMBased, NotNullAttribute );
182   if (check == -1) goto error_handler;
183    ndbout << "\t\tOK" << endl ;
184 
185   ndbout << "Count attribute..." ;
186   check = MySchemaOp->createAttribute("Count", NoKey, 32, 1,
187 						       UnSigned, MMBased, NotNullAttribute );
188   if (check == -1) goto error_handler;
189    ndbout << "\t\tOK" << endl ;
190 
191   ndbout << "Placeholder attribute..." ;
192   check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 1014,
193 						       UnSigned, MMBased, NotNullAttribute );
194   if (check == -1) goto error_handler;
195   ndbout << "\tOK" << endl ;
196 
197   if (MySchemaTransaction->execute() == -1) {
198 	  if(721 == MySchemaOp->getNdbError().code){
199 		  ndbout << "Table LONG_REC already exists" << endl ;
200 	  }else{
201 		  ndbout << MySchemaTransaction->getNdbError() << endl;
202 	  }
203   }else{
204 	  ndbout << "LONG_REC created" << endl;
205   }// if
206 
207   NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
208 
209 
210   check = InsertRecords(pNdb, tNoOfRecords);
211 
212   delete pNdb ;
213 
214   if(-1 == check){
215 	  ndbout << endl << "Initial loading of Ronja Database failed" << endl;
216 	  return NDBT_ProgramExit(NDBT_FAILED) ;
217   }else{
218       ndbout << endl << "Initial loading of Ronja Database completed" << endl;
219 	  return NDBT_ProgramExit(NDBT_OK) ;
220   }
221 
222 
223 
224 
225 
226 error_handler:
227   ndbout << "SchemaTransaction returned error:" ;
228   ndbout << MySchemaTransaction->getNdbError() << endl;
229   NdbSchemaCon::closeSchemaTrans(MySchemaTransaction);
230   delete pNdb ;
231   NDBT_ProgramExit(NDBT_FAILED) ;
232   exit(-1);
233 
234 error_input:
235   ndbout << endl << "  Ivalid parameter(s)" << endl;
236   ndbout <<         "  Usage: initronja [-r n] , where 'n' is the number of records to be inserted" << endl;
237   ndbout <<			"  If omitted, 500 records will be created by default" << endl;
238   ndbout <<			"  Note: use this number in combination with '-r' argument when running 'benchronja'" << endl << endl;
239   NDBT_ProgramExit(NDBT_WRONGARGS) ;
240   exit(1);
241 }
242 ////////////////////////////////////////
243 
InsertRecords(Ndb * pNdb,int nNoRecords)244 inline int InsertRecords(Ndb* pNdb, int nNoRecords){
245 
246     NdbConnection		*MyTransaction = NULL ;
247     NdbOperation*		MyOperation[10];
248 
249     int				Tsuccess = 0 ;
250 	int				loop_count_ops = 2 * tNoOfLoops;
251     int				loop_count_tables = 10;
252     int				loop_count_attributes = 0 ;
253     int				check = 0;
254     int				count = 0 ;
255     int				count_tables = 0;
256     int				count_attributes = 0 ;
257     int				i = 0 ;
258     int 			tType = 0 ;
259     unsigned int	attrValue[1000];
260 	unsigned int	setAttrValue = 0;
261 	unsigned int	keyValue[3];
262 
263 	for (i = 0; i < 1000; i ++) attrValue[i] = 1;
264 
265 	for (count=0 ; count < loop_count_ops ; count++){
266 		  if ((((count / 100)* 100) == count) && (count != 0)){
267 			  ndbout << "1000 records inserted again, " << (count/100) << "000 records now inserted" << endl;
268 		  }
269 
270 		  MyTransaction = pNdb->startTransaction();
271 		  if(!MyTransaction){
272 			  ndbout << "startTransaction: " << pNdb->getNdbError();
273 			  ndbout << " count = " << count << endl;
274 			  return -1 ;
275 		  }
276 
277 		  for (count_tables = 0; count_tables < loop_count_tables; count_tables++) {
278 			  if (count < tNoOfLoops) {
279 				  keyValue[0] = count*10 + count_tables ;
280 				  MyOperation[count_tables] = MyTransaction->getNdbOperation("SHORT_REC") ;
281 			  }else{
282 				  keyValue[0] = (count - tNoOfLoops)*10 + count_tables;
283 				  MyOperation[count_tables] = MyTransaction->getNdbOperation("LONG_REC");
284 			  }//if
285 
286 			  if (!MyOperation[count_tables]) goto error_handler1;
287 
288 			  check = MyOperation[count_tables]->insertTuple();
289 			  if (check == -1) goto error_handler2;
290 
291 		      check = MyOperation[count_tables]->equal("Key",(char*)&keyValue[0]);
292               if (check == -1) goto error_handler4;
293 
294               check = MyOperation[count_tables]->setValue("Flip",(char*)&setAttrValue);
295               if (check == -1) goto error_handler5;
296 
297 		      check = MyOperation[count_tables]->setValue("Count",(char*)&setAttrValue);
298               if (check == -1) goto error_handler5;
299 
300 		      check = MyOperation[count_tables]->setValue("Placeholder",(char*)&attrValue[0]);
301               if (check == -1) goto error_handler5;
302 		  }//for
303 
304 		  if (MyTransaction->execute( Commit ) == -1){
305 			  ndbout << MyTransaction->getNdbError()<< endl ;
306 			  ndbout << "count = " << count << endl;
307 		  }//if
308 
309 		  pNdb->closeTransaction(MyTransaction) ;
310 	  }//for
311 	  return 0;
312 
313 error_handler1:
314    ndbout << "Error occured in getNdbOperation " << endl;
315    ndbout << MyTransaction->getNdbError() << endl;
316    pNdb->closeTransaction(MyTransaction);
317    return -1 ;
318 
319 error_handler2:
320    ndbout << "Error occured in defining operation " << endl;
321    ndbout << MyOperation[count_tables]->getNdbError() << endl;
322    pNdb->closeTransaction(MyTransaction);
323    return -1 ;
324 
325 error_handler3:
326    pNdb->closeTransaction(MyTransaction);
327    return -1 ;
328 
329 error_handler4:
330    ndbout << "Error occured in equal " << endl;
331    ndbout << MyOperation[count_tables]->getNdbError() << endl;
332    pNdb->closeTransaction(MyTransaction);
333    return -1 ;
334 
335 error_handler5:
336    ndbout << "Error occured in get/setValue " << endl;
337    ndbout << MyOperation[count_tables]->getNdbError() << endl;
338    pNdb->closeTransaction(MyTransaction);
339    return -1 ;
340 
341 }
342