From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/dbrw/sql.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 plugins/dbrw/sql.c (limited to 'plugins/dbrw/sql.c') diff --git a/plugins/dbrw/sql.c b/plugins/dbrw/sql.c new file mode 100644 index 0000000000..d1f1c14a86 --- /dev/null +++ b/plugins/dbrw/sql.c @@ -0,0 +1,229 @@ +/* +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 char **sql_prepare_text; +static sqlite3_stmt ***sql_prepare_stmt; +static int sql_prepare_len = 0; +static unsigned sqlThreadId; +static HANDLE hSqlThread; +static HWND hAPCWindow = NULL; +static HANDLE hSqlThreadEvent = NULL; + +static unsigned __stdcall sql_threadProc(void *arg); +static DWORD CALLBACK sql_apcproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +enum { + SQL_STMT_BEGIN=0, + SQL_STMT_END, + SQL_STMT_NUM +}; +static char *sql_stmts[SQL_STMT_NUM] = { + "BEGIN TRANSACTION;", + "COMMIT;" +}; +sqlite3_stmt *sql_stmts_prep[SQL_STMT_NUM] = {0}; + +typedef struct TSqlMessage { + int op; + sqlite3 *pDb; + sqlite3_stmt *pStmt; + int retCode; + const char *zIn; + HANDLE hDoneEvent; +} TSqlMessage; + +enum { + SQL_STEP, + SQL_RESET, + SQL_EXEC, + SQL_OPEN, + SQL_CLOSE, + SQL_PREPARE, + SQL_FINALIZE +}; + +void sql_init() { + hSqlThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hSqlThread = (HANDLE)mir_forkthreadex(sql_threadProc, 0, 0, &sqlThreadId); + hAPCWindow = CreateWindowEx(0, _T("STATIC"), NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + SetWindowLongPtr(hAPCWindow, GWLP_WNDPROC, (LONG_PTR)sql_apcproc); + sql_prepare_add(sql_stmts, sql_stmts_prep, SQL_STMT_NUM); +} + +void sql_destroy() { + int i; + + for(i = 0; i < sql_prepare_len; i++) + sql_finalize(*sql_prepare_stmt[i]); + dbrw_free(sql_prepare_text); + dbrw_free(sql_prepare_stmt); + SetEvent(hSqlThreadEvent); // kill off the sql thread + CloseHandle(hSqlThread); + DestroyWindow(hAPCWindow); +} + +void sql_prepare_add(char **text, sqlite3_stmt **stmts, int len) { + int i; + + sql_prepare_text = (char**)dbrw_realloc(sql_prepare_text, (sql_prepare_len+len)*sizeof(char*)); + sql_prepare_stmt = (sqlite3_stmt***)dbrw_realloc(sql_prepare_stmt, (sql_prepare_len+len)*sizeof(sqlite3_stmt**)); + for (i=0; iop) { + 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: + log1("Invalid op code in sql server (msg->op=%d)", msg->op); + return; + } + SetEvent(msg->hDoneEvent); +} + +static void sql_server_sync(TSqlMessage *msg) { + msg->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + sql_server_sync_apc((DWORD)msg); + PostMessage(hAPCWindow, WM_NULL, 0, 0); + WaitForSingleObject(msg->hDoneEvent, INFINITE); + CloseHandle(msg->hDoneEvent); +} + +int sql_step(sqlite3_stmt *stmt) { + TSqlMessage msg; + msg.op = SQL_STEP; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} + +int sql_reset(sqlite3_stmt *stmt) { + TSqlMessage msg; + msg.op = SQL_RESET; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} + +int 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 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 sql_close(sqlite3 *sql) { + TSqlMessage msg; + msg.op = SQL_CLOSE; + msg.pDb = sql; + sql_server_sync(&msg); + return msg.retCode; +} + +int 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 sql_finalize(sqlite3_stmt *stmt) { + TSqlMessage msg; + msg.op = SQL_FINALIZE; + msg.pStmt = stmt; + sql_server_sync(&msg); + return msg.retCode; +} + -- cgit v1.2.3