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 //#define DEBUG_ON
27
28 #include <string.h>
29 #include "userHandle.h"
30 #include "userInterface.h"
31
32 #include "macros.h"
33 #include "ndb_schema.hpp"
34 #include "ndb_error.hpp"
35
36 #include <NdbApi.hpp>
37
38
39 void
userCheckpoint(UserHandle * uh)40 userCheckpoint(UserHandle *uh){
41 }
42
43 inline
44 NdbConnection *
startTransaction(Ndb * pNDB,ServerId inServerId,const SubscriberNumber inNumber)45 startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){
46
47 const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH;
48 const int keyDataLen_64Words = keyDataLenBytes >> 3;
49
50 Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding...
51
52 char * keyDataBuf_charP = (char *)&keyDataBuf[0];
53 Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0];
54
55 // Server Id comes first
56 keyDataBuf_wo32P[0] = inServerId;
57 // Then subscriber number
58 memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH);
59
60 return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes);
61 }
62
63 /**
64 * Transaction 1 - T1
65 *
66 * Update location and changed by/time on a subscriber
67 *
68 * Input:
69 * SubscriberNumber,
70 * Location,
71 * ChangedBy,
72 * ChangedTime
73 *
74 * Output:
75 */
76 void
userTransaction_T1(UserHandle * uh,SubscriberNumber number,Location new_location,ChangedBy changed_by,ChangedTime changed_time)77 userTransaction_T1(UserHandle * uh,
78 SubscriberNumber number,
79 Location new_location,
80 ChangedBy changed_by,
81 ChangedTime changed_time){
82 Ndb * pNDB = uh->pNDB;
83
84 DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number);
85
86 int check;
87 NdbRecAttr * check2;
88
89 NdbConnection * MyTransaction = pNDB->startTransaction();
90 if (MyTransaction != NULL) {
91 NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
92 if (MyOperation != NULL) {
93 MyOperation->updateTuple();
94 MyOperation->equal(IND_SUBSCRIBER_NUMBER,
95 number);
96 MyOperation->setValue(IND_SUBSCRIBER_LOCATION,
97 (char *)&new_location);
98 MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY,
99 changed_by);
100 MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME,
101 changed_time);
102 check = MyTransaction->execute( Commit );
103 if (check != -1) {
104 pNDB->closeTransaction(MyTransaction);
105 return;
106 } else {
107 CHECK_MINUS_ONE(check, "T1: Commit",
108 MyTransaction);
109 }//if
110 } else {
111 CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction);
112 }//if
113 } else {
114 error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
115 }//if
116 }
117
118 /**
119 * Transaction 2 - T2
120 *
121 * Read from Subscriber:
122 *
123 * Input:
124 * SubscriberNumber
125 *
126 * Output:
127 * Location
128 * Changed by
129 * Changed Timestamp
130 * Name
131 */
132 void
userTransaction_T2(UserHandle * uh,SubscriberNumber number,Location * readLocation,ChangedBy changed_by,ChangedTime changed_time,SubscriberName subscriberName)133 userTransaction_T2(UserHandle * uh,
134 SubscriberNumber number,
135 Location * readLocation,
136 ChangedBy changed_by,
137 ChangedTime changed_time,
138 SubscriberName subscriberName){
139 Ndb * pNDB = uh->pNDB;
140
141 DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number);
142
143 int check;
144 NdbRecAttr * check2;
145
146 NdbConnection * MyTransaction = pNDB->startTransaction();
147 if (MyTransaction == NULL)
148 error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError());
149
150 NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
151 CHECK_NULL(MyOperation, "T2: getNdbOperation",
152 MyTransaction);
153
154 MyOperation->readTuple();
155 MyOperation->equal(IND_SUBSCRIBER_NUMBER,
156 number);
157 MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
158 (char *)readLocation);
159 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
160 changed_by);
161 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
162 changed_time);
163 MyOperation->getValue(IND_SUBSCRIBER_NAME,
164 subscriberName);
165 check = MyTransaction->execute( Commit );
166 CHECK_MINUS_ONE(check, "T2: Commit",
167 MyTransaction);
168 pNDB->closeTransaction(MyTransaction);
169 }
170
171 /**
172 * Transaction 3 - T3
173 *
174 * Read session details
175 *
176 * Input:
177 * SubscriberNumber
178 * ServerId
179 * ServerBit
180 *
181 * Output:
182 * BranchExecuted
183 * SessionDetails
184 * ChangedBy
185 * ChangedTime
186 * Location
187 */
188 void
userTransaction_T3(UserHandle * uh,SubscriberNumber inNumber,ServerId inServerId,ServerBit inServerBit,SessionDetails outSessionDetails,BranchExecuted * outBranchExecuted)189 userTransaction_T3(UserHandle * uh,
190 SubscriberNumber inNumber,
191 ServerId inServerId,
192 ServerBit inServerBit,
193 SessionDetails outSessionDetails,
194 BranchExecuted * outBranchExecuted){
195 Ndb * pNDB = uh->pNDB;
196
197 char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))];
198 char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
199 Location outLocation;
200 GroupId groupId;
201 ActiveSessions sessions;
202 Permission permission;
203 SubscriberSuffix inSuffix;
204
205 DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
206
207 int check;
208 NdbRecAttr * check2;
209
210 NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber);
211 if (MyTransaction == NULL)
212 error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
213
214 NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
215 CHECK_NULL(MyOperation, "T3-1: getNdbOperation",
216 MyTransaction);
217
218 MyOperation->readTuple();
219 MyOperation->equal(IND_SUBSCRIBER_NUMBER,
220 inNumber);
221 MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
222 (char *)&outLocation);
223 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
224 outChangedBy);
225 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
226 outChangedTime);
227 MyOperation->getValue(IND_SUBSCRIBER_GROUP,
228 (char *)&groupId);
229 MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
230 (char *)&sessions);
231 check = MyTransaction->execute( NoCommit );
232 CHECK_MINUS_ONE(check, "T3-1: NoCommit",
233 MyTransaction);
234
235 /* Operation 2 */
236
237 MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
238 CHECK_NULL(MyOperation, "T3-2: getNdbOperation",
239 MyTransaction);
240
241
242 MyOperation->readTuple();
243 MyOperation->equal(IND_GROUP_ID,
244 (char*)&groupId);
245 MyOperation->getValue(IND_GROUP_ALLOW_READ,
246 (char *)&permission);
247 check = MyTransaction->execute( NoCommit );
248 CHECK_MINUS_ONE(check, "T3-2: NoCommit",
249 MyTransaction);
250
251 if(((permission & inServerBit) == inServerBit) &&
252 ((sessions & inServerBit) == inServerBit)){
253
254 memcpy(inSuffix,
255 &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
256 DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
257
258 /* Operation 3 */
259 MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
260 CHECK_NULL(MyOperation, "T3-3: getNdbOperation",
261 MyTransaction);
262
263 MyOperation->simpleRead();
264
265 MyOperation->equal(IND_SESSION_SUBSCRIBER,
266 (char*)inNumber);
267 MyOperation->equal(IND_SESSION_SERVER,
268 (char*)&inServerId);
269 MyOperation->getValue(IND_SESSION_DATA,
270 (char *)outSessionDetails);
271 /* Operation 4 */
272 MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
273 CHECK_NULL(MyOperation, "T3-4: getNdbOperation",
274 MyTransaction);
275
276 MyOperation->interpretedUpdateTuple();
277 MyOperation->equal(IND_SERVER_ID,
278 (char*)&inServerId);
279 MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
280 (char*)inSuffix);
281 MyOperation->incValue(IND_SERVER_READS, (uint32)1);
282 (* outBranchExecuted) = 1;
283 } else {
284 (* outBranchExecuted) = 0;
285 }
286 DEBUG("commit...");
287 check = MyTransaction->execute( Commit );
288 CHECK_MINUS_ONE(check, "T3: Commit",
289 MyTransaction);
290
291 pNDB->closeTransaction(MyTransaction);
292
293 DEBUG("done\n");
294 }
295
296
297 /**
298 * Transaction 4 - T4
299 *
300 * Create session
301 *
302 * Input:
303 * SubscriberNumber
304 * ServerId
305 * ServerBit
306 * SessionDetails,
307 * DoRollback
308 * Output:
309 * ChangedBy
310 * ChangedTime
311 * Location
312 * BranchExecuted
313 */
314 void
userTransaction_T4(UserHandle * uh,SubscriberNumber inNumber,ServerId inServerId,ServerBit inServerBit,SessionDetails inSessionDetails,DoRollback inDoRollback,BranchExecuted * outBranchExecuted)315 userTransaction_T4(UserHandle * uh,
316 SubscriberNumber inNumber,
317 ServerId inServerId,
318 ServerBit inServerBit,
319 SessionDetails inSessionDetails,
320 DoRollback inDoRollback,
321 BranchExecuted * outBranchExecuted){
322
323 Ndb * pNDB = uh->pNDB;
324
325 char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))];
326 char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
327 Location outLocation;
328 GroupId groupId;
329 ActiveSessions sessions;
330 Permission permission;
331 SubscriberSuffix inSuffix;
332
333 DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
334
335 int check;
336 NdbRecAttr * check2;
337
338 NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber);
339 if (MyTransaction == NULL)
340 error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
341
342 NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
343 CHECK_NULL(MyOperation, "T4-1: getNdbOperation",
344 MyTransaction);
345
346 MyOperation->interpretedUpdateTuple();
347 MyOperation->equal(IND_SUBSCRIBER_NUMBER,
348 inNumber);
349 MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
350 (char *)&outLocation);
351 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
352 outChangedBy);
353 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
354 outChangedTime);
355 MyOperation->getValue(IND_SUBSCRIBER_GROUP,
356 (char *)&groupId);
357 MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
358 (char *)&sessions);
359 MyOperation->incValue(IND_SUBSCRIBER_SESSIONS,
360 (uint32)inServerBit);
361 check = MyTransaction->execute( NoCommit );
362
363 /* Operation 2 */
364
365 MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
366 CHECK_NULL(MyOperation, "T4-2: getNdbOperation",
367 MyTransaction);
368
369 MyOperation->readTuple();
370 MyOperation->equal(IND_GROUP_ID,
371 (char*)&groupId);
372 MyOperation->getValue(IND_GROUP_ALLOW_INSERT,
373 (char *)&permission);
374 check = MyTransaction->execute( NoCommit );
375 CHECK_MINUS_ONE(check, "T4-2: NoCommit",
376 MyTransaction);
377
378 if(((permission & inServerBit) == inServerBit) &&
379 ((sessions & inServerBit) == 0)){
380
381 memcpy(inSuffix,
382 &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
383
384 DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
385
386 /* Operation 3 */
387
388 MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
389 CHECK_NULL(MyOperation, "T4-3: getNdbOperation",
390 MyTransaction);
391
392 MyOperation->insertTuple();
393 MyOperation->equal(IND_SESSION_SUBSCRIBER,
394 (char*)inNumber);
395 MyOperation->equal(IND_SESSION_SERVER,
396 (char*)&inServerId);
397 MyOperation->setValue(SESSION_DATA,
398 (char *)inSessionDetails);
399 /* Operation 4 */
400
401 /* Operation 5 */
402 MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
403 CHECK_NULL(MyOperation, "T4-5: getNdbOperation",
404 MyTransaction);
405
406 MyOperation->interpretedUpdateTuple();
407 MyOperation->equal(IND_SERVER_ID,
408 (char*)&inServerId);
409 MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
410 (char*)inSuffix);
411 MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1);
412 (* outBranchExecuted) = 1;
413 } else {
414 (* outBranchExecuted) = 0;
415 DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
416 DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - "));
417 }
418
419 if(!inDoRollback && (* outBranchExecuted)){
420 DEBUG("commit\n");
421 check = MyTransaction->execute( Commit );
422 CHECK_MINUS_ONE(check, "T4: Commit",
423 MyTransaction);
424 } else {
425 DEBUG("rollback\n");
426 check = MyTransaction->execute(Rollback);
427 CHECK_MINUS_ONE(check, "T4:Rollback",
428 MyTransaction);
429
430 }
431
432 pNDB->closeTransaction(MyTransaction);
433 }
434
435
436 /**
437 * Transaction 5 - T5
438 *
439 * Delete session
440 *
441 * Input:
442 * SubscriberNumber
443 * ServerId
444 * ServerBit
445 * DoRollback
446 * Output:
447 * ChangedBy
448 * ChangedTime
449 * Location
450 * BranchExecuted
451 */
452 void
userTransaction_T5(UserHandle * uh,SubscriberNumber inNumber,ServerId inServerId,ServerBit inServerBit,DoRollback inDoRollback,BranchExecuted * outBranchExecuted)453 userTransaction_T5(UserHandle * uh,
454 SubscriberNumber inNumber,
455 ServerId inServerId,
456 ServerBit inServerBit,
457 DoRollback inDoRollback,
458 BranchExecuted * outBranchExecuted){
459 Ndb * pNDB = uh->pNDB;
460
461 DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
462
463 NdbConnection * MyTransaction = 0;
464 NdbOperation * MyOperation = 0;
465
466 char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))];
467 char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
468 Location outLocation;
469 GroupId groupId;
470 ActiveSessions sessions;
471 Permission permission;
472 SubscriberSuffix inSuffix;
473
474 int check;
475 NdbRecAttr * check2;
476
477 MyTransaction = pNDB->startTransaction();
478 if (MyTransaction == NULL)
479 error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
480
481 MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
482 CHECK_NULL(MyOperation, "T5-1: getNdbOperation",
483 MyTransaction);
484
485 MyOperation->interpretedUpdateTuple();
486 MyOperation->equal(IND_SUBSCRIBER_NUMBER,
487 inNumber);
488 MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
489 (char *)&outLocation);
490 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
491 &outChangedBy[0]);
492 MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
493 &outChangedTime[0]);
494 MyOperation->getValue(IND_SUBSCRIBER_GROUP,
495 (char *)&groupId);
496 MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
497 (char *)&sessions);
498 MyOperation->subValue(IND_SUBSCRIBER_SESSIONS,
499 (uint32)inServerBit);
500 MyTransaction->execute( NoCommit );
501 /* Operation 2 */
502
503 MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
504 CHECK_NULL(MyOperation, "T5-2: getNdbOperation",
505 MyTransaction);
506
507 MyOperation->readTuple();
508 MyOperation->equal(IND_GROUP_ID,
509 (char*)&groupId);
510 MyOperation->getValue(IND_GROUP_ALLOW_DELETE,
511 (char *)&permission);
512 check = MyTransaction->execute( NoCommit );
513 CHECK_MINUS_ONE(check, "T5-2: NoCommit",
514 MyTransaction);
515
516 if(((permission & inServerBit) == inServerBit) &&
517 ((sessions & inServerBit) == inServerBit)){
518
519 memcpy(inSuffix,
520 &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
521
522 DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
523
524 /* Operation 3 */
525 MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
526 CHECK_NULL(MyOperation, "T5-3: getNdbOperation",
527 MyTransaction);
528
529 MyOperation->deleteTuple();
530 MyOperation->equal(IND_SESSION_SUBSCRIBER,
531 (char*)inNumber);
532 MyOperation->equal(IND_SESSION_SERVER,
533 (char*)&inServerId);
534 /* Operation 4 */
535
536 /* Operation 5 */
537 MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
538 CHECK_NULL(MyOperation, "T5-5: getNdbOperation",
539 MyTransaction);
540
541
542 MyOperation->interpretedUpdateTuple();
543 MyOperation->equal(IND_SERVER_ID,
544 (char*)&inServerId);
545 MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
546 (char*)inSuffix);
547 MyOperation->incValue(IND_SERVER_DELETES, (uint32)1);
548 (* outBranchExecuted) = 1;
549 } else {
550 (* outBranchExecuted) = 0;
551 DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
552 DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - "));
553 }
554
555 if(!inDoRollback && (* outBranchExecuted)){
556 DEBUG("commit\n");
557 check = MyTransaction->execute( Commit );
558 CHECK_MINUS_ONE(check, "T5: Commit",
559 MyTransaction);
560 } else {
561 DEBUG("rollback\n");
562 check = MyTransaction->execute(Rollback);
563 CHECK_MINUS_ONE(check, "T5:Rollback",
564 MyTransaction);
565
566 }
567
568 pNDB->closeTransaction(MyTransaction);
569 }
570
571