aboutsummaryrefslogtreecommitdiffstats
path: root/src/sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sqlite.c')
-rw-r--r--src/sqlite.c753
1 files changed, 753 insertions, 0 deletions
diff --git a/src/sqlite.c b/src/sqlite.c
new file mode 100644
index 00000000000..649cb382948
--- /dev/null
+++ b/src/sqlite.c
@@ -0,0 +1,753 @@
1/*
2Copyright (C) 2021-2022 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or (at
9your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
18
19This file is based on the emacs-sqlite3 package written by Syohei
20YOSHIDA <syohex@gmail.com>, which can be found at:
21
22 https://github.com/syohex/emacs-sqlite3
23*/
24
25#include <config.h>
26#include "lisp.h"
27#include "coding.h"
28
29#ifdef HAVE_SQLITE3
30
31#include <sqlite3.h>
32
33#ifdef WINDOWSNT
34
35# include <windows.h>
36# include "w32common.h"
37# include "w32.h"
38
39DEF_DLL_FN (SQLITE_API int, sqlite3_finalize, (sqlite3_stmt*));
40DEF_DLL_FN (SQLITE_API int, sqlite3_close, (sqlite3*));
41DEF_DLL_FN (SQLITE_API int, sqlite3_open_v2,
42 (const char*, sqlite3**, int, const char*));
43DEF_DLL_FN (SQLITE_API int, sqlite3_reset, (sqlite3_stmt*));
44DEF_DLL_FN (SQLITE_API int, sqlite3_bind_text,
45 (sqlite3_stmt*, int, const char*, int, void(*)(void*)));
46DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int64,
47 (sqlite3_stmt*, int, sqlite3_int64));
48DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double));
49DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int));
50DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int));
51DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*));
52DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*));
53DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*));
54DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*));
55DEF_DLL_FN (SQLITE_API int, sqlite3_column_type, (sqlite3_stmt*, int));
56DEF_DLL_FN (SQLITE_API sqlite3_int64, sqlite3_column_int64,
57 (sqlite3_stmt*, int));
58DEF_DLL_FN (SQLITE_API double, sqlite3_column_double, (sqlite3_stmt*, int));
59DEF_DLL_FN (SQLITE_API const void*, sqlite3_column_blob,
60 (sqlite3_stmt*, int));
61DEF_DLL_FN (SQLITE_API int, sqlite3_column_bytes, (sqlite3_stmt*, int));
62DEF_DLL_FN (SQLITE_API const unsigned char*, sqlite3_column_text,
63 (sqlite3_stmt*, int));
64DEF_DLL_FN (SQLITE_API const char*, sqlite3_column_name, (sqlite3_stmt*, int));
65DEF_DLL_FN (SQLITE_API int, sqlite3_exec,
66 (sqlite3*, const char*, int (*callback)(void*,int,char**,char**),
67 void*, char**));
68DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2,
69 (sqlite3*, const char*, int, sqlite3_stmt**, const char**));
70
71# ifdef HAVE_SQLITE3_LOAD_EXTENSION
72DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
73 (sqlite3*, const char*, const char*, char**));
74# undef sqlite3_load_extension
75# define sqlite3_load_extension fn_sqlite3_load_extension
76# endif
77
78# undef sqlite3_finalize
79# undef sqlite3_close
80# undef sqlite3_open_v2
81# undef sqlite3_reset
82# undef sqlite3_bind_text
83# undef sqlite3_bind_int64
84# undef sqlite3_bind_double
85# undef sqlite3_bind_null
86# undef sqlite3_bind_int
87# undef sqlite3_errmsg
88# undef sqlite3_step
89# undef sqlite3_changes
90# undef sqlite3_column_count
91# undef sqlite3_column_type
92# undef sqlite3_column_int64
93# undef sqlite3_column_double
94# undef sqlite3_column_blob
95# undef sqlite3_column_bytes
96# undef sqlite3_column_text
97# undef sqlite3_column_name
98# undef sqlite3_exec
99# undef sqlite3_prepare_v2
100
101# define sqlite3_finalize fn_sqlite3_finalize
102# define sqlite3_close fn_sqlite3_close
103# define sqlite3_open_v2 fn_sqlite3_open_v2
104# define sqlite3_reset fn_sqlite3_reset
105# define sqlite3_bind_text fn_sqlite3_bind_text
106# define sqlite3_bind_int64 fn_sqlite3_bind_int64
107# define sqlite3_bind_double fn_sqlite3_bind_double
108# define sqlite3_bind_null fn_sqlite3_bind_null
109# define sqlite3_bind_int fn_sqlite3_bind_int
110# define sqlite3_errmsg fn_sqlite3_errmsg
111# define sqlite3_step fn_sqlite3_step
112# define sqlite3_changes fn_sqlite3_changes
113# define sqlite3_column_count fn_sqlite3_column_count
114# define sqlite3_column_type fn_sqlite3_column_type
115# define sqlite3_column_int64 fn_sqlite3_column_int64
116# define sqlite3_column_double fn_sqlite3_column_double
117# define sqlite3_column_blob fn_sqlite3_column_blob
118# define sqlite3_column_bytes fn_sqlite3_column_bytes
119# define sqlite3_column_text fn_sqlite3_column_text
120# define sqlite3_column_name fn_sqlite3_column_name
121# define sqlite3_exec fn_sqlite3_exec
122# define sqlite3_prepare_v2 fn_sqlite3_prepare_v2
123
124static bool
125load_dll_functions (HMODULE library)
126{
127 LOAD_DLL_FN (library, sqlite3_finalize);
128 LOAD_DLL_FN (library, sqlite3_close);
129 LOAD_DLL_FN (library, sqlite3_open_v2);
130 LOAD_DLL_FN (library, sqlite3_reset);
131 LOAD_DLL_FN (library, sqlite3_bind_text);
132 LOAD_DLL_FN (library, sqlite3_bind_int64);
133 LOAD_DLL_FN (library, sqlite3_bind_double);
134 LOAD_DLL_FN (library, sqlite3_bind_null);
135 LOAD_DLL_FN (library, sqlite3_bind_int);
136 LOAD_DLL_FN (library, sqlite3_errmsg);
137 LOAD_DLL_FN (library, sqlite3_step);
138 LOAD_DLL_FN (library, sqlite3_changes);
139 LOAD_DLL_FN (library, sqlite3_column_count);
140 LOAD_DLL_FN (library, sqlite3_column_type);
141 LOAD_DLL_FN (library, sqlite3_column_int64);
142 LOAD_DLL_FN (library, sqlite3_column_double);
143 LOAD_DLL_FN (library, sqlite3_column_blob);
144 LOAD_DLL_FN (library, sqlite3_column_bytes);
145 LOAD_DLL_FN (library, sqlite3_column_text);
146 LOAD_DLL_FN (library, sqlite3_column_name);
147 LOAD_DLL_FN (library, sqlite3_exec);
148# ifdef HAVE_SQLITE3_LOAD_EXTENSION
149 LOAD_DLL_FN (library, sqlite3_load_extension);
150# endif
151 LOAD_DLL_FN (library, sqlite3_prepare_v2);
152 return true;
153}
154#endif /* WINDOWSNT */
155
156static bool
157init_sqlite_functions (void)
158{
159#ifdef WINDOWSNT
160 static bool sqlite3_initialized;
161
162 if (!sqlite3_initialized)
163 {
164 HMODULE library = w32_delayed_load (Qsqlite3);
165
166 if (!library)
167 message1 ("sqlite3 library was not found");
168 else if (load_dll_functions (library))
169 {
170 sqlite3_initialized = true;
171 Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qt), Vlibrary_cache);
172 }
173 else
174 {
175 message1 ("sqlite3 library was found, but could not be loaded successfully");
176 Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qnil), Vlibrary_cache);
177 }
178 }
179 return sqlite3_initialized;
180#else /* !WINDOWSNT */
181 return true;
182#endif /* !WINDOWSNT */
183}
184
185
186static void
187sqlite_free (void *arg)
188{
189 struct Lisp_Sqlite *ptr = (struct Lisp_Sqlite *)arg;
190 if (ptr->is_statement)
191 sqlite3_finalize (ptr->stmt);
192 else if (ptr->db)
193 sqlite3_close (ptr->db);
194 xfree (ptr->name);
195 xfree (ptr);
196}
197
198static Lisp_Object
199encode_string (Lisp_Object string)
200{
201 if (STRING_MULTIBYTE (string))
202 return encode_string_utf_8 (string, Qnil, 0, Qt, Qt);
203 else
204 return string;
205}
206
207static Lisp_Object
208make_sqlite (bool is_statement, void *db, void *stmt, char *name)
209{
210 struct Lisp_Sqlite *ptr
211 = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Sqlite, PVEC_SQLITE);
212 ptr->is_statement = is_statement;
213 ptr->finalizer = sqlite_free;
214 ptr->db = db;
215 ptr->name = name;
216 ptr->stmt = stmt;
217 ptr->eof = false;
218 return make_lisp_ptr (ptr, Lisp_Vectorlike);
219}
220
221static void
222check_sqlite (Lisp_Object db, bool is_statement)
223{
224 init_sqlite_functions ();
225 CHECK_SQLITE (db);
226 if (is_statement && !XSQLITE (db)->is_statement)
227 xsignal1 (Qerror, build_string ("Invalid set object"));
228 else if (!is_statement && XSQLITE (db)->is_statement)
229 xsignal1 (Qerror, build_string ("Invalid database object"));
230 if (!is_statement && !XSQLITE (db)->db)
231 xsignal1 (Qerror, build_string ("Database closed"));
232 else if (is_statement && !XSQLITE (db)->db)
233 xsignal1 (Qerror, build_string ("Statement closed"));
234}
235
236static int db_count = 0;
237
238DEFUN ("sqlite-open", Fsqlite_open, Ssqlite_open, 0, 1, 0,
239 doc: /* Open FILE as an sqlite database.
240If FILE is nil, an in-memory database will be opened instead. */)
241 (Lisp_Object file)
242{
243 char *name;
244 if (!init_sqlite_functions ())
245 xsignal1 (Qerror, build_string ("sqlite support is not available"));
246
247 if (!NILP (file))
248 {
249 CHECK_STRING (file);
250 file = ENCODE_FILE (Fexpand_file_name (file, Qnil));
251 name = xstrdup (SSDATA (file));
252 }
253 else
254 /* In-memory database. These have to have different names to
255 refer to different databases. */
256 name = xstrdup (SSDATA (CALLN (Fformat, build_string (":memory:%d"),
257 make_int (++db_count))));
258
259 sqlite3 *sdb;
260 int ret = sqlite3_open_v2 (name,
261 &sdb,
262 SQLITE_OPEN_FULLMUTEX
263 | SQLITE_OPEN_READWRITE
264 | SQLITE_OPEN_CREATE
265 | (NILP (file) ? SQLITE_OPEN_MEMORY : 0)
266#ifdef SQLITE_OPEN_URI
267 | SQLITE_OPEN_URI
268#endif
269 | 0, NULL);
270
271 if (ret != SQLITE_OK)
272 return Qnil;
273
274 return make_sqlite (false, sdb, NULL, name);
275}
276
277DEFUN ("sqlite-close", Fsqlite_close, Ssqlite_close, 1, 1, 0,
278 doc: /* Close the sqlite database DB. */)
279 (Lisp_Object db)
280{
281 check_sqlite (db, false);
282 sqlite3_close (XSQLITE (db)->db);
283 XSQLITE (db)->db = NULL;
284 return Qt;
285}
286
287/* Bind values in a statement like
288 "insert into foo values (?, ?, ?)". */
289static const char *
290bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
291{
292 sqlite3_reset (stmt);
293 int len;
294 if (VECTORP (values))
295 len = ASIZE (values);
296 else
297 len = list_length (values);
298
299 for (int i = 0; i < len; ++i)
300 {
301 int ret = SQLITE_MISMATCH;
302 Lisp_Object value;
303 if (VECTORP (values))
304 value = AREF (values, i);
305 else
306 {
307 value = XCAR (values);
308 values = XCDR (values);
309 }
310 Lisp_Object type = Ftype_of (value);
311
312 if (EQ (type, Qstring))
313 {
314 Lisp_Object encoded = encode_string (value);
315 ret = sqlite3_bind_text (stmt, i + 1,
316 SSDATA (encoded), SBYTES (encoded),
317 NULL);
318 }
319 else if (EQ (type, Qinteger))
320 {
321 if (BIGNUMP (value))
322 ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value));
323 else
324 ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value));
325 }
326 else if (EQ (type, Qfloat))
327 ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value));
328 else if (NILP (value))
329 ret = sqlite3_bind_null (stmt, i + 1);
330 else if (EQ (value, Qt))
331 ret = sqlite3_bind_int (stmt, i + 1, 1);
332 else if (EQ (value, Qfalse))
333 ret = sqlite3_bind_int (stmt, i + 1, 0);
334 else
335 return "invalid argument";
336
337 if (ret != SQLITE_OK)
338 return sqlite3_errmsg (db);
339 }
340
341 return NULL;
342}
343
344DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
345 doc: /* Execute a non-select SQL statement.
346If VALUES is non-nil, it should be a vector or a list of values
347to bind when executing a statement like
348
349 insert into foo values (?, ?, ...)
350
351Value is the number of affected rows. */)
352 (Lisp_Object db, Lisp_Object query, Lisp_Object values)
353{
354 check_sqlite (db, false);
355 CHECK_STRING (query);
356 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
357 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
358
359 sqlite3 *sdb = XSQLITE (db)->db;
360 Lisp_Object retval = Qnil;
361 const char *errmsg = NULL;
362 Lisp_Object encoded = encode_string (query);
363 sqlite3_stmt *stmt = NULL;
364
365 /* We only execute the first statement -- if there's several
366 (separated by a semicolon), the subsequent statements won't be
367 done. */
368 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
369 if (ret != SQLITE_OK)
370 {
371 if (stmt != NULL)
372 {
373 sqlite3_finalize (stmt);
374 sqlite3_reset (stmt);
375 }
376
377 errmsg = sqlite3_errmsg (sdb);
378 goto exit;
379 }
380
381 /* Bind ? values. */
382 if (!NILP (values)) {
383 const char *err = bind_values (sdb, stmt, values);
384 if (err != NULL)
385 {
386 errmsg = err;
387 goto exit;
388 }
389 }
390
391 ret = sqlite3_step (stmt);
392 sqlite3_finalize (stmt);
393 if (ret != SQLITE_OK && ret != SQLITE_DONE)
394 {
395 errmsg = sqlite3_errmsg (sdb);
396 goto exit;
397 }
398
399 retval = make_fixnum (sqlite3_changes (sdb));
400
401 exit:
402 if (errmsg != NULL)
403 xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
404 Qsqlite_locked_error: Qerror,
405 build_string (errmsg));
406
407 return retval;
408}
409
410static Lisp_Object
411row_to_value (sqlite3_stmt *stmt)
412{
413 int len = sqlite3_column_count (stmt);
414 Lisp_Object values = Qnil;
415
416 for (int i = 0; i < len; ++i)
417 {
418 Lisp_Object v = Qnil;
419
420 switch (sqlite3_column_type (stmt, i))
421 {
422 case SQLITE_INTEGER:
423 v = make_int (sqlite3_column_int64 (stmt, i));
424 break;
425
426 case SQLITE_FLOAT:
427 v = make_float (sqlite3_column_double (stmt, i));
428 break;
429
430 case SQLITE_BLOB:
431 v =
432 code_convert_string_norecord
433 (make_unibyte_string (sqlite3_column_blob (stmt, i),
434 sqlite3_column_bytes (stmt, i)),
435 Qutf_8, false);
436 break;
437
438 case SQLITE_NULL:
439 v = Qnil;
440 break;
441
442 case SQLITE_TEXT:
443 v =
444 code_convert_string_norecord
445 (make_unibyte_string ((const char *)sqlite3_column_text (stmt, i),
446 sqlite3_column_bytes (stmt, i)),
447 Qutf_8, false);
448 break;
449 }
450
451 values = Fcons (v, values);
452 }
453
454 return Fnreverse (values);
455}
456
457static Lisp_Object
458column_names (sqlite3_stmt *stmt)
459{
460 Lisp_Object columns = Qnil;
461 int count = sqlite3_column_count (stmt);
462 for (int i = 0; i < count; ++i)
463 columns = Fcons (build_string (sqlite3_column_name (stmt, i)), columns);
464
465 return Fnreverse (columns);
466}
467
468DEFUN ("sqlite-select", Fsqlite_select, Ssqlite_select, 2, 4, 0,
469 doc: /* Select data from the database DB that matches QUERY.
470If VALUES is non-nil, it should be a list or a vector specifying the
471values that will be interpolated into a parameterized statement.
472
473By default, the return value is a list where the first element is a
474list of column names, and the rest of the elements are the matching data.
475
476RETURN-TYPE can be either nil (which means that the matching data
477should be returned as a list of rows), or `full' (the same, but the
478first element in the return list will be the column names), or `set',
479which means that we return a set object that can be queried with
480`sqlite-next' and other functions to get the data. */)
481 (Lisp_Object db, Lisp_Object query, Lisp_Object values,
482 Lisp_Object return_type)
483{
484 check_sqlite (db, false);
485 CHECK_STRING (query);
486
487 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
488 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
489
490 sqlite3 *sdb = XSQLITE (db)->db;
491 Lisp_Object retval = Qnil;
492 const char *errmsg = NULL;
493 Lisp_Object encoded = encode_string (query);
494
495 sqlite3_stmt *stmt = NULL;
496 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
497 &stmt, NULL);
498 if (ret != SQLITE_OK)
499 {
500 if (stmt)
501 sqlite3_finalize (stmt);
502
503 goto exit;
504 }
505
506 /* Query with parameters. */
507 if (!NILP (values))
508 {
509 const char *err = bind_values (sdb, stmt, values);
510 if (err != NULL)
511 {
512 sqlite3_finalize (stmt);
513 errmsg = err;
514 goto exit;
515 }
516 }
517
518 /* Return a handle to get the data. */
519 if (EQ (return_type, Qset))
520 {
521 retval = make_sqlite (true, sdb, stmt, XSQLITE (db)->name);
522 goto exit;
523 }
524
525 /* Return the data directly. */
526 Lisp_Object data = Qnil;
527 while ((ret = sqlite3_step (stmt)) == SQLITE_ROW)
528 data = Fcons (row_to_value (stmt), data);
529
530 if (EQ (return_type, Qfull))
531 retval = Fcons (column_names (stmt), Fnreverse (data));
532 else
533 retval = Fnreverse (data);
534 sqlite3_finalize (stmt);
535
536 exit:
537 if (errmsg != NULL)
538 xsignal1 (Qerror, build_string (errmsg));
539
540 return retval;
541}
542
543static Lisp_Object
544sqlite_exec (sqlite3 *sdb, const char *query)
545{
546 int ret = sqlite3_exec (sdb, query, NULL, NULL, NULL);
547 if (ret != SQLITE_OK)
548 return Qnil;
549
550 return Qt;
551}
552
553DEFUN ("sqlite-transaction", Fsqlite_transaction, Ssqlite_transaction, 1, 1, 0,
554 doc: /* Start a transaction in DB. */)
555 (Lisp_Object db)
556{
557 check_sqlite (db, false);
558 return sqlite_exec (XSQLITE (db)->db, "begin");
559}
560
561DEFUN ("sqlite-commit", Fsqlite_commit, Ssqlite_commit, 1, 1, 0,
562 doc: /* Commit a transaction in DB. */)
563 (Lisp_Object db)
564{
565 check_sqlite (db, false);
566 return sqlite_exec (XSQLITE (db)->db, "commit");
567}
568
569DEFUN ("sqlite-rollback", Fsqlite_rollback, Ssqlite_rollback, 1, 1, 0,
570 doc: /* Roll back a transaction in DB. */)
571 (Lisp_Object db)
572{
573 check_sqlite (db, false);
574 return sqlite_exec (XSQLITE (db)->db, "rollback");
575}
576
577DEFUN ("sqlite-pragma", Fsqlite_pragma, Ssqlite_pragma, 2, 2, 0,
578 doc: /* Execute PRAGMA in DB. */)
579 (Lisp_Object db, Lisp_Object pragma)
580{
581 check_sqlite (db, false);
582 CHECK_STRING (pragma);
583
584 return sqlite_exec (XSQLITE (db)->db,
585 SSDATA (concat2 (build_string ("PRAGMA "), pragma)));
586}
587
588#ifdef HAVE_SQLITE3_LOAD_EXTENSION
589DEFUN ("sqlite-load-extension", Fsqlite_load_extension,
590 Ssqlite_load_extension, 2, 2, 0,
591 doc: /* Load an SQlite MODULE into DB.
592MODULE should be the name of an SQlite module's file, a
593shared library in the system-dependent format and having a
594system-dependent file-name extension.
595
596Only modules on Emacs' list of allowed modules can be loaded. */)
597 (Lisp_Object db, Lisp_Object module)
598{
599 check_sqlite (db, false);
600 CHECK_STRING (module);
601
602 /* Add names of useful and free modules here. */
603 const char *allowlist[3] = { "pcre", "csvtable", NULL };
604 char *name = SSDATA (Ffile_name_nondirectory (module));
605 /* Possibly skip past a common prefix. */
606 const char *prefix = "libsqlite3_mod_";
607 if (!strncmp (name, prefix, strlen (prefix)))
608 name += strlen (prefix);
609
610 bool do_allow = false;
611 for (const char **allow = allowlist; *allow; allow++)
612 {
613 if (strlen (*allow) < strlen (name)
614 && !strncmp (*allow, name, strlen (*allow))
615 && (!strcmp (name + strlen (*allow), ".so")
616 || !strcmp (name + strlen (*allow), ".DLL")))
617 {
618 do_allow = true;
619 break;
620 }
621 }
622
623 if (!do_allow)
624 xsignal (Qerror, build_string ("Module name not on allowlist"));
625
626 int result = sqlite3_load_extension
627 (XSQLITE (db)->db,
628 SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))),
629 NULL, NULL);
630 if (result == SQLITE_OK)
631 return Qt;
632 return Qnil;
633}
634#endif /* HAVE_SQLITE3_LOAD_EXTENSION */
635
636DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0,
637 doc: /* Return the next result set from SET. */)
638 (Lisp_Object set)
639{
640 check_sqlite (set, true);
641
642 int ret = sqlite3_step (XSQLITE (set)->stmt);
643 if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE)
644 xsignal1 (Qerror, build_string (sqlite3_errmsg (XSQLITE (set)->db)));
645
646 if (ret == SQLITE_DONE)
647 {
648 XSQLITE (set)->eof = true;
649 return Qnil;
650 }
651
652 return row_to_value (XSQLITE (set)->stmt);
653}
654
655DEFUN ("sqlite-columns", Fsqlite_columns, Ssqlite_columns, 1, 1, 0,
656 doc: /* Return the column names of SET. */)
657 (Lisp_Object set)
658{
659 check_sqlite (set, true);
660 return column_names (XSQLITE (set)->stmt);
661}
662
663DEFUN ("sqlite-more-p", Fsqlite_more_p, Ssqlite_more_p, 1, 1, 0,
664 doc: /* Say whether there are any further results in SET. */)
665 (Lisp_Object set)
666{
667 check_sqlite (set, true);
668
669 if (XSQLITE (set)->eof)
670 return Qnil;
671 else
672 return Qt;
673}
674
675DEFUN ("sqlite-finalize", Fsqlite_finalize, Ssqlite_finalize, 1, 1, 0,
676 doc: /* Mark this SET as being finished.
677This will free the resources held by SET. */)
678 (Lisp_Object set)
679{
680 check_sqlite (set, true);
681 sqlite3_finalize (XSQLITE (set)->stmt);
682 XSQLITE (set)->db = NULL;
683 return Qt;
684}
685
686#endif /* HAVE_SQLITE3 */
687
688DEFUN ("sqlitep", Fsqlitep, Ssqlitep, 1, 1, 0,
689 doc: /* Say whether OBJECT is an SQlite object. */)
690 (Lisp_Object object)
691{
692#ifdef HAVE_SQLITE3
693 return SQLITE (object)? Qt: Qnil;
694#else
695 return Qnil;
696#endif
697}
698
699DEFUN ("sqlite-available-p", Fsqlite_available_p, Ssqlite_available_p, 0, 0, 0,
700 doc: /* Return t if sqlite3 support is available in this instance of Emacs.*/)
701 (void)
702{
703#ifdef HAVE_SQLITE3
704# ifdef WINDOWSNT
705 Lisp_Object found = Fassq (Qsqlite3, Vlibrary_cache);
706 if (CONSP (found))
707 return XCDR (found);
708 else
709 return init_sqlite_functions () ? Qt : Qnil;
710# else
711 return Qt;
712#endif
713#else
714 return Qnil;
715#endif
716}
717
718void
719syms_of_sqlite (void)
720{
721#ifdef HAVE_SQLITE3
722 defsubr (&Ssqlite_open);
723 defsubr (&Ssqlite_close);
724 defsubr (&Ssqlite_execute);
725 defsubr (&Ssqlite_select);
726 defsubr (&Ssqlite_transaction);
727 defsubr (&Ssqlite_commit);
728 defsubr (&Ssqlite_rollback);
729 defsubr (&Ssqlite_pragma);
730#ifdef HAVE_SQLITE3_LOAD_EXTENSION
731 defsubr (&Ssqlite_load_extension);
732#endif
733 defsubr (&Ssqlite_next);
734 defsubr (&Ssqlite_columns);
735 defsubr (&Ssqlite_more_p);
736 defsubr (&Ssqlite_finalize);
737 DEFSYM (Qset, "set");
738 DEFSYM (Qfull, "full");
739#endif
740 defsubr (&Ssqlitep);
741 defsubr (&Ssqlite_available_p);
742
743 DEFSYM (Qsqlite_locked_error, "sqlite-locked-error");
744 Fput (Qsqlite_locked_error, Qerror_conditions,
745 Fpurecopy (list2 (Qsqlite_locked_error, Qerror)));
746 Fput (Qsqlite_locked_error, Qerror_message,
747 build_pure_c_string ("Database locked"));
748
749 DEFSYM (Qsqlitep, "sqlitep");
750 DEFSYM (Qfalse, "false");
751 DEFSYM (Qsqlite, "sqlite");
752 DEFSYM (Qsqlite3, "sqlite3");
753}