aboutsummaryrefslogtreecommitdiffstats
path: root/src/sqlite.c
diff options
context:
space:
mode:
authorLars Ingebrigtsen2021-12-11 04:55:57 +0100
committerLars Ingebrigtsen2021-12-11 04:55:57 +0100
commit3d38d1d1345aa65c4018b42e6c648606e32216f8 (patch)
tree5e6b51f9aa79c6a2e7604934f3ffe9314db21c71 /src/sqlite.c
parentaf1c5ec0fcd3f25234cfe2986c873ff2e5ed63a0 (diff)
downloademacs-3d38d1d1345aa65c4018b42e6c648606e32216f8.tar.gz
emacs-3d38d1d1345aa65c4018b42e6c648606e32216f8.zip
Add sqlite3 support to Emacs
* configure.ac: Add check for the sqlite library. * doc/lispref/text.texi (Database): Document it. * lisp/sqlite.el: New file. * lisp/term/w32-win.el (dynamic-library-alist): Add a mapping. * src/Makefile.in (SQLITE3_LIBS): Add the libraries. * src/alloc.c (union emacs_align_type): Add a Lisp_Sqlite struct. * src/data.c (Ftype_of): Add sqlite. * src/emacs.c (main): Load the syms. * src/lisp.h (DEFINE_GDB_SYMBOL_BEGIN): Add PVEC_SQLITE. (GCALIGNED_STRUCT): New struct to keep data for sqlite database objects and statement objects. (SQLITEP, SQLITE, CHECK_SQLITE, XSQLITE): New macros for accessing the objects. * src/pdumper.c (dump_vectorlike): Update hash. (dump_vectorlike): Don't dump it. * src/print.c (print_vectorlike): Add a printer for the sqlite object. * src/sqlite.c: New file. * test/src/sqlite-tests.el: Add tests.
Diffstat (limited to 'src/sqlite.c')
-rw-r--r--src/sqlite.c708
1 files changed, 708 insertions, 0 deletions
diff --git a/src/sqlite.c b/src/sqlite.c
new file mode 100644
index 00000000000..b1843bc573a
--- /dev/null
+++ b/src/sqlite.c
@@ -0,0 +1,708 @@
1/*
2Copyright (C) 2021 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_load_extension,
69 (sqlite3*, const char*, const char*, char**));
70DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2,
71 (sqlite3*, const char*, int, sqlite3_stmt**, const char**));
72
73# undef sqlite3_finalize
74# undef sqlite3_close
75# undef sqlite3_open_v2
76# undef sqlite3_reset
77# undef sqlite3_bind_text
78# undef sqlite3_bind_int64
79# undef sqlite3_bind_double
80# undef sqlite3_bind_null
81# undef sqlite3_bind_int
82# undef sqlite3_errmsg
83# undef sqlite3_step
84# undef sqlite3_changes
85# undef sqlite3_column_count
86# undef sqlite3_column_type
87# undef sqlite3_column_int64
88# undef sqlite3_column_double
89# undef sqlite3_column_blob
90# undef sqlite3_column_bytes
91# undef sqlite3_column_text
92# undef sqlite3_column_name
93# undef sqlite3_exec
94# undef sqlite3_load_extension
95# undef sqlite3_prepare_v2
96
97# define sqlite3_finalize fn_sqlite3_finalize
98# define sqlite3_close fn_sqlite3_close
99# define sqlite3_open_v2 fn_sqlite3_open_v2
100# define sqlite3_reset fn_sqlite3_reset
101# define sqlite3_bind_text fn_sqlite3_bind_text
102# define sqlite3_bind_int64 fn_sqlite3_bind_int64
103# define sqlite3_bind_double fn_sqlite3_bind_double
104# define sqlite3_bind_null fn_sqlite3_bind_null
105# define sqlite3_bind_int fn_sqlite3_bind_int
106# define sqlite3_errmsg fn_sqlite3_errmsg
107# define sqlite3_step fn_sqlite3_step
108# define sqlite3_changes fn_sqlite3_changes
109# define sqlite3_column_count fn_sqlite3_column_count
110# define sqlite3_column_type fn_sqlite3_column_type
111# define sqlite3_column_int64 fn_sqlite3_column_int64
112# define sqlite3_column_double fn_sqlite3_column_double
113# define sqlite3_column_blob fn_sqlite3_column_blob
114# define sqlite3_column_bytes fn_sqlite3_column_bytes
115# define sqlite3_column_text fn_sqlite3_column_text
116# define sqlite3_column_name fn_sqlite3_column_name
117# define sqlite3_exec fn_sqlite3_exec
118# define sqlite3_load_extension fn_sqlite3_load_extension
119# define sqlite3_prepare_v2 fn_sqlite3_prepare_v2
120
121static bool
122load_dll_functions (HMODULE library)
123{
124 LOAD_DLL_FN (library, sqlite3_finalize);
125 LOAD_DLL_FN (library, sqlite3_close);
126 LOAD_DLL_FN (library, sqlite3_open_v2);
127 LOAD_DLL_FN (library, sqlite3_reset);
128 LOAD_DLL_FN (library, sqlite3_bind_text);
129 LOAD_DLL_FN (library, sqlite3_bind_int64);
130 LOAD_DLL_FN (library, sqlite3_bind_double);
131 LOAD_DLL_FN (library, sqlite3_bind_null);
132 LOAD_DLL_FN (library, sqlite3_bind_int);
133 LOAD_DLL_FN (library, sqlite3_errmsg);
134 LOAD_DLL_FN (library, sqlite3_step);
135 LOAD_DLL_FN (library, sqlite3_changes);
136 LOAD_DLL_FN (library, sqlite3_column_count);
137 LOAD_DLL_FN (library, sqlite3_column_type);
138 LOAD_DLL_FN (library, sqlite3_column_int64);
139 LOAD_DLL_FN (library, sqlite3_column_double);
140 LOAD_DLL_FN (library, sqlite3_column_blob);
141 LOAD_DLL_FN (library, sqlite3_column_bytes);
142 LOAD_DLL_FN (library, sqlite3_column_text);
143 LOAD_DLL_FN (library, sqlite3_column_name);
144 LOAD_DLL_FN (library, sqlite3_exec);
145 LOAD_DLL_FN (library, sqlite3_load_extension);
146 LOAD_DLL_FN (library, sqlite3_prepare_v2);
147 return true;
148}
149
150static bool
151sqlite_loaded_p (void)
152{
153 Lisp_Object found = Fassq (Qsqlite3, Vlibrary_cache);
154
155 return CONSP (found) && EQ (XCDR (found), Qt);
156}
157#endif /* WINDOWSNT */
158
159static bool
160init_sqlite_functions (void)
161{
162#ifdef WINDOWSNT
163 if (sqlite_loaded_p ())
164 return true;
165 else
166 {
167 HMODULE library;
168
169 if (!(library = w32_delayed_load (Qsqlite3)))
170 {
171 message1 ("sqlite3 library not found");
172 return false;
173 }
174
175 if (! load_dll_functions (library))
176 goto bad_library;
177
178 Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qt), Vlibrary_cache);
179 return true;
180 }
181
182 bad_library:
183 Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qnil), Vlibrary_cache);
184
185 return false;
186#else /* !WINDOWSNT */
187 return true;
188#endif /* !WINDOWSNT */
189}
190
191
192static void
193sqlite_free (void *arg)
194{
195 struct Lisp_Sqlite *ptr = (struct Lisp_Sqlite *)arg;
196 if (ptr->is_statement)
197 sqlite3_finalize (ptr->stmt);
198 else if (ptr->db)
199 sqlite3_close (ptr->db);
200 xfree (ptr->name);
201 xfree (ptr);
202}
203
204static Lisp_Object
205encode_string (Lisp_Object string)
206{
207 if (STRING_MULTIBYTE (string))
208 return encode_string_utf_8 (string, Qnil, 0, Qt, Qt);
209 else
210 return string;
211}
212
213static Lisp_Object
214make_sqlite (bool is_statement, void *db, void *stmt, char *name)
215{
216 struct Lisp_Sqlite *ptr
217 = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Sqlite, PVEC_SQLITE);
218 ptr->is_statement = is_statement;
219 ptr->finalizer = sqlite_free;
220 ptr->db = db;
221 ptr->name = name;
222 ptr->stmt = stmt;
223 ptr->eof = false;
224 return make_lisp_ptr (ptr, Lisp_Vectorlike);
225}
226
227static void
228check_sqlite (Lisp_Object db, bool is_statement)
229{
230 init_sqlite_functions ();
231 CHECK_SQLITE (db);
232 if (is_statement && !XSQLITE (db)->is_statement)
233 xsignal1 (Qerror, build_string ("Invalid set object"));
234 else if (!is_statement && XSQLITE (db)->is_statement)
235 xsignal1 (Qerror, build_string ("Invalid database object"));
236 if (!is_statement && !XSQLITE (db)->db)
237 xsignal1 (Qerror, build_string ("Database closed"));
238 else if (is_statement && !XSQLITE (db)->db)
239 xsignal1 (Qerror, build_string ("Statement closed"));
240}
241
242static int db_count = 0;
243
244DEFUN ("sqlite-open", Fsqlite_open, Ssqlite_open, 0, 1, 0,
245 doc: /* Open FILE as an sqlite database.
246If FILE is nil, an in-memory database will be opened instead. */)
247 (Lisp_Object file)
248{
249 char *name;
250 init_sqlite_functions ();
251
252 if (!NILP (file))
253 {
254 CHECK_STRING (file);
255 name = xstrdup (SSDATA (Fexpand_file_name (file, Qnil)));
256 }
257 else
258 /* In-memory database. These have to have different names to
259 refer to different databases. */
260 name = xstrdup (SSDATA (CALLN (Fformat, build_string (":memory:%d"),
261 make_int (++db_count))));
262
263 sqlite3 *sdb;
264 int ret = sqlite3_open_v2 (name,
265 &sdb,
266 SQLITE_OPEN_FULLMUTEX
267 | SQLITE_OPEN_READWRITE
268 | SQLITE_OPEN_CREATE
269 | (NILP (file) ? SQLITE_OPEN_MEMORY : 0)
270#ifdef SQLITE_OPEN_URI
271 | SQLITE_OPEN_URI
272#endif
273 | 0, NULL);
274
275 if (ret != SQLITE_OK)
276 return Qnil;
277
278 return make_sqlite (false, sdb, NULL, name);
279}
280
281DEFUN ("sqlite-close", Fsqlite_close, Ssqlite_close, 1, 1, 0,
282 doc: /* Close the database DB. */)
283 (Lisp_Object db)
284{
285 check_sqlite (db, false);
286 sqlite3_close (XSQLITE (db)->db);
287 XSQLITE (db)->db = NULL;
288 return Qnil;
289}
290
291/* Bind values in a statement like
292 "insert into foo values (?, ?, ?)". */
293static const char *
294bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
295{
296 sqlite3_reset (stmt);
297 int len;
298 if (VECTORP (values))
299 len = ASIZE (values);
300 else
301 len = list_length (values);
302
303 for (int i = 0; i < len; ++i)
304 {
305 int ret = SQLITE_MISMATCH;
306 Lisp_Object value;
307 if (VECTORP (values))
308 value = AREF (values, i);
309 else
310 {
311 value = XCAR (values);
312 values = XCDR (values);
313 }
314 Lisp_Object type = Ftype_of (value);
315
316 if (EQ (type, Qstring))
317 {
318 Lisp_Object encoded = encode_string (value);
319 ret = sqlite3_bind_text (stmt, i + 1,
320 SSDATA (encoded), SBYTES (encoded),
321 NULL);
322 }
323 else if (EQ (type, Qinteger))
324 {
325 if (BIGNUMP (value))
326 ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value));
327 else
328 ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value));
329 }
330 else if (EQ (type, Qfloat))
331 ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value));
332 else if (NILP (value))
333 ret = sqlite3_bind_null (stmt, i + 1);
334 else if (EQ (value, Qt))
335 ret = sqlite3_bind_int (stmt, i + 1, 1);
336 else if (EQ (value, Qfalse))
337 ret = sqlite3_bind_int (stmt, i + 1, 0);
338 else
339 return "invalid argument";
340
341 if (ret != SQLITE_OK)
342 return sqlite3_errmsg (db);
343 }
344
345 return NULL;
346}
347
348DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
349 doc: /* Execute a non-select SQL statement.
350If VALUES is non-nil, it should be a list of values to bind when
351executing a statement like
352
353 insert into foo values (?, ?, ...)
354
355The number of affected rows is returned. */)
356 (Lisp_Object db, Lisp_Object query, Lisp_Object values)
357{
358 check_sqlite (db, false);
359 CHECK_STRING (query);
360 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
361 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
362
363 sqlite3 *sdb = XSQLITE (db)->db;
364 Lisp_Object retval = Qnil;
365 const char *errmsg = NULL;
366 Lisp_Object encoded = encode_string (query);
367 sqlite3_stmt *stmt = NULL;
368
369 /* We only execute the first statement -- if there's several
370 (separated by a semicolon), the subsequent statements won't be
371 done. */
372 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
373 if (ret != SQLITE_OK)
374 {
375 if (stmt != NULL)
376 {
377 sqlite3_finalize (stmt);
378 sqlite3_reset (stmt);
379 }
380
381 errmsg = sqlite3_errmsg (sdb);
382 goto exit;
383 }
384
385 /* Bind ? values. */
386 if (!NILP (values)) {
387 const char *err = bind_values (sdb, stmt, values);
388 if (err != NULL)
389 {
390 errmsg = err;
391 goto exit;
392 }
393 }
394
395 ret = sqlite3_step (stmt);
396 sqlite3_finalize (stmt);
397 if (ret != SQLITE_OK && ret != SQLITE_DONE)
398 {
399 errmsg = sqlite3_errmsg (sdb);
400 goto exit;
401 }
402
403 retval = make_fixnum (sqlite3_changes (sdb));
404
405 exit:
406 if (errmsg != NULL)
407 xsignal1 (Qerror, build_string (errmsg));
408
409 return retval;
410}
411
412static Lisp_Object
413row_to_value (sqlite3_stmt *stmt)
414{
415 int len = sqlite3_column_count (stmt);
416 Lisp_Object values = Qnil;
417
418 for (int i = 0; i < len; ++i)
419 {
420 Lisp_Object v = Qnil;
421
422 switch (sqlite3_column_type (stmt, i))
423 {
424 case SQLITE_INTEGER:
425 v = make_int (sqlite3_column_int64 (stmt, i));
426 break;
427
428 case SQLITE_FLOAT:
429 v = make_float (sqlite3_column_double (stmt, i));
430 break;
431
432 case SQLITE_BLOB:
433 v =
434 code_convert_string_norecord
435 (make_string (sqlite3_column_blob (stmt, i),
436 sqlite3_column_bytes (stmt, i)),
437 Qutf_8, false);
438 break;
439
440 case SQLITE_NULL:
441 v = Qnil;
442 break;
443
444 case SQLITE_TEXT:
445 v =
446 code_convert_string_norecord
447 (make_string ((const char*)sqlite3_column_text (stmt, i),
448 sqlite3_column_bytes (stmt, i)),
449 Qutf_8, false);
450 break;
451 }
452
453 values = Fcons (v, values);
454 }
455
456 return Fnreverse (values);
457}
458
459static Lisp_Object
460column_names (sqlite3_stmt *stmt)
461{
462 Lisp_Object columns = Qnil;
463 int count = sqlite3_column_count (stmt);
464 for (int i = 0; i < count; ++i)
465 columns = Fcons (build_string (sqlite3_column_name (stmt, i)), columns);
466
467 return Fnreverse (columns);
468}
469
470DEFUN ("sqlite-select", Fsqlite_select, Ssqlite_select, 2, 4, 0,
471 doc: /* Select data from the database DB that matches QUERY.
472If VALUES is non-nil, they are values that will be interpolated into a
473parametrised statement.
474
475By default, the return value is a list where the first element is a
476list of column names, and the rest of the elements are the matching data.
477
478RETURN-TYPE can be either nil (which means that the matching data
479should be returned as a list of rows), or `full' (the same, but the
480first element in the return list will be the column names), or `set',
481which means that we return a set object that can be queried with
482`sqlite-next' and other functions to get the data. */)
483 (Lisp_Object db, Lisp_Object query, Lisp_Object values,
484 Lisp_Object return_type)
485{
486 check_sqlite (db, false);
487 CHECK_STRING (query);
488
489 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
490 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
491
492 sqlite3 *sdb = XSQLITE (db)->db;
493 Lisp_Object retval = Qnil;
494 const char *errmsg = NULL;
495 Lisp_Object encoded = encode_string (query);
496
497 sqlite3_stmt *stmt = NULL;
498 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
499 &stmt, NULL);
500 if (ret != SQLITE_OK)
501 {
502 if (stmt)
503 sqlite3_finalize (stmt);
504
505 goto exit;
506 }
507
508 /* Query with parameters. */
509 if (!NILP (values))
510 {
511 const char *err = bind_values (sdb, stmt, values);
512 if (err != NULL)
513 {
514 sqlite3_finalize (stmt);
515 errmsg = err;
516 goto exit;
517 }
518 }
519
520 /* Return a handle to get the data. */
521 if (EQ (return_type, Qset))
522 {
523 retval = make_sqlite (true, db, stmt, XSQLITE (db)->name);
524 goto exit;
525 }
526
527 /* Return the data directly. */
528 Lisp_Object data = Qnil;
529 while ((ret = sqlite3_step (stmt)) == SQLITE_ROW)
530 data = Fcons (row_to_value (stmt), data);
531
532 if (EQ (return_type, Qfull))
533 retval = Fcons (column_names (stmt), Fnreverse (data));
534 else
535 retval = Fnreverse (data);
536 sqlite3_finalize (stmt);
537
538 exit:
539 if (errmsg != NULL)
540 xsignal1 (Qerror, build_string (errmsg));
541
542 return retval;
543}
544
545static Lisp_Object
546sqlite_exec (sqlite3 *sdb, const char *query)
547{
548 int ret = sqlite3_exec (sdb, query, NULL, NULL, NULL);
549 if (ret != SQLITE_OK)
550 return Qnil;
551
552 return Qt;
553}
554
555DEFUN ("sqlite-transaction", Fsqlite_transaction, Ssqlite_transaction, 1, 1, 0,
556 doc: /* Start a transaction in DB. */)
557 (Lisp_Object db)
558{
559 check_sqlite (db, false);
560 return sqlite_exec (XSQLITE (db)->db, "begin");
561}
562
563DEFUN ("sqlite-commit", Fsqlite_commit, Ssqlite_commit, 1, 1, 0,
564 doc: /* Commit a transaction in DB. */)
565 (Lisp_Object db)
566{
567 check_sqlite (db, false);
568 return sqlite_exec (XSQLITE (db)->db, "commit");
569}
570
571DEFUN ("sqlite-rollback", Fsqlite_rollback, Ssqlite_rollback, 1, 1, 0,
572 doc: /* Roll back a transaction in DB. */)
573 (Lisp_Object db)
574{
575 check_sqlite (db, false);
576 return sqlite_exec (XSQLITE (db)->db, "rollback");
577}
578
579DEFUN ("sqlite-load-extension", Fsqlite_load_extension,
580 Ssqlite_load_extension, 2, 2, 0,
581 doc: /* Load a an SQlite module into DB.
582MODULE should be the file name of an SQlite module .so file. */)
583 (Lisp_Object db, Lisp_Object module)
584{
585 check_sqlite (db, false);
586 CHECK_STRING (module);
587
588 sqlite3 *sdb = XSQLITE (db)->db;
589 int result = sqlite3_load_extension (sdb,
590 SSDATA (Fexpand_file_name (module, Qnil)),
591 NULL, NULL);
592 if (result == SQLITE_OK)
593 return Qt;
594 return Qnil;
595}
596
597DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0,
598 doc: /* Return the next result set from SET. */)
599 (Lisp_Object set)
600{
601 check_sqlite (set, true);
602
603 int ret = sqlite3_step (XSQLITE (set)->stmt);
604 if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE)
605 xsignal1 (Qerror, build_string (sqlite3_errmsg (XSQLITE (set)->db)));
606
607 if (ret == SQLITE_DONE)
608 {
609 XSQLITE (set)->eof = true;
610 return Qnil;
611 }
612
613 return row_to_value (XSQLITE (set)->stmt);
614}
615
616DEFUN ("sqlite-columns", Fsqlite_columns, Ssqlite_columns, 1, 1, 0,
617 doc: /* Return the column names of SET. */)
618 (Lisp_Object set)
619{
620 check_sqlite (set, true);
621 return column_names (XSQLITE (set)->stmt);
622}
623
624DEFUN ("sqlite-more-p", Fsqlite_more_p, Ssqlite_more_p, 1, 1, 0,
625 doc: /* Say whether there's any further results in SET. */)
626 (Lisp_Object set)
627{
628 check_sqlite (set, true);
629
630 if (XSQLITE (set)->eof)
631 return Qnil;
632 else
633 return Qt;
634}
635
636DEFUN ("sqlite-finalize", Fsqlite_finalize, Ssqlite_finalize, 1, 1, 0,
637 doc: /* Mark this SET as being finished.
638This will free the resources held by SET. */)
639 (Lisp_Object set)
640{
641 check_sqlite (set, true);
642 sqlite3_finalize (XSQLITE (set)->stmt);
643 return Qt;
644}
645
646#endif /* HAVE_SQLITE3 */
647
648DEFUN ("sqlitep", Fsqlitep, Ssqlitep, 1, 1, 0,
649 doc: /* Say whether OBJECT is an SQlite object. */)
650 (Lisp_Object object)
651{
652#ifdef HAVE_SQLITE3
653 return SQLITE (object)? Qt: Qnil;
654#else
655 return Qnil;
656#endif
657}
658
659DEFUN ("sqlite-available-p", Fsqlite_available_p, Ssqlite_available_p, 0, 0, 0,
660 doc: /* Return t if sqlite3 support is available in this instance of Emacs.*/)
661 (void)
662{
663#ifdef HAVE_SQLITE3
664# ifdef WINDOWSNT
665 Lisp_Object found = Fassq (Qsqlite3, Vlibrary_cache);
666 if (CONSP (found))
667 return XCDR (found);
668 else
669 {
670 Lisp_Object status;
671 status = init_sqlite_functions () ? Qt : Qnil;
672 Vlibrary_cache = Fcons (Fcons (Qsqlite3, status), Vlibrary_cache);
673 return status;
674 }
675# else
676 return Qt;
677#endif
678#else
679 return Qnil;
680#endif
681}
682
683void
684syms_of_sqlite (void)
685{
686#ifdef HAVE_SQLITE3
687 defsubr (&Ssqlite_open);
688 defsubr (&Ssqlite_close);
689 defsubr (&Ssqlite_execute);
690 defsubr (&Ssqlite_select);
691 defsubr (&Ssqlite_transaction);
692 defsubr (&Ssqlite_commit);
693 defsubr (&Ssqlite_rollback);
694 defsubr (&Ssqlite_load_extension);
695 defsubr (&Ssqlite_next);
696 defsubr (&Ssqlite_columns);
697 defsubr (&Ssqlite_more_p);
698 defsubr (&Ssqlite_finalize);
699 DEFSYM (Qset, "set");
700 DEFSYM (Qfull, "full");
701#endif
702 defsubr (&Ssqlitep);
703 DEFSYM (Qsqlitep, "sqlitep");
704 defsubr (&Ssqlite_available_p);
705 DEFSYM (Qfalse, "false");
706 DEFSYM (Qsqlite, "sqlite");
707 DEFSYM (Qsqlite3, "sqlite3");
708}