summaryrefslogtreecommitdiff
path: root/plugins/Dbrw/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbrw/events.c')
-rw-r--r--plugins/Dbrw/events.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/plugins/Dbrw/events.c b/plugins/Dbrw/events.c
new file mode 100644
index 0000000000..8b494a10b1
--- /dev/null
+++ b/plugins/Dbrw/events.c
@@ -0,0 +1,461 @@
+/*
+dbRW
+
+Copyright (c) 2005-2009 Robert Rainwater
+
+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 "dbrw.h"
+
+static CRITICAL_SECTION csEventsDb;
+static HANDLE hEventsThread = 0, hEventsEvent = 0, hHeap;
+static SortedList sModuleNames;
+
+static int events_cmpModuleNames(void *p1, void *p2);
+static unsigned __stdcall events_timerProcThread(void *arg);
+
+typedef struct {
+ char *name;
+ DWORD nameHash;
+} DBCachedModuleName;
+
+enum {
+ SQL_EVT_STMT_COUNT=0,
+ SQL_EVT_STMT_ADD,
+ SQL_EVT_STMT_DELETE,
+ SQL_EVT_STMT_BLOBSIZE,
+ SQL_EVT_STMT_BLOBSIZE_CACHE,
+ SQL_EVT_STMT_GET,
+ SQL_EVT_STMT_GET_CACHE,
+ SQL_EVT_STMT_GETFLAGS,
+ SQL_EVT_STMT_SETFLAGS,
+ SQL_EVT_STMT_GETCONTACT,
+ SQL_EVT_STMT_GETCONTACT_CACHE,
+ SQL_EVT_STMT_FINDFIRST,
+ SQL_EVT_STMT_FINDFIRSTUNREAD,
+ SQL_EVT_STMT_FINDLAST,
+ SQL_EVT_STMT_FINDNEXT,
+ SQL_EVT_STMT_FINDPREV,
+ SQL_EVT_STMT_CREATETEMPTABLE,
+ SQL_EVT_STMT_DROPTEMPTABLE,
+ SQL_EVT_STMT_DELETECONTACT,
+ SQL_EVT_STMT_NUM
+};
+static char *evt_stmts[SQL_EVT_STMT_NUM] = {
+ "SELECT count(*) FROM dbrw_events where contactid = ?;",
+ "INSERT INTO dbrw_events VALUES(NULL,?,?,?,?,?,?,?,?);",
+ "DELETE FROM dbrw_events where id = ? AND contactid = ?;",
+ "SELECT blobsize FROM dbrw_events where id = ? LIMIT 1;",
+ "SELECT blobsize FROM temp_dbrw_events where id = ? LIMIT 1;",
+ "SELECT * FROM dbrw_events where id = ? LIMIT 1;",
+ "SELECT * FROM temp_dbrw_events where id = ? LIMIT 1;",
+ "SELECT flags FROM dbrw_events where id = ? LIMIT 1;",
+ "UPDATE dbrw_events SET flags = ? WHERE id = ?;",
+ "SELECT contactid FROM dbrw_events where id = ? LIMIT 1;",
+ "SELECT contactid FROM temp_dbrw_events where id = ? LIMIT 1;",
+ "SELECT id FROM dbrw_events where contactid = ? ORDER by id;",
+ "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;",
+ "create temp table temp_dbrw_events (id integer primary key,eventtime integer,flags integer,eventtype integer, blob any, blobsize integer, contactid integer,modulename varchar(255),inserttime integer);"
+ "create temp trigger insert_new_temp_event1 after insert on dbrw_events begin replace into temp_dbrw_events values(new.id,new.eventtime,new.flags,new.eventtype,new.blob,new.blobsize,new.contactid,new.modulename,new.inserttime); end;"
+ "create temp trigger insert_new_temp_event2 after update on dbrw_events begin replace into temp_dbrw_events values(new.id,new.eventtime,new.flags,new.eventtype,new.blob,new.blobsize,new.contactid,new.modulename,new.inserttime); end;"
+ "create temp trigger delete_temp_event after delete on dbrw_events begin delete from temp_dbrw_events where id=old.id and contactid=old.id; end;",
+ "drop trigger insert_new_temp_event1;"
+ "drop trigger insert_new_temp_event2;"
+ "drop trigger delete_temp_event;"
+ "drop table temp_dbrw_events;",
+ "DELETE FROM dbrw_events WHERE contactid = ?;"
+};
+static sqlite3_stmt *evt_stmts_prep[SQL_EVT_STMT_NUM] = {0};
+
+void events_init() {
+ InitializeCriticalSection(&csEventsDb);
+ hHeap = HeapCreate(0, 0, 0);
+ ZeroMemory(&sModuleNames, sizeof(sModuleNames));
+ sModuleNames.increment = 100;
+ sModuleNames.sortFunc = events_cmpModuleNames;
+ sql_prepare_add(evt_stmts, evt_stmts_prep, SQL_EVT_STMT_NUM);
+ sql_exec(g_sqlite, "BEGIN TRANSACTION;");
+ sql_exec(g_sqlite, "create temp table temp_dbrw_events (id integer primary key,eventtime integer,flags integer,eventtype integer, blob any, blobsize integer, contactid integer,modulename varchar(255),inserttime integer);"
+ "create temp trigger insert_new_temp_event1 after insert on dbrw_events begin replace into temp_dbrw_events values(new.id,new.eventtime,new.flags,new.eventtype,new.blob,new.blobsize,new.contactid,new.modulename,new.inserttime); end;"
+ "create temp trigger insert_new_temp_event2 after update on dbrw_events begin replace into temp_dbrw_events values(new.id,new.eventtime,new.flags,new.eventtype,new.blob,new.blobsize,new.contactid,new.modulename,new.inserttime); end;"
+ "create temp trigger delete_temp_event after delete on dbrw_events begin delete from temp_dbrw_events where id=old.id and contactid=old.id; end;");
+ sql_exec(g_sqlite, "COMMIT;");
+ hEventsEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ hEventsThread = (HANDLE)mir_forkthreadex(events_timerProcThread, 0, 0, 0);
+}
+
+void events_destroy() {
+ if (hEventsEvent) {
+ SetEvent(hEventsEvent);
+ WaitForSingleObjectEx(hEventsThread, INFINITE, FALSE);
+ CloseHandle(hEventsThread);
+ }
+ HeapDestroy(hHeap);
+ li.List_Destroy(&sModuleNames);
+ DeleteCriticalSection(&csEventsDb);
+}
+
+static int events_cmpModuleNames(void *p1, void *p2) {
+ DBCachedModuleName *v1 = (DBCachedModuleName*)p1;
+ DBCachedModuleName *v2 = (DBCachedModuleName*)p2;
+
+ if (v1->nameHash!=v2->nameHash)
+ return v1->nameHash-v2->nameHash;
+ return strcmp(v1->name, v2->name);
+}
+
+static char *events_moduleCacheAdd(char *szModule) {
+ if (!szModule)
+ return 0;
+ {
+ int idx = 0;
+ size_t nameLen;
+ DBCachedModuleName Vtemp, *V;
+
+ Vtemp.name = szModule;
+ Vtemp.nameHash = utils_hashString(szModule);
+ if (li.List_GetIndex(&sModuleNames, &Vtemp, &idx)) {
+ V = (DBCachedModuleName*)sModuleNames.items[idx];
+ return V->name;
+ }
+ V = (DBCachedModuleName*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedModuleName));
+ nameLen = strlen(szModule)+1;
+ V->name = (char*)HeapAlloc(hHeap, 0, nameLen);
+ mir_snprintf(V->name, nameLen, "%s", szModule);
+ V->nameHash = utils_hashString(szModule);
+ li.List_Insert(&sModuleNames, V, idx);
+ return V->name;
+ }
+}
+
+static unsigned __stdcall events_timerProcThread(void *arg) {
+ DWORD dwWait;
+
+ for(;;) {
+ dwWait = WaitForSingleObjectEx(hEventsEvent, DBRW_EVENTS_FLUSHCACHE, TRUE);
+
+ if (dwWait==WAIT_OBJECT_0)
+ break;
+ else if(dwWait == WAIT_TIMEOUT) {
+ EnterCriticalSection(&csEventsDb);
+ sql_stmt_begin();
+ sql_step(evt_stmts_prep[SQL_EVT_STMT_DROPTEMPTABLE]);
+ sql_step(evt_stmts_prep[SQL_EVT_STMT_CREATETEMPTABLE]);
+ sql_stmt_end();
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_DROPTEMPTABLE]);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_CREATETEMPTABLE]);
+ LeaveCriticalSection(&csEventsDb);
+ }
+ else if (dwWait == WAIT_IO_COMPLETION)
+ if (Miranda_Terminated())
+ break;
+ }
+ CloseHandle(hEventsEvent);
+ hEventsEvent = NULL;
+ return 0;
+}
+
+INT_PTR events_getCount(WPARAM wParam, LPARAM lParam) {
+ int rc = 0;
+
+ EnterCriticalSection(&csEventsDb);
+ if (!contacts_isContact(wParam, 0)) {
+ LeaveCriticalSection(&csEventsDb);
+ return -1;
+ }
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_COUNT], 1, (int)wParam);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_COUNT])==SQLITE_ROW)
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_COUNT], 0);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_COUNT]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_add(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ DBEVENTINFO *dbei = (DBEVENTINFO*)lParam;
+ int rc = 0;
+
+ if (dbei==NULL||
+ dbei->cbSize!=sizeof(DBEVENTINFO)||
+ dbei->timestamp==0||
+ NotifyEventHooks(hEventFilterAddedEvent, wParam, lParam)) {
+ log1("Attempt to add invalid event for contact(%d)", (int)hContact);
+ return 0;
+ }
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 1, (int)dbei->timestamp);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 2, (int)dbei->flags);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 3, (int)dbei->eventType);
+ sqlite3_bind_blob(evt_stmts_prep[SQL_EVT_STMT_ADD], 4, dbei->pBlob, (int)dbei->cbBlob, SQLITE_STATIC);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 5, (int)dbei->cbBlob);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 6, (int)hContact);
+ sqlite3_bind_text(evt_stmts_prep[SQL_EVT_STMT_ADD], 7, dbei->szModule?dbei->szModule:NULL, -1, SQLITE_STATIC);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_ADD], 8, time(NULL));
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_ADD])==SQLITE_DONE) {
+ rc = (int)sqlite3_last_insert_rowid(g_sqlite);
+ }
+ else {
+ log2("Error adding event(#%d,%s)", sqlite3_errcode(g_sqlite), sqlite3_errmsg(g_sqlite));
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_ADD]);
+ LeaveCriticalSection(&csEventsDb);
+ if (rc) {
+ NotifyEventHooks(hEventAddedEvent,wParam,(LPARAM)rc);
+ }
+ return rc;
+}
+
+INT_PTR events_delete(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam, hContactFind;
+ HANDLE hDbEvent = (HANDLE)lParam;
+ int rc = 1;
+
+ hContactFind = (HANDLE)events_getContact((WPARAM)hDbEvent, 0);
+ if ((int)hContactFind==-1||hContact!=hContactFind)
+ return rc;
+ NotifyEventHooks(hEventDeletedEvent, wParam, lParam);
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_DELETE], 1, (int)hDbEvent);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_DELETE], 2, (int)hContact);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_DELETE])==SQLITE_DONE) {
+ log1("Deleted event(%d)", (int)hDbEvent);
+ rc = 0;
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_DELETE]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+static int events_getBlobSizeConditional(HANDLE hDbEvent, int cache) {
+ int rc = -1;
+ sqlite3_stmt* stmt;
+
+ EnterCriticalSection(&csEventsDb);
+ stmt = cache?evt_stmts_prep[SQL_EVT_STMT_BLOBSIZE_CACHE]:evt_stmts_prep[SQL_EVT_STMT_BLOBSIZE];
+ sqlite3_bind_int(stmt, 1, (int)hDbEvent);
+ if (sql_step(stmt)==SQLITE_ROW)
+ rc = sqlite3_column_int(stmt, 0);
+ sql_reset(stmt);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_getBlobSize(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)wParam;
+ int rc = events_getBlobSizeConditional(hDbEvent, 1);
+
+ if (rc!=-1)
+ return rc;
+ return events_getBlobSizeConditional(hDbEvent, 0);;
+}
+
+static int events_getConditional(HANDLE hDbEvent, DBEVENTINFO *dbei, int cache) {
+ int rc = 1;
+ sqlite3_stmt* stmt;
+
+ if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO))
+ return 1;
+ if(dbei->cbBlob>0&&dbei->pBlob==NULL) {
+ dbei->cbBlob = 0;
+ return 1;
+ }
+ EnterCriticalSection(&csEventsDb);
+ stmt = cache?evt_stmts_prep[SQL_EVT_STMT_GET_CACHE]:evt_stmts_prep[SQL_EVT_STMT_GET];
+ sqlite3_bind_int(stmt, 1, (int)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 = events_moduleCacheAdd((char*)sqlite3_column_text(stmt, 7));
+ copySize = size<dbei->cbBlob ? size : dbei->cbBlob;
+ CopyMemory(dbei->pBlob, blob, copySize);
+ dbei->cbBlob = copySize;
+ rc = 0;
+ }
+ sql_reset(stmt);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_get(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)wParam;
+ DBEVENTINFO *dbei = (DBEVENTINFO*)lParam;
+ int rc = events_getConditional(hDbEvent, dbei, 1);
+
+ if (!rc)
+ return 0;
+ return events_getConditional(hDbEvent, dbei, 0);
+}
+
+INT_PTR events_markRead(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)lParam;
+ int rc = -1;
+
+ EnterCriticalSection(&csEventsDb);
+ sql_stmt_begin();
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_GETFLAGS], 1, (int)hDbEvent);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_GETFLAGS])==SQLITE_ROW) {
+ DWORD flags = (DWORD)sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_GETFLAGS], 0);
+
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_GETFLAGS]);
+ rc = flags;
+ if (!(flags&DBEF_READ)) {
+ flags|=DBEF_READ;
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_SETFLAGS], 1, (int)flags);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_SETFLAGS], 2, (int)hDbEvent);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_SETFLAGS])!=SQLITE_DONE) {
+ rc = -1;
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_SETFLAGS]);
+ }
+ }
+ else sql_reset(evt_stmts_prep[SQL_EVT_STMT_GETFLAGS]);
+ sql_stmt_end();
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+static int events_getContactConditional(HANDLE hDbEvent, int cache) {
+ int rc = -1;
+ sqlite3_stmt* stmt;
+
+ EnterCriticalSection(&csEventsDb);
+ stmt = cache?evt_stmts_prep[SQL_EVT_STMT_GETCONTACT_CACHE]:evt_stmts_prep[SQL_EVT_STMT_GETCONTACT];
+ sqlite3_bind_int(stmt, 1, (int)hDbEvent);
+ if (sql_step(stmt)==SQLITE_ROW)
+ rc = sqlite3_column_int(stmt, 0);
+ sql_reset(stmt);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_getContact(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)wParam;
+ int rc = events_getContactConditional(hDbEvent, 1);
+
+ if (rc!=-1)
+ return rc;
+ return events_getContactConditional(hDbEvent, 0);
+}
+
+INT_PTR events_findFirst(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ int rc = 0;
+
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST], 1, (int)hContact);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST])==SQLITE_ROW) {
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST], 0);
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRST]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_findFirstUnread(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ int rc = 0;
+ DWORD flags = 0;
+
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD], 1, (int)hContact);
+ 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))) {
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD], 1);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+ }
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDFIRSTUNREAD]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_findLast(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ int rc = 0;
+
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDLAST], 1, (int)hContact);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDLAST])==SQLITE_ROW)
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDLAST], 0);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDLAST]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_findNext(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)wParam;
+ int hContact = -1, rc = 0;
+
+ if (hDbEvent==NULL) {
+ return 0;
+ }
+ hContact = events_getContact(wParam, 0);
+ if (hContact==-1)
+ return 0;
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 1, hContact);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 2, (int)hDbEvent);
+ if (sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT])==SQLITE_ROW)
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT], 0);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDNEXT]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+INT_PTR events_findPrev(WPARAM wParam, LPARAM lParam) {
+ HANDLE hDbEvent = (HANDLE)wParam;
+ int hContact = -1, rc = 0;
+
+ if (hDbEvent==NULL) {
+ return 0;
+ }
+ hContact = events_getContact(wParam, 0);
+ if (hContact==-1) {
+ return 0;
+ }
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 1, hContact);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 2, (int)hDbEvent);
+ rc = sql_step(evt_stmts_prep[SQL_EVT_STMT_FINDPREV]);
+ if (rc==SQLITE_ROW) {
+ rc = sqlite3_column_int(evt_stmts_prep[SQL_EVT_STMT_FINDPREV], 0);
+ }
+ else {
+ rc = 0;
+ }
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_FINDPREV]);
+ LeaveCriticalSection(&csEventsDb);
+ return rc;
+}
+
+void events_deleteContactData(HANDLE hContact) {
+ EnterCriticalSection(&csEventsDb);
+ sqlite3_bind_int(evt_stmts_prep[SQL_EVT_STMT_DELETECONTACT], 1, (int)hContact);
+ sql_step(evt_stmts_prep[SQL_EVT_STMT_DELETECONTACT]);
+ sql_reset(evt_stmts_prep[SQL_EVT_STMT_DELETECONTACT]);
+ LeaveCriticalSection(&csEventsDb);
+}