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