1
/* Copyright (C) 2003 MySQL AB
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.
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.
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 */
17
#include <UtilTransactions.hpp>
20
* Default account types
23
struct AccountTypesStruct {
27
const AccountTypesStruct accountTypes[] = {
36
accountTypesSize = sizeof(accountTypes)/sizeof(AccountTypesStruct);
39
const char* tableNames[] = {
48
tableNamesSize = sizeof(tableNames)/sizeof(const char*);
51
int Bank::getNumAccountTypes(){
52
return accountTypesSize;
55
int Bank::createAndLoadBank(bool ovrWrt, bool disk, int num_accounts){
58
if (m_ndb.waitUntilReady() != 0)
61
const NdbDictionary::Table* pSysValTab =
62
m_ndb.getDictionary()->getTable("SYSTEM_VALUES");
63
if (pSysValTab != NULL){
66
ndbout << "Bank already exist and overwrite == false" << endl;
71
if (!m_skip_create && createTables(disk) != NDBT_OK)
74
if (clearTables() != NDBT_OK)
77
if (loadAccountType() != NDBT_OK)
80
if (loadAccount(num_accounts) != NDBT_OK)
83
if (loadSystemValues() != NDBT_OK)
86
if (loadGl() != NDBT_OK)
96
if (m_ndb.waitUntilReady() != 0)
99
if (dropTables() != NDBT_OK)
106
int Bank::createTables(bool disk){
107
for (int i = 0; i < tableNamesSize; i++){
108
if (createTable(tableNames[i], disk) != NDBT_OK)
115
int Bank::dropTables(){
116
for (int i = 0; i < tableNamesSize; i++){
117
if (dropTable(tableNames[i]) != NDBT_OK)
123
int Bank::clearTables(){
124
for (int i = 0; i < tableNamesSize; i++){
125
if (clearTable(tableNames[i]) != NDBT_OK)
131
int Bank::clearTable(const char* tabName){
132
UtilTransactions util(&m_ndb, tabName);
133
if(util.clearTable(&m_ndb, 64) != 0)
138
int Bank::createTable(const char* tabName, bool disk){
139
ndbout << "createTable " << tabName << endl;
141
const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName);
145
const NdbDictionary::Table* org =
146
m_ndb.getDictionary()->getTable(tabName);
148
if (org != 0 && (disk || pTab->equal(* org)))
154
ndbout << "Different table with same name exists" << endl;
160
if (NDBT_Tables::create_default_tablespace(&m_ndb))
162
ndbout << "Failed to create tablespaces" << endl;
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;
177
if(m_ndb.getDictionary()->createTable(* pTab) == -1){
178
ndbout << "Failed to create table: " <<
179
m_ndb.getNdbError() << endl;
187
int Bank::dropTable(const char* tabName){
188
const NdbDictionary::Table* org =
189
m_ndb.getDictionary()->getTable(tabName);
194
ndbout << "dropTable " <<tabName<<endl;
195
if (m_ndb.getDictionary()->dropTable(tabName) != 0){
210
* Load SYSTEM_VALUES table
211
* This table keeps track of system wide settings
213
* - next transaction id
216
int Bank::loadSystemValues (){
220
* Insert start value for next transaction id
223
result = writeSystemValue(LastTransactionId, 0);
226
* Insert start value for current time
229
result = writeSystemValue(CurrentTime, 1);
239
* Insert GL records for time = 0 with balance 0
242
g_info << "loadGl" << endl;
245
NdbConnection* pTrans = m_ndb.startTransaction();
247
ERR(m_ndb.getNdbError());
251
for (int i = 0; i < getNumAccountTypes(); i++){
253
NdbOperation* pOp = pTrans->getNdbOperation("GL");
255
ERR(pTrans->getNdbError());
256
m_ndb.closeTransaction(pTrans);
260
check = pOp->insertTuple();
262
ERR(pTrans->getNdbError());
263
m_ndb.closeTransaction(pTrans);
268
check = pOp->equal("TIME", time);
270
ERR(pTrans->getNdbError());
271
m_ndb.closeTransaction(pTrans);
275
check = pOp->equal("ACCOUNT_TYPE", i);
277
ERR(pTrans->getNdbError());
278
m_ndb.closeTransaction(pTrans);
283
if (getBalanceForAccountType(i, balance) != NDBT_OK){
287
check = pOp->setValue("BALANCE", balance);
289
ERR(pTrans->getNdbError());
290
m_ndb.closeTransaction(pTrans);
294
Uint32 depositCount = 0;
295
check = pOp->setValue("DEPOSIT_COUNT", depositCount);
297
ERR(pTrans->getNdbError());
298
m_ndb.closeTransaction(pTrans);
302
Uint32 depositSum = 0;
303
check = pOp->setValue("DEPOSIT_SUM", depositSum);
305
ERR(pTrans->getNdbError());
306
m_ndb.closeTransaction(pTrans);
310
Uint32 withdrawalCount = 0;
311
check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount);
313
ERR(pTrans->getNdbError());
314
m_ndb.closeTransaction(pTrans);
318
Uint32 withdrawalSum = 0;
319
check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum);
321
ERR(pTrans->getNdbError());
322
m_ndb.closeTransaction(pTrans);
327
check = pOp->setValue("PURGED", purged);
329
ERR(pTrans->getNdbError());
330
m_ndb.closeTransaction(pTrans);
335
check = pTrans->execute(Commit);
337
ERR(pTrans->getNdbError());
338
m_ndb.closeTransaction(pTrans);
342
m_ndb.closeTransaction(pTrans);
347
int Bank::getBalanceForAccountType(const Uint32 accountType,
350
g_info << "getBalanceForAccountType: accountType="<<accountType<<endl;
352
NdbConnection* pScanTrans = m_ndb.startTransaction();
353
if (pScanTrans == NULL) {
354
ERR(m_ndb.getNdbError());
358
NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("ACCOUNT");
360
ERR(pScanTrans->getNdbError());
361
m_ndb.closeTransaction(pScanTrans);
365
if( pOp->readTuples() ) {
366
ERR(pScanTrans->getNdbError());
367
m_ndb.closeTransaction(pScanTrans);
371
check = pOp->interpret_exit_ok();
373
ERR(pScanTrans->getNdbError());
374
m_ndb.closeTransaction(pScanTrans);
378
NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE");
379
if( accountTypeRec ==NULL ) {
380
ERR(pScanTrans->getNdbError());
381
m_ndb.closeTransaction(pScanTrans);
385
NdbRecAttr* balanceRec = pOp->getValue("BALANCE");
386
if( balanceRec ==NULL ) {
387
ERR(pScanTrans->getNdbError());
388
m_ndb.closeTransaction(pScanTrans);
392
check = pScanTrans->execute(NoCommit);
394
ERR(pScanTrans->getNdbError());
395
m_ndb.closeTransaction(pScanTrans);
401
eof = pOp->nextResult();
405
Uint32 a = accountTypeRec->u_32_value();
406
Uint32 b = balanceRec->u_32_value();
408
if (a == accountType){
413
eof = pOp->nextResult();
416
ERR(pScanTrans->getNdbError());
417
m_ndb.closeTransaction(pScanTrans);
421
m_ndb.closeTransaction(pScanTrans);
422
// ndbout << rows << " rows have been read" << endl;
429
* Load ACCOUNT_TYPE table
433
int Bank::loadAccountType(){
434
g_info << "loadAccountType" << endl;
437
NdbConnection* pTrans = m_ndb.startTransaction();
439
ERR(m_ndb.getNdbError());
443
for (int i = 0; i < getNumAccountTypes(); i++){
445
NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT_TYPE");
447
ERR(pTrans->getNdbError());
448
m_ndb.closeTransaction(pTrans);
452
check = pOp->insertTuple();
454
ERR(pTrans->getNdbError());
455
m_ndb.closeTransaction(pTrans);
459
check = pOp->equal("ACCOUNT_TYPE_ID", accountTypes[i].id);
461
ERR(pTrans->getNdbError());
462
m_ndb.closeTransaction(pTrans);
466
check = pOp->setValue("DESCRIPTION", accountTypes[i].descr);
468
ERR(pTrans->getNdbError());
469
m_ndb.closeTransaction(pTrans);
473
check = pTrans->execute(Commit);
475
ERR(pTrans->getNdbError());
476
m_ndb.closeTransaction(pTrans);
480
m_ndb.closeTransaction(pTrans);
490
int Bank::loadAccount (int numAccounts){
491
g_info << "loadAccount" << endl;
494
NdbConnection* pTrans = m_ndb.startTransaction();
496
ERR(m_ndb.getNdbError());
500
for (int i = 0; i < numAccounts; i++){
502
NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT");
504
ERR(pTrans->getNdbError());
505
m_ndb.closeTransaction(pTrans);
509
check = pOp->insertTuple();
511
ERR(pTrans->getNdbError());
512
m_ndb.closeTransaction(pTrans);
516
check = pOp->equal("ACCOUNT_ID", i);
518
ERR(pTrans->getNdbError());
519
m_ndb.closeTransaction(pTrans);
528
check = pOp->setValue("OWNER", owner);
530
ERR(pTrans->getNdbError());
531
m_ndb.closeTransaction(pTrans);
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
548
check = pOp->setValue("BALANCE", balance);
550
ERR(pTrans->getNdbError());
551
m_ndb.closeTransaction(pTrans);
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
564
accountType = 0; // KASSA
566
accountType = ((i%accountTypesSize) == 0 ? 1 : (i%getNumAccountTypes()));
567
check = pOp->setValue("ACCOUNT_TYPE", accountType);
569
ERR(pTrans->getNdbError());
570
m_ndb.closeTransaction(pTrans);
574
check = pTrans->execute(Commit);
576
ERR(pTrans->getNdbError());
577
m_ndb.closeTransaction(pTrans);
581
m_ndb.closeTransaction(pTrans);
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;
593
UtilTransactions util(*accountTab);
594
if(util.selectCount(&m_ndb, 64, &m_maxAccount) != 0)
599
int Bank::getMaxAmount(){