BankLoad.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:13k
源码类别:

MySQL数据库

开发平台:

Visual C++

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