From b80bf9c6208115addd64726fc6904f1543c63952 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 17 Oct 2018 14:52:12 +0300 Subject: fixes #1626 (Dbx_mdbx: subcontact's history disappears after removing a subcontact instead of saving in meta) --- plugins/Dbx_mdbx/src/dbcontacts.cpp | 84 ++++++++++++++++++++++++++----------- plugins/Dbx_mdbx/src/dbintf.h | 4 +- 2 files changed, 63 insertions(+), 25 deletions(-) (limited to 'plugins/Dbx_mdbx') diff --git a/plugins/Dbx_mdbx/src/dbcontacts.cpp b/plugins/Dbx_mdbx/src/dbcontacts.cpp index 6c6fd8a8ba..eb0c6d4258 100644 --- a/plugins/Dbx_mdbx/src/dbcontacts.cpp +++ b/plugins/Dbx_mdbx/src/dbcontacts.cpp @@ -42,6 +42,8 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID) return 1; NotifyEventHooks(g_hevContactDeleted, contactID, 0); + + // remove events owned by contact { OBJLIST events(50); GatherContactHistory(contactID, events); @@ -50,6 +52,8 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID) events.remove(0); } } + + // remove all contact's settings { MDBX_val key, data; DBSettingKey keyS = { contactID, 0, 0 }; @@ -66,9 +70,11 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID) mdbx_cursor_del(cursor, 0); } - trnlck.commit(); + if (trnlck.commit() != MDBX_SUCCESS) + return 1; } + // finally remove the contact itself MDBX_val key = { &contactID, sizeof(MCONTACT) }; { txn_ptr trnlck(StartTran()); @@ -114,7 +120,7 @@ STDMETHODIMP_(BOOL) CDbxMDBX::IsDbContact(MCONTACT contactID) ///////////////////////////////////////////////////////////////////////////////////////// -void CDbxMDBX::GatherContactHistory(MCONTACT hContact, LIST &list) +void CDbxMDBX::GatherContactHistory(MCONTACT hContact, OBJLIST &list) { DBEventSortingKey keyVal = { hContact, 0, 0 }; MDBX_val key = { &keyVal, sizeof(keyVal) }, data; @@ -133,23 +139,21 @@ void CDbxMDBX::GatherContactHistory(MCONTACT hContact, LIST &list) BOOL CDbxMDBX::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) { - LIST list(1000); + OBJLIST list(1000); GatherContactHistory(ccSub->contactID, list); for (auto &EI : list) { - { - txn_ptr trnlck(StartTran()); + txn_ptr trnlck(StartTran()); - DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts }; - MDBX_val key = { &insVal, sizeof(insVal) }, data = { (void*)"", 1 }; - if (mdbx_put(trnlck, m_dbEventsSort, &key, &data, 0) != MDBX_SUCCESS) - return 1; + DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts }; + MDBX_val key = { &insVal, sizeof(insVal) }, data = { (void*)"", 1 }; + if (mdbx_put(trnlck, m_dbEventsSort, &key, &data, 0) != MDBX_SUCCESS) + return 1; + + if (trnlck.commit() != MDBX_SUCCESS) + return 1; - if (trnlck.commit() != MDBX_SUCCESS) - return 1; - } ccMeta->dbc.dwEventCount++; - delete EI; } MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) }; @@ -167,21 +171,19 @@ BOOL CDbxMDBX::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) BOOL CDbxMDBX::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) { - LIST list(1000); + OBJLIST list(1000); GatherContactHistory(ccSub->contactID, list); for (auto &EI : list) { - { - txn_ptr trnlck(StartTran()); - DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts }; - MDBX_val key = { &insVal, sizeof(insVal) }; - if (mdbx_del(trnlck, m_dbEventsSort, &key, nullptr) != MDBX_SUCCESS) - return 1; - if (trnlck.commit() != MDBX_SUCCESS) - return 1; - } + txn_ptr trnlck(StartTran()); + DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts }; + MDBX_val key = { &insVal, sizeof(insVal) }; + if (mdbx_del(trnlck, m_dbEventsSort, &key, nullptr) != MDBX_SUCCESS) + return 1; + if (trnlck.commit() != MDBX_SUCCESS) + return 1; + ccMeta->dbc.dwEventCount--; - delete EI; } txn_ptr trnlck(StartTran()); @@ -197,6 +199,40 @@ BOOL CDbxMDBX::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) ///////////////////////////////////////////////////////////////////////////////////////// +BOOL CDbxMDBX::MetaRemoveSubHistory(DBCachedContact *ccSub) +{ + OBJLIST list(1000); + GatherContactHistory(ccSub->contactID, list); + + for (auto &EI : list) { + txn_ptr trnlck(StartTran()); + { + MDBX_val key = { &EI->eventId, sizeof(MEVENT) }, data; + if (mdbx_get(trnlck, m_dbEvents, &key, &data) == MDBX_SUCCESS) { + DBEvent *pEvent = (DBEvent*)data.iov_base; + pEvent->contactID = ccSub->parentID; + if (mdbx_put(trnlck, m_dbEvents, &key, &data, 0) != MDBX_SUCCESS) + return 1; + } + } + + DBEventSortingKey sortKey = { ccSub->contactID, EI->eventId, EI->ts }; + { + MDBX_val key = { &sortKey, sizeof(sortKey) }; + if (mdbx_del(trnlck, m_dbEventsSort, &key, nullptr) != MDBX_SUCCESS) + return 1; + } + + if (trnlck.commit() != MDBX_SUCCESS) + return 1; + } + + DBFlush(); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + void DBCachedContact::Advance(MEVENT id, DBEvent &dbe) { dbc.dwEventCount++; diff --git a/plugins/Dbx_mdbx/src/dbintf.h b/plugins/Dbx_mdbx/src/dbintf.h index 2098412a68..f35da2a3bc 100644 --- a/plugins/Dbx_mdbx/src/dbintf.h +++ b/plugins/Dbx_mdbx/src/dbintf.h @@ -187,7 +187,7 @@ class CDbxMDBX : public MDatabaseCommon, public MZeroedObject MCONTACT m_maxContactId; - void GatherContactHistory(MCONTACT hContact, LIST &items); + void GatherContactHistory(MCONTACT hContact, OBJLIST &items); //////////////////////////////////////////////////////////////////////////// // events @@ -271,6 +271,8 @@ public: STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; + STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact *ccSub) override; + STDMETHODIMP_(BOOL) Compact(); STDMETHODIMP_(BOOL) Backup(const wchar_t*); -- cgit v1.2.3