diff options
author | George Hazan <ghazan@miranda.im> | 2021-01-16 19:30:20 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2021-01-16 19:30:20 +0300 |
commit | b2a65cb0e93f070ebb78dd69a9740527fb0e6261 (patch) | |
tree | e83aac634813a44991f212cbaab43dbab60f37a3 | |
parent | 97f80dd9e5737bb65cdd2b745c864e9c3b7ab433 (diff) |
dbx_sqlite:
- major speed-up (we don't close each transaction immediately);
- assert replaced with correct error logging (to be able to debug problems using network logs);
- code cleaning;
- version bump
-rw-r--r-- | plugins/Dbx_sqlite/dbx_sqlite.vcxproj | 1 | ||||
-rw-r--r-- | plugins/Dbx_sqlite/dbx_sqlite.vcxproj.filters | 3 | ||||
-rwxr-xr-x | plugins/Dbx_sqlite/src/dbcontacts.cpp | 17 | ||||
-rw-r--r-- | plugins/Dbx_sqlite/src/dbcrypt.cpp | 2 | ||||
-rwxr-xr-x | plugins/Dbx_sqlite/src/dbevents.cpp | 63 | ||||
-rwxr-xr-x | plugins/Dbx_sqlite/src/dbintf.cpp | 123 | ||||
-rwxr-xr-x | plugins/Dbx_sqlite/src/dbintf.h | 20 | ||||
-rwxr-xr-x | plugins/Dbx_sqlite/src/dbsettings.cpp | 13 | ||||
-rw-r--r-- | plugins/Dbx_sqlite/src/stdafx.h | 13 | ||||
-rw-r--r-- | plugins/Dbx_sqlite/src/utils.cpp | 14 | ||||
-rw-r--r-- | plugins/Dbx_sqlite/src/version.h | 4 |
11 files changed, 160 insertions, 113 deletions
diff --git a/plugins/Dbx_sqlite/dbx_sqlite.vcxproj b/plugins/Dbx_sqlite/dbx_sqlite.vcxproj index ef4e8a8b49..36e99bb7a3 100644 --- a/plugins/Dbx_sqlite/dbx_sqlite.vcxproj +++ b/plugins/Dbx_sqlite/dbx_sqlite.vcxproj @@ -40,6 +40,7 @@ <ClCompile Include="src\stdafx.cxx"> <PrecompiledHeader>Create</PrecompiledHeader> </ClCompile> + <ClCompile Include="src\utils.cpp" /> <ClInclude Include="src\dbintf.h" /> <ClInclude Include="src\resource.h" /> <ClInclude Include="src\stdafx.h" /> diff --git a/plugins/Dbx_sqlite/dbx_sqlite.vcxproj.filters b/plugins/Dbx_sqlite/dbx_sqlite.vcxproj.filters index cda2246184..f2b029085d 100644 --- a/plugins/Dbx_sqlite/dbx_sqlite.vcxproj.filters +++ b/plugins/Dbx_sqlite/dbx_sqlite.vcxproj.filters @@ -23,6 +23,9 @@ <ClCompile Include="src\dbcrypt.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="src\utils.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="src\dbintf.h"> diff --git a/plugins/Dbx_sqlite/src/dbcontacts.cpp b/plugins/Dbx_sqlite/src/dbcontacts.cpp index 23d243f145..f9c32981cf 100755 --- a/plugins/Dbx_sqlite/src/dbcontacts.cpp +++ b/plugins/Dbx_sqlite/src/dbcontacts.cpp @@ -32,7 +32,7 @@ void CDbxSQLite::InitContacts() DBCachedContact *cc = (hContact) ? m_cache->AddContactToCache(hContact) : &m_system; cc->m_count = sqlite3_column_int64(stmt, 1); } - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_finalize(stmt); } @@ -47,7 +47,7 @@ LONG CDbxSQLite::GetContactCount() mir_cslock lock(m_csDbAccess); sqlite3_stmt *stmt = ctc_stmts[SQL_CTC_STMT_COUNT].pQuery; int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); int count = sqlite3_column_int(stmt, 0); sqlite3_reset(stmt); return count; @@ -60,11 +60,12 @@ MCONTACT CDbxSQLite::AddContact() mir_cslock lock(m_csDbAccess); sqlite3_stmt *stmt = ctc_stmts[SQL_CTC_STMT_ADD].pQuery; int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return INVALID_CONTACT_ID; hContact = sqlite3_last_insert_rowid(m_db); + DBFlush(); } DBCachedContact *cc = m_cache->AddContactToCache(hContact); @@ -86,7 +87,7 @@ LONG CDbxSQLite::DeleteContact(MCONTACT hContact) sqlite3_stmt *stmt = ctc_stmts[SQL_CTC_STMT_DELETEEVENTS].pQuery; sqlite3_bind_int64(stmt, 1, hContact); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -94,7 +95,7 @@ LONG CDbxSQLite::DeleteContact(MCONTACT hContact) stmt = ctc_stmts[SQL_CTC_STMT_DELETEEVENTS_SRT].pQuery; sqlite3_bind_int64(stmt, 1, hContact); rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -102,7 +103,7 @@ LONG CDbxSQLite::DeleteContact(MCONTACT hContact) stmt = ctc_stmts[SQL_CTC_STMT_DELETESETTINGS].pQuery; sqlite3_bind_int64(stmt, 1, hContact); rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -110,7 +111,7 @@ LONG CDbxSQLite::DeleteContact(MCONTACT hContact) stmt = ctc_stmts[SQL_CTC_STMT_DELETE].pQuery; sqlite3_bind_int64(stmt, 1, hContact); rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -119,6 +120,8 @@ LONG CDbxSQLite::DeleteContact(MCONTACT hContact) lock.unlock(); NotifyEventHooks(g_hevContactDeleted, hContact); + + DBFlush(); return 0; } diff --git a/plugins/Dbx_sqlite/src/dbcrypt.cpp b/plugins/Dbx_sqlite/src/dbcrypt.cpp index 8ba9ae64fa..1acab4b150 100644 --- a/plugins/Dbx_sqlite/src/dbcrypt.cpp +++ b/plugins/Dbx_sqlite/src/dbcrypt.cpp @@ -27,6 +27,7 @@ STDMETHODIMP_(BOOL) CDbxSQLite::StoreCryptoKey() WriteContactSetting(0, &dbcws); SecureZeroMemory(pKey, iKeyLength); + DBFlush(); return TRUE; } @@ -65,6 +66,7 @@ STDMETHODIMP_(BOOL) CDbxSQLite::StoreProvider(CRYPTO_PROVIDER *pProvider) dbcws.value.pbVal = (PBYTE)pProvider->pszName; dbcws.value.cpbVal = (WORD)mir_strlen(pProvider->pszName) + 1; WriteContactSetting(0, &dbcws); + DBFlush(); return TRUE; } diff --git a/plugins/Dbx_sqlite/src/dbevents.cpp b/plugins/Dbx_sqlite/src/dbevents.cpp index 6abd5de844..7204aea647 100755 --- a/plugins/Dbx_sqlite/src/dbevents.cpp +++ b/plugins/Dbx_sqlite/src/dbevents.cpp @@ -65,7 +65,7 @@ void CDbxSQLite::InitEvents() if (mir_strlen(module) > 0) m_modules.insert(mir_strdup(module)); } - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_finalize(stmt); } @@ -90,7 +90,7 @@ LONG CDbxSQLite::GetEventCount(MCONTACT hContact) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_COUNT].pQuery; sqlite3_bind_int64(stmt, 1, hContact); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); cc->m_count = (rc != SQLITE_ROW) ? 0 : sqlite3_column_int64(stmt, 0); sqlite3_reset(stmt); return cc->m_count; @@ -149,7 +149,7 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) sqlite3_bind_blob(stmt, 6, dbei->pBlob, dbei->cbBlob, nullptr); sqlite3_bind_text(stmt, 7, szEventId, (int)mir_strlen(szEventId), nullptr); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); MEVENT hDbEvent = sqlite3_last_insert_rowid(m_db); @@ -159,7 +159,7 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) sqlite3_bind_int64(stmt, 2, cc->contactID); sqlite3_bind_int64(stmt, 3, dbei->timestamp); rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); cc->AddEvent(hDbEvent, dbei->timestamp, !dbei->markedRead()); @@ -169,7 +169,7 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) sqlite3_bind_int64(stmt, 2, ccSub->contactID); sqlite3_bind_int64(stmt, 3, dbei->timestamp); rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); //is this necessary ? ccSub->AddEvent(hDbEvent, dbei->timestamp, !dbei->markedRead()); @@ -180,6 +180,8 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) m_modules.insert(mir_strdup(dbei->szModule)); lock.unlock(); + + DBFlush(); if (m_safetyMode && !(dbei->flags & DBEF_TEMPORARY)) NotifyEventHooks(g_hevEventAdded, hNotifyContact, (LPARAM)hDbEvent); @@ -200,7 +202,7 @@ BOOL CDbxSQLite::DeleteEvent(MEVENT hDbEvent) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_DELETE].pQuery; sqlite3_bind_int64(stmt, 1, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -208,7 +210,7 @@ BOOL CDbxSQLite::DeleteEvent(MEVENT hDbEvent) stmt = evt_stmts[SQL_EVT_STMT_DELETE_SRT].pQuery; sqlite3_bind_int64(stmt, 1, hDbEvent); rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; @@ -218,6 +220,8 @@ BOOL CDbxSQLite::DeleteEvent(MEVENT hDbEvent) cc->DeleteEvent(hDbEvent); lock.unlock(); + + DBFlush(); NotifyEventHooks(g_hevEventDeleted, hContact, hDbEvent); return 0; } @@ -243,7 +247,7 @@ BOOL CDbxSQLite::EditEvent(MCONTACT hContact, MEVENT hDbEvent, const DBEVENTINFO sqlite3_bind_blob(stmt, 5, dbei->pBlob, dbei->cbBlob, nullptr); sqlite3_bind_int64(stmt, 6, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); cc->EditEvent(hDbEvent, dbei->timestamp, !dbei->markedRead()); @@ -255,6 +259,8 @@ BOOL CDbxSQLite::EditEvent(MCONTACT hContact, MEVENT hDbEvent, const DBEVENTINFO m_modules.insert(mir_strdup(dbei->szModule)); lock.unlock(); + + DBFlush(); NotifyEventHooks(g_hevEventEdited, hContact, (LPARAM)hDbEvent); return 0; } @@ -268,7 +274,7 @@ LONG CDbxSQLite::GetBlobSize(MEVENT hDbEvent) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_BLOBSIZE].pQuery; sqlite3_bind_int(stmt, 1, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return -1; @@ -296,7 +302,7 @@ BOOL CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_GET].pQuery; sqlite3_bind_int64(stmt, 1, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return 1; @@ -337,7 +343,7 @@ BOOL CDbxSQLite::MarkEventRead(MCONTACT hContact, MEVENT hDbEvent) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_GETFLAGS].pQuery; sqlite3_bind_int64(stmt, 1, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return -1; @@ -356,7 +362,7 @@ BOOL CDbxSQLite::MarkEventRead(MCONTACT hContact, MEVENT hDbEvent) sqlite3_bind_int(stmt, 1, flags); sqlite3_bind_int64(stmt, 2, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return -1; @@ -366,6 +372,7 @@ BOOL CDbxSQLite::MarkEventRead(MCONTACT hContact, MEVENT hDbEvent) cc->MarkRead(hDbEvent); } + DBFlush(); NotifyEventHooks(g_hevMarkedRead, hContact, (LPARAM)hDbEvent); return flags; } @@ -379,7 +386,7 @@ MCONTACT CDbxSQLite::GetEventContact(MEVENT hDbEvent) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_GETCONTACT].pQuery; sqlite3_bind_int64(stmt, 1, hDbEvent); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return INVALID_CONTACT_ID; @@ -406,7 +413,7 @@ MEVENT CDbxSQLite::FindFirstEvent(MCONTACT hContact) sqlite3_bind_int64(evt_cur_fwd, 1, hContact); int rc = sqlite3_step(evt_cur_fwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { //empty response //reset sql cursor @@ -446,7 +453,7 @@ MEVENT CDbxSQLite::FindFirstUnreadEvent(MCONTACT hContact) sqlite3_stmt *stmt; sqlite3_prepare_v2(m_db, query, -1, &stmt, nullptr); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_finalize(stmt); return 0; @@ -461,7 +468,7 @@ MEVENT CDbxSQLite::FindFirstUnreadEvent(MCONTACT hContact) sqlite3_bind_int64(stmt, 1, hContact); sqlite3_bind_int(stmt, 2, DBEF_READ | DBEF_SENT); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return 0; @@ -488,7 +495,7 @@ MEVENT CDbxSQLite::FindLastEvent(MCONTACT hContact) evt_cur_backwd = evt_stmts[SQL_EVT_STMT_FINDLAST].pQuery; sqlite3_bind_int64(evt_cur_backwd, 1, hContact); int rc = sqlite3_step(evt_cur_backwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { //empty response //reset sql cursor @@ -524,7 +531,7 @@ MEVENT CDbxSQLite::FindNextEvent(MCONTACT hContact, MEVENT hDbEvent) while (hDbEvent != sqlite3_column_int64(evt_cur_fwd, 0)) { int rc = sqlite3_step(evt_cur_fwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc == SQLITE_DONE) { //reset sql cursor sqlite3_reset(evt_cur_fwd); @@ -536,7 +543,7 @@ MEVENT CDbxSQLite::FindNextEvent(MCONTACT hContact, MEVENT hDbEvent) } int rc = sqlite3_step(evt_cur_fwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { //reset sql cursor sqlite3_reset(evt_cur_fwd); @@ -573,7 +580,7 @@ MEVENT CDbxSQLite::FindPrevEvent(MCONTACT hContact, MEVENT hDbEvent) while (hDbEvent != sqlite3_column_int64(evt_cur_backwd, 0)) { int rc = sqlite3_step(evt_cur_backwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc == SQLITE_DONE) { //reset sql cursor sqlite3_reset(evt_cur_backwd); @@ -585,7 +592,7 @@ MEVENT CDbxSQLite::FindPrevEvent(MCONTACT hContact, MEVENT hDbEvent) } int rc = sqlite3_step(evt_cur_backwd); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { //reset sql cursor sqlite3_reset(evt_cur_backwd); @@ -609,7 +616,7 @@ MEVENT CDbxSQLite::GetEventById(LPCSTR szModule, LPCSTR szId) sqlite3_bind_text(stmt, 1, szModule, (int)mir_strlen(szModule), nullptr); sqlite3_bind_text(stmt, 2, szId, (int)mir_strlen(szId), nullptr); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { sqlite3_reset(stmt); return 0; @@ -626,20 +633,21 @@ BOOL CDbxSQLite::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSu sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_META_MERGE_SELECT].pQuery; sqlite3_bind_int64(stmt, 1, ccSub->contactID); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); while (rc == SQLITE_ROW) { sqlite3_stmt *stmt2 = evt_stmts[SQL_EVT_STMT_ADDEVENT_SRT].pQuery; sqlite3_bind_int64(stmt2, 1, sqlite3_column_int64(stmt, 0)); sqlite3_bind_int64(stmt2, 2, ccMeta->contactID); sqlite3_bind_int64(stmt2, 3, sqlite3_column_int64(stmt, 1)); int rc2 = sqlite3_step(stmt2); - assert(rc2 == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc2); sqlite3_reset(stmt2); rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); } sqlite3_reset(stmt); + DBFlush(); return TRUE; } @@ -649,11 +657,12 @@ BOOL CDbxSQLite::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *) sqlite3_stmt *stmt = evt_stmts[SQL_EVT_STMT_META_SPLIT].pQuery; sqlite3_bind_int64(stmt, 1, ccMeta->contactID); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; + DBFlush(); return TRUE; } @@ -699,7 +708,7 @@ MEVENT CDbxSQLiteEventCursor::FetchNext() return 0; int rc = sqlite3_step(cursor); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); if (rc != SQLITE_ROW) { //empty response //reset sql cursor diff --git a/plugins/Dbx_sqlite/src/dbintf.cpp b/plugins/Dbx_sqlite/src/dbintf.cpp index b219cb11af..e0f45a7e18 100755 --- a/plugins/Dbx_sqlite/src/dbintf.cpp +++ b/plugins/Dbx_sqlite/src/dbintf.cpp @@ -1,7 +1,8 @@ #include "stdafx.h" -CDbxSQLite::CDbxSQLite(sqlite3 *database) - : m_db(database), +CDbxSQLite::CDbxSQLite(sqlite3 *database) : + m_db(database), + m_impl(*this), m_safetyMode(true), m_modules(1, strcmp) { @@ -9,16 +10,17 @@ CDbxSQLite::CDbxSQLite(sqlite3 *database) CDbxSQLite::~CDbxSQLite() { + int rc = sqlite3_exec(m_db, "commit;", nullptr, nullptr, nullptr); + logError(rc); + UninitEvents(); UninitContacts(); UninitSettings(); if (m_db) { - int rc = sqlite3_close(m_db); - if (rc != SQLITE_OK) - { - //TODO: - } + rc = sqlite3_close(m_db); + logError(rc); + m_db = nullptr; } } @@ -28,57 +30,41 @@ int CDbxSQLite::Create(const wchar_t *profile) sqlite3 *database = nullptr; ptrA path(mir_utf8encodeW(profile)); int rc = sqlite3_open_v2(path, &database, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, nullptr); + logError(rc); if (rc != SQLITE_OK) return 1; rc = sqlite3_exec(database, "CREATE TABLE contacts (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); + rc = sqlite3_exec(database, "CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, contact_id INTEGER NOT NULL, module TEXT NOT NULL," "timestamp INTEGER NOT NULL, type INTEGER NOT NULL, flags INTEGER NOT NULL, data BLOB, server_id TEXT);", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); + rc = sqlite3_exec(database, "CREATE INDEX idx_events_contactid_timestamp ON events(contact_id, timestamp);", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); + rc = sqlite3_exec(database, "CREATE INDEX idx_events_module_serverid ON events(module, server_id);", nullptr, nullptr, nullptr); if (rc != SQLITE_OK) - { - //TODO: handle error - } - rc = sqlite3_exec(database, "CREATE TABLE events_srt (id INTEGER NOT NULL, contact_id INTEGER NOT NULL, timestamp INTEGER, PRIMARY KEY(contact_id, timestamp, id));", - nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); + + rc = sqlite3_exec(database, "CREATE TABLE events_srt (id INTEGER NOT NULL, contact_id INTEGER NOT NULL, timestamp INTEGER, PRIMARY KEY(contact_id, timestamp, id));", nullptr, nullptr, nullptr); + logError(rc); + rc = sqlite3_exec(database, "CREATE TABLE settings (contact_id INTEGER NOT NULL, module TEXT NOT NULL, setting TEXT NOT NULL, type INTEGER NOT NULL, value ANY," "PRIMARY KEY(contact_id, module, setting)) WITHOUT ROWID;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); + rc = sqlite3_exec(database, "CREATE INDEX idx_settings_module ON settings(module);", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } + logError(rc); sqlite3_close(database); - return 0; } int CDbxSQLite::Check(const wchar_t *profile) { FILE *hFile = _wfopen(profile, L"rb"); - if (hFile == INVALID_HANDLE_VALUE) return EGROKPRF_CANTREAD; @@ -113,33 +99,21 @@ MDatabaseCommon* CDbxSQLite::Load(const wchar_t *profile, int readonly) int flags = SQLITE_OPEN_READWRITE; if (readonly) flags |= SQLITE_OPEN_READONLY; + int rc = sqlite3_open_v2(path, &database, flags, nullptr); if (rc != SQLITE_OK) return nullptr; rc = sqlite3_exec(database, "begin transaction;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) - { - //TODO: handle error - } - rc = sqlite3_exec(database, "pragma locking_mode = EXCLUSIVE;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) { - // TODO: handle error - } - rc = sqlite3_exec(database, "pragma synchronous = NORMAL;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) { - // TODO: handle error - } - sqlite3_exec(database, "pragma foreign_keys = OFF;", nullptr, nullptr, nullptr); - rc = sqlite3_exec(database, "pragma journal_mode = OFF;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) { - // TODO: handle error - } - rc = sqlite3_exec(database, "commit;", nullptr, nullptr, nullptr); - if (rc != SQLITE_OK) { - // TODO: handle error - } + logError(rc); + + sqlite3_exec(database, "pragma locking_mode = EXCLUSIVE;", nullptr, nullptr, nullptr); + sqlite3_exec(database, "pragma synchronous = NORMAL;", nullptr, nullptr, nullptr); + sqlite3_exec(database, "pragma foreign_keys = OFF;", nullptr, nullptr, nullptr); + sqlite3_exec(database, "pragma journal_mode = OFF;", nullptr, nullptr, nullptr); + rc = sqlite3_exec(database, "commit;", nullptr, nullptr, nullptr); + logError(rc); CDbxSQLite *db = new CDbxSQLite(database); db->InitContacts(); @@ -151,16 +125,11 @@ MDatabaseCommon* CDbxSQLite::Load(const wchar_t *profile, int readonly) return nullptr; } + rc = sqlite3_exec(database, "begin transaction;", nullptr, nullptr, nullptr); + logError(rc); return db; } -BOOL CDbxSQLite::Compact() -{ - sqlite3_exec(m_db, "pragma optimize;", nullptr, nullptr, nullptr); - sqlite3_exec(m_db, "vacuum;", nullptr, nullptr, nullptr); - return 0; -} - BOOL CDbxSQLite::Backup(LPCWSTR profile) { sqlite3 *database = nullptr; @@ -176,11 +145,33 @@ BOOL CDbxSQLite::Backup(LPCWSTR profile) sqlite3_backup_step(backup, -1); sqlite3_backup_finish(backup); } + sqlite3_close(database); + return 0; +} +BOOL CDbxSQLite::Compact() +{ + sqlite3_exec(m_db, "pragma optimize;", nullptr, nullptr, nullptr); + sqlite3_exec(m_db, "vacuum;", nullptr, nullptr, nullptr); return 0; } +void CDbxSQLite::DBFlush(bool bForce) +{ + if (bForce) { + mir_cslock lck(m_csDbAccess); + + int rc = sqlite3_exec(m_db, "commit;", nullptr, nullptr, nullptr); + logError(rc); + + rc = sqlite3_exec(m_db, "begin transaction;", nullptr, nullptr, nullptr); + logError(rc); + } + else if (m_safetyMode) + m_impl.m_timer.Start(50); +} + BOOL CDbxSQLite::IsRelational() { return TRUE; diff --git a/plugins/Dbx_sqlite/src/dbintf.h b/plugins/Dbx_sqlite/src/dbintf.h index e3e2fc46d7..123f950e72 100755 --- a/plugins/Dbx_sqlite/src/dbintf.h +++ b/plugins/Dbx_sqlite/src/dbintf.h @@ -43,6 +43,24 @@ class CDbxSQLite : public MDatabaseCommon, public MZeroedObject DBCachedContact m_system; + struct Impl { + CDbxSQLite &pro; + + CTimer m_timer; + void OnTimer(CTimer *pTimer) + { + pTimer->Stop(); + pro.DBFlush(true); + } + + Impl(CDbxSQLite &_p) : + pro(_p), + m_timer(Miranda_GetSystemWindow(), UINT_PTR(this)) + { + m_timer.OnEvent = Callback(this, &Impl::OnTimer); + } + } m_impl; + bool m_safetyMode; CDbxSQLite(sqlite3 *database); @@ -57,6 +75,8 @@ class CDbxSQLite : public MDatabaseCommon, public MZeroedObject void InitSettings(); void UninitSettings(); + void DBFlush(bool bForce = false); + public: ~CDbxSQLite(); diff --git a/plugins/Dbx_sqlite/src/dbsettings.cpp b/plugins/Dbx_sqlite/src/dbsettings.cpp index aab8f5f30c..45c77dbf06 100755 --- a/plugins/Dbx_sqlite/src/dbsettings.cpp +++ b/plugins/Dbx_sqlite/src/dbsettings.cpp @@ -100,7 +100,7 @@ BOOL CDbxSQLite::EnumModuleNames(DBMODULEENUMPROC pFunc, void *param) const char *value = (const char *)sqlite3_column_text(stmt, 0); modules.insert(mir_strdup(value)); } - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); } @@ -142,11 +142,12 @@ BOOL CDbxSQLite::WriteContactSettingWorker(MCONTACT hContact, DBCONTACTWRITESETT } int rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); if (rc != SQLITE_DONE) return 1; + DBFlush(); return 0; } @@ -171,15 +172,17 @@ BOOL CDbxSQLite::DeleteContactSetting(MCONTACT hContact, LPCSTR szModule, LPCSTR sqlite3_bind_text(stmt, 2, szModule, (int)mir_strlen(szModule), nullptr); sqlite3_bind_text(stmt, 3, szSetting, (int)mir_strlen(szSetting), nullptr); int rc = sqlite3_step(stmt); - assert(rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); stmt = settings_stmts[SQL_SET_STMT_CHANGES].pQuery; rc = sqlite3_step(stmt); - assert(rc == SQLITE_ROW); + logError(rc); int deleted = sqlite3_column_int(stmt, 0); sqlite3_reset(stmt); if (deleted == 0) return 1; + + DBFlush(); } m_cache->GetCachedValuePtr(hContact, szCachedSettingName, -1); @@ -217,7 +220,7 @@ BOOL CDbxSQLite::EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnu const char *value = (const char *)sqlite3_column_text(stmt, 0); settings.insert(mir_strdup(value)); } - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + logError(rc); sqlite3_reset(stmt); } diff --git a/plugins/Dbx_sqlite/src/stdafx.h b/plugins/Dbx_sqlite/src/stdafx.h index edeed11711..9cb2103537 100644 --- a/plugins/Dbx_sqlite/src/stdafx.h +++ b/plugins/Dbx_sqlite/src/stdafx.h @@ -1,20 +1,19 @@ #pragma once #include <windows.h> -#include <sqlite3.h> - -#include <memory> - #include <malloc.h> -#include <win2k.h> -#include <assert.h> +#include <crtdbg.h> #include <newpluginapi.h> #include <m_crypto.h> #include <m_database.h> +#include <m_gui.h> +#include <m_netlib.h> #include <m_protocols.h> #include <m_metacontacts.h> +#include <sqlite3.h> + #include "dbintf.h" #include "resource.h" #include "version.h" @@ -25,6 +24,8 @@ struct CQuery sqlite3_stmt *pQuery; }; +void logError(int rc, const char *szFile = __FILE__, int line = __LINE__); + ///////////////////////////////////////////////////////////////////////////////////////// constexpr auto SQLITE_HEADER_STR = "SQLite format 3"; diff --git a/plugins/Dbx_sqlite/src/utils.cpp b/plugins/Dbx_sqlite/src/utils.cpp new file mode 100644 index 0000000000..174fe9d394 --- /dev/null +++ b/plugins/Dbx_sqlite/src/utils.cpp @@ -0,0 +1,14 @@ +#include "stdafx.h" + +void logError(int rc, const char *szFile, int line) +{ + switch (rc) { + case SQLITE_OK: + case SQLITE_ROW: + case SQLITE_DONE: + return; + } + + _ASSERT(rc == 0); + Netlib_Logf(0, "SQLITE error %d (%s, %d)", rc, szFile, line); +} diff --git a/plugins/Dbx_sqlite/src/version.h b/plugins/Dbx_sqlite/src/version.h index 34737ca826..f35e26ae44 100644 --- a/plugins/Dbx_sqlite/src/version.h +++ b/plugins/Dbx_sqlite/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 95 -#define __RELEASE_NUM 10 -#define __BUILD_NUM 2 +#define __RELEASE_NUM 13 +#define __BUILD_NUM 1 #include <stdver.h> |