[nongnu] elpa/emacsql c7a8ef0908 015/427: Rename every emacsql argument to conn.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit c7a8ef0908bd0a304f19231ff1f36651e4ed3d58
Author: Christopher Wellons 
Commit: Christopher Wellons 

Rename every emacsql argument to conn.
---
 emacsql.el | 106 ++---
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index b9778ea84f..ac200b7e08 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -88,30 +88,30 @@ buffer. This is for debugging purposes."
 (setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
 (process-send-string process ".prompt #\n")
 (process-send-string process ".mode line\n")
-(let ((emacsql (emacsql--create :process process :file file)))
+(let ((conn (emacsql--create :process process :file file)))
   (when log
-(setf (emacsql-log emacsql) (generate-new-buffer "*emacsql-log*")))
-  (prog1 emacsql
-(push (cons (copy-seq emacsql) (emacsql--ref emacsql))
+(setf (emacsql-log conn) (generate-new-buffer "*emacsql-log*")))
+  (prog1 conn
+(push (cons (copy-seq conn) (emacsql--ref conn))
   emacsql-connections)
 
-(defun emacsql-close (emacsql)
-  "Close connection to EMACSQL database."
-  (let ((process (emacsql-process emacsql)))
+(defun emacsql-close (conn)
+  "Close connection to CONN database."
+  (let ((process (emacsql-process conn)))
 (when (and process (process-live-p process))
   (process-send-string process ".exit\n"
 
-(defun emacsql-buffer (emacsql)
-  "Get proccess buffer for EMACSQL."
-  (process-buffer (emacsql-process emacsql)))
+(defun emacsql-buffer (conn)
+  "Get proccess buffer for CONN."
+  (process-buffer (emacsql-process conn)))
 
 (defun emacsql-reap ()
   "Clean up after lost connections."
-  (cl-loop for (emacsql-copy . ref) in emacsql-connections
+  (cl-loop for (conn-copy . ref) in emacsql-connections
when (null (emacsql--deref ref))
count (prog1 t (ignore-errors (emacsql-close emacsql-copy)))
into total
-   else collect (cons emacsql-copy ref) into connections
+   else collect (cons conn-copy ref) into connections
finally (progn
  (setf emacsql-connections connections)
  (return total
@@ -127,37 +127,37 @@ buffer. This is for debugging purposes."
 (cancel-timer emacsql-reap-timer)
 (setf emacsql-reap-timer nil)))
 
-(defun emacsql--log (emacsql &rest messages)
-  (let ((log (emacsql-log emacsql)))
+(defun emacsql--log (conn &rest messages)
+  (let ((log (emacsql-log conn)))
 (when log
   (with-current-buffer log
 (setf (point) (point-max))
 (mapc (lambda (s) (princ s log)) messages)
 
-(defun emacsql--send (emacsql string)
-  "Send STRING to EMACSQL, automatically appending newline."
-  (let ((process (emacsql-process emacsql)))
-(emacsql--log emacsql string "\n")
+(defun emacsql--send (conn string)
+  "Send STRING to CONN, automatically appending newline."
+  (let ((process (emacsql-process conn)))
+(emacsql--log conn string "\n")
 (process-send-string process string)
 (process-send-string process "\n")))
 
-(defun emacsql--clear (emacsql)
-  "Clear the process buffer for EMACSQL."
-  (with-current-buffer (emacsql-buffer emacsql)
+(defun emacsql--clear (conn)
+  "Clear the process buffer for CONN."
+  (with-current-buffer (emacsql-buffer conn)
 (erase-buffer)))
 
-(defun emacsql--complete-p (emacsql)
+(defun emacsql--complete-p (conn)
   "Return non-nil if receive buffer has finished filling."
-  (with-current-buffer (emacsql-buffer emacsql)
+  (with-current-buffer (emacsql-buffer conn)
 (cond ((= (buffer-size) 1) (string= "#" (buffer-string)))
   ((> (buffer-size) 1) (string= "\n#"
 (buffer-substring
  (- (point-max) 2) (point-max)))
 
-(defun emacsql--parse (emacsql &rest named)
+(defun emacsql--parse (conn &rest named)
   "Parse a query result into an s-expression.
 If NAMED is non-nil, don't include column names."
-  (with-current-buffer (emacsql-buffer emacsql)
+  (with-current-buffer (emacsql-buffer conn)
 (let ((standard-input (current-buffer)))
   (setf (point) (point-min))
   (cl-loop until (looking-at "#")
@@ -185,48 +185,48 @@ If NAMED is non-nil, don't include column names."
 (format "'%s'" (replace-regexp-in-string "'" "''" string))
   string)))
 
-(defun emacsql--check-error (emacsql)
+(defun emacsql--check-error (conn)
   "Return non-nil or throw an appropriate error."
-  (with-current-buffer (emacsql-buffer emacsql)
-(emacsql-wait emacsql)
+  (with-current-buffer (emacsql-buffer conn)
+(emacsql-wait conn)
 (setf (point) (point-min))
 (prog1 t
   (when (looking-at "Error:")
 (error (buffer-substring (line-beginning-position)
  (line-end-position)))
 
-(defun emacsql-wait (emacsql 

[nongnu] elpa/emacsql e859204451 064/427: Flesh out more README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit e8592044516ef4d36f5a66f4957f67f58f2d35f1
Author: Christopher Wellons 
Commit: Christopher Wellons 

Flesh out more README.
---
 README.md | 78 ---
 1 file changed, 75 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index cac2ff25a4..9c4f4f610d 100644
--- a/README.md
+++ b/README.md
@@ -8,13 +8,15 @@ It works by keeping a `sqlite3` inferior process running (a
 are automatically cleaned up if they are garbage collected. All
 requests are synchronous.
 
-Any [readable lisp value][readable] can be stored as values in
+Any [readable lisp value][readable] can be stored as a value in
 Emacsql, including numbers, strings, symbols, lists, vectors, and
-closures. Emacsql has no concept of "TEXT" values, it's all just lisp
+closures. Emacsql has no concept of "TEXT" values; it's all just lisp
 objects.
 
 Requires Emacs 24 or later.
 
+## Usage
+
 ```el
 (defvar db (emacsql-connect "company.db"))
 
@@ -32,13 +34,83 @@ Requires Emacs 24 or later.
 (emacsql db [:select [name id] :from employees :where (> salary 62000)])
 ;; => (("Susan" 1001))
 
-;; Queries can be templates using $1, $2, etc.:
+;; Queries can be templates, using $1, $2, etc.:
 (emacsql db
  [:select [name id] :from employees :where (> salary $1)]
  5)
 ;; => (("Jeff" 1000) ("Susan" 1001))
 ```
 
+## Operators
+
+Emacsql currently supports the following expression operators, named
+exactly like so in a structured Emacsql statement.
+
+* / % + - <<>>&
+| < <=> >== !=
+islike  glob  and   or
+
+The `<=` and `>=` operators accept 2 or 3 operands, transforming into
+a SQL `_ BETWEEN _ AND _` operator as appropriate.
+
+With `glob` and `like` keep in mind that they're matching the
+*printed* representations of these values, even if the value is a
+string.
+
+The `||` concatenation operator is unsupported because concatenating
+printed represenations breaks an important constraint: all values must
+remain readable within SQLite.
+
+## Structured Statements
+
+The database is interacted with via structured s-expression
+statements. You won't be concatenating strings on your own. (And it
+leaves out any possibility of a SQL injection!) See the "Usage"
+section above for examples. A statement is a vector of keywords and
+other lisp object.
+
+Structured Emacsql statements are compiled into SQL statements. The
+statement compiler is memoized so that using the same statement
+multiple times is fast. To assist in this, the statement can act as a
+template -- using `$1`, `$2`, etc. -- working like the Elisp `format`
+function.
+
+### Keywords
+
+Rather than the typical uppercase SQL keywords, keywords in a
+structured Emacsql statement are literally just that: lisp keywords.
+When multiple keywords appear in sequence, Emacsql will generally
+concatenate them with a dash, e.g. `CREATE TABLE` becomes
+`:create-table`.
+
+ * `:create-table  `
+
+ex. [:create-table employees [name (id integer :primary) (salary float)]]
+
+ * `:drop-table `
+
+ex. [:drop-table employees]
+
+ * `:select `
+
+ex. [:select [name (/ salary 52)] ...]
+
+`column-spec` can be a `*` symbol or a vector of column identifiers,
+optionally as expressions.
+
+ * `:from `
+
+ex. [... :from employees]
+
+### Templates
+
+To make statement compilation faster, and to avoid making you build up
+statements dynamically, you can insert `$n` "variables" in place of
+identifiers and values. These refer to argument positions after the
+statement in the `emacsql` function, 1-indexed.
+
+(emacsql db [:select * :from $1 :where (> salary $2)] 'employees 5)
+
 ## Limitations
 
 Emacsql is *not* intended to play well with other programs accessing



[nongnu] elpa/emacsql 031ec59f18 048/427: Add combine function to with-vars macro.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 031ec59f18471b0511d3acc2d5fb97e4d2c03430
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add combine function to with-vars macro.
---
 emacsql.el | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 97d2638a52..faa727a17d 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -375,14 +375,22 @@ KIND should be :value or :identifier."
   (:auto (emacsql-escape-format
   thing (if (symbolp thing) :identifier :value))
 
+(defun emacsql--vars-combine (expanded)
+  "Only use within `emacsql-with-vars'!"
+  (cl-destructuring-bind (string . vars) expanded
+(setf emacsql--vars (nconc emacsql--vars vars))
+string))
+
 (defmacro emacsql-with-vars (prefix &rest body)
-  "Evaluate BODY, collecting variables with `var'.
+  "Evaluate BODY, collecting variables with `var' and `combine'.
 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)))
+(symbol-function 'emacsql--vars-collect))
+   ((emacsql-symbol-function 'combine)
+(symbol-function 'emacsql--vars-combine)))
(cons (concat ,prefix (progn ,@body)) emacsql--vars
 
 ;; SQL Expansion Functions:



[nongnu] elpa/emacsql 35676bb560 065/427: Fix README examples.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 35676bb56080f21d3b21de5d2a79df04af7722bc
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix README examples.
---
 README.md | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 9c4f4f610d..9dc13cea30 100644
--- a/README.md
+++ b/README.md
@@ -85,21 +85,27 @@ concatenate them with a dash, e.g. `CREATE TABLE` becomes
 
  * `:create-table  `
 
+Provides `CREATE TABLE`.
+
 ex. [:create-table employees [name (id integer :primary) (salary float)]]
 
  * `:drop-table `
 
+Provides `DROP TABLE`.
+
 ex. [:drop-table employees]
 
  * `:select `
 
-ex. [:select [name (/ salary 52)] ...]
+Provides `SELECT`. `column-spec` can be a `*` symbol or a vector of
+column identifiers, optionally as expressions.
 
-`column-spec` can be a `*` symbol or a vector of column identifiers,
-optionally as expressions.
+ex. [:select [name (/ salary 52)] ...]
 
  * `:from `
 
+Provides `FROM`.
+
 ex. [... :from employees]
 
 ### Templates



[nongnu] elpa/emacsql f54142f1eb 062/427: Argument list checking in emacsql-format.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f54142f1eb1cd5bceb8130cf9bfafbfa8dd3d74b
Author: Christopher Wellons 
Commit: Christopher Wellons 

Argument list checking in emacsql-format.
---
 emacsql.el | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/emacsql.el b/emacsql.el
index e2c646d578..728b0a8f42 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -329,6 +329,8 @@ See also `emacsql-with-errors'."
 (defun emacsql-format (expansion &rest args)
   "Fill in the variables EXPANSION with ARGS."
   (cl-destructuring-bind (format . vars) expansion
+(unless (= (length args) (length vars))
+  (error "Wrong number of arguments for SQL template."))
 (apply #'format format
(cl-loop for (i . kind) in vars collect
 (let ((thing (nth i args)))



[nongnu] elpa/emacsql 7c572d688d 052/427: Fix % operator situation.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 7c572d688d6b308157154e0b6d588dabe7a63a5e
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix % operator situation.
---
 emacsql.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index eb6866b143..ede5b0b288 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -408,7 +408,7 @@ definitions for return from a `emacsql-defexpander'."
 ((< > = != like glob is and or * / % << >> + - & |)
  (format "%s %s %s"
  (recur 0)
- (upcase (symbol-name op))
+ (if (eq op '%) '%% (upcase (symbol-name op)))
  (recur 1)
 
 ;; SQL Expansion Functions:



[nongnu] elpa/emacsql 08ea1e6636 005/427: Wrap with single rather than double quotes.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 08ea1e6636a99240eb916a02b1e4f9ffdc70763a
Author: Christopher Wellons 
Commit: Christopher Wellons 

Wrap with single rather than double quotes.
---
 emacsql.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index f14a12f34f..a0e9b6a1c3 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -164,7 +164,7 @@ This collection exists for cleanup purposes.")
 (if (or (string-match-p "[]-\000-\040!\"#%&'()*+,./:;<=>?@[\\^`{|}~\177]"
 string)
 (string-match-p "^[0-9$]" string))
-(format "\"%s\"" (replace-regexp-in-string "\"" "\"\"" string))
+(format "'%s'" (replace-regexp-in-string "'" "''" string))
   string)))
 
 (defun emacsql--check-error (emacsql)



[nongnu] elpa/emacsql b2d83c6477 123/427: Fix up ORDER BY, drop :ascending-by.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit b2d83c6477fc120dc4b98d7897bf5b4087b95cd1
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix up ORDER BY, drop :ascending-by.
---
 README.md|  7 ---
 emacsql-tests.el |  7 +++
 emacsql.el   | 20 ++--
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 9675a6fdca..0c8f789266 100644
--- a/README.md
+++ b/README.md
@@ -160,13 +160,14 @@ Provides `GROUP BY`.
 [... :group-by name]
 ```
 
- :ascending-by ``, :descending-by ``
+ :order-by `|( <:asc|:desc>)|[ ...]`
 
 Provides `ORDER BY`.
 
 ```el
-[... :ascending-by date]
-[... :descending-by [width height]]
+[... :order-by date]
+[... :order-by [(width :asc) (height :desc)]]
+[... :order-by [(width :asc) (- height)]]
 ```
 
  :insert, :replace
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 5744e3c3a2..867678aef9 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -74,6 +74,13 @@
   (emacsql-tests-query [:create-table (:temporary :if-not-exists x) [y]] '()
"CREATE TEMPORARY TABLE IF NOT EXISTS x (y);"))
 
+(ert-deftest emacsql-order-by ()
+  (emacsql-tests-query [:order-by foo] '() "ORDER BY foo;")
+  (emacsql-tests-query [:order-by [$1]] '(bar) "ORDER BY bar;")
+  (emacsql-tests-query [:order-by (- foo)] '() "ORDER BY -(foo);")
+  (emacsql-tests-query [:order-by [(a :asc) ((/ b 2) :desc)]] '()
+   "ORDER BY a ASC, b / 2 DESC;"))
+
 (ert-deftest emacsql-system ()
   (should-not (emacsql-sqlite3-unavailable-p))
   (emacsql-with-connection (db nil)
diff --git a/emacsql.el b/emacsql.el
index 9b428ab93f..1deea2ede0 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -535,13 +535,21 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars "GROUP BY "
 (expr expr)))
 
-(emacsql-defexpander :ascending-by (columns)
+(emacsql-defexpander :order-by (columns)
   (emacsql-with-vars "ORDER BY "
-(concat (combine (emacsql--idents columns)) " ASC")))
-
-(emacsql-defexpander :descending-by (columns)
-  (emacsql-with-vars "ORDER BY "
-(concat (combine (emacsql--idents columns)) " DESC")))
+(cl-flet ((order (k) (cl-ecase k (:asc " ASC") (:desc " DESC"
+  (if (not (vectorp columns))
+  (expr columns)
+(cl-loop for column across columns collect
+ (cl-etypecase column
+   (list (let ((kpos (cl-position-if #'keywordp column)))
+   (if kpos
+   (concat (expr (nth (- 1 kpos) column))
+   (order (nth kpos column)))
+ (expr column
+   (symbol (var column :identifier)))
+ into parts
+ finally (cl-return (mapconcat #'identity parts ", ")))
 
 (emacsql-defexpander :create-table (table schema)
   (emacsql-with-vars "CREATE "



[nongnu] elpa/emacsql 9091fe8df5 019/427: Rename sqlite-program-name into namespace.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 9091fe8df579f9162fdcd6935889ebba286ad40b
Author: Christopher Wellons 
Commit: Christopher Wellons 

Rename sqlite-program-name into namespace.
---
 emacsql.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index c42b19366a..9f4033874a 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -54,7 +54,7 @@
 
 (require 'cl-lib)
 
-(defvar sqlite-program-name "sqlite3"
+(defvar emacsql-sqlite-executable "sqlite3"
   "Path to the sqlite3 executable.")
 
 (cl-defstruct (emacsql (:constructor emacsql--create))
@@ -85,7 +85,7 @@ If FILE is nil use an in-memory database.
 buffer. This is for debugging purposes."
   (emacsql-start-reap-timer)
   (let* ((buffer (generate-new-buffer "*emacsql-connection*"))
- (process (start-process "emacsql" buffer sqlite-program-name
+ (process (start-process "emacsql" buffer emacsql-sqlite-executable
  (or file ":memory:"
 (setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
 (process-send-string process ".prompt #\n")



[nongnu] elpa/emacsql 77ae713186 046/427: Create table expander.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 77ae713186a750bc5c6fb1e77aa177f445dfe0c2
Author: Christopher Wellons 
Commit: Christopher Wellons 

Create table expander.
---
 emacsql-tests.el | 4 +++-
 emacsql.el   | 5 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 59332dbe34..f27fd23860 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -48,4 +48,6 @@
   (emacsql-tests-query [:select * :from employees] ()
"SELECT * FROM employees;")
   (emacsql-tests-query [:select * :from employees :where (< salary 5)] ()
-   "SELECT * FROM employees WHERE salary < 5;"))
+   "SELECT * FROM employees WHERE salary < 5;")
+  (emacsql-tests-query [:create-table foo [a b c]] ()
+   "CREATE TABLE foo (a, b, c);"))
diff --git a/emacsql.el b/emacsql.el
index cbf2634fb6..be59bc2977 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -411,6 +411,11 @@ definitions for return from a `emacsql-defexpander'."
 (cl-destructuring-bind (op a b) expr
   (format "%s %s %s" (var a :auto) op (var b :auto)
 
+(emacsql-defexpander :create-table (table schema)
+  (emacsql-with-vars "CREATE TABLE "
+(format "%s (%s)" (var table :identifier)
+(emacsql--schema-to-string schema
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql d1c0904564 120/427: Fix missing quotes.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit d1c0904564273f6b0640fd214f1de376b6ac0305
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix missing quotes.
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6e71467091..320333fe43 100644
--- a/README.md
+++ b/README.md
@@ -160,7 +160,7 @@ Provides `GROUP BY`.
 [... :group-by name]
 ```
 
- :ascending-by , :descending-by 
+ :ascending-by ``, :descending-by ``
 
 Provides `ORDER BY`.
 



[nongnu] elpa/emacsql 43ecb5a252 071/427: Tweak README names.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 43ecb5a252c37d03d93a6b69796b968d9a18cd46
Author: Christopher Wellons 
Commit: Christopher Wellons 

Tweak README names.
---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 7a58addfe3..748696bab8 100644
--- a/README.md
+++ b/README.md
@@ -99,7 +99,7 @@ When multiple keywords appear in sequence, Emacsql will 
generally
 concatenate them with a dash, e.g. `CREATE TABLE` becomes
 `:create-table`.
 
- :create-table `` ``
+ :create-table `` ``
 
 Provides `CREATE TABLE`.
 
@@ -107,7 +107,7 @@ Provides `CREATE TABLE`.
 [:create-table employees [name (id integer :primary) (salary float)]]
 ```
 
- :drop-table ``
+ :drop-table ``
 
 Provides `DROP TABLE`.
 
@@ -124,7 +124,7 @@ column identifiers, optionally as expressions.
 [:select [name (/ salary 52)] ...]
 ```
 
- :from ``
+ :from ``
 
 Provides `FROM`.
 



[nongnu] elpa/emacsql 36c6aae4b5 042/427: Drop raw select.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 36c6aae4b58159e976da8b03db444d0846336efb
Author: Christopher Wellons 
Commit: Christopher Wellons 

Drop raw select.
---
 emacsql.el | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index b5ccb82a6b..dc27c69de1 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -290,13 +290,6 @@ Each row must be a sequence of values to store into TABLE.
   (mapconcat #'emacsql-escape-value row ", "))
 rows "), (")
 
-(defun emacsql-select-raw (conn query)
-  "Send a raw QUERY string to CONN."
-  (emacsql--clear conn)
-  (emacsql--send conn query)
-  (emacsql--check-error conn)
-  (emacsql--parse conn))
-
 ;; SQL Expansion:
 
 (defvar emacsql-expanders ()



[nongnu] elpa/emacsql 727f3c8566 022/427: Make nil correspond to NULL.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 727f3c85669fcce033000a625477d01908c21b33
Author: Christopher Wellons 
Commit: Christopher Wellons 

Make nil correspond to NULL.
---
 emacsql-tests.el | 3 ++-
 emacsql.el   | 7 ---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index d1bcd2f41c..548eb807b6 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -14,4 +14,5 @@
   (should (string= (emacsql-escape-value "foo") "'\"foo\"'"))
   (should (string= (emacsql-escape-value :foo) "':foo'"))
   (should (string= (emacsql-escape-value [1 2 3]) "'[1 2 3]'"))
-  (should (string= (emacsql-escape-value '(a b c)) "'(a b c)'")))
+  (should (string= (emacsql-escape-value '(a b c)) "'(a b c)'"))
+  (should (string= (emacsql-escape-value nil) "NULL")))
diff --git a/emacsql.el b/emacsql.el
index 4c5ed414e6..a8334426ea 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -91,6 +91,7 @@ buffer. This is for debugging purposes."
 (setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
 (process-send-string process ".prompt #\n")
 (process-send-string process ".mode line\n")
+(process-send-string process ".nullvalue nil\n")
 (let ((conn (emacsql--create :process process :file file)))
   (when log
 (setf (emacsql-log conn) (generate-new-buffer "*emacsql-log*")))
@@ -234,9 +235,9 @@ If NAMED is non-nil, don't include column names."
 (defun emacsql-escape-value (value)
   "Escape VALUE for sending to SQLite."
   (let ((print-escape-newlines t))
-(if (numberp value)
-(prin1-to-string value)
-  (emacsql-escape (prin1-to-string value) t
+(cond ((null value) "NULL")
+  ((numberp value) (prin1-to-string value))
+  (:else (emacsql-escape (prin1-to-string value) t)
 
 (defun emacsql-insert (conn table &rest rows)
   "Insert ROWS into TABLE.



[nongnu] elpa/emacsql aa9283ca0a 132/427: Allow sub-selects with :from.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit aa9283ca0a638fa53625743624e8e74b8cf6fbae
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow sub-selects with :from.
---
 README.md  | 2 ++
 emacsql.el | 5 -
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index e3beb5d452..d936c94f92 100644
--- a/README.md
+++ b/README.md
@@ -151,6 +151,8 @@ Provides `FROM`.
 
 ```el
 [... :from employees]
+[... :from [employees accounts]]
+[... :from (:select ...)]
 ```
 
  :where ``
diff --git a/emacsql.el b/emacsql.el
index 91808ae202..c38af94b21 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -535,7 +535,10 @@ definitions for return from a `emacsql-defexpander'."
 (emacsql-defexpander :from (table)
   "Expands to the FROM keyword."
   (emacsql-with-vars "FROM "
-(var table :identifier)))
+(cl-etypecase table
+  (vector (idents table))
+  (symbol (var table :identifier))
+  (list (combine (emacsql-expand table :subsql-p))
 
 (emacsql-defexpander :replace ()
   (list "REPLACE"))



[nongnu] elpa/emacsql 25f9817064 094/427: Add work-in-progress note back.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 25f981706480928eabe98916d6c90417b3f6d31d
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add work-in-progress note back.
---
 README.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index bbab63fdbe..ef41cdfef4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 # Emacsql
 
-Emacsql is a high-level Emacs Lisp front-end for SQLite.
+Emacsql is a high-level Emacs Lisp front-end for SQLite. It is
+currently a work-in-progress as the s-expression query language is
+still being hammered out.
 
 It works by keeping a `sqlite3` inferior process running (a
 "connection") for interacting with the back-end database. Connections



[nongnu] elpa/emacsql 72145a1627 045/427: Allow for multi-arity keyword expanders.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 72145a16279a51c2f24263ffbed15822f0918fcf
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow for multi-arity keyword expanders.
---
 emacsql.el | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index ab39fa7c8d..cbf2634fb6 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -295,24 +295,30 @@ Each row must be a sequence of values to store into TABLE.
 (defvar emacsql-expanders ()
   "Alist of all expansion functions.")
 
-(defun emacsql-add-expander (keyword function)
+(defun emacsql-add-expander (keyword arity function)
   "Register FUNCTION for KEYWORD as a SQL expander.
-FUNCTION should accept a single argument, the keyword's argument,
-and should return a list of ( [arg-pos] ...)."
+FUNCTION should accept the keyword's arguments and should return
+a list of ( [arg-pos] ...).
+
+See also `emacsql-with-errors'."
   (prog1 keyword
-(push (cons keyword function) emacsql-expanders)))
+(push (list keyword arity function) emacsql-expanders)))
 
 (defmacro emacsql-defexpander (keyword args &rest body)
   "Define an expander for KEYWORD."
   (declare (indent 2))
-  `(emacsql-add-expander ,keyword (lambda ,args ,@body)))
+  `(emacsql-add-expander ,keyword ,(length args) (lambda ,args ,@body)))
 
 (defun emacsql-expand (sql)
   "Expand SQL into a SQL-consumable string, with variables."
-  (loop for (keyword argument) on (cl-coerce sql 'list) by #'cddr
-for expander = (cdr (assoc keyword emacsql-expanders))
-when expander collect (funcall expander argument) into parts
+  (loop with items = (cl-coerce sql 'list)
+while (not (null items))
+for keyword = (pop items)
+for (arity expander) = (cdr (assoc keyword emacsql-expanders))
+when expander
+collect (apply expander (subseq items 0 arity)) into parts
 else do (error "Unrecognized keyword %s" keyword)
+do (setf items (subseq items arity))
 finally (return (cons (concat (mapconcat #'car parts " ") ";")
   (apply #'nconc (mapcar #'cdr parts))
 



[nongnu] elpa/emacsql c9aab20d47 082/427: Add in operator (special case operator).

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit c9aab20d476ca9dd67cbbb0ddedcafc23a59c197
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add in operator (special case operator).
---
 README.md| 2 +-
 emacsql-tests.el | 4 +++-
 emacsql.el   | 7 ++-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 7e232caa20..89b8603025 100644
--- a/README.md
+++ b/README.md
@@ -69,7 +69,7 @@ exactly like so in a structured Emacsql statement.
 
 * / % + - <<>>&
 | < <=> >== !=
-islike  glob  and   or
+islike  glob  and   orin
 
 The `<=` and `>=` operators accept 2 or 3 operands, transforming into
 a SQL `_ BETWEEN _ AND _` operator as appropriate.
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 41ebd4eb74..ac96be14b2 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -65,7 +65,9 @@
   (emacsql-tests-query [:drop-table $1] '(foo)
"DROP TABLE foo;")
   (emacsql-tests-query [:update people :set (= id $1)] '(10)
-   "UPDATE people SET id = 10;"))
+   "UPDATE people SET id = 10;")
+  (emacsql-tests-query [:select * :from people :where (in name $1)] '([FOO 
BAR])
+   "SELECT * FROM people WHERE name IN ('FOO', 'BAR');"))
 
 (provide 'emacsql-tests)
 
diff --git a/emacsql.el b/emacsql.el
index 4ba13c93c3..1fde40847e 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -426,7 +426,12 @@ definitions for return from a `emacsql-defexpander'."
 ((-)
  (cl-ecase (length args)
(1 (format "-(%s)" (recur 0)))
-   (2 (format "%s - %s" (recur 0) (recur 1)))
+   (2 (format "%s - %s" (recur 0) (recur 1)
+;; IN special case
+((in)
+ (if (= 2 (length args))
+ (format "%s IN %s" (recur 0)
+ (var (nth 1 args) :vector))
 
 ;; SQL Expansion Functions:
 



[nongnu] elpa/emacsql 0bff8ccc34 126/427: Fix up README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 0bff8ccc34926dbe6cd4106c7718f20934f8d895
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix up README.
---
 README.md | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index e8d0263b58..a82a88c6cc 100644
--- a/README.md
+++ b/README.md
@@ -193,8 +193,8 @@ Provides `INSERT`, `REPLACE`.
 Provides `INTO`.
 
 ```el
-[:insert-into employees ...]
-[:insert-into (employees [id name]) ...]
+[:into employees ...]
+[:into (employees [id name]) ...]
 ```
 
  :delete
@@ -205,14 +205,6 @@ Provides `DELETE`.
 [:delete :from employees :where ...]
 ```
 
- :replace
-
-Provides `REPLACE`.
-
-```el
-[:replace :into employees ...]
-```
-
  :values `|( ...)`
 
 ```el



[nongnu] elpa/emacsql abe43b3381 043/427: Add :where test.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit abe43b3381fba02e481b5767343d3b690be10421
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :where test.
---
 emacsql-tests.el | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 32b984a130..59332dbe34 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -39,10 +39,13 @@
 
 (defun emacsql-tests-query (query args result)
   "Check that QUERY outputs RESULT for ARGS."
-  (should (string= (apply #'emacsql-format (emacsql-expand query) args) 
result)))
+  (should (string= (apply #'emacsql-format (emacsql-expand query) args)
+   result)))
 
 (ert-deftest emacsql-expand ()
   (emacsql-tests-query [:select [$1 name] :from $2] '(id people)
"SELECT id, name FROM people;")
   (emacsql-tests-query [:select * :from employees] ()
-   "SELECT * FROM employees;"))
+   "SELECT * FROM employees;")
+  (emacsql-tests-query [:select * :from employees :where (< salary 5)] ()
+   "SELECT * FROM employees WHERE salary < 5;"))



[nongnu] elpa/emacsql 29f65b3b8e 093/427: Update Windows statement in the README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 29f65b3b8e2fc6c922bf59948be87695c0b299aa
Author: Christopher Wellons 
Commit: Christopher Wellons 

Update Windows statement in the README.
---
 README.md | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 34f4e9a0b1..bbab63fdbe 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,10 @@ objects.
 
 Requires Emacs 24 or later.
 
-Due to bad behavior from SQLite on Windows (not flushing stderr when
-`-interactive` is set) Emacsql will *not* signal error messages for
-invalid statements on this platform.
+Due to [bad behavior from SQLite on Windows][stderr] Emacsql will
+*not* signal error messages for invalid statements on this platform.
+Fortunately this would only be an issue during package development and
+shouldn't impact normal use of the database.
 
 ## Example Usage
 
@@ -227,4 +228,4 @@ types. This is a high-performance database specifically for 
Emacs.
 
 
 [readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably
-[issue-1]: https://github.com/skeeto/emacsql/issues/1
+[stderr]: http://thread.gmane.org/gmane.comp.db.sqlite.general/85824



[nongnu] elpa/emacsql f794d4d38f 116/427: Allow for selected columns in :insert-into.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f794d4d38fb1dece67b13ccb4465085e6100da97
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow for selected columns in :insert-into.
---
 README.md  | 1 +
 emacsql.el | 7 ++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 46b2465ecb..318906e58a 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,7 @@ Provides `INSERT INTO`.
 
 ```el
 [:insert-into employees ...]
+[:insert-into (employees [id name]) ...]
 ```
 
  :delete
diff --git a/emacsql.el b/emacsql.el
index 91be4b9b3a..548606715f 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -502,7 +502,12 @@ definitions for return from a `emacsql-defexpander'."
 (emacsql-defexpander :insert-into (table)
   "Expands to the INSERT INTO keywords."
   (emacsql-with-vars "INSERT INTO "
-(var table :identifier)))
+(cl-typecase table
+  (symbol (var table :identifier))
+  (list (cl-destructuring-bind (name columns) table
+  (format "%s (%s)" (var name :identifier)
+  (mapconcat (lambda (c) (var c :identifier))
+ columns ", ")))
 
 (emacsql-defexpander :where (expr)
   (emacsql-with-vars "WHERE "



[nongnu] elpa/emacsql f512300aba 054/427: Fix a few things in emacsql-expr.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f512300abafa580abe5e8f7d125babb248e4fad0
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix a few things in emacsql-expr.
---
 emacsql.el | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index cd7606bf92..23ba6c7f68 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -402,14 +402,14 @@ definitions for return from a `emacsql-defexpander'."
  (cl-ecase (length args)
(2 (format "%s %s %s" (recur 0) op (recur 1)))
(3 (format "%s BETWEEN %s AND %s"
-  (recur 1)
-  (recur (if (eq op '<=) 2 0))
-  (recur (if (eq op '<=) 0 2))
+  (recur 1) (recur 0) (recur 2)
 ((< > = != like glob is and or * / % << >> + - & |)
- (format "%s %s %s"
- (recur 0)
- (if (eq op '%) '%% (upcase (symbol-name op)))
- (recur 1)
+ (if (= 2 (length args))
+ (format "%s %s %s"
+ (recur 0)
+ (if (eq op '%) '%% (upcase (symbol-name op)))
+ (recur 1))
+   (error "Wrong number of operands for %s" op)
 
 ;; SQL Expansion Functions:
 



[nongnu] elpa/emacsql 9272d13ace 036/427: Add some tests for the expanders.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 9272d13ace5bf59dbb8b04554a631361deca9335
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add some tests for the expanders.
---
 emacsql-tests.el | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 481c09c566..32b984a130 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -27,3 +27,22 @@
"a, b REAL PRIMARY KEY UNIQUE"))
   (should (string= (emacsql--schema-to-string [(a integer) (b float)])
"a INTEGER, b REAL")))
+
+(ert-deftest emacsql-var ()
+  (should (eq (emacsql-var 'a) nil))
+  (should (eq (emacsql-var 0) nil))
+  (should (eq (emacsql-var "") nil))
+  (should (eq (emacsql-var '$) 0))
+  (should (eq (emacsql-var '$1) 0))
+  (should (eq (emacsql-var '$5) 4))
+  (should (eq (emacsql-var '$10) 9)))
+
+(defun emacsql-tests-query (query args result)
+  "Check that QUERY outputs RESULT for ARGS."
+  (should (string= (apply #'emacsql-format (emacsql-expand query) args) 
result)))
+
+(ert-deftest emacsql-expand ()
+  (emacsql-tests-query [:select [$1 name] :from $2] '(id people)
+   "SELECT id, name FROM people;")
+  (emacsql-tests-query [:select * :from employees] ()
+   "SELECT * FROM employees;"))



[nongnu] elpa/emacsql cefe1ec014 121/427: Add emacsql-sqlite3-unavailable-p.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit cefe1ec01426231bdb79e154f5301f1500ed68b1
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add emacsql-sqlite3-unavailable-p.
---
 README.md|  2 +-
 emacsql-tests.el |  1 +
 emacsql.el   | 18 ++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 320333fe43..9675a6fdca 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Emacsql, including numbers, strings, symbols, lists, vectors, 
and
 closures. Emacsql has no concept of "TEXT" values; it's all just lisp
 objects.
 
-Requires Emacs 24 or later.
+Requires Emacs 24 or later and SQLite 3.7.15 or later.
 
 Due to [bad behavior from SQLite on Windows][stderr] Emacsql will
 *not* signal error messages for invalid statements on this platform.
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 2138d3ec96..5744e3c3a2 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -75,6 +75,7 @@
"CREATE TEMPORARY TABLE IF NOT EXISTS x (y);"))
 
 (ert-deftest emacsql-system ()
+  (should-not (emacsql-sqlite3-unavailable-p))
   (emacsql-with-connection (db nil)
 (emacsql db [:create-table foo [x]])
 (should-error (emacsql db [:create-table foo [x]]))
diff --git a/emacsql.el b/emacsql.el
index 70cf4e673c..20b04eb632 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -99,6 +99,24 @@ This collection exists for cleanup purposes.")
  do (accept-process-output)))
   (emacsql--clear conn))
 
+(defun emacsql-sqlite3-unavailable-p ()
+  "Return a reason if the sqlite3 executable is not available.
+
+:no-executable -- cannot find the executable
+:cannot-execute -- cannot run the executable
+:old-version -- sqlite3 version is too old"
+  (let ((sqlite3 emacsql-sqlite3-executable))
+(if (null (executable-find sqlite3))
+:no-executable
+  (condition-case _
+  (with-temp-buffer
+(call-process sqlite3 nil (current-buffer) nil "--version")
+(let ((version (car (split-string (buffer-string)
+  (if (version< version "3.7.15")
+  :old-version
+nil)))
+(error :cannot-execute)
+
 (cl-defun emacsql-connect (file &key log)
   "Open a connected to database stored in FILE.
 If FILE is nil use an in-memory database.



[nongnu] elpa/emacsql f410b5d663 068/427: Fix spelling error.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f410b5d6630f7f40282f1735e278eb2d9827433e
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix spelling error.
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9508383903..25a9b91c75 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ symbol or it can include constraints, such as type and 
uniqueness.
 Because Emacsql stores entire lisp objects as values, the only
 relevant types are `integer`, `float`, and `object` (default).
 
-Additional contraints include `:primary` (aka `PRIMARY KEY`),
+Additional constraints include `:primary` (aka `PRIMARY KEY`),
 `:unique` (aka `UNIQUE`), `:non-nil` (aka `NOT NULL`).
 
 ```el



[nongnu] elpa/emacsql eb10ddcdba 004/427: Error-free reaping since it's automatic.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit eb10ddcdbabd22b9af2721eefdca3dd5daea3432
Author: Christopher Wellons 
Commit: Christopher Wellons 

Error-free reaping since it's automatic.
---
 emacsql.el | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index 04413bd6fb..f14a12f34f 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -104,7 +104,8 @@ This collection exists for cleanup purposes.")
   "Clean up after lost connections."
   (cl-loop for (emacsql-copy . ref) in emacsql-connections
when (null (emacsql--deref ref))
-   count (prog1 t (emacsql-close emacsql-copy)) into total
+   count (prog1 t (ignore-errors (emacsql-close emacsql-copy)))
+   into total
else collect (cons emacsql-copy ref) into connections
finally (progn
  (setf emacsql-connections connections)



[nongnu] elpa/emacsql a306de980a 070/427: Add :delete keyword.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit a306de980ac720634666c12c215f5c7c79769205
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :delete keyword.
---
 README.md  | 8 
 emacsql.el | 3 +++
 2 files changed, 11 insertions(+)

diff --git a/README.md b/README.md
index 62e19530bf..7a58addfe3 100644
--- a/README.md
+++ b/README.md
@@ -132,6 +132,14 @@ Provides `FROM`.
 [... :from employees]
 ```
 
+ :delete
+
+Provides `DELETE`.
+
+```el
+[:delete :from employees :where ...]
+```
+
 ### Templates
 
 To make statement compilation faster, and to avoid making you build up
diff --git a/emacsql.el b/emacsql.el
index d3e11e97c0..dff4e2e130 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -473,6 +473,9 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars "DROP TABLE "
 (var table :identifier)))
 
+(emacsql-defexpander :delete ()
+  (list "DELETE"))
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql 85076dfe0f 027/427: Flesh out example more.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 85076dfe0f8f4cd8910eea15cc04343073be3fcf
Author: Christopher Wellons 
Commit: Christopher Wellons 

Flesh out example more.
---
 README.md  | 8 
 emacsql.el | 8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 057f940ba9..082143f52d 100644
--- a/README.md
+++ b/README.md
@@ -19,14 +19,14 @@ Requires Emacs 24 or later.
 (defvar db (emacsql-connect "company.db"))
 
 ;; Create a table. A table identifier can be any kind of lisp value.
-(emacsql-create db :employees '(name id salary))
+(emacsql-create db :employees [name id salary])
 
 ;; Or optionally provide column constraints.
-(emacsql-create db :employees '((name text) (id integer) salary))
+(emacsql-create db :employees [(name text) (id integer) (salary real)])
 
 ;; Insert some data:
-(emacsql-insert db :employees ["Jeff"  1000 6]
-  ["Susan" 1001 64000])
+(emacsql-insert db :employees ["Jeff"  1000 6.0]
+  ["Susan" 1001 64000.0])
 
 ;; The high-level SELECT interface is a work in progress.
 (emacsql-select-raw db (concat "SELECT name, id FROM ':employees' "
diff --git a/emacsql.el b/emacsql.el
index ebefea0f5d..865930eb68 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -21,16 +21,16 @@
 ;; Table identifiers can be any lisp object: string, symbol, etc. I
 ;; suggest using a keyword. Use `emacsql-create' to create a table.
 
-;; (emacsql-create db :employees '(name id salary))
+;; (emacsql-create db :employees [name id salary])
 
 ;; Column constraints can optionally be provided.
 
-;; (emacsql-create db :employees '((name text) (id integer) salary))
+;; (emacsql-create db :employees [(name text) (id integer) (salary real)])
 
 ;; Insert values into a table with `emacsql-insert'.
 
-;; (emacsql-insert db :employees ["Jeff"  1000 6]
-;;   ["Susan" 1001 64000])
+;; (emacsql-insert db :employees ["Jeff"  1000 6.0]
+;;   ["Susan" 1001 64000.0])
 
 ;; Currently all actions are synchronous and Emacs will block until
 ;; SQLite has indicated it is finished processing the last command.



[nongnu] elpa/emacsql 178a31d5ca 024/427: Lock in the coding system.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 178a31d5ca753143e1d4e55119bc68c648fffe47
Author: Christopher Wellons 
Commit: Christopher Wellons 

Lock in the coding system.
---
 emacsql.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/emacsql.el b/emacsql.el
index 5f2535b923..a59f91931e 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -89,6 +89,7 @@ buffer. This is for debugging purposes."
  (process (start-process "emacsql" buffer emacsql-sqlite-executable
  (or file ":memory:"
 (setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
+(set-process-coding-system process 'utf-8-unix 'utf-8-unix)
 (process-send-string process ".prompt #\n")
 (process-send-string process ".mode line\n")
 (process-send-string process ".nullvalue nil\n")



[nongnu] elpa/emacsql 58e31aa3a9 079/427: Add :update and :set expanders.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 58e31aa3a9f888e197f086060ce5c6cabcd168e6
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :update and :set expanders.
---
 README.md| 17 +
 emacsql-tests.el |  4 +++-
 emacsql.el   | 10 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6e95635e4c..d40356bc83 100644
--- a/README.md
+++ b/README.md
@@ -168,6 +168,23 @@ Provides `INSERT`.
 [:insert :into employees :values (["Jeff" 0] ["Susan" 0])]
 ```
 
+ :update ``
+
+Provides `UPDATE`.
+
+```el
+[:update people :set ...]
+```
+
+ :set `|[ ...]`
+
+Provides `SET`.
+
+```el
+[:update people :set (= name "Richy") :where ...]
+[:update people :set [(= name "Ricky") (= salary 30)] :where ...]
+```
+
 ### Templates
 
 To make statement compilation faster, and to avoid making you build up
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 42adb83255..41ebd4eb74 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -63,7 +63,9 @@
   (emacsql-tests-query [:create-table foo [a b c]] ()
"CREATE TABLE foo (a, b, c);")
   (emacsql-tests-query [:drop-table $1] '(foo)
-   "DROP TABLE foo;"))
+   "DROP TABLE foo;")
+  (emacsql-tests-query [:update people :set (= id $1)] '(10)
+   "UPDATE people SET id = 10;"))
 
 (provide 'emacsql-tests)
 
diff --git a/emacsql.el b/emacsql.el
index cd75907f7b..c378d65cf3 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -472,6 +472,16 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars "VALUES "
 (var values :vector)))
 
+(emacsql-defexpander :update (table)
+  (emacsql-with-vars "UPDATE "
+(var table :identifier)))
+
+(emacsql-defexpander :set (set)
+  (emacsql-with-vars "SET "
+(cl-etypecase set
+  (vector (mapconcat (lambda (s) (combine (emacsql--expr s))) set ", "))
+  (list (combine (emacsql--expr set))
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql b3110c9fa9 018/427: Rename .sqlite to .db.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit b3110c9fa9b6411c24e8d1a47c6e48717bfca8ea
Author: Christopher Wellons 
Commit: Christopher Wellons 

Rename .sqlite to .db.
---
 README.md  | 2 +-
 emacsql.el | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 47f437eb54..ce1a9bc8b9 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ objects.
 Requires Emacs 24 or later.
 
 ```el
-(defvar db (emacsql-connect "company.sqlite"))
+(defvar db (emacsql-connect "company.db"))
 
 ;; Create a table. A table identifier can be any kind of lisp value.
 (emacsql-create db :employees '(name id salary))
diff --git a/emacsql.el b/emacsql.el
index 5bdb325e13..c42b19366a 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -12,7 +12,7 @@
 ;; file. For each connection a sqlite3 inferior process is kept alive.
 ;; Connections are closed with `elfeed-close'.
 
-;; (defvar db (emacsql-connect "company.sqlite"))
+;; (defvar db (emacsql-connect "company.db"))
 
 ;; Database connections are automatically closed when the connection
 ;; object is garbage collected. Though this doesn't excuse poor coding



[nongnu] elpa/emacsql 76bf0c34dc 038/427: Add rudimentary :where expander.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 76bf0c34dce3efb24702635a341b51b7f2e754ef
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add rudimentary :where expander.
---
 README.md  |  5 ++---
 emacsql.el | 15 +++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index f288c265ee..f323cf7f88 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,8 @@ Requires Emacs 24 or later.
 (emacsql-insert db 'employees ["Jeff"  1000 6.0]
   ["Susan" 1001 64000.0])
 
-;; The high-level SELECT interface is a work in progress.
-(emacsql-select-raw db (concat "SELECT name, id FROM employees "
-   "WHERE salary > 6;"))
+;; Query the database for results:
+(emacsql db [:select [name id] :from employees :where (> salary 6)])
 ;; => (("Susan" 1001))
 ```
 
diff --git a/emacsql.el b/emacsql.el
index ebb62d31b8..ef6a7a0188 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -386,6 +386,21 @@ KIND should be :value or :identifier."
   (list "FROM %s" (cons (emacsql-var table) :identifier))
 (list (concat "FROM " (emacsql-escape-format table :identifier)
 
+(emacsql-defexpander :where (expr)
+  (let ((vars ()))
+(cl-flet* ((collect (thing kind)
+ (push (cons (emacsql-var thing) kind) vars) "%s")
+   (handle (v)
+ (cond ((emacsql-var v) (collect v))
+   ((symbolp v) (emacsql-escape-format v :identifier))
+   ((emacsql-escape-value v)
+  (cl-destructuring-bind (op a b) expr
+(cons (format "WHERE %s %s %s"
+  (handle a)
+  op
+  (handle b))
+  vars)
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql 2053a15b21 010/427: Add Emacs requirement note.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 2053a15b214353ea0595eb2608b1f1db925bc66a
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add Emacs requirement note.
---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index eae6f6aea2..54b6d03745 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,8 @@ It works by keeping a `sqlite3` inferior process running (a
 are automatically cleaned up if they are garbage collected. All
 requests are synchronous.
 
+Requires Emacs 24 or later.
+
 ```el
 (defvar db (emacsql-connect "company.sqlite"))
 



[nongnu] elpa/emacsql 75ea77c9a0 149/427: Add an "as" operator, greatly simplifying :from.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 75ea77c9a0d1f5aede67a01dceeeaa3b077948fe
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add an "as" operator, greatly simplifying :from.
---
 README.md|  11 --
 emacsql-tests.el |   8 ++---
 emacsql.el   | 103 ---
 3 files changed, 57 insertions(+), 65 deletions(-)

diff --git a/README.md b/README.md
index 8de9635404..6e85073a9a 100644
--- a/README.md
+++ b/README.md
@@ -103,13 +103,17 @@ so you'll need to enable it for each connection.
 
 ## Operators
 
-Emacsql currently supports the following expression operators, named
+Emacsql supports the following SQLite expression operators, named
 exactly like so in a structured Emacsql statement.
 
 * / % + - <<>>&
 | < <=> >== !=
 islike  glob  and   orin
 
+In addition, Emacsql has these operators.
+
+quote   asnot
+
 The `<=` and `>=` operators accept 2 or 3 operands, transforming into
 a SQL `_ BETWEEN _ AND _` operator as appropriate.
 
@@ -180,6 +184,7 @@ column identifiers, optionally as expressions.
 
 ```el
 [:select [name (/ salary 52)] ...]
+[:select [(as name n) (as age a)] ...]
 ```
 
  :from ``
@@ -189,9 +194,9 @@ Provides `FROM`.
 ```el
 [... :from employees]
 [... :from [employees accounts]]
-[... :from [employees (accounts a)]]
+[... :from [employees (as accounts a)]]
 [... :from (:select ...)]
-[... :from [((:select ...) s1) ((:select ...) s2)]]
+[... :from [(as (:select ...) s1) (as (:select ...) s2)]]
 ```
 
  :where ``
diff --git a/emacsql-tests.el b/emacsql-tests.el
index cb383f563f..763a014d0f 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -75,10 +75,10 @@
 ;; Sub queries
 ([:select name :from (:select * :from $1)] '(people)
  "SELECT name FROM (SELECT * FROM people);")
-([:select name :from [people (accounts a)]] '()
- "SELECT name FROM people, accounts a;")
-([:select p:name :from [((:select * :from people) p)]] '()
- "SELECT p.name FROM (SELECT * FROM people) p;")))
+([:select name :from [people (as accounts a)]] '()
+ "SELECT name FROM people, accounts AS a;")
+([:select p:name :from [(as (:select * :from people) p)]] '()
+ "SELECT p.name FROM (SELECT * FROM people) AS p;")))
 
 (ert-deftest emacsql-create-table ()
   (emacsql-tests-with-queries
diff --git a/emacsql.el b/emacsql.el
index 449544bba6..c79d90b70e 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -504,54 +504,56 @@ definitions for return from a `emacsql-defexpander'."
 (defun emacsql--expr (expr)
   "Expand EXPR recursively."
   (emacsql-with-vars ""
-(if (atom expr)
-(var expr :auto)
-  (cl-destructuring-bind (op . args) expr
-(cl-flet ((recur (n) (combine (emacsql--expr (nth n args)
-  (cl-ecase op
-;; Trinary/binary
-((<= >=)
- (cl-ecase (length args)
-   (2 (format "%s %s %s" (recur 0) op (recur 1)))
-   (3 (format "%s BETWEEN %s AND %s"
-  (recur 1)
-  (recur (if (eq op '>=) 2 0))
-  (recur (if (eq op '>=) 0 2))
-;; Binary
-((< > = != like glob is and or * / % << >> + & |)
- (if (= 2 (length args))
- (format "%s %s %s"
- (recur 0)
- (if (eq op '%) '%% (upcase (symbol-name op)))
- (recur 1))
-   (error "Wrong number of operands for %s" op)))
-;; Unary
-((not)
- (if (= 1 (length args))
- (format "%s %s" (upcase (symbol-name op)) (recur 0))
-   (error "Wrong number of operands for %s" op)))
-;; Unary/Binary
-((-)
- (cl-ecase (length args)
-   (1 (format "-(%s)" (recur 0)))
-   (2 (format "%s - %s" (recur 0) (recur 1)
-;; quote special case
-((quote)
- (cl-ecase (length args)
-   (1 (var (nth 0 args) :value
-;; IN special case
-((in)
- (cl-case (length args)
-   (1 (error "Wrong number of operands for %s" op))
-   (2 (format "%s IN %s" (recur 0) (var (nth 1 args) :vector)))
-   (otherwise
-(format "%s IN %s" (recur 0) (subsql (cdr args
+(cond
+ ((and (sequencep expr) (eq :select (elt expr 0))) (subsql expr))
+ ((atom expr) (var expr :auto))
+ ((cl-destructuring-bind (op . args) expr
+ (cl-flet ((recur (n) (combine (emacsql--expr (nth n args)
+   (cl-ecase op
+ ;; Trinary/binary
+ ((<= >=)
+  (cl-ecase (length args)
+(2 (format "%s %s %s" (recur 0) op (recur 1)))
+(3 (format "%s BETWEEN %s AND %s"
+   (recur 1)
+ 

[nongnu] elpa/emacsql beb0e00b9e 100/427: Rename emacsql--vars-collect.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit beb0e00b9ed0d9b307e10833d6d597164e94ea5e
Author: Christopher Wellons 
Commit: Christopher Wellons 

Rename emacsql--vars-collect.
---
 emacsql.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 6037a84921..4e5464aad9 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -379,7 +379,7 @@ KIND should be :value or :identifier."
 (gv-define-setter emacsql-symbol-function (store symbol)
   `(if ,store (fset ,symbol ,store) (fmakunbound ,symbol)))
 
-(defun emacsql--vars-collect (thing kind)
+(defun emacsql--vars-var (thing kind)
   "Only use within `emacsql-with-vars'!"
   (if (emacsql-var thing)
   (prog1 "%s" (push (cons (emacsql-var thing) kind) emacsql--vars))
@@ -401,7 +401,7 @@ definitions for return from a `emacsql-defexpander'."
   (declare (indent 1))
   `(let ((emacsql--vars ()))
  (cl-letf (((emacsql-symbol-function 'var)
-(symbol-function 'emacsql--vars-collect))
+(symbol-function 'emacsql--vars-var))
((emacsql-symbol-function 'combine)
 (symbol-function 'emacsql--vars-combine)))
(cons (concat ,prefix (progn ,@body)) emacsql--vars



[nongnu] elpa/emacsql da9797e948 098/427: Add a system-level test.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit da9797e948d8a311970951252c712125f92b77b1
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add a system-level test.
---
 emacsql-tests.el | 8 
 1 file changed, 8 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index bf1741298a..f53cd679ca 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -69,6 +69,14 @@
   (emacsql-tests-query [:select * :from people :where (in name $1)] '([FOO 
BAR])
"SELECT * FROM people WHERE name IN ('FOO', 'BAR');"))
 
+(ert-deftest emacsql-system ()
+  (emacsql-with-connection (db nil)
+(emacsql db [:create-table foo [x]])
+(should-error (emacsql db [:create-table foo [x]]))
+(emacsql db [:insert :into foo :values ([1] [2] [3])])
+(should (equal (emacsql db [:select * :from foo])
+   '((1) (2) (3))
+
 (provide 'emacsql-tests)
 
 ;;; emacsql-tests.el ends here



[nongnu] elpa/emacsql ee2877dab0 106/427: Clearer error message from escape identifier.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit ee2877dab0097bde20e7592193cb654aa7f56c5c
Author: Christopher Wellons 
Commit: Christopher Wellons 

Clearer error message from escape identifier.
---
 emacsql.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index 1f5f8518f6..8c14f9f392 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -224,7 +224,7 @@ CONN-SPEC is a connection specification like the call to
 (forbidden "[]-\000-\040!\"#%&'()*+,./;<=>?@[\\^`{|}~\177]"))
 (when (or (string-match-p forbidden string)
   (string-match-p "^[0-9$]" string))
-  (error "Invalid Emacsql identifier."))
+  (error "Invalid Emacsql identifier: %S" identifier))
 (if (string-match-p ":" string)
 (replace-regexp-in-string ":" "." string)
   string)))



[nongnu] elpa/emacsql 3eb06cdd73 114/427: Add GROUP BY expander.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 3eb06cdd73a51f7cba83b18b95236d134de1f653
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add GROUP BY expander.
---
 emacsql.el | 4 
 1 file changed, 4 insertions(+)

diff --git a/emacsql.el b/emacsql.el
index 01ee0ddd49..91be4b9b3a 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -508,6 +508,10 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars "WHERE "
 (combine (emacsql--expr expr
 
+(emacsql-defexpander :group-by (expr)
+  (emacsql-with-vars "GROUP BY "
+(combine (emacsql--expr expr
+
 (emacsql-defexpander :create-table (table schema)
   (emacsql-with-vars "CREATE "
 (let (temporary if-not-exists name)



[nongnu] elpa/emacsql e900f99091 075/427: Update examples.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit e900f990910e6447966e7ee91f27494b3ff204d9
Author: Christopher Wellons 
Commit: Christopher Wellons 

Update examples.
---
 README.md  | 13 +
 emacsql.el |  9 +
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 560959af0f..d189cbbe10 100644
--- a/README.md
+++ b/README.md
@@ -27,15 +27,20 @@ Requires Emacs 24 or later.
 (emacsql db [:create-table people [name (id integer :unique) (salary float)]])
 
 ;; Insert some data:
-(emacsql-insert db 'people ["Jeff"  1000 6.0]
-   ["Susan" 1001 64000.0])
+(emacsql db [:insert :into people
+ :values (["Jeff"  1000 6.0] ["Susan" 1001 64000.0])])
 
 ;; Query the database for results:
-(emacsql db [:select [name id] :from people :where (> salary 62000)])
+(emacsql db [:select [name id]
+ :from people
+ :where (> salary 62000)])
 ;; => (("Susan" 1001))
 
 ;; Queries can be templates, using $1, $2, etc.:
-(emacsql db [:select [name id] :from people :where (> salary $1)] 5)
+(emacsql db [:select [name id]
+ :from people
+ :where (> salary $1)]
+ 5)
 ;; => (("Jeff" 1000) ("Susan" 1001))
 ```
 
diff --git a/emacsql.el b/emacsql.el
index 5dd6ba7fed..c0fa338734 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -28,16 +28,16 @@
 ;; Table identifiers can be any lisp object: string, symbol, etc. I
 ;; suggest using a symbol. Use `emacsql-create' to create a table.
 
-;; (emacsql-create db 'employees [name id salary])
+;; (emacsql db [:create-table people [name id salary]])
 
 ;; Column constraints can optionally be provided.
 
-;; (emacsql-create db 'employees [name (id integer) (salary real)])
+;; (emacsql db [:create-table people [name (id integer :unique) salary]])
 
 ;; Insert values into a table with `emacsql-insert'.
 
-;; (emacsql-insert db 'employees ["Jeff"  1000 6.0]
-;;   ["Susan" 1001 64000.0])
+;; (emacsql db [:insert :into people
+;;  :values (["Jeff"  1000 6.0] ["Susan" 1001 64000.0])])
 
 ;; Currently all actions are synchronous and Emacs will block until
 ;; SQLite has indicated it is finished processing the last command.
@@ -48,6 +48,7 @@
 ;; ;; => (("Susan" 1001))
 
 ;; Queries can be templates using $1, $2, etc.:
+
 ;; (emacsql db
 ;;  [:select [name id] :from employees :where (> salary $1)]
 ;;  5)



[nongnu] elpa/emacsql bd6e02db55 104/427: Be much more strict with identifiers.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit bd6e02db55a9b2ca8c4065437df137964ebdd5df
Author: Christopher Wellons 
Commit: Christopher Wellons 

Be much more strict with identifiers.

The form table:column now convers to table.column.
---
 emacsql-tests.el | 11 ++-
 emacsql.el   | 28 
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index cec191f6a9..19299426a7 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -8,11 +8,12 @@
 (ert-deftest emacsql-escape-identifier ()
   (should (string= (emacsql-escape-identifier "foo") "foo"))
   (should (string= (emacsql-escape-identifier 'foo) "foo"))
-  (should (string= (emacsql-escape-identifier :foo) "':foo'"))
-  (should (string= (emacsql-escape-identifier "a b") "'a b'"))
-  (should (string= (emacsql-escape-identifier '$foo) "'$foo'"))
-  (should (string= (emacsql-escape-identifier "foo$") "foo$"))
-  (should (string= (emacsql-escape-identifier "they're") "'they''re'")))
+  (should (string= (emacsql-escape-identifier :foo) "foo"))
+  (should-error (emacsql-escape-identifier "a b"))
+  (should-error (emacsql-escape-identifier '$foo))
+  (should-error (emacsql-escape-identifier 10))
+  (should (string= (emacsql-escape-identifier 'foo$) "foo$"))
+  (should (string= (emacsql-escape-identifier "foo:bar") "foo.bar")))
 
 (ert-deftest emacsql-escape-value ()
   (should (string= (emacsql-escape-value 'foo) "'foo'"))
diff --git a/emacsql.el b/emacsql.el
index 6f7596648b..43fb473aba 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -211,18 +211,22 @@ CONN-SPEC is a connection specification like the call to
collect row into rows and do (setf row ())
finally (cl-return rows)
 
-(defun emacsql-escape-identifier (identifier &optional force)
+(defun emacsql-quote (string)
+  "Quote STRING for use in a SQL expression."
+  (format "'%s'" (replace-regexp-in-string "'" "''" string)))
+
+(defun emacsql-escape-identifier (identifier)
   "Escape an identifier, always with quotes when FORCE is non-nil."
-  (let ((string (if (stringp identifier)
-identifier
-  (format "%S" identifier)))
-(forbidden "[]-\000-\040!\"#%&'()*+,./:;<=>?@[\\^`{|}~\177]"))
-(when (string-match-p "\n" string)
-  (error "Newlines not permitted in identifiers by emacsql."))
-(if (or force
-(string-match-p forbidden string)
-(string-match-p "^[0-9$]" string))
-(format "'%s'" (replace-regexp-in-string "'" "''" string))
+  (let ((string (cl-typecase identifier
+  (string identifier)
+  (keyword (substring (symbol-name identifier) 1))
+  (otherwise (format "%S" identifier
+(forbidden "[]-\000-\040!\"#%&'()*+,./;<=>?@[\\^`{|}~\177]"))
+(when (or (string-match-p forbidden string)
+  (string-match-p "^[0-9$]" string))
+  (error "Invalid Emacsql identifier."))
+(if (string-match-p ":" string)
+(replace-regexp-in-string ":" "." string)
   string)))
 
 (defun emacsql--check-error (conn)
@@ -278,7 +282,7 @@ CONN-SPEC is a connection specification like the call to
   (let ((print-escape-newlines t))
 (cond ((null value) "NULL")
   ((numberp value) (prin1-to-string value))
-  ((emacsql-escape-identifier (prin1-to-string value) t)
+  ((emacsql-quote (prin1-to-string value))
 
 (defun emacsql-escape-vector (vector)
   "Encode VECTOR into a SQL vector scalar."



[nongnu] elpa/emacsql 8f59fe6e80 073/427: Add a vector escape.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 8f59fe6e8051b9cd1436e83a71633b7aec6dc355
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add a vector escape.
---
 emacsql.el | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 49d87b0715..8aa0a67968 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -273,18 +273,11 @@ buffer. This is for debugging purposes."
   ((numberp value) (prin1-to-string value))
   ((emacsql-escape (prin1-to-string value) t)
 
-(defun emacsql-insert (conn table &rest rows)
-  "Insert ROWS into TABLE.
-Each row must be a sequence of values to store into TABLE.
-
-  (emacsql-insert db :table '(\"Chris\" 0) [\"Jeff\" 1])"
-  (emacsql-with-errors conn
-(emacsql--send
- conn
- (format "INSERT INTO %s VALUES (%s);" (emacsql-escape table)
- (mapconcat (lambda (row)
-  (mapconcat #'emacsql-escape-value row ", "))
-rows "), (")
+(defun emacsql-escape-vector (vector)
+  "Encode VECTOR into a SQL vector scalar."
+  (cl-etypecase vector
+(list   (mapconcat #'emacsql-escape-vector vector ", "))
+(vector (concat "(" (mapconcat #'emacsql-escape-value vector ", ") ")"
 
 ;; SQL Expansion:
 
@@ -339,6 +332,7 @@ See also `emacsql-with-errors'."
   (cl-ecase kind
 (:identifier (emacsql-escape thing))
 (:value (emacsql-escape-value thing))
+(:vector (emacsql-escape-vector thing))
 (:auto (if (symbolp thing)
(emacsql-escape thing)
  (emacsql-escape-value thing)
@@ -367,6 +361,7 @@ KIND should be :value or :identifier."
"%" "%%" (cl-case kind
   (:value (emacsql-escape-value thing))
   (:identifier (emacsql-escape thing))
+  (:vector (emacsql-escape-vector thing))
   (otherwise thing
 
 (defvar emacsql--vars ()
@@ -384,7 +379,7 @@ KIND should be :value or :identifier."
   (if (emacsql-var thing)
   (prog1 "%s" (push (cons (emacsql-var thing) kind) emacsql--vars))
 (cl-ecase kind
-  ((:identifier :value) (emacsql-escape-format thing kind))
+  ((:identifier :value :vector) (emacsql-escape-format thing kind))
   (:auto (emacsql-escape-format
   thing (if (symbolp thing) :identifier :value))
 



[nongnu] elpa/emacsql 19a65f390e 147/427: Add ignored features section to README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 19a65f390e2908aa6ded203f43e4f317b5c5ca96
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add ignored features section to README.
---
 README.md | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/README.md b/README.md
index 4d6dcb0ac0..3fe6ad60ac 100644
--- a/README.md
+++ b/README.md
@@ -326,6 +326,24 @@ statement in the `emacsql` function, 1-indexed.
 To get a literal symbol that looks like one of these variables, escape
 it with an extra dollar sign (i.e. `$$1` becomes `$1`).
 
+## Ignored Features
+
+Emacsql doesn't cover all of SQLite's features, focusing on the most
+important syntax. Here are a list of things that aren't supported, and
+probably will never be.
+
+ * Collating. SQLite has three built-in collation functions: BINARY
+   (default), NOCASE, and RTRIM. Emacsql values never have right-hand
+   whitepsace, so RTRIM won't be of any use. NOCASE is broken
+   (ASCII-only) and there's little reason to use it.
+
+ * Databases attachments. I don't expect any program using Emacsql to
+   become so complex as to warrant multiple databases. Ignoring this
+   removes unneeded complexity.
+
+ * Date and time. These are incompatible with the printed values
+   stored by Emacsql and therefore have little use.
+
 ## Limitations
 
 Emacsql is *not* intended to play well with other programs accessing



[nongnu] elpa/emacsql 935cca89a9 176/427: Add updated information about Windows.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 935cca89a98c815071f824fcb321ea2db86d6794
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add updated information about Windows.
---
 README.md | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 28543f0367..0e6d9e4f04 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,18 @@ database.
 
 Requires Emacs 24 or later.
 
-Due to [bad behavior from SQLite on Windows][stderr] Emacsql will
-*not* signal error messages for problems on this platform.
+### Windows Issues
+
+Due to [bad behavior from both SQLite and Windows][stderr] the
+official SQLite command shell binary will *not* work with Emacsql on
+Windows. Fortunately, [this simple patch][patch] corrects the issue.
+Here's a build with the fix:
+
+ * [sqlite3.exe][exe] (3.8.2, [asc][asc])
+
+Also, due to a [long-standing Emacs bug][batch], Emacsql cannot be
+used in Emacs' "-batch" mode on Windows, which includes running the
+Emacsql test suite from the Makefile.
 
 ## Example Usage
 
@@ -389,3 +399,7 @@ The provided implementations should serve as useful 
examples.
 [readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably
 [stderr]: http://thread.gmane.org/gmane.comp.db.sqlite.general/85824
 [foreign]: http://www.sqlite.org/foreignkeys.html
+[patch]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-stderr-fix.patch
+[exe]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-3.8.2-fixed.exe
+[asc]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-3.8.2-fixed.exe.asc
+[batch]: 
http://lists.gnu.org/archive/html/emacs-pretest-bug/2005-11/msg00320.html



[nongnu] elpa/emacsql b9599f1f41 066/427: Spelling error.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit b9599f1f416032ae646cb879e257ada23a3f30e3
Author: Christopher Wellons 
Commit: Christopher Wellons 

Spelling error.
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9dc13cea30..7d3aeea714 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ With `glob` and `like` keep in mind that they're matching the
 string.
 
 The `||` concatenation operator is unsupported because concatenating
-printed represenations breaks an important constraint: all values must
+printed representations breaks an important constraint: all values must
 remain readable within SQLite.
 
 ## Structured Statements



[nongnu] elpa/emacsql a9b9d6bfc8 083/427: Fix typo in README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit a9b9d6bfc866d73dc5ad3590cb9df3e5d4322815
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix typo in README.
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 89b8603025..12b421b377 100644
--- a/README.md
+++ b/README.md
@@ -190,7 +190,7 @@ Provides `SET`.
 
 ```el
 [:update people :set (= name "Richy") :where ...]
-[:update people :set [(= name "Ricky") (= salary 30)] :where ...]
+[:update people :set [(= name "Richy") (= salary 30)] :where ...]
 ```
 
  :union, :union-all, :difference, :except



[nongnu] elpa/emacsql 161e3a41b1 006/427: Add some tests.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 161e3a41b1e5611bd3808c6658cfff821de4d346
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add some tests.
---
 emacsql-tests.el | 17 +
 1 file changed, 17 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
new file mode 100644
index 00..31a3921c5c
--- /dev/null
+++ b/emacsql-tests.el
@@ -0,0 +1,17 @@
+(require 'ert)
+
+(ert-deftest emacsql-escape ()
+  (should (string= (emacsql-escape "foo") "foo"))
+  (should (string= (emacsql-escape 'foo) "foo"))
+  (should (string= (emacsql-escape :foo) "':foo'"))
+  (should (string= (emacsql-escape "a b") "'a b'"))
+  (should (string= (emacsql-escape '$foo) "'$foo'"))
+  (should (string= (emacsql-escape "foo$") "foo$"))
+  (should (string= (emacsql-escape "they're") "'they''re'")))
+
+(ert-deftest emacsql-escape-value ()
+  (should (string= (emacsql-escape-value 'foo) "foo"))
+  (should (string= (emacsql-escape-value "foo") "'\"foo\"'"))
+  (should (string= (emacsql-escape-value :foo) "':foo'"))
+  (should (string= (emacsql-escape-value [1 2 3]) "'[1 2 3]'"))
+  (should (string= (emacsql-escape-value '(a b c)) "'(a b c)'")))



[nongnu] elpa/emacsql f8d9511d1d 025/427: Tweak README limitations paragraph.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f8d9511d1d401e157b0fef6123a9e6435bfaa560
Author: Christopher Wellons 
Commit: Christopher Wellons 

Tweak README limitations paragraph.
---
 README.md | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 8362cb320f..057f940ba9 100644
--- a/README.md
+++ b/README.md
@@ -36,11 +36,11 @@ Requires Emacs 24 or later.
 
 ## Limitations
 
-Due to limitations of the SQLite command line program, emacsql is
-*not* intended to play well with other programs accessing the SQLite
-database. Text values and blobs are stored encoded as s-expressions in
-order to avoid ambiguities in parsing output from the command line.
-This is a high-performance database specifically for Emacs.
+Emacsql is *not* intended to play well with other programs accessing
+the SQLite database. Non-numeric values are are stored encoded as
+s-expressions TEXT values. This avoids ambiguities in parsing output
+from the command line and allows for storage of Emacs richer data
+types. This is a high-performance database specifically for Emacs.
 
 
 [readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably



[nongnu] elpa/emacsql 3012f5b725 154/427: Fix typo.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 3012f5b725b5afb680254d46891af970de3648d8
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix typo.
---
 emacsql.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index df5ed36084..79ff8a8d10 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -549,7 +549,7 @@ definitions for return from a `emacsql-defexpander'."
   (cl-ecase (length args)
 (1 (format "-(%s)" (recur 0)))
 (2 (format "%s - %s" (recur 0) (recur 1)
- ;; variadic
+ ;; Variadic
  ((and or)
   (cl-case (length args)
 (0 (if (eq op 'and) "1" "0"))



[nongnu] elpa/emacsql 8951084b40 143/427: Add variable escaping.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 8951084b4006f69525c63b790c02de9b42492b37
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add variable escaping.
---
 README.md|  5 -
 emacsql-tests.el | 12 +---
 emacsql.el   | 26 +++---
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index f680060849..d9e4b8e9ca 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,7 @@ Inside expressions, Emacsql cannot tell the difference 
between symbol
 literals and column references. If you're talking about the symbol
 itself, just quote it as you would in normal Elisp. Note that this
 does not "escape" `$n` variables: it just means the argument gets
-quoted.
+quoted. Use `$$` for escaping variables.
 
 ```el
 [... :where (= category 'hiking)]
@@ -304,6 +304,9 @@ statement in the `emacsql` function, 1-indexed.
 
 (emacsql db [:select * :from $1 :where (> salary $2)] 'employees 5)
 
+To get a literal symbol that looks like one of these variables, escape
+it with an extra dollar sign (i.e. `$$1` becomes `$1`).
+
 ## Limitations
 
 Emacsql is *not* intended to play well with other programs accessing
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 18a36194ce..b4edd8c2bb 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -48,7 +48,9 @@
   (should (eq (emacsql-var '$) 0))
   (should (eq (emacsql-var '$1) 0))
   (should (eq (emacsql-var '$5) 4))
-  (should (eq (emacsql-var '$10) 9)))
+  (should (eq (emacsql-var '$10) 9))
+  (should (eq (emacsql-var '$a) nil))
+  (should (eq (emacsql-var '$$10) '$10)))
 
 (defun emacsql-tests-query (query args result)
   "Check that QUERY outputs RESULT for ARGS."
@@ -150,12 +152,16 @@
 ([:limit [$1 $2]] '(4 30)
  "LIMIT 4, 30;")))
 
-(ert-deftest emacsql-expr ()
+(ert-deftest emacsql-quoting ()
   (emacsql-tests-with-queries
 ([:where (= name 'foo)] '()
  "WHERE name = 'foo';")
 ([:where (= name '$1)] '(qux)
- "WHERE name = 'qux';")))
+ "WHERE name = 'qux';")
+([:where (= name '$$1)] '()
+ "WHERE name = '$1';")
+([:values [a $$1]] '()
+ "VALUES ('a', '$1');")))
 
 (ert-deftest emacsql-system ()
   "A short test that fully interacts with SQLite."
diff --git a/emacsql.el b/emacsql.el
index 9292a0b730..e995f8bce4 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -361,13 +361,15 @@ a list of ( [arg-pos] ...)."
 
 (defun emacsql-var (var)
   "Return the index number of VAR, or nil if VAR is not a variable.
-A variable is a symbol that looks like $1, $2, $3, etc. A $ means $1."
+A variable is a symbol that looks like $1, $2, $3, etc. A $ means
+$1. These are escaped with a double $$, in which case the proper
+symbol is returned."
   (when (symbolp var)
 (let ((name (symbol-name var)))
-  (when (eql (aref name 0) ?$)
-(if (> (length name) 1)
-(1- (read (substring name 1)))
-  0)
+  (cond
+   ((string-match-p "^\\$[0-9]+" name) (1- (read (substring name 1
+   ((string-match-p "^\\$$" name) 0)
+   ((string-match-p "^\\$\\$[0-9]+" name) (intern (substring name 1)))
 
 (defun emacsql-escape-format (thing &optional kind)
   "Escape THING for use as a `format' spec, pre-escaping for KIND.
@@ -384,12 +386,14 @@ KIND should be :value or :identifier."
 
 (defun emacsql--vars-var (thing kind)
   "Only use within `emacsql-with-vars'!"
-  (if (emacsql-var thing)
-  (prog1 "%s" (push (cons (emacsql-var thing) kind) emacsql--vars))
-(cl-ecase kind
-  ((:identifier :value :vector) (emacsql-escape-format thing kind))
-  (:auto (emacsql-escape-format
-  thing (if (symbolp thing) :identifier :value))
+  (let ((var (emacsql-var thing)))
+(when (and var (symbolp var)) (setf thing var))
+(if (numberp var)
+(prog1 "%s" (push (cons var kind) emacsql--vars))
+  (cl-ecase kind
+((:identifier :value :vector) (emacsql-escape-format thing kind))
+(:auto (emacsql-escape-format
+thing (if (symbolp thing) :identifier :value)))
 
 (defun emacsql--vars-combine (expanded)
   "Only use within `emacsql-with-vars'!"



[nongnu] elpa/emacsql afe64ca63a 040/427: Fix emacsql-add-expander example.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit afe64ca63a7a08a651d0efd02ed5cc16c4965f59
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix emacsql-add-expander example.
---
 emacsql.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index ae596c15bd..e130a531a2 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -306,8 +306,8 @@ Each row must be a sequence of values to store into TABLE.
   "Register FUNCTION for KEYWORD as a SQL expander.
 FUNCTION should accept a single argument, the keyword's argument,
 and should return a list of ( [arg-pos] ...)."
-  (push (cons keyword function) emacsql-expanders)
-  :keyword)
+  (prog1 keyword
+(push (cons keyword function) emacsql-expanders)))
 
 (defmacro emacsql-defexpander (keyword args &rest body)
   "Define an expander for KEYWORD."



[nongnu] elpa/emacsql 4fa57ba758 051/427: Fully drop named parsing.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 4fa57ba758fd17e508ffdb949e268836e00f4bbc
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fully drop named parsing.

This is because I'd rather support expressions inside queries.
---
 emacsql.el | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 1c22769a2b..eb6866b143 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -169,18 +169,15 @@ buffer. This is for debugging purposes."
 (buffer-substring
  (- (point-max) 2) (point-max)))
 
-(defun emacsql--parse (conn &rest named)
-  "Parse a query result into an s-expression.
-If NAMED is non-nil, don't include column names."
+(defun emacsql--parse (conn)
+  "Parse a query result into an s-expression."
   (with-current-buffer (emacsql-buffer conn)
 (let ((standard-input (current-buffer)))
   (setf (point) (point-min))
   (cl-loop until (looking-at "#")
-   for name = (read)
-   do (forward-char 3)
+   do (search-forward "=")
for value = (read)
-   when named collect (cons name value) into row
- else collect value into row
+   collect value into row
do (forward-char)
when (or (looking-at "\n") (looking-at "#"))
collect row into rows and do (setf row ())



[nongnu] elpa/emacsql 652847dbf5 110/427: Allow memoization cache to be nil (for development).

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 652847dbf57a476d641b0160f28ee0ba834f2092
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow memoization cache to be nil (for development).
---
 emacsql.el | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 9335f45cbf..4482878968 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -303,7 +303,7 @@ CONN-SPEC is a connection specification like the call to
 FUNCTION should accept the keyword's arguments and should return
 a list of ( [arg-pos] ...)."
   (prog1 keyword
-(clrhash emacsql-expander-cache)
+(when emacsql-expander-cache (clrhash emacsql-expander-cache))
 (push (list keyword arity function) emacsql-expanders)))
 
 (defmacro emacsql-defexpander (keyword args &rest body)
@@ -329,8 +329,9 @@ a list of ( [arg-pos] ...)."
(mapconcat #'car parts " ")
(if subsql-p ")" ";")))
(vars (apply #'nconc (mapcar #'cdr parts
-   (cl-return (setf (gethash sql cache)
-(cons string vars
+   (cl-return (if cache
+  (setf (gethash sql cache) (cons string vars))
+(cons string vars
 
 (defun emacsql-format (expansion &rest args)
   "Fill in the variables EXPANSION with ARGS."



[nongnu] elpa/emacsql 50ae54d159 053/427: Use expressions in select columns.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 50ae54d15932d128bd4429c2695f0531ccbc0f40
Author: Christopher Wellons 
Commit: Christopher Wellons 

Use expressions in select columns.
---
 emacsql.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index ede5b0b288..cd7606bf92 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -419,7 +419,7 @@ definitions for return from a `emacsql-defexpander'."
 (cond
  ((eq '* arg) "*")
  ((vectorp arg)
-  (mapconcat (lambda (s) (var s :identifier)) arg ", "))
+  (mapconcat (lambda (s) (combine (emacsql--expr s))) arg ", "))
  ((var arg :identifier)
 
 (emacsql-defexpander :from (table)



[nongnu] elpa/emacsql 769abe20fa 183/427: Don't rely on a closure in cleanup hook.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 769abe20fa6182d11e283b1737c40ef16e57ccf8
Author: Christopher Wellons 
Commit: Christopher Wellons 

Don't rely on a closure in cleanup hook.

It's unnecessary so just skip it.
---
 emacsql-psql.el   | 2 +-
 emacsql-sqlite.el | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/emacsql-psql.el b/emacsql-psql.el
index 9001cef311..ea6358e371 100644
--- a/emacsql-psql.el
+++ b/emacsql-psql.el
@@ -59,7 +59,7 @@
   :dbname dbname)))
   (prog1 connection
 (setf (process-sentinel process)
-  (lambda (_proc _) (kill-buffer buffer)))
+  (lambda (proc _) (kill-buffer (process-buffer proc
 (when debug
   (setf (emacsql-log-buffer connection)
 (generate-new-buffer "*emacsql-log*")))
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 0fa6c7f3f0..06165cc714 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -51,7 +51,8 @@ buffer. This is for debugging purposes."
  (sqlite3 emacsql-sqlite3-executable)
  (process (start-process "emacsql-sqlite" buffer sqlite3
  "-interactive" fullfile)))
-(setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
+(setf (process-sentinel process)
+  (lambda (proc _) (kill-buffer (process-buffer proc
 (process-send-string process ".mode list\n")
 (process-send-string process ".separator ' '\n")
 (process-send-string process ".nullvalue nil\n")



[nongnu] elpa/emacsql 1f57b77c4f 007/427: Add command logging.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 1f57b77c4fe67ffbacfbeedb925a3515b6dfd909
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add command logging.
---
 emacsql.el | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index a0e9b6a1c3..8c3d91c9ef 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -58,7 +58,7 @@
   "Path to the sqlite3 executable.")
 
 (cl-defstruct (emacsql (:constructor emacsql--create))
-  process file)
+  process file log)
 
 (defvar emacsql-connections ()
   "Collection of all known emacsql connections.
@@ -77,8 +77,11 @@ This collection exists for cleanup purposes.")
   "Retrieve value from REF."
   (gethash t ref))
 
-(defun emacsql-connect (file)
-  "Open a connected to database stored in FILE."
+(cl-defun emacsql-connect (file &key log)
+  "Open a connected to database stored in FILE.
+
+:log LOG -- When non-nil, log all SQLite commands to a log
+buffer. This is for debugging purposes."
   (emacsql-start-reap-timer)
   (let* ((buffer (generate-new-buffer "*emacsql-connection*"))
  (process (start-process "emacsql" buffer sqlite-program-name file)))
@@ -86,6 +89,8 @@ This collection exists for cleanup purposes.")
 (process-send-string process ".prompt #\n")
 (process-send-string process ".mode line\n")
 (let ((emacsql (emacsql--create :process process :file file)))
+  (when log
+(setf (emacsql-log emacsql) (generate-new-buffer "*emacsql-log*")))
   (prog1 emacsql
 (push (cons (copy-seq emacsql) (emacsql--ref emacsql))
   emacsql-connections)
@@ -122,9 +127,17 @@ This collection exists for cleanup purposes.")
 (cancel-timer emacsql-reap-timer)
 (setf emacsql-reap-timer nil)))
 
+(defun emacsql--log (emacsql &rest messages)
+  (let ((log (emacsql-log emacsql)))
+(when log
+  (with-current-buffer log
+(setf (point) (point-max))
+(mapc (lambda (s) (princ s log)) messages)
+
 (defun emacsql--send (emacsql string)
   "Send STRING to EMACSQL, automatically appending newline."
   (let ((process (emacsql-process emacsql)))
+(emacsql--log emacsql string "\n")
 (process-send-string process string)
 (process-send-string process "\n")))
 



[nongnu] elpa/emacsql 3511a0df1d 037/427: Add a top-level query function, emacsql.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 3511a0df1d1a19d7be0b2507e16330eff6b12470
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add a top-level query function, emacsql.
---
 emacsql.el | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index 07a2b97901..ebb62d31b8 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -292,7 +292,7 @@ Each row must be a sequence of values to store into TABLE.
   (emacsql--check-error conn)
   (emacsql--parse conn))
 
-;; SQL Expansion Functions
+;; SQL Expansion:
 
 (defvar emacsql-expanders ()
   "Alist of all expansion functions.")
@@ -327,6 +327,13 @@ and should return a list of ( [arg-pos] ...)."
   (:identifier (emacsql-escape (nth i args)))
   (:value (emacsql-escape-value (nth i args
 
+(defun emacsql (conn sql &optional args)
+  "Send structured SQL expression to CONN with ARGS."
+  (emacsql--clear conn)
+  (emacsql--send conn (apply #'emacsql-format (emacsql-expand sql) args))
+  (emacsql--check-error conn)
+  (emacsql--parse conn))
+
 (defun emacsql-var (var)
   "Return the index number of VAR, or nil if VAR is not a variable.
 A variable is a symbol that looks like $1, $2, $3, etc. A $ means $1."
@@ -346,6 +353,8 @@ KIND should be :value or :identifier."
   (:identifier (emacsql-escape thing))
   (otherwise thing
 
+;; SQL Expansion Functions:
+
 (emacsql-defexpander :select (arg)
   "Expands to the SELECT keyword."
   (let ((vars ()))



[nongnu] elpa/emacsql 578a71d2d8 157/427: Re-order some definitions to group them.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 578a71d2d8fca0da023197e1dbd014ca8f1cdaa0
Author: Christopher Wellons 
Commit: Christopher Wellons 

Re-order some definitions to group them.
---
 emacsql.el | 72 ++
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 2196d282ed..abec8f6771 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -61,10 +61,34 @@
 (defvar emacsql-sqlite3-executable "sqlite3"
   "Path to the sqlite3 executable.")
 
+(defun emacsql-sqlite3-unavailable-p ()
+  "Return a reason if the sqlite3 executable is not available.
+
+:no-executable -- cannot find the executable
+:cannot-execute -- cannot run the executable
+:old-version -- sqlite3 version is too old"
+  (let ((sqlite3 emacsql-sqlite3-executable))
+(if (null (executable-find sqlite3))
+:no-executable
+  (condition-case _
+  (with-temp-buffer
+(call-process sqlite3 nil (current-buffer) nil "--version")
+(let ((version (car (split-string (buffer-string)
+  (if (version< version "3.7.15")
+  :old-version
+nil)))
+(error :cannot-execute)
+
+;;; Connection handling:
+
 (cl-defstruct (emacsql (:constructor emacsql--create))
   "A connection to a SQLite database."
   process file log)
 
+(defun emacsql-buffer (conn)
+  "Get proccess buffer for CONN."
+  (process-buffer (emacsql-process conn)))
+
 (defvar emacsql-connections ()
   "Collection of all known emacsql connections.
 This collection exists for cleanup purposes.")
@@ -90,24 +114,6 @@ This collection exists for cleanup purposes.")
  do (accept-process-output)))
   (emacsql--clear conn))
 
-(defun emacsql-sqlite3-unavailable-p ()
-  "Return a reason if the sqlite3 executable is not available.
-
-:no-executable -- cannot find the executable
-:cannot-execute -- cannot run the executable
-:old-version -- sqlite3 version is too old"
-  (let ((sqlite3 emacsql-sqlite3-executable))
-(if (null (executable-find sqlite3))
-:no-executable
-  (condition-case _
-  (with-temp-buffer
-(call-process sqlite3 nil (current-buffer) nil "--version")
-(let ((version (car (split-string (buffer-string)
-  (if (version< version "3.7.15")
-  :old-version
-nil)))
-(error :cannot-execute)
-
 (cl-defun emacsql-connect (file &key log)
   "Open a connected to database stored in FILE.
 If FILE is nil use an in-memory database.
@@ -163,10 +169,6 @@ A statement can be a list, containing a statement with its 
arguments."
else
collect (append (list 'emacsql 'emacsql--conn) statement
 
-(defun emacsql-buffer (conn)
-  "Get proccess buffer for CONN."
-  (process-buffer (emacsql-process conn)))
-
 (defun emacsql-reap ()
   "Clean up after lost connections."
   (cl-loop for (conn-copy . ref) in emacsql-connections
@@ -189,6 +191,8 @@ A statement can be a list, containing a statement with its 
arguments."
 (cancel-timer emacsql-reap-timer)
 (setf emacsql-reap-timer nil)))
 
+;;; Sending and receiving:
+
 (defun emacsql--log (conn &rest messages)
   "Log MESSAGES into CONN's log."
   (let ((log (emacsql-log conn)))
@@ -231,6 +235,18 @@ A statement can be a list, containing a statement with its 
arguments."
collect row into rows and do (setf row ())
finally (cl-return rows)
 
+(defun emacsql--check-error (conn)
+  "Return non-nil or throw an appropriate error."
+  (with-current-buffer (emacsql-buffer conn)
+(emacsql-wait conn)
+(setf (point) (point-min))
+(prog1 t
+  (when (looking-at "Error:")
+(error (buffer-substring (line-beginning-position)
+ (line-end-position)))
+
+;;; Escaping:
+
 (defun emacsql-quote (string)
   "Quote STRING for use in a SQL expression."
   (format "'%s'" (replace-regexp-in-string "'" "''" string)))
@@ -249,16 +265,6 @@ A statement can be a list, containing a statement with its 
arguments."
 (replace-regexp-in-string ":" "." string)
   string)))
 
-(defun emacsql--check-error (conn)
-  "Return non-nil or throw an appropriate error."
-  (with-current-buffer (emacsql-buffer conn)
-(emacsql-wait conn)
-(setf (point) (point-min))
-(prog1 t
-  (when (looking-at "Error:")
-(error (buffer-substring (line-beginning-position)
- (line-end-position)))
-
 (defun emacsql-wait (conn &optional timeout)
   "Block Emacs until CONN has finished sending output."
   (let ((end (when timeout (+ (float-time) timeout
@@ -279,7 +285,7 @@ A statement can be a list, containing a statement with its 
arguments."
 (list   (mapconcat #'emacsql-escape-vector vector ", "))
 (vector (concat "(" (mapconcat #'emacsql-escape-value vector ", ") ")"
 
-;; SQL Expansion:
+;; Structured SQL compilation:
 
 (def

[nongnu] elpa/emacsql ba2fac7701 228/427: Update the README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit ba2fac77013d7b780e42ddba6e29604c13f3db25
Author: Christopher Wellons 
Commit: Christopher Wellons 

Update the README.
---
 README.md | 42 +++---
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index 3a21197ea6..e27330ff1e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,14 @@
 # Emacsql
 
 Emacsql is a high-level Emacs Lisp front-end for SQLite (primarily),
-PostgreSQL, and potentially other SQL databases. It is currently a
-work-in-progress (90% complete) because the s-expression query
-language is still being hammered out.
+PostgreSQL, and potentially other SQL databases.
 
-It works by keeping a `sqlite3` (or `psql`) inferior process running
-(a "connection") for interacting with the back-end database.
-Connections are automatically cleaned up if they are garbage
-collected. All requests are synchronous.
+It is currently a work-in-progress (around 90% complete).
+
+It works by maintaining a inferior process running (a "connection")
+for interacting with the back-end database. Connections are
+automatically cleaned up if they are garbage collected. All requests
+are synchronous.
 
 Any [readable lisp value][readable] can be stored as a value in
 Emacsql, including numbers, strings, symbols, lists, vectors, and
@@ -16,20 +16,19 @@ closures. Emacsql has no concept of "TEXT" values; it's all 
just lisp
 objects. The lisp object `nil` corresponds 1:1 with `NULL` in the
 database.
 
-Requires Emacs 24 or later.
-
-### Windows Issues
+This package includes custom native binaries for communicating with a
+SQLite database. When linked with GNU Readline, or when run in
+Windows, the official sqlite3 command shell is incapable of correct
+interaction. If your package depends on Emacsql it also means you
+don't have to rely on the user having particular software installed.
 
-Due to [bad behavior from both SQLite and Windows][stderr] the
-official SQLite command shell binary will *not* work with Emacsql on
-Windows. Fortunately, [this simple patch][patch] corrects the issue.
-Here's a build with the fix:
+Requires Emacs 24 or later.
 
- * [sqlite3.exe][exe] (3.8.2, [asc][asc])
+### Windows Issue
 
-Also, due to a [long-standing Emacs bug][batch], Emacsql cannot be
-used in Emacs' "-batch" mode on Windows, which includes running the
-Emacsql test suite from the Makefile.
+Due to a [long-standing Emacs bug][batch], Emacsql cannot be used in
+Emacs' "-batch" mode on Windows, which includes running the Emacsql
+test suite from the Makefile.
 
 ## Example Usage
 
@@ -422,7 +421,7 @@ probably will never be.
 
  * Collating. SQLite has three built-in collation functions: BINARY
(default), NOCASE, and RTRIM. Emacsql values never have right-hand
-   whitepsace, so RTRIM won't be of any use. NOCASE is broken
+   whitespace, so RTRIM won't be of any use. NOCASE is broken
(ASCII-only) and there's little reason to use it.
 
  * Databases attachments. I don't expect any program using Emacsql to
@@ -463,7 +462,7 @@ inherits from `emacsql-connection`.
 
 The provided implementations should serve as useful examples. If your
 back-end outputs data in a clean, standard way you may be able to use
-the emacsql-simple-parser mixin class to do most of the work.
+the emacsql-protocol-mixin class to do most of the work.
 
 ## See Also
 
@@ -473,8 +472,5 @@ the emacsql-simple-parser mixin class to do most of the 
work.
 [readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably
 [stderr]: http://thread.gmane.org/gmane.comp.db.sqlite.general/85824
 [foreign]: http://www.sqlite.org/foreignkeys.html
-[patch]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-stderr-fix.patch
-[exe]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-3.8.2-fixed.exe
-[asc]: http://skeeto.s3.amazonaws.com/emacs/sqlite3-3.8.2-fixed.exe.asc
 [batch]: 
http://lists.gnu.org/archive/html/emacs-pretest-bug/2005-11/msg00320.html
 [cask]: http://cask.github.io/



[nongnu] elpa/emacsql adfbc7ed83 156/427: Add emacsql-show-last-sql.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit adfbc7ed837d5757c5681d5d2e830c3d43b3201a
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add emacsql-show-last-sql.
---
 README.md  |  4 
 emacsql.el | 48 
 2 files changed, 52 insertions(+)

diff --git a/README.md b/README.md
index 12a8faa210..d1998e8d6c 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,10 @@ shouldn't impact normal use of the database.
 ;; => (("Jeff" 1000) ("Susan" 1001))
 ```
 
+When editing these structured SQL statements, the `M-x
+emacsql-show-last-sql` command (think `eval-last-sexp`) is useful for
+seeing what the actual SQL expression will become when compiled.
+
 ## Schema
 
 A table schema is a vector of column specifications, or a list
diff --git a/emacsql.el b/emacsql.el
index 64993134b7..2196d282ed 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -711,6 +711,54 @@ definitions for return from a `emacsql-defexpander'."
 (emacsql-defexpander :vacuum ()
   (list "VACUUM"))
 
+;; User interaction functions:
+
+(defvar emacsql-show-buffer-name "*emacsql-show*"
+  "Name of the buffer for displaying intermediate SQL.")
+
+(defun emacsql--indent ()
+  "Indent and wrap the SQL expression in the current buffer."
+  (interactive)
+  (save-excursion
+(setf (point) (point-min))
+(let ((case-fold-search nil))
+  (while (search-forward-regexp " [A-Z]+" nil :no-error)
+(when (> (current-column) (* fill-column 0.8))
+  (backward-word)
+  (insert "\n"))
+
+(defun emacsql-show-sql (string)
+  "Fontify and display the SQL expression in STRING."
+  (let ((fontified
+ (with-temp-buffer
+   (insert string)
+   (sql-mode)
+   (with-no-warnings ;; autoloaded by previous line
+ (sql-highlight-sqlite-keywords))
+   (font-lock-fontify-buffer)
+   (emacsql--indent)
+   (buffer-string
+(with-current-buffer (get-buffer-create emacsql-show-buffer-name)
+  (if (< (length string) fill-column)
+  (message "%s" fontified)
+(let ((buffer-read-only nil))
+  (erase-buffer)
+  (insert fontified))
+(special-mode)
+(visual-line-mode)
+(pop-to-buffer (current-buffer))
+
+(defun emacsql-flatten-sql (sql)
+  "Convert a structured SQL into a flat string for display."
+  (cl-destructuring-bind (string . vars) (emacsql-expand sql)
+(apply #'format string (cl-loop for i from 1 to (length vars)
+collect (intern (format "$%d" i))
+
+(defun emacsql-show-last-sql ()
+  "Display the compiled SQL of the structured SQL expression before point."
+  (interactive)
+  (emacsql-show-sql (emacsql-flatten-sql (preceding-sexp
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql 76a430032e 014/427: Fix up old test.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 76a430032ef22de5d19fe82ad15b4e0371999d7c
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix up old test.
---
 emacsql-tests.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 31a3921c5c..d1bcd2f41c 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -10,7 +10,7 @@
   (should (string= (emacsql-escape "they're") "'they''re'")))
 
 (ert-deftest emacsql-escape-value ()
-  (should (string= (emacsql-escape-value 'foo) "foo"))
+  (should (string= (emacsql-escape-value 'foo) "'foo'"))
   (should (string= (emacsql-escape-value "foo") "'\"foo\"'"))
   (should (string= (emacsql-escape-value :foo) "':foo'"))
   (should (string= (emacsql-escape-value [1 2 3]) "'[1 2 3]'"))



[nongnu] elpa/emacsql 4718ff4e89 122/427: Simplify all the expanders with new local functions.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 4718ff4e899a7ce9bd9a662c2ae083e99a128d6a
Author: Christopher Wellons 
Commit: Christopher Wellons 

Simplify all the expanders with new local functions.
---
 emacsql.el | 35 ---
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 20b04eb632..9b428ab93f 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -401,13 +401,6 @@ KIND should be :value or :identifier."
 (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-var (thing kind)
   "Only use within `emacsql-with-vars'!"
   (if (emacsql-var thing)
@@ -424,20 +417,17 @@ KIND should be :value or :identifier."
 string))
 
 (defmacro emacsql-with-vars (prefix &rest body)
-  "Evaluate BODY, collecting variables with `var' and `combine'.
+  "Evaluate BODY, collecting variables with `var', `combine', `expr', `idents'.
 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-var))
-   ((emacsql-symbol-function 'combine)
-(symbol-function 'emacsql--vars-combine)))
+ (cl-flet* ((var (thing kind) (emacsql--vars-var thing kind))
+(combine (expanded) (emacsql--vars-combine expanded))
+(expr (thing) (combine (emacsql--expr thing)))
+(idents (thing) (combine (emacsql--idents thing
(cons (concat ,prefix (progn ,@body)) emacsql--vars
 
-(declare-function combine nil (expanded))
-(declare-function var nil (thing kind))
-
 (defun emacsql--vector (vector)
   "Expand VECTOR, making variables as needed."
   (emacsql-with-vars ""
@@ -499,8 +489,7 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars ""
 (cl-etypecase idents
   (symbol (var idents :identifier))
-  (vector (mapconcat (lambda (e) (combine (emacsql--expr e)))
- idents ", ")
+  (vector (mapconcat (lambda (e) (expr e)) idents ", ")
 
 (defun emacsql-init-font-lock ()
   "Add font-lock highlighting for `emacsql-defexpander'."
@@ -516,7 +505,7 @@ definitions for return from a `emacsql-defexpander'."
   (emacsql-with-vars "SELECT "
 (if (eq '* arg)
 "*"
-  (combine (emacsql--idents arg)
+  (idents arg
 
 (emacsql-defexpander :from (table)
   "Expands to the FROM keyword."
@@ -536,15 +525,15 @@ definitions for return from a `emacsql-defexpander'."
   (symbol (var table :identifier))
   (list (cl-destructuring-bind (name columns) table
   (format "%s (%s)" (var name :identifier)
-  (combine (emacsql--idents columns
+  (idents columns)))
 
 (emacsql-defexpander :where (expr)
   (emacsql-with-vars "WHERE "
-(combine (emacsql--expr expr
+(expr expr)))
 
 (emacsql-defexpander :group-by (expr)
   (emacsql-with-vars "GROUP BY "
-(combine (emacsql--expr expr
+(expr expr)))
 
 (emacsql-defexpander :ascending-by (columns)
   (emacsql-with-vars "ORDER BY "
@@ -585,8 +574,8 @@ definitions for return from a `emacsql-defexpander'."
 (emacsql-defexpander :set (set)
   (emacsql-with-vars "SET "
 (cl-etypecase set
-  (vector (combine (emacsql--idents set)))
-  (list (combine (emacsql--expr set))
+  (vector (idents set))
+  (list (expr set)
 
 (emacsql-defexpander :union ()
   (list "UNION"))



[nongnu] elpa/emacsql d8d4bf4b98 202/427: Add emacsql-with-transaction macro.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit d8d4bf4b98c36b50ab9c57e1b6892328ae1084c4
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add emacsql-with-transaction macro.
---
 emacsql.el | 24 
 1 file changed, 24 insertions(+)

diff --git a/emacsql.el b/emacsql.el
index 5e8562be48..37ac8cc966 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -228,6 +228,30 @@ A statement can be a list, containing a statement with its 
arguments."
else
collect (append (list 'emacsql 'emacsql--conn) statement
 
+(defvar emacsql--transaction-level 0
+  "Keeps track of nested transactions in `emacsql-with-transaction'.")
+
+(defmacro emacsql-with-transaction (connection &rest body)
+  "Evaluate BODY inside a single transaction, issuing a rollback on error.
+This macro can be nested indefinitely, wrapping everything in a
+single transaction at the lowest level."
+  (declare (indent 1))
+  `(let ((emacsql--connection ,connection)
+ (emacsql--completed nil)
+ (emacsql--transaction-level (1+ emacsql--transaction-level)))
+ (unwind-protect
+ (progn
+   (when (= 1 emacsql--transaction-level)
+ (emacsql emacsql--connection [:begin :transaction]))
+   (let ((result (progn ,@body)))
+ (prog1 result
+   (when (= 1 emacsql--transaction-level)
+ (emacsql emacsql--connection [:commit]))
+   (setf emacsql--completed t
+   (when (and (= 1 emacsql--transaction-level)
+  (not emacsql--completed))
+ (emacsql emacsql--connection [:rollback])
+
 ;; User interaction functions:
 
 (defvar emacsql-show-buffer-name "*emacsql-show*"



[nongnu] elpa/emacsql 54247e4b5e 127/427: Add another insertion unit test.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 54247e4b5e65a4e7b803cd73afe638cd82963c92
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add another insertion unit test.
---
 emacsql-tests.el | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 377e5a794c..3d048e3849 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -88,6 +88,8 @@
   (emacsql-tests-with-queries
 ([:insert :into foo :values [nil $1]] '(10.1)
  "INSERT INTO foo VALUES (NULL, 10.1);")
+([:insert :into (foo [a b]) :values $1] '([1 2])
+ "INSERT INTO foo (a, b) VALUES (1, 2);")
 ([:replace :into $1 :values $2] '(bar ([1 2] [3 4]))
  "REPLACE INTO bar VALUES (1, 2), (3, 4);")))
 



[nongnu] elpa/emacsql d440b44778 076/427: Add escape vector test.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit d440b447788b2b3d615ada91d6a836448c244125
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add escape vector test.
---
 emacsql-tests.el | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 38fc5e0300..42adb83255 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -22,6 +22,12 @@
   (should (string= (emacsql-escape-value '(a b c)) "'(a b c)'"))
   (should (string= (emacsql-escape-value nil) "NULL")))
 
+(ert-deftest emacsql-escape-vector ()
+  (should (string= (emacsql-escape-vector [1 2 3]) "(1, 2, 3)"))
+  (should (string= (emacsql-escape-vector '([1 2 3])) "(1, 2, 3)"))
+  (should (string= (emacsql-escape-vector '([1 2 3] [4 5 6]))
+   "(1, 2, 3), (4, 5, 6)")))
+
 (ert-deftest emacsql-schema ()
   (should (string= (emacsql--schema-to-string [a]) "a"))
   (should (string= (emacsql--schema-to-string [a b c]) "a, b, c"))



[nongnu] elpa/emacsql f179ba928a 047/427: Add :drop-table expander.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f179ba928a98a7a71db0c298f73205cd95eb9682
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :drop-table expander.
---
 emacsql-tests.el | 4 +++-
 emacsql.el   | 9 -
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index f27fd23860..63ba565522 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -50,4 +50,6 @@
   (emacsql-tests-query [:select * :from employees :where (< salary 5)] ()
"SELECT * FROM employees WHERE salary < 5;")
   (emacsql-tests-query [:create-table foo [a b c]] ()
-   "CREATE TABLE foo (a, b, c);"))
+   "CREATE TABLE foo (a, b, c);")
+  (emacsql-tests-query [:drop-table $1] '(foo)
+   "DROP TABLE foo;"))
diff --git a/emacsql.el b/emacsql.el
index be59bc2977..97d2638a52 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -265,11 +265,6 @@ If NAMED is non-nil, don't include column names."
  (emacsql-escape table)
  (emacsql--schema-to-string schema)
 
-(defun emacsql-drop (conn table)
-  "Drop TABLE from CONN."
-  (emacsql-with-errors conn
-(emacsql--send conn (format "DROP TABLE %s;" (emacsql-escape table)
-
 (defun emacsql-escape-value (value)
   "Escape VALUE for sending to SQLite."
   (let ((print-escape-newlines t))
@@ -416,6 +411,10 @@ definitions for return from a `emacsql-defexpander'."
 (format "%s (%s)" (var table :identifier)
 (emacsql--schema-to-string schema
 
+(emacsql-defexpander :drop-table (table)
+  (emacsql-with-vars "DROP TABLE "
+(var table :identifier)))
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql a362a97c98 136/427: Add README section on foreign keys.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit a362a97c98569045056a4be576ffa4c137aa0814
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add README section on foreign keys.
---
 README.md | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9a9c7764be..e58c86ce2b 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ allowed) types are `integer`, `float`, and `object` (default).
 Columns constraints include `:primary` (aka `PRIMARY KEY`), `:unique`,
 `:non-nil` (aka `NOT NULL`), `:default`, and `:check`.
 
-Table constraints can be `:primary`, `:unique`, and `:check`.
+Table constraints can be `:primary`, `:unique`, `:check`, and `:foreign`.
 
 ```el
 ;; No constraints schema with four columns:
@@ -77,6 +77,25 @@ Table constraints can be `:primary`, `:unique`, and `:check`.
  :unique [building room] :check ())
 ```
 
+Foreign keys are the most complex. Action triggers are `:on-delete`
+or `:on-update` and possible actions are `:set-nil`, `:set-default`,
+`:restrict`, `:cascade`. See [the SQLite documentation][foreign] for
+the details on what each of these means.
+
+`:foreign (   [])`.
+
+```el
+;; "subject" table
+[(id integer :primary) subject]
+
+;; "tag" table references subjects
+([(subjectid integer) tag]
+ :foreign (subjectid subject id :on-delete :cascade))
+```
+
+Put the keys in a vector if the reference is composite, but remember
+that the cardinality must match.
+
 ## Operators
 
 Emacsql currently supports the following expression operators, named
@@ -276,3 +295,4 @@ types. This is a high-performance database specifically for 
Emacs.
 
 [readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably
 [stderr]: http://thread.gmane.org/gmane.comp.db.sqlite.general/85824
+[foreign]: http://www.sqlite.org/foreignkeys.html



[nongnu] elpa/emacsql f31120edb6 155/427: Fix up documentation headers.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit f31120edb6fe347ab9c81cf29df94a1709e42ed2
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix up documentation headers.
---
 README.md  |  2 +-
 emacsql.el | 31 +++
 2 files changed, 12 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index bd92bb97f1..12a8faa210 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ shouldn't impact normal use of the database.
 ```el
 (defvar db (emacsql-connect "/var/lib/company.db"))
 
-;; Create a table. A table identifier can be any kind of lisp value.
+;; Create a table. Table and column identifiers are symbols.
 (emacsql db [:create-table people [name id salary]])
 
 ;; Or optionally provide column constraints.
diff --git a/emacsql.el b/emacsql.el
index 79ff8a8d10..64993134b7 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -10,9 +10,9 @@
 ;;; Commentary:
 
 ;; The purpose of this package is to provide a high-level Elisp
-;; interface to a high-performance database backend. Not every last
-;; feature of SQLite will be exposed at the high-level, but most of it
-;; should be.
+;; interface to a high-performance database backend. Not every feature
+;; of SQLite will be exposed at the high-level, but most of it should
+;; be.
 
 ;; Every emacsql function operates on a database connection
 ;; established with `emacsql-connect', connecting to a SQLite database
@@ -21,20 +21,17 @@
 
 ;; (defvar db (emacsql-connect "company.db"))
 
-;; Database connections are automatically closed when the connection
-;; object is garbage collected. Though this doesn't excuse poor coding
-;; habits! :-)
-
-;; Table identifiers can be any lisp object: string, symbol, etc. I
-;; suggest using a symbol. Use `emacsql-create' to create a table.
+;; Identifiers for tables and columns are symbols. SQL keywords are
+;; lisp keywords. Use `emacsql' for sending structured statements to
+;; the database.
 
 ;; (emacsql db [:create-table people [name id salary]])
 
-;; Column constraints can optionally be provided.
+;; Column constraints can optionally be provided in the schema.
 
 ;; (emacsql db [:create-table people [name (id integer :unique) salary]])
 
-;; Insert values into a table with `emacsql-insert'.
+;; Insert some values.
 
 ;; (emacsql db [:insert :into people
 ;;  :values (["Jeff"  1000 6.0] ["Susan" 1001 64000.0])])
@@ -47,21 +44,15 @@
 ;; (emacsql db [:select [name id] :from employees :where (> salary 6)])
 ;; ;; => (("Susan" 1001))
 
-;; Queries can be templates using $1, $2, etc.:
+;; Queries can be templates -- $1, $2, etc. -- so they don't need to
+;; be built up dynamically:
 
 ;; (emacsql db
 ;;  [:select [name id] :from employees :where (> salary $1)]
 ;;  5)
 ;; ;; => (("Jeff" 1000) ("Susan" 1001))
 
-;; Limitations:
-
-;; Due to limitations of the SQLite command line program, emacsql is
-;; *not* intended to play well with other programs accessing the
-;; SQLite database. Text values and blobs are stored encoded as
-;; s-expressions in order to avoid ambiguities in parsing output from
-;; the command line. This is a high-performance database specifically
-;; for Emacs.
+;; See README.md for much more complete documentation.
 
 ;;; Code:
 



[nongnu] elpa/emacsql 1074113f03 016/427: Add readability note.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 1074113f03778bb52163d17615595366dda07fc8
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add readability note.
---
 README.md | 8 
 1 file changed, 8 insertions(+)

diff --git a/README.md b/README.md
index 1cf833ea4b..47f437eb54 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,11 @@ It works by keeping a `sqlite3` inferior process running (a
 are automatically cleaned up if they are garbage collected. All
 requests are synchronous.
 
+Any [readable lisp value][readable] can be stored as values in
+Emacsql, including numbers, strings, symbols, lists, vectors, and
+closures. Emacsql has no concept of "TEXT" values, it's all just lisp
+objects.
+
 Requires Emacs 24 or later.
 
 ```el
@@ -36,3 +41,6 @@ Due to limitations of the SQLite command line program, 
emacsql is
 database. Text values and blobs are stored encoded as s-expressions in
 order to avoid ambiguities in parsing output from the command line.
 This is a high-performance database specifically for Emacs.
+
+
+[readable]: 
http://nullprogram.com/blog/2013/12/30/#almost_everything_prints_readably



[nongnu] elpa/emacsql ed86b098ce 197/427: Add prefix arg to emacsql-show-last-sql.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit ed86b098ce341997058e6fa4c06a84c96ed7ee2d
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add prefix arg to emacsql-show-last-sql.
---
 emacsql.el | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 623c340a25..e8f4a36a02 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -272,9 +272,13 @@ A statement can be a list, containing a statement with its 
arguments."
 collect (intern (format "$%d" i))
 
 ;;;###autoload
-(defun emacsql-show-last-sql ()
-  "Display the compiled SQL of the s-expression SQL expression before point."
-  (interactive)
-  (emacsql-show-sql (emacsql-flatten-sql (preceding-sexp
+(defun emacsql-show-last-sql (&optional prefix)
+  "Display the compiled SQL of the s-expression SQL expression before point.
+A prefix argument causes the SQL to be printed into the current buffer."
+  (interactive "P")
+  (let ((sql (emacsql-flatten-sql (preceding-sexp
+(if prefix
+(insert sql)
+  (emacsql-show-sql 
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql 458b8a6acd 074/427: Add :insert and :values expanders.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 458b8a6acdf7157dfb328a1b7f5885c6c3ee23d2
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :insert and :values expanders.
---
 emacsql.el | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/emacsql.el b/emacsql.el
index 8aa0a67968..5dd6ba7fed 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -476,6 +476,13 @@ definitions for return from a `emacsql-defexpander'."
 (emacsql-defexpander :delete ()
   (list "DELETE"))
 
+(emacsql-defexpander :insert ()
+  (list "INSERT"))
+
+(emacsql-defexpander :values (values)
+  (emacsql-with-vars "VALUES "
+(var values :vector)))
+
 (provide 'emacsql)
 
 ;;; emacsql.el ends here



[nongnu] elpa/emacsql eb3283990e 077/427: Drop emacsql-create.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit eb3283990ebbc15bffa8da17f7e77fd67070ae69
Author: Christopher Wellons 
Commit: Christopher Wellons 

Drop emacsql-create.
---
 emacsql.el | 12 
 1 file changed, 12 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index c0fa338734..cd75907f7b 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -255,18 +255,6 @@ buffer. This is for debugging purposes."
else collect (emacsql--column-to-string column) into parts
finally (cl-return (mapconcat #'identity parts ", "
 
-(defun emacsql-create (conn table schema &optional if-not-exists)
-  "Create TABLE in CONN with SCHEMA."
-  (when (= 0 (length schema))
-(error "Schema must not be empty."))
-  (emacsql-with-errors conn
-(emacsql--send
- conn
- (format "CREATE TABLE %s%s (%s);"
- (if if-not-exists "IF NOT EXISTS " "")
- (emacsql-escape table)
- (emacsql--schema-to-string schema)
-
 (defun emacsql-escape-value (value)
   "Escape VALUE for sending to SQLite."
   (let ((print-escape-newlines t))



[nongnu] elpa/emacsql ef976b8649 189/427: Add package target for Makefile.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit ef976b8649dd59f8539fd17de91319411d141859
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add package target for Makefile.
---
 .gitignore |  1 +
 Makefile   | 15 ++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/.gitignore b/.gitignore
index c531d9867f..ef8cdbb022 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 *.elc
+*.tar
diff --git a/Makefile b/Makefile
index dc9bb14523..7057a2cb80 100644
--- a/Makefile
+++ b/Makefile
@@ -1,26 +1,31 @@
 PACKAGE  = emacsql
+VERSION := $(word 1,$(subst -, ,$(shell git describe)))
 
 EMACS   ?= emacs
 BATCH   := $(EMACS) -batch -Q -L .
 COMPILE := $(BATCH) -f batch-byte-compile
-TEST:= $(BATCH) -l $(PACKAGE)-tests.elc -f ert-run-tests-batch
 
 EL = emacsql-reap.el emacsql-compiler.el emacsql.el emacsql-sqlite.el \
  emacsql-psql.el emacsql-tests.el
-
 ELC = $(EL:.el=.elc)
+EXTRA_DIST = README.md UNLICENSE
 
-.PHONY : all compile test clean
+.PHONY : all compile package test clean
 
 all : test
 
 compile: $(ELC)
 
+package : $(PACKAGE)-$(VERSION).tar
+
+$(PACKAGE)-$(VERSION).tar : $(EL) $(PACKAGE)-pkg.el $(EXTRA_DIST)
+   tar -cf $@ --transform "s,^,$(PACKAGE)-$(VERSION)/," $^
+
 test: compile
-   $(TEST)
+   $(BATCH) -l $(PACKAGE)-tests.elc -f ert-run-tests-batch
 
 clean:
-   $(RM) *.elc
+   $(RM) *.tar $(ELC)
 
 %.elc: %.el
$(COMPILE) $<



[nongnu] elpa/emacsql 301e2ff4b6 175/427: Drop "simple" from helper method names.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 301e2ff4b6b43981b6df7b92330c4767f8f88ec3
Author: Christopher Wellons 
Commit: Christopher Wellons 

Drop "simple" from helper method names.
---
 emacsql-psql.el   | 4 ++--
 emacsql-sqlite.el | 4 ++--
 emacsql.el| 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/emacsql-psql.el b/emacsql-psql.el
index f7a895ef2b..47ed1e0eb7 100644
--- a/emacsql-psql.el
+++ b/emacsql-psql.el
@@ -75,10 +75,10 @@
 (emacsql-clear connection)
 (emacsql-send-string connection sql-string)
 (emacsql-wait connection)
-(let ((error (emacsql-simple-error-check connection)))
+(let ((error (emacsql-error-check connection)))
   (if error
   (signal 'emacsql-error (list error))
-(emacsql-simple-parse connection)
+(emacsql-parse connection)
 
 (provide 'emacsql-psql)
 
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 63018cb6a8..5b5905910b 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -127,10 +127,10 @@ buffer. This is for debugging purposes."
 (emacsql-clear connection)
 (emacsql-send-string connection sql-string)
 (emacsql-wait connection)
-(let ((error (emacsql-simple-error-check connection)))
+(let ((error (emacsql-error-check connection)))
   (if error
   (signal (emacsql-sqlite-get-condition error) (list error))
-(emacsql-simple-parse connection)
+(emacsql-parse connection)
 
 (provide 'emacsql-sqlite)
 
diff --git a/emacsql.el b/emacsql.el
index e3f6f2067c..a81cd8eea5 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -156,7 +156,7 @@ This prompt value was chosen because it is unreadable."
 (buffer-substring
  (- (point-max) 2) (point-max)))
 
-(defmethod emacsql-simple-parse ((connection emacsql-simple-parser))
+(defmethod emacsql-parse ((connection emacsql-simple-parser))
   "Parse output into an s-expression.
 Output should have one row per line, separated by whitespace."
   (with-current-buffer (emacsql-buffer connection)
@@ -169,7 +169,7 @@ Output should have one row per line, separated by 
whitespace."
and do (progn (forward-char 1) (setf row ()))
finally (cl-return rows)
 
-(defmethod emacsql-simple-error-check ((connection emacsql-simple-parser))
+(defmethod emacsql-error-check ((connection emacsql-simple-parser))
   "Return the error message from CONNECTION, or nil for no error."
   (with-current-buffer (emacsql-buffer connection)
 (let ((case-fold-search t))



[nongnu] elpa/emacsql b447994514 033/427: Change table type recommendation.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit b4479945141462bad282f4b81ddf397c01986705
Author: Christopher Wellons 
Commit: Christopher Wellons 

Change table type recommendation.
---
 README.md  | 8 
 emacsql.el | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 3f26389b00..f288c265ee 100644
--- a/README.md
+++ b/README.md
@@ -19,17 +19,17 @@ Requires Emacs 24 or later.
 (defvar db (emacsql-connect "company.db"))
 
 ;; Create a table. A table identifier can be any kind of lisp value.
-(emacsql-create db :employees [name id salary])
+(emacsql-create db 'employees [name id salary])
 
 ;; Or optionally provide column constraints.
-(emacsql-create db :employees [name (id integer :unique) (salary float)])
+(emacsql-create db 'employees [name (id integer :unique) (salary float)])
 
 ;; Insert some data:
-(emacsql-insert db :employees ["Jeff"  1000 6.0]
+(emacsql-insert db 'employees ["Jeff"  1000 6.0]
   ["Susan" 1001 64000.0])
 
 ;; The high-level SELECT interface is a work in progress.
-(emacsql-select-raw db (concat "SELECT name, id FROM ':employees' "
+(emacsql-select-raw db (concat "SELECT name, id FROM employees "
"WHERE salary > 6;"))
 ;; => (("Susan" 1001))
 ```
diff --git a/emacsql.el b/emacsql.el
index fa75f38ef5..4e2dcb3eec 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -24,7 +24,7 @@
 ;; habits! :-)
 
 ;; Table identifiers can be any lisp object: string, symbol, etc. I
-;; suggest using a keyword. Use `emacsql-create' to create a table.
+;; suggest using a symbol. Use `emacsql-create' to create a table.
 
 ;; (emacsql-create db :employees [name id salary])
 



[nongnu] elpa/emacsql e9fbc4a913 061/427: Fill out a Makefile.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit e9fbc4a913497d1036415bef1f8c2e69f788faea
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fill out a Makefile.
---
 Makefile | 25 +
 emacsql-tests.el |  9 +
 2 files changed, 34 insertions(+)

diff --git a/Makefile b/Makefile
new file mode 100644
index 00..8f4579f75b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,25 @@
+PACKAGE  = emacsql
+
+EMACS   ?= emacs
+BATCH   := $(EMACS) -batch -Q -L .
+COMPILE := $(BATCH) -f batch-byte-compile
+TEST:= $(BATCH) -l $(PACKAGE)-tests.elc -f ert-run-tests-batch
+
+EL = $(PACKAGE).el $(PACKAGE)-tests.el
+
+ELC = $(EL:.el=.elc)
+
+.PHONY : all compile test clean
+
+all : test
+
+compile: $(ELC)
+
+test: compile
+   $(TEST)
+
+clean:
+   $(RM) *.elc
+
+%.elc: %.el
+   @$(COMPILE) $<
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 63ba565522..38fc5e0300 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -1,4 +1,9 @@
+;;; emacsql-tests.el --- tests for emacsql
+
+;;; Code:
+
 (require 'ert)
+(require 'emacsql)
 
 (ert-deftest emacsql-escape ()
   (should (string= (emacsql-escape "foo") "foo"))
@@ -53,3 +58,7 @@
"CREATE TABLE foo (a, b, c);")
   (emacsql-tests-query [:drop-table $1] '(foo)
"DROP TABLE foo;"))
+
+(provide 'emacsql-tests)
+
+;;; emacsql-tests.el ends here



[nongnu] elpa/emacsql 0ba12b89d5 084/427: Drop "work in progress."

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 0ba12b89d5a76cffeaf4e59cc6c44eedeb9edbf4
Author: Christopher Wellons 
Commit: Christopher Wellons 

Drop "work in progress."
---
 README.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 12b421b377..e9a5bcec3d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
 # Emacsql
 
-Emacsql is a high-level Emacs Lisp front-end for SQLite. It's
-currently a work in progress.
+Emacsql is a high-level Emacs Lisp front-end for SQLite.
 
 It works by keeping a `sqlite3` inferior process running (a
 "connection") for interacting with the back-end database. Connections



[nongnu] elpa/emacsql 13cfbeeaba 186/427: Tidy up the constructors.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 13cfbeeaba9462a9a111a3293cf6fddf1939a9bd
Author: Christopher Wellons 
Commit: Christopher Wellons 

Tidy up the constructors.
---
 emacsql-psql.el   | 33 -
 emacsql-sqlite.el | 32 +++-
 emacsql.el|  5 +++--
 3 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/emacsql-psql.el b/emacsql-psql.el
index ea6358e371..fe697ff855 100644
--- a/emacsql-psql.el
+++ b/emacsql-psql.el
@@ -57,23 +57,22 @@
(connection (make-instance 'emacsql-psql-connection
   :process process
   :dbname dbname)))
-  (prog1 connection
-(setf (process-sentinel process)
-  (lambda (proc _) (kill-buffer (process-buffer proc
-(when debug
-  (setf (emacsql-log-buffer connection)
-(generate-new-buffer "*emacsql-log*")))
-(emacsql-register connection)
-(mapc (lambda (s) (emacsql-send-string connection s :no-log))
-  '("\\pset pager off"
-"\\pset null nil"
-"\\a"
-"\\t"
-"\\f ' '"
-"SET client_min_messages TO ERROR;"
-"\\set PROMPT1 ]"
-"EMACSQL;")) ; error message flush
-(emacsql-wait connection)
+  (setf (process-sentinel process)
+(lambda (proc _) (kill-buffer (process-buffer proc
+  (when debug
+(setf (emacsql-log-buffer connection)
+  (generate-new-buffer "*emacsql-log*")))
+  (mapc (lambda (s) (emacsql-send-string connection s :no-log))
+'("\\pset pager off"
+  "\\pset null nil"
+  "\\a"
+  "\\t"
+  "\\f ' '"
+  "SET client_min_messages TO ERROR;"
+  "\\set PROMPT1 ]"
+  "EMACSQL;")) ; error message flush
+  (emacsql-wait connection)
+  (emacsql-register connection
 
 (defmethod emacsql-close ((connection emacsql-psql-connection))
   (let ((process (emacsql-process connection)))
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 06165cc714..1274898c62 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -50,25 +50,23 @@ buffer. This is for debugging purposes."
  (fullfile (if file (expand-file-name file) ":memory:"))
  (sqlite3 emacsql-sqlite3-executable)
  (process (start-process "emacsql-sqlite" buffer sqlite3
- "-interactive" fullfile)))
+ "-interactive" fullfile))
+ (connection (make-instance 'emacsql-sqlite-connection
+:process process
+:file (when file fullfile
 (setf (process-sentinel process)
   (lambda (proc _) (kill-buffer (process-buffer proc
-(process-send-string process ".mode list\n")
-(process-send-string process ".separator ' '\n")
-(process-send-string process ".nullvalue nil\n")
-(process-send-string process ".prompt ]\n")
-(process-send-string process "EMACSQL;\n") ;; error message flush
-(let ((connection (make-instance
-   'emacsql-sqlite-connection
-   :process process
-   :file (when file fullfile)
-   :log-buffer )))
-  (prog1 connection
-(when debug
-  (setf (emacsql-log-buffer connection)
-(generate-new-buffer "*emacsql-log*")))
-(emacsql-wait connection)
-(emacsql-register connection)
+(mapc (lambda (s) (emacsql-send-string connection s :no-log))
+  '(".mode list"
+".separator ' '"
+".nullvalue nil"
+".prompt ]"
+"EMACSQL;")) ; error message flush
+(when debug
+  (setf (emacsql-log-buffer connection)
+(generate-new-buffer "*emacsql-log*")))
+(emacsql-wait connection)
+(emacsql-register connection)))
 
 ;;;###autoload
 (defalias 'emacsql-connect 'emacsql-sqlite)
diff --git a/emacsql.el b/emacsql.el
index 47687f6e3c..623c340a25 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -196,8 +196,9 @@ specific error conditions."
 ;; Automatic connection cleanup:
 
 (defun emacsql-register (connection)
-  "Add CONNECTION to the global connection list."
-  (emacsql-reap-register connection #'emacsql-close (copy-sequence 
connection)))
+  "Register CONNECTION for automatic cleanup and return CONNECTION."
+  (emacsql-reap-register connection #'emacsql-close (copy-sequence connection))
+  connection)
 
 ;; Useful macros:
 



[nongnu] elpa/emacsql b2f2dd37cf 178/427: Allow connection to specify their own types.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit b2f2dd37cf5b1f58640312bab9c933af26efce9d
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow connection to specify their own types.
---
 emacsql-psql.el   | 10 --
 emacsql-sqlite.el | 10 --
 emacsql-tests.el  | 43 +++
 emacsql.el| 41 +
 4 files changed, 68 insertions(+), 36 deletions(-)

diff --git a/emacsql-psql.el b/emacsql-psql.el
index 1f23407018..0f07075ad4 100644
--- a/emacsql-psql.el
+++ b/emacsql-psql.el
@@ -28,7 +28,13 @@
 (error :cannot-execute)
 
 (defclass emacsql-psql-connection (emacsql-connection emacsql-simple-parser)
-  ((dbname :reader emacsql-psql-dbname :initarg :dbname))
+  ((dbname :reader emacsql-psql-dbname :initarg :dbname)
+   (types :allocation :class
+  :reader emacsql-types
+  :initform '((integer "BIGINT")
+  (float "DOUBLE PRECISION")
+  (object "TEXT")
+  (nil "TEXT"
   (:documentation "A connection to a PostgreSQL database."))
 
 ;;;###autoload
@@ -74,7 +80,7 @@
   (process-send-string process "\\q\n"
 
 (defmethod emacsql ((connection emacsql-psql-connection) sql &rest args)
-  (let ((sql-string (apply #'emacsql-compile sql args)))
+  (let ((sql-string (apply #'emacsql-compile connection sql args)))
 (emacsql-clear connection)
 (emacsql-send-string connection sql-string)
 (emacsql-wait connection)
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 5b5905910b..36eeba6647 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -30,7 +30,13 @@
 (defclass emacsql-sqlite-connection (emacsql-connection emacsql-simple-parser)
   ((file :initarg :file
  :type (or null string)
- :documentation "Database file name."))
+ :documentation "Database file name.")
+   (types :allocation :class
+  :reader emacsql-types
+  :initform '((integer "INTEGER")
+  (float "REAL")
+  (object "TEXT")
+  (nil nil
   (:documentation "A connection to a SQLite database."))
 
 ;;;###autoload
@@ -123,7 +129,7 @@ buffer. This is for debugging purposes."
   'emacsql-error))
 
 (defmethod emacsql ((connection emacsql-sqlite-connection) sql &rest args)
-  (let ((sql-string (apply #'emacsql-compile sql args)))
+  (let ((sql-string (apply #'emacsql-compile connection sql args)))
 (emacsql-clear connection)
 (emacsql-send-string connection sql-string)
 (emacsql-wait connection)
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 32168b1eaa..0c0ed5191e 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -31,14 +31,17 @@
"(1, 2, 3), (4, 5, 6)")))
 
 (ert-deftest emacsql-schema ()
-  (should (string= (car (emacsql--schema-to-string [a])) "a"))
-  (should (string= (car (emacsql--schema-to-string [a b c])) "a, b, c"))
-  (should (string= (car (emacsql--schema-to-string [a (b)])) "a, b"))
+  (should (string= (car (emacsql--schema-to-string [a]))
+   "a NONE"))
+  (should (string= (car (emacsql--schema-to-string [a b c]))
+   "a NONE, b NONE, c NONE"))
+  (should (string= (car (emacsql--schema-to-string [a (b)]))
+   "a NONE, b NONE"))
   (should (string= (car (emacsql--schema-to-string [a (b float)]))
-   "a, b REAL"))
+   "a NONE, b REAL"))
   (should (string= (car (emacsql--schema-to-string
- [a (b :primary float :unique)]))
-   "a, b REAL PRIMARY KEY UNIQUE"))
+ [a (b float :primary :unique)]))
+   "a NONE, b REAL PRIMARY KEY UNIQUE"))
   (should (string= (car (emacsql--schema-to-string [(a integer) (b float)]))
"a INTEGER, b REAL")))
 
@@ -84,32 +87,32 @@
 (ert-deftest emacsql-create-table ()
   (emacsql-tests-with-queries
 ([:create-table foo [a b c]] ()
- "CREATE TABLE foo (a, b, c);")
+ "CREATE TABLE foo (a NONE, b NONE, c NONE);")
 ([:create-table (:temporary :if-not-exists x) [y]] '()
- "CREATE TEMPORARY TABLE IF NOT EXISTS x (y);")
+ "CREATE TEMPORARY TABLE IF NOT EXISTS x (y NONE);")
 ([:create-table foo [(a :default 10)]] '()
- "CREATE TABLE foo (a DEFAULT 10);")
+ "CREATE TABLE foo (a NONE DEFAULT 10);")
 ([:create-table foo [(a :primary :non-nil) b]] '()
- "CREATE TABLE foo (a PRIMARY KEY NOT NULL, b);")
+ "CREATE TABLE foo (a NONE PRIMARY KEY NOT NULL, b NONE);")
 ([:create-table foo [a (b :check (< b 10))]] '()
- "CREATE TABLE foo (a, b CHECK (b < 10));")
+ "CREATE TABLE foo (a NONE, b NONE CHECK (b < 10));")
 ([:create-table foo $1] '([a b (c :primary)])
- "CREATE TABLE foo (a, b, c PRIMARY KEY);")
+ "CREATE TABLE foo (a NONE, b NONE, c NONE PRIMARY KEY);")
 ([:create-table foo [a b (c :default $1)]] '("FOO")
- "CREATE TABLE foo (a, b, c DE

[nongnu] elpa/emacsql be9c46c274 259/427: Change the way tuples are computed.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit be9c46c2746a7e27d06a294547edfcf480f011ed
Author: Christopher Wellons 
Commit: Christopher Wellons 

Change the way tuples are computed.
---
 emacsql-sqlite.el |  2 +-
 emacsql-system.el | 48 +++-
 2 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index a8afc23cdd..5a60eec670 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -8,7 +8,7 @@
 (require 'emacsql-system)
 
 (defvar emacsql-sqlite-executable
-  (expand-file-name (emacsql-system-binary "bin/emacsql-sqlite")
+  (expand-file-name (concat "bin/emacsql-sqlite-" (emacsql-system-tuple))
 (file-name-directory load-file-name))
   "Path to the Emacsql backend (this is not the sqlite3 shell).")
 
diff --git a/emacsql-system.el b/emacsql-system.el
index 8bca22b24a..38a8618f23 100644
--- a/emacsql-system.el
+++ b/emacsql-system.el
@@ -8,40 +8,30 @@
 
 (defun emacsql-system-normalize-arch (arch)
   "Normalize the name of string ARCH."
-  (cl-case (intern arch)
-((x86 i386 i486 i586 i686) 'x86)
-((x86_64 amd64) 'x86_64)
-(otherwise (intern arch
-
-(defun emacsql-system-architecture ()
-  "Determine this system's architecture."
-  (emacsql-system-normalize-arch
-(if (executable-find "uname")
-(with-temp-buffer
-  (call-process "uname" nil (current-buffer) nil "-m")
-  (replace-regexp-in-string "\\s " "" (buffer-string)))
-  (getenv "PROCESSOR_ARCHITECTURE"
+  (cond ((string-match-p "^i[0-9]\\{3\\}" arch) "x86")
+((string-match-p "^amd64" arch) "x86_64")
+(arch)))
+
+(defun emacsql-system-normalize-os (os)
+  "Normalize OS into a simple canonical name.
+Unfortunately config.guess has lots of names for Windows."
+  (cond ((string-match-p "^nt" os) "windows")
+((string-match-p "^ming" os) "windows")
+((string-match-p "^cygwin" os) "windows")
+((string-match-p "^linux" os) "linux")
+(os)))
 
 (defun emacsql-system-tuple ()
-  "Return a tuple (kernel architecture) for the current system."
-  (list
-   (emacsql-system-architecture)
-   (cl-ecase system-type
- (gnu 'hurd)
- (gnu/linux 'linux)
- ((gnu/kfreebsd berkeley-unix) 'bsd)
- (darwin 'darwin)
- (ms-dos 'dos)
- (windows-nt 'windows)
- (cygwin 'windows
-
-(defun emacsql-system-binary (prefix)
-  "Determine an executable name for PREFIX."
-  (concat prefix "-" (mapconcat #'symbol-name (emacsql-system-tuple) "-")))
+  "Determine the architecture-system tuple for Emacs' host system."
+  (cl-destructuring-bind (arch _vendor . os-parts)
+  (split-string system-configuration "-")
+(let ((os (mapconcat #'identity os-parts "-")))
+  (format "%s-%s" (emacsql-system-normalize-arch arch)
+  (emacsql-system-normalize-os os)
 
 (defun emacsql-system-print-tuple ()
   "This is for calling from a Makefile."
-  (princ (mapconcat #'symbol-name (emacsql-system-tuple) "-"))
+  (emacsql-system-tuple)
   (princ "\n"))
 
 (provide 'emacsql-system)



[nongnu] elpa/emacsql af2cdddca1 231/427: Squash a bunch of bugs.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit af2cdddca1374971e3f767d1c37e7d67e780ee75
Author: Christopher Wellons 
Commit: Christopher Wellons 

Squash a bunch of bugs.
---
 emacsql-compiler.el |  20 ++---
 emacsql-sqlite.el   |   2 +-
 emacsql-tests.el| 122 +++-
 sqlite/emacsql.c|  25 ++-
 4 files changed, 93 insertions(+), 76 deletions(-)

diff --git a/emacsql-compiler.el b/emacsql-compiler.el
index 18d979348a..1b209f09fc 100644
--- a/emacsql-compiler.el
+++ b/emacsql-compiler.el
@@ -55,7 +55,7 @@
 (if (or (string-match-p special print)
 (string-match-p "^[0-9$]" print))
 (emacsql-quote-identifier print)
-  name)
+  print)
 
 (defun emacsql-escape-scalar (value)
   "Escape VALUE for sending to SQLite."
@@ -124,7 +124,7 @@ KIND should be :scalar or :identifier."
  (symbol (list (emacsql-escape-identifier column)
(cadr (assoc nil emacsql-type-map
  (list (cl-destructuring-bind (name . constraints) column
- (delete-if
+ (cl-delete-if
   (lambda (s) (zerop (length s)))
   (list (emacsql-escape-identifier name)
 (if (member (car constraints) '(integer float object))
@@ -207,7 +207,7 @@ which will be combined with variable definitions."
  (if (symbolp thing)
  (emacsql-escape-identifier thing)
(emacsql-escape-scalar thing
-(prog1 "%s"
+(prog1 (if (eq (cdr param) :schema) "(%s)" "%s")
   (check param)
   (setf emacsql--vars (nconc emacsql--vars (list param
 
@@ -215,7 +215,7 @@ which will be combined with variable definitions."
   "Prepare VECTOR."
   (emacsql-with-params ""
 (cl-typecase vector
-  (symbol (param vector :vector))
+  (symbol (emacsql--!param vector :vector))
   (list (mapconcat #'svector vector ", "))
   (vector (format "(%s)" (mapconcat #'scalar vector ", ")))
   (otherwise (emacsql-error "Invalid vector: %S" vector)
@@ -247,6 +247,9 @@ which will be combined with variable definitions."
(1 (format "-(%s)" (recur 0)))
(2 (format "%s - %s" (recur 0) (recur 1)))
(otherwise (nops op
+;; Ordering
+((asc desc)
+ (format "%s %s" (recur 0) (upcase (symbol-name op
 ;; Special case quote
 ((quote) (scalar (nth 0 args)))
 ;; Guess
@@ -284,7 +287,7 @@ which will be combined with variable definitions."
   (emacsql--from-keyword item)))
(symbolp (if (eq item '*)
 "*"
-  (identifier item)))
+  (param item)))
(vector (if (emacsql-sql-p item)
(subsql item)
  (let ((idents (combine
@@ -296,7 +299,10 @@ which will be combined with variable definitions."
  (emacsql-escape-format
   (format "(%s)"
   (emacsql-prepare-schema item)))
-   (combine (emacsql--*expr item)
+   (combine (emacsql--*expr item
+   (otherwise
+(emacsql-escape-format
+ (emacsql-escape-scalar item
  into parts
  do (setf last item)
  finally (cl-return
@@ -314,7 +320,7 @@ which will be combined with variable definitions."
 (:identifier (emacsql-escape-identifier thing))
 (:scalar (emacsql-escape-scalar thing))
 (:vector (emacsql-escape-vector thing))
-(:schema (car (emacsql--schema-to-string thing)))
+(:schema (emacsql-prepare-schema thing))
 (otherwise
  (emacsql-error "Invalid var type %S" kind
 
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 7491999050..a32abd7a03 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -41,7 +41,7 @@ buffer. This is for debugging purposes."
 (setf (process-sentinel process)
   (lambda (proc _) (kill-buffer (process-buffer proc
 (emacsql-wait connection)
-(emacsql connection [:pragma (= busy-timeout $1)]
+(emacsql connection [:pragma (= busy-timeout $s1)]
  (/ (* emacsql-global-timeout 1000) 2))
 (when debug
   (setf (emacsql-log-buffer connection)
diff --git a/emacsql-tests.el b/emacsql-tests.el
index f8fd98e1af..2a5b072a0b 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -26,9 +26,8 @@
(mapca

[nongnu] elpa/emacsql 327b09b4b9 348/427: Add support for raw strings and raw parameters (#26, #28).

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 327b09b4b99ccb6b5605b804027a42fd73589929
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add support for raw strings and raw parameters (#26, #28).

Strings quoted with ' are not printed when used. A new "r" parameter
type was also introduced to include unprinted string values in
queries.
---
 README.md   | 14 ++
 emacsql-compiler.el | 25 +++--
 tests/emacsql-compiler-tests.el | 14 ++
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index c76ed67f1d..2edb978142 100644
--- a/README.md
+++ b/README.md
@@ -137,6 +137,17 @@ does not "escape" `$tn` parameter symbols.
 (emacsql db [... :where (= category 'hiking)])
 ```
 
+Quoting a string makes EmacSQL handle it as a "raw string." These raw
+strings are not printed when being assembled into a query. These are
+intended for use in special circumstances like filenames (`ATTACH`) or
+pattern matching (`LIKE`). It is vital that raw strings are not
+returned as results.
+
+```el
+(emacsql db [... :where (like name '"%foo%")])
+(emacsql db [:attach '"/path/to/foo.db" :as foo])
+```
+
 Since template parameters include their type they never need to be
 quoted.
 
@@ -261,6 +272,8 @@ one-indexed.
 
 ```el
 (emacsql db [:select * :from $i1 :where (> salary $s2)] 'employees 5)
+
+(emacsql db [:select * :from employees :where (like name $r1)] "%Smith%")
 ```
 
 The letter before the number is the type.
@@ -268,6 +281,7 @@ The letter before the number is the type.
  * `i` : identifier
  * `s` : scalar
  * `v` : vector (or multiple vectors)
+ * `r` : raw, unprinted strings
  * `S` : schema
 
 When combined with `:values`, the vector type can refer to lists of
diff --git a/emacsql-compiler.el b/emacsql-compiler.el
index 2f5b596f4e..3267d18118 100644
--- a/emacsql-compiler.el
+++ b/emacsql-compiler.el
@@ -83,6 +83,12 @@
   ((numberp value) (prin1-to-string value))
   ((emacsql-quote-scalar (prin1-to-string value))
 
+(defun emacsql-escape-raw (value)
+  "Escape VALUE for sending to SQLite."
+  (cond ((null value) "NULL")
+((stringp value) (emacsql-quote-scalar value))
+((error "Expected string or nil"
+
 (defun emacsql-escape-vector (vector)
   "Encode VECTOR into a SQL vector scalar."
   (cl-typecase vector
@@ -174,28 +180,30 @@
   "Return the index and type of THING, or nil if THING is not a parameter.
 A parameter is a symbol that looks like $i1, $s2, $v3, etc. The
 letter refers to the type: identifier (i), scalar (s),
-vector (v), schema (S)."
+vector (v), raw string (r), schema (S)."
   (when (symbolp thing)
 (let ((name (symbol-name thing)))
-  (when (string-match-p "^\\$[isvS][0-9]+$" name)
+  (when (string-match-p "^\\$[isvrS][0-9]+$" name)
 (cons (1- (read (substring name 2)))
   (cl-ecase (aref name 1)
 (?i :identifier)
 (?s :scalar)
 (?v :vector)
+(?r :raw)
 (?S :schema)))
 
 (defmacro emacsql-with-params (prefix &rest body)
   "Evaluate BODY, collecting parameters.
-Provided local functions: `param', `identifier', `scalar',
-`svector', `expr', `subsql', and `combine'. BODY should return a string,
-which will be combined with variable definitions."
+Provided local functions: `param', `identifier', `scalar', `raw',
+`svector', `expr', `subsql', and `combine'. BODY should return a
+string, which will be combined with variable definitions."
   (declare (indent 1))
   `(let ((emacsql--vars ()))
  (cl-flet* ((combine (prepared) (emacsql--*combine prepared))
 (param (thing) (emacsql--!param thing))
 (identifier (thing) (emacsql--!param thing :identifier))
 (scalar (thing) (emacsql--!param thing :scalar))
+(raw (thing) (emacsql--!param thing :raw))
 (svector (thing) (combine (emacsql--*vector thing)))
 (expr (thing) (combine (emacsql--*expr thing)))
 (subsql (thing)
@@ -218,6 +226,7 @@ Only use within `emacsql-with-params'!"
  (:identifier (emacsql-escape-identifier thing))
  (:scalar (emacsql-escape-scalar thing))
  (:vector (emacsql-escape-vector thing))
+ (:raw (emacsql-escape-raw thing))
  (:schema (emacsql-prepare-schema thing)))
  (if (and (not (null thing))
   (not (keywordp thing))
@@ -275,7 +284,10 @@ Only use within `emacsql-with-params'!"
 ((asc desc)
  (format "%s %s" (recur 0) (upcase (symbol-name op
 ;; Special case quote
-((quote) (scalar (nth 0 args)))
+((quote) (let ((arg (nth 0 args)))
+   (if (stringp arg)
+   (raw arg)
+ (scalar arg
 ;; Special case funcall

[nongnu] elpa/emacsql e42d939235 187/427: In SQLite, block for up to 30 seconds on db lock.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit e42d9392358780294bc5c4fca9ef95247da17945
Author: Christopher Wellons 
Commit: Christopher Wellons 

In SQLite, block for up to 30 seconds on db lock.

This should make it a lot easier to use.
---
 emacsql-sqlite.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 1274898c62..6a12f719a9 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -60,6 +60,7 @@ buffer. This is for debugging purposes."
   '(".mode list"
 ".separator ' '"
 ".nullvalue nil"
+"PRAGMA busy_timeout = 3;"
 ".prompt ]"
 "EMACSQL;")) ; error message flush
 (when debug



[nongnu] elpa/emacsql 39ce3b9736 287/427: Smarter identifier identification in expressions.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 39ce3b9736751fe473fcb5e0f279b2f4da301645
Author: Christopher Wellons 
Commit: Christopher Wellons 

Smarter identifier identification in expressions.
---
 emacsql-compiler.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/emacsql-compiler.el b/emacsql-compiler.el
index 8f0e829f10..81c55c1d8f 100644
--- a/emacsql-compiler.el
+++ b/emacsql-compiler.el
@@ -204,7 +204,9 @@ which will be combined with variable definitions."
  (:scalar (emacsql-escape-scalar thing))
  (:vector (emacsql-escape-vector thing))
  (:schema (emacsql-prepare-schema thing)))
- (if (symbolp thing)
+ (if (and (not (null thing))
+  (not (keywordp thing))
+  (symbolp thing))
  (emacsql-escape-identifier thing)
(emacsql-escape-scalar thing
 (prog1 (if (eq (cdr param) :schema) "(%s)" "%s")



[nongnu] elpa/emacsql 7cfed08ab8 099/427: Add docstring to emacsql--log.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 7cfed08ab861c06c7bf57bf692e641e795155976
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add docstring to emacsql--log.
---
 emacsql.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/emacsql.el b/emacsql.el
index 1983ca6ab6..6037a84921 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -170,6 +170,7 @@ CONN-SPEC is a connection specification like the call to
 (setf emacsql-reap-timer nil)))
 
 (defun emacsql--log (conn &rest messages)
+  "Log MESSAGES into CONN's log."
   (let ((log (emacsql-log conn)))
 (when log
   (with-current-buffer log



[nongnu] elpa/emacsql 47d9476a02 142/427: Add tests for quote operator.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 47d9476a02c698184bef312ba876c3860b7d9589
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add tests for quote operator.
---
 emacsql-tests.el | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 85a822fb62..18a36194ce 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -150,6 +150,13 @@
 ([:limit [$1 $2]] '(4 30)
  "LIMIT 4, 30;")))
 
+(ert-deftest emacsql-expr ()
+  (emacsql-tests-with-queries
+([:where (= name 'foo)] '()
+ "WHERE name = 'foo';")
+([:where (= name '$1)] '(qux)
+ "WHERE name = 'qux';")))
+
 (ert-deftest emacsql-system ()
   "A short test that fully interacts with SQLite."
   (should-not (emacsql-sqlite3-unavailable-p))



[nongnu] elpa/emacsql 1f6c06bda9 050/427: Use expr expansion in :where expander.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 1f6c06bda92f9e646af162eb997d1d9df5436ef0
Author: Christopher Wellons 
Commit: Christopher Wellons 

Use expr expansion in :where expander.
---
 emacsql.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 9a0d7521f6..1c22769a2b 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -432,8 +432,7 @@ definitions for return from a `emacsql-defexpander'."
 
 (emacsql-defexpander :where (expr)
   (emacsql-with-vars "WHERE "
-(cl-destructuring-bind (op a b) expr
-  (format "%s %s %s" (var a :auto) op (var b :auto)
+(combine (emacsql--expr expr
 
 (emacsql-defexpander :create-table (table schema)
   (emacsql-with-vars "CREATE TABLE "



[nongnu] elpa/emacsql ad6c09681e 261/427: Oops, print the tuple.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit ad6c09681e483f68316330324900789e32858037
Author: Christopher Wellons 
Commit: Christopher Wellons 

Oops, print the tuple.
---
 emacsql-system.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacsql-system.el b/emacsql-system.el
index c33a823d55..ec05bff153 100644
--- a/emacsql-system.el
+++ b/emacsql-system.el
@@ -32,7 +32,7 @@ Unfortunately config.guess has lots of names for Windows."
 
 (defun emacsql-system-print-tuple ()
   "This is for calling from a Makefile."
-  (emacsql-system-tuple)
+  (princ (emacsql-system-tuple))
   (princ "\n"))
 
 (provide 'emacsql-system)



[nongnu] elpa/emacsql d5cfaee783 158/427: Be more precise about error messages.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit d5cfaee78389f35fd70b55bcf812b4c9e23f8bb4
Author: Christopher Wellons 
Commit: Christopher Wellons 

Be more precise about error messages.
---
 emacsql-tests.el |  13 
 emacsql.el   | 190 +--
 2 files changed, 157 insertions(+), 46 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index 3e109788db..36d78722ee 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -216,6 +216,19 @@
 (should (equal (emacsql db [:select * :from likes])
'((1 yellow))
 
+(ert-deftest emacsql-error ()
+  "Check that we're getting expected conditions."
+  (should-error (emacsql-compile [:begin :foo])
+:type 'emacsql-syntax)
+  (should-error (emacsql-compile [:create-table $foo$ [a]])
+:type 'emacsql-syntax)
+  (should-error (emacsql-compile [:insert :into foo :values 1])
+:type 'emacsql-syntax)
+  (emacsql-with-connection (db nil)
+(emacsql db [:create-table foo [x]])
+(should-error (emacsql db [:create-table foo [x]])
+  :type 'emacsql-table)))
+
 (provide 'emacsql-tests)
 
 ;;; emacsql-tests.el ends here
diff --git a/emacsql.el b/emacsql.el
index abec8f6771..1e286709f5 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -79,6 +79,80 @@
 nil)))
 (error :cannot-execute)
 
+;;; Error definitions
+
+(defmacro emacsql-deferror (symbol parents message)
+  "Defines a new error symbol  for Emacsql."
+  (declare (indent 2))
+  (let ((conditions (cl-remove-duplicates
+ (append parents (list symbol 'emacsql-error 'error)
+`(prog1 ',symbol
+   (setf (get ',symbol 'error-conditions) ',conditions
+ (get ',symbol 'error-message) ,message
+
+(emacsql-deferror emacsql-error () ;; parent condition for all others
+  "Emacsql had an unhandled condition")
+
+(emacsql-deferror emacsql-syntax () "Invalid SQL statement")
+(emacsql-deferror emacsql-table () "SQL table error")
+(emacsql-deferror emacsql-lock () "Database locked")
+(emacsql-deferror emacsql-transaction () "Invalid transaction")
+(emacsql-deferror emacsql-fatal () "Fatal error")
+(emacsql-deferror emacsql-file () "Filesystem access error")
+
+(defvar emacsql-condition-alist
+  '(("unable to open"  emacsql-file)
+("cannot open" emacsql-file)
+("source database is busy" emacsql-file)
+("unknown database"emacsql-file)
+("writable"emacsql-file)
+("no such table"   emacsql-table)
+("table [^ ]+ already exists"  emacsql-table)
+("no such column"  emacsql-table)
+("already another table"   emacsql-table)
+("Cannot add"  emacsql-table)
+("table name"  emacsql-table)
+("already an index"emacsql-table)
+("constraint cannot be drop"   emacsql-table)
+("database is locked"  emacsql-lock)
+("no transaction is active"emacsql-transaction)
+("cannot start a transaction"  emacsql-transaction)
+("out of memory"   emacsql-fatal)
+("corrupt database"emacsql-fatal)
+("interrupt"   emacsql-fatal)
+("values were supplied"emacsql-syntax)
+("mismatch"emacsql-syntax)
+("no such" emacsql-syntax)
+("does not match"  emacsql-syntax)
+("circularly defined"  emacsql-syntax)
+("parameters are not allowed"  emacsql-syntax)
+("missing" emacsql-syntax)
+("is only allowed on"  emacsql-syntax)
+("more than one primary key"   emacsql-syntax)
+("not constant"emacsql-syntax)
+("duplicate"   emacsql-syntax)
+("name reserved"   emacsql-syntax)
+("cannot use variables"emacsql-syntax)
+("no tables specified" emacsql-syntax)
+("syntax error"emacsql-syntax)
+("no such function"emacsql-syntax)
+("unknown function"emacsql-syntax)
+("wrong number of arguments"   emacsql-syntax)
+("term does not match" emacsql-syntax)
+("clause"  emacsql-syntax)
+("tree is too large"   emacsql-syntax)
+("too many"emacsql-syntax))
+  "List of regexp's mapping sqlite3 output to conditions.")
+
+(defun emacsql-get-condition (message)
+  (or (cadr (cl-assoc message emacsql-condition-alist
+  :test (lambda (a b) (string-match-p b a
+  'emacsql-error))
+
+(defun emacsql-error (format &rest args)
+  "Like `error', but signal an emacsql-syntax condition."
+  (signal 'emacsql-syntax (list (apply #'format format args
+
 ;;; Connection handling:
 
 (cl-defstruct (emacsql (:constructor emacsql--create))
@@ -242,8 +316,10 @@ A statement can be a list, containing a statement with 

[nongnu] elpa/emacsql 1e9857ccc4 103/427: Allow variables inside vectors.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 1e9857ccc450cf339ea6dd4b144e57e219c3be9b
Author: Christopher Wellons 
Commit: Christopher Wellons 

Allow variables inside vectors.
---
 emacsql.el | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index 4e3875a12b..6f7596648b 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -413,6 +413,17 @@ definitions for return from a `emacsql-defexpander'."
 (declare-function combine nil (expanded))
 (declare-function var nil (thing kind))
 
+(defun emacsql--vector (vector)
+  "Expand VECTOR, making variables as needed."
+  (emacsql-with-vars ""
+(cl-etypecase vector
+  (symbol
+   (var vector :vector))
+  (list
+   (mapconcat (lambda (v) (combine (emacsql--vector v))) vector ", "))
+  (vector
+   (format "(%s)" (mapconcat (lambda (x) (var x :value)) vector ", "))
+
 (defun emacsql--expr (expr)
   "Expand EXPR recursively."
   (emacsql-with-vars ""
@@ -498,7 +509,7 @@ definitions for return from a `emacsql-defexpander'."
 
 (emacsql-defexpander :values (values)
   (emacsql-with-vars "VALUES "
-(var values :vector)))
+(combine (emacsql--vector values
 
 (emacsql-defexpander :update (table)
   (emacsql-with-vars "UPDATE "



[nongnu] elpa/emacsql cd5e856ea6 150/427: Add :autoincrement.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit cd5e856ea6a9c7675bca68876bf438a69f0a621a
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add :autoincrement.
---
 README.md  | 5 +++--
 emacsql.el | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 6e85073a9a..d6d22ed5fa 100644
--- a/README.md
+++ b/README.md
@@ -60,8 +60,9 @@ can either be just this symbol or it can include constraints. 
Because
 Emacsql stores entire lisp objects as values, the only relevant (and
 allowed) types are `integer`, `float`, and `object` (default).
 
-Columns constraints include `:primary` (aka `PRIMARY KEY`), `:unique`,
-`:non-nil` (aka `NOT NULL`), `:default`, and `:check`.
+Columns constraints include `:primary` (aka `PRIMARY KEY`),
+`:autoincrement`, `:unique`, `:non-nil` (aka `NOT NULL`), `:default`,
+and `:check`.
 
 Table constraints can be `:primary`, `:unique`, `:check`, and `:foreign`.
 
diff --git a/emacsql.el b/emacsql.el
index c79d90b70e..3449777253 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -424,6 +424,7 @@ definitions for return from a `emacsql-defexpander'."
 (let ((next (pop column)))
   (cl-case next
 (:primary (push "PRIMARY KEY" output))
+(:autoincrement (push "AUTOINCREMENT" output))
 (:non-nil (push "NOT NULL" output))
 (:unique  (push "UNIQUE" output))
 (:default (push "DEFAULT" output)



[nongnu] elpa/emacsql e6ab07e16b 140/427: Switch to a friendlier name.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit e6ab07e16bf094f53b0d8edda7211ddb0a7c7201
Author: Christopher Wellons 
Commit: Christopher Wellons 

Switch to a friendlier name.
---
 emacsql-tests.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/emacsql-tests.el b/emacsql-tests.el
index c1f4542725..85a822fb62 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -168,9 +168,9 @@
   [:create-table person [(id integer :primary) name]]
   [:create-table likes ([(personid integer) color]
 :foreign (personid person id :on-delete :cascade))]
-  [:replace :into person :values ([0 "Chris"] [1 "Jeff"])])
+  [:replace :into person :values ([0 "Chris"] [1 "Brian"])])
 (should (equal (emacsql db [:select * :from person :order-by id])
-   '((0 "Chris") (1 "Jeff"
+   '((0 "Chris") (1 "Brian"
 (emacsql db [:insert :into likes :values ([0 red] [0 yellow] [1 yellow])])
 (should (equal (emacsql db [:select * :from likes
 :order-by [personid color]])



[nongnu] elpa/emacsql 9dcfebfba7 030/427: Factor out schema->string code.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 9dcfebfba7b3ce50dd56e777a404f900c6f0b23c
Author: Christopher Wellons 
Commit: Christopher Wellons 

Factor out schema->string code.
---
 emacsql.el | 47 ---
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 69711df2ae..fd043d7f2f 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -218,20 +218,45 @@ If NAMED is non-nil, don't include column names."
  ,@body
  (emacsql--check-error ,conn)))
 
+(defun emacsql--column-to-string (column)
+  "Convert COLUMN schema into a SQL string."
+  (let ((name (emacsql-escape (pop column)))
+(output ())
+(type nil))
+(while column
+  (let ((next (pop column)))
+(case next
+  (:primary (push "PRIMARY KEY" output))
+  (:non-nil (push "NOT NULL" output))
+  (:unique  (push "UNIQUE" output))
+  (integer  (setf type "INTEGER"))
+  (float(setf type "REAL"))
+  (object   (setf type "TEXT"))
+  (otherwise
+   (if (keywordp next)
+   (error "Unknown schema contraint %s" next)
+ (error "Invalid type %s: %s" next
+"must be 'integer', 'float', or 'object'"))
+(mapconcat #'identity
+   (nconc (if type (list name type) (list name)) (nreverse output))
+   " ")))
+
+(defun emacsql--schema-to-string (schema)
+  "Convert SCHEMA into a SQL-consumable string."
+  (cl-loop for column being the elements of schema
+   when (symbolp column) collect (emacsql-escape column) into parts
+   else collect (emacsql--column-to-string column) into parts
+   finally (return (mapconcat #'identity parts ", "
+
 (defun emacsql-create (conn table schema &optional if-not-exists)
   "Create TABLE in CONN with SCHEMA."
   (emacsql-with-errors conn
-(cl-loop for column being the elements of schema
- when (consp column)
- collect (mapconcat #'emacsql-escape column " ")
- into parts
- else collect (format "%s" column) into parts
- finally (emacsql--send
-  conn
-  (format "CREATE TABLE %s%s(%s);"
-  (if if-not-exists "IF NOT EXISTS " "")
-  (emacsql-escape table)
-  (mapconcat #'identity parts ", "))
+(emacsql--send
+ conn
+ (format "CREATE TABLE %s%s(%s);"
+ (if if-not-exists "IF NOT EXISTS " "")
+ (emacsql-escape table)
+ (emacsql--schema-to-string schema)
 
 (defun emacsql-drop (conn table)
   "Drop TABLE from CONN."



[nongnu] elpa/emacsql 9e6ea00f01 243/427: Add note about PostgreSQL.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 9e6ea00f01b8dc85b7966e08c1625554764b97cb
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add note about PostgreSQL.
---
 README.md | 4 
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index ef009129bb..d9236aded4 100644
--- a/README.md
+++ b/README.md
@@ -309,6 +309,10 @@ and unit testing.
 
 make test
 
+If the environmental variable `PGDATABASE` is present then the unit
+tests will also be run with PostgreSQL in addition to SQLite. Also
+provide `PGHOST`, `PGPORT`, and `PGUSER` if needed.
+
 ### Creating a New Front-end
 
 Emacsql uses EIEIO so that interactions with a connection occur



[nongnu] elpa/emacsql c4396ec5e6 057/427: Fix a bunch of warnings.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit c4396ec5e6cc036556e6d1a601f0513a015f1af3
Author: Christopher Wellons 
Commit: Christopher Wellons 

Fix a bunch of warnings.
---
 emacsql.el | 39 +--
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/emacsql.el b/emacsql.el
index 6b89a35bc4..e8cf911048 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -107,7 +107,7 @@ buffer. This is for debugging purposes."
   (when log
 (setf (emacsql-log conn) (generate-new-buffer "*emacsql-log*")))
   (prog1 conn
-(push (cons (copy-seq conn) (emacsql--ref conn))
+(push (cons (copy-sequence conn) (emacsql--ref conn))
   emacsql-connections)
 
 (defun emacsql-close (conn)
@@ -124,12 +124,12 @@ buffer. This is for debugging purposes."
   "Clean up after lost connections."
   (cl-loop for (conn-copy . ref) in emacsql-connections
when (null (emacsql--deref ref))
-   count (prog1 t (ignore-errors (emacsql-close emacsql-copy)))
+   count (prog1 t (ignore-errors (emacsql-close conn-copy)))
into total
else collect (cons conn-copy ref) into connections
finally (progn
  (setf emacsql-connections connections)
- (return total
+ (cl-return total
 
 (cl-defun emacsql-start-reap-timer (&optional (interval 60))
   "Start the automatic `emacql-reap' timer."
@@ -181,7 +181,7 @@ buffer. This is for debugging purposes."
do (forward-char)
when (or (looking-at "\n") (looking-at "#"))
collect row into rows and do (setf row ())
-   finally (return rows)
+   finally (cl-return rows)
 
 (defun emacsql-escape (identifier &optional force)
   "Escape an identifier, always with quotes when FORCE is non-nil."
@@ -227,7 +227,7 @@ buffer. This is for debugging purposes."
 (type nil))
 (while column
   (let ((next (pop column)))
-(case next
+(cl-case next
   (:primary (push "PRIMARY KEY" output))
   (:non-nil (push "NOT NULL" output))
   (:unique  (push "UNIQUE" output))
@@ -248,7 +248,7 @@ buffer. This is for debugging purposes."
   (cl-loop for column being the elements of schema
when (symbolp column) collect (emacsql-escape column) into parts
else collect (emacsql--column-to-string column) into parts
-   finally (return (mapconcat #'identity parts ", "
+   finally (cl-return (mapconcat #'identity parts ", "
 
 (defun emacsql-create (conn table schema &optional if-not-exists)
   "Create TABLE in CONN with SCHEMA."
@@ -303,16 +303,16 @@ See also `emacsql-with-errors'."
 
 (defun emacsql-expand (sql)
   "Expand SQL into a SQL-consumable string, with variables."
-  (loop with items = (cl-coerce sql 'list)
-while (not (null items))
-for keyword = (pop items)
-for (arity expander) = (cdr (assoc keyword emacsql-expanders))
-when expander
-collect (apply expander (subseq items 0 arity)) into parts
-else do (error "Unrecognized keyword %s" keyword)
-do (setf items (subseq items arity))
-finally (return (cons (concat (mapconcat #'car parts " ") ";")
-  (apply #'nconc (mapcar #'cdr parts))
+  (cl-loop with items = (cl-coerce sql 'list)
+   while (not (null items))
+   for keyword = (pop items)
+   for (arity expander) = (cdr (assoc keyword emacsql-expanders))
+   when expander
+   collect (apply expander (cl-subseq items 0 arity)) into parts
+   else do (error "Unrecognized keyword %s" keyword)
+   do (setf items (cl-subseq items arity))
+   finally (cl-return (cons (concat (mapconcat #'car parts " ") ";")
+ (apply #'nconc (mapcar #'cdr parts))
 
 (defun emacsql-format (expansion &rest args)
   "Fill in the variables EXPANSION with ARGS."
@@ -348,7 +348,7 @@ A variable is a symbol that looks like $1, $2, $3, etc. A $ 
means $1."
   "Escape THING for use as a `format' spec, pre-escaping for KIND.
 KIND should be :value or :identifier."
   (replace-regexp-in-string
-   "%" "%%" (case kind
+   "%" "%%" (cl-case kind
   (:value (emacsql-escape-value thing))
   (:identifier (emacsql-escape thing))
   (otherwise thing
@@ -367,7 +367,7 @@ KIND should be :value or :identifier."
   "Only use within `emacsql-with-vars'!"
   (if (emacsql-var thing)
   (prog1 "%s" (push (cons (emacsql-var thing) kind) emacsql--vars))
-(ecase kind
+(cl-ecase kind
   ((:identifier :value) (emacsql-escape-format thing kind))
   (:auto (emacsql-escape-format
   thing (if (symbolp thing) :identifier :value))
@@ -390,6 +390,9 @@ definitions for return from a `emacsql-defexpander'."
 (symbol-function 'emacsql--vars-combine)))
 

[nongnu] elpa/emacsql 3f38b357c3 206/427: Detect empty SQL vectors (better error messages).

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 3f38b357c3f5ca7a3a2041c624daaa7962a20a58
Author: Christopher Wellons 
Commit: Christopher Wellons 

Detect empty SQL vectors (better error messages).
---
 emacsql-compiler.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/emacsql-compiler.el b/emacsql-compiler.el
index 5a226579fc..5413d5cee9 100644
--- a/emacsql-compiler.el
+++ b/emacsql-compiler.el
@@ -58,6 +58,7 @@
 (defun emacsql-escape-vector (vector)
   "Encode VECTOR into a SQL vector scalar."
   (cl-typecase vector
+(null   (emacsql-error "Empty SQL vector expression."))
 (list   (mapconcat #'emacsql-escape-vector vector ", "))
 (vector (concat "(" (mapconcat #'emacsql-escape-value vector ", ") ")"))
 (otherwise (emacsql-error "Invalid vector %S" vector



[nongnu] elpa/emacsql 86687b6ba3 067/427: Flesh out more README.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 86687b6ba3e0830da7179b4ce218da7b571debbf
Author: Christopher Wellons 
Commit: Christopher Wellons 

Flesh out more README.
---
 README.md | 60 ++--
 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index 7d3aeea714..9508383903 100644
--- a/README.md
+++ b/README.md
@@ -15,32 +15,48 @@ objects.
 
 Requires Emacs 24 or later.
 
-## Usage
+## Example Usage
 
 ```el
-(defvar db (emacsql-connect "company.db"))
+(defvar db (emacsql-connect "/var/lib/company.db"))
 
 ;; Create a table. A table identifier can be any kind of lisp value.
-(emacsql-create db 'employees [name id salary])
+(emacsql db [:create-table people [name id salary]])
 
 ;; Or optionally provide column constraints.
-(emacsql-create db 'employees [name (id integer :unique) (salary float)])
+(emacsql db [:create-table people [name (id integer :unique) (salary float)]])
 
 ;; Insert some data:
-(emacsql-insert db 'employees ["Jeff"  1000 6.0]
-  ["Susan" 1001 64000.0])
+(emacsql-insert db 'people ["Jeff"  1000 6.0]
+   ["Susan" 1001 64000.0])
 
 ;; Query the database for results:
-(emacsql db [:select [name id] :from employees :where (> salary 62000)])
+(emacsql db [:select [name id] :from people :where (> salary 62000)])
 ;; => (("Susan" 1001))
 
 ;; Queries can be templates, using $1, $2, etc.:
-(emacsql db
- [:select [name id] :from employees :where (> salary $1)]
- 5)
+(emacsql db [:select [name id] :from people :where (> salary $1)] 5)
 ;; => (("Jeff" 1000) ("Susan" 1001))
 ```
 
+## Schema
+
+A table schema is a vector of column specification. A column
+identifier is a symbol and a specification can either be just this
+symbol or it can include constraints, such as type and uniqueness.
+Because Emacsql stores entire lisp objects as values, the only
+relevant types are `integer`, `float`, and `object` (default).
+
+Additional contraints include `:primary` (aka `PRIMARY KEY`),
+`:unique` (aka `UNIQUE`), `:non-nil` (aka `NOT NULL`).
+
+```el
+;; Example schema:
+[name (badge-no integer :primary :unique) address]
+```
+
+The lisp object `nil` corresponds 1:1 with `NULL` in the database.
+
 ## Operators
 
 Emacsql currently supports the following expression operators, named
@@ -83,30 +99,38 @@ When multiple keywords appear in sequence, Emacsql will 
generally
 concatenate them with a dash, e.g. `CREATE TABLE` becomes
 `:create-table`.
 
- * `:create-table  `
+ :create-table `` ``
 
 Provides `CREATE TABLE`.
 
-ex. [:create-table employees [name (id integer :primary) (salary float)]]
+```el
+[:create-table employees [name (id integer :primary) (salary float)]]
+```
 
- * `:drop-table `
+ :drop-table ``
 
 Provides `DROP TABLE`.
 
-ex. [:drop-table employees]
+```el
+[:drop-table employees]
+```
 
- * `:select `
+ :select ``
 
 Provides `SELECT`. `column-spec` can be a `*` symbol or a vector of
 column identifiers, optionally as expressions.
 
-ex. [:select [name (/ salary 52)] ...]
+```el
+[:select [name (/ salary 52)] ...]
+```
 
- * `:from `
+ :from ``
 
 Provides `FROM`.
 
-ex. [... :from employees]
+```el
+[... :from employees]
+```
 
 ### Templates
 



[nongnu] elpa/emacsql 39aa16906a 034/427: Remove redundant wait.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 39aa16906a707b5ca06dd3ecff5889353866d5c5
Author: Christopher Wellons 
Commit: Christopher Wellons 

Remove redundant wait.
---
 emacsql.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/emacsql.el b/emacsql.el
index 4e2dcb3eec..9badf8cd6e 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -289,7 +289,6 @@ Each row must be a sequence of values to store into TABLE.
   "Send a raw QUERY string to CONN."
   (emacsql--clear conn)
   (emacsql--send conn query)
-  (emacsql-wait conn)
   (emacsql--check-error conn)
   (emacsql--parse conn))
 



[nongnu] elpa/emacsql c1ea25c872 322/427: Drop Windows issue from README (fixed in 24.4).

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit c1ea25c87290f6d222497ad73ac0828c39daffef
Author: Christopher Wellons 
Commit: Christopher Wellons 

Drop Windows issue from README (fixed in 24.4).

This statement was only true up until 24.4.
---
 README.md | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/README.md b/README.md
index 48e7cb3316..c5ec5ee7e3 100644
--- a/README.md
+++ b/README.md
@@ -26,13 +26,6 @@ having any particular software installed.
 
 Requires Emacs 24 or later.
 
-### Windows Issue
-
-Due to a [long-standing Emacs bug][batch], EmacSQL cannot be used in
-Emacs' "-batch" mode on Windows, which includes running the EmacSQL
-test suite from the Makefile. However, it will still work properly
-within Cygwin.
-
 ## Example Usage
 
 ```el



[nongnu] elpa/emacsql 6c32f02139 137/427: Add emacsql-thread macro.

2022-12-13 Thread ELPA Syncer
branch: elpa/emacsql
commit 6c32f02139d54b989be62fb530ff2e73899ceb74
Author: Christopher Wellons 
Commit: Christopher Wellons 

Add emacsql-thread macro.
---
 emacsql.el | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/emacsql.el b/emacsql.el
index a1986e2e19..6e44c2a2bd 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -161,6 +161,17 @@ CONN-SPEC is a connection specification like the call to
  (progn ,@body)
(emacsql-close ,(car conn-spec)
 
+(defmacro emacsql-thread (conn &rest statements)
+  "Thread CONN through STATEMENTS.
+A statement can be a list, containing a statement with its arguments."
+  (declare (indent 1))
+  `(let ((emacsql--conn ,conn))
+ ,@(cl-loop for statement in statements
+   when (vectorp statement)
+   collect (list 'emacsql 'emacsql--conn statement)
+   else
+   collect (append (list 'emacsql 'emacsql--conn) statement
+
 (defun emacsql-buffer (conn)
   "Get proccess buffer for CONN."
   (process-buffer (emacsql-process conn)))



  1   2   3   4   5   6   7   >