Skip to content

Commit 7f29a3e

Browse files
committed
Query abort via command bar button or Ctrl+C during execute using sqlite_progress_handler and a progress callback message pump that keeps the UI active during execution
1 parent c91062d commit 7f29a3e

4 files changed

Lines changed: 57 additions & 8 deletions

File tree

src/sqlite-ce-edit/execute.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@
44

55
#include "globals.h"
66

7+
/*============================================================================
8+
** Progress callback for query abort
9+
**============================================================================*/
10+
11+
static int ProgressCallback(void *arg) {
12+
MSG msg;
13+
(void)arg;
14+
/* Process pending messages to keep UI responsive */
15+
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
16+
/* Check for Ctrl+C to abort */
17+
if (msg.message == WM_KEYDOWN && msg.wParam == 'C' &&
18+
GetKeyState(VK_CONTROL) < 0) {
19+
g_abortQuery = 1;
20+
}
21+
TranslateMessage(&msg);
22+
DispatchMessage(&msg);
23+
}
24+
return g_abortQuery;
25+
}
26+
727
/*============================================================================
828
** Query Execution State
929
**============================================================================*/
@@ -163,9 +183,11 @@ void ExecuteQuery(void) {
163183
return;
164184
}
165185

166-
/* Disable Execute while running */
186+
/* Disable Execute while running, enable Stop */
167187
EnableMenuItem(g_hMenu, IDM_EXECUTE, MF_GRAYED);
168188
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_EXECUTE, FALSE);
189+
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_STOP, TRUE);
190+
g_abortQuery = 0;
169191
UpdateWindow(g_hwndCB);
170192

171193
/* Check for selection */
@@ -286,6 +308,9 @@ void ExecuteQuery(void) {
286308
g_nCols = 0;
287309
g_totalRows = 0;
288310

311+
/* Install progress handler for abort support */
312+
sqlite_progress_handler(g_db, 1000, ProgressCallback, NULL);
313+
289314
SetStatusResult(L"Executing...");
290315
SendMessageW(g_hwndStatus, SB_SETTEXTW, 1, (LPARAM)L"Executing...");
291316
UpdateWindow(g_hwndStatus);
@@ -317,7 +342,11 @@ void ExecuteQuery(void) {
317342
p[1] = '\0';
318343
rc = sqlite_exec(g_db, stmt, QueryCallback, NULL, &errmsg);
319344
p[1] = saved;
320-
if (rc != SQLITE_OK) {
345+
if (rc == SQLITE_INTERRUPT) {
346+
OutputLine("Query aborted by user.");
347+
if (errmsg) sqlite_freemem(errmsg);
348+
hadError = 1;
349+
} else if (rc != SQLITE_OK) {
321350
int ln = 1, i;
322351
char lb[16]; char *lp = lb + 14;
323352
const char *es = errmsg ? errmsg : sqlite_error_string(rc);
@@ -353,7 +382,11 @@ void ExecuteQuery(void) {
353382
/* Execute any remaining statement (no trailing semicolon) */
354383
if (!hadError && *stmt) {
355384
rc = sqlite_exec(g_db, stmt, QueryCallback, NULL, &errmsg);
356-
if (rc != SQLITE_OK) {
385+
if (rc == SQLITE_INTERRUPT) {
386+
OutputLine("Query aborted by user.");
387+
if (errmsg) sqlite_freemem(errmsg);
388+
hadError = 1;
389+
} else if (rc != SQLITE_OK) {
357390
int ln = 1, i;
358391
char lb[16]; char *lp = lb + 14;
359392
const char *es = errmsg ? errmsg : sqlite_error_string(rc);
@@ -382,7 +415,11 @@ void ExecuteQuery(void) {
382415

383416
elapsed = GetTickCount() - startTick;
384417

385-
if (hadError) {
418+
if (g_abortQuery) {
419+
/* Query was aborted by user */
420+
SendMessageW(g_hwndStatus, SB_SETTEXTW, 1, (LPARAM)L"Aborted");
421+
SetStatusResult(L"Aborted");
422+
} else if (hadError) {
386423
/* Position cursor at the errored statement */
387424
int adjOffset = errorOffset;
388425
int lineNum = 1;
@@ -419,9 +456,11 @@ void ExecuteQuery(void) {
419456
FlushOutput();
420457
UpdateDbSize();
421458

422-
/* Re-enable Execute */
459+
/* Remove progress handler and re-enable Execute, disable Stop */
460+
sqlite_progress_handler(g_db, 0, NULL, NULL);
423461
EnableMenuItem(g_hMenu, IDM_EXECUTE, MF_ENABLED);
424462
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_EXECUTE, TRUE);
463+
SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_STOP, FALSE);
425464

426465
/* Switch to results view (unless error - stay in query to show cursor) */
427466
if (!hadError) {

src/sqlite-ce-edit/globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int g_viewMode = 0;
4343
int g_showingHint = 0;
4444
int g_suppressLineCount = 0;
4545
int g_execAtCursor = 0;
46+
int g_abortQuery = 0;
4647
wchar_t g_lastResultStatus[64] = L"";
4748
wchar_t g_findText[128] = L"";
4849
int g_searchMode = 0;

src/sqlite-ce-edit/globals.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ BOOL WINAPI GetSaveFileNameW(CE_OPENFILENAME*);
6565
** Version
6666
**============================================================================*/
6767

68-
#define SQLITECEDIT_VERSION L"0.4.0"
68+
#define SQLITECEDIT_VERSION L"0.5.0"
6969

7070
/*============================================================================
7171
** Menu IDs
@@ -86,6 +86,7 @@ BOOL WINAPI GetSaveFileNameW(CE_OPENFILENAME*);
8686
#define IDM_FINDNEXT 203
8787
#define IDM_EXECATCURSOR 204
8888
#define IDM_EXECATCURSOR_PLACEHOLDER 205
89+
#define IDM_STOP 206
8990
#define IDM_CLEAR 301
9091
#define IDM_VIEWQUERY 401
9192
#define IDM_VIEWRESULT 402
@@ -160,6 +161,7 @@ extern int g_viewMode;
160161
extern int g_showingHint;
161162
extern int g_suppressLineCount;
162163
extern int g_execAtCursor;
164+
extern int g_abortQuery;
163165
extern wchar_t g_lastResultStatus[64];
164166
extern wchar_t g_findText[128];
165167
extern int g_searchMode;

src/sqlite-ce-edit/main.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
1919
RECT rc;
2020
int cbHeight;
2121
HMENU hMenu, hFile, hQuery;
22-
TBBUTTON tbButtons[13];
22+
TBBUTTON tbButtons[14];
2323

2424
g_hBrushWhite = CreateSolidBrush(RGB(255, 255, 255));
2525

@@ -135,7 +135,12 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
135135
tbButtons[12].fsState = TBSTATE_ENABLED;
136136
tbButtons[12].fsStyle = TBSTYLE_BUTTON;
137137

138-
CommandBar_AddButtons(g_hwndCB, 13, tbButtons);
138+
tbButtons[13].iBitmap = TB_STOP;
139+
tbButtons[13].idCommand = IDM_STOP;
140+
tbButtons[13].fsState = 0;
141+
tbButtons[13].fsStyle = TBSTYLE_BUTTON;
142+
143+
CommandBar_AddButtons(g_hwndCB, 14, tbButtons);
139144

140145
CommandBar_AddAdornments(g_hwndCB, 0, 0);
141146
cbHeight = CommandBar_Height(g_hwndCB);
@@ -230,6 +235,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
230235
case IDM_IMPORTCEDB: DoImportCEDB(); break;
231236
case IDM_EXIT: SendMessage(hwnd, WM_CLOSE, 0, 0); break;
232237
case IDM_EXECUTE: ExecuteQuery(); break;
238+
case IDM_STOP: g_abortQuery = 1; break;
233239
case IDM_EXECATCURSOR:
234240
g_execAtCursor = !g_execAtCursor;
235241
SendMessage(g_hwndCB, TB_CHECKBUTTON, IDM_EXECATCURSOR, g_execAtCursor);
@@ -298,6 +304,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
298304
if (GetKeyState(VK_CONTROL) < 0) {
299305
if (wParam == 'O') { DoOpenQuery(); return 0; }
300306
if (wParam == 'N') { DoFileNew(); return 0; }
307+
if (wParam == 'C') { g_abortQuery = 1; return 0; }
301308
}
302309
if (wParam == VK_F5) { ExecuteQuery(); return 0; }
303310
if (wParam == VK_RETURN || wParam == VK_UP ||

0 commit comments

Comments
 (0)