1 /*
2    Copyright (C) 2003-2006 MySQL AB
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 extern "C" {
29 #include "user_transaction.h"
30 };
31 
32 #include "macros.h"
33 #include "ndb_schema.hpp"
34 #include "ndb_error.hpp"
35 
36 #include <time.h>
37 #include <NdbApi.hpp>
38 
39 /**
40  * Transaction 1 - T1
41  *
42  * Update location and changed by/time on a subscriber
43  *
44  * Input:
45  *   SubscriberNumber,
46  *   Location,
47  *   ChangedBy,
48  *   ChangedTime
49  *
50  * Output:
51  */
52 int
T1(void * obj,const SubscriberNumber number,const Location new_location,const ChangedBy changed_by,const ChangedTime changed_time,BenchmarkTime * transaction_time)53 T1(void * obj,
54    const SubscriberNumber number,
55    const Location new_location,
56    const ChangedBy changed_by,
57    const ChangedTime changed_time,
58    BenchmarkTime * transaction_time){
59 
60   Ndb * pNDB = (Ndb *) obj;
61 
62   BenchmarkTime start;
63   get_time(&start);
64 
65   int check;
66   NdbRecAttr * check2;
67 
68   NdbConnection * MyTransaction = pNDB->startTransaction();
69   if (MyTransaction == NULL)
70     error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0);
71 
72   NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
73   CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction);
74 
75   check = MyOperation->updateTuple();
76   CHECK_MINUS_ONE(check, "T1: updateTuple",
77 		  MyTransaction);
78 
79   check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
80 			     number);
81   CHECK_MINUS_ONE(check, "T1: equal subscriber",
82 		  MyTransaction);
83 
84   check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION,
85 				(char *)&new_location);
86   CHECK_MINUS_ONE(check, "T1: setValue location",
87 		  MyTransaction);
88 
89   check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY,
90 				changed_by);
91   CHECK_MINUS_ONE(check, "T1: setValue changed_by",
92 		  MyTransaction);
93 
94   check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME,
95 				changed_time);
96   CHECK_MINUS_ONE(check, "T1: setValue changed_time",
97 		  MyTransaction);
98 
99   check = MyTransaction->execute( Commit );
100   CHECK_MINUS_ONE(check, "T1: Commit",
101 		  MyTransaction);
102 
103   pNDB->closeTransaction(MyTransaction);
104 
105   get_time(transaction_time);
106   time_diff(transaction_time, &start);
107   return 0;
108 }
109 
110 /**
111  * Transaction 2 - T2
112  *
113  * Read from Subscriber:
114  *
115  * Input:
116  *   SubscriberNumber
117  *
118  * Output:
119  *   Location
120  *   Changed by
121  *   Changed Timestamp
122  *   Name
123  */
124 int
T2(void * obj,const SubscriberNumber number,Location * readLocation,ChangedBy changed_by,ChangedTime changed_time,SubscriberName subscriberName,BenchmarkTime * transaction_time)125 T2(void * obj,
126    const SubscriberNumber number,
127    Location * readLocation,
128    ChangedBy changed_by,
129    ChangedTime changed_time,
130    SubscriberName subscriberName,
131    BenchmarkTime * transaction_time){
132 
133   Ndb * pNDB = (Ndb *) obj;
134 
135   BenchmarkTime start;
136   get_time(&start);
137 
138   int check;
139   NdbRecAttr * check2;
140 
141   NdbConnection * MyTransaction = pNDB->startTransaction();
142   if (MyTransaction == NULL)
143     error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0);
144 
145   NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
146   CHECK_NULL(MyOperation, "T2: getNdbOperation",
147 	     MyTransaction);
148 
149 
150   check = MyOperation->readTuple();
151   CHECK_MINUS_ONE(check, "T2: readTuple",
152 		  MyTransaction);
153 
154   check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
155 			     number);
156   CHECK_MINUS_ONE(check, "T2: equal subscriber",
157 		  MyTransaction);
158 
159   check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
160 				(char *)readLocation);
161   CHECK_NULL(check2, "T2: getValue location",
162 	     MyTransaction);
163 
164   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
165 				 changed_by);
166   CHECK_NULL(check2, "T2: getValue changed_by",
167 	     MyTransaction);
168 
169   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
170                                  changed_time);
171   CHECK_NULL(check2, "T2: getValue changed_time",
172 	     MyTransaction);
173 
174   check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME,
175 				subscriberName);
176   CHECK_NULL(check2, "T2: getValue name",
177 	     MyTransaction);
178 
179   check = MyTransaction->execute( Commit );
180   CHECK_MINUS_ONE(check, "T2: Commit",
181 		  MyTransaction);
182 
183   pNDB->closeTransaction(MyTransaction);
184 
185   get_time(transaction_time);
186   time_diff(transaction_time, &start);
187   return 0;
188 }
189 
190 /**
191  * Transaction 3 - T3
192  *
193  * Read session details
194  *
195  * Input:
196  *   SubscriberNumber
197  *   ServerId
198  *   ServerBit
199  *
200  * Output:
201  *   BranchExecuted
202  *   SessionDetails
203  *   ChangedBy
204  *   ChangedTime
205  *   Location
206  */
207 int
T3(void * obj,const SubscriberNumber inNumber,const SubscriberSuffix inSuffix,const ServerId inServerId,const ServerBit inServerBit,SessionDetails outSessionDetails,ChangedBy outChangedBy,ChangedTime outChangedTime,Location * outLocation,BranchExecuted * outBranchExecuted,BenchmarkTime * outTransactionTime)208 T3(void * obj,
209    const SubscriberNumber   inNumber,
210    const SubscriberSuffix   inSuffix,
211    const ServerId           inServerId,
212    const ServerBit          inServerBit,
213    SessionDetails     outSessionDetails,
214    ChangedBy          outChangedBy,
215    ChangedTime        outChangedTime,
216    Location         * outLocation,
217    BranchExecuted   * outBranchExecuted,
218    BenchmarkTime    * outTransactionTime){
219 
220   Ndb * pNDB = (Ndb *) obj;
221 
222   GroupId        groupId;
223   ActiveSessions sessions;
224   Permission     permission;
225 
226   BenchmarkTime start;
227   get_time(&start);
228 
229   int check;
230   NdbRecAttr * check2;
231 
232   NdbConnection * MyTransaction = pNDB->startTransaction();
233   if (MyTransaction == NULL)
234     error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0);
235 
236   NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
237   CHECK_NULL(MyOperation, "T3-1: getNdbOperation",
238 	     MyTransaction);
239 
240 
241   check = MyOperation->readTuple();
242   CHECK_MINUS_ONE(check, "T3-1: readTuple",
243 		  MyTransaction);
244 
245   check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
246 			     inNumber);
247   CHECK_MINUS_ONE(check, "T3-1: equal subscriber",
248 		  MyTransaction);
249 
250   check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
251 				 (char *)outLocation);
252   CHECK_NULL(check2, "T3-1: getValue location",
253 	     MyTransaction);
254 
255   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
256 				 outChangedBy);
257   CHECK_NULL(check2, "T3-1: getValue changed_by",
258 	     MyTransaction);
259 
260   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
261                                  outChangedTime);
262   CHECK_NULL(check2, "T3-1: getValue changed_time",
263 	     MyTransaction);
264 
265   check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP,
266 				 (char *)&groupId);
267   CHECK_NULL(check2, "T3-1: getValue group",
268 	     MyTransaction);
269 
270   check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
271 				 (char *)&sessions);
272   CHECK_NULL(check2, "T3-1: getValue sessions",
273 	     MyTransaction);
274 
275   check = MyTransaction->execute( NoCommit );
276   CHECK_MINUS_ONE(check, "T3-1: NoCommit",
277 		  MyTransaction);
278 
279     /* Operation 2 */
280 
281   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
282   CHECK_NULL(MyOperation, "T3-2: getNdbOperation",
283 	     MyTransaction);
284 
285 
286   check = MyOperation->readTuple();
287   CHECK_MINUS_ONE(check, "T3-2: readTuple",
288 		  MyTransaction);
289 
290   check = MyOperation->equal(IND_GROUP_ID,
291 		     (char*)&groupId);
292   CHECK_MINUS_ONE(check, "T3-2: equal group",
293 		  MyTransaction);
294 
295   check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ,
296 				 (char *)&permission);
297   CHECK_NULL(check2, "T3-2: getValue allow_read",
298 	     MyTransaction);
299 
300   check = MyTransaction->execute( NoCommit );
301   CHECK_MINUS_ONE(check, "T3-2: NoCommit",
302 		  MyTransaction);
303 
304   DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
305 
306   if(((permission & inServerBit) == inServerBit) &&
307      ((sessions   & inServerBit) == inServerBit)){
308 
309     DEBUG("reading - ");
310 
311     /* Operation 3 */
312 
313     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
314     CHECK_NULL(MyOperation, "T3-3: getNdbOperation",
315 	       MyTransaction);
316 
317     check = MyOperation->readTuple();
318     CHECK_MINUS_ONE(check, "T3-3: readTuple",
319 		    MyTransaction);
320 
321     check = MyOperation->equal(IND_SESSION_SUBSCRIBER,
322 			       (char*)inNumber);
323     CHECK_MINUS_ONE(check, "T3-3: equal number",
324 		    MyTransaction);
325 
326     check = MyOperation->equal(IND_SESSION_SERVER,
327 			       (char*)&inServerId);
328     CHECK_MINUS_ONE(check, "T3-3: equal server id",
329 		    MyTransaction);
330 
331     check2 = MyOperation->getValue(IND_SESSION_DATA,
332 				   (char *)outSessionDetails);
333     CHECK_NULL(check2, "T3-3: getValue session details",
334 	       MyTransaction);
335 
336     check = MyTransaction->execute( NoCommit );
337     CHECK_MINUS_ONE(check, "T3-3: NoCommit",
338 		    MyTransaction);
339 
340     /* Operation 4 */
341 
342     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
343     CHECK_NULL(MyOperation, "T3-4: getNdbOperation",
344 	       MyTransaction);
345 
346     check = MyOperation->interpretedUpdateTuple();
347     CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple",
348 		    MyTransaction);
349 
350     check = MyOperation->equal(IND_SERVER_ID,
351 			       (char*)&inServerId);
352     CHECK_MINUS_ONE(check, "T3-4: equal serverId",
353 		    MyTransaction);
354 
355     check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
356 			       (char*)inSuffix);
357     CHECK_MINUS_ONE(check, "T3-4: equal suffix",
358 		    MyTransaction);
359 
360     check = MyOperation->incValue(IND_SERVER_READS, (uint32)1);
361     CHECK_MINUS_ONE(check, "T3-4: inc value",
362 		    MyTransaction);
363 
364     check = MyTransaction->execute( NoCommit );
365     CHECK_MINUS_ONE(check, "T3-4: NoCommit",
366 		    MyTransaction);
367 
368     (* outBranchExecuted) = 1;
369   } else {
370     (* outBranchExecuted) = 0;
371   }
372   DEBUG("commit\n");
373   check = MyTransaction->execute( Commit );
374   CHECK_MINUS_ONE(check, "T3: Commit",
375 		  MyTransaction);
376 
377   pNDB->closeTransaction(MyTransaction);
378 
379   get_time(outTransactionTime);
380   time_diff(outTransactionTime, &start);
381   return 0;
382 }
383 
384 
385 /**
386  * Transaction 4 - T4
387  *
388  * Create session
389  *
390  * Input:
391  *   SubscriberNumber
392  *   ServerId
393  *   ServerBit
394  *   SessionDetails,
395  *   DoRollback
396  * Output:
397  *   ChangedBy
398  *   ChangedTime
399  *   Location
400  *   BranchExecuted
401  */
402 int
T4(void * obj,const SubscriberNumber inNumber,const SubscriberSuffix inSuffix,const ServerId inServerId,const ServerBit inServerBit,const SessionDetails inSessionDetails,ChangedBy outChangedBy,ChangedTime outChangedTime,Location * outLocation,DoRollback inDoRollback,BranchExecuted * outBranchExecuted,BenchmarkTime * outTransactionTime)403 T4(void * obj,
404    const SubscriberNumber   inNumber,
405    const SubscriberSuffix   inSuffix,
406    const ServerId           inServerId,
407    const ServerBit          inServerBit,
408    const SessionDetails     inSessionDetails,
409    ChangedBy          outChangedBy,
410    ChangedTime        outChangedTime,
411    Location         * outLocation,
412    DoRollback         inDoRollback,
413    BranchExecuted   * outBranchExecuted,
414    BenchmarkTime    * outTransactionTime){
415 
416   Ndb * pNDB = (Ndb *) obj;
417 
418   GroupId        groupId;
419   ActiveSessions sessions;
420   Permission     permission;
421 
422   BenchmarkTime start;
423   get_time(&start);
424 
425   int check;
426   NdbRecAttr * check2;
427 
428   NdbConnection * MyTransaction = pNDB->startTransaction();
429   if (MyTransaction == NULL)
430     error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0);
431 
432   DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
433 
434   NdbOperation * MyOperation = 0;
435 
436   MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
437   CHECK_NULL(MyOperation, "T4-1: getNdbOperation",
438 	     MyTransaction);
439 
440   check = MyOperation->readTupleExclusive();
441   CHECK_MINUS_ONE(check, "T4-1: readTuple",
442 		  MyTransaction);
443 
444   check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
445 			     inNumber);
446   CHECK_MINUS_ONE(check, "T4-1: equal subscriber",
447 		  MyTransaction);
448 
449   check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
450 				 (char *)outLocation);
451   CHECK_NULL(check2, "T4-1: getValue location",
452 	     MyTransaction);
453 
454   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
455 				 outChangedBy);
456   CHECK_NULL(check2, "T4-1: getValue changed_by",
457 	     MyTransaction);
458 
459   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
460                                  outChangedTime);
461   CHECK_NULL(check2, "T4-1: getValue changed_time",
462 	     MyTransaction);
463 
464   check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP,
465 				 (char *)&groupId);
466   CHECK_NULL(check2, "T4-1: getValue group",
467 	     MyTransaction);
468 
469   check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
470 				 (char *)&sessions);
471   CHECK_NULL(check2, "T4-1: getValue sessions",
472 	     MyTransaction);
473 
474   check = MyTransaction->execute( NoCommit );
475   CHECK_MINUS_ONE(check, "T4-1: NoCommit",
476 		  MyTransaction);
477 
478     /* Operation 2 */
479   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
480   CHECK_NULL(MyOperation, "T4-2: getNdbOperation",
481 	     MyTransaction);
482 
483   check = MyOperation->readTuple();
484   CHECK_MINUS_ONE(check, "T4-2: readTuple",
485 		  MyTransaction);
486 
487   check = MyOperation->equal(IND_GROUP_ID,
488 		     (char*)&groupId);
489   CHECK_MINUS_ONE(check, "T4-2: equal group",
490 		  MyTransaction);
491 
492   check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT,
493 				 (char *)&permission);
494   CHECK_NULL(check2, "T4-2: getValue allow_insert",
495 	     MyTransaction);
496 
497   check = MyTransaction->execute( NoCommit );
498   CHECK_MINUS_ONE(check, "T4-2: NoCommit",
499 		  MyTransaction);
500 
501   if(((permission & inServerBit) == inServerBit) &&
502      ((sessions   & inServerBit) == 0)){
503 
504     DEBUG("inserting - ");
505 
506     /* Operation 3 */
507     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
508     CHECK_NULL(MyOperation, "T4-3: getNdbOperation",
509 	       MyTransaction);
510 
511     check = MyOperation->insertTuple();
512     CHECK_MINUS_ONE(check, "T4-3: insertTuple",
513 		    MyTransaction);
514 
515     check = MyOperation->equal(IND_SESSION_SUBSCRIBER,
516 			       (char*)inNumber);
517     CHECK_MINUS_ONE(check, "T4-3: equal number",
518 		    MyTransaction);
519 
520     check = MyOperation->equal(IND_SESSION_SERVER,
521 			       (char*)&inServerId);
522     CHECK_MINUS_ONE(check, "T4-3: equal server id",
523 		    MyTransaction);
524 
525     check = MyOperation->setValue(SESSION_DATA,
526 				   (char *)inSessionDetails);
527     CHECK_MINUS_ONE(check, "T4-3: setValue session details",
528 	       MyTransaction);
529 
530     check = MyTransaction->execute( NoCommit );
531     CHECK_MINUS_ONE(check, "T4-3: NoCommit",
532 		    MyTransaction);
533 
534     /* Operation 4 */
535     MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
536     CHECK_NULL(MyOperation, "T4-4: getNdbOperation",
537 	       MyTransaction);
538 
539     check = MyOperation->interpretedUpdateTuple();
540     CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple",
541 		    MyTransaction);
542 
543     check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
544 			       (char*)inNumber);
545     CHECK_MINUS_ONE(check, "T4-4: equal number",
546 		    MyTransaction);
547 
548     check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS,
549 				  (uint32)inServerBit);
550     CHECK_MINUS_ONE(check, "T4-4: inc value",
551 		    MyTransaction);
552 
553     check = MyTransaction->execute( NoCommit );
554     CHECK_MINUS_ONE(check, "T4-4: NoCommit",
555 		    MyTransaction);
556 
557     /* Operation 5 */
558     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
559     CHECK_NULL(MyOperation, "T4-5: getNdbOperation",
560 	       MyTransaction);
561 
562     check = MyOperation->interpretedUpdateTuple();
563     CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple",
564 		    MyTransaction);
565 
566     check = MyOperation->equal(IND_SERVER_ID,
567 			       (char*)&inServerId);
568     CHECK_MINUS_ONE(check, "T4-5: equal serverId",
569 		    MyTransaction);
570 
571     check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
572 			       (char*)inSuffix);
573     CHECK_MINUS_ONE(check, "T4-5: equal suffix",
574 		    MyTransaction);
575 
576     check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1);
577     CHECK_MINUS_ONE(check, "T4-5: inc value",
578 		    MyTransaction);
579 
580     check = MyTransaction->execute( NoCommit );
581     CHECK_MINUS_ONE(check, "T4-5: NoCommit",
582 		    MyTransaction);
583 
584     (* outBranchExecuted) = 1;
585   } else {
586     DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
587     DEBUG1("%s", ((sessions   & inServerBit) ? "in session - " : "no in session - "));
588     (* outBranchExecuted) = 0;
589   }
590 
591   if(!inDoRollback){
592     DEBUG("commit\n");
593     check = MyTransaction->execute( Commit );
594     CHECK_MINUS_ONE(check, "T4: Commit",
595 		    MyTransaction);
596   } else {
597     DEBUG("rollback\n");
598     check = MyTransaction->execute(Rollback);
599     CHECK_MINUS_ONE(check, "T4:Rollback",
600 		    MyTransaction);
601 
602   }
603 
604   pNDB->closeTransaction(MyTransaction);
605 
606   get_time(outTransactionTime);
607   time_diff(outTransactionTime, &start);
608   return 0;
609 }
610 
611 
612 /**
613  * Transaction 5 - T5
614  *
615  * Delete session
616  *
617  * Input:
618  *   SubscriberNumber
619  *   ServerId
620  *   ServerBit
621  *   DoRollback
622  * Output:
623  *   ChangedBy
624  *   ChangedTime
625  *   Location
626  *   BranchExecuted
627  */
628 int
T5(void * obj,const SubscriberNumber inNumber,const SubscriberSuffix inSuffix,const ServerId inServerId,const ServerBit inServerBit,ChangedBy outChangedBy,ChangedTime outChangedTime,Location * outLocation,DoRollback inDoRollback,BranchExecuted * outBranchExecuted,BenchmarkTime * outTransactionTime)629 T5(void * obj,
630    const SubscriberNumber   inNumber,
631    const SubscriberSuffix   inSuffix,
632    const ServerId           inServerId,
633    const ServerBit          inServerBit,
634    ChangedBy          outChangedBy,
635    ChangedTime        outChangedTime,
636    Location         * outLocation,
637    DoRollback         inDoRollback,
638    BranchExecuted   * outBranchExecuted,
639    BenchmarkTime    * outTransactionTime){
640 
641   Ndb           * pNDB = (Ndb *) obj;
642   NdbConnection * MyTransaction = 0;
643   NdbOperation  * MyOperation = 0;
644 
645   GroupId        groupId;
646   ActiveSessions sessions;
647   Permission     permission;
648 
649   BenchmarkTime start;
650   get_time(&start);
651 
652   int check;
653   NdbRecAttr * check2;
654 
655   MyTransaction = pNDB->startTransaction();
656   if (MyTransaction == NULL)
657     error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0);
658 
659   MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
660   CHECK_NULL(MyOperation, "T5-1: getNdbOperation",
661 	     MyTransaction);
662 
663 
664   check = MyOperation->readTupleExclusive();
665   CHECK_MINUS_ONE(check, "T5-1: readTuple",
666 		  MyTransaction);
667 
668   check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
669 			     inNumber);
670   CHECK_MINUS_ONE(check, "T5-1: equal subscriber",
671 		  MyTransaction);
672 
673   check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION,
674 				 (char *)outLocation);
675   CHECK_NULL(check2, "T5-1: getValue location",
676 	     MyTransaction);
677 
678   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY,
679 				 outChangedBy);
680   CHECK_NULL(check2, "T5-1: getValue changed_by",
681 	     MyTransaction);
682 
683   check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME,
684                                  outChangedTime);
685   CHECK_NULL(check2, "T5-1: getValue changed_time",
686 	     MyTransaction);
687 
688   check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP,
689 				 (char *)&groupId);
690   CHECK_NULL(check2, "T5-1: getValue group",
691 	     MyTransaction);
692 
693   check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
694 				 (char *)&sessions);
695   CHECK_NULL(check2, "T5-1: getValue sessions",
696 	     MyTransaction);
697 
698   check = MyTransaction->execute( NoCommit );
699   CHECK_MINUS_ONE(check, "T5-1: NoCommit",
700 		  MyTransaction);
701 
702     /* Operation 2 */
703 
704   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
705   CHECK_NULL(MyOperation, "T5-2: getNdbOperation",
706 	     MyTransaction);
707 
708 
709   check = MyOperation->readTuple();
710   CHECK_MINUS_ONE(check, "T5-2: readTuple",
711 		  MyTransaction);
712 
713   check = MyOperation->equal(IND_GROUP_ID,
714 		     (char*)&groupId);
715   CHECK_MINUS_ONE(check, "T5-2: equal group",
716 		  MyTransaction);
717 
718   check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE,
719 				 (char *)&permission);
720   CHECK_NULL(check2, "T5-2: getValue allow_delete",
721 	     MyTransaction);
722 
723   check = MyTransaction->execute( NoCommit );
724   CHECK_MINUS_ONE(check, "T5-2: NoCommit",
725 		  MyTransaction);
726 
727   DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
728 
729   if(((permission & inServerBit) == inServerBit) &&
730      ((sessions   & inServerBit) == inServerBit)){
731 
732     DEBUG("deleting - ");
733 
734     /* Operation 3 */
735     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
736     CHECK_NULL(MyOperation, "T5-3: getNdbOperation",
737 	       MyTransaction);
738 
739     check = MyOperation->deleteTuple();
740     CHECK_MINUS_ONE(check, "T5-3: deleteTuple",
741 		    MyTransaction);
742 
743     check = MyOperation->equal(IND_SESSION_SUBSCRIBER,
744 			       (char*)inNumber);
745     CHECK_MINUS_ONE(check, "T5-3: equal number",
746 		    MyTransaction);
747 
748     check = MyOperation->equal(IND_SESSION_SERVER,
749 			       (char*)&inServerId);
750     CHECK_MINUS_ONE(check, "T5-3: equal server id",
751 		    MyTransaction);
752 
753     check = MyTransaction->execute( NoCommit );
754     CHECK_MINUS_ONE(check, "T5-3: NoCommit",
755 		    MyTransaction);
756 
757     /* Operation 4 */
758     MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
759     CHECK_NULL(MyOperation, "T5-4: getNdbOperation",
760 	       MyTransaction);
761 
762     check = MyOperation->interpretedUpdateTuple();
763     CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple",
764 		    MyTransaction);
765 
766     check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
767 			       (char*)inNumber);
768     CHECK_MINUS_ONE(check, "T5-4: equal number",
769 		    MyTransaction);
770 
771     check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS,
772 				  (uint32)inServerBit);
773     CHECK_MINUS_ONE(check, "T5-4: dec value",
774 		    MyTransaction);
775 
776     check = MyTransaction->execute( NoCommit );
777     CHECK_MINUS_ONE(check, "T5-4: NoCommit",
778 		    MyTransaction);
779 
780     /* Operation 5 */
781     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
782     CHECK_NULL(MyOperation, "T5-5: getNdbOperation",
783 	       MyTransaction);
784 
785 
786     check = MyOperation->interpretedUpdateTuple();
787     CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple",
788 		    MyTransaction);
789 
790     check = MyOperation->equal(IND_SERVER_ID,
791 			       (char*)&inServerId);
792     CHECK_MINUS_ONE(check, "T5-5: equal serverId",
793 		    MyTransaction);
794 
795     check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
796 			       (char*)inSuffix);
797     CHECK_MINUS_ONE(check, "T5-5: equal suffix",
798 		    MyTransaction);
799 
800     check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1);
801     CHECK_MINUS_ONE(check, "T5-5: inc value",
802 		    MyTransaction);
803 
804     check = MyTransaction->execute( NoCommit );
805     CHECK_MINUS_ONE(check, "T5-5: NoCommit",
806 		    MyTransaction);
807 
808     (* outBranchExecuted) = 1;
809   } else {
810     DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
811     DEBUG1("%s", ((sessions   & inServerBit) ? "in session - " : "no in session - "));
812     (* outBranchExecuted) = 0;
813   }
814 
815   if(!inDoRollback){
816     DEBUG("commit\n");
817     check = MyTransaction->execute( Commit );
818     CHECK_MINUS_ONE(check, "T5: Commit",
819 		    MyTransaction);
820   } else {
821     DEBUG("rollback\n");
822     check = MyTransaction->execute(Rollback);
823     CHECK_MINUS_ONE(check, "T5:Rollback",
824 		    MyTransaction);
825 
826   }
827 
828   pNDB->closeTransaction(MyTransaction);
829 
830   get_time(outTransactionTime);
831   time_diff(outTransactionTime, &start);
832   return 0;
833 }
834 
835