diff options
| author | Gregory Heytings | 2022-10-30 17:00:35 +0100 |
|---|---|---|
| committer | Gregory Heytings | 2022-10-30 17:00:35 +0100 |
| commit | aef803d6c3d61004f15d0bc82fa7bf9952302312 (patch) | |
| tree | 087c444f788cda27006ddc066ad430f62f5ac02a /src/sqlite.c | |
| parent | 3bf19c417fd39766ee9c7a793c9faadd3bd88478 (diff) | |
| parent | 3fa4cca3d244f51e471e7779c934278731fc21e9 (diff) | |
| download | emacs-aef803d6c3d61004f15d0bc82fa7bf9952302312.tar.gz emacs-aef803d6c3d61004f15d0bc82fa7bf9952302312.zip | |
Merge master into feature/improved-locked-narrowing.
Diffstat (limited to 'src/sqlite.c')
| -rw-r--r-- | src/sqlite.c | 219 |
1 files changed, 127 insertions, 92 deletions
diff --git a/src/sqlite.c b/src/sqlite.c index 54bfb7b6c61..08bf696b8ca 100644 --- a/src/sqlite.c +++ b/src/sqlite.c | |||
| @@ -50,7 +50,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int64, | |||
| 50 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double)); | 50 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double)); |
| 51 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int)); | 51 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int)); |
| 52 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int)); | 52 | DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int)); |
| 53 | DEF_DLL_FN (SQLITE_API int, sqlite3_extended_errcode, (sqlite3*)); | ||
| 53 | DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*)); | 54 | DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*)); |
| 55 | DEF_DLL_FN (SQLITE_API const char*, sqlite3_errstr, (int)); | ||
| 54 | DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*)); | 56 | DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*)); |
| 55 | DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*)); | 57 | DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*)); |
| 56 | DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*)); | 58 | DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*)); |
| @@ -87,7 +89,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, | |||
| 87 | # undef sqlite3_bind_double | 89 | # undef sqlite3_bind_double |
| 88 | # undef sqlite3_bind_null | 90 | # undef sqlite3_bind_null |
| 89 | # undef sqlite3_bind_int | 91 | # undef sqlite3_bind_int |
| 92 | # undef sqlite3_extended_errcode | ||
| 90 | # undef sqlite3_errmsg | 93 | # undef sqlite3_errmsg |
| 94 | # undef sqlite3_errstr | ||
| 91 | # undef sqlite3_step | 95 | # undef sqlite3_step |
| 92 | # undef sqlite3_changes | 96 | # undef sqlite3_changes |
| 93 | # undef sqlite3_column_count | 97 | # undef sqlite3_column_count |
| @@ -111,7 +115,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, | |||
| 111 | # define sqlite3_bind_double fn_sqlite3_bind_double | 115 | # define sqlite3_bind_double fn_sqlite3_bind_double |
| 112 | # define sqlite3_bind_null fn_sqlite3_bind_null | 116 | # define sqlite3_bind_null fn_sqlite3_bind_null |
| 113 | # define sqlite3_bind_int fn_sqlite3_bind_int | 117 | # define sqlite3_bind_int fn_sqlite3_bind_int |
| 118 | # define sqlite3_extended_errcode fn_sqlite3_extended_errcode | ||
| 114 | # define sqlite3_errmsg fn_sqlite3_errmsg | 119 | # define sqlite3_errmsg fn_sqlite3_errmsg |
| 120 | # define sqlite3_errstr fn_sqlite3_errstr | ||
| 115 | # define sqlite3_step fn_sqlite3_step | 121 | # define sqlite3_step fn_sqlite3_step |
| 116 | # define sqlite3_changes fn_sqlite3_changes | 122 | # define sqlite3_changes fn_sqlite3_changes |
| 117 | # define sqlite3_column_count fn_sqlite3_column_count | 123 | # define sqlite3_column_count fn_sqlite3_column_count |
| @@ -138,7 +144,9 @@ load_dll_functions (HMODULE library) | |||
| 138 | LOAD_DLL_FN (library, sqlite3_bind_double); | 144 | LOAD_DLL_FN (library, sqlite3_bind_double); |
| 139 | LOAD_DLL_FN (library, sqlite3_bind_null); | 145 | LOAD_DLL_FN (library, sqlite3_bind_null); |
| 140 | LOAD_DLL_FN (library, sqlite3_bind_int); | 146 | LOAD_DLL_FN (library, sqlite3_bind_int); |
| 147 | LOAD_DLL_FN (library, sqlite3_extended_errcode); | ||
| 141 | LOAD_DLL_FN (library, sqlite3_errmsg); | 148 | LOAD_DLL_FN (library, sqlite3_errmsg); |
| 149 | LOAD_DLL_FN (library, sqlite3_errstr); | ||
| 142 | LOAD_DLL_FN (library, sqlite3_step); | 150 | LOAD_DLL_FN (library, sqlite3_step); |
| 143 | LOAD_DLL_FN (library, sqlite3_changes); | 151 | LOAD_DLL_FN (library, sqlite3_changes); |
| 144 | LOAD_DLL_FN (library, sqlite3_column_count); | 152 | LOAD_DLL_FN (library, sqlite3_column_count); |
| @@ -229,13 +237,13 @@ check_sqlite (Lisp_Object db, bool is_statement) | |||
| 229 | init_sqlite_functions (); | 237 | init_sqlite_functions (); |
| 230 | CHECK_SQLITE (db); | 238 | CHECK_SQLITE (db); |
| 231 | if (is_statement && !XSQLITE (db)->is_statement) | 239 | if (is_statement && !XSQLITE (db)->is_statement) |
| 232 | xsignal1 (Qerror, build_string ("Invalid set object")); | 240 | xsignal1 (Qsqlite_error, build_string ("Invalid set object")); |
| 233 | else if (!is_statement && XSQLITE (db)->is_statement) | 241 | else if (!is_statement && XSQLITE (db)->is_statement) |
| 234 | xsignal1 (Qerror, build_string ("Invalid database object")); | 242 | xsignal1 (Qsqlite_error, build_string ("Invalid database object")); |
| 235 | if (!is_statement && !XSQLITE (db)->db) | 243 | if (!is_statement && !XSQLITE (db)->db) |
| 236 | xsignal1 (Qerror, build_string ("Database closed")); | 244 | xsignal1 (Qsqlite_error, build_string ("Database closed")); |
| 237 | else if (is_statement && !XSQLITE (db)->db) | 245 | else if (is_statement && !XSQLITE (db)->db) |
| 238 | xsignal1 (Qerror, build_string ("Statement closed")); | 246 | xsignal1 (Qsqlite_error, build_string ("Statement closed")); |
| 239 | } | 247 | } |
| 240 | 248 | ||
| 241 | static int db_count = 0; | 249 | static int db_count = 0; |
| @@ -255,7 +263,7 @@ If FILE is nil, an in-memory database will be opened instead. */) | |||
| 255 | #endif | 263 | #endif |
| 256 | 264 | ||
| 257 | if (!init_sqlite_functions ()) | 265 | if (!init_sqlite_functions ()) |
| 258 | xsignal1 (Qerror, build_string ("sqlite support is not available")); | 266 | xsignal1 (Qsqlite_error, build_string ("sqlite support is not available")); |
| 259 | 267 | ||
| 260 | if (!NILP (file)) | 268 | if (!NILP (file)) |
| 261 | name = ENCODE_FILE (Fexpand_file_name (file, Qnil)); | 269 | name = ENCODE_FILE (Fexpand_file_name (file, Qnil)); |
| @@ -268,7 +276,7 @@ If FILE is nil, an in-memory database will be opened instead. */) | |||
| 268 | name = CALLN (Fformat, memory_fmt, make_int (++db_count)); | 276 | name = CALLN (Fformat, memory_fmt, make_int (++db_count)); |
| 269 | flags |= SQLITE_OPEN_MEMORY; | 277 | flags |= SQLITE_OPEN_MEMORY; |
| 270 | #else | 278 | #else |
| 271 | xsignal1 (Qerror, build_string ("sqlite in-memory is not available")); | 279 | xsignal1 (Qsqlite_error, build_string ("sqlite in-memory is not available")); |
| 272 | #endif | 280 | #endif |
| 273 | } | 281 | } |
| 274 | 282 | ||
| @@ -338,7 +346,7 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values) | |||
| 338 | if (blob) | 346 | if (blob) |
| 339 | { | 347 | { |
| 340 | if (SBYTES (value) != SCHARS (value)) | 348 | if (SBYTES (value) != SCHARS (value)) |
| 341 | xsignal1 (Qerror, build_string ("BLOB values must be unibyte")); | 349 | xsignal1 (Qsqlite_error, build_string ("BLOB values must be unibyte")); |
| 342 | ret = sqlite3_bind_blob (stmt, i + 1, | 350 | ret = sqlite3_bind_blob (stmt, i + 1, |
| 343 | SSDATA (value), SBYTES (value), | 351 | SSDATA (value), SBYTES (value), |
| 344 | NULL); | 352 | NULL); |
| @@ -373,72 +381,6 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values) | |||
| 373 | return NULL; | 381 | return NULL; |
| 374 | } | 382 | } |
| 375 | 383 | ||
| 376 | DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0, | ||
| 377 | doc: /* Execute a non-select SQL statement. | ||
| 378 | If VALUES is non-nil, it should be a vector or a list of values | ||
| 379 | to bind when executing a statement like | ||
| 380 | |||
| 381 | insert into foo values (?, ?, ...) | ||
| 382 | |||
| 383 | Value is the number of affected rows. */) | ||
| 384 | (Lisp_Object db, Lisp_Object query, Lisp_Object values) | ||
| 385 | { | ||
| 386 | check_sqlite (db, false); | ||
| 387 | CHECK_STRING (query); | ||
| 388 | if (!(NILP (values) || CONSP (values) || VECTORP (values))) | ||
| 389 | xsignal1 (Qerror, build_string ("VALUES must be a list or a vector")); | ||
| 390 | |||
| 391 | sqlite3 *sdb = XSQLITE (db)->db; | ||
| 392 | Lisp_Object retval = Qnil; | ||
| 393 | const char *errmsg = NULL; | ||
| 394 | Lisp_Object encoded = encode_string (query); | ||
| 395 | sqlite3_stmt *stmt = NULL; | ||
| 396 | |||
| 397 | /* We only execute the first statement -- if there's several | ||
| 398 | (separated by a semicolon), the subsequent statements won't be | ||
| 399 | done. */ | ||
| 400 | int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL); | ||
| 401 | if (ret != SQLITE_OK) | ||
| 402 | { | ||
| 403 | if (stmt != NULL) | ||
| 404 | { | ||
| 405 | sqlite3_finalize (stmt); | ||
| 406 | sqlite3_reset (stmt); | ||
| 407 | } | ||
| 408 | |||
| 409 | errmsg = sqlite3_errmsg (sdb); | ||
| 410 | goto exit; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* Bind ? values. */ | ||
| 414 | if (!NILP (values)) { | ||
| 415 | const char *err = bind_values (sdb, stmt, values); | ||
| 416 | if (err != NULL) | ||
| 417 | { | ||
| 418 | errmsg = err; | ||
| 419 | goto exit; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | ret = sqlite3_step (stmt); | ||
| 424 | sqlite3_finalize (stmt); | ||
| 425 | if (ret != SQLITE_OK && ret != SQLITE_DONE) | ||
| 426 | { | ||
| 427 | errmsg = sqlite3_errmsg (sdb); | ||
| 428 | goto exit; | ||
| 429 | } | ||
| 430 | |||
| 431 | retval = make_fixnum (sqlite3_changes (sdb)); | ||
| 432 | |||
| 433 | exit: | ||
| 434 | if (errmsg != NULL) | ||
| 435 | xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY? | ||
| 436 | Qsqlite_locked_error: Qerror, | ||
| 437 | build_string (errmsg)); | ||
| 438 | |||
| 439 | return retval; | ||
| 440 | } | ||
| 441 | |||
| 442 | static Lisp_Object | 384 | static Lisp_Object |
| 443 | row_to_value (sqlite3_stmt *stmt) | 385 | row_to_value (sqlite3_stmt *stmt) |
| 444 | { | 386 | { |
| @@ -484,6 +426,93 @@ row_to_value (sqlite3_stmt *stmt) | |||
| 484 | } | 426 | } |
| 485 | 427 | ||
| 486 | static Lisp_Object | 428 | static Lisp_Object |
| 429 | sqlite_prepare_errdata (int code, sqlite3 *sdb) | ||
| 430 | { | ||
| 431 | Lisp_Object errstr = build_string (sqlite3_errstr (code)); | ||
| 432 | Lisp_Object errcode = make_fixnum (code); | ||
| 433 | /* More details about what went wrong. */ | ||
| 434 | Lisp_Object ext_errcode = make_fixnum (sqlite3_extended_errcode (sdb)); | ||
| 435 | const char *errmsg = sqlite3_errmsg (sdb); | ||
| 436 | return list4 (errstr, errmsg ? build_string (errmsg) : Qnil, | ||
| 437 | errcode, ext_errcode); | ||
| 438 | } | ||
| 439 | |||
| 440 | DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0, | ||
| 441 | doc: /* Execute a non-select SQL statement. | ||
| 442 | If VALUES is non-nil, it should be a vector or a list of values | ||
| 443 | to bind when executing a statement like | ||
| 444 | |||
| 445 | insert into foo values (?, ?, ...) | ||
| 446 | |||
| 447 | Value is the number of affected rows. */) | ||
| 448 | (Lisp_Object db, Lisp_Object query, Lisp_Object values) | ||
| 449 | { | ||
| 450 | check_sqlite (db, false); | ||
| 451 | CHECK_STRING (query); | ||
| 452 | if (!(NILP (values) || CONSP (values) || VECTORP (values))) | ||
| 453 | xsignal1 (Qsqlite_error, build_string ("VALUES must be a list or a vector")); | ||
| 454 | |||
| 455 | sqlite3 *sdb = XSQLITE (db)->db; | ||
| 456 | Lisp_Object errmsg = Qnil, | ||
| 457 | encoded = encode_string (query); | ||
| 458 | sqlite3_stmt *stmt = NULL; | ||
| 459 | |||
| 460 | /* We only execute the first statement -- if there's several | ||
| 461 | (separated by a semicolon), the subsequent statements won't be | ||
| 462 | done. */ | ||
| 463 | int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL); | ||
| 464 | if (ret != SQLITE_OK) | ||
| 465 | { | ||
| 466 | if (stmt != NULL) | ||
| 467 | { | ||
| 468 | sqlite3_finalize (stmt); | ||
| 469 | sqlite3_reset (stmt); | ||
| 470 | } | ||
| 471 | |||
| 472 | errmsg = sqlite_prepare_errdata (ret, sdb); | ||
| 473 | goto exit; | ||
| 474 | } | ||
| 475 | |||
| 476 | /* Bind ? values. */ | ||
| 477 | if (!NILP (values)) | ||
| 478 | { | ||
| 479 | const char *err = bind_values (sdb, stmt, values); | ||
| 480 | if (err != NULL) | ||
| 481 | { | ||
| 482 | errmsg = build_string (err); | ||
| 483 | goto exit; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | ret = sqlite3_step (stmt); | ||
| 488 | |||
| 489 | if (ret == SQLITE_ROW) | ||
| 490 | { | ||
| 491 | Lisp_Object data = Qnil; | ||
| 492 | do | ||
| 493 | data = Fcons (row_to_value (stmt), data); | ||
| 494 | while (sqlite3_step (stmt) == SQLITE_ROW); | ||
| 495 | |||
| 496 | sqlite3_finalize (stmt); | ||
| 497 | return Fnreverse (data); | ||
| 498 | } | ||
| 499 | else if (ret == SQLITE_OK || ret == SQLITE_DONE) | ||
| 500 | { | ||
| 501 | Lisp_Object rows = make_fixnum (sqlite3_changes (sdb)); | ||
| 502 | sqlite3_finalize (stmt); | ||
| 503 | return rows; | ||
| 504 | } | ||
| 505 | else | ||
| 506 | errmsg = build_string (sqlite3_errmsg (sdb)); | ||
| 507 | |||
| 508 | exit: | ||
| 509 | sqlite3_finalize (stmt); | ||
| 510 | xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY? | ||
| 511 | Qsqlite_locked_error: Qsqlite_error, | ||
| 512 | errmsg); | ||
| 513 | } | ||
| 514 | |||
| 515 | static Lisp_Object | ||
| 487 | column_names (sqlite3_stmt *stmt) | 516 | column_names (sqlite3_stmt *stmt) |
| 488 | { | 517 | { |
| 489 | Lisp_Object columns = Qnil; | 518 | Lisp_Object columns = Qnil; |
| @@ -499,14 +528,15 @@ DEFUN ("sqlite-select", Fsqlite_select, Ssqlite_select, 2, 4, 0, | |||
| 499 | If VALUES is non-nil, it should be a list or a vector specifying the | 528 | If VALUES is non-nil, it should be a list or a vector specifying the |
| 500 | values that will be interpolated into a parameterized statement. | 529 | values that will be interpolated into a parameterized statement. |
| 501 | 530 | ||
| 502 | By default, the return value is a list where the first element is a | 531 | By default, the return value is a list, whose contents depend on |
| 503 | list of column names, and the rest of the elements are the matching data. | 532 | the value of the optional argument RETURN-TYPE. |
| 504 | 533 | ||
| 505 | RETURN-TYPE can be either nil (which means that the matching data | 534 | If RETURN-TYPE is nil or omitted, the function returns a list of rows |
| 506 | should be returned as a list of rows), or `full' (the same, but the | 535 | matching QUERY. If RETURN-TYPE is `full', the function returns a |
| 507 | first element in the return list will be the column names), or `set', | 536 | list whose first element is the list of column names, and the rest |
| 508 | which means that we return a set object that can be queried with | 537 | of the elements are the rows matching QUERY. If RETURN-TYPE is `set', |
| 509 | `sqlite-next' and other functions to get the data. */) | 538 | the function returns a set object that can be queried with functions |
| 539 | like `sqlite-next' etc., in order to get the data. */) | ||
| 510 | (Lisp_Object db, Lisp_Object query, Lisp_Object values, | 540 | (Lisp_Object db, Lisp_Object query, Lisp_Object values, |
| 511 | Lisp_Object return_type) | 541 | Lisp_Object return_type) |
| 512 | { | 542 | { |
| @@ -514,12 +544,11 @@ which means that we return a set object that can be queried with | |||
| 514 | CHECK_STRING (query); | 544 | CHECK_STRING (query); |
| 515 | 545 | ||
| 516 | if (!(NILP (values) || CONSP (values) || VECTORP (values))) | 546 | if (!(NILP (values) || CONSP (values) || VECTORP (values))) |
| 517 | xsignal1 (Qerror, build_string ("VALUES must be a list or a vector")); | 547 | xsignal1 (Qsqlite_error, build_string ("VALUES must be a list or a vector")); |
| 518 | 548 | ||
| 519 | sqlite3 *sdb = XSQLITE (db)->db; | 549 | sqlite3 *sdb = XSQLITE (db)->db; |
| 520 | Lisp_Object retval = Qnil; | 550 | Lisp_Object retval = Qnil, errmsg = Qnil, |
| 521 | const char *errmsg = NULL; | 551 | encoded = encode_string (query); |
| 522 | Lisp_Object encoded = encode_string (query); | ||
| 523 | 552 | ||
| 524 | sqlite3_stmt *stmt = NULL; | 553 | sqlite3_stmt *stmt = NULL; |
| 525 | int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded), | 554 | int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded), |
| @@ -528,7 +557,7 @@ which means that we return a set object that can be queried with | |||
| 528 | { | 557 | { |
| 529 | if (stmt) | 558 | if (stmt) |
| 530 | sqlite3_finalize (stmt); | 559 | sqlite3_finalize (stmt); |
| 531 | 560 | errmsg = sqlite_prepare_errdata (ret, sdb); | |
| 532 | goto exit; | 561 | goto exit; |
| 533 | } | 562 | } |
| 534 | 563 | ||
| @@ -539,7 +568,7 @@ which means that we return a set object that can be queried with | |||
| 539 | if (err != NULL) | 568 | if (err != NULL) |
| 540 | { | 569 | { |
| 541 | sqlite3_finalize (stmt); | 570 | sqlite3_finalize (stmt); |
| 542 | errmsg = err; | 571 | errmsg = build_string (err); |
| 543 | goto exit; | 572 | goto exit; |
| 544 | } | 573 | } |
| 545 | } | 574 | } |
| @@ -553,7 +582,7 @@ which means that we return a set object that can be queried with | |||
| 553 | 582 | ||
| 554 | /* Return the data directly. */ | 583 | /* Return the data directly. */ |
| 555 | Lisp_Object data = Qnil; | 584 | Lisp_Object data = Qnil; |
| 556 | while ((ret = sqlite3_step (stmt)) == SQLITE_ROW) | 585 | while (sqlite3_step (stmt) == SQLITE_ROW) |
| 557 | data = Fcons (row_to_value (stmt), data); | 586 | data = Fcons (row_to_value (stmt), data); |
| 558 | 587 | ||
| 559 | if (EQ (return_type, Qfull)) | 588 | if (EQ (return_type, Qfull)) |
| @@ -563,8 +592,8 @@ which means that we return a set object that can be queried with | |||
| 563 | sqlite3_finalize (stmt); | 592 | sqlite3_finalize (stmt); |
| 564 | 593 | ||
| 565 | exit: | 594 | exit: |
| 566 | if (errmsg != NULL) | 595 | if (! NILP (errmsg)) |
| 567 | xsignal1 (Qerror, build_string (errmsg)); | 596 | xsignal1 (Qsqlite_error, errmsg); |
| 568 | 597 | ||
| 569 | return retval; | 598 | return retval; |
| 570 | } | 599 | } |
| @@ -650,7 +679,7 @@ Only modules on Emacs' list of allowed modules can be loaded. */) | |||
| 650 | } | 679 | } |
| 651 | 680 | ||
| 652 | if (!do_allow) | 681 | if (!do_allow) |
| 653 | xsignal (Qerror, build_string ("Module name not on allowlist")); | 682 | xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist")); |
| 654 | 683 | ||
| 655 | int result = sqlite3_load_extension | 684 | int result = sqlite3_load_extension |
| 656 | (XSQLITE (db)->db, | 685 | (XSQLITE (db)->db, |
| @@ -670,7 +699,7 @@ DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0, | |||
| 670 | 699 | ||
| 671 | int ret = sqlite3_step (XSQLITE (set)->stmt); | 700 | int ret = sqlite3_step (XSQLITE (set)->stmt); |
| 672 | if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE) | 701 | if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE) |
| 673 | xsignal1 (Qerror, build_string (sqlite3_errmsg (XSQLITE (set)->db))); | 702 | xsignal1 (Qsqlite_error, build_string (sqlite3_errmsg (XSQLITE (set)->db))); |
| 674 | 703 | ||
| 675 | if (ret == SQLITE_DONE) | 704 | if (ret == SQLITE_DONE) |
| 676 | { | 705 | { |
| @@ -769,9 +798,15 @@ syms_of_sqlite (void) | |||
| 769 | defsubr (&Ssqlitep); | 798 | defsubr (&Ssqlitep); |
| 770 | defsubr (&Ssqlite_available_p); | 799 | defsubr (&Ssqlite_available_p); |
| 771 | 800 | ||
| 801 | DEFSYM (Qsqlite_error, "sqlite-error"); | ||
| 802 | Fput (Qsqlite_error, Qerror_conditions, | ||
| 803 | Fpurecopy (list2 (Qsqlite_error, Qerror))); | ||
| 804 | Fput (Qsqlite_error, Qerror_message, | ||
| 805 | build_pure_c_string ("Database error")); | ||
| 806 | |||
| 772 | DEFSYM (Qsqlite_locked_error, "sqlite-locked-error"); | 807 | DEFSYM (Qsqlite_locked_error, "sqlite-locked-error"); |
| 773 | Fput (Qsqlite_locked_error, Qerror_conditions, | 808 | Fput (Qsqlite_locked_error, Qerror_conditions, |
| 774 | Fpurecopy (list2 (Qsqlite_locked_error, Qerror))); | 809 | Fpurecopy (list3 (Qsqlite_locked_error, Qsqlite_error, Qerror))); |
| 775 | Fput (Qsqlite_locked_error, Qerror_message, | 810 | Fput (Qsqlite_locked_error, Qerror_message, |
| 776 | build_pure_c_string ("Database locked")); | 811 | build_pure_c_string ("Database locked")); |
| 777 | 812 | ||