[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/emacsql 4a89bfaf44 044/427: Use a macro to greatly simplif
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/emacsql 4a89bfaf44 044/427: Use a macro to greatly simplify expanders. |
Date: |
Tue, 13 Dec 2022 02:59:26 -0500 (EST) |
branch: elpa/emacsql
commit 4a89bfaf4487d82429944fb35893e16680483417
Author: Christopher Wellons <wellons@nullprogram.com>
Commit: Christopher Wellons <wellons@nullprogram.com>
Use a macro to greatly simplify expanders.
---
emacsql.el | 78 ++++++++++++++++++++++++++++++++------------------------------
1 file changed, 40 insertions(+), 38 deletions(-)
diff --git a/emacsql.el b/emacsql.el
index dc27c69de1..ab39fa7c8d 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -355,53 +355,55 @@ KIND should be :value or :identifier."
(:identifier (emacsql-escape thing))
(otherwise thing))))
+(defvar emacsql--vars ()
+ "For use with `emacsql-with-vars'.")
+
+(defun emacsql-symbol-function (symbol)
+ "Like `symbol-function' but don't return an error."
+ (ignore-errors (symbol-function symbol)))
+
+(gv-define-setter emacsql-symbol-function (store symbol)
+ `(if ,store (fset ,symbol ,store) (fmakunbound ,symbol)))
+
+(defun emacsql--vars-collect (thing kind)
+ "Only use within `emacsql-with-vars'!"
+ (if (emacsql-var thing)
+ (prog1 "%s" (push (cons (emacsql-var thing) kind) emacsql--vars))
+ (ecase kind
+ ((:identifier :value) (emacsql-escape-format thing kind))
+ (:auto (emacsql-escape-format
+ thing (if (symbolp thing) :identifier :value))))))
+
+(defmacro emacsql-with-vars (prefix &rest body)
+ "Evaluate BODY, collecting variables with `var'.
+BODY should return a string, which will be combined with variable
+definitions for return from a `emacsql-defexpander'."
+ (declare (indent 1))
+ `(let ((emacsql--vars ()))
+ (cl-letf (((emacsql-symbol-function 'var)
+ (symbol-function 'emacsql--vars-collect)))
+ (cons (concat ,prefix (progn ,@body)) emacsql--vars))))
+
;; SQL Expansion Functions:
(emacsql-defexpander :select (arg)
"Expands to the SELECT keyword."
- (let ((vars ()))
- (cons
- (concat
- "SELECT "
- (cond
- ((eq '* arg) "*")
- ((emacsql-var arg)
- (push (cons (emacsql-var arg) :identifier) vars)
- "%s")
- ((symbolp arg)
- (emacsql-escape-format arg :identifier))
- ((vectorp arg)
- (mapconcat
- #'identity
- (cl-loop for name elements of arg
- when (emacsql-var name)
- collect (prog1 "%s" (push (cons it :identifier) vars))
- else when (symbolp name)
- collect (emacsql-escape-format name :identifier)
- else do (error "Unknown format %S" name))
- ", "))))
- (nreverse vars))))
+ (emacsql-with-vars "SELECT "
+ (cond
+ ((eq '* arg) "*")
+ ((vectorp arg)
+ (mapconcat (lambda (s) (var s :identifier)) arg ", "))
+ ((var arg :identifier)))))
(emacsql-defexpander :from (table)
"Expands to the FROM keyword."
- (if (emacsql-var table)
- (list "FROM %s" (cons (emacsql-var table) :identifier))
- (list (concat "FROM " (emacsql-escape-format table :identifier)))))
+ (emacsql-with-vars "FROM "
+ (var table :identifier)))
(emacsql-defexpander :where (expr)
- (let ((vars ()))
- (cl-flet* ((collect (thing)
- (push (cons (emacsql-var thing) :auto) vars) "%s")
- (handle (v)
- (cond ((emacsql-var v) (collect v))
- ((symbolp v) (emacsql-escape-format v :identifier))
- ((emacsql-escape-format v :value)))))
- (cl-destructuring-bind (op a b) expr
- (cons (format "WHERE %s %s %s"
- (handle a)
- op
- (handle b))
- (nreverse vars))))))
+ (emacsql-with-vars "WHERE "
+ (cl-destructuring-bind (op a b) expr
+ (format "%s %s %s" (var a :auto) op (var b :auto)))))
(provide 'emacsql)
- [nongnu] elpa/emacsql 161e3a41b1 006/427: Add some tests., (continued)
- [nongnu] elpa/emacsql 161e3a41b1 006/427: Add some tests., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 97e9764343 008/427: Change the API of emacsql-insert., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql ccfafd7703 012/427: Always quote non-number values., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 1074113f03 016/427: Add readability note., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 727f3c8566 022/427: Make nil correspond to NULL., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql f8d9511d1d 025/427: Tweak README limitations paragraph., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 2f0a9457a4 029/427: Drop non-idiomatic :else., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4f6b524b9f 026/427: Rename spec to schema., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 208885e264 031/427: Add testing to schema handling., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql abe43b3381 043/427: Add :where test., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4a89bfaf44 044/427: Use a macro to greatly simplify expanders.,
ELPA Syncer <=
- [nongnu] elpa/emacsql eb10ddcdba 004/427: Error-free reaping since it's automatic., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a6dbb52a3c 009/427: Add flatten option., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 2053a15b21 010/427: Add Emacs requirement note., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 961c689269 011/427: Rename information to constraints., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql c7a8ef0908 015/427: Rename every emacsql argument to conn., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql d083cbb70e 017/427: Add in-memory database support., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9091fe8df5 019/427: Rename sqlite-program-name into namespace., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9c3293c57e 020/427: Add a docstring to emacsql struct., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 178a31d5ca 024/427: Lock in the coding system., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 85076dfe0f 027/427: Flesh out example more., ELPA Syncer, 2022/12/13