~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/test/ndbapi/bank/BankLoad.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include "Bank.hpp"
 
17
#include <UtilTransactions.hpp>
 
18
 
 
19
/**
 
20
 * Default account types
 
21
 *
 
22
 */
 
23
struct AccountTypesStruct {
 
24
  int id;
 
25
  const char descr[64];
 
26
};
 
27
const AccountTypesStruct accountTypes[] = {
 
28
  { 0, "KASSA"},
 
29
  { 1, "BANKOMAT"},
 
30
  { 2, "POSTGIRO"},
 
31
  { 3, "Lļæ½NEKONTO"},
 
32
  { 4, "SPARKONTO"}
 
33
};
 
34
 
 
35
const int
 
36
accountTypesSize = sizeof(accountTypes)/sizeof(AccountTypesStruct);
 
37
 
 
38
 
 
39
const char*  tableNames[] = {
 
40
  "GL",
 
41
  "ACCOUNT", 
 
42
  "SYSTEM_VALUES",
 
43
  "TRANSACTION",
 
44
  "ACCOUNT_TYPE"
 
45
};
 
46
 
 
47
const int
 
48
tableNamesSize = sizeof(tableNames)/sizeof(const char*);
 
49
 
 
50
 
 
51
int Bank::getNumAccountTypes(){
 
52
  return accountTypesSize;
 
53
}
 
54
 
 
55
int Bank::createAndLoadBank(bool ovrWrt, bool disk, int num_accounts){
 
56
 
 
57
  m_ndb.init();   
 
58
  if (m_ndb.waitUntilReady() != 0)
 
59
    return NDBT_FAILED;
 
60
 
 
61
  const NdbDictionary::Table* pSysValTab = 
 
62
    m_ndb.getDictionary()->getTable("SYSTEM_VALUES");
 
63
  if (pSysValTab != NULL){
 
64
    // The table exists
 
65
    if (ovrWrt == false){
 
66
      ndbout << "Bank already exist and overwrite == false" << endl;
 
67
      return NDBT_FAILED;
 
68
    }
 
69
  }
 
70
  
 
71
  if (!m_skip_create && createTables(disk) != NDBT_OK)
 
72
    return NDBT_FAILED;
 
73
  
 
74
  if (clearTables() != NDBT_OK)
 
75
    return NDBT_FAILED;
 
76
  
 
77
  if (loadAccountType() != NDBT_OK)
 
78
    return NDBT_FAILED;
 
79
  
 
80
  if (loadAccount(num_accounts) != NDBT_OK)
 
81
    return NDBT_FAILED;
 
82
    
 
83
  if (loadSystemValues() != NDBT_OK)
 
84
    return NDBT_FAILED;
 
85
 
 
86
  if (loadGl() != NDBT_OK)
 
87
    return NDBT_FAILED;
 
88
  
 
89
  return NDBT_OK;
 
90
 
 
91
}
 
92
 
 
93
int Bank::dropBank(){
 
94
 
 
95
  m_ndb.init();   
 
96
  if (m_ndb.waitUntilReady() != 0)
 
97
    return NDBT_FAILED;
 
98
 
 
99
  if (dropTables() != NDBT_OK)
 
100
    return NDBT_FAILED;
 
101
  
 
102
  return NDBT_OK;
 
103
 
 
104
}
 
105
 
 
106
int Bank::createTables(bool disk){
 
107
  for (int i = 0; i < tableNamesSize; i++){
 
108
    if (createTable(tableNames[i], disk) != NDBT_OK)
 
109
      return NDBT_FAILED;
 
110
  }
 
111
  return NDBT_OK;
 
112
}
 
113
 
 
114
 
 
115
int Bank::dropTables(){
 
116
  for (int i = 0; i < tableNamesSize; i++){
 
117
    if (dropTable(tableNames[i]) != NDBT_OK)
 
118
      return NDBT_FAILED;
 
119
  }
 
120
  return NDBT_OK;
 
121
}
 
122
 
 
123
int Bank::clearTables(){
 
124
  for (int i = 0; i < tableNamesSize; i++){
 
125
    if (clearTable(tableNames[i]) != NDBT_OK)
 
126
      return NDBT_FAILED;
 
127
  }
 
128
  return NDBT_OK;
 
129
}
 
130
   
 
131
int Bank::clearTable(const char* tabName){ 
 
132
  UtilTransactions util(&m_ndb, tabName);
 
133
  if(util.clearTable(&m_ndb, 64) != 0)
 
134
    return NDBT_FAILED;
 
135
  return NDBT_OK;
 
136
}
 
137
 
 
138
int Bank::createTable(const char* tabName, bool disk){    
 
139
  ndbout << "createTable " << tabName << endl;
 
140
 
 
141
  const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName);
 
142
  if (pTab == NULL)
 
143
    return NDBT_FAILED;
 
144
  
 
145
  const NdbDictionary::Table* org = 
 
146
    m_ndb.getDictionary()->getTable(tabName);
 
147
  
 
148
  if (org != 0 && (disk || pTab->equal(* org)))
 
149
  {
 
150
    return NDBT_OK;
 
151
  }
 
152
  
 
153
  if (org != 0){
 
154
    ndbout << "Different table with same name exists" << endl;
 
155
    return NDBT_FAILED;
 
156
  }
 
157
 
 
158
  if (disk)
 
159
  {
 
160
    if (NDBT_Tables::create_default_tablespace(&m_ndb))
 
161
    {
 
162
      ndbout << "Failed to create tablespaces" << endl;
 
163
      return NDBT_FAILED;
 
164
    }
 
165
    NdbDictionary::Table copy(* pTab);
 
166
    copy.setTablespaceName("DEFAULT-TS");
 
167
    for (Uint32 i = 0; i<copy.getNoOfColumns(); i++)
 
168
      copy.getColumn(i)->setStorageType(NdbDictionary::Column::StorageTypeDisk);
 
169
    if(m_ndb.getDictionary()->createTable(copy) == -1){
 
170
      ndbout << "Failed to create table: " <<
 
171
        m_ndb.getNdbError() << endl;
 
172
      return NDBT_FAILED;
 
173
    }
 
174
  }
 
175
  else
 
176
  {
 
177
    if(m_ndb.getDictionary()->createTable(* pTab) == -1){
 
178
      ndbout << "Failed to create table: " <<
 
179
        m_ndb.getNdbError() << endl;
 
180
      return NDBT_FAILED;
 
181
    }
 
182
  }
 
183
 
 
184
  return NDBT_OK;    
 
185
}
 
186
 
 
187
int Bank::dropTable(const char* tabName){    
 
188
  const NdbDictionary::Table* org = 
 
189
    m_ndb.getDictionary()->getTable(tabName);
 
190
  
 
191
  if (org == NULL)
 
192
    return NDBT_OK;
 
193
  
 
194
  ndbout << "dropTable " <<tabName<<endl;
 
195
  if (m_ndb.getDictionary()->dropTable(tabName)  != 0){
 
196
    return NDBT_FAILED;
 
197
  }
 
198
  
 
199
  return NDBT_OK;    
 
200
}
 
201
 
 
202
 
 
203
 
 
204
 
 
205
 
 
206
 
 
207
 
 
208
 
 
209
/**
 
210
 * Load SYSTEM_VALUES table
 
211
 *  This table keeps track of system wide settings
 
212
 *  For example:
 
213
 *   - next transaction id
 
214
 *
 
215
 */
 
216
int Bank::loadSystemValues (){
 
217
int result;
 
218
 
 
219
/**
 
220
 * Insert start value for next transaction id
 
221
 *
 
222
 */
 
223
result = writeSystemValue(LastTransactionId, 0);
 
224
 
 
225
/**
 
226
 * Insert start value for current time
 
227
 *
 
228
 */
 
229
result = writeSystemValue(CurrentTime, 1);
 
230
 
 
231
return result;
 
232
 
 
233
}
 
234
 
 
235
 
 
236
/**
 
237
 * Load GL table
 
238
 * 
 
239
 * Insert GL records for time = 0 with balance 0
 
240
 */
 
241
int Bank::loadGl(){
 
242
  g_info << "loadGl" << endl;
 
243
  int check;
 
244
    
 
245
  NdbConnection* pTrans = m_ndb.startTransaction();
 
246
  if (pTrans == NULL){
 
247
    ERR(m_ndb.getNdbError());
 
248
    return NDBT_FAILED;
 
249
  }
 
250
    
 
251
  for (int i = 0; i < getNumAccountTypes(); i++){
 
252
      
 
253
    NdbOperation* pOp = pTrans->getNdbOperation("GL");
 
254
    if (pOp == NULL) {
 
255
      ERR(pTrans->getNdbError());
 
256
      m_ndb.closeTransaction(pTrans);
 
257
      return NDBT_FAILED;
 
258
    }
 
259
    
 
260
    check = pOp->insertTuple();
 
261
    if( check == -1 ) {
 
262
      ERR(pTrans->getNdbError());
 
263
      m_ndb.closeTransaction(pTrans);
 
264
      return NDBT_FAILED;
 
265
    }
 
266
 
 
267
    Uint64 time = 0;
 
268
    check = pOp->equal("TIME", time);
 
269
    if( check == -1 ) {
 
270
      ERR(pTrans->getNdbError());
 
271
      m_ndb.closeTransaction(pTrans);
 
272
      return NDBT_FAILED;
 
273
    }
 
274
      
 
275
    check = pOp->equal("ACCOUNT_TYPE", i);
 
276
    if( check == -1 ) {
 
277
      ERR(pTrans->getNdbError());
 
278
      m_ndb.closeTransaction(pTrans);
 
279
      return NDBT_FAILED;
 
280
    }
 
281
 
 
282
    Uint32 balance = 0;
 
283
    if (getBalanceForAccountType(i, balance) != NDBT_OK){
 
284
      return NDBT_FAILED;
 
285
    }
 
286
 
 
287
    check = pOp->setValue("BALANCE", balance);
 
288
    if( check == -1 ) {
 
289
      ERR(pTrans->getNdbError());
 
290
      m_ndb.closeTransaction(pTrans);
 
291
      return NDBT_FAILED;
 
292
    }
 
293
      
 
294
    Uint32 depositCount = 0;
 
295
    check = pOp->setValue("DEPOSIT_COUNT", depositCount);
 
296
    if( check == -1 ) {
 
297
      ERR(pTrans->getNdbError());
 
298
      m_ndb.closeTransaction(pTrans);
 
299
      return NDBT_FAILED;
 
300
    }
 
301
      
 
302
    Uint32 depositSum = 0;
 
303
    check = pOp->setValue("DEPOSIT_SUM", depositSum);
 
304
    if( check == -1 ) {
 
305
      ERR(pTrans->getNdbError());
 
306
      m_ndb.closeTransaction(pTrans);
 
307
      return NDBT_FAILED;
 
308
    }
 
309
      
 
310
    Uint32 withdrawalCount = 0;
 
311
    check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount);
 
312
    if( check == -1 ) {
 
313
      ERR(pTrans->getNdbError());
 
314
      m_ndb.closeTransaction(pTrans);
 
315
      return NDBT_FAILED;
 
316
    }
 
317
      
 
318
    Uint32 withdrawalSum = 0;
 
319
    check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum);
 
320
    if( check == -1 ) {
 
321
      ERR(pTrans->getNdbError());
 
322
      m_ndb.closeTransaction(pTrans);
 
323
      return NDBT_FAILED;
 
324
    }
 
325
      
 
326
    Uint32 purged = 1;
 
327
    check = pOp->setValue("PURGED", purged);
 
328
    if( check == -1 ) {
 
329
      ERR(pTrans->getNdbError());
 
330
      m_ndb.closeTransaction(pTrans);
 
331
      return NDBT_FAILED;
 
332
    }
 
333
      
 
334
  }
 
335
  check = pTrans->execute(Commit);
 
336
  if( check == -1 ) {
 
337
    ERR(pTrans->getNdbError());
 
338
    m_ndb.closeTransaction(pTrans);
 
339
    return NDBT_FAILED;
 
340
  }
 
341
    
 
342
  m_ndb.closeTransaction(pTrans);      
 
343
  return NDBT_OK;
 
344
 
345
 
 
346
 
 
347
int Bank::getBalanceForAccountType(const Uint32 accountType,
 
348
                                   Uint32& balance){
 
349
  int check;
 
350
  g_info << "getBalanceForAccountType: accountType="<<accountType<<endl;
 
351
    
 
352
  NdbConnection* pScanTrans = m_ndb.startTransaction();
 
353
  if (pScanTrans == NULL) {
 
354
    ERR(m_ndb.getNdbError());
 
355
    return NDBT_FAILED;
 
356
  }
 
357
      
 
358
  NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("ACCOUNT");   
 
359
  if (pOp == NULL) {
 
360
    ERR(pScanTrans->getNdbError());
 
361
    m_ndb.closeTransaction(pScanTrans);
 
362
    return NDBT_FAILED;
 
363
  }
 
364
 
 
365
  if( pOp->readTuples() ) {
 
366
    ERR(pScanTrans->getNdbError());
 
367
    m_ndb.closeTransaction(pScanTrans);
 
368
    return NDBT_FAILED;
 
369
  }
 
370
 
 
371
  check = pOp->interpret_exit_ok();
 
372
  if( check == -1 ) {
 
373
    ERR(pScanTrans->getNdbError());
 
374
    m_ndb.closeTransaction(pScanTrans);
 
375
    return NDBT_FAILED;
 
376
  }
 
377
 
 
378
  NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE");
 
379
  if( accountTypeRec ==NULL ) {
 
380
    ERR(pScanTrans->getNdbError());
 
381
    m_ndb.closeTransaction(pScanTrans);
 
382
    return NDBT_FAILED;
 
383
  }
 
384
 
 
385
  NdbRecAttr* balanceRec = pOp->getValue("BALANCE");
 
386
  if( balanceRec ==NULL ) {
 
387
    ERR(pScanTrans->getNdbError());
 
388
    m_ndb.closeTransaction(pScanTrans);
 
389
    return NDBT_FAILED;
 
390
  }
 
391
 
 
392
  check = pScanTrans->execute(NoCommit);
 
393
  if( check == -1 ) {
 
394
    ERR(pScanTrans->getNdbError());
 
395
    m_ndb.closeTransaction(pScanTrans);
 
396
    return NDBT_FAILED;
 
397
  }
 
398
    
 
399
  int eof;
 
400
  int rows = 0;
 
401
  eof = pOp->nextResult();
 
402
    
 
403
  while(eof == 0){
 
404
    rows++;
 
405
    Uint32 a = accountTypeRec->u_32_value();
 
406
    Uint32 b = balanceRec->u_32_value();
 
407
 
 
408
    if (a == accountType){
 
409
      // One record found
 
410
      balance += b;
 
411
    }
 
412
                
 
413
    eof = pOp->nextResult();
 
414
  }
 
415
  if (eof == -1) {
 
416
    ERR(pScanTrans->getNdbError());
 
417
    m_ndb.closeTransaction(pScanTrans);
 
418
    return NDBT_FAILED;
 
419
  }
 
420
    
 
421
  m_ndb.closeTransaction(pScanTrans);
 
422
  // ndbout << rows << " rows have been read" << endl;
 
423
 
 
424
  return NDBT_OK;
 
425
 
 
426
}
 
427
  
 
428
/**
 
429
 * Load ACCOUNT_TYPE table
 
430
 * 
 
431
 *
 
432
 */
 
433
int Bank::loadAccountType(){
 
434
  g_info << "loadAccountType" << endl;
 
435
  int check;
 
436
    
 
437
  NdbConnection* pTrans = m_ndb.startTransaction();
 
438
  if (pTrans == NULL){
 
439
    ERR(m_ndb.getNdbError());
 
440
    return NDBT_FAILED;
 
441
  }
 
442
    
 
443
  for (int i = 0; i < getNumAccountTypes(); i++){
 
444
      
 
445
    NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT_TYPE");
 
446
    if (pOp == NULL) {
 
447
      ERR(pTrans->getNdbError());
 
448
      m_ndb.closeTransaction(pTrans);
 
449
      return NDBT_FAILED;
 
450
    }
 
451
    
 
452
    check = pOp->insertTuple();
 
453
    if( check == -1 ) {
 
454
      ERR(pTrans->getNdbError());
 
455
      m_ndb.closeTransaction(pTrans);
 
456
      return NDBT_FAILED;
 
457
    }
 
458
      
 
459
    check = pOp->equal("ACCOUNT_TYPE_ID", accountTypes[i].id);
 
460
    if( check == -1 ) {
 
461
      ERR(pTrans->getNdbError());
 
462
      m_ndb.closeTransaction(pTrans);
 
463
      return NDBT_FAILED;
 
464
    }
 
465
 
 
466
    check = pOp->setValue("DESCRIPTION", accountTypes[i].descr);
 
467
    if( check == -1 ) {
 
468
      ERR(pTrans->getNdbError());
 
469
      m_ndb.closeTransaction(pTrans);
 
470
      return NDBT_FAILED;
 
471
    }
 
472
  }
 
473
  check = pTrans->execute(Commit);
 
474
  if( check == -1 ) {
 
475
    ERR(pTrans->getNdbError());
 
476
    m_ndb.closeTransaction(pTrans);
 
477
    return NDBT_FAILED;
 
478
  }
 
479
    
 
480
  m_ndb.closeTransaction(pTrans);      
 
481
  return NDBT_OK;
 
482
}
 
483
  
 
484
/**
 
485
 * Load ACCOUNT table
 
486
 * 
 
487
 *  
 
488
 *
 
489
 */
 
490
int Bank::loadAccount (int numAccounts){
 
491
  g_info << "loadAccount" << endl;
 
492
  int check;
 
493
    
 
494
  NdbConnection* pTrans = m_ndb.startTransaction();
 
495
  if (pTrans == NULL){
 
496
    ERR(m_ndb.getNdbError());
 
497
    return NDBT_FAILED;
 
498
  }
 
499
    
 
500
  for (int i = 0; i < numAccounts; i++){
 
501
      
 
502
    NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT");
 
503
    if (pOp == NULL) {
 
504
      ERR(pTrans->getNdbError());
 
505
      m_ndb.closeTransaction(pTrans);
 
506
      return NDBT_FAILED;
 
507
    }
 
508
    
 
509
    check = pOp->insertTuple();
 
510
    if( check == -1 ) {
 
511
      ERR(pTrans->getNdbError());
 
512
      m_ndb.closeTransaction(pTrans);
 
513
      return NDBT_FAILED;
 
514
    }
 
515
      
 
516
    check = pOp->equal("ACCOUNT_ID", i);
 
517
    if( check == -1 ) {
 
518
      ERR(pTrans->getNdbError());
 
519
      m_ndb.closeTransaction(pTrans);
 
520
      return NDBT_FAILED;
 
521
    }
 
522
 
 
523
    int owner;
 
524
    if (i == 0)
 
525
      owner = 0;
 
526
    else
 
527
      owner = i + 3000;
 
528
    check = pOp->setValue("OWNER", owner);
 
529
    if( check == -1 ) {
 
530
      ERR(pTrans->getNdbError());
 
531
      m_ndb.closeTransaction(pTrans);
 
532
      return NDBT_FAILED;
 
533
    }
 
534
 
 
535
    // Load balance so that the bank's account = 0 has 10 millions
 
536
    // and all other accounts have 10000
 
537
    // This set the total balance for the entire bank to 
 
538
    // 10000000 + (10000 * numAccounts-1)
 
539
    // Since no money should dissapear from to the bank nor
 
540
    // any money should be added this is a rule that can be checked when 
 
541
    // validating the db
 
542
    int balance;
 
543
    if (i == 0){
 
544
      balance = 10000000;
 
545
    } else {
 
546
      balance = 10000;
 
547
    }
 
548
    check = pOp->setValue("BALANCE", balance);
 
549
    if( check == -1 ) {
 
550
      ERR(pTrans->getNdbError());
 
551
      m_ndb.closeTransaction(pTrans);
 
552
      return NDBT_FAILED;
 
553
    }
 
554
 
 
555
    // TODO - This is how to set a value in a 16, 1 attribute, not so nice?
 
556
    // NOTE - its not even possible to set the value 0 in this column
 
557
    // since that is equal to NULL when casting to char*
 
558
    // check = pOp->setValue("ACCOUNT_TYPE", (const char*)(Uint16)(i/accountTypesSize), 2);
 
559
    // NOTE attribute now changed to be a 32 bit
 
560
 
 
561
      
 
562
    int accountType;
 
563
    if (i == 0)
 
564
      accountType = 0; // KASSA
 
565
    else
 
566
      accountType = ((i%accountTypesSize) == 0 ?  1 : (i%getNumAccountTypes()));
 
567
    check = pOp->setValue("ACCOUNT_TYPE", accountType);
 
568
    if( check == -1 ) {
 
569
      ERR(pTrans->getNdbError());
 
570
      m_ndb.closeTransaction(pTrans);
 
571
      return NDBT_FAILED;
 
572
    }
 
573
  }
 
574
  check = pTrans->execute(Commit);
 
575
  if( check == -1 ) {
 
576
    ERR(pTrans->getNdbError());
 
577
    m_ndb.closeTransaction(pTrans);
 
578
    return NDBT_FAILED;
 
579
  }
 
580
    
 
581
  m_ndb.closeTransaction(pTrans);      
 
582
  return NDBT_OK;
 
583
}
 
584
 
 
585
 
 
586
int Bank::getNumAccounts(){
 
587
  const NdbDictionary::Table* accountTab = 
 
588
    m_ndb.getDictionary()->getTable("ACCOUNT");
 
589
  if (accountTab == NULL){
 
590
    g_err << "Table ACCOUNT does not exist" << endl;
 
591
    return NDBT_FAILED;
 
592
  }
 
593
  UtilTransactions util(*accountTab);
 
594
  if(util.selectCount(&m_ndb, 64, &m_maxAccount) != 0)
 
595
    return NDBT_FAILED;    
 
596
  return NDBT_OK;
 
597
}
 
598
 
 
599
int Bank::getMaxAmount(){
 
600
  return 10000;
 
601
}