From a7f4aed08c5a90082a1a4e686276ac96644b24fd Mon Sep 17 00:00:00 2001 From: Phil Estival Date: Fri, 17 Jan 2025 01:40:47 +0100 Subject: [PATCH 06/11] ob-sql: add support for sessions in `org-babel-execute:sql' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/ob-sql.el: regular code block execution can also be run through the same path as sessions — e.g. functions of sql.el and a comint buffer — when the custom predicate `org-sql-run-comint-p' is set, but this is slower. --- lisp/ob-sql.el | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/lisp/ob-sql.el b/lisp/ob-sql.el index 976f673ee..ca9634a43 100644 --- a/lisp/ob-sql.el +++ b/lisp/ob-sql.el @@ -294,7 +294,7 @@ database connections." (cdr (assoc-string dbconnection sql-connection-alist t)))))))) (defun org-babel-execute:sql (body params) - "Execute a block of Sql code with Babel. + "Execute SQL BODY with PARAMS. This function is called by `org-babel-execute-src-block'." (let* ((result-params (cdr (assq :result-params params))) (cmdline (cdr (assq :cmdline params))) @@ -305,11 +305,52 @@ This function is called by `org-babel-execute-src-block'." (dbinstance (org-babel-find-db-connection-param params :dbinstance)) (database (org-babel-find-db-connection-param params :database)) (engine (cdr (assq :engine params))) + (in-engine (intern (or engine (user-error "Missing :engine")))) (colnames-p (not (equal "no" (cdr (assq :colnames params))))) (in-file (org-babel-temp-file "sql-in-")) (out-file (or (cdr (assq :out-file params)) (org-babel-temp-file "sql-out-"))) (header-delim "") + (session (cdr (assoc :session params))) + (session-p (not (string= session "none")))) + + (if (or session-p org-sql-run-comint-p) ; run through comint + (let ((sql--buffer + (org-babel-sql-session-connect in-engine params session))) + (with-current-buffer (get-buffer-create "*ob-sql-result*") + (erase-buffer)) + (setq org-sql-session-start-time (current-time)) + (setq org-sql-session-command-terminated nil) + + (with-current-buffer (get-buffer sql--buffer) + (process-send-string (current-buffer) + (org-sql-session-format-query + (org-babel-expand-body:sql body params) + in-engine)) + (while (or (not org-sql-session-command-terminated) + (> (time-to-seconds + (time-subtract (current-time) + org-sql-session-start-time)) + org-sql-timeout)) + (sleep-for 0.03)) + ;; command finished, remove filter + (set-process-filter (get-buffer-process sql--buffer) nil) + + (when (not session-p) + (comint-quit-subjob) + ;; despite this quit signal, the process may not be finished yet + (let ((kill-buffer-query-functions nil)) + (kill-this-buffer)))) + + (with-current-buffer (get-buffer-create "*ob-sql-result*") + (goto-char (point-min)) + ;; clear the output or prompt and termination + (let ((clean-output (plist-get org-sql-session-clean-output in-engine))) + (while (re-search-forward clean-output nil t) + (replace-match ""))) + (write-file out-file))) + + (let ( ; else run one command line (command (cl-case (intern engine) (dbi (format "dbish --batch %s < %s | sed '%s' > %s" (or cmdline "") @@ -405,7 +446,7 @@ SET COLSEP '|' (org-babel-expand-body:sql body params) ;; "sqsh" requires "go" inserted at EOF. (if (string= engine "sqsh") "\ngo" ""))) - (org-babel-eval command "") + (org-babel-eval command ""))) (org-babel-result-cond result-params (with-temp-buffer (progn (insert-file-contents-literally out-file) (buffer-string))) @@ -435,6 +476,8 @@ SET COLSEP '|' (forward-char -1)) (write-file out-file)))) (org-table-import out-file (if (string= engine "sqsh") '(4) '(16))) + (when org-sql-close-out-temp-buffer-p + (kill-buffer (get-file-buffer out-file))) (org-babel-reassemble-table (mapcar (lambda (x) (if (string= (car x) header-delim) -- 2.39.5