diff options
author | aunsane <aunsane@gmail.com> | 2018-03-07 00:54:57 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2018-03-07 00:54:57 +0300 |
commit | 7e9fef8a6ff35c63f9217fcc618d77f660e45245 (patch) | |
tree | 319319349fbdbec1def789f67ca7f2f7ccdab77a /plugins/Import | |
parent | 3eaee7138f6f34cb05c963993eca48b7429f2456 (diff) |
Import: first compiled version of dbrw loader
Diffstat (limited to 'plugins/Import')
-rw-r--r-- | plugins/Import/import.vcxproj | 34 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbcontacts.cpp | 54 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbevents.cpp | 184 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbintf.cpp | 83 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbintf.h | 155 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbrw.cpp | 107 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbrw.h | 30 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbsettings.cpp | 181 | ||||
-rw-r--r-- | plugins/Import/src/dbrw/dbsql.cpp | 162 | ||||
-rw-r--r-- | plugins/Import/src/main.cpp | 3 | ||||
-rw-r--r-- | plugins/Import/src/stdafx.h | 4 |
11 files changed, 997 insertions, 0 deletions
diff --git a/plugins/Import/import.vcxproj b/plugins/Import/import.vcxproj index 60ff6a6a35..444582b9fd 100644 --- a/plugins/Import/import.vcxproj +++ b/plugins/Import/import.vcxproj @@ -18,6 +18,11 @@ <Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\libs\sqlite3\sqlite3.vcxproj">
+ <Project>{0c02e395-e73f-47e3-8b95-b7924c0c7a6a}</Project>
+ </ProjectReference>
+ </ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>Import</ProjectName>
<ProjectGuid>{9299B507-1AF9-4C93-9560-5F637D1E0C9E}</ProjectGuid>
@@ -25,4 +30,33 @@ <ImportGroup Label="PropertySheets">
<Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
</ImportGroup>
+ <ItemGroup>
+ <ClCompile Include="src\dbrw\dbcontacts.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="src\dbrw\dbevents.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="src\dbrw\dbsettings.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="src\dbrw\dbintf.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="src\dbrw\dbsql.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="src\dbrw\dbrw.cpp">
+ <PrecompiledHeaderFile>..\stdafx.h</PrecompiledHeaderFile>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\dbrw\*.h" />
+ </ItemGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <AdditionalIncludeDirectories>$(ProjectDir)..\..\libs\sqlite3\src;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
</Project>
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbcontacts.cpp b/plugins/Import/src/dbrw/dbcontacts.cpp new file mode 100644 index 0000000000..c3aac4b1bc --- /dev/null +++ b/plugins/Import/src/dbrw/dbcontacts.cpp @@ -0,0 +1,54 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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_(BOOL) CDbxSQLite::IsDbContact(MCONTACT contactID) +{ + DBCachedContact *cc = m_cache->GetCachedContact(contactID); + return (cc != nullptr); +} + +STDMETHODIMP_(LONG) CDbxSQLite::GetContactCount(void) +{ + int res = 0; + sqlite3_bind_int(ctc_stmts_prep[SQL_CTC_STMT_COUNT], 1, res); + if (sql_step(ctc_stmts_prep[SQL_CTC_STMT_COUNT]) == SQLITE_ROW) + res = sqlite3_column_int(ctc_stmts_prep[SQL_CTC_STMT_COUNT], 0); + sql_reset(ctc_stmts_prep[SQL_CTC_STMT_COUNT]); + return res; +} + +STDMETHODIMP_(LONG) CDbxSQLite::GetContactSize(void) +{ + return sizeof(DBCachedContact); +} + +STDMETHODIMP_(MCONTACT) CDbxSQLite::AddContact(void) +{ + return INVALID_CONTACT_ID; +} + +STDMETHODIMP_(LONG) CDbxSQLite::DeleteContact(MCONTACT) +{ + return 1; +}
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbevents.cpp b/plugins/Import/src/dbrw/dbevents.cpp new file mode 100644 index 0000000000..cc8c04c5b3 --- /dev/null +++ b/plugins/Import/src/dbrw/dbevents.cpp @@ -0,0 +1,184 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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) CDbxSQLite::GetEventCount(MCONTACT contactID) +{ + mir_cslock lock(m_csDbAccess); + + int res = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_COUNT], 1, contactID); + if (sql_step(evt_stmts_prep[SQL_EVT_STMT_COUNT]) == SQLITE_ROW) + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_COUNT], 0); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_COUNT]); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::AddEvent(MCONTACT, DBEVENTINFO*) +{ + return 0; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::DeleteEvent(MCONTACT, MEVENT) +{ + return FALSE; +} + +STDMETHODIMP_(LONG) CDbxSQLite::GetBlobSize(MEVENT hDbEvent) +{ + mir_cslock lock(m_csDbAccess); + + int res = -1; + sqlite3_stmt *stmt = evt_stmts_prep[SQL_EVT_STMT_BLOBSIZE]; + sqlite3_bind_int(stmt, 1, hDbEvent); + if (sql_step(stmt) == SQLITE_ROW) + res = sqlite3_column_int(stmt, 0); + sql_reset(stmt); + return res; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) +{ + if (dbei == nullptr) + return 1; + + if (dbei->cbBlob > 0 && dbei->pBlob == nullptr) { + dbei->cbBlob = 0; + return 1; + } + + mir_cslock lock(m_csDbAccess); + + int res = 1; + sqlite3_stmt *stmt = evt_stmts_prep[SQL_EVT_STMT_GET]; + sqlite3_bind_int(stmt, 1, hDbEvent); + if (sql_step(stmt) == SQLITE_ROW) { + unsigned copySize; + const void *blob = sqlite3_column_blob(stmt, 4); + const unsigned size = sqlite3_column_int(stmt, 5); + + dbei->timestamp = (DWORD)sqlite3_column_int(stmt, 1); + dbei->flags = (DWORD)sqlite3_column_int(stmt, 2); + dbei->eventType = (WORD)sqlite3_column_int(stmt, 3); + dbei->szModule = mir_strdup((char*)sqlite3_column_text(stmt, 7)); + copySize = size<dbei->cbBlob ? size : dbei->cbBlob; + memcpy(dbei->pBlob, blob, copySize); + dbei->cbBlob = copySize; + res = 0; + } + sql_reset(stmt); + return res; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::MarkEventRead(MCONTACT, MEVENT) +{ + return FALSE; +} + +STDMETHODIMP_(MCONTACT) CDbxSQLite::GetEventContact(MEVENT hDbEvent) +{ + mir_cslock lock(m_csDbAccess); + + int res = INVALID_CONTACT_ID; + sqlite3_stmt *stmt = evt_stmts_prep[SQL_EVT_STMT_GETCONTACT]; + sqlite3_bind_int(stmt, 1, hDbEvent); + if (sql_step(stmt) == SQLITE_ROW) + res = sqlite3_column_int(stmt, 0); + sql_reset(stmt); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::FindFirstEvent(MCONTACT contactID) +{ + mir_cslock lock(m_csDbAccess); + + int res = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST], 1, contactID); + if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST]) == SQLITE_ROW) + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST], 0); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST]); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::FindFirstUnreadEvent(MCONTACT contactID) +{ + mir_cslock lock(m_csDbAccess); + + int res = 0; + DWORD flags = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD], 1, contactID); + while (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD]) == SQLITE_ROW) { + flags = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD], 0); + if (!(flags & (DBEF_READ | DBEF_SENT))) { + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD], 1); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD]); + return res; + } + } + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD]); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::FindLastEvent(MCONTACT contactID) +{ + mir_cslock lock(m_csDbAccess); + + int res = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDLAST], 1, contactID); + if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDLAST]) == SQLITE_ROW) + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDLAST], 0); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDLAST]); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::FindNextEvent(MCONTACT contactID, MEVENT hDbEvent) +{ + if (hDbEvent == NULL) + return 0; + + mir_cslock lock(m_csDbAccess); + + int res = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 1, contactID); + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 2, hDbEvent); + if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT]) == SQLITE_ROW) + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 0); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT]); + return res; +} + +STDMETHODIMP_(MEVENT) CDbxSQLite::FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent) +{ + if (!hDbEvent) + return 0; + + mir_cslock lock(m_csDbAccess); + + int res = 0; + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 1, contactID); + sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 2, hDbEvent); + if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDPREV]) == SQLITE_ROW) + res = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 0); + sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDPREV]); + return res; +}
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbintf.cpp b/plugins/Import/src/dbrw/dbintf.cpp new file mode 100644 index 0000000000..73c48676d4 --- /dev/null +++ b/plugins/Import/src/dbrw/dbintf.cpp @@ -0,0 +1,83 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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" + +CDbxSQLite::CDbxSQLite() + : sql_prepare_len(0) +{ + m_hAPCWindow = CreateWindowEx(0, L"STATIC", NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + + sql_prepare_add(ctc_stmts, ctc_stmts_prep, SQL_CTC_STMT_NUM); + sql_prepare_add(evt_stmts, evt_stmts_prep, SQL_EVT_STMT_NUM); + sql_prepare_add(set_stmts, set_stmts_prep, SQL_SET_STMT_NUM); +} + +CDbxSQLite::~CDbxSQLite() +{ + sql_close(m_sqlite); + + for (int i = 0; i < sql_prepare_len; i++) + sql_finalize(*sql_prepare_stmt[i]); + mir_free(sql_prepare_text); + mir_free(sql_prepare_stmt); + DestroyWindow(m_hAPCWindow); +} + +int CDbxSQLite::Open(const wchar_t *profile) +{ + T2Utf path(profile); + if (sql_open(path, &m_sqlite) != SQLITE_OK) + return 1; + + //utils_vacuum_check(); + { + sql_exec(m_sqlite, "BEGIN TRANSACTION;"); + sql_exec(m_sqlite, "PRAGMA locking_mode = EXCLUSIVE;"); + sql_exec(m_sqlite, "PRAGMA synchronous = NORMAL;"); + sql_exec(m_sqlite, "PRAGMA cache_size = 6000;"); + sql_exec(m_sqlite, "PRAGMA temp_store = MEMORY;"); + sql_exec(m_sqlite, "COMMIT;"); + } + + sql_prepare_statements(); + + return 0; +} + +STDMETHODIMP_(void) CDbxSQLite::SetCacheSafetyMode(BOOL safeMode) +{ + if (safeMode) + sql_exec(m_sqlite, "PRAGMA synchronous = NORMAL;"); + else + sql_exec(m_sqlite, "PRAGMA synchronous = OFF;"); +} + +STDMETHODIMP_(BOOL) CDbxSQLite::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) +{ + return FALSE; +}
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbintf.h b/plugins/Import/src/dbrw/dbintf.h new file mode 100644 index 0000000000..801377fdde --- /dev/null +++ b/plugins/Import/src/dbrw/dbintf.h @@ -0,0 +1,155 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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. + +*/ + +#pragma once + +enum SQL_CTC_STMT +{ + SQL_CTC_STMT_COUNT = 0, + SQL_CTC_STMT_EXISTS, + SQL_CTC_STMT_NUM +}; + +static char *ctc_stmts[SQL_CTC_STMT_NUM] = +{ + "SELECT count(*) FROM dbrw_contacts;", + "SELECT id FROM dbrw_contacts WHERE id = ? LIMIT 1;" +}; + +enum SQL_EVT_STMT +{ + SQL_EVT_STMT_COUNT = 0, + SQL_EVT_STMT_BLOBSIZE, + SQL_EVT_STMT_GET, + SQL_EVT_STMT_GETFLAGS, + SQL_EVT_STMT_GETCONTACT, + SQL_EVT_STMT_FINDFIRST, + SQL_EVT_STMT_FINDFIRSTUNREAD, + SQL_EVT_STMT_FINDLAST, + SQL_EVT_STMT_FINDNEXT, + SQL_EVT_STMT_FINDPREV, + SQL_EVT_STMT_NUM +}; + +static char *evt_stmts[SQL_EVT_STMT_NUM] = +{ + "SELECT count(*) FROM dbrw_events where contactid = ?;", + "SELECT blobsize FROM dbrw_events where id = ? LIMIT 1;", + "SELECT * FROM dbrw_events where id = ? LIMIT 1;", + "SELECT flags FROM dbrw_events where id = ? LIMIT 1;", + "SELECT contactid FROM dbrw_events where id = ? LIMIT 1;", + "SELECT id FROM dbrw_events where contactid = ? ORDER by id LIMIT 1;", + "SELECT flags, id FROM dbrw_events where contactid = ? ORDER by id;", + "SELECT id FROM dbrw_events where contactid = ? ORDER by id DESC;", + "SELECT id FROM dbrw_events where contactid = ? AND id > ? ORDER by id LIMIT 1;", + "SELECT id FROM dbrw_events where contactid = ? AND id < ? ORDER by id DESC LIMIT 1;" +}; + +enum SQL_SET_STMT +{ + SQL_SET_STMT_READ = 0, + SQL_SET_STMT_ENUM, + SQL_SET_STMT_ENUMMODULES, + SQL_SET_STMT_SETTINGCHECK, + SQL_SET_STMT_NUM +}; + +static char *set_stmts[SQL_SET_STMT_NUM] = +{ + "SELECT type, val FROM dbrw_settings WHERE setting = ? AND module = ? AND id = ? LIMIT 1;", + "SELECT setting from dbrw_settings where id = ? AND module = ? ORDER by setting;", + "SELECT DISTINCT module from dbrw_settings;", + "SELECT count(*) FROM dbrw_settings WHERE setting = ? AND module = ? AND id = ?;", +}; + +struct TSqlMessage { + int op; + sqlite3 *pDb; + sqlite3_stmt *pStmt; + int retCode; + const char *zIn; + HANDLE hDoneEvent; +}; + +struct CDbxSQLite : public MDatabaseCommon, public MZeroedObject +{ +private: + sqlite3 *m_sqlite; + HWND m_hAPCWindow; + + int sql_prepare_len; + char **sql_prepare_text; + sqlite3_stmt ***sql_prepare_stmt; + sqlite3_stmt *ctc_stmts_prep[SQL_CTC_STMT_NUM] = { 0 }; + sqlite3_stmt *evt_stmts_prep[SQL_EVT_STMT_NUM] = { 0 }; + sqlite3_stmt *set_stmts_prep[SQL_SET_STMT_NUM] = { 0 }; + + void sql_prepare_add(char **text, sqlite3_stmt **stmts, int len); + void sql_prepare_statements(); + static void CALLBACK sql_server_sync_apc(DWORD dwParam); + void sql_server_sync(TSqlMessage *msg); + int sql_step(sqlite3_stmt *stmt); + int sql_reset(sqlite3_stmt *stmt); + int sql_exec(sqlite3 *sql, const char *query); + int sql_open(const char *path, sqlite3 **sql); + int sql_close(sqlite3 *sql); + int sql_prepare(sqlite3 *sql, const char *query, sqlite3_stmt **stmt); + int sql_finalize(sqlite3_stmt *stmt); + +public: + CDbxSQLite(); + ~CDbxSQLite(); + + int Open(const wchar_t *profile); + + STDMETHODIMP_(BOOL) IsRelational(void) override { return FALSE; } + STDMETHODIMP_(void) SetCacheSafetyMode(BOOL) override; + + STDMETHODIMP_(LONG) GetContactCount(void) override; + STDMETHODIMP_(LONG) DeleteContact(MCONTACT contactID) override; + STDMETHODIMP_(MCONTACT) AddContact(void) override; + STDMETHODIMP_(BOOL) IsDbContact(MCONTACT contactID) override; + STDMETHODIMP_(LONG) GetContactSize(void) override; + + STDMETHODIMP_(LONG) GetEventCount(MCONTACT contactID) override; + STDMETHODIMP_(MEVENT) AddEvent(MCONTACT contactID, DBEVENTINFO *dbe) override; + STDMETHODIMP_(BOOL) DeleteEvent(MCONTACT contactID, MEVENT hDbEvent) override; + STDMETHODIMP_(LONG) GetBlobSize(MEVENT hDbEvent) override; + STDMETHODIMP_(BOOL) GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbe) override; + STDMETHODIMP_(BOOL) MarkEventRead(MCONTACT contactID, MEVENT hDbEvent) override; + STDMETHODIMP_(MCONTACT) GetEventContact(MEVENT hDbEvent) override; + STDMETHODIMP_(MEVENT) FindFirstEvent(MCONTACT contactID) override; + STDMETHODIMP_(MEVENT) FindFirstUnreadEvent(MCONTACT contactID) override; + STDMETHODIMP_(MEVENT) FindLastEvent(MCONTACT contactID) override; + STDMETHODIMP_(MEVENT) FindNextEvent(MCONTACT contactID, MEVENT hDbEvent) override; + STDMETHODIMP_(MEVENT) FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent) override; + + STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) override; + + STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic) override; + STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) override; + STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) override; + STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) override; + + STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; + STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; +}; diff --git a/plugins/Import/src/dbrw/dbrw.cpp b/plugins/Import/src/dbrw/dbrw.cpp new file mode 100644 index 0000000000..0e43f23d8b --- /dev/null +++ b/plugins/Import/src/dbrw/dbrw.cpp @@ -0,0 +1,107 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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" + +static int dbrw_makeDatabase(const wchar_t*) +{ + return 1; +} + +static int dbrw_grokHeader(const wchar_t *profile) +{ + HANDLE hFile = CreateFile(profile, GENERIC_READ, 0, NULL, OPEN_ALWAYS, 0, NULL); + int rc = 1; + int err = EGROKPRF_CANTREAD; + + if (hFile != INVALID_HANDLE_VALUE) { + BOOL r; + char buf[64]; + DWORD dwRead; + + ZeroMemory(buf, sizeof(buf)); + r = ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL); + CloseHandle(hFile); + if (r && memcmp(buf, DBRW_HEADER_STR, strlen(DBRW_HEADER_STR)) == 0) { + sqlite3 *sqlcheck = NULL; + char *szPath = mir_utf8encodeW(profile); + + rc = sqlite3_open(szPath, &sqlcheck); + free(szPath); + if (rc == SQLITE_OK) { + sqlite3_stmt *stmt; + err = EGROKPRF_UNKHEADER; + + sqlite3_prepare_v2(sqlcheck, "select * from sqlite_master where type = 'table' and name = 'dbrw_core';", -1, &stmt, NULL); + if (sqlite3_step(stmt) == SQLITE_ROW) { + + sqlite3_finalize(stmt); + sqlite3_prepare_v2(sqlcheck, "select val from dbrw_core where setting = 'SchemaVersion';", -1, &stmt, NULL); + if (sqlite3_step(stmt) == SQLITE_ROW) { + int sVersion; + + sVersion = sqlite3_column_int(stmt, 0); + if (sVersion == atoi(DBRW_SCHEMA_VERSION)) + rc = 0; + else { + // TODO: Return as valid and upgrade in + // dbrw_Load() if schema version is upgradable + } + } + } + sqlite3_finalize(stmt); + sqlite3_close(sqlcheck); + } + } + else err = r ? EGROKPRF_UNKHEADER : EGROKPRF_CANTREAD; + } + return rc; +} + +static MIDatabase* dbrw_Load(const wchar_t *profile, BOOL) +{ + CDbxSQLite *db = new CDbxSQLite(); + db->Open(profile); + return db; +} + +static int dbrw_Unload(MIDatabase *db) +{ + delete (CDbxSQLite*)db; + return 0; +} + +static DATABASELINK dblink = +{ + sizeof(DATABASELINK), + "dbrw", + L"dbx SQLite driver", + dbrw_makeDatabase, + dbrw_grokHeader, + dbrw_Load, + dbrw_Unload +}; + +void RegisterDbrw() +{ + RegisterDatabasePlugin(&dblink); +}
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbrw.h b/plugins/Import/src/dbrw/dbrw.h new file mode 100644 index 0000000000..45034fcf3c --- /dev/null +++ b/plugins/Import/src/dbrw/dbrw.h @@ -0,0 +1,30 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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. + +*/ + +#pragma once + +#include <sqlite3.h> + +#define DBRW_SCHEMA_VERSION "2" +#define DBRW_HEADER_STR "SQLite format 3" + +void RegisterDbrw();
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbsettings.cpp b/plugins/Import/src/dbrw/dbsettings.cpp new file mode 100644 index 0000000000..64501078c6 --- /dev/null +++ b/plugins/Import/src/dbrw/dbsettings.cpp @@ -0,0 +1,181 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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_(BOOL) CDbxSQLite::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) +{ + mir_cslockfull lock(m_csDbAccess); + + int res = 0; + while (sql_step(set_stmts_prep[SQL_SET_STMT_ENUMMODULES]) == SQLITE_ROW && !res) { + const char *szModule = (const char *)sqlite3_column_text(set_stmts_prep[SQL_SET_STMT_ENUMMODULES], 0); + lock.unlock(); + res = (pFunc)(szModule, pParam); + lock.lock(); + } + sql_reset(set_stmts_prep[SQL_SET_STMT_ENUMMODULES]); + return res; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic) +{ + if (!szSetting || !szModule) + return 1; + + size_t settingNameLen = strlen(szSetting); + size_t moduleNameLen = strlen(szModule); + + mir_cslock lock(m_csDbAccess); + + char *szCachedSettingName = m_cache->GetCachedSetting(szModule, szSetting, moduleNameLen, settingNameLen); + DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 0); + if (pCachedValue != nullptr) { + if (pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8) { + int cbOrigLen = dbv->cchVal; + char *cbOrigPtr = dbv->pszVal; + memcpy(dbv, pCachedValue, sizeof(DBVARIANT)); + if (isStatic) { + int cbLen = 0; + if (pCachedValue->pszVal != nullptr) + cbLen = (int)strlen(pCachedValue->pszVal); + + cbOrigLen--; + dbv->pszVal = cbOrigPtr; + if (cbLen < cbOrigLen) + cbOrigLen = cbLen; + memcpy(dbv->pszVal, pCachedValue->pszVal, cbOrigLen); + dbv->pszVal[cbOrigLen] = 0; + dbv->cchVal = cbLen; + } + else { + dbv->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal) + 1); + strcpy(dbv->pszVal, pCachedValue->pszVal); + } + } + else memcpy(dbv, pCachedValue, sizeof(DBVARIANT)); + + return (pCachedValue->type == DBVT_DELETED) ? 1 : 0; + } + + // never look db for the resident variable + if (szCachedSettingName[-1] != 0) + return 1; + + sqlite3_bind_text(set_stmts_prep[SQL_SET_STMT_READ], 1, szSetting, -1, SQLITE_STATIC); + sqlite3_bind_text(set_stmts_prep[SQL_SET_STMT_READ], 2, szModule, -1, SQLITE_STATIC); + sqlite3_bind_int(set_stmts_prep[SQL_SET_STMT_READ], 3, contactID); + if (sql_step(set_stmts_prep[SQL_SET_STMT_READ]) != SQLITE_ROW) { + /*if (dbv->type != DBVT_BLOB) { + DBVARIANT* pCachedValue = settings_getCachedValue(contactID, szCachedSettingName, 1); + + if (pCachedValue != NULL) + pCachedValue->type = DBVT_DELETED; + }*/ + sql_reset(set_stmts_prep[SQL_SET_STMT_READ]); + return 1; + } + dbv->type = (int)sqlite3_column_int(set_stmts_prep[SQL_SET_STMT_READ], 0); + switch (dbv->type) { + case DBVT_BYTE: + dbv->bVal = (BYTE)sqlite3_column_int(set_stmts_prep[SQL_SET_STMT_READ], 1); + break; + case DBVT_WORD: + dbv->wVal = (WORD)sqlite3_column_int(set_stmts_prep[SQL_SET_STMT_READ], 1); + break; + case DBVT_DWORD: + dbv->dVal = (DWORD)sqlite3_column_int(set_stmts_prep[SQL_SET_STMT_READ], 1); + break; + case DBVT_UTF8: + case DBVT_ASCIIZ: + { + const char *p = (const char *)sqlite3_column_text(set_stmts_prep[SQL_SET_STMT_READ], 1); + + if (p != NULL) { + size_t len = strlen(p) + 1; + size_t copylen = isStatic ? (len < dbv->cchVal ? len : dbv->cchVal) : len; + if (!isStatic) + dbv->pszVal = (char*)mir_alloc(len); + memmove(dbv->pszVal, p, copylen); + } + else + dbv->pszVal = 0; + break; + } + case DBVT_BLOB: + { + size_t len = sqlite3_column_bytes(set_stmts_prep[SQL_SET_STMT_READ], 1); + + if (len) { + size_t copylen = isStatic ? (len < dbv->cpbVal ? len : dbv->cpbVal) : len; + if (!isStatic) + dbv->pbVal = (BYTE*)mir_alloc(copylen); + memcpy(dbv->pbVal, sqlite3_column_blob(set_stmts_prep[SQL_SET_STMT_READ], 1), copylen); + dbv->cpbVal = (WORD)copylen; + } + else { + dbv = 0; + } + } + } + sql_reset(set_stmts_prep[SQL_SET_STMT_READ]); + // add to cache + if (dbv->type != DBVT_BLOB/* && dbv->type != DBVT_ENCRYPTED*/) { + pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); + if (pCachedValue != nullptr) + m_cache->SetCachedVariant(dbv, pCachedValue); + } + + return 0; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::WriteContactSetting(MCONTACT, DBCONTACTWRITESETTING*) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::DeleteContactSetting(MCONTACT, LPCSTR, LPCSTR) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) +{ + if (szModule == nullptr) + return -1; + + mir_cslockfull lock(m_csDbAccess); + + int res = -1; + sqlite3_bind_int(set_stmts_prep[SQL_SET_STMT_ENUM], 1, hContact); + sqlite3_bind_text(set_stmts_prep[SQL_SET_STMT_ENUM], 2, szModule, -1, SQLITE_STATIC); + while (sql_step(set_stmts_prep[SQL_SET_STMT_ENUM]) == SQLITE_ROW) { + const char *sczSetting = (const char*)sqlite3_column_text(set_stmts_prep[SQL_SET_STMT_ENUM], 0); + if (sczSetting) { + lock.unlock(); + res = (pfnEnumProc)(sczSetting, param); + lock.lock(); + } + } + sql_reset(set_stmts_prep[SQL_SET_STMT_ENUM]); + return res; +}
\ No newline at end of file diff --git a/plugins/Import/src/dbrw/dbsql.cpp b/plugins/Import/src/dbrw/dbsql.cpp new file mode 100644 index 0000000000..4d49471e8e --- /dev/null +++ b/plugins/Import/src/dbrw/dbsql.cpp @@ -0,0 +1,162 @@ +/* + +Import plugin for Miranda NG + +Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org) + +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" + +enum SQL +{ + SQL_STEP, + SQL_RESET, + SQL_EXEC, + SQL_OPEN, + SQL_CLOSE, + SQL_PREPARE, + SQL_FINALIZE +}; + +void CDbxSQLite::sql_prepare_add(char **text, sqlite3_stmt **stmts, int len) +{ + sql_prepare_text = (char**)mir_realloc(sql_prepare_text, (sql_prepare_len + len) * sizeof(char*)); + sql_prepare_stmt = (sqlite3_stmt***)mir_realloc(sql_prepare_stmt, (sql_prepare_len + len) * sizeof(sqlite3_stmt**)); + for (int i = 0; i < len; i++) { + sql_prepare_text[sql_prepare_len + i] = text[i]; + sql_prepare_stmt[sql_prepare_len + i] = &stmts[i]; + } + sql_prepare_len += len; +} + +void CDbxSQLite::sql_prepare_statements() +{ + for (int i = 0; i < sql_prepare_len; i++) + sql_prepare(m_sqlite, sql_prepare_text[i], sql_prepare_stmt[i]); +} + +void CALLBACK CDbxSQLite::sql_server_sync_apc(DWORD dwParam) +{ + TSqlMessage *msg = (TSqlMessage*)dwParam; + + if (!msg) + return; + + switch (msg->op) { + case SQL_STEP: + msg->retCode = sqlite3_step(msg->pStmt); + break; + case SQL_RESET: + msg->retCode = sqlite3_reset(msg->pStmt); + break; + case SQL_EXEC: + msg->retCode = sqlite3_exec(msg->pDb, msg->zIn, NULL, NULL, NULL); + break; + case SQL_OPEN: + msg->retCode = sqlite3_open(msg->zIn, &msg->pDb); + break; + case SQL_CLOSE: + msg->retCode = sqlite3_close(msg->pDb); + break; + case SQL_PREPARE: + msg->retCode = sqlite3_prepare_v2(msg->pDb, msg->zIn, -1, &msg->pStmt, NULL); + break; + case SQL_FINALIZE: + msg->retCode = sqlite3_finalize(msg->pStmt); + break; + default: + return; + } + SetEvent(msg->hDoneEvent); +} + +void CDbxSQLite::sql_server_sync(TSqlMessage *msg) +{ + msg->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + sql_server_sync_apc((DWORD)msg); + PostMessage(m_hAPCWindow, WM_NULL, 0, 0); + WaitForSingleObject(msg->hDoneEvent, INFINITE); + CloseHandle(msg->hDoneEvent); +} + +int CDbxSQLite::sql_step(sqlite3_stmt *stmt) +{ + TSqlMessage msg; + msg.op = SQL_STEP; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} + +int CDbxSQLite::sql_reset(sqlite3_stmt *stmt) +{ + TSqlMessage msg; + msg.op = SQL_RESET; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} + +int CDbxSQLite::sql_exec(sqlite3 *sql, const char *query) +{ + TSqlMessage msg; + msg.op = SQL_EXEC; + msg.pDb = sql; + msg.zIn = query; + sql_server_sync(&msg); + return msg.retCode; +} + +int CDbxSQLite::sql_open(const char *path, sqlite3 **sql) +{ + TSqlMessage msg; + msg.op = SQL_OPEN; + msg.zIn = path; + sql_server_sync(&msg); + *sql = msg.pDb; + return msg.retCode; +} + +int CDbxSQLite::sql_close(sqlite3 *sql) +{ + TSqlMessage msg; + msg.op = SQL_CLOSE; + msg.pDb = sql; + sql_server_sync(&msg); + return msg.retCode; +} + +int CDbxSQLite::sql_prepare(sqlite3 *sql, const char *query, sqlite3_stmt **stmt) +{ + TSqlMessage msg; + msg.op = SQL_PREPARE; + msg.pDb = sql; + msg.zIn = query; + sql_server_sync(&msg); + *stmt = msg.pStmt; + return msg.retCode; +} + +int CDbxSQLite::sql_finalize(sqlite3_stmt *stmt) +{ + TSqlMessage msg; + msg.op = SQL_FINALIZE; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} diff --git a/plugins/Import/src/main.cpp b/plugins/Import/src/main.cpp index 14e7e02b79..151e8509c9 100644 --- a/plugins/Import/src/main.cpp +++ b/plugins/Import/src/main.cpp @@ -134,6 +134,9 @@ extern "C" __declspec(dllexport) int Load(void) icex.dwSize = sizeof(icex);
icex.dwICC = ICC_DATE_CLASSES;
InitCommonControlsEx(&icex);
+
+ RegisterDbrw();
+
return 0;
}
diff --git a/plugins/Import/src/stdafx.h b/plugins/Import/src/stdafx.h index 7c29403b61..d0e0e976ee 100644 --- a/plugins/Import/src/stdafx.h +++ b/plugins/Import/src/stdafx.h @@ -44,6 +44,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "version.h"
#include "resource.h"
+// dbrw
+#include "dbrw\dbrw.h"
+#include "dbrw\dbintf.h"
+
// ** Global constants
#define IMPORT_MODULE "MIMImport" // Module name
|