From 64faba3d3ef5f7bdd889e1c0ff207f07bd4e842c Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Tue, 9 May 2023 17:02:58 +0200 Subject: [PATCH] update ejc-sql Signed-off-by: Andreas Gerler --- elpa/ejc-sql-20220414.1329/ejc-direx.el | 197 -------- .../ejc-autocomplete.el | 0 .../ejc-company.el | 0 .../ejc-completion-common.el | 2 +- .../ejc-doc.el | 0 .../ejc-eldoc.el | 0 .../ejc-flx.el | 0 .../ejc-format.el | 0 .../ejc-interaction.el | 0 .../ejc-lib.el | 3 +- .../ejc-result-buffer.el | 14 +- .../ejc-result-mode.el | 0 .../ejc-sql-autoloads.el | 11 - .../ejc-sql-pkg.el | 9 +- .../ejc-sql.el | 12 +- .../project.clj | 4 +- .../snippets/sql-mode/alter.yasnippet | 0 .../snippets/sql-mode/begin.snippet | 0 .../snippets/sql-mode/delete.yasnippet | 0 .../snippets/sql-mode/grant.yasnippet | 0 .../snippets/sql-mode/inner.yasnippet | 0 .../snippets/sql-mode/insert.yasnippet | 0 .../snippets/sql-mode/left.yasnippet | 0 .../snippets/sql-mode/revoke.yasnippet | 0 .../snippets/sql-mode/right.yasnippet | 0 .../snippets/sql-mode/select.yasnippet | 0 .../snippets/sql-mode/update.yasnippet | 0 .../snippets/sql-mode/where.yasnippet | 0 .../src/ejc_sql/cache.clj | 4 +- .../src/ejc_sql/classpath.clj | 2 +- .../src/ejc_sql/connect.clj | 55 +-- .../src/ejc_sql/deps_resolver.clj | 9 +- .../src/ejc_sql/keywords.clj | 0 .../src/ejc_sql/lib.clj | 0 .../src/ejc_sql/output.clj | 71 ++- .../src/ejc_sql/structure.clj | 429 ++++++++++-------- 36 files changed, 338 insertions(+), 484 deletions(-) delete mode 100644 elpa/ejc-sql-20220414.1329/ejc-direx.el rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-autocomplete.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-company.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-completion-common.el (98%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-doc.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-eldoc.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-flx.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-format.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-interaction.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-lib.el (98%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-result-buffer.el (94%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-result-mode.el (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-sql-autoloads.el (95%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-sql-pkg.el (56%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/ejc-sql.el (99%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/project.clj (86%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/alter.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/begin.snippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/delete.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/grant.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/inner.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/insert.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/left.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/revoke.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/right.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/select.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/update.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/snippets/sql-mode/where.yasnippet (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/cache.clj (96%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/classpath.clj (96%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/connect.clj (91%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/deps_resolver.clj (91%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/keywords.clj (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/lib.clj (100%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/output.clj (82%) rename elpa/{ejc-sql-20220414.1329 => ejc-sql-20230228.102}/src/ejc_sql/structure.clj (79%) diff --git a/elpa/ejc-sql-20220414.1329/ejc-direx.el b/elpa/ejc-sql-20220414.1329/ejc-direx.el deleted file mode 100644 index dec1488c..00000000 --- a/elpa/ejc-sql-20220414.1329/ejc-direx.el +++ /dev/null @@ -1,197 +0,0 @@ -;;; ejc-direx.el - -;;; Copyright © 2017 - Kostafey - -;;; 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 2, 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, write to the Free Software Foundation, -;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -;;; Code: - - -(require 'dash) -(require 'direx) -(require 'ejc-interaction) - -(defgroup ejc-direx nil - "Database structure visualisation tree." - :group 'ejc - :prefix "ejc-direx") - - -;;; Core - -(defclass ejc-direx:object (direx:tree) ((cache :initarg :cache))) -(defclass ejc-direx:database (ejc-direx:object direx:node) - ((buffer :initarg :buffer) - (file-name :initarg :file-name - :accessor direx:file-full-name))) -(defclass ejc-direx:schema (ejc-direx:object direx:node) ()) -(defclass ejc-direx:table (ejc-direx:object direx:node) ()) -(defclass ejc-direx:colomn (ejc-direx:object direx:leaf) ()) - -(defvar ejc-direx:type-class-map - '(("database" . ejc-direx:database) - ("schema" . ejc-direx:schema) - ("table" . ejc-direx:table) - ("column" . ejc-direx:colomn))) - -(defun ejc-direx:node-from-cache (cache) - (let* ((type (plist-get (car cache) :type)) - (class (or (assoc-default type ejc-direx:type-class-map) - 'ejc-direx:colomn))) - (make-instance class - :cache cache - :name (plist-get (car cache) :name)))) - -(defun ejc-direx:-filter-cache (items) - "Filter out cache items according to configuration." - (delq nil items)) - -(defmethod direx:node-children ((node ejc-direx:object)) - (mapcar 'ejc-direx:node-from-cache - (ejc-direx:-filter-cache (cdr (oref node :cache))))) - - -;;; Face -(defface ejc-direx:database - '((t :inherit font-lock-keyword-face)) - "Face for database name in direx tree" - :group 'ejc-direx) - -(defface ejc-direx:schema - '((t :inherit font-lock-type-face)) - "Face for schema name in direx tree" - :group 'ejc-direx) - -(defface ejc-direx:table - '((t :inherit font-lock-function-name-face)) - "Face for table name in direx tree" - :group 'ejc-direx) - -(defface ejc-direx:colomn - '((t :inherit font-lock-variable-name-face)) - "Face for column name in direx tree" - :group 'ejc-direx) - - -;;; View - -(defclass ejc-direx:item (direx:item) ()) - -(defmethod direx:make-item ((tree ejc-direx:object) parent) - (make-instance 'ejc-direx:item :tree tree :parent parent)) - -(defmethod direx:make-item ((tree ejc-direx:colomn) parent) - (let ((item (call-next-method))) - (oset item :face 'ejc-direx:colomn) - item)) - -(defmethod direx:make-item ((tree ejc-direx:table) parent) - (let ((item (call-next-method))) - (oset item :face 'ejc-direx:table) - item)) - -(defmethod direx:make-item ((tree ejc-direx:schema) parent) - (let ((item (call-next-method))) - (oset item :face 'ejc-direx:schema) - item)) - -(defmethod direx:make-item ((tree ejc-direx:database) parent) - (let ((item (call-next-method))) - (oset item :face 'ejc-direx:database) - item)) - -(defun direx-ejc:-goto-item (item) - (destructuring-bind (&key line_nr column &allow-other-keys) - (car (oref (direx:item-tree item) :cache)) - (ejc:goto--line-column line_nr column))) - -(defmethod direx:generic-find-item ((item ejc-direx:item) - not-this-window) - (let* ((root (direx:item-root item)) - (filename (direx:file-full-name (direx:item-tree root)))) - (if not-this-window - (find-file-other-window filename) - (find-file filename)) - (direx-ejc:-goto-item item))) - -(defmethod direx:generic-display-item ((item ejc-direx:item)) - (let* ((root (direx:item-root item)) - (filename (direx:file-full-name (direx:item-tree root)))) - (with-selected-window (display-buffer (find-file-noselect filename)) - (direx-ejc:-goto-item item)))) - -(defvar ejc-direx:item-refresh--recurring nil) - -(defun ejc-direx:get-structure () - "Provide data - database structure for direx tree." - (cl-labels ((column-item (column) - (list :type "column" :name column)) - (table-item (table) - (let ((columns - (ejc-get-cached-colomns-list ejc-db table t))) - (cons (list :type "table" :name table) - (-map 'list - (-map #'column-item columns))))) - (schema-item (schema) - (let ((tables (ejc-get-cached-tables-list - ejc-db schema t))) - (cons (list :type "schema" :name schema) - (-map #'table-item tables))))) - ;; Assume schema == owner (difference depends on exact database type). - (if-let ((schemas (ejc-get-cached-owners-list ejc-db t))) - (-map #'schema-item schemas) - (-map #'table-item (ejc-get-cached-tables-list ejc-db nil t))))) - -(defmethod direx:item-refresh ((item ejc-direx:item) &key recursive) - "Currently it always recursively refreshes whole tree." - (if ejc-direx:item-refresh--recurring - (call-next-method) - (let* ((ejc-direx:item-refresh--recurring t) - (root (direx:item-root item)) - (module (direx:item-tree root))) - (if (with-current-buffer (oref module :buffer) - (unless (eq (cdr (oref module :cache)) (ejc-direx:get-structure)) - (oset module :cache (cons nil (ejc-direx:get-structure))))) - (call-next-method root :recursive t) - (message "No need to refresh"))))) - - -;;; Command - -(defun ejc-direx:make-buffer () - (let ((current-ejc-db ejc-db) - (buf (direx:ensure-buffer-for-root - (make-instance 'ejc-direx:database - :name (format "%s" (ejc-get-db-name ejc-db)) - :buffer (current-buffer) - :file-name (buffer-file-name) - :cache (cons nil (ejc-direx:get-structure)))))) - (with-current-buffer buf - (setq-local ejc-db current-ejc-db)) - buf)) - -;;;###autoload -(defun ejc-direx:pop-to-buffer () - (interactive) - (pop-to-buffer (ejc-direx:make-buffer))) - -;;;###autoload -(defun ejc-direx:switch-to-buffer () - (interactive) - (switch-to-buffer (ejc-direx:make-buffer))) - -(provide 'ejc-direx) - -;;; ejc-direx.el ends here diff --git a/elpa/ejc-sql-20220414.1329/ejc-autocomplete.el b/elpa/ejc-sql-20230228.102/ejc-autocomplete.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-autocomplete.el rename to elpa/ejc-sql-20230228.102/ejc-autocomplete.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-company.el b/elpa/ejc-sql-20230228.102/ejc-company.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-company.el rename to elpa/ejc-sql-20230228.102/ejc-company.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-completion-common.el b/elpa/ejc-sql-20230228.102/ejc-completion-common.el similarity index 98% rename from elpa/ejc-sql-20220414.1329/ejc-completion-common.el rename to elpa/ejc-sql-20230228.102/ejc-completion-common.el index 96a25cc3..701d9461 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-completion-common.el +++ b/elpa/ejc-sql-20230228.102/ejc-completion-common.el @@ -87,7 +87,7 @@ Uppercase by default, set to nil to use downcase candidates." (unless (or (ejc-return-point) (ejc-get-prefix-word)) (if ejc-candidates-uppercase (mapcar 'upcase (ejc-get-keywords-inner ejc-db nil)) - (mapcar 'lowercase (ejc-get-keywords-inner ejc-db nil)))))) + (mapcar 'downcase (ejc-get-keywords-inner ejc-db nil)))))) (cl-defun ejc-complete-auto-complete (buffer-name point) "Called by Clojure side when db structure cache creation process completes. diff --git a/elpa/ejc-sql-20220414.1329/ejc-doc.el b/elpa/ejc-sql-20230228.102/ejc-doc.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-doc.el rename to elpa/ejc-sql-20230228.102/ejc-doc.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-eldoc.el b/elpa/ejc-sql-20230228.102/ejc-eldoc.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-eldoc.el rename to elpa/ejc-sql-20230228.102/ejc-eldoc.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-flx.el b/elpa/ejc-sql-20230228.102/ejc-flx.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-flx.el rename to elpa/ejc-sql-20230228.102/ejc-flx.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-format.el b/elpa/ejc-sql-20230228.102/ejc-format.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-format.el rename to elpa/ejc-sql-20230228.102/ejc-format.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-interaction.el b/elpa/ejc-sql-20230228.102/ejc-interaction.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-interaction.el rename to elpa/ejc-sql-20230228.102/ejc-interaction.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-lib.el b/elpa/ejc-sql-20230228.102/ejc-lib.el similarity index 98% rename from elpa/ejc-sql-20220414.1329/ejc-lib.el rename to elpa/ejc-sql-20230228.102/ejc-lib.el index 3f0425e7..459519dc 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-lib.el +++ b/elpa/ejc-sql-20230228.102/ejc-lib.el @@ -1,6 +1,6 @@ ;;; ejc-lib.el -- ejc-sql shared objects (the part of ejc-sql). -;;; Copyright © 2013-2020 - Kostafey +;;; Copyright © 2013-2023 - Kostafey ;;; 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 @@ -20,6 +20,7 @@ (require 's) (require 'dash) +(require 'sql) (defvar-local ejc-connection-name nil "Buffer-local connection name created with `ejc-create-connection'.") diff --git a/elpa/ejc-sql-20220414.1329/ejc-result-buffer.el b/elpa/ejc-sql-20230228.102/ejc-result-buffer.el similarity index 94% rename from elpa/ejc-sql-20220414.1329/ejc-result-buffer.el rename to elpa/ejc-sql-20230228.102/ejc-result-buffer.el index acfd696e..fb61175a 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-result-buffer.el +++ b/elpa/ejc-sql-20230228.102/ejc-result-buffer.el @@ -43,6 +43,11 @@ :group 'ejc-sql :type 'integer) +(defcustom ejc-show-result-bottom nil + "When t show result output buffer in the bottom window." + :group 'ejc-sql + :type 'boolean) + (defvar ejc-ring-position 0 "Current SQL evaluation result position in ring.") @@ -123,6 +128,11 @@ or error messages." (orgtbl-mode (when (org-table-p) (org-table-align))) (ejc-result-mode (read-only-mode 1)))) +(defun ejc-show-result-buffer (output-buffer) + (if ejc-show-result-bottom + (display-buffer output-buffer '(display-buffer-at-bottom . ())) + (display-buffer output-buffer))) + ;;;###autoload (cl-defun ejc-show-last-result (&key result mode @@ -148,7 +158,7 @@ or error messages." (beginning-of-buffer) (let* ((window (or (get-buffer-window output-buffer t) (progn - (display-buffer output-buffer) + (ejc-show-result-buffer output-buffer) (get-buffer-window output-buffer t)))) (frame (window-frame window))) (if (not (eq frame (selected-frame))) @@ -182,7 +192,7 @@ or error messages." (insert-file-contents file-path) (ejc-output-mode-specific-customization) (beginning-of-buffer) - (display-buffer output-buffer) + (ejc-show-result-buffer output-buffer) (message file-path)))) ;;;###autoload diff --git a/elpa/ejc-sql-20220414.1329/ejc-result-mode.el b/elpa/ejc-sql-20230228.102/ejc-result-mode.el similarity index 100% rename from elpa/ejc-sql-20220414.1329/ejc-result-mode.el rename to elpa/ejc-sql-20230228.102/ejc-result-mode.el diff --git a/elpa/ejc-sql-20220414.1329/ejc-sql-autoloads.el b/elpa/ejc-sql-20230228.102/ejc-sql-autoloads.el similarity index 95% rename from elpa/ejc-sql-20220414.1329/ejc-sql-autoloads.el rename to elpa/ejc-sql-20230228.102/ejc-sql-autoloads.el index 3f13aa29..c05dbe88 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-sql-autoloads.el +++ b/elpa/ejc-sql-20230228.102/ejc-sql-autoloads.el @@ -46,17 +46,6 @@ something#" t nil) (register-definition-prefixes "ejc-completion-common" '("ac-ejc-documentation" "ejc-")) -;;;*** - -;;;### (autoloads nil "ejc-direx" "ejc-direx.el" (0 0 0 0)) -;;; Generated autoloads from ejc-direx.el - -(autoload 'ejc-direx:pop-to-buffer "ejc-direx" nil t nil) - -(autoload 'ejc-direx:switch-to-buffer "ejc-direx" nil t nil) - -(register-definition-prefixes "ejc-direx" '("direx" "ejc-direx:")) - ;;;*** ;;;### (autoloads nil "ejc-doc" "ejc-doc.el" (0 0 0 0)) diff --git a/elpa/ejc-sql-20220414.1329/ejc-sql-pkg.el b/elpa/ejc-sql-20230228.102/ejc-sql-pkg.el similarity index 56% rename from elpa/ejc-sql-20220414.1329/ejc-sql-pkg.el rename to elpa/ejc-sql-20230228.102/ejc-sql-pkg.el index 2d093006..f2c19318 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-sql-pkg.el +++ b/elpa/ejc-sql-20230228.102/ejc-sql-pkg.el @@ -1,10 +1,11 @@ -(define-package "ejc-sql" "20220414.1329" "Emacs SQL client uses Clojure JDBC." +(define-package "ejc-sql" "20230228.102" "Emacs SQL client uses Clojure JDBC." '((emacs "26.3") (clomacs "0.0.5") (dash "2.16.0") - (spinner "1.7.3") - (direx "1.0.0")) - :commit "5c6341c751da9c7dbed43eafc8e99f456c1de0d2" :authors + (spinner "1.7.3")) + :commit "29308faad38e9cabd98fb5a8450df15db1e4a4cb" :authors + '(("Kostafey" . "kostafey@gmail.com")) + :maintainers '(("Kostafey" . "kostafey@gmail.com")) :maintainer '("Kostafey" . "kostafey@gmail.com") diff --git a/elpa/ejc-sql-20220414.1329/ejc-sql.el b/elpa/ejc-sql-20230228.102/ejc-sql.el similarity index 99% rename from elpa/ejc-sql-20220414.1329/ejc-sql.el rename to elpa/ejc-sql-20230228.102/ejc-sql.el index cc61da06..c60e0aa1 100644 --- a/elpa/ejc-sql-20220414.1329/ejc-sql.el +++ b/elpa/ejc-sql-20230228.102/ejc-sql.el @@ -6,7 +6,7 @@ ;; URL: https://github.com/kostafey/ejc-sql ;; Keywords: sql, jdbc ;; Version: 0.4.1 -;; Package-Requires: ((emacs "26.3")(clomacs "0.0.5")(dash "2.16.0")(spinner "1.7.3")(direx "1.0.0")) +;; Package-Requires: ((emacs "26.3")(clomacs "0.0.5")(dash "2.16.0")(spinner "1.7.3")) ;; This file is not part of GNU Emacs. @@ -38,7 +38,6 @@ (require 'cl-lib) (require 'org-table) (require 'ejc-lib) -(require 'ejc-direx) (require 'ejc-eldoc) (require 'ejc-format) (require 'ejc-interaction) @@ -111,7 +110,7 @@ results. When nil, otherwise, provide `ejc-sql' users expected behaviour." :group 'ejc-sql :type '(plist :key-type string :value-type (vector symbol string))) -(defcustom ejc-completion-system 'ido +(defcustom ejc-completion-system 'standard "The completion system used by `ejc-connect'." :group 'ejc-sql :type '(radio @@ -370,7 +369,11 @@ For more details about parameters see `get-connection' function in jdbc.clj: (defun ejc-set-mode-name (connection-name) "Show CONNECTION-NAME as part of `mode-name' in `mode-line'." (setq mode-name (format "%s->[%s]" - (car (split-string mode-name "->\\[.+\\]")) + (car (split-string + (if (listp mode-name) + (car mode-name) + mode-name) + "->\\[.+\\]")) connection-name))) (cl-defun ejc-add-connection (&optional connection-name db) @@ -861,7 +864,6 @@ Buffer can be saved to file with `ejc-temp-editor-file' path." (find-file tmp-file-path) (rename-buffer tmp-buffer-name) (sql-mode) - (auto-fill-mode t) (ejc-add-connection) (get-buffer tmp-buffer-name))))) diff --git a/elpa/ejc-sql-20220414.1329/project.clj b/elpa/ejc-sql-20230228.102/project.clj similarity index 86% rename from elpa/ejc-sql-20220414.1329/project.clj rename to elpa/ejc-sql-20230228.102/project.clj index f7f0d493..95fae0fb 100644 --- a/elpa/ejc-sql-20220414.1329/project.clj +++ b/elpa/ejc-sql-20230228.102/project.clj @@ -3,11 +3,11 @@ :url "https://github.com/kostafey/ejc-sql" :license {:name "GPL 2.0+" :url "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html"} - :dependencies [[org.clojure/clojure "1.9.0"] + :dependencies [[org.clojure/clojure "1.11.1"] [org.clojure/java.jdbc "0.7.10"] [org.hibernate/hibernate-core "5.4.1.Final"] [com.cemerick/pomegranate "1.1.0"] [leiningen-core "2.9.3"] [org.apache.commons/commons-lang3 "3.5"] [org.apache.httpcomponents/httpclient "4.5.5"] - [clomacs "0.0.4-SNAPSHOT"]]) + [clomacs "0.0.5-SNAPSHOT"]]) diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/alter.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/alter.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/alter.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/alter.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/begin.snippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/begin.snippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/begin.snippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/begin.snippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/delete.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/delete.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/delete.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/delete.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/grant.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/grant.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/grant.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/grant.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/inner.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/inner.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/inner.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/inner.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/insert.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/insert.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/insert.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/insert.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/left.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/left.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/left.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/left.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/revoke.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/revoke.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/revoke.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/revoke.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/right.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/right.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/right.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/right.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/select.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/select.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/select.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/select.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/update.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/update.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/update.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/update.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/snippets/sql-mode/where.yasnippet b/elpa/ejc-sql-20230228.102/snippets/sql-mode/where.yasnippet similarity index 100% rename from elpa/ejc-sql-20220414.1329/snippets/sql-mode/where.yasnippet rename to elpa/ejc-sql-20230228.102/snippets/sql-mode/where.yasnippet diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/cache.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/cache.clj similarity index 96% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/cache.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/cache.clj index 89a86258..196cb16b 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/cache.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/cache.clj @@ -1,6 +1,6 @@ ;;; cache.clj -- Keep database stucture cache. -;;; Copyright © 2019 - Kostafey +;;; Copyright © 2019-2023 - Kostafey ;;; 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 @@ -17,7 +17,7 @@ ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ (ns ejc-sql.cache - (:use [clomacs])) + (:require [clomacs :as clomacs])) (def cache "Keep information about structure of databases used for autocomplete & eldoc. diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/classpath.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/classpath.clj similarity index 96% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/classpath.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/classpath.clj index 311b7944..c0d5612b 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/classpath.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/classpath.clj @@ -48,7 +48,7 @@ to add that path to the right classloader (with the search rooted at the current thread's context classloader)." ([jar-or-dir classloader] - (if-not (dp/add-classpath-url classloader (.toURL (.toURI (io/file jar-or-dir)))) + (when-not (dp/add-classpath-url classloader (.toURL (.toURI (io/file jar-or-dir)))) (throw (IllegalStateException. (str classloader " is not a modifiable classloader"))))) ([jar-or-dir] (let [classloaders (classloader-hierarchy)] diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/connect.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/connect.clj similarity index 91% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/connect.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/connect.clj index 4ce4019d..645d8a34 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/connect.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/connect.clj @@ -1,6 +1,6 @@ ;;; connect.clj -- Core clojure functions for ejc-sql emacs extension. -;;; Copyright © 2013-2019 - Kostafey +;;; Copyright © 2013-2023 - Kostafey ;;; 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 @@ -17,33 +17,27 @@ ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ (ns ejc-sql.connect - (:use [clojure.java.io] - [ejc-sql.lib] - [ejc-sql.cache] - [clomacs]) (:require [clojure.java.jdbc :as j] [clojure.java.io :as io] [clojure.string :as s] - [ejc-sql.output :as o]) - (:import [java.sql Connection - DriverManager - PreparedStatement - ResultSet - SQLException] - [java.io File])) + [clomacs :refer [clomacs-defn]] + [ejc-sql.output :as o] + [ejc-sql.lib :refer [select? ddl? clob-to-string-row *max-column-width*]] + [ejc-sql.cache :refer [invalidate-cache]]) + (:import [java.sql SQLException])) (def db "DataBase connection properties list from the last transaction. For debug purpose." (atom nil)) +(defn set-db [ejc-db] + (reset! db ejc-db)) + (def current-query "Current running query data." (atom {})) -(defn set-db [ejc-db] - (reset! db ejc-db)) - (defn handle-special-cases [db sql] (case (:subprotocol db) "oracle" (case (clojure.string/upper-case sql) @@ -78,13 +72,13 @@ For debug purpose." Unsafe for INSERT/UPDATE/CREATE/ALTER queries." [] (future - (if (is-statement-not-closed?) + (when (is-statement-not-closed?) (let [conn (:conn @current-query)] (try (.rollback conn) (finally (.close conn))))) - (if (is-query-process-running?) + (when (is-query-process-running?) (future-cancel (:runner @current-query)))) (:start-time @current-query)) @@ -129,7 +123,7 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" (bit-or java.util.regex.Pattern/DOTALL java.util.regex.Pattern/MULTILINE))) -(clomacs-defn complete-query ejc-complete-query +(clomacs-defn complete-query 'ejc-complete-query :doc "Show file contents with SQL query evaluation results.") (defn complete @@ -198,19 +192,20 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" msg (if (> result 0) (str "Records affected: " result) "Executed")] - (if (ddl? sql) + (when (ddl? sql) (invalidate-cache db)) (list :message msg))) (catch SQLException e (list :message (o/unify-str "Error: " (.getMessage e)))))) -(defn- eval-user-sql [db sql & {:keys [rows-limit - fetch-size - append - display-result - result-file]}] +(defn- eval-user-sql "Receive raw SQL from the user, log it, divide by statements and eval them." + [db sql & {:keys [rows-limit + fetch-size + append + display-result + result-file]}] (let [sql (s/trim sql) _ (do (o/log-sql (str sql "\n")) (o/clear-result-file :result-file result-file)) @@ -228,9 +223,8 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" (for [sql-part (filter ;; Remove parts contains comments only. (fn [part] - (not (empty? - (s/trim - (s/replace part comments-re ""))))) + (seq (s/trim + (s/replace part comments-re "")))) (if (or (not (:separator db)) manual-separator) (s/split sql statement-separator-re) [sql]))] @@ -246,7 +240,7 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" nil :start-time (:start-time @current-query) :status (if (or - (every? (fn [[result-type result]] + (every? (fn [[result-type _]] (= result-type :result-set)) results) (not (some (fn [[result-type result]] @@ -258,7 +252,7 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" :done (if (and (= (count results) 1) - (some (fn [[result-type result]] + (some (fn [[_ result]] (.contains (s/lower-case result) "closed connection")) results)) @@ -301,7 +295,8 @@ SELECT * FROM urls WHERE path like '%http://localhost%'" (s/join "\n" (.getStackTrace e))) :start-time (:start-time @current-query) :status :error - :display-result true))))] + :display-result true + :result-file result-file))))] (if sync (run-query) (swap! current-query assoc diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/deps_resolver.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/deps_resolver.clj similarity index 91% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/deps_resolver.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/deps_resolver.clj index 2911400c..3048b1a4 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/deps_resolver.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/deps_resolver.clj @@ -1,6 +1,6 @@ ;;; deps_resolver.clj -- Discover required jar artifacts. -;;; Copyright © 2020 - Kostafey +;;; Copyright © 2020-2023 - Kostafey ;;; 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 @@ -17,10 +17,9 @@ ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ (ns ejc-sql.deps-resolver - (:use - [leiningen.core.project :only [default-repositories]]) (:require - [cemerick.pomegranate.aether :as aether])) + [cemerick.pomegranate.aether :as aether] + [leiningen.core.project :refer [default-repositories]])) (defn get-hierarchy [artifacts-list] (aether/dependency-hierarchy @@ -63,5 +62,5 @@ (map (fn [dep] (get-hierarchy (vector dep))) (get-dependeces-list artifacts-list))))) - (catch Exception e + (catch Exception _ nil))) diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/keywords.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/keywords.clj similarity index 100% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/keywords.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/keywords.clj diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/lib.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/lib.clj similarity index 100% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/lib.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/lib.clj diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/output.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/output.clj similarity index 82% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/output.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/output.clj index 86fa9950..682bd67e 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/output.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/output.clj @@ -1,6 +1,6 @@ ;;; output.clj -- Output & formatting clojure functions for ejc-sql. -;;; Copyright © 2013-2019 - Kostafey +;;; Copyright © 2013-2023 - Kostafey ;;; 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 @@ -17,13 +17,11 @@ ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ (ns ejc-sql.output - (:use clojure.java.io - ejc-sql.lib) - (:require [clojure.string :as s]) + (:require [clojure.string :as s] + [clojure.java.io :refer [file writer]] + [ejc-sql.lib :refer [*max-column-width* dml? simple-join windows?]]) (:import (java.io File) - (java.lang.reflect Method) - (java.util Date) - (java.text SimpleDateFormat) + (java.lang Character$UnicodeBlock) (org.apache.commons.lang3 StringUtils) (org.hibernate.engine.jdbc.internal BasicFormatterImpl DDLFormatterImpl))) @@ -64,7 +62,7 @@ (when is-new-file (.mkdirs (File. (.getParent log-file))) (.createNewFile log-file)) - (with-open [wrtr (clojure.java.io/writer log-file :append true)] + (with-open [wrtr (writer log-file :append true)] (when is-new-file (.write wrtr (str "-- -*- mode: sql; -*-\n" "-- Local Variables:\n" @@ -179,6 +177,27 @@ (min (if (> x 0) x y) (if (> y 0) y x))) +(defn- cjk-char? + "Return true if argument char is CJK character." + [char] + (= (Character$UnicodeBlock/of char) + Character$UnicodeBlock/CJK_UNIFIED_IDEOGRAPHS)) + +(defn- cjk-chars-count + "Return count of CJK characters in string." + [text] + (count (filter cjk-char? text))) + +(defn- string-length + "Return string length, given that CJK characters have a length of 2." + [text] + (loop [string text + length 0] + (if (= (count string) 0) + length + (recur (next string) (+ length + (if (cjk-char? (first string)) 2 1)))))) + (defn print-table "Converts a seq of seqs to a textual table. Uses the first seq as the table headings and the remaining seqs as rows." @@ -191,7 +210,7 @@ ;; `row` 1 should be added to `row-limit`. (> (count rows) (+ row-limit 1))) [(take (+ row-limit 1) rows) - (if @show-too-many-rows-message + (when @show-too-many-rows-message (format "Too many rows. Only %s from %s%s are shown." row-limit (min-not-zero @max-rows (- (count rows) 1)) @@ -210,8 +229,8 @@ [(rotate-table [headers (first rows)]) true] [rows false]) [single-column-and-row - cell-value] (if-let [single-cell? (and (= (count rows) 1) - (= (count (first rows)) 1))] + cell-value] (when-let [single-cell? (and (= (count rows) 1) + (= (count (first rows)) 1))] [single-cell? (ffirst rows)]) [headers rows] (if (or rotated single-column-and-row) ;; Do not restrict column width if result @@ -239,33 +258,41 @@ (list (apply max (cons - (count (first headers)) + (string-length (first headers)) (if (string? cell-value) - (map count (s/split cell-value rn)) - (list (count (str cell-value))))))) + (map string-length (s/split cell-value rn)) + (list (string-length (str cell-value))))))) (for [col (rotate-table (conj rows headers))] - (apply max (map #(count (str %)) col)))) + (apply max (map #(string-length (str %)) col)))) spacers (map #(apply str (repeat % (u? "─" "-"))) widths) ;; TODO: #(str "%" % "d") for numbers fmts (if (and rotated (not aob)) ;; Remove trailing spaces for data column of single-row ;; result if no outer borders required. - (list (str "%-" (first widths) "s") "%s") - (map #(str "%-" % "s") widths)) + (list (fn [text] (let [width (- (first widths) + (cjk-chars-count text)) + pattern (str "%-" width "s")] + (format pattern text))) + (fn [text] (let [pattern "%s"] + (format pattern text)))) + (map (fn [w] + (fn [text] (let [width (- w (cjk-chars-count text)) + pattern (str "%-" width "s")] + (format pattern text)))) + widths)) fmt-row (fn [leader divider trailer row] (str leader (apply str (interpose divider (for [[col fmt] (map vector row fmts)] - (format fmt (str col))))) + (fmt (str col))))) trailer))] (when (not-empty msg) (println msg) (println)) - (if (not rotated) - (do - (println (fmt-row (if aob (u? "│ " "| ") "") (u? " │ " " | ") (if aob (u? " │" " |") "") headers)) - (println (fmt-row (if aob (u? "├─" "|-") "") (u? "─┼─" "-+-") (if aob (u? "─┤" "-|") "") spacers)))) + (when (not rotated) + (println (fmt-row (if aob (u? "│ " "| ") "") (u? " │ " " | ") (if aob (u? " │" " |") "") headers)) + (println (fmt-row (if aob (u? "├─" "|-") "") (u? "─┼─" "-+-") (if aob (u? "─┤" "-|") "") spacers))) (doseq [row (if (and aob single-column-and-row (string? cell-value)) (map list (s/split cell-value (re-pattern nl))) rows)] diff --git a/elpa/ejc-sql-20220414.1329/src/ejc_sql/structure.clj b/elpa/ejc-sql-20230228.102/src/ejc_sql/structure.clj similarity index 79% rename from elpa/ejc-sql-20220414.1329/src/ejc_sql/structure.clj rename to elpa/ejc-sql-20230228.102/src/ejc_sql/structure.clj index 547f4a64..97f0d092 100644 --- a/elpa/ejc-sql-20220414.1329/src/ejc_sql/structure.clj +++ b/elpa/ejc-sql-20230228.102/src/ejc_sql/structure.clj @@ -1,6 +1,6 @@ ;;; structure.clj -- Receive database stucture and keep it in cache. -;;; Copyright © 2016-2019 - Kostafey +;;; Copyright © 2016-2023 - Kostafey ;;; 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 @@ -17,13 +17,13 @@ ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ (ns ejc-sql.structure - (:use [ejc-sql.lib] - [ejc-sql.cache] - [clomacs]) (:require [clojure.java.jdbc :as j] [clojure.string :as s] [clojure.java.io :as io] + [clomacs :refer [clomacs-defn]] + [ejc-sql.lib :refer [is-clob? clob-to-string clean-sql in? get->in]] + [ejc-sql.cache :refer [cache cache-creation-promises]] [ejc-sql.connect :as c] [ejc-sql.output :as o] [ejc-sql.keywords :as k])) @@ -77,146 +77,145 @@ true (> (get-ms-sql-server-version ver) 2000)))) -(def default-queries - {:owners (fn [& _] " +(def queries + "Database - specific queries used for obtain data about database structure." + (let [default-queries + {:owners (fn [& _] " SELECT schema_owner FROM information_schema.schemata ") - :schemas (fn [& _] " + :schemas (fn [& _] " SELECT schema_name FROM information_schema.schemata ") - :tables (fn [& {:keys [schema]}] - (format " + :tables (fn [& {:keys [schema]}] + (format " SELECT table_name FROM information_schema.tables %s ORDER BY table_name " - (if schema - (format " WHERE table_schema = '%s'" schema) - ""))) - :views (fn [& _] " + (if schema + (format " WHERE table_schema = '%s'" schema) + ""))) + :views (fn [& _] " SELECT table_name FROM information_schema.views ") - :all-tables (fn [& _] " + :all-tables (fn [& _] " SELECT s.schema_owner, s.schema_name, t.table_name FROM information_schema.schemata AS s, information_schema.tables AS t WHERE t.table_schema = s.schema_name ") - :columns (fn [& {:keys [table]}] - (format " + :columns (fn [& {:keys [table]}] + (format " SELECT column_name FROM information_schema.columns WHERE UPPER(table_name) = '%s' ORDER BY column_name " - (s/upper-case table))) - :view (fn [& {:keys [entity-name]}] - (format " + (s/upper-case table))) + :view (fn [& {:keys [entity-name]}] + (format " SELECT v.view_definition FROM information_schema.views AS v WHERE UPPER(v.table_name) = '%s' " - (s/upper-case entity-name)))}) - -(def queries - "Database - specific queries used for obtain data about database structure." - { - ;;-------- - :oracle - ;;-------- - {:entity (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name)))} + ;;-------- + oracle + ;;-------- + {:entity (fn [& {:keys [entity-name]}] + (format " SELECT text FROM all_source WHERE UPPER(name) = '%s' " - (s/upper-case entity-name))) - :entity-type (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name))) + :entity-type (fn [& {:keys [entity-name]}] + (format " SELECT object_type FROM all_objects WHERE UPPER(OBJECT_NAME) = '%s' AND object_type NOT IN ('SYNONYM', 'PACKAGE BODY') UNION - SELECT 'PROCEDURE' FROM dba_procedures - WHERE UPPER(PROCEDURE_NAME) = '%s' + SELECT 'PROCEDURE' FROM all_procedures + WHERE UPPER(OBJECT_NAME) = '%s' + AND object_type = 'PROCEDURE' AND rownum = 1" - (s/upper-case entity-name) - (s/upper-case entity-name))) - :view (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name) + (s/upper-case entity-name))) + :view (fn [& {:keys [entity-name]}] + (format " SELECT text FROM all_views WHERE UPPER(view_name) = '%s' " - (s/upper-case entity-name))) - :types (fn [& _] " + (s/upper-case entity-name))) + :types (fn [& _] " SELECT * FROM USER_TYPES ") - :owners (fn [& _] " + :owners (fn [& _] " SELECT DISTINCT(owner) FROM ALL_OBJECTS ORDER BY owner ") - :tables (fn [& {:keys [owner]}] - (format " + :tables (fn [& {:keys [owner]}] + (format " SELECT table_name, owner FROM all_tables %s ORDER BY table_name " - (if owner - (format " WHERE UPPER(owner) = '%s' " - (s/upper-case owner)) - ""))) - :views (fn [& {:keys [owner]}] - (format " + (if owner + (format " WHERE UPPER(owner) = '%s' " + (s/upper-case owner)) + ""))) + :views (fn [& {:keys [owner]}] + (format " SELECT view_name FROM all_views %s ORDER BY view_name " - (if owner - (format " WHERE UPPER(owner) = '%s' " - (s/upper-case owner)) - ""))) - :all-tables (fn [& _] " + (if owner + (format " WHERE UPPER(owner) = '%s' " + (s/upper-case owner)) + ""))) + :all-tables (fn [& _] " SELECT owner, table_name FROM all_tables WHERE owner NOT IN ('SYS', 'SYSTEM') ORDER BY owner ") - :columns (fn [& {:keys [table]}] - (format " + :columns (fn [& {:keys [table]}] + (format " SELECT column_name FROM ALL_TAB_COLUMNS WHERE UPPER(table_name) = '%s' " - (s/upper-case table))) - :constraints (fn [& {:keys [owner table]}] - (cond - (and owner table) - (format " + (s/upper-case table))) + :constraints (fn [& {:keys [owner table]}] + (cond + (and owner table) + (format " SELECT * FROM all_constraints WHERE owner = '%s' AND table_name = '%s' " - owner table) - table - (format " + owner table) + table + (format " SELECT * FROM all_constraints WHERE table_name = '%s' " table) - :else - "SELECT * FROM user_constraints")) - :procedures (fn [& {:keys [owner]}] - (format " + :else + "SELECT * FROM user_constraints")) + :procedures (fn [& {:keys [owner]}] + (format " SELECT object_name, procedure_name FROM all_procedures %s " (if owner (format "WHERE owner = '%s' " owner) ""))) - :parameters (fn [& {:keys [package entity-name]}] - (format " + :parameters (fn [& {:keys [package entity-name]}] + (format " SELECT data_type, argument_name FROM SYS.ALL_ARGUMENTS WHERE object_name = '%s' AND in_out = 'IN' %s " - (s/upper-case entity-name) - (if package - (format "AND package_name = '%s'" package) - ""))) - :package (fn [& {:keys [entity-name]}] - ;; entity-name is a package name here - (format " + (s/upper-case entity-name) + (if package + (format "AND package_name = '%s'" package) + ""))) + :package (fn [& {:keys [entity-name]}] + ;; entity-name is a package name here + (format " SELECT text FROM ( SELECT text AS text, @@ -239,29 +238,29 @@ AND type = 'PACKAGE BODY' ) ORDER BY ordered, line " - (s/upper-case entity-name) - (s/upper-case entity-name))) - :table (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name) + (s/upper-case entity-name))) + :table (fn [& {:keys [entity-name]}] + (format " SELECT dbms_metadata.get_ddl('TABLE','%s') FROM dual " (s/upper-case entity-name))) - :objects (fn [& _] " + :objects (fn [& _] " SELECT * FROM all_objects WHERE object_type IN ('FUNCTION','PROCEDURE','PACKAGE') ") - :keywords (fn [& _] " + :keywords (fn [& _] " SELECT * FROM V$RESERVED_WORDS ORDER BY keyword ")} - ;;-------- - :informix - ;;-------- - {:owners nil - :tables (fn [& _] " + ;;-------- + informix + ;;-------- + {:owners nil + :tables (fn [& _] " SELECT TRIM(t.tabname) as tablesList FROM systables AS t WHERE t.tabtype = 'T' AND t.tabid >= 100 ORDER BY t.tabname; ") - :columns (fn [& {:keys [table]}] - (format " + :columns (fn [& {:keys [table]}] + (format " SELECT TRIM(c.colname) AS column_name FROM systables AS t, syscolumns AS c WHERE t.tabid = c.tabid @@ -269,23 +268,23 @@ AND t.tabid >= 100 AND TRIM(t.tabname) = '%s' ORDER BY c.colno; " table))} - ;;------- - :mysql - ;;------- - {:owners (fn [& _] " + ;;------- + mysql + ;;------- + {:owners (fn [& _] " SELECT schema_name FROM information_schema.schemata ") - :tables (default-queries :tables) - :all-tables (fn [& _] " + :tables (default-queries :tables) + :all-tables (fn [& _] " SELECT s.schema_name, t.table_name FROM information_schema.schemata AS s, information_schema.tables AS t WHERE t.table_schema = s.schema_name ") - :columns (default-queries :columns) - :keywords (fn [& _] " + :columns (default-queries :columns) + :keywords (fn [& _] " SELECT name FROM mysql.help_keyword") - :entity-type (fn [& {:keys [entity-name]}] - (format " + :entity-type (fn [& {:keys [entity-name]}] + (format " SELECT routine_type FROM information_schema.routines WHERE UPPER(routine_name) = '%s' @@ -296,117 +295,142 @@ AND c.parent_category_id IN (SELECT help_category_id FROM mysql.help_category WHERE name = 'Functions') - WHERE UPPER(t.name) = '%s'" - (s/upper-case entity-name) - (s/upper-case entity-name))) - :procedures (fn [& _] " + WHERE UPPER(t.name) = '%s' + UNION + SELECT 'table' as table_name + FROM information_schema.tables + WHERE UPPER(table_name) = '%s'" + (s/upper-case entity-name) + (s/upper-case entity-name) + (s/upper-case entity-name))) + :constraints (fn [& {:keys [owner table]}] + (cond + (and owner table) + (format " + SELECT column_name, constraint_name, + referenced_column_name, referenced_table_name + FROM information_schema.key_column_usage + WHERE constraint_schema = '%s' + AND table_name = '%s' " + owner table) + table + (format " + SELECT column_name, constraint_name, + referenced_column_name, referenced_table_name + FROM information_schema.key_column_usage + WHERE table_name = '%s' " table) + :else + "SELECT * FROM information_schema.key_column_usage")) + :procedures (fn [& _] " SELECT routine_schema, routine_name FROM information_schema.routines ") - :procedure (fn [& {:keys [entity-name]}] - (format " + :procedure (fn [& {:keys [entity-name]}] + (format " SHOW CREATE PROCEDURE %s " - entity-name)) - :function (fn [& {:keys [entity-name]}] - (format " + entity-name)) + :function (fn [& {:keys [entity-name]}] + (format " SHOW CREATE FUNCTION %s " - entity-name)) - :standard-function (fn [& {:keys [entity-name]}] - (format " + entity-name)) + :table (fn [& {:keys [entity-name]}] + (format "SHOW CREATE TABLE %s " entity-name)) + :standard-function (fn [& {:keys [entity-name]}] + (format " SELECT description FROM mysql.help_topic WHERE UPPER(name) = '%s' " - (s/upper-case entity-name))) - :parameters (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name))) + :parameters (fn [& {:keys [entity-name]}] + (format " SELECT data_type, parameter_name FROM information_schema.parameters WHERE parameter_mode = 'IN' AND UPPER(specific_name) = '%s'" - (s/upper-case entity-name)))} - ;;-------- - :h2 - ;;-------- - {:tables (fn [& _] ((default-queries :tables) :schema "PUBLIC")) - :views (default-queries :views) - :all-tables (fn [& _] " + (s/upper-case entity-name)))} + ;;-------- + h2 + ;;-------- + {:tables (fn [& _] ((default-queries :tables) :schema "PUBLIC")) + :views (default-queries :views) + :all-tables (fn [& _] " SELECT s.schema_owner, s.schema_name, t.table_name FROM information_schema.schemata AS s, information_schema.tables AS t WHERE t.table_schema = s.schema_name AND LCASE(s.schema_name) != 'information_schema' ") - :columns (default-queries :columns) - :keywords (fn [& _] - "SELECT topic FROM information_schema.help") - :entity-type (fn [& {:keys [entity-name]}] - (format " + :columns (default-queries :columns) + :keywords (fn [& _] + "SELECT topic FROM information_schema.help") + :entity-type (fn [& {:keys [entity-name]}] + (format " SELECT t.table_type FROM information_schema.tables AS t WHERE UPPER(t.table_name) = '%s' " - (s/upper-case entity-name))) - :view (fn [& {:keys [entity-name]}] - ((default-queries :view) :entity-name entity-name))} - ;;-------- - :sqlite - ;;-------- - {:tables (fn [& _] "SELECT name FROM sqlite_master WHERE type='table'") - :views (fn [& _] "SELECT name FROM sqlite_master WHERE type='view'") - :all-tables (fn [& _] "SELECT name FROM sqlite_master WHERE type='table'") - :columns (fn [& {:keys [table]}] - (format " + (s/upper-case entity-name))) + :view (fn [& {:keys [entity-name]}] + ((default-queries :view) :entity-name entity-name))} + ;;-------- + sqlite + ;;-------- + {:tables (fn [& _] "SELECT name FROM sqlite_master WHERE type='table'") + :views (fn [& _] "SELECT name FROM sqlite_master WHERE type='view'") + :all-tables (fn [& _] "SELECT name FROM sqlite_master WHERE type='table'") + :columns (fn [& {:keys [table]}] + (format " SELECT p.name as columnName FROM sqlite_master m LEFT OUTER JOIN pragma_table_info((m.name)) p ON m.name <> p.name WHERE m.name = '%s' ORDER BY columnName " table)) - :keywords (:sqlite k/keywords) - :entity-type (fn [& {:keys [entity-name]}] - (format " + :keywords (:sqlite k/keywords) + :entity-type (fn [& {:keys [entity-name]}] + (format " SELECT type FROM sqlite_master WHERE UPPER(name) = '%s' " - (s/upper-case entity-name))) - :view (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name))) + :view (fn [& {:keys [entity-name]}] + (format " SELECT sql FROM sqlite_master WHERE UPPER(name) = '%s' " - (s/upper-case entity-name)))} - ;;------- - :sqlserver ; ms sql server - ;;------- - {:owners (default-queries :owners) - :schemas (default-queries :schemas) - :tables (default-queries :tables) - :all-tables (default-queries :all-tables) - :columns (default-queries :columns) - :constraints (fn [& {:keys [table]}] - (format " + (s/upper-case entity-name)))} + ;;------- + sqlserver ; ms sql server + ;;------- + {:owners (default-queries :owners) + :schemas (default-queries :schemas) + :tables (default-queries :tables) + :all-tables (default-queries :all-tables) + :columns (default-queries :columns) + :constraints (fn [& {:keys [table]}] + (format " SELECT type_desc AS constraint_type, name FROM sys.objects WHERE type_desc LIKE '%CONSTRAINT' AND OBJECT_NAME(parent_object_id)='%s' " table)) - :entity (fn [& {:keys [db entity-name]}] - (if (is-modern-sql-server? db) - (format " + :entity (fn [& {:keys [db entity-name]}] + (if (is-modern-sql-server? db) + (format " SELECT definition FROM sys.objects o JOIN sys.sql_modules m ON m.object_id = o.object_id WHERE o.object_id = object_id('%s') " entity-name) - (format " + (format " SELECT c.text FROM sysobjects o JOIN syscomments c ON c.id = o.id WHERE o.name = '%s' " entity-name)))} - ;;------- - :postgresql - ;;------- - {:procedure (fn [& {:keys [entity-name]}] - (format " + ;;------- + postgresql + ;;------- + {:procedure (fn [& {:keys [entity-name]}] + (format " SELECT pg_get_functiondef(p.oid) FROM pg_catalog.pg_proc p WHERE upper(p.proname) = '%s' " - (s/upper-case entity-name))) - :table (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name))) + :table (fn [& {:keys [entity-name]}] + (format " SELECT 'CREATE TABLE %s (\n' || string_agg(column_list.column_expr, ', \n') || '\n);' @@ -421,21 +445,21 @@ WHERE table_schema = 'public' AND upper(table_name) = '%s' ORDER BY ordinal_position) column_list" - entity-name - (s/upper-case entity-name))) - :owners (default-queries :owners) - :schemas (default-queries :schemas) - :tables (default-queries :tables) - :all-tables (default-queries :all-tables) - :columns (default-queries :columns) - :procedures (fn [& _] " + entity-name + (s/upper-case entity-name))) + :owners (default-queries :owners) + :schemas (default-queries :schemas) + :tables (default-queries :tables) + :all-tables (default-queries :all-tables) + :columns (default-queries :columns) + :procedures (fn [& _] " SELECT p.proname FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid ORDER BY proname ") - :entity-type (fn [& {:keys [entity-name]}] - (format " + :entity-type (fn [& {:keys [entity-name]}] + (format " SELECT 'namespace' FROM pg_catalog.pg_namespace n WHERE upper(n.nspname) = '%s' @@ -453,24 +477,26 @@ JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE upper(p.proname) = '%s' " - (s/upper-case entity-name) - (s/upper-case entity-name) - (s/upper-case entity-name) - (s/upper-case entity-name))) - :parameters (fn [& {:keys [entity-name]}] - (format " + (s/upper-case entity-name) + (s/upper-case entity-name) + (s/upper-case entity-name) + (s/upper-case entity-name))) + :parameters (fn [& {:keys [entity-name]}] + (format " SELECT pg_catalog.pg_get_function_identity_arguments( p.oid) FROM pg_catalog.pg_proc p WHERE p.proname = '%s'" entity-name)) - :keywords (fn [& _] - "SELECT word FROM pg_get_keywords()")}}) - -;; Use the same database introspection queries for MariaDB as for MySQL. -(def queries (assoc queries :mariadb (queries :mysql))) - -(defn autocomplete-available-for-db? [db-type] - (queries db-type)) + :keywords (fn [& _] + "SELECT word FROM pg_get_keywords()")}] + {:oracle oracle + :informix informix + :mysql mysql + :mariadb mysql + :h2 h2 + :sqlite sqlite + :sqlserver sqlserver + :postgresql postgresql})) (defn get-db-name [db] (let [{:keys [database subname connection-uri dbname]} db] @@ -568,7 +594,7 @@ meta-type (if (keyword? meta-type) meta-type (keyword meta-type)) ;; owner (get-this-owner db owner) sql-receiver (get-in queries [db-type meta-type]) - sql (if sql-receiver + sql (when sql-receiver (sql-receiver :db db :owner owner :schema owner @@ -749,10 +775,10 @@ "Return keywords list for this database type from cache if already received from DB, check if receiveing process is not running, then start it." [db force?] - (if-let [keywords-query (get-in queries [(get-db-type db) :keywords])] + (when-let [keywords-query (get-in queries [(get-db-type db) :keywords])] (get-or-create-cache :db db :path [:keywords] - :direct-value (if (vector? keywords-query) + :direct-value (when (vector? keywords-query) keywords-query) :sql (select-db-meta-script db :keywords) :force? force? @@ -774,7 +800,7 @@ (clomacs-defn complete-auto-complete - ejc-complete-auto-complete + 'ejc-complete-auto-complete :doc "Call Emacs auto-complete if point is the same as before loading.") (defn run-autocomplete [db buffer-name point] @@ -994,7 +1020,7 @@ (let [pattern (re-pattern (str "\\(.+\\)(\\s|\\s(as)\\s)" prefix-1)) complex-alias (first (re-find pattern sql)) - complex-alias (if complex-alias + complex-alias (when complex-alias (subs complex-alias 1 (.lastIndexOf complex-alias ")")))] (if complex-alias @@ -1013,10 +1039,10 @@ "Determine DB entity type, whether it is a `:view`, `:type`, `:package`, `:namespace` or `:procedure`." [db entity-name] - (if-let [sql (and entity-name - (select-db-meta-script db :entity-type - :entity-name entity-name))] - (if-let [found-type (db->value db sql)] + (when-let [sql (and entity-name + (select-db-meta-script db :entity-type + :entity-name entity-name))] + (when-let [found-type (db->value db sql)] (-> (.split found-type " ") first s/lower-case @@ -1084,6 +1110,7 @@ :mysql (case type :function "create function" :procedure "create procedure" + :table "create table" nil) nil)))] (c/complete (o/unify-str @@ -1099,7 +1126,7 @@ :connection-name connection-name :db db :result-file result-file - :goto-symbol (if prefix entity-name)) + :goto-symbol (when prefix entity-name)) (c/complete (format "Can't find %s named %s." (name type) sql-object) :result-file result-file)) -- 2.47.3