From 88722c0734ae6ce9b91ba397b89c4b73ed6f064d Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 12 Jan 2015 23:00:18 +0000 Subject: transaction locker very first version of settings writer/reader git-svn-id: http://svn.miranda-ng.org/main/trunk@11847 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mdb/src/dbsettings.cpp | 204 +++++++++++++++++++++++++++++++++++-- 1 file changed, 194 insertions(+), 10 deletions(-) (limited to 'plugins/Dbx_mdb/src/dbsettings.cpp') diff --git a/plugins/Dbx_mdb/src/dbsettings.cpp b/plugins/Dbx_mdb/src/dbsettings.cpp index 099625a1d2..7b0825d8c9 100644 --- a/plugins/Dbx_mdb/src/dbsettings.cpp +++ b/plugins/Dbx_mdb/src/dbsettings.cpp @@ -119,19 +119,117 @@ LBL_Seek: DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL; - DWORD ofsModuleName = GetModuleNameOfs(szModule); - - // try to get the missing mc setting from the active sub - if (cc && cc->IsMeta() && ValidLookupName(szModule, szSetting)) { - if (contactID = db_mc_getDefault(contactID)) { - if (szModule = GetContactProto(contactID)) { - moduleNameLen = (int)strlen(szModule); - goto LBL_Seek; + txn_lock trnlck(m_pMdbEnv); + mdb_open(trnlck, "settings", 0, &m_dbSettings); + + DBSettingKey keySearch; + keySearch.dwContactID = contactID; + keySearch.dwOfsModule = GetModuleNameOfs(szModule); + strncpy_s(keySearch.szSettingName, szSetting, _TRUNCATE); + + MDB_val key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch }, data; + if (mdb_get(trnlck, m_dbSettings, &key, &data)) { + // try to get the missing mc setting from the active sub + if (cc && cc->IsMeta() && ValidLookupName(szModule, szSetting)) { + if (contactID = db_mc_getDefault(contactID)) { + if (szModule = GetContactProto(contactID)) { + moduleNameLen = (int)strlen(szModule); + goto LBL_Seek; + } + } + } + return 1; + } + + BYTE *pBlob = (BYTE*)data.mv_data; + if (isStatic && (pBlob[0] & DBVTF_VARIABLELENGTH) && VLT(dbv->type) != VLT(pBlob[0])) + return 1; + + int varLen; + BYTE iType = dbv->type = pBlob[0]; + switch (iType) { + case DBVT_DELETED: /* this setting is deleted */ + dbv->type = DBVT_DELETED; + return 2; + + case DBVT_BYTE: dbv->bVal = pBlob[1]; break; + case DBVT_WORD: memmove(&(dbv->wVal), (PWORD)(pBlob + 1), 2); break; + case DBVT_DWORD: memmove(&(dbv->dVal), (PDWORD)(pBlob + 1), 4); break; + + case DBVT_UTF8: + case DBVT_ASCIIZ: + varLen = *(PWORD)(pBlob + 1); + pBlob += 3 + varLen; + if (isStatic) { + dbv->cchVal--; + if (varLen < dbv->cchVal) + dbv->cchVal = varLen; + memmove(dbv->pszVal, pBlob + 3, dbv->cchVal); // decode + dbv->pszVal[dbv->cchVal] = 0; + dbv->cchVal = varLen; + } + else { + dbv->pszVal = (char*)mir_alloc(1 + varLen); + memmove(dbv->pszVal, pBlob + 3, varLen); + dbv->pszVal[varLen] = 0; + } + break; + + case DBVT_BLOB: + varLen = *(PWORD)(pBlob + 1); + pBlob += 3 + varLen; + if (isStatic) { + if (varLen < dbv->cpbVal) + dbv->cpbVal = varLen; + memmove(dbv->pbVal, pBlob + 3, dbv->cpbVal); + } + else { + dbv->pbVal = (BYTE *)mir_alloc(varLen); + memmove(dbv->pbVal, pBlob + 3, varLen); + } + dbv->cpbVal = varLen; + break; + + case DBVT_ENCRYPTED: + if (m_crypto == NULL) + return 1; + else { + varLen = *(PWORD)(pBlob + 1); + pBlob += 3 + varLen; + size_t realLen; + ptrA decoded(m_crypto->decodeString(pBlob + 3, varLen, &realLen)); + if (decoded == NULL) + return 1; + + varLen = (WORD)realLen; + dbv->type = DBVT_UTF8; + if (isStatic) { + dbv->cchVal--; + if (varLen < dbv->cchVal) + dbv->cchVal = varLen; + memmove(dbv->pszVal, decoded, dbv->cchVal); + dbv->pszVal[dbv->cchVal] = 0; + dbv->cchVal = varLen; + } + else { + dbv->pszVal = (char*)mir_alloc(1 + varLen); + memmove(dbv->pszVal, decoded, varLen); + dbv->pszVal[varLen] = 0; } } + break; } - return 1; + /**** add to cache **********************/ + if (iType != DBVT_BLOB && iType != DBVT_ENCRYPTED) { + DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); + if (pCachedValue != NULL) { + m_cache->SetCachedVariant(dbv, pCachedValue); + log3("set cached [%08p] %s (%p)", hContact, szCachedSettingName, pCachedValue); + } + } + + return 0; } STDMETHODIMP_(BOOL) CDbxMdb::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) @@ -375,6 +473,54 @@ STDMETHODIMP_(BOOL) CDbxMdb::WriteContactSetting(MCONTACT contactID, DBCONTACTWR } else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1); + txn_lock trnlck(m_pMdbEnv); + mdb_open(trnlck, "settings", 0, &m_dbSettings); + + DBSettingKey keySearch; + keySearch.dwContactID = contactID; + keySearch.dwOfsModule = GetModuleNameOfs(dbcws->szModule); + strncpy_s(keySearch.szSettingName, dbcws->szSetting, _TRUNCATE); + + MDB_val key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch }, data; + + switch (dbcwWork.value.type) { + case DBVT_BYTE: data.mv_size = 2; break; + case DBVT_WORD: data.mv_size = 3; break; + case DBVT_DWORD: data.mv_size = 5; break; + + case DBVT_ASCIIZ: + case DBVT_UTF8: + data.mv_size = 3 + dbcwWork.value.cchVal; break; + + case DBVT_BLOB: + case DBVT_ENCRYPTED: + data.mv_size = 3 + dbcwWork.value.cpbVal; break; + } + + if (mdb_put(trnlck, m_dbSettings, &key, &data, MDB_RESERVE) != 0) + return 1; + + BYTE *pBlob = (BYTE*)data.mv_data; + *pBlob++ = dbcwWork.value.type; + switch (dbcwWork.value.type) { + case DBVT_BYTE: *pBlob = dbcwWork.value.bVal; break; + case DBVT_WORD: *(WORD*)pBlob = dbcwWork.value.wVal; break; + case DBVT_DWORD: *(DWORD*)pBlob = dbcwWork.value.dVal; break; + + case DBVT_ASCIIZ: + case DBVT_UTF8: + data.mv_size = *(WORD*)pBlob = dbcwWork.value.cchVal; + pBlob += 2; + memcpy(pBlob, dbcwWork.value.pszVal, dbcwWork.value.cchVal); + break; + + case DBVT_BLOB: + case DBVT_ENCRYPTED: + data.mv_size = *(WORD*)pBlob = dbcwWork.value.cpbVal; + pBlob += 2; + memcpy(pBlob, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); + } + lck.unlock(); // notify @@ -408,6 +554,19 @@ STDMETHODIMP_(BOOL) CDbxMdb::DeleteContactSetting(MCONTACT contactID, LPCSTR szM mir_cslock lck(m_csDbAccess); char *szCachedSettingName = m_cache->GetCachedSetting(szModule, szSetting, moduleNameLen, settingNameLen); if (szCachedSettingName[-1] == 0) { // it's not a resident variable + txn_lock trnlck(m_pMdbEnv); + mdb_open(trnlck, "settings", 0, &m_dbSettings); + + DBSettingKey keySearch; + keySearch.dwContactID = contactID; + keySearch.dwOfsModule = GetModuleNameOfs(szModule); + strncpy_s(keySearch.szSettingName, szSetting, _TRUNCATE); + + MDB_val key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch }, data; + if (mdb_del(trnlck, m_dbSettings, &key, &data)) + return 1; + + trnlck.commit(); } m_cache->GetCachedValuePtr(saveContact, szCachedSettingName, -1); @@ -427,8 +586,33 @@ STDMETHODIMP_(BOOL) CDbxMdb::EnumContactSettings(MCONTACT contactID, DBCONTACTEN if (!dbces->szModule) return -1; + int result = 0; mir_cslock lck(m_csDbAccess); - return -11; + /* + txn_lock trnlck(m_pMdbEnv); + mdb_open(trnlck, "settings", 0, &m_dbSettings); + + MDB_cursor *cursor; + mdb_cursor_open(trnlck, m_dbSettings, &cursor); + + DBSettingKey keySearch; + keySearch.dwContactID = contactID; + keySearch.dwOfsModule = GetModuleNameOfs(dbces->szModule); + keySearch.szSettingName[0] = 0; + + MDB_val key = { 2 * sizeof(DWORD), &keySearch }, data; + while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) { + DBSettingKey *pKey = (DBSettingKey*)key.mv_data; + if (pKey->dwContactID != contactID || pKey->dwOfsModule != keySearch.dwOfsModule) + break; + + char szSetting[256]; + strncpy_s(szSetting, pKey->szSettingName, key.mv_size - sizeof(DWORD)*2); + result = (dbces->pfnEnumProc)(szSetting, dbces->lParam); + } + + mdb_cursor_close(cursor); */ + return result; } STDMETHODIMP_(BOOL) CDbxMdb::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) -- cgit v1.2.3