branch: elpa/emacsql commit 6d17256e1b80da18e7bbd69c880cd4f4b9cf1af8 Author: Christopher Wellons <well...@nullprogram.com> Commit: Christopher Wellons <well...@nullprogram.com>
Add a mix-in class to reduce code duplication. --- emacsql-psql.el | 4 ++-- emacsql-sqlite.el | 23 ++--------------------- emacsql.el | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/emacsql-psql.el b/emacsql-psql.el index 008eb8334c..56583f6de4 100644 --- a/emacsql-psql.el +++ b/emacsql-psql.el @@ -26,7 +26,7 @@ nil))) (error :cannot-execute))))) -(defclass emacsql-psql-connection (emacsql-connection) +(defclass emacsql-psql-connection (emacsql-connection emacsql-simple-parser) ((dbname :reader emacsql-psql-dbname :initarg :dbname)) (:documentation "A connection to a PostgreSQL database.")) @@ -91,7 +91,7 @@ (emacsql-clear connection) (emacsql-send-string connection sql-string) (emacsql-psql--check-error connection) - (emacsql-sqlite--parse connection))) + (emacsql-simple-parse connection))) (provide 'emacsql-psql) diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el index 6bb1f2e5c1..4708ffbaf2 100644 --- a/emacsql-sqlite.el +++ b/emacsql-sqlite.el @@ -26,7 +26,7 @@ nil))) (error :cannot-execute))))) -(defclass emacsql-sqlite-connection (emacsql-connection) +(defclass emacsql-sqlite-connection (emacsql-connection emacsql-simple-parser) ((file :initarg :file :type (or null string) :documentation "Database file name.")) @@ -71,25 +71,6 @@ buffer. This is for debugging purposes." (when (process-live-p process) (process-send-string process ".exit\n")))) -(defmethod emacsql-waiting-p ((connection emacsql-sqlite-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-sqlite--parse (connection) - "Parse SQLite output into an s-expression." - (with-current-buffer (emacsql-buffer connection) - (let ((standard-input (current-buffer))) - (setf (point) (point-min)) - (cl-loop until (looking-at "]") - collect (read) into row - when (looking-at "\n") - collect row into rows - and do (progn (forward-char 1) (setf row ())) - finally (cl-return rows))))) - (defvar emacsql-sqlite-condition-alist '(("unable to open" emacsql-access) ("cannot open" emacsql-access) @@ -157,7 +138,7 @@ buffer. This is for debugging purposes." (emacsql-clear connection) (emacsql-send-string connection sql-string) (emacsql-sqlite--check-error connection) - (emacsql-sqlite--parse connection))) + (emacsql-simple-parse connection))) (provide 'emacsql-sqlite) diff --git a/emacsql.el b/emacsql.el index eb30f73ca3..17a574d56d 100644 --- a/emacsql.el +++ b/emacsql.el @@ -115,7 +115,7 @@ MESSAGE should not have a newline on the end." "Like `error', but signal an emacsql-syntax condition." (signal 'emacsql-syntax (list (apply #'format format args)))) -;;; Sending and receiving: +;; Sending and receiving: (defmethod emacsql-send-string ((connection emacsql-connection) string &optional no-log) @@ -140,6 +140,35 @@ MESSAGE should not have a newline on the end." (not (emacsql-waiting-p connection))) (accept-process-output (emacsql-process connection) timeout)))) +;; Helper mix-in class: + +(defclass emacsql-simple-parser () + () + (:documentation "A mix-in for back-ends with a specific output format.") + :abstract t) + +(defmethod emacsql-waiting-p ((connection emacsql-simple-parser)) + "The back-end must us a single \"]\" character as its prompt. +This prompt value was chosen because it is unreadable." + (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))))))) + +(defmethod emacsql-simple-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) + (let ((standard-input (current-buffer))) + (setf (point) (point-min)) + (cl-loop until (looking-at "]") + collect (read) into row + when (looking-at "\n") + collect row into rows + and do (progn (forward-char 1) (setf row ())) + finally (cl-return rows))))) + (provide 'emacsql) ; end of generic function declarations ;; Automatic connection cleanup: @@ -218,7 +247,7 @@ A statement can be a list, containing a statement with its arguments." else collect (append (list 'emacsql 'emacsql--conn) statement)))) -;;; Escaping: +;; Escaping: (defun emacsql-quote (string) "Quote STRING for use in a SQL expression."