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 /****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/
29 extern "C" {
30 #include <dba.h>
31 }
32 
33 #include "common.hpp"
34 
35 #include <NdbOut.hpp>
36 #include <NdbSleep.h>
37 #include <NdbMain.h>
38 
39 static const
40 DBA_ColumnDesc_t EmpColDesc[] = {
41   { "emp_no",     DBA_INT,  PCN_SIZE_OF( Employee, EmpNo ),     PCN_TRUE },
42   { "first_name", DBA_CHAR, PCN_SIZE_OF( Employee, FirstName ), PCN_FALSE },
43   { "last_name",  DBA_CHAR, PCN_SIZE_OF( Employee, LastName ),  PCN_FALSE }
44 };
45 
46 static const
47 DBA_ColumnDesc_t AddColDesc[] = {
48   { "emp_no",      DBA_INT,  PCN_SIZE_OF( Address, EmpNo ),      PCN_TRUE },
49   { "street_name", DBA_CHAR, PCN_SIZE_OF( Address, StreetName ), PCN_FALSE},
50   { "street_no",   DBA_INT,  PCN_SIZE_OF( Address, StreetNo ),   PCN_FALSE},
51   { "city",        DBA_CHAR, PCN_SIZE_OF( Address, City ),       PCN_FALSE}
52 } ;
53 
54 static const
55 DBA_ColumnBinding_t EmpBindings[] = {
56   DBA_BINDING( "emp_no",     DBA_INT,  Employee, EmpNo ),
57   DBA_BINDING( "last_name",  DBA_CHAR, Employee, LastName ),
58   DBA_BINDING( "first_name", DBA_CHAR, Employee, FirstName)
59 };
60 
61 static const
62 DBA_ColumnBinding_t AddBindings[] = {
63   DBA_BINDING( "emp_no",      DBA_INT,  Address, EmpNo ),
64   DBA_BINDING( "street_name", DBA_CHAR, Address, StreetName ),
65   DBA_BINDING( "street_no",   DBA_INT,  Address, StreetNo ),
66   DBA_BINDING( "city",        DBA_CHAR, Address, City )
67 };
68 
69 static DBA_Binding_t * EmpB;
70 static DBA_Binding_t * AddB;
71 
72 static const int Rows = 6;
73 
74 static
75 Employee_t EMP_TABLE_DATA[] = {
76   { 1242, "Joe",     "Dalton" },
77   { 123,  "Lucky",   "Luke" },
78   { 456,  "Averell", "Dalton" },
79   { 8976, "Gaston",  "Lagaffe" },
80   { 1122, "Jolly",   "Jumper" },
81   { 3211, "Leffe",   "Pagrotsky" }
82 };
83 
84 static
85 Employee_t EMP_TABLE_DATA_READ[] = {
86   { 1242, "", "" },
87   { 123,  "", "" },
88   { 456,  "", "" },
89   { 8976, "", "" },
90   { 1122, "", "" },
91   { 3211, "", "" }
92 };
93 
94 static
95 Address_t ADD_TABLE_DATA[] = {
96   { 1242, "Lonesome Street", 12, "Crime Town" },
97   { 123,  "Pistol Road",     13, "Fort Mount" },
98   { 456,  "Banking Blv.",    43, "Las Vegas"  },
99   { 8976, "ChancylleZee",    54, "Paris" },
100   { 1122, "Lucky",          111, "Wild West"  },
101   { 3211, "Parlament St.",   11, "Stockholm" }
102 };
103 
104 static
105 Address_t ADD_TABLE_DATA_READ[] = {
106   { 1242, "", 0, "" },
107   { 123,  "", 0, "" },
108   { 456,  "", 0, "" },
109   { 8976, "", 0, "" },
110   { 1122, "", 0, "" },
111   { 3211, "", 0, "" }
112 };
113 
114 static const char EMP_TABLE[] = "employees";
115 static const char ADD_TABLE[] = "addresses";
116 
117 static const int EmpNbCol = 3;
118 static const int AddNbCol = 4;
119 
120 static
121 void
DbCreate(void)122 DbCreate(void){
123 
124   ndbout << "Opening database" << endl;
125   require( DBA_Open() == DBA_NO_ERROR );
126 
127   ndbout << "Creating tables" << endl;
128   require( DBA_CreateTable( EMP_TABLE, EmpNbCol, EmpColDesc ) == DBA_NO_ERROR );
129   require( DBA_CreateTable( ADD_TABLE, AddNbCol, AddColDesc ) == DBA_NO_ERROR );
130 
131   ndbout << "Checking for table existance" << endl;
132   require( DBA_TableExists( EMP_TABLE ) );
133   require( DBA_TableExists( ADD_TABLE ) );
134 }
135 
136 static
137 void
CreateBindings(void)138 CreateBindings(void){
139   ndbout << "Creating bindings" << endl;
140 
141   EmpB = DBA_CreateBinding(EMP_TABLE,
142 			    EmpNbCol,
143 			    EmpBindings,
144 			    sizeof(Employee_t) );
145   require(EmpB != 0);
146 
147   AddB = DBA_CreateBinding(ADD_TABLE,
148 			   AddNbCol,
149 			   AddBindings,
150 			   sizeof(Address_t) );
151   require(AddB != 0);
152 }
153 
154 int
CountRows(DBA_BulkReadResultSet_t * rs,int count)155 CountRows(DBA_BulkReadResultSet_t * rs, int count){
156   int res = 0;
157   for(int i = 0; i<count; i++)
158     if(rs[i].RowFoundIndicator)
159       res++;
160   return res;
161 }
162 
163 extern "C" {
164   static void insertCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t );
165   static void deleteCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t );
166   static void updateCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t );
167   static void readCallback  ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t );
168   static void writeCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t );
169 }
170 
171 static
Multi()172 void Multi(){
173   ndbout << "Testing multi operations" << endl;
174 
175   DBA_ArrayInsertRows(EmpB, EMP_TABLE_DATA, Rows-2, insertCallback);
176   DBA_ArrayInsertRows(AddB, ADD_TABLE_DATA, Rows-2, insertCallback);
177   NdbSleep_SecSleep(1);
178 
179   const int R2 = Rows + Rows;
180 
181   DBA_Binding_t * Bindings[2];
182   DBA_BulkReadResultSet_t DataRead[R2];
183 
184   Bindings[0] = EmpB;
185   Bindings[1] = AddB;
186 
187   for(int i = 0; i<Rows; i++)
188     DataRead[i].DataPtr = &EMP_TABLE_DATA_READ[i];
189 
190   for(int i = 0; i<Rows; i++)
191     DataRead[i+Rows].DataPtr = &ADD_TABLE_DATA_READ[i];
192 
193   NdbSleep_SecSleep(1);
194 
195   DBA_BulkMultiReadRows(Bindings, DataRead, 2, Rows, readCallback);
196   NdbSleep_SecSleep(1);
197   CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ);
198   CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ);
199 
200   require(CountRows(DataRead, R2) == (R2-4));
201 
202   // Basic delete
203   DBA_ArrayDeleteRows(EmpB, EMP_TABLE_DATA, Rows-2, deleteCallback);
204   DBA_ArrayDeleteRows(AddB, ADD_TABLE_DATA, Rows-2, deleteCallback);
205   NdbSleep_SecSleep(1);
206 }
207 
208 static
BasicPtr()209 void BasicPtr(){
210   ndbout << "Testing array of pointer operations" << endl;
211 
212   // Basic insert
213   DBA_ArrayInsertRows(EmpB, EMP_TABLE_DATA, Rows-2, insertCallback);
214   NdbSleep_SecSleep(1);
215 
216   DBA_BulkReadResultSet_t EmpDataRead[Rows];
217   for(int i = 0; i<Rows; i++){
218     EmpDataRead[i].DataPtr = &EMP_TABLE_DATA_READ[i];
219   }
220 
221   DBA_BulkReadRows(EmpB, EmpDataRead, Rows, readCallback);
222   NdbSleep_SecSleep(1);
223   CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ);
224   require(CountRows(EmpDataRead, Rows) == (Rows-2));
225 
226   // Basic delete
227   DBA_ArrayDeleteRows(EmpB, EMP_TABLE_DATA, Rows-2, deleteCallback);
228   NdbSleep_SecSleep(1);
229 }
230 
231 /*---------------------------------------------------------------------------*/
232 NDB_COMMAND(newton_br, "newton_br",
233 	    "newton_br", "newton_br", 65535){
234 
235   DbCreate();
236   CreateBindings();
237 
238   BasicPtr();
239   Multi();
240 
241   DBA_Close();
242 
243   return 0;
244 }
245 
246 
247 
248 /**
249  *  callbackStatusCheck  checks whether or not the operation succeeded
250  */
251 void
callbackStatusCheck(DBA_Error_t status,const char * operation)252 callbackStatusCheck( DBA_Error_t status, const char* operation) {
253   ndbout_c("%s: %d", operation, status);
254 }
255 
insertCallback(DBA_ReqId_t,DBA_Error_t s,DBA_ErrorCode_t)256 void insertCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){
257   callbackStatusCheck(s, "insert");
258 }
deleteCallback(DBA_ReqId_t,DBA_Error_t s,DBA_ErrorCode_t)259 void deleteCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){
260   callbackStatusCheck(s, "delete");
261 }
updateCallback(DBA_ReqId_t,DBA_Error_t s,DBA_ErrorCode_t)262 void updateCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){
263   callbackStatusCheck(s, "update");
264 }
readCallback(DBA_ReqId_t,DBA_Error_t s,DBA_ErrorCode_t)265 void readCallback  ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){
266   callbackStatusCheck(s, "read");
267 }
writeCallback(DBA_ReqId_t,DBA_Error_t s,DBA_ErrorCode_t)268 void writeCallback  ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){
269   callbackStatusCheck(s, "write");
270 }
271 
272