📄 bank.cpp
字号:
while(eof == 0){ rows++; Uint64 t = timeRec->u_64_value(); if (t == glTime){ countGlRecords++; Uint32 a = accountTypeRec->u_32_value(); Uint32 purged = purgedRec->u_32_value(); Uint32 wsum = withdrawalSumRec->u_32_value(); Uint32 wcount = withdrawalCountRec->u_32_value(); Uint32 dsum = depositSumRec->u_32_value(); Uint32 dcount = depositCountRec->u_32_value(); Uint32 b = balanceRec->u_32_value(); Uint32 balance = 0; Uint32 withdrawalSum = 0; Uint32 withdrawalCount = 0; Uint32 depositSum = 0; Uint32 depositCount = 0; Uint32 countTransactions = 0; if (purged == 0){ // If purged == 0, then the TRANSACTION table should be checked // to see that there are: // + DEPOSIT_COUNT deposit transactions with account_type == ACCOUNT_TYPE // and TIME == glTime. The sum of these transactions should be // DEPOSIT_SUM // + WITHDRAWAL_COUNT withdrawal transactions with account_type == // ACCOUNT_TYPE and TIME == glTime. The sum of these transactions // should be WITHDRAWAL_SUM // + BALANCE should be equal to the sum of all transactions plus // the balance of the previous GL record if (sumTransactionsForGL(t, a, balance, withdrawalCount, withdrawalSum, depositSum, depositCount, countTransactions, pScanTrans) != NDBT_OK){ result = NDBT_FAILED; } else { Uint32 prevBalance = 0; if (getBalanceForGL(t-1, a, prevBalance) != NDBT_OK){ result = NDBT_FAILED; } else if (((prevBalance + balance) != b) || (wsum != withdrawalSum) || (wcount != withdrawalCount) || (dsum != depositSum) || (dcount != depositCount)){ g_err << "performValidateGL, sums and counts failed" << endl << "balance : " << balance+prevBalance << "!="<<b<<endl << "with sum : " << withdrawalSum << "!="<<wsum<<endl << "with count: " << withdrawalCount << "!="<<wcount<<endl << "dep sum : " << depositSum << "!="<<dsum<<endl << "dep count : " << depositCount << "!="<<dcount<<endl; result = VERIFICATION_FAILED; } } } else { assert(purged == 1); // If purged == 1 then there should be NO transactions with // TIME == glTime and ACCOUNT_TYPE == account_type if (sumTransactionsForGL(t, a, balance, withdrawalCount, withdrawalSum, depositSum, depositCount, countTransactions, pScanTrans) != NDBT_OK){ result = NDBT_FAILED; } else { if (countTransactions != 0){ g_err << "performValidateGL, countTransactions("<<countTransactions<<") != 0" << endl; result = VERIFICATION_FAILED; } } } } eof = pOp->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } m_ndb.closeTransaction(pScanTrans); // - There should be zero or NoAccountTypes GL records for each glTime if ((countGlRecords != 0) && (countGlRecords != getNumAccountTypes())){ g_err << "performValidateGL: " << endl << "countGlRecords = " << countGlRecords << endl; result = VERIFICATION_FAILED; } return result; }int Bank::getBalanceForGL(const Uint64 glTime, const Uint32 accountTypeId, Uint32 &balance){ int check; NdbConnection* pTrans = m_ndb.startTransaction(); if (pTrans == NULL) { ERR(m_ndb.getNdbError()); return NDBT_FAILED; } NdbOperation* pOp = pTrans->getNdbOperation("GL"); if (pOp == NULL) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->readTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->equal("TIME", glTime); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->equal("ACCOUNT_TYPE", accountTypeId); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); if( balanceRec == NULL ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pTrans->execute(Commit); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } m_ndb.closeTransaction(pTrans); balance = balanceRec->u_32_value(); return NDBT_OK;}int Bank::getOldestPurgedGL(const Uint32 accountType, Uint64 &oldest){ int check; /** * SELECT MAX(time) FROM GL WHERE account_type = @accountType and purged=1 */ NdbConnection* pScanTrans = m_ndb.startTransaction(); if (pScanTrans == NULL) { ERR(m_ndb.getNdbError()); return NDBT_FAILED; } NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } if( pOp->readTuples() ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); if( accountTypeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* timeRec = pOp->getValue("TIME"); if( timeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* purgedRec = pOp->getValue("PURGED"); if( purgedRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } int eof; int rows = 0; eof = pOp->nextResult(); oldest = 0; while(eof == 0){ rows++; Uint32 a = accountTypeRec->u_32_value(); Uint32 p = purgedRec->u_32_value(); if (a == accountType && p == 1){ // One record found Uint64 t = timeRec->u_64_value(); if (t > oldest) oldest = t; } eof = pOp->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } m_ndb.closeTransaction(pScanTrans); return NDBT_OK;}int Bank::getOldestNotPurgedGL(Uint64 &oldest, Uint32 &accountTypeId, bool &found){ int check; /** * SELECT time, accountTypeId FROM GL * WHERE purged=0 order by time asc */ NdbConnection* pScanTrans = m_ndb.startTransaction(); if (pScanTrans == NULL) { ERR(m_ndb.getNdbError()); return NDBT_FAILED; } NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } if( pOp->readTuples() ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); if( accountTypeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* timeRec = pOp->getValue("TIME"); if( timeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* purgedRec = pOp->getValue("PURGED"); if( purgedRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } int eof; int rows = 0; eof = pOp->nextResult(); oldest = (Uint64)-1; found = false; while(eof == 0){ rows++; Uint32 p = purgedRec->u_32_value(); if (p == 0){ found = true; // One record found Uint32 a = accountTypeRec->u_32_value(); Uint64 t = timeRec->u_64_value(); if (t < oldest){ oldest = t; accountTypeId = a; } } eof = pOp->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } m_ndb.closeTransaction(pScanTrans); return NDBT_OK;}int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, const Uint64 oldest){ /** * SELECT COUNT(transaction_id) FROM TRANSACTION * WHERE account_type = @accountType and time <= @oldest * */ int check; NdbConnection* pScanTrans = m_ndb.startTransaction(); if (pScanTrans == NULL) { ERR(m_ndb.getNdbError()); return NDBT_FAILED; } NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("TRANSACTION"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } if( pOp->readTuples() ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); if( accountTypeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* timeRec = pOp->getValue("TIME"); if( timeRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } NdbRecAttr* transactionIdRec = pOp->getValue("TRANSACTION_ID"); if( transactionIdRec ==NULL ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } int eof; int rows = 0; int found = 0; eof = pOp->nextResult(); while(eof == 0){ rows++; Uint32 a = accountTypeRec->u_32_value(); Uint32 t = timeRec->u_32_value(); if (a == accountType && t <= oldest){ // One record found Uint64 ti = transactionIdRec->u_64_value(); g_err << "checkNoTransactionsOlderThan found one record" << endl << " t = " << t << endl << " a = " << a << endl << " ti = " << ti << endl; found++; } eof = pOp->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } m_ndb.closeTransaction(pScanTrans); if (found == 0) return NDBT_OK; else return VERIFICATION_FAILED;} int Bank::performValidatePurged(){ /** * Make sure there are no TRANSACTIONS older than the oldest * purged GL record * */ for (int i = 0; i < getNumAccountTypes(); i++){ ndbout << "performValidatePurged: " << i << endl; Uint64 oldestGlTime; if (getOldestPurgedGL(i, oldestGlTime) != NDBT_OK){ g_err << "getOldestPurgedGL failed" << endl; return NDBT_FAILED; } int result = checkNoTransactionsOlderThan(i, oldestGlTime); if (result != NDBT_OK){ g_err << "checkNoTransactionsOlderThan failed" << endl; return result; } } return NDBT_OK; } int Bank::purgeOldGLTransactions(Uint64 currTime, Uint32 age){ /** * For each GL record that are older than age and have purged == 0 * - delete all TRANSACTIONS belonging to the GL and set purged = 1 * * */ bool found; int count = 0; while(1){ count++; if (count > 100) return NDBT_OK; // Search for the oldest GL record with purged == 0 Uint64 oldestGlTime; Uint32 accountTypeId; if (getOldestNotPurgedGL(oldestGlTime, accountTypeId, found) != NDBT_OK){ g_err << "getOldestNotPurgedGL failed" << endl; return NDBT_FAILED; } if (found == false){ // ndbout << "not found" << endl; return NDBT_OK; } // ndbout << "purgeOldGLTransactions" << endl// << " oldestGlTime = " << oldestGlTime << endl// << " currTime = " << currTime << endl// << " age = " << age << endl; // Check if this GL is old enough to be purged if ((currTime < age) || (oldestGlTime > (currTime-age))){ // ndbout << "is not old enough" << endl; return NDBT_OK; } if (purgeTransactions(oldestGlTime, accountTypeId) != NDBT_OK){ g_err << "purgeTransactions failed" << endl; return NDBT_FAILED; } } g_err << "abnormal return" << endl; return NDBT_FAILED; } int Bank::purgeTransactions(const Uint64 glTime, const Uint32 accountTypeId){ int check; g_info << "purgeTransactions: " << glTime << ", "<<accountTypeId<<endl; NdbConnection* pTrans = m_ndb.startTransaction(); if (pTrans == NULL){ ERR(m_ndb.getNdbError()); return NDBT_FAILED; } // Start by updating the GL record with purged = 1, use NoCommit NdbOperation* pOp = pTrans->getNdbOperation("GL"); if (pOp == NULL) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->updateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->equal("TIME", glTime); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->equal("ACCOUNT_TYPE", accountTypeId); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } Uint32 purged = 1; check = pOp->setValue("PURGED", purged); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } // Execute transaction check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } // Find all transactions and take over them for delete if(findTransactionsToPurge(glTime, accountTypeId, pTrans) != NDBT_OK){ g_err << "findTransactionToPurge failed" << endl; m_ndb.closeTransaction(pTrans); return NDBT_FAILED; } check = pTrans->execute(Commit); if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } m_ndb.closeTransaction(pTrans); return NDBT_OK;}int Bank::findTransactionsToPurge(const Uint64 glTime, const Uint32 accountType, NdbConnection* pTrans){ int check; NdbConnection* pScanTrans = m_ndb.startTransaction(); if (pScanTrans == NULL) { ERR(m_ndb.getNdbError()); return NDBT_FAILED; } NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("TRANSACTION"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } if( pOp->readTuplesExclusive() ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -