[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kmymoney] kmymoney/mymoney/storage: Corrected calculation of the next MyMoneyObject ids in SQL back
From:       Christian_Dávid <christian-david () web ! de>
Date:       2015-01-31 21:15:51
Message-ID: E1YHfOR-0000jm-Q8 () scm ! kde ! org
[Download RAW message or body]

Git commit b36a26f9a2c2e683537e3e678a54caadc61a7171 by Christian Dávid.
Committed on 31/01/2015 at 20:43.
Pushed by christiand into branch 'master'.

Corrected calculation of the next MyMoneyObject ids in SQL backend

The next MyMoneyObjects' ids were stored in the table kmmFileInfo. But
this data got corrupted in the past several times.

Now the highest id is calculated - so corruptions should not be possible
anymore.

The calculation process is lazy and is only executed when needed as it
is quite expensive (uses regex on some RDBMSs). Unfortunatly the SQL
backend triggers the calculation all the time at the moment - way more
often than needed. Some writeFileInfo() and readFileInfo() calls must
be removed to fix that (future work).

Any calls to writeFileInfo() and readFileInfo() are removed - these
methods cannot be called before the upgrade process is finished!

Also the higest id numbers are not set during the upgrade process.

BUG: 339103
FIXED-IN: 4.8

M  +20   -20   kmymoney/mymoney/storage/mymoneydatabasemgr.cpp
M  +108  -234  kmymoney/mymoney/storage/mymoneystoragesql.cpp
M  +10   -6    kmymoney/mymoney/storage/mymoneystoragesql.h

http://commits.kde.org/kmymoney/b36a26f9a2c2e683537e3e678a54caadc61a7171

diff --git a/kmymoney/mymoney/storage/mymoneydatabasemgr.cpp \
b/kmymoney/mymoney/storage/mymoneydatabasemgr.cpp index e8d0259..391b138 100644
--- a/kmymoney/mymoney/storage/mymoneydatabasemgr.cpp
+++ b/kmymoney/mymoney/storage/mymoneydatabasemgr.cpp
@@ -2105,59 +2105,59 @@ void MyMoneyDatabaseMgr::loadOnlineJobs(const QMap< QString, \
onlineJob >& online  Q_UNUSED(onlineJobs);
 }
 
-unsigned long MyMoneyDatabaseMgr::accountId(void) const
+unsigned long MyMoneyDatabaseMgr::accountId() const
 {
-  return m_sql->getNextAccountId();
+  return m_sql->getNextAccountId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::transactionId(void) const
+unsigned long MyMoneyDatabaseMgr::transactionId() const
 {
-  return m_sql->getNextTransactionId();
+  return m_sql->getNextTransactionId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::payeeId(void) const
+unsigned long MyMoneyDatabaseMgr::payeeId() const
 {
-  return m_sql->getNextPayeeId();
+  return m_sql->getNextPayeeId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::tagId(void) const
+unsigned long MyMoneyDatabaseMgr::tagId() const
 {
-  return m_sql->getNextTagId();
+  return m_sql->getNextTagId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::institutionId(void) const
+unsigned long MyMoneyDatabaseMgr::institutionId() const
 {
-  return m_sql->getNextInstitutionId();
+  return m_sql->getNextInstitutionId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::scheduleId(void) const
+unsigned long MyMoneyDatabaseMgr::scheduleId() const
 {
-  return m_sql->getNextScheduleId();
+  return m_sql->getNextScheduleId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::securityId(void) const
+unsigned long MyMoneyDatabaseMgr::securityId() const
 {
-  return m_sql->getNextSecurityId();
+  return m_sql->getNextSecurityId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::reportId(void) const
+unsigned long MyMoneyDatabaseMgr::reportId() const
 {
-  return m_sql->getNextReportId();
+  return m_sql->getNextReportId()-1;
 }
 
-unsigned long MyMoneyDatabaseMgr::budgetId(void) const
+unsigned long MyMoneyDatabaseMgr::budgetId() const
 {
-  return m_sql->getNextBudgetId();
+  return m_sql->getNextBudgetId()-1;
 }
 
 long unsigned int MyMoneyDatabaseMgr::onlineJobId() const
 {
-  return m_sql->getNextOnlineJobId();
+  return m_sql->getNextOnlineJobId()-1;
 }
 
 long unsigned int MyMoneyDatabaseMgr::payeeIdentifierId() const
 {
-  return m_sql->getNextPayeeIdentifierId();
+  return m_sql->getNextPayeeIdentifierId()-1;
 }
 
 void MyMoneyDatabaseMgr::loadAccountId(const unsigned long id)
diff --git a/kmymoney/mymoney/storage/mymoneystoragesql.cpp \
b/kmymoney/mymoney/storage/mymoneystoragesql.cpp index 572386b..8e59051 100644
--- a/kmymoney/mymoney/storage/mymoneystoragesql.cpp
+++ b/kmymoney/mymoney/storage/mymoneystoragesql.cpp
@@ -106,7 +106,18 @@ MyMoneyDbTransaction::~MyMoneyDbTransaction()
 
 //************************ Constructor/Destructor *****************************
 MyMoneyStorageSql::MyMoneyStorageSql(IMyMoneySerialize *storage, const KUrl& url)
-    : QSqlDatabase(url.queryItem("driver"))
+    : QSqlDatabase(url.queryItem("driver")),
+    m_hiIdInstitutions(0),
+    m_hiIdPayees(0),
+    m_hiIdTags(0),
+    m_hiIdAccounts(0),
+    m_hiIdTransactions(0),
+    m_hiIdSchedules(0),
+    m_hiIdSecurities(0),
+    m_hiIdReports(0),
+    m_hiIdBudgets(0),
+    m_hiIdOnlineJobs(0),
+    m_hiIdPayeeIdentifier(0)
 {
   DBG("*** Entering MyMoneyStorageSql::MyMoneyStorageSql");
   m_storage = storage;
@@ -120,8 +131,6 @@ MyMoneyStorageSql::MyMoneyStorageSql(IMyMoneySerialize *storage, \
const KUrl& url  m_loadAll = false;
   m_override = false;
   m_preferred.setReportAllSplits(false);
-
-  m_hiIdOnlineJobs = 0;
 }
 
 int MyMoneyStorageSql::open(const KUrl& url, int openMode, bool clear)
@@ -510,21 +519,6 @@ int MyMoneyStorageSql::upgradeToV1()
     }
   }
   m_transactionCountMap.clear();
-  // there were considerable problems with record counts in V0, so rebuild them
-  readFileInfo();
-  m_institutions = getRecCount("kmmInstitutions");
-  m_accounts = getRecCount("kmmAccounts");
-  m_payees = getRecCount("kmmPayees");
-  m_transactions = getRecCount("kmmTransactions WHERE txType = 'N'");
-  m_splits = getRecCount("kmmSplits");
-  m_securities = getRecCount("kmmSecurities");
-  m_prices = getRecCount("kmmPrices");
-  m_currencies = getRecCount("kmmCurrencies");
-  m_schedules = getRecCount("kmmSchedules");
-  m_reports = getRecCount("kmmReportConfig");
-  m_kvps = getRecCount("kmmKeyValuePairs");
-  m_budgets = getRecCount("kmmBudgetConfig");
-  writeFileInfo();
   return (0);
 }
 
@@ -609,9 +603,7 @@ int MyMoneyStorageSql::upgradeToV6()
       }
     }
   }
-  // kmmReportConfig - add a unique id as primary key
-  // read and write reports to get ids inserted
-  readFileInfo();
+
   // the alterTable function really doesn't work too well
   // with adding a new column which is also to be primary key
   // so add the column first
@@ -632,15 +624,14 @@ int MyMoneyStorageSql::upgradeToV6()
   // add unique id to reports table
   if (!alterTable(m_db.m_tables["kmmReportConfig"], m_dbVersion))
     return(1);
-  unsigned long long hiReportId = 0;
+
   QMap<QString, MyMoneyReport>::const_iterator it_r;
   for (it_r = reportList.constBegin(); it_r != reportList.constEnd(); ++it_r) {
     MyMoneyReport r = *it_r;
-    hiReportId = calcHighId(hiReportId, r.id());
     q.prepare(m_db.m_tables["kmmReportConfig"].insertString());
     writeReport(*it_r, q);
   }
-  m_hiIdReports = hiReportId;
+
   m_storage->loadReportId(m_hiIdReports);
   endCommitUnit(Q_FUNC_INFO);
   return 0;
@@ -670,9 +661,6 @@ int MyMoneyStorageSql::upgradeToV8()
   if (!alterTable(m_db.m_tables["kmmFileInfo"], m_dbVersion))
     return (1);
 
-  m_hiIdOnlineJobs = getRecCount("kmmOnlineJobs");
-  m_hiIdPayeeIdentifier = getRecCount("kmmPayeeIdentifier");
-
   return 0;
 }
 
@@ -867,6 +855,7 @@ bool MyMoneyStorageSql::writeFile(void)
                                 = m_securities = m_prices = m_currencies = \
m_schedules  = m_reports = m_kvps = m_budgets = 0;  m_hiIdInstitutions = m_hiIdPayees \
                = m_hiIdTags = m_hiIdAccounts = m_hiIdTransactions =
                                         m_hiIdSchedules = m_hiIdSecurities = \
m_hiIdReports = m_hiIdBudgets = 0; +  m_onlineJobs = m_payeeIdentifier = 0;
   m_displayStatus = true;
   try {
     MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
@@ -1071,8 +1060,6 @@ void MyMoneyStorageSql::writeInstitutionList(const \
QList<MyMoneyInstitution>& iL  QVariantList telephoneList;
   QList<QMap<QString, QString> > kvpPairsList;
 
-  unsigned long hiId = m_hiIdInstitutions;
-
   foreach (const MyMoneyInstitution& i, iList) {
     idList << i.id();
     nameList << i.name();
@@ -1083,7 +1070,6 @@ void MyMoneyStorageSql::writeInstitutionList(const \
QList<MyMoneyInstitution>& iL  addressZipcodeList << i.postcode();
     telephoneList << i.telephone();
     kvpPairsList << i.pairs();
-    hiId = calcHighId(hiId, i.id());
   }
 
   q.bindValue(":id", idList);
@@ -1095,9 +1081,11 @@ void MyMoneyStorageSql::writeInstitutionList(const \
QList<MyMoneyInstitution>& iL  q.bindValue(":addressZipcode", addressZipcodeList);
   q.bindValue(":telephone", telephoneList);
 
-  if (!q.execBatch()) throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, \
QString("writing Institution"))); +  if (!q.execBatch())
+    throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, QString("writing \
Institution")));  writeKeyValuePairs("OFXSETTINGS", idList, kvpPairsList);
-  m_hiIdInstitutions = std::max(m_hiIdInstitutions, hiId);
+  // Set m_hiIdInstitutions to 0 to force recalculation the next time it is \
requested +  m_hiIdInstitutions = 0;
 }
 
 // **** Payees ****
@@ -1330,11 +1318,18 @@ void MyMoneyStorageSql::writePayee(const MyMoneyPayee& p, \
QSqlQuery& q, bool isU  QString matchKeys;
   MyMoneyPayee::payeeMatchType type = p.matchData(ignoreCase, matchKeys);
   q.bindValue(":matchData", static_cast<unsigned int>(type));
-  if (ignoreCase) q.bindValue(":matchIgnoreCase", "Y");
-  else q.bindValue(":matchIgnoreCase", "N");
+
+  if (ignoreCase)
+    q.bindValue(":matchIgnoreCase", "Y");
+  else
+    q.bindValue(":matchIgnoreCase", "N");
+
   q.bindValue(":matchKeys", matchKeys);
-  if (!q.exec()) throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, QString("writing \
                Payee"))); // krazy:exclude=crashy
-  if (!isUserInfo) m_hiIdPayees = calcHighId(m_hiIdPayees, p.id());
+  if (!q.exec())
+    throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, QString("writing Payee"))); // \
krazy:exclude=crashy +
+  if (!isUserInfo)
+    m_hiIdPayees = 0;
 }
 
 // **** Tags ****
@@ -1419,7 +1414,7 @@ void MyMoneyStorageSql::writeTag(const MyMoneyTag& ta, \
QSqlQuery& q)  else q.bindValue(":closed", "N");
   q.bindValue(":notes", ta.notes());
   if (!q.exec()) throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, QString("writing \
                Tag"))); // krazy:exclude=crashy
-  m_hiIdTags = calcHighId(m_hiIdTags, ta.id());
+  m_hiIdTags = 0;
 }
 
 // **** Accounts ****
@@ -1607,8 +1602,6 @@ void MyMoneyStorageSql::writeAccountList(const \
QList<MyMoneyAccount>& accList, Q  QList<QMap<QString, QString> > pairs;
   QList<QMap<QString, QString> > onlineBankingPairs;
 
-  unsigned long hiId = m_hiIdAccounts;
-
   foreach (const MyMoneyAccount& a, accList) {
     idList << a.id();
     institutionIdList << a.institutionId();
@@ -1648,8 +1641,6 @@ void MyMoneyStorageSql::writeAccountList(const \
QList<MyMoneyAccount>& accList, Q  }
     transactionCountList << quint64(m_transactionCountMap[a.id()]);
 
-    hiId = calcHighId(hiId, a.id());
-
     //MMAccount inherits from KVPContainer AND has a KVPContainer member
     //so handle both
     pairs << a.pairs();
@@ -1673,12 +1664,13 @@ void MyMoneyStorageSql::writeAccountList(const \
QList<MyMoneyAccount>& accList, Q  q.bindValue(":balanceFormatted", \
balanceFormattedList);  q.bindValue(":transactionCount", transactionCountList);
 
-  if (!q.execBatch()) throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, \
QString("writing Account"))); +  if (!q.execBatch())
+    throw MYMONEYEXCEPTION(buildError(q, Q_FUNC_INFO, QString("writing Account")));
 
   //Add in Key-Value Pairs for accounts.
   writeKeyValuePairs("ACCOUNT", idList, pairs);
   writeKeyValuePairs("ONLINEBANKING", idList, onlineBankingPairs);
-  m_hiIdAccounts = std::max(m_hiIdAccounts, hiId);
+  m_hiIdAccounts = 0;
 }
 
 // **** Transactions and Splits ****
@@ -1834,7 +1826,7 @@ void MyMoneyStorageSql::writeTransaction(const QString& txId, \
const MyMoneyTrans  QList<QMap<QString, QString> > pairs;
   pairs << tx.pairs();
   writeKeyValuePairs("TRANSACTION", idList, pairs);
-  m_hiIdTransactions = calcHighId(m_hiIdTransactions, tx.id());
+  m_hiIdTransactions = 0;
 }
 
 void MyMoneyStorageSql::writeSplits(const QString& txId, const QString& type, const \
QList<MyMoneySplit>& splitList) @@ -2179,7 +2171,6 @@ void \
MyMoneyStorageSql::writeSchedule(const MyMoneySchedule& sch, QSqlQuery& q,  //Add in \
Key-Value Pairs for transactions.  //deleteKeyValuePairs("SCHEDULE", sch.id());
   //writeKeyValuePairs("SCHEDULE", sch.id(), sch.pairs());
-  m_hiIdSchedules = calcHighId(m_hiIdSchedules, sch.id());
 }
 
 // **** Securities ****
@@ -2286,7 +2277,7 @@ void MyMoneyStorageSql::writeSecurity(const MyMoneySecurity& \
security, QSqlQuery  QList<QMap<QString, QString> > pairs;
   pairs << security.pairs();
   writeKeyValuePairs("SECURITY", idList, pairs);
-  m_hiIdSecurities = calcHighId(m_hiIdSecurities, security.id());
+  m_hiIdSecurities = 0;
 }
 
 // **** Prices ****
@@ -2955,17 +2946,19 @@ void MyMoneyStorageSql::writeFileInfo()
   //startCommitUnit(Q_FUNC_INFO);
   //}
 
-  q.bindValue(":hiInstitutionId", (unsigned long long) m_hiIdInstitutions);
-  q.bindValue(":hiPayeeId", (unsigned long long) m_hiIdPayees);
-  q.bindValue(":hiTagId", (unsigned long long) m_hiIdTags);
-  q.bindValue(":hiAccountId", (unsigned long long) m_hiIdAccounts);
-  q.bindValue(":hiTransactionId", (unsigned long long) m_hiIdTransactions);
-  q.bindValue(":hiScheduleId", (unsigned long long) m_hiIdSchedules);
-  q.bindValue(":hiSecurityId", (unsigned long long) m_hiIdSecurities);
-  q.bindValue(":hiReportId", (unsigned long long) m_hiIdReports);
-  q.bindValue(":hiBudgetId", (unsigned long long) m_hiIdBudgets);
-  q.bindValue(":hiOnlineJobId",  (unsigned long long) m_hiIdOnlineJobs);
-  q.bindValue(":hiPayeeIdentifierId",  (unsigned long long) m_hiIdPayeeIdentifier);
+  //! @todo The following bindings are for backwards compatibility only
+  //! remove backwards compatibility in a later version
+  q.bindValue(":hiInstitutionId", QVariant::fromValue(getNextInstitutionId()));
+  q.bindValue(":hiPayeeId", QVariant::fromValue(getNextPayeeId()));
+  q.bindValue(":hiTagId", QVariant::fromValue(getNextTagId()));
+  q.bindValue(":hiAccountId", QVariant::fromValue(getNextAccountId()));
+  q.bindValue(":hiTransactionId", QVariant::fromValue(getNextTransactionId()));
+  q.bindValue(":hiScheduleId", QVariant::fromValue(getNextScheduleId()));
+  q.bindValue(":hiSecurityId", QVariant::fromValue(getNextSecurityId()));
+  q.bindValue(":hiReportId", QVariant::fromValue(getNextReportId()));
+  q.bindValue(":hiBudgetId", QVariant::fromValue(getNextBudgetId()));
+  q.bindValue(":hiOnlineJobId", QVariant::fromValue(getNextOnlineJobId()));
+  q.bindValue(":hiPayeeIdentifierId", \
QVariant::fromValue(getNextPayeeIdentifierId()));  
   q.bindValue(":encryptData", m_encryptData);
   q.bindValue(":updateInProgress", "N");
@@ -3066,8 +3059,7 @@ void MyMoneyStorageSql::readFileInfo(void)
 
   q.prepare(
     "SELECT "
-    "  created, lastModified, hiInstitutionId, hiPayeeId, hiTagId, hiAccountId, \
                hiTransactionId,"
-    "  hiScheduleId, hiSecurityId, hiReportId, hiBudgetId, hiOnlineJobId, \
hiPayeeIdentifierId, " +    "  created, lastModified, "
     "  encryptData, logonUser, logonAt, "
     "  (SELECT count(*) FROM kmmInstitutions) AS institutions, "
     "  (SELECT count(*) from kmmAccounts) AS accounts, "
@@ -3097,18 +3089,6 @@ void MyMoneyStorageSql::readFileInfo(void)
   m_storage->setCreationDate(GETDATE(rec.indexOf("created")));
   m_storage->setLastModificationDate(GETDATE(rec.indexOf("lastModified")));
 
-  m_hiIdInstitutions = (unsigned long) GETULL(rec.indexOf("hiInstitutionId"));
-  m_hiIdPayees = (unsigned long) GETULL(rec.indexOf("hiPayeeId"));
-  m_hiIdTags = (unsigned long) GETULL(rec.indexOf("hiTagId"));
-  m_hiIdAccounts = (unsigned long) GETULL(rec.indexOf("hiAccountId"));
-  m_hiIdTransactions = (unsigned long) GETULL(rec.indexOf("hiTransactionId"));
-  m_hiIdSchedules = (unsigned long) GETULL(rec.indexOf("hiScheduleId"));
-  m_hiIdSecurities = (unsigned long) GETULL(rec.indexOf("hiSecurityId"));
-  m_hiIdReports = (unsigned long) GETULL(rec.indexOf("hiReportId"));
-  m_hiIdBudgets = (unsigned long) GETULL(rec.indexOf("hiBudgetId"));
-  m_hiIdOnlineJobs = (unsigned long) GETULL(rec.indexOf("hiOnlineJobId"));
-  m_hiIdPayeeIdentifier = (unsigned long) \
                GETULL(rec.indexOf("hiPayeeIdentifierId"));
-
   m_institutions = (unsigned long) GETULL(rec.indexOf("institutions"));
   m_accounts = (unsigned long) GETULL(rec.indexOf("accounts"));
   m_payees = (unsigned long) GETULL(rec.indexOf("payees"));
@@ -3243,8 +3223,7 @@ void MyMoneyStorageSql::readPayees(const QList<QString>& pid)
   DBG("*** Entering MyMoneyStorageSql::readPayees(list)");
   try {
     m_storage->loadPayees(fetchPayees(pid));
-    readFileInfo();
-    m_storage->loadPayeeId(m_hiIdPayees);
+    m_storage->loadPayeeId(getNextPayeeId());
   } catch (const MyMoneyException &) {
   }
 //  if (pid.isEmpty()) m_payeeListRead = true;
@@ -3737,7 +3716,7 @@ void MyMoneyStorageSql::readTransactions(const QString& \
tidList, const QString&  {
   try {
     m_storage->loadTransactions(fetchTransactions(tidList, dateClause));
-    m_storage->loadTransactionId(m_hiIdTransactions);
+    m_storage->loadTransactionId(getNextTransactionId());
   } catch (const MyMoneyException &) {
     throw;
   }
@@ -3747,7 +3726,7 @@ void MyMoneyStorageSql::readTransactions(const \
MyMoneyTransactionFilter& filter)  {
   try {
     m_storage->loadTransactions(fetchTransactions(filter));
-    m_storage->loadTransactionId(m_hiIdTransactions);
+    m_storage->loadTransactionId(getNextTransactionId());
   } catch (const MyMoneyException &) {
     throw;
   }
@@ -4151,8 +4130,7 @@ void MyMoneyStorageSql::readSchedules(void)
 
   try {
     m_storage->loadSchedules(fetchSchedules());
-    readFileInfo();
-    m_storage->loadScheduleId(m_hiIdSchedules);
+    m_storage->loadScheduleId(getNextScheduleId());
   } catch (const MyMoneyException &) {
     throw;
   }
@@ -4304,8 +4282,7 @@ void MyMoneyStorageSql::readSecurities(void)
 {
   try {
     m_storage->loadSecurities(fetchSecurities());
-    readFileInfo();
-    m_storage->loadSecurityId(m_hiIdSecurities);
+    m_storage->loadSecurityId(getNextSecurityId());
   } catch (const MyMoneyException &) {
     throw;
   }
@@ -4578,8 +4555,7 @@ void MyMoneyStorageSql::readReports(void)
 {
   try {
     m_storage->loadReports(fetchReports());
-    readFileInfo();
-    m_storage->loadReportId(m_hiIdReports);
+    m_storage->loadReportId(getNextReportId());
   } catch (const MyMoneyException &) {
     throw;
   }
@@ -4711,245 +4687,143 @@ const QHash<QString, MyMoneyKeyValueContainer> \
MyMoneyStorageSql::readKeyValuePa  return (retval);
 }
 
+template<long unsigned MyMoneyStorageSql::* cache>
+long unsigned int MyMoneyStorageSql::getNextId(const QString& table, const QString& \
id, const int prefixLength) const +{
+  Q_CHECK_PTR(cache);
+  if (this->*cache == 0) {
+    MyMoneyStorageSql* nonConstThis = const_cast<MyMoneyStorageSql*>(this);
+    nonConstThis->*cache = 1 + nonConstThis->highestNumberFromIdString(table, id, \
prefixLength); +  }
+  Q_ASSERT(this->*cache > 0); // everything else is never a valid id
+  return this->*cache;
+}
+
 long unsigned MyMoneyStorageSql::getNextBudgetId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdBudgets;
+  return getNextId<&MyMoneyStorageSql::m_hiIdBudgets>(QLatin1String("kmmBudgetConfig"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextAccountId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdAccounts;
+  return getNextId<&MyMoneyStorageSql::m_hiIdAccounts>(QLatin1String("kmmAccounts"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextInstitutionId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdInstitutions;
+  return getNextId<&MyMoneyStorageSql::m_hiIdInstitutions>(QLatin1String("kmmInstitutions"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextPayeeId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdPayees;
+  return getNextId<&MyMoneyStorageSql::m_hiIdPayees>(QLatin1String("kmmPayees"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextTagId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdTags;
+  return getNextId<&MyMoneyStorageSql::m_hiIdTags>(QLatin1String("kmmTags"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextReportId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdReports;
+  return getNextId<&MyMoneyStorageSql::m_hiIdReports>(QLatin1String("kmmReportConfig"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextScheduleId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdSchedules;
+  return getNextId<&MyMoneyStorageSql::m_hiIdSchedules>(QLatin1String("kmmSchedules"), \
QLatin1String("id"), 3);  }
 
 long unsigned MyMoneyStorageSql::getNextSecurityId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdSecurities;
+  return getNextId<&MyMoneyStorageSql::m_hiIdSecurities>(QLatin1String("kmmSecurities"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextTransactionId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdTransactions;
+  return getNextId<&MyMoneyStorageSql::m_hiIdTransactions>(QLatin1String("kmmTransactions"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextOnlineJobId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdOnlineJobs;
+  return getNextId<&MyMoneyStorageSql::m_hiIdOnlineJobs>(QLatin1String("kmmOnlineJobs"), \
QLatin1String("id"), 1);  }
 
 long unsigned MyMoneyStorageSql::getNextPayeeIdentifierId() const
 {
-  const_cast <MyMoneyStorageSql*>(this)->readFileInfo();
-  return m_hiIdPayeeIdentifier;
+  return getNextId<&MyMoneyStorageSql::m_hiIdPayeeIdentifier>(QLatin1String("kmmPayeeIdentifier"), \
QLatin1String("id"), 5);  }
 
 long unsigned MyMoneyStorageSql::incrementBudgetId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiBudgetId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiBudgetId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdBudgets = returnValue;
-  return returnValue;
+  m_hiIdBudgets = getNextBudgetId() + 1;
+  return (m_hiIdBudgets-1);
 }
 
+/**
+ * @warning This method uses getNextAccountId() internaly. The database is not \
informed which can cause issues + * when the database is accessed concurrently. Then \
maybe a single id is used twice but the RDBMS will detect the + * issue and KMyMoney \
crashes. This issue can only occour when two instances of KMyMoney access the same \
database. + * But in this unlikley case MyMoneyStorageSql will have a lot more \
issues, I think. + */
 long unsigned MyMoneyStorageSql::incrementAccountId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiAccountId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiAccountId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdAccounts = returnValue;
-  return returnValue;
+  m_hiIdAccounts = getNextAccountId() + 1;
+  return (m_hiIdAccounts-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementInstitutionId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiInstitutionId FROM kmmFileInfo " + \
                m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiInstitutionId = \
                %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdInstitutions = returnValue;
-  return returnValue;
+  m_hiIdInstitutions = getNextInstitutionId() + 1;
+  return (m_hiIdInstitutions-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementPayeeId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiPayeeId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiPayeeId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdPayees = returnValue;
-  return returnValue;
+  m_hiIdPayees = getNextPayeeId() + 1;
+  return (m_hiIdPayees-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementTagId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiTagId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiTagId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdTags = returnValue;
-  return returnValue;
+  m_hiIdTags = getNextTagId() + 1;
+  return (m_hiIdTags-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementReportId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiReportId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiReportId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdReports = returnValue;
-  return returnValue;
+  m_hiIdReports = getNextReportId() + 1;
+  return (m_hiIdReports-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementScheduleId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiScheduleId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiScheduleId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdSchedules = returnValue;
-  return returnValue;
+  m_hiIdSchedules = getNextScheduleId() + 1;
+  return (m_hiIdSchedules-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementSecurityId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiSecurityId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiSecurityId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdSecurities = returnValue;
-  return returnValue;
+  m_hiIdSecurities = getNextSecurityId() + 1;
+  return (m_hiIdSecurities-1);
 }
 
 long unsigned MyMoneyStorageSql::incrementTransactionId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiTransactionId FROM kmmFileInfo " + \
                m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiTransactionId = \
                %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdTransactions = returnValue;
-  return returnValue;
+  m_hiIdTransactions = getNextTransactionId() + 1;
+  return (m_hiIdTransactions-1);
 }
 
 long unsigned int MyMoneyStorageSql::incrementOnlineJobId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiOnlineJobId FROM kmmFileInfo " + m_driver->forUpdateString());
-  q.exec(); // krazy:exclude=crashy
-  q.next();
-  long unsigned returnValue = ((unsigned long) q.value(0).toULongLong()) + 1;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiOnlineJobId = %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdOnlineJobs = returnValue;
-  return returnValue;
+  m_hiIdOnlineJobs = getNextOnlineJobId() + 1;
+  return (m_hiIdOnlineJobs-1);
 }
 
 long unsigned int MyMoneyStorageSql::incrementPayeeIdentfierId()
 {
-  QSqlQuery q(*this);
-
-  MyMoneyDbTransaction t(*this, Q_FUNC_INFO);
-  q.prepare("SELECT hiPayeeIdentifierId FROM kmmFileInfo " + \
                m_driver->forUpdateString());
-  q.exec();
-  q.next();
-  long unsigned returnValue = (unsigned long) q.value(0).toULongLong();
-  ++returnValue;
-  q.prepare(QString("UPDATE kmmFileInfo SET hiPayeeIdentifierId = \
                %1").arg(returnValue));
-  q.exec(); // krazy:exclude=crashy
-  m_hiIdPayeeIdentifier = returnValue;
-  return returnValue;
+  m_hiIdPayeeIdentifier = getNextPayeeIdentifierId() + 1;
+  return (m_hiIdPayeeIdentifier-1);
 }
 
 void MyMoneyStorageSql::loadAccountId(const unsigned long& id)
diff --git a/kmymoney/mymoney/storage/mymoneystoragesql.h \
b/kmymoney/mymoney/storage/mymoneystoragesql.h index 96a37ce..6080868 100644
--- a/kmymoney/mymoney/storage/mymoneystoragesql.h
+++ b/kmymoney/mymoney/storage/mymoneystoragesql.h
@@ -172,10 +172,10 @@ public:
   bool writeFile(void);
 
   /**
-  * MyMoneyStorageSql generalized error routine
-  *
-  * @return : error message to be displayed
-  *
+   * MyMoneyStorageSql generalized error routine
+   *
+   * @return : error message to be displayed
+   *
    */
   const QString& lastError() const {
     return (m_error);
@@ -185,7 +185,6 @@ public:
    * MyMoneyStorageSql get highest ID number from the database
    *
    * @return : highest ID number
-   *
    */
   long unsigned highestNumberFromIdString(QString tableName, QString tableField, int \
prefixLength);  
@@ -195,6 +194,7 @@ public:
    * from the database is available in memory to enable it to be written.
    */
   virtual void fillStorage();
+
   /**
     * The following functions correspond to the identically named (usually) \
                functions
     * within the Storage Manager, and are called to update the database
@@ -411,6 +411,9 @@ private:
   void readBudgets(void);
   /** @} */
 
+  template<long unsigned MyMoneyStorageSql::* cache>
+  long unsigned int getNextId(const QString& table, const QString& id, const int \
prefixLength) const; +
   void deleteTransaction(const QString& id);
   void deleteTagSplitsList(const QString& txId, const QList<int>& splitIdList);
   void deleteSchedule(const QString& id);
@@ -507,7 +510,8 @@ private:
   long unsigned m_onlineJobs;
   long unsigned m_payeeIdentifier;
 
-  // next id to use (for future archive)
+  // Cache for next id to use
+  // value 0 means data is not available and has to be loaded from the database
   long unsigned m_hiIdInstitutions;
   long unsigned m_hiIdPayees;
   long unsigned m_hiIdTags;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic