|
4 | 4 |
|
5 | 5 | #include "globals.h" |
6 | 6 |
|
| 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 | + |
7 | 27 | /*============================================================================ |
8 | 28 | ** Query Execution State |
9 | 29 | **============================================================================*/ |
@@ -163,9 +183,11 @@ void ExecuteQuery(void) { |
163 | 183 | return; |
164 | 184 | } |
165 | 185 |
|
166 | | - /* Disable Execute while running */ |
| 186 | + /* Disable Execute while running, enable Stop */ |
167 | 187 | EnableMenuItem(g_hMenu, IDM_EXECUTE, MF_GRAYED); |
168 | 188 | SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_EXECUTE, FALSE); |
| 189 | + SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_STOP, TRUE); |
| 190 | + g_abortQuery = 0; |
169 | 191 | UpdateWindow(g_hwndCB); |
170 | 192 |
|
171 | 193 | /* Check for selection */ |
@@ -286,6 +308,9 @@ void ExecuteQuery(void) { |
286 | 308 | g_nCols = 0; |
287 | 309 | g_totalRows = 0; |
288 | 310 |
|
| 311 | + /* Install progress handler for abort support */ |
| 312 | + sqlite_progress_handler(g_db, 1000, ProgressCallback, NULL); |
| 313 | + |
289 | 314 | SetStatusResult(L"Executing..."); |
290 | 315 | SendMessageW(g_hwndStatus, SB_SETTEXTW, 1, (LPARAM)L"Executing..."); |
291 | 316 | UpdateWindow(g_hwndStatus); |
@@ -317,7 +342,11 @@ void ExecuteQuery(void) { |
317 | 342 | p[1] = '\0'; |
318 | 343 | rc = sqlite_exec(g_db, stmt, QueryCallback, NULL, &errmsg); |
319 | 344 | 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) { |
321 | 350 | int ln = 1, i; |
322 | 351 | char lb[16]; char *lp = lb + 14; |
323 | 352 | const char *es = errmsg ? errmsg : sqlite_error_string(rc); |
@@ -353,7 +382,11 @@ void ExecuteQuery(void) { |
353 | 382 | /* Execute any remaining statement (no trailing semicolon) */ |
354 | 383 | if (!hadError && *stmt) { |
355 | 384 | 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) { |
357 | 390 | int ln = 1, i; |
358 | 391 | char lb[16]; char *lp = lb + 14; |
359 | 392 | const char *es = errmsg ? errmsg : sqlite_error_string(rc); |
@@ -382,7 +415,11 @@ void ExecuteQuery(void) { |
382 | 415 |
|
383 | 416 | elapsed = GetTickCount() - startTick; |
384 | 417 |
|
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) { |
386 | 423 | /* Position cursor at the errored statement */ |
387 | 424 | int adjOffset = errorOffset; |
388 | 425 | int lineNum = 1; |
@@ -419,9 +456,11 @@ void ExecuteQuery(void) { |
419 | 456 | FlushOutput(); |
420 | 457 | UpdateDbSize(); |
421 | 458 |
|
422 | | - /* Re-enable Execute */ |
| 459 | + /* Remove progress handler and re-enable Execute, disable Stop */ |
| 460 | + sqlite_progress_handler(g_db, 0, NULL, NULL); |
423 | 461 | EnableMenuItem(g_hMenu, IDM_EXECUTE, MF_ENABLED); |
424 | 462 | SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_EXECUTE, TRUE); |
| 463 | + SendMessage(g_hwndCB, TB_ENABLEBUTTON, IDM_STOP, FALSE); |
425 | 464 |
|
426 | 465 | /* Switch to results view (unless error - stay in query to show cursor) */ |
427 | 466 | if (!hadError) { |
|
0 commit comments