lsp-sqls.el (7386B)
1 ;;; lsp-sqls.el --- SQL Client settings -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2020 Shunya Ishii 4 5 ;; Author: Shunya Ishii 6 ;; Keywords: sql lsp 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; LSP client for SQL 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 29 (defgroup lsp-sqls nil 30 "LSP support for SQL, using sqls." 31 :group 'lsp-mode 32 :link '(url-link "https://github.com/sqls-server/sqls") 33 :package-version `(lsp-mode . "7.0")) 34 35 (defcustom lsp-sqls-server "sqls" 36 "Path to the `sqls` binary." 37 :group 'lsp-sqls 38 :risky t 39 :type 'file 40 :package-version `(lsp-mode . "7.0")) 41 42 (defcustom lsp-sqls-workspace-config-path "workspace" 43 "If non-nil then setup workspace configuration with json file path." 44 :group 'lsp-sqls 45 :risky t 46 :type '(choice (const "workspace") 47 (const "root")) 48 :package-version `(lsp-mode . "7.0")) 49 50 (defun lsp-sqls--make-launch-cmd () 51 (-let [base `(,lsp-sqls-server)] 52 ;; we can add some options to command. (e.g. "-config") 53 base)) 54 55 56 (defcustom lsp-sqls-timeout 0.5 57 "Timeout to use for `sqls' requests." 58 :type 'number 59 :package-version '(lsp-mode . "8.0.0")) 60 61 (defcustom lsp-sqls-connections nil 62 "The connections to the SQL server(s)." 63 :type '(repeat (alist :key-type (choice 64 (const :tag "Driver" driver) 65 (const :tag "Connection String" dataSourceName)) 66 :value-type string))) 67 68 (defun lsp-sqls-setup-workspace-configuration () 69 "Setup workspace configuration using json file. 70 Depending on `lsp-sqls-workspace-config-path'." 71 72 (if lsp-sqls-connections 73 (lsp--set-configuration `(:sqls (:connections ,(apply #'vector lsp-sqls-connections)))) 74 (when-let ((config-json-path (cond 75 ((equal lsp-sqls-workspace-config-path "workspace") 76 ".sqls/config.json") 77 ((equal lsp-sqls-workspace-config-path "root") 78 (-> (lsp-workspace-root) 79 (f-join ".sqls/config.json")))))) 80 (when (file-exists-p config-json-path) 81 (lsp--set-configuration (lsp--read-json-file config-json-path)))))) 82 83 (defun lsp-sqls--show-results (result) 84 (with-current-buffer (get-buffer-create "*sqls results*") 85 (with-help-window (buffer-name) 86 (erase-buffer) 87 (insert result)))) 88 89 (defun lsp-sql-execute-query (&optional command start end) 90 "Execute COMMAND on buffer text against current database. 91 Buffer text is between START and END. If START and END are nil, 92 use the current region if set, otherwise the entire buffer." 93 (interactive) 94 (lsp-sqls--show-results 95 (lsp-request 96 "workspace/executeCommand" 97 (list :command "executeQuery" 98 :arguments (or 99 (when command 100 (lsp:command-arguments? command)) 101 (vector (lsp--buffer-uri))) 102 :timeout lsp-sqls-timeout 103 :range (list 104 :start (lsp--point-to-position 105 (cond 106 (start start) 107 ((use-region-p) (region-beginning)) 108 (t (point-min)))) 109 :end (lsp--point-to-position 110 (cond 111 (end end) 112 ((use-region-p) (region-end)) 113 (t (point-max))))))))) 114 115 (defun lsp-sql-execute-paragraph (&optional command) 116 "Execute COMMAND on paragraph against current database." 117 (interactive) 118 (let ((start (save-excursion (backward-paragraph) (point))) 119 (end (save-excursion (forward-paragraph) (point)))) 120 (lsp-sql-execute-query command start end))) 121 122 (defun lsp-sql-show-databases (&optional _command) 123 "Show databases." 124 (interactive) 125 (lsp-sqls--show-results 126 (lsp-request 127 "workspace/executeCommand" 128 (list :command "showDatabases" :timeout lsp-sqls-timeout)))) 129 130 (defun lsp-sql-show-schemas (&optional _command) 131 "Show schemas." 132 (interactive) 133 (lsp-sqls--show-results 134 (lsp-request 135 "workspace/executeCommand" 136 (list :command "showSchemas" :timeout lsp-sqls-timeout)))) 137 138 (defun lsp-sql-show-connections (&optional _command) 139 "Show connections." 140 (interactive) 141 (lsp-sqls--show-results 142 (lsp-request 143 "workspace/executeCommand" 144 (list :command "showConnections" :timeout lsp-sqls-timeout)))) 145 146 (defun lsp-sql-show-tables (&optional _command) 147 "Show tables." 148 (interactive) 149 (lsp-sqls--show-results 150 (lsp-request 151 "workspace/executeCommand" 152 (list :command "showTables" :timeout lsp-sqls-timeout)))) 153 154 (defun lsp-sql-switch-database (&optional _command) 155 "Switch database." 156 (interactive) 157 (lsp-workspace-command-execute 158 "switchDatabase" 159 (vector (completing-read 160 "Select database: " 161 (s-lines (lsp-workspace-command-execute "showDatabases")) 162 nil 163 t)))) 164 165 (defun lsp-sql-switch-connection (&optional _command) 166 "Switch connection." 167 (interactive) 168 (lsp-workspace-command-execute 169 "switchConnections" 170 (vector (cl-first 171 (s-match "\\([[:digit:]]*\\)" 172 (completing-read 173 "Select connection: " 174 (s-lines (lsp-workspace-command-execute "showConnections")) 175 nil 176 t)))))) 177 178 (lsp-register-client 179 (make-lsp-client :new-connection (lsp-stdio-connection #'lsp-sqls--make-launch-cmd) 180 :major-modes '(sql-mode) 181 :priority -2 182 :action-handlers (ht ("executeParagraph" #'lsp-sql-execute-paragraph) 183 ("executeQuery" #'lsp-sql-execute-query) 184 ("showDatabases" #'lsp-sql-show-databases) 185 ("showSchemas" #'lsp-sql-show-schemas) 186 ("showConnections" #'lsp-sql-show-connections) 187 ("showTables" #'lsp-sql-show-tables) 188 ("switchDatabase" #'lsp-sql-switch-database) 189 ("switchConnections" #'lsp-sql-switch-connection)) 190 :server-id 'sqls 191 :initialized-fn (lambda (workspace) 192 (-> workspace 193 (lsp--workspace-server-capabilities) 194 (lsp:set-server-capabilities-execute-command-provider? t)) 195 (with-lsp-workspace workspace 196 (lsp-sqls-setup-workspace-configuration))))) 197 198 (lsp-consistency-check lsp-sqls) 199 200 (provide 'lsp-sqls) 201 ;;; lsp-sqls.el ends here