aboutsummaryrefslogtreecommitdiffstats
path: root/src/sqlite.c
diff options
context:
space:
mode:
authorLars Ingebrigtsen2022-04-28 14:58:20 +0200
committerLars Ingebrigtsen2022-04-28 14:58:53 +0200
commit5d032f2904d4604110e24eb3ae0daf8f7701d72f (patch)
tree13a686be0f9936e85d29318b8520606d4fccb92c /src/sqlite.c
parent613aa1894500f4c707078e71b497662e91f3f6f3 (diff)
downloademacs-5d032f2904d4604110e24eb3ae0daf8f7701d72f.tar.gz
emacs-5d032f2904d4604110e24eb3ae0daf8f7701d72f.zip
Allow inserting and selecting binary blobs from sqlite
* doc/lispref/text.texi (Database): Document how to insert binary data. * src/sqlite.c (bind_values): Bind BLOB columns correctly (bug#54591).
Diffstat (limited to 'src/sqlite.c')
-rw-r--r--src/sqlite.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/sqlite.c b/src/sqlite.c
index 7388b576e90..75a3b2ea32c 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -43,6 +43,8 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_open_v2,
43DEF_DLL_FN (SQLITE_API int, sqlite3_reset, (sqlite3_stmt*)); 43DEF_DLL_FN (SQLITE_API int, sqlite3_reset, (sqlite3_stmt*));
44DEF_DLL_FN (SQLITE_API int, sqlite3_bind_text, 44DEF_DLL_FN (SQLITE_API int, sqlite3_bind_text,
45 (sqlite3_stmt*, int, const char*, int, void(*)(void*))); 45 (sqlite3_stmt*, int, const char*, int, void(*)(void*)));
46DEF_DLL_FN (SQLITE_API int, sqlite3_bind_blob,
47 (sqlite3_stmt*, int, const char*, int, void(*)(void*)));
46DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int64, 48DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int64,
47 (sqlite3_stmt*, int, sqlite3_int64)); 49 (sqlite3_stmt*, int, sqlite3_int64));
48DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double)); 50DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double));
@@ -80,6 +82,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
80# undef sqlite3_open_v2 82# undef sqlite3_open_v2
81# undef sqlite3_reset 83# undef sqlite3_reset
82# undef sqlite3_bind_text 84# undef sqlite3_bind_text
85# undef sqlite3_bind_blob
83# undef sqlite3_bind_int64 86# undef sqlite3_bind_int64
84# undef sqlite3_bind_double 87# undef sqlite3_bind_double
85# undef sqlite3_bind_null 88# undef sqlite3_bind_null
@@ -103,6 +106,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
103# define sqlite3_open_v2 fn_sqlite3_open_v2 106# define sqlite3_open_v2 fn_sqlite3_open_v2
104# define sqlite3_reset fn_sqlite3_reset 107# define sqlite3_reset fn_sqlite3_reset
105# define sqlite3_bind_text fn_sqlite3_bind_text 108# define sqlite3_bind_text fn_sqlite3_bind_text
109# define sqlite3_bind_blob fn_sqlite3_bind_blob
106# define sqlite3_bind_int64 fn_sqlite3_bind_int64 110# define sqlite3_bind_int64 fn_sqlite3_bind_int64
107# define sqlite3_bind_double fn_sqlite3_bind_double 111# define sqlite3_bind_double fn_sqlite3_bind_double
108# define sqlite3_bind_null fn_sqlite3_bind_null 112# define sqlite3_bind_null fn_sqlite3_bind_null
@@ -129,6 +133,7 @@ load_dll_functions (HMODULE library)
129 LOAD_DLL_FN (library, sqlite3_open_v2); 133 LOAD_DLL_FN (library, sqlite3_open_v2);
130 LOAD_DLL_FN (library, sqlite3_reset); 134 LOAD_DLL_FN (library, sqlite3_reset);
131 LOAD_DLL_FN (library, sqlite3_bind_text); 135 LOAD_DLL_FN (library, sqlite3_bind_text);
136 LOAD_DLL_FN (library, sqlite3_bind_blob);
132 LOAD_DLL_FN (library, sqlite3_bind_int64); 137 LOAD_DLL_FN (library, sqlite3_bind_int64);
133 LOAD_DLL_FN (library, sqlite3_bind_double); 138 LOAD_DLL_FN (library, sqlite3_bind_double);
134 LOAD_DLL_FN (library, sqlite3_bind_null); 139 LOAD_DLL_FN (library, sqlite3_bind_null);
@@ -309,10 +314,37 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
309 314
310 if (EQ (type, Qstring)) 315 if (EQ (type, Qstring))
311 { 316 {
312 Lisp_Object encoded = encode_string (value); 317 Lisp_Object encoded;
313 ret = sqlite3_bind_text (stmt, i + 1, 318 bool blob = false;
314 SSDATA (encoded), SBYTES (encoded), 319
315 NULL); 320 if (SBYTES (value) == 0)
321 encoded = value;
322 else
323 {
324 Lisp_Object coding_system =
325 Fget_text_property (make_fixnum (0), Qcoding_system, value);
326 if (NILP (coding_system))
327 /* Default to utf-8. */
328 encoded = encode_string (value);
329 else if (EQ (coding_system, Qbinary))
330 blob = true;
331 else
332 encoded = Fencode_coding_string (value, coding_system,
333 Qnil, Qnil);
334 }
335
336 if (blob)
337 {
338 if (SBYTES (value) != SCHARS (value))
339 xsignal1 (Qerror, build_string ("BLOB values must be unibyte"));
340 ret = sqlite3_bind_blob (stmt, i + 1,
341 SSDATA (value), SBYTES (value),
342 NULL);
343 }
344 else
345 ret = sqlite3_bind_text (stmt, i + 1,
346 SSDATA (encoded), SBYTES (encoded),
347 NULL);
316 } 348 }
317 else if (EQ (type, Qinteger)) 349 else if (EQ (type, Qinteger))
318 { 350 {
@@ -426,11 +458,8 @@ row_to_value (sqlite3_stmt *stmt)
426 break; 458 break;
427 459
428 case SQLITE_BLOB: 460 case SQLITE_BLOB:
429 v = 461 v = make_unibyte_string (sqlite3_column_blob (stmt, i),
430 code_convert_string_norecord 462 sqlite3_column_bytes (stmt, i));
431 (make_unibyte_string (sqlite3_column_blob (stmt, i),
432 sqlite3_column_bytes (stmt, i)),
433 Qutf_8, false);
434 break; 463 break;
435 464
436 case SQLITE_NULL: 465 case SQLITE_NULL:
@@ -748,4 +777,6 @@ syms_of_sqlite (void)
748 DEFSYM (Qfalse, "false"); 777 DEFSYM (Qfalse, "false");
749 DEFSYM (Qsqlite, "sqlite"); 778 DEFSYM (Qsqlite, "sqlite");
750 DEFSYM (Qsqlite3, "sqlite3"); 779 DEFSYM (Qsqlite3, "sqlite3");
780 DEFSYM (Qbinary, "binary");
781 DEFSYM (Qcoding_system, "coding-system");
751} 782}