[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/emacsql b5c8553fc9 1/2: Read all forms in column string re
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/emacsql b5c8553fc9 1/2: Read all forms in column string returned by SQLite |
Date: |
Wed, 27 Nov 2024 12:59:51 -0500 (EST) |
branch: elpa/emacsql
commit b5c8553fc9f1cfb5aa1f122f77cf209ab3065e2f
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Jonas Bernoulli <jonas@bernoul.li>
Read all forms in column string returned by SQLite
Unlike the low-level function of the removed legacy SQLite back-end
(which inserted a single string into a buffer) `sqlite-select' and
`sqlite3-exec' return a two-dimensional tree, in which cells have
already been parsed.
When a cell is still a string after that, then we have to read a sexp
from that string. That is usually enough, but in special cases the
string may contain multiple sexp, for example, given:
(emacsql db [:insert-into tbl :values (["a"] ["b"] ["c"])])
(emacsql db [:select (funcall group-concat tbl)])
we have to parse this string "\"a\"\";\"\"b\"\";\"\"c\"".
The legacy back-end did not have to parse such a string explicitly,
because it got to read the complete value (in this case confined to
the first line) in a buffer containing this instead:
((\"a\"\";\"\"b\"\";\"\"c\"))
success
#
so it can essentially do
(car (read-from-string "((\"a\"\";\"\"b\"\";\"\"c\"))"))
to parse everything in one go. The new back-ends have helpfully
made that this more complicated (which makes sense, it's just a
bit inconvenient, when using our "store everything as a string"
approach.
An approach for the new back-ends, which needs much less code,
could be:
(caar (read-from-string (format "(%s)" col)))
but that feels less safe.
This commit teaches the new back-ends to behave the same as the
legacy back-end used to. In the future we might want to look into
automatically stripping the separators.
Closes #127.
---
emacsql-sqlite-builtin.el | 12 ++++++------
emacsql-sqlite-module.el | 9 +++++----
emacsql-sqlite.el | 10 ++++++++++
3 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/emacsql-sqlite-builtin.el b/emacsql-sqlite-builtin.el
index 7ec926feff..986e99dd17 100644
--- a/emacsql-sqlite-builtin.el
+++ b/emacsql-sqlite-builtin.el
@@ -59,12 +59,12 @@ buffer. This is for debugging purposes."
(condition-case err
(let ((include-header emacsql-include-header))
(mapcar (lambda (row)
- (prog1 (mapcar (lambda (col)
- (cond (include-header col)
- ((null col) nil)
- ((equal col "") "")
- ((numberp col) col)
- (t (read col))))
+ (prog1 (mapcan (lambda (col)
+ (cond (include-header (list col))
+ ((null col) (list nil))
+ ((equal col "") (list ""))
+ ((numberp col) (list col))
+ ((emacsql-sqlite-read-column col))))
row)
(setq include-header nil)))
(sqlite-select (oref connection handle) message nil
diff --git a/emacsql-sqlite-module.el b/emacsql-sqlite-module.el
index ba4a4e99d7..c3cf29caa2 100644
--- a/emacsql-sqlite-module.el
+++ b/emacsql-sqlite-module.el
@@ -69,10 +69,11 @@ buffer. This is for debugging purposes."
(when include-header
(push header rows)
(setq include-header nil))
- (push (mapcar (lambda (col)
- (cond ((null col) nil)
- ((equal col "") "")
- (t (read col))))
+ (push (mapcan (lambda (col)
+ (cond
+ ((null col) (list nil))
+ ((equal col "") (list ""))
+ ((emacsql-sqlite-read-column col))))
row)
rows)))
(nreverse rows))
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 38ca112ea2..f1557637f9 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -188,6 +188,16 @@ been remove, so we can no longer fall back to that.
(emacsql connection [:pragma (= busy-timeout $s1)]
(* emacsql-sqlite-busy-timeout 1000))))
+(defun emacsql-sqlite-read-column (string)
+ (let ((value nil)
+ (beg 0)
+ (end (length string)))
+ (while (< beg end)
+ (let ((v (read-from-string string beg)))
+ (push (car v) value)
+ (setq beg (cdr v))))
+ (nreverse value)))
+
(defun emacsql-sqlite-list-tables (connection)
"Return a list of the names of all tables in CONNECTION.
Tables whose names begin with \"sqlite_\", are not included