From b69809d6331b17865cc657cfd2ad48ed7464a6f2 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 11 Jan 2018 20:31:51 +0300 Subject: mdbx-plugin: fix names for clarity (minor, but renaming). # Conflicts: # plugins/Dbx_mdbx/src/libmdbx --- plugins/Dbx_mdbx/src/dbcontacts.cpp | 247 ++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 plugins/Dbx_mdbx/src/dbcontacts.cpp (limited to 'plugins/Dbx_mdbx/src/dbcontacts.cpp') diff --git a/plugins/Dbx_mdbx/src/dbcontacts.cpp b/plugins/Dbx_mdbx/src/dbcontacts.cpp new file mode 100644 index 0000000000..1195c0af6e --- /dev/null +++ b/plugins/Dbx_mdbx/src/dbcontacts.cpp @@ -0,0 +1,247 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +STDMETHODIMP_(LONG) CDbxMDBX::GetContactCount(void) +{ + return m_contactCount; +} + +STDMETHODIMP_(LONG) CDbxMDBX::GetContactSize(void) +{ + return sizeof(DBCachedContact); +} + +STDMETHODIMP_(LONG) CDbxMDBX::DeleteContact(MCONTACT contactID) +{ + if (contactID == 0) // global contact cannot be removed + return 1; + + NotifyEventHooks(hContactDeletedEvent, contactID, 0); + { + OBJLIST events(50); + GatherContactHistory(contactID, events); + while (events.getCount()) { + DeleteEvent(contactID, events[0].eventId); + events.remove(0); + } + } + { + MDBX_val key, data; + DBSettingKey keyS = { contactID, 0, 0 }; + + txn_ptr txn(m_env); + cursor_ptr cursor(txn, m_dbSettings); + + key.iov_len = sizeof(keyS); key.iov_base = &keyS; + + for (int res = mdbx_cursor_get(cursor, &key, &data, MDBX_SET_RANGE); res == MDBX_SUCCESS; res = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) { + const DBSettingKey *pKey = (const DBSettingKey*)key.iov_base; + if (pKey->hContact != contactID) + break; + mdbx_cursor_del(cursor, 0); + } + + txn.commit(); + } + + MDBX_val key = { &contactID, sizeof(MCONTACT) }; + for (;; Remap()) { + txn_ptr trnlck(m_env); + MDBX_CHECK(mdbx_del(trnlck, m_dbContacts, &key, nullptr), 1); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + + InterlockedDecrement(&m_contactCount); + + return 0; +} + +STDMETHODIMP_(MCONTACT) CDbxMDBX::AddContact() +{ + MCONTACT dwContactId = InterlockedIncrement(&m_maxContactId); + + DBCachedContact *cc = m_cache->AddContactToCache(dwContactId); + + MDBX_val key = { &dwContactId, sizeof(MCONTACT) }; + MDBX_val data = { &cc->dbc, sizeof(cc->dbc) }; + + for (;; Remap()) { + txn_ptr trnlck(m_env); + MDBX_CHECK(mdbx_put(trnlck, m_dbContacts, &key, &data, 0), 0); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + + InterlockedIncrement(&m_contactCount); + NotifyEventHooks(hContactAddedEvent, dwContactId, 0); + return dwContactId; +} + +STDMETHODIMP_(BOOL) CDbxMDBX::IsDbContact(MCONTACT contactID) +{ + DBCachedContact *cc = m_cache->GetCachedContact(contactID); + return (cc != NULL); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CDbxMDBX::GatherContactHistory(MCONTACT hContact, LIST &list) +{ + DBEventSortingKey keyVal = { 0, 0, hContact }; + MDBX_val key = { &keyVal, sizeof(keyVal) }, data; + + txn_ptr_ro trnlck(m_txn); + cursor_ptr_ro cursor(m_curEventsSort); + + for (int res = mdbx_cursor_get(cursor, &key, &data, MDBX_SET_RANGE); res == MDBX_SUCCESS; res = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) { + const DBEventSortingKey *pKey = (const DBEventSortingKey*)key.iov_base; + if (pKey->hContact != hContact) + return; + + list.insert(new EventItem(pKey->ts, pKey->hEvent)); + } +} + +BOOL CDbxMDBX::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) +{ + LIST list(1000); + GatherContactHistory(ccSub->contactID, list); + + for (int i = 0; i < list.getCount(); i++) { + EventItem *EI = list[i]; + + for (;; Remap()) { + txn_ptr trnlck(m_env); + DBEventSortingKey insVal = { EI->eventId, EI->ts, ccMeta->contactID }; + MDBX_val key = { &insVal, sizeof(insVal) }, data = { (void*)"", 1 }; + mdbx_put(trnlck, m_dbEventsSort, &key, &data, 0); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + ccMeta->dbc.dwEventCount++; + delete EI; + } + + MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) }; + + for (;; Remap()) { + txn_ptr trnlck(m_env); + MDBX_CHECK(mdbx_put(trnlck, m_dbContacts, &keyc, &datac, 0), 1); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +BOOL CDbxMDBX::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) +{ + LIST list(1000); + GatherContactHistory(ccSub->contactID, list); + + for (int i = 0; i < list.getCount(); i++) { + EventItem *EI = list[i]; + + for (;; Remap()) { + txn_ptr trnlck(m_env); + DBEventSortingKey insVal = { EI->eventId, EI->ts, ccMeta->contactID }; + MDBX_val key = { &insVal, sizeof(insVal) }, data = { (void*)"", 1 }; + mdbx_del(trnlck, m_dbEventsSort, &key, &data); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + ccMeta->dbc.dwEventCount--; + delete EI; + } + + MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) }; + + for (;; Remap()) { + txn_ptr trnlck(m_env); + MDBX_CHECK(mdbx_put(trnlck, m_dbContacts, &keyc, &datac, 0), 1); + if (trnlck.commit() == MDBX_SUCCESS) + break; + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void DBCachedContact::Advance(MEVENT id, DBEvent &dbe) +{ + dbc.dwEventCount++; + + if (dbe.flags & (DBEF_READ | DBEF_SENT)) + return; + + if (dbe.timestamp < dbc.tsFirstUnread || dbc.tsFirstUnread == 0) { + dbc.tsFirstUnread = dbe.timestamp; + dbc.evFirstUnread = id; + } +} + +void DBCachedContact::Snapshot() +{ + tmp_dbc = dbc; +} + +void DBCachedContact::Revert() +{ + dbc = tmp_dbc; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// initial cycle to fill the contacts' cache + +void CDbxMDBX::FillContacts() +{ + LIST arContacts(m_contactCount); + + txn_ptr_ro trnlck(m_txn); + cursor_ptr_ro cursor(m_curContacts); + + MDBX_val key, data; + while (mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT) == MDBX_SUCCESS) { + DBCachedContact *cc = m_cache->AddContactToCache(*(MCONTACT*)key.iov_base); + cc->dbc = *(DBContact*)data.iov_base; + + CheckProto(cc, ""); + + DBVARIANT dbv; dbv.type = DBVT_DWORD; + cc->nSubs = (0 != GetContactSetting(cc->contactID, META_PROTO, "NumContacts", &dbv)) ? -1 : dbv.dVal; + if (cc->nSubs != -1) { + cc->pSubs = (MCONTACT*)mir_alloc(cc->nSubs * sizeof(MCONTACT)); + for (int k = 0; k < cc->nSubs; k++) { + char setting[100]; + mir_snprintf(setting, _countof(setting), "Handle%d", k); + cc->pSubs[k] = (0 != GetContactSetting(cc->contactID, META_PROTO, setting, &dbv)) ? NULL : dbv.dVal; + } + } + cc->nDefault = (0 != GetContactSetting(cc->contactID, META_PROTO, "Default", &dbv)) ? -1 : dbv.dVal; + cc->parentID = (0 != GetContactSetting(cc->contactID, META_PROTO, "ParentMeta", &dbv)) ? NULL : dbv.dVal; + } +} -- cgit v1.2.3