[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/emacsql 9a1b4209ba 164/427: Add PostgreSQL front-end.
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/emacsql 9a1b4209ba 164/427: Add PostgreSQL front-end. |
Date: |
Tue, 13 Dec 2022 02:59:38 -0500 (EST) |
branch: elpa/emacsql
commit 9a1b4209ba967506cc5d91bb63395123807e956d
Author: Christopher Wellons <wellons@nullprogram.com>
Commit: Christopher Wellons <wellons@nullprogram.com>
Add PostgreSQL front-end.
---
Makefile | 2 +-
emacsql-psql.el | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
emacsql-sqlite.el | 10 ++++----
emacsql-tests.el | 7 ++---
emacsql.el | 7 +++--
5 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/Makefile b/Makefile
index b6ea2b187b..477486dba3 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ BATCH := $(EMACS) -batch -Q -L .
COMPILE := $(BATCH) -f batch-byte-compile
TEST := $(BATCH) -l $(PACKAGE)-tests.elc -f ert-run-tests-batch
-EL = emacsql.el emacsql-sqlite.el $(PACKAGE)-tests.el
+EL = emacsql.el emacsql-sqlite.el emacsql-psql.el $(PACKAGE)-tests.el
ELC = $(EL:.el=.elc)
diff --git a/emacsql-psql.el b/emacsql-psql.el
new file mode 100644
index 0000000000..5dd3184e4a
--- /dev/null
+++ b/emacsql-psql.el
@@ -0,0 +1,77 @@
+;;; emacsql-psql.el --- PostgreSQL front-end for Emacsql -*- lexical-binding:
t; -*-
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'eieio)
+(require 'emacsql)
+
+(defvar emacsql-psql-executable "psql"
+ "Path to the psql (PostgreSQL client) executable.")
+
+(defclass emacsql-psql-connection (emacsql-connection)
+ ((dbname :reader emacsql-psql-dbname :initarg :dbname))
+ (:documentation "A connection to a PostgreSQL database."))
+
+(cl-defun emacsql-psql (dbname &key username hostname port)
+ "Connect to a PostgreSQL server using the psql command line program."
+ (let ((args (list dbname)))
+ (when username
+ (push username args))
+ (push "-n" args)
+ (when port
+ (push "-p" args)
+ (push port args))
+ (when hostname
+ (push "-h" args)
+ (push hostname args))
+ (setf args (nreverse args))
+ (let* ((buffer (generate-new-buffer "*emacsql-psql*"))
+ (psql emacsql-psql-executable)
+ (process (apply #'start-process "emacsql-psql" buffer psql args))
+ (connection (make-instance 'emacsql-psql-connection
+ :process process
+ :dbname dbname)))
+ (prog1 connection
+ (emacsql-add-connection connection)
+ (emacsql-send-string connection "\\pset pager off")
+ (emacsql-send-string connection "\\a")
+ (emacsql-send-string connection "\\t")
+ (emacsql-send-string connection "\\f ' '")
+ (emacsql-send-string connection "\\set PROMPT1 ]")
+ (emacsql-send-string connection "EMACSQL;") ; error message flush
+ (emacsql-wait connection)))))
+
+(defmethod emacsql-close ((connection emacsql-psql-connection))
+ (let ((process (emacsql-process connection)))
+ (when (process-live-p process)
+ (process-send-string process "\\q\n"))))
+
+(defmethod emacsql-waiting-p ((connection emacsql-psql-connection))
+ (with-current-buffer (emacsql-buffer connection)
+ (cond ((= (buffer-size) 1) (string= "]" (buffer-string)))
+ ((> (buffer-size) 1) (string= "\n]"
+ (buffer-substring
+ (- (point-max) 2) (point-max)))))))
+
+(defun emacsql-psql--check-error (connection)
+ "Return non-nil or throw an appropriate error."
+ (with-current-buffer (emacsql-buffer connection)
+ (emacsql-wait connection)
+ (setf (point) (point-min))
+ (prog1 t
+ (when (looking-at "ERROR:")
+ (let ((message (buffer-substring (line-beginning-position)
+ (line-end-position))))
+ (emacsql-error "%s" message))))))
+
+(defmethod emacsql ((connection emacsql-psql-connection) sql &rest args)
+ (let ((sql-string (apply #'emacsql-compile sql args)))
+ (emacsql-clear connection)
+ (emacsql-send-string connection sql-string)
+ (emacsql-psql--check-error connection)
+ (emacsql-sqlite--parse connection)))
+
+(provide 'emacsql-psql)
+
+;;; emacsql-psql.el ends here
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index 243cb73113..25e9ca5fbc 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -1,4 +1,4 @@
-;; emacsql-sqlite.el --- SQLite backend for Emacsql -*- lexical-binding: t; -*-
+;; emacsql-sqlite.el --- SQLite front-end for Emacsql -*- lexical-binding: t;
-*-
;;; Code:
@@ -40,9 +40,10 @@ If FILE is nil use an in-memory database.
:debug LOG -- When non-nil, log all SQLite commands to a log
buffer. This is for debugging purposes."
- (let* ((buffer (generate-new-buffer "*emacsql-connection*"))
+ (let* ((buffer (generate-new-buffer "*emacsql-sqlite*"))
(fullfile (if file (expand-file-name file) ":memory:"))
- (process (start-process "emacsql" buffer emacsql-sqlite3-executable
+ (sqlite3 emacsql-sqlite3-executable)
+ (process (start-process "emacsql-sqlite" buffer sqlite3
"-interactive" fullfile)))
(setf (process-sentinel process) (lambda (_proc _) (kill-buffer buffer)))
(process-send-string process ".mode list\n")
@@ -68,7 +69,7 @@ buffer. This is for debugging purposes."
(defmethod emacsql-close ((connection emacsql-sqlite-connection))
"Gracefully exits the SQLite subprocess."
(let ((process (emacsql-process connection)))
- (when (and process (process-live-p process))
+ (when (process-live-p process)
(process-send-string process ".exit\n"))))
(defmethod emacsql-waiting-p ((connection emacsql-sqlite-connection))
@@ -153,7 +154,6 @@ buffer. This is for debugging purposes."
(signal condition (list message)))))))
(defmethod emacsql ((connection emacsql-sqlite-connection) sql &rest args)
- "Send structured SQL expression to CONNECTION with ARGS."
(let ((sql-string (apply #'emacsql-compile sql args)))
(emacsql-clear connection)
(emacsql-send-string connection sql-string)
diff --git a/emacsql-tests.el b/emacsql-tests.el
index 36d78722ee..32168b1eaa 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -4,6 +4,7 @@
(require 'ert)
(require 'emacsql)
+(require 'emacsql-sqlite)
(ert-deftest emacsql-escape-identifier ()
(should (string= (emacsql-escape-identifier "foo") "foo"))
@@ -190,7 +191,7 @@
(ert-deftest emacsql-system ()
"A short test that fully interacts with SQLite."
(should-not (emacsql-sqlite3-unavailable-p))
- (emacsql-with-connection (db nil)
+ (emacsql-with-connection (db (emacsql-sqlite nil))
(emacsql db [:create-table foo [x]])
(should-error (emacsql db [:create-table foo [x]]))
(emacsql db [:insert :into foo :values ([1] [2] [3])])
@@ -199,7 +200,7 @@
(ert-deftest emacsql-foreign-system ()
"Tests that foreign keys work properly through Emacsql."
- (emacsql-with-connection (db nil)
+ (emacsql-with-connection (db (emacsql-sqlite nil))
(emacsql-thread db
[:pragma (= foreign_keys on)]
[:create-table person [(id integer :primary) name]]
@@ -224,7 +225,7 @@
:type 'emacsql-syntax)
(should-error (emacsql-compile [:insert :into foo :values 1])
:type 'emacsql-syntax)
- (emacsql-with-connection (db nil)
+ (emacsql-with-connection (db (emacsql-sqlite nil))
(emacsql db [:create-table foo [x]])
(should-error (emacsql db [:create-table foo [x]])
:type 'emacsql-table)))
diff --git a/emacsql.el b/emacsql.el
index c9097c6113..e6e8bf50ef 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -194,15 +194,14 @@ This collection exists for cleanup purposes.")
(defmacro emacsql-with-connection (connection-spec &rest body)
"Open an Emacsql connection, evaluate BODY, and close the connection.
-CONNECTION-SPEC is a connection specification like the call to
-`emacsql-connect', establishing a single binding.
+CONNECTION-SPEC establishes a single binding.
- (emacsql-with-connection (db \"company.db\")
+ (emacsql-with-connection (db (emacsql-sqlite \"company.db\"))
(emacsql db [:create-table foo [x]])
(emacsql db [:insert :into foo :values ([1] [2] [3])])
(emacsql db [:select * :from foo]))"
(declare (indent 1))
- `(let ((,(car connection-spec) (emacsql-connect ,@(cdr connection-spec))))
+ `(let ((,(car connection-spec) ,(cadr connection-spec)))
(unwind-protect
(progn ,@body)
(emacsql-close ,(car connection-spec)))))
- [nongnu] elpa/emacsql fc941d7c75 118/427: Capture a common identifier vector pattern., (continued)
- [nongnu] elpa/emacsql fc941d7c75 118/427: Capture a common identifier vector pattern., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a09911a205 125/427: Add LIMIT and OFFSET expanders., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 8945af0dd8 129/427: Add :check and allow schemas to have variables., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4206b17f39 134/427: Add support for AS with CREATE TABLE., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 6c32f02139 137/427: Add emacsql-thread macro., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 54c180017e 138/427: Add :pragma and note in README., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 5e2ab842f7 139/427: Add foreign key test., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 42c2fd7569 145/427: Tweak limitation wording., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql fe0c7004fc 146/427: Add :begin, :commit, and :rollback., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 2550196816 162/427: Drop SQLite version requirements., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9a1b4209ba 164/427: Add PostgreSQL front-end.,
ELPA Syncer <=
- [nongnu] elpa/emacsql 5f4c2ed5a7 166/427: Add emacsql-psql-unavailable-p., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 1d0ef4011c 167/427: Make emacsql-connection abstract., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 64c3a03d62 169/427: Flesh out some more README., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9f6c10eca0 172/427: Move error checking out to helper mix-in., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4f76b94f7c 168/427: Set psql to print nil for NULL., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 7434263d82 174/427: Oops, drop leftover function call., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql ca62adc4b2 177/427: Add debug argument to emacsql-psql., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql afef528d81 179/427: Fix memoization to include type map., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql b2f2dd37cf 178/427: Allow connection to specify their own types., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4aa889882d 182/427: Fix slot allocation on emacsql-connection., ELPA Syncer, 2022/12/13