-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmadolt-sql.el
More file actions
140 lines (111 loc) · 4.47 KB
/
madolt-sql.el
File metadata and controls
140 lines (111 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
;;; madolt-sql.el --- SQL query interface for Madolt -*- lexical-binding:t -*-
;; Copyright (C) 2026 Adam Spiers
;; Author: Adam Spiers <madolt@adamspiers.org>
;; Maintainer: Adam Spiers <madolt@adamspiers.org>
;; Package-Requires: ((emacs "29.1") (magit-section "4.0"))
;; SPDX-License-Identifier: GPL-3.0-or-later
;; This file is not part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Interactive SQL query interface for madolt. Prompts for a SQL
;; query via the minibuffer, executes it with `dolt sql -q', and
;; displays the results in a dedicated buffer. Previous queries
;; are available via minibuffer history.
;;; Code:
(require 'magit-section)
(require 'madolt-dolt)
(require 'madolt-mode)
;;;; Query history
(defvar madolt-sql-history nil
"Minibuffer history for SQL queries.")
;;;; Buffer-local variables
(defvar-local madolt-sql--query nil
"The SQL query shown in this result buffer.")
(defvar-local madolt-sql--limit 1000
"Number of SQL result output lines to show.")
;;;; Row limit expansion
(defun madolt-sql-double-limit ()
"Double the number of SQL result lines shown and refresh."
(interactive)
(setq madolt-sql--limit (* madolt-sql--limit 2))
(madolt-refresh))
;;;; SQL result mode
(define-derived-mode madolt-sql-mode madolt-mode "Madolt SQL"
"Mode for madolt SQL result buffers.")
;;;; Commands
;;;###autoload
(defun madolt-sql-query (query)
"Execute SQL QUERY and display results.
Prompts for QUERY via the minibuffer with history support."
(interactive
(list (read-string "SQL query: " nil 'madolt-sql-history)))
(when (string-blank-p query)
(user-error "Empty query"))
(let* ((db-dir (or (madolt-database-dir)
(user-error "Not in a Dolt database")))
(buf-name (madolt--buffer-name 'madolt-sql-mode db-dir))
(buffer (or (get-buffer buf-name)
(generate-new-buffer buf-name))))
(with-current-buffer buffer
(unless (derived-mode-p 'madolt-sql-mode)
(madolt-sql-mode))
(setq default-directory db-dir)
(setq madolt-buffer-database-dir db-dir)
(setq madolt-sql--query query)
(madolt-refresh))
(madolt-display-buffer buffer)
buffer))
;;;; Refresh
(defun madolt-sql-refresh-buffer ()
"Refresh the SQL result buffer by re-executing the query."
(let* ((query madolt-sql--query)
(result (madolt--run "sql" "-q" query "-r" "tabular"))
(exit-code (car result))
(output (madolt--strip-ansi (cdr result))))
(magit-insert-section (sql-result)
(magit-insert-heading
(format "SQL: %s" query))
(if (zerop exit-code)
(if (string-blank-p (string-trim output))
(insert (propertize " Query executed successfully (no output)\n"
'font-lock-face 'shadow))
(madolt-sql--insert-result output))
(insert (propertize (format " Error: %s\n" (string-trim output))
'font-lock-face 'error)))
(insert "\n"))))
;;;; Result rendering
(defun madolt-sql--insert-result (output)
"Insert tabular OUTPUT from dolt sql into the current buffer."
(let* ((lines (split-string output "\n" t))
(total (length lines))
(limit madolt-sql--limit)
(shown 0))
(dolist (line lines)
(when (< shown limit)
(insert (madolt-sql--fontify-line line) "\n")
(cl-incf shown)))
(when (> total limit)
(madolt-insert-show-more-button
shown total
'madolt-mode-map 'madolt-sql-double-limit))))
(defun madolt-sql--fontify-line (line)
"Apply faces to a tabular result LINE.
Border lines (+-...) get shadow face; header rows get bold."
(cond
;; Border line: +----+----+
((string-match-p "^[+|]-" line)
(if (string-match-p "^\\+-" line)
(propertize line 'font-lock-face 'shadow)
line))
(t line)))
(provide 'madolt-sql)
;;; madolt-sql.el ends here