diff options
| author | Michael Mauger | 2011-07-05 23:51:48 -0400 |
|---|---|---|
| committer | Michael Mauger | 2011-07-05 23:51:48 -0400 |
| commit | fbcc67e2aada556f30f6cb330c96f0094a870f2f (patch) | |
| tree | 8d02734b4d32dc5a198ba41e694bc6505a765fa5 /lisp/progmodes/sql.el | |
| parent | d4eaeab175c1854421c56039c4d140ea672841a1 (diff) | |
| download | emacs-fbcc67e2aada556f30f6cb330c96f0094a870f2f.tar.gz emacs-fbcc67e2aada556f30f6cb330c96f0094a870f2f.zip | |
* progmodes/sql.el: Version 3.0
(sql-product-alist): Added product :completion-object,
:completion-column, and :statement attributes.
(sql-mode-menu, sql-interactive-mode-map): Fixed List entries.
(sql-mode-syntax-table): Mark all punctuation.
(sql-font-lock-keywords-builder): Temporarily removed fallback on
ansi keywords.
(sql-regexp-abbrev, sql-regexp-abbrev-list): New functions.
(sql-mode-oracle-font-lock-keywords): Improved.
(sql-oracle-show-reserved-words): New function for development.
(sql-product-font-lock): Simplify for source code buffers.
(sql-product-syntax-table, sql-product-font-lock-syntax-alist):
New functions.
(sql-highlight-product): Set product specific syntax table.
(sql-mode-map): Added statement movement functions.
(sql-ansi-statement-starters, sql-oracle-statement-starters): New
variable.
(sql-statement-regexp, sql-beginning-of-statement)
(sql-end-of-statement, sql-signum): New functions.
(sql-buffer-live-p, sql=find-sqli-buffer): Added CONNECTION
parameter.
(sql-show-sqli-buffer): Bug fix.
(sql-interactive-mode): Store connection data as buffer local.
(sql-connect): Added NEW-NAME parameter. Redesigned interaction
with sql-interactive-mode.
(sql-save-connection): Save buffer local settings.
(sql-connection-menu-filter): Changed menu entry name.
(sql-product-interactive): Bug fix.
(sql-preoutput-hold): New variable.
(sql-interactive-remove-continuation-prompt): Bug fixes.
(sql-debug-redirect): New variable.
(sql-str-literal): New function.
(sql-redirect, sql-redirect-one, sql-redirect-value, sql-execute):
Redesigned.
(sql-oracle-save-settings, sql-oracle-restore-settings)
(sql-oracle-list-all, sql-oracle-list-table): New functions.
(sql-completion-object, sql-completion-column)
(sql-completion-sqlbuf): New variables.
(sql-build-completions-1, sql-build-completions)
(sql-try-completion): New functions.
(sql-read-table-name): Use them.
(sql-contains-names): New buffer local variable.
(sql-list-all, sql-list-table): Use it.
(sql-oracle-completion-types): New variable.
(sql-oracle-completion-object, sql-sqlite-completion-object)
(sql-postgres-completion-object): New functions.
Diffstat (limited to 'lisp/progmodes/sql.el')
| -rw-r--r-- | lisp/progmodes/sql.el | 1155 |
1 files changed, 900 insertions, 255 deletions
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 1da819660d2..80358e1c651 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el | |||
| @@ -4,10 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: Alex Schroeder <alex@gnu.org> | 5 | ;; Author: Alex Schroeder <alex@gnu.org> |
| 6 | ;; Maintainer: Michael Mauger <mmaug@yahoo.com> | 6 | ;; Maintainer: Michael Mauger <mmaug@yahoo.com> |
| 7 | ;; Version: 2.8 | 7 | ;; Version: 3.0 |
| 8 | ;; Keywords: comm languages processes | 8 | ;; Keywords: comm languages processes |
| 9 | ;; URL: http://savannah.gnu.org/projects/emacs/ | 9 | ;; URL: http://savannah.gnu.org/projects/emacs/ |
| 10 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode | ||
| 11 | 10 | ||
| 12 | ;; This file is part of GNU Emacs. | 11 | ;; This file is part of GNU Emacs. |
| 13 | 12 | ||
| @@ -46,7 +45,7 @@ | |||
| 46 | ;; available in early versions of sql.el. This support has been | 45 | ;; available in early versions of sql.el. This support has been |
| 47 | ;; extended and formalized in later versions. Part of the impetus for | 46 | ;; extended and formalized in later versions. Part of the impetus for |
| 48 | ;; the improved support of SQL flavors was borne out of the current | 47 | ;; the improved support of SQL flavors was borne out of the current |
| 49 | ;; maintainer's consulting experience. In the past fifteen years, I | 48 | ;; maintainers consulting experience. In the past twenty years, I |
| 50 | ;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer. | 49 | ;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer. |
| 51 | ;; On some assignments, I have used two or more of these concurrently. | 50 | ;; On some assignments, I have used two or more of these concurrently. |
| 52 | 51 | ||
| @@ -130,7 +129,7 @@ | |||
| 130 | ;; identifier characters. | 129 | ;; identifier characters. |
| 131 | 130 | ||
| 132 | ;; (sql-set-product-feature 'xyz | 131 | ;; (sql-set-product-feature 'xyz |
| 133 | ;; :syntax-alist ((?# . "w"))) | 132 | ;; :syntax-alist ((?# . "_"))) |
| 134 | 133 | ||
| 135 | ;; 4) Define the interactive command interpreter for the database | 134 | ;; 4) Define the interactive command interpreter for the database |
| 136 | ;; product. | 135 | ;; product. |
| @@ -184,7 +183,7 @@ | |||
| 184 | ;; (sql-set-product-feature 'xyz | 183 | ;; (sql-set-product-feature 'xyz |
| 185 | ;; :sqli-comint-func 'my-sql-comint-xyz) | 184 | ;; :sqli-comint-func 'my-sql-comint-xyz) |
| 186 | 185 | ||
| 187 | ;; 6) Define a convienence function to invoke the SQL interpreter. | 186 | ;; 6) Define a convenience function to invoke the SQL interpreter. |
| 188 | 187 | ||
| 189 | ;; (defun my-sql-xyz (&optional buffer) | 188 | ;; (defun my-sql-xyz (&optional buffer) |
| 190 | ;; "Run ixyz by XyzDB as an inferior process." | 189 | ;; "Run ixyz by XyzDB as an inferior process." |
| @@ -230,9 +229,18 @@ | |||
| 230 | (eval-when-compile | 229 | (eval-when-compile |
| 231 | (require 'regexp-opt)) | 230 | (require 'regexp-opt)) |
| 232 | (require 'custom) | 231 | (require 'custom) |
| 232 | (require 'thingatpt) | ||
| 233 | (eval-when-compile ;; needed in Emacs 19, 20 | 233 | (eval-when-compile ;; needed in Emacs 19, 20 |
| 234 | (setq max-specpdl-size (max max-specpdl-size 2000))) | 234 | (setq max-specpdl-size (max max-specpdl-size 2000))) |
| 235 | 235 | ||
| 236 | (defun sql-signum (n) | ||
| 237 | "Return 1, 0, or -1 to identify the sign of N." | ||
| 238 | (cond | ||
| 239 | ((not (numberp n)) nil) | ||
| 240 | ((< n 0) -1) | ||
| 241 | ((> n 0) 1) | ||
| 242 | (t 0))) | ||
| 243 | |||
| 236 | (defvar font-lock-keyword-face) | 244 | (defvar font-lock-keyword-face) |
| 237 | (defvar font-lock-set-defaults) | 245 | (defvar font-lock-set-defaults) |
| 238 | (defvar font-lock-string-face) | 246 | (defvar font-lock-string-face) |
| @@ -327,7 +335,8 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 327 | (defvar sql-product-alist | 335 | (defvar sql-product-alist |
| 328 | '((ansi | 336 | '((ansi |
| 329 | :name "ANSI" | 337 | :name "ANSI" |
| 330 | :font-lock sql-mode-ansi-font-lock-keywords) | 338 | :font-lock sql-mode-ansi-font-lock-keywords |
| 339 | :statement sql-ansi-statement-starters) | ||
| 331 | 340 | ||
| 332 | (db2 | 341 | (db2 |
| 333 | :name "DB2" | 342 | :name "DB2" |
| @@ -392,7 +401,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 392 | :sqli-comint-func sql-comint-ms | 401 | :sqli-comint-func sql-comint-ms |
| 393 | :prompt-regexp "^[0-9]*>" | 402 | :prompt-regexp "^[0-9]*>" |
| 394 | :prompt-length 5 | 403 | :prompt-length 5 |
| 395 | :syntax-alist ((?@ . "w")) | 404 | :syntax-alist ((?@ . "_")) |
| 396 | :terminator ("^go" . "go")) | 405 | :terminator ("^go" . "go")) |
| 397 | 406 | ||
| 398 | (mysql | 407 | (mysql |
| @@ -408,6 +417,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 408 | :prompt-regexp "^mysql> " | 417 | :prompt-regexp "^mysql> " |
| 409 | :prompt-length 6 | 418 | :prompt-length 6 |
| 410 | :prompt-cont-regexp "^ -> " | 419 | :prompt-cont-regexp "^ -> " |
| 420 | :syntax-alist ((?# . "< b")) | ||
| 411 | :input-filter sql-remove-tabs-filter) | 421 | :input-filter sql-remove-tabs-filter) |
| 412 | 422 | ||
| 413 | (oracle | 423 | (oracle |
| @@ -417,11 +427,15 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 417 | :sqli-options sql-oracle-options | 427 | :sqli-options sql-oracle-options |
| 418 | :sqli-login sql-oracle-login-params | 428 | :sqli-login sql-oracle-login-params |
| 419 | :sqli-comint-func sql-comint-oracle | 429 | :sqli-comint-func sql-comint-oracle |
| 430 | :list-all sql-oracle-list-all | ||
| 431 | :list-table sql-oracle-list-table | ||
| 432 | :completion-object sql-oracle-completion-object | ||
| 420 | :prompt-regexp "^SQL> " | 433 | :prompt-regexp "^SQL> " |
| 421 | :prompt-length 5 | 434 | :prompt-length 5 |
| 422 | :prompt-cont-regexp "^\\s-*\\d+> " | 435 | :prompt-cont-regexp "^\\s-*[[:digit:]]+ " |
| 423 | :syntax-alist ((?$ . "w") (?# . "w")) | 436 | :statement sql-oracle-statement-starters |
| 424 | :terminator ("\\(^/\\|;\\)" . "/") | 437 | :syntax-alist ((?$ . "_") (?# . "_")) |
| 438 | :terminator ("\\(^/\\|;\\)$" . "/") | ||
| 425 | :input-filter sql-placeholders-filter) | 439 | :input-filter sql-placeholders-filter) |
| 426 | 440 | ||
| 427 | (postgres | 441 | (postgres |
| @@ -434,11 +448,12 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 434 | :sqli-comint-func sql-comint-postgres | 448 | :sqli-comint-func sql-comint-postgres |
| 435 | :list-all ("\\d+" . "\\dS+") | 449 | :list-all ("\\d+" . "\\dS+") |
| 436 | :list-table ("\\d+ %s" . "\\dS+ %s") | 450 | :list-table ("\\d+ %s" . "\\dS+ %s") |
| 437 | :prompt-regexp "^.*=[#>] " | 451 | :completion-object sql-postgres-completion-object |
| 452 | :prompt-regexp "^\\w*=[#>] " | ||
| 438 | :prompt-length 5 | 453 | :prompt-length 5 |
| 439 | :prompt-cont-regexp "^.*[-(][#>] " | 454 | :prompt-cont-regexp "^\\w*[-(][#>] " |
| 440 | :input-filter sql-remove-tabs-filter | 455 | :input-filter sql-remove-tabs-filter |
| 441 | :terminator ("\\(^\\s-*\\\\g\\|;\\)" . ";")) | 456 | :terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g")) |
| 442 | 457 | ||
| 443 | (solid | 458 | (solid |
| 444 | :name "Solid" | 459 | :name "Solid" |
| @@ -460,9 +475,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 460 | :sqli-comint-func sql-comint-sqlite | 475 | :sqli-comint-func sql-comint-sqlite |
| 461 | :list-all ".tables" | 476 | :list-all ".tables" |
| 462 | :list-table ".schema %s" | 477 | :list-table ".schema %s" |
| 478 | :completion-object sql-sqlite-completion-object | ||
| 463 | :prompt-regexp "^sqlite> " | 479 | :prompt-regexp "^sqlite> " |
| 464 | :prompt-length 8 | 480 | :prompt-length 8 |
| 465 | :prompt-cont-regexp "^ ...> " | 481 | :prompt-cont-regexp "^ \.\.\.> " |
| 466 | :terminator ";") | 482 | :terminator ";") |
| 467 | 483 | ||
| 468 | (sybase | 484 | (sybase |
| @@ -474,7 +490,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 474 | :sqli-comint-func sql-comint-sybase | 490 | :sqli-comint-func sql-comint-sybase |
| 475 | :prompt-regexp "^SQL> " | 491 | :prompt-regexp "^SQL> " |
| 476 | :prompt-length 5 | 492 | :prompt-length 5 |
| 477 | :syntax-alist ((?@ . "w")) | 493 | :syntax-alist ((?@ . "_")) |
| 478 | :terminator ("^go" . "go")) | 494 | :terminator ("^go" . "go")) |
| 479 | ) | 495 | ) |
| 480 | "An alist of product specific configuration settings. | 496 | "An alist of product specific configuration settings. |
| @@ -513,10 +529,11 @@ may be any one of the following: | |||
| 513 | :sqli-comint-func name of a function which accepts no | 529 | :sqli-comint-func name of a function which accepts no |
| 514 | parameters that will use the values of | 530 | parameters that will use the values of |
| 515 | `sql-user', `sql-password', | 531 | `sql-user', `sql-password', |
| 516 | `sql-database' and `sql-server' to open a | 532 | `sql-database', `sql-server' and |
| 517 | comint buffer and connect to the | 533 | `sql-port' to open a comint buffer and |
| 518 | database. Do product specific | 534 | connect to the database. Do product |
| 519 | configuration of comint in this function. | 535 | specific configuration of comint in this |
| 536 | function. | ||
| 520 | 537 | ||
| 521 | :list-all Command string or function which produces | 538 | :list-all Command string or function which produces |
| 522 | a listing of all objects in the database. | 539 | a listing of all objects in the database. |
| @@ -535,6 +552,20 @@ may be any one of the following: | |||
| 535 | produces the standard list and the cdr | 552 | produces the standard list and the cdr |
| 536 | produces an enhanced list. | 553 | produces an enhanced list. |
| 537 | 554 | ||
| 555 | :completion-object A function that returns a list of | ||
| 556 | objects. Called with a single | ||
| 557 | parameter--if nil then list objects | ||
| 558 | accessible in the current schema, if | ||
| 559 | not-nil it is the name of a schema whose | ||
| 560 | objects should be listed. | ||
| 561 | |||
| 562 | :completion-column A function that returns a list of | ||
| 563 | columns. Called with a single | ||
| 564 | parameter--if nil then list objects | ||
| 565 | accessible in the current schema, if | ||
| 566 | not-nil it is the name of a schema whose | ||
| 567 | objects should be listed. | ||
| 568 | |||
| 538 | :prompt-regexp regular expression string that matches | 569 | :prompt-regexp regular expression string that matches |
| 539 | the prompt issued by the product | 570 | the prompt issued by the product |
| 540 | interpreter. | 571 | interpreter. |
| @@ -555,6 +586,9 @@ may be any one of the following: | |||
| 555 | filtered string. May also be a list of | 586 | filtered string. May also be a list of |
| 556 | such functions. | 587 | such functions. |
| 557 | 588 | ||
| 589 | :statement name of a variable containing a regexp that | ||
| 590 | matches the beginning of SQL statements. | ||
| 591 | |||
| 558 | :terminator the terminator to be sent after a | 592 | :terminator the terminator to be sent after a |
| 559 | `sql-send-string', `sql-send-region', | 593 | `sql-send-string', `sql-send-region', |
| 560 | `sql-send-paragraph' and | 594 | `sql-send-paragraph' and |
| @@ -574,7 +608,7 @@ using `sql-get-product-feature' to lookup the product specific | |||
| 574 | settings.") | 608 | settings.") |
| 575 | 609 | ||
| 576 | (defvar sql-indirect-features | 610 | (defvar sql-indirect-features |
| 577 | '(:font-lock :sqli-program :sqli-options :sqli-login)) | 611 | '(:font-lock :sqli-program :sqli-options :sqli-login :statement)) |
| 578 | 612 | ||
| 579 | (defcustom sql-connection-alist nil | 613 | (defcustom sql-connection-alist nil |
| 580 | "An alist of connection parameters for interacting with a SQL | 614 | "An alist of connection parameters for interacting with a SQL |
| @@ -683,6 +717,13 @@ it automatically." | |||
| 683 | :version "22.2" | 717 | :version "22.2" |
| 684 | :group 'SQL) | 718 | :group 'SQL) |
| 685 | 719 | ||
| 720 | (defvar sql-contains-names nil | ||
| 721 | "When non-nil, the current buffer contains database names. | ||
| 722 | |||
| 723 | Globally should be set to nil; it will be non-nil in `sql-mode', | ||
| 724 | `sql-interactive-mode' and list all buffers.") | ||
| 725 | |||
| 726 | |||
| 686 | (defcustom sql-pop-to-buffer-after-send-region nil | 727 | (defcustom sql-pop-to-buffer-after-send-region nil |
| 687 | "When non-nil, pop to the buffer SQL statements are sent to. | 728 | "When non-nil, pop to the buffer SQL statements are sent to. |
| 688 | 729 | ||
| @@ -770,6 +811,19 @@ is changed." | |||
| 770 | :type 'hook | 811 | :type 'hook |
| 771 | :group 'SQL) | 812 | :group 'SQL) |
| 772 | 813 | ||
| 814 | ;; Customization for ANSI | ||
| 815 | |||
| 816 | (defcustom sql-ansi-statement-starters (regexp-opt '( | ||
| 817 | "create" "alter" "drop" | ||
| 818 | "select" "insert" "update" "delete" "merge" | ||
| 819 | "grant" "revoke" | ||
| 820 | )) | ||
| 821 | "Regexp of keywords that start SQL commands | ||
| 822 | |||
| 823 | All products share this list; products should define a regexp to | ||
| 824 | identify additional keywords in a variable defined by | ||
| 825 | the :statement feature.") | ||
| 826 | |||
| 773 | ;; Customization for Oracle | 827 | ;; Customization for Oracle |
| 774 | 828 | ||
| 775 | (defcustom sql-oracle-program "sqlplus" | 829 | (defcustom sql-oracle-program "sqlplus" |
| @@ -795,18 +849,22 @@ You will find the file in your Orant\\bin directory." | |||
| 795 | :version "24.1" | 849 | :version "24.1" |
| 796 | :group 'SQL) | 850 | :group 'SQL) |
| 797 | 851 | ||
| 852 | (defcustom sql-oracle-statement-starters (regexp-opt '("declare" "begin" "with")) | ||
| 853 | "Additional statement starting keywords in Oracle.") | ||
| 854 | |||
| 798 | (defcustom sql-oracle-scan-on t | 855 | (defcustom sql-oracle-scan-on t |
| 799 | "Non-nil if placeholders should be replaced in Oracle SQLi. | 856 | "Non-nil if placeholders should be replaced in Oracle SQLi. |
| 800 | 857 | ||
| 801 | When non-nil, Emacs will scan text sent to sqlplus and prompt | 858 | When non-nil, Emacs will scan text sent to sqlplus and prompt |
| 802 | for replacement text for & placeholders as sqlplus does. This | 859 | for replacement text for & placeholders as sqlplus does. This |
| 803 | is needed on Windows where sqlplus output is buffered and the | 860 | is needed on Windows where SQL*Plus output is buffered and the |
| 804 | prompts are not shown until after the text is entered. | 861 | prompts are not shown until after the text is entered. |
| 805 | 862 | ||
| 806 | You will probably want to issue the following command in sqlplus | 863 | You need to issue the following command in SQL*Plus to be safe: |
| 807 | to be safe: | 864 | |
| 865 | SET DEFINE OFF | ||
| 808 | 866 | ||
| 809 | SET SCAN OFF" | 867 | In older versions of SQL*Plus, this was the SET SCAN OFF command." |
| 810 | :type 'boolean | 868 | :type 'boolean |
| 811 | :group 'SQL) | 869 | :group 'SQL) |
| 812 | 870 | ||
| @@ -833,7 +891,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 833 | :version "24.1" | 891 | :version "24.1" |
| 834 | :group 'SQL) | 892 | :group 'SQL) |
| 835 | 893 | ||
| 836 | ;; Customization for MySql | 894 | ;; Customization for MySQL |
| 837 | 895 | ||
| 838 | (defcustom sql-mysql-program "mysql" | 896 | (defcustom sql-mysql-program "mysql" |
| 839 | "Command to start mysql by TcX. | 897 | "Command to start mysql by TcX. |
| @@ -851,7 +909,7 @@ on Windows: \"-C\" \"-t\" \"-f\" \"-n\"." | |||
| 851 | :group 'SQL) | 909 | :group 'SQL) |
| 852 | 910 | ||
| 853 | (defcustom sql-mysql-login-params '(user password database server) | 911 | (defcustom sql-mysql-login-params '(user password database server) |
| 854 | "List of login parameters needed to connect to MySql." | 912 | "List of login parameters needed to connect to MySQL." |
| 855 | :type 'sql-login-params | 913 | :type 'sql-login-params |
| 856 | :version "24.1" | 914 | :version "24.1" |
| 857 | :group 'SQL) | 915 | :group 'SQL) |
| @@ -1085,13 +1143,13 @@ You can change `sql-prompt-length' on `sql-interactive-mode-hook'.") | |||
| 1085 | 1143 | ||
| 1086 | Used by `sql-rename-buffer'.") | 1144 | Used by `sql-rename-buffer'.") |
| 1087 | 1145 | ||
| 1088 | (defun sql-buffer-live-p (buffer &optional product) | 1146 | (defun sql-buffer-live-p (buffer &optional product connection) |
| 1089 | "Returns non-nil if the process associated with buffer is live. | 1147 | "Returns non-nil if the process associated with buffer is live. |
| 1090 | 1148 | ||
| 1091 | BUFFER can be a buffer object or a buffer name. The buffer must | 1149 | BUFFER can be a buffer object or a buffer name. The buffer must |
| 1092 | be a live buffer, have an running process attached to it, be in | 1150 | be a live buffer, have an running process attached to it, be in |
| 1093 | `sql-interactive-mode', and, if PRODUCT is specified, it's | 1151 | `sql-interactive-mode', and, if PRODUCT or CONNECTION are |
| 1094 | `sql-product' must match." | 1152 | specified, it's `sql-product' or `sql-connection' must match." |
| 1095 | 1153 | ||
| 1096 | (when buffer | 1154 | (when buffer |
| 1097 | (setq buffer (get-buffer buffer)) | 1155 | (setq buffer (get-buffer buffer)) |
| @@ -1102,7 +1160,9 @@ be a live buffer, have an running process attached to it, be in | |||
| 1102 | (with-current-buffer buffer | 1160 | (with-current-buffer buffer |
| 1103 | (and (derived-mode-p 'sql-interactive-mode) | 1161 | (and (derived-mode-p 'sql-interactive-mode) |
| 1104 | (or (not product) | 1162 | (or (not product) |
| 1105 | (eq product sql-product))))))) | 1163 | (eq product sql-product)) |
| 1164 | (or (not connection) | ||
| 1165 | (eq connection sql-connection))))))) | ||
| 1106 | 1166 | ||
| 1107 | ;; Keymap for sql-interactive-mode. | 1167 | ;; Keymap for sql-interactive-mode. |
| 1108 | 1168 | ||
| @@ -1136,6 +1196,8 @@ Based on `comint-mode-map'.") | |||
| 1136 | (define-key map (kbd "C-c C-i") 'sql-product-interactive) | 1196 | (define-key map (kbd "C-c C-i") 'sql-product-interactive) |
| 1137 | (define-key map (kbd "C-c C-l a") 'sql-list-all) | 1197 | (define-key map (kbd "C-c C-l a") 'sql-list-all) |
| 1138 | (define-key map (kbd "C-c C-l t") 'sql-list-table) | 1198 | (define-key map (kbd "C-c C-l t") 'sql-list-table) |
| 1199 | (define-key map [remap beginning-of-defun] 'sql-beginning-of-statement) | ||
| 1200 | (define-key map [remap end-of-defun] 'sql-end-of-statement) | ||
| 1139 | map) | 1201 | map) |
| 1140 | "Mode map used for `sql-mode'.") | 1202 | "Mode map used for `sql-mode'.") |
| 1141 | 1203 | ||
| @@ -1151,8 +1213,10 @@ Based on `comint-mode-map'.") | |||
| 1151 | ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] | 1213 | ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] |
| 1152 | ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] | 1214 | ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] |
| 1153 | "--" | 1215 | "--" |
| 1154 | ["List all objects" sql-list-all (sql-buffer-live-p sql-buffer)] | 1216 | ["List all objects" sql-list-all (and (sql-buffer-live-p sql-buffer) |
| 1155 | ["List table details" sql-list-table (sql-buffer-live-p sql-buffer)] | 1217 | (sql-get-product-feature sql-product :list-all))] |
| 1218 | ["List table details" sql-list-table (and (sql-buffer-live-p sql-buffer) | ||
| 1219 | (sql-get-product-feature sql-product :list-table))] | ||
| 1156 | "--" | 1220 | "--" |
| 1157 | ["Start SQLi session" sql-product-interactive | 1221 | ["Start SQLi session" sql-product-interactive |
| 1158 | :visible (not sql-connection-alist) | 1222 | :visible (not sql-connection-alist) |
| @@ -1194,8 +1258,8 @@ Based on `comint-mode-map'.") | |||
| 1194 | ["Rename Buffer" sql-rename-buffer t] | 1258 | ["Rename Buffer" sql-rename-buffer t] |
| 1195 | ["Save Connection" sql-save-connection (not sql-connection)] | 1259 | ["Save Connection" sql-save-connection (not sql-connection)] |
| 1196 | "--" | 1260 | "--" |
| 1197 | ["List all objects" sql-list-all t] | 1261 | ["List all objects" sql-list-all (sql-get-product-feature sql-product :list-all)] |
| 1198 | ["List table details" sql-list-table t])) | 1262 | ["List table details" sql-list-table (sql-get-product-feature sql-product :list-table)])) |
| 1199 | 1263 | ||
| 1200 | ;; Abbreviations -- if you want more of them, define them in your | 1264 | ;; Abbreviations -- if you want more of them, define them in your |
| 1201 | ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. | 1265 | ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. |
| @@ -1238,8 +1302,9 @@ Based on `comint-mode-map'.") | |||
| 1238 | (modify-syntax-entry ?' "\"" table) | 1302 | (modify-syntax-entry ?' "\"" table) |
| 1239 | ;; double quotes (") don't delimit strings | 1303 | ;; double quotes (") don't delimit strings |
| 1240 | (modify-syntax-entry ?\" "." table) | 1304 | (modify-syntax-entry ?\" "." table) |
| 1241 | ;; backslash is no escape character | 1305 | ;; Make these all punctuation |
| 1242 | (modify-syntax-entry ?\\ "." table) | 1306 | (mapc (lambda (c) (modify-syntax-entry c "." table)) |
| 1307 | (string-to-list "!#$%&+,.:;<=>?@\\|")) | ||
| 1243 | table) | 1308 | table) |
| 1244 | "Syntax table used in `sql-mode' and `sql-interactive-mode'.") | 1309 | "Syntax table used in `sql-mode' and `sql-interactive-mode'.") |
| 1245 | 1310 | ||
| @@ -1298,20 +1363,45 @@ statement. The format of variable should be a valid | |||
| 1298 | 1363 | ||
| 1299 | ;; Remove keywords that are defined in ANSI | 1364 | ;; Remove keywords that are defined in ANSI |
| 1300 | (setq kwd keywords) | 1365 | (setq kwd keywords) |
| 1301 | (dolist (k keywords) | 1366 | ;; (dolist (k keywords) |
| 1302 | (catch 'next | 1367 | ;; (catch 'next |
| 1303 | (dolist (a sql-mode-ansi-font-lock-keywords) | 1368 | ;; (dolist (a sql-mode-ansi-font-lock-keywords) |
| 1304 | (when (and (eq face (cdr a)) | 1369 | ;; (when (and (eq face (cdr a)) |
| 1305 | (eq (string-match (car a) k 0) 0) | 1370 | ;; (eq (string-match (car a) k 0) 0) |
| 1306 | (eq (match-end 0) (length k))) | 1371 | ;; (eq (match-end 0) (length k))) |
| 1307 | (setq kwd (delq k kwd)) | 1372 | ;; (setq kwd (delq k kwd)) |
| 1308 | (throw 'next nil))))) | 1373 | ;; (throw 'next nil))))) |
| 1309 | 1374 | ||
| 1310 | ;; Create a properly formed font-lock-keywords item | 1375 | ;; Create a properly formed font-lock-keywords item |
| 1311 | (cons (concat (car bdy) | 1376 | (cons (concat (car bdy) |
| 1312 | (regexp-opt kwd t) | 1377 | (regexp-opt kwd t) |
| 1313 | (cdr bdy)) | 1378 | (cdr bdy)) |
| 1314 | face)))) | 1379 | face))) |
| 1380 | |||
| 1381 | (defun sql-regexp-abbrev (keyword) | ||
| 1382 | (let ((brk (string-match "[~]" keyword)) | ||
| 1383 | (len (length keyword)) | ||
| 1384 | (sep "\\(?:") | ||
| 1385 | re i) | ||
| 1386 | (if (not brk) | ||
| 1387 | keyword | ||
| 1388 | (setq re (substring keyword 0 brk) | ||
| 1389 | i (+ 2 brk) | ||
| 1390 | brk (1+ brk)) | ||
| 1391 | (while (<= i len) | ||
| 1392 | (setq re (concat re sep (substring keyword brk i)) | ||
| 1393 | sep "\\|" | ||
| 1394 | i (1+ i))) | ||
| 1395 | (concat re "\\)?")))) | ||
| 1396 | |||
| 1397 | (defun sql-regexp-abbrev-list (&rest keyw-list) | ||
| 1398 | (let ((re nil) | ||
| 1399 | (sep "\\<\\(?:")) | ||
| 1400 | (while keyw-list | ||
| 1401 | (setq re (concat re sep (sql-regexp-abbrev (car keyw-list))) | ||
| 1402 | sep "\\|" | ||
| 1403 | keyw-list (cdr keyw-list))) | ||
| 1404 | (concat re "\\)\\>")))) | ||
| 1315 | 1405 | ||
| 1316 | (eval-when-compile | 1406 | (eval-when-compile |
| 1317 | (setq sql-mode-ansi-font-lock-keywords | 1407 | (setq sql-mode-ansi-font-lock-keywords |
| @@ -1346,6 +1436,7 @@ statement. The format of variable should be a valid | |||
| 1346 | "user_defined_type_catalog" "user_defined_type_name" | 1436 | "user_defined_type_catalog" "user_defined_type_name" |
| 1347 | "user_defined_type_schema" | 1437 | "user_defined_type_schema" |
| 1348 | ) | 1438 | ) |
| 1439 | |||
| 1349 | ;; ANSI Reserved keywords | 1440 | ;; ANSI Reserved keywords |
| 1350 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil | 1441 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil |
| 1351 | "absolute" "action" "add" "admin" "after" "aggregate" "alias" "all" | 1442 | "absolute" "action" "add" "admin" "after" "aggregate" "alias" "all" |
| @@ -1395,6 +1486,7 @@ statement. The format of variable should be a valid | |||
| 1395 | "substring" "sum" "system_user" "translate" "treat" "trim" "upper" | 1486 | "substring" "sum" "system_user" "translate" "treat" "trim" "upper" |
| 1396 | "user" | 1487 | "user" |
| 1397 | ) | 1488 | ) |
| 1489 | |||
| 1398 | ;; ANSI Data Types | 1490 | ;; ANSI Data Types |
| 1399 | (sql-font-lock-keywords-builder 'font-lock-type-face nil | 1491 | (sql-font-lock-keywords-builder 'font-lock-type-face nil |
| 1400 | "array" "binary" "bit" "blob" "boolean" "char" "character" "clob" | 1492 | "array" "binary" "bit" "blob" "boolean" "char" "character" "clob" |
| @@ -1414,86 +1506,142 @@ function `regexp-opt'. Therefore, take a look at the source before | |||
| 1414 | you define your own `sql-mode-ansi-font-lock-keywords'. You may want | 1506 | you define your own `sql-mode-ansi-font-lock-keywords'. You may want |
| 1415 | to add functions and PL/SQL keywords.") | 1507 | to add functions and PL/SQL keywords.") |
| 1416 | 1508 | ||
| 1509 | (defun sql-oracle-show-reserved-words () | ||
| 1510 | ;; This function is for use by the maintainer of SQL.EL only. | ||
| 1511 | (interactive) | ||
| 1512 | (if (or (and (not (derived-mode-p 'sql-mode)) | ||
| 1513 | (not (derived-mode-p 'sql-interactive-mode))) | ||
| 1514 | (not sql-buffer) | ||
| 1515 | (not (eq sql-product 'oracle))) | ||
| 1516 | (error "Not an Oracle buffer") | ||
| 1517 | |||
| 1518 | (let ((b "*RESERVED WORDS*")) | ||
| 1519 | (sql-execute sql-buffer b | ||
| 1520 | (concat "SELECT " | ||
| 1521 | " keyword " | ||
| 1522 | ", reserved AS \"Res\" " | ||
| 1523 | ", res_type AS \"Type\" " | ||
| 1524 | ", res_attr AS \"Attr\" " | ||
| 1525 | ", res_semi AS \"Semi\" " | ||
| 1526 | ", duplicate AS \"Dup\" " | ||
| 1527 | "FROM V$RESERVED_WORDS " | ||
| 1528 | "WHERE length > 1 " | ||
| 1529 | "AND SUBSTR(keyword, 1, 1) BETWEEN 'A' AND 'Z' " | ||
| 1530 | "ORDER BY 2 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC, 1;") | ||
| 1531 | nil nil) | ||
| 1532 | (with-current-buffer b | ||
| 1533 | (set (make-local-variable 'sql-product) 'oracle) | ||
| 1534 | (sql-product-font-lock t nil) | ||
| 1535 | (font-lock-mode +1))))) | ||
| 1536 | |||
| 1417 | (defvar sql-mode-oracle-font-lock-keywords | 1537 | (defvar sql-mode-oracle-font-lock-keywords |
| 1418 | (eval-when-compile | 1538 | (eval-when-compile |
| 1419 | (list | 1539 | (list |
| 1420 | ;; Oracle SQL*Plus Commands | 1540 | ;; Oracle SQL*Plus Commands |
| 1421 | (cons | 1541 | ;; Only recognized in they start in column 1 and the |
| 1422 | (concat | 1542 | ;; abbreviation is followed by a space or the end of line. |
| 1423 | "^\\s-*\\(?:\\(?:" (regexp-opt '( | ||
| 1424 | "@" "@@" "accept" "append" "archive" "attribute" "break" | ||
| 1425 | "btitle" "change" "clear" "column" "connect" "copy" "define" | ||
| 1426 | "del" "describe" "disconnect" "edit" "execute" "exit" "get" "help" | ||
| 1427 | "host" "input" "list" "password" "pause" "print" "prompt" "recover" | ||
| 1428 | "remark" "repfooter" "repheader" "run" "save" "show" "shutdown" | ||
| 1429 | "spool" "start" "startup" "store" "timing" "ttitle" "undefine" | ||
| 1430 | "variable" "whenever" | ||
| 1431 | ) t) | ||
| 1432 | 1543 | ||
| 1433 | "\\)\\|" | 1544 | "\\|" |
| 1434 | "\\(?:compute\\s-+\\(?:avg\\|cou\\|min\\|max\\|num\\|sum\\|std\\|var\\)\\)\\|" | 1545 | (list (concat "^" (sql-regexp-abbrev "rem~ark") "\\(?:\\s-.*\\)?$") |
| 1435 | "\\(?:set\\s-+\\(" | 1546 | 0 'font-lock-comment-face t) |
| 1436 | 1547 | ||
| 1437 | (regexp-opt | 1548 | (list |
| 1438 | '("appi" "appinfo" "array" "arraysize" "auto" "autocommit" | 1549 | (concat |
| 1439 | "autop" "autoprint" "autorecovery" "autot" "autotrace" "blo" | 1550 | "^\\(?:" |
| 1440 | "blockterminator" "buffer" "closecursor" "cmds" "cmdsep" | 1551 | (sql-regexp-abbrev-list |
| 1441 | "colsep" "com" "compatibility" "con" "concat" "constraint" | 1552 | "[@]\\{1,2\\}" "acc~ept" "a~ppend" "archive" "attribute" |
| 1442 | "constraints" "copyc" "copycommit" "copytypecheck" "database" | 1553 | "bre~ak" "bti~tle" "c~hange" "cl~ear" "col~umn" "conn~ect" |
| 1443 | "def" "define" "document" "echo" "editf" "editfile" "emb" | 1554 | "copy" "def~ine" "del" "desc~ribe" "disc~onnect" "ed~it" |
| 1444 | "embedded" "esc" "escape" "feed" "feedback" "flagger" "flu" | 1555 | "exec~ute" "exit" "get" "help" "ho~st" "[$]" "i~nput" "l~ist" |
| 1445 | "flush" "hea" "heading" "heads" "headsep" "instance" "lin" | 1556 | "passw~ord" "pau~se" "pri~nt" "pro~mpt" "quit" "recover" |
| 1446 | "linesize" "lobof" "loboffset" "logsource" "long" "longc" | 1557 | "repf~ooter" "reph~eader" "r~un" "sav~e" "sho~w" "shutdown" |
| 1447 | "longchunksize" "maxdata" "newp" "newpage" "null" "num" | 1558 | "spo~ol" "sta~rt" "startup" "store" "tim~ing" "tti~tle" |
| 1448 | "numf" "numformat" "numwidth" "pages" "pagesize" "pau" | 1559 | "undef~ine" "var~iable" "whenever") |
| 1449 | "pause" "recsep" "recsepchar" "role" "scan" "serveroutput" | 1560 | "\\|" |
| 1450 | "shift" "shiftinout" "show" "showmode" "space" "sqlbl" | 1561 | (concat "\\(?:" |
| 1451 | "sqlblanklines" "sqlc" "sqlcase" "sqlco" "sqlcontinue" "sqln" | 1562 | (sql-regexp-abbrev "comp~ute") |
| 1452 | "sqlnumber" "sqlp" "sqlpluscompat" "sqlpluscompatibility" | 1563 | "\\s-+" |
| 1453 | "sqlpre" "sqlprefix" "sqlprompt" "sqlt" "sqlterminator" | 1564 | (sql-regexp-abbrev-list |
| 1454 | "statement_id" "suf" "suffix" "tab" "term" "termout" "ti" | 1565 | "avg" "cou~nt" "min~imum" "max~imum" "num~ber" "sum" |
| 1455 | "time" "timi" "timing" "transaction" "trim" "trimout" "trims" | 1566 | "std" "var~iance") |
| 1456 | "trimspool" "truncate" "und" "underline" "ver" "verify" "wra" | 1567 | "\\)") |
| 1457 | "wrap")) "\\)\\)" | 1568 | "\\|" |
| 1458 | 1569 | (concat "\\(?:set\\s-+" | |
| 1459 | "\\)\\b.*" | 1570 | (sql-regexp-abbrev-list |
| 1460 | ) | 1571 | "appi~nfo" "array~size" "auto~commit" "autop~rint" |
| 1461 | 'font-lock-doc-face) | 1572 | "autorecovery" "autot~race" "blo~ckterminator" |
| 1462 | '("^\\s-*rem\\(?:ark\\)?\\>.*" . font-lock-comment-face) | 1573 | "cmds~ep" "colsep" "com~patibility" "con~cat" |
| 1574 | "copyc~ommit" "copytypecheck" "def~ine" "describe" | ||
| 1575 | "echo" "editf~ile" "emb~edded" "esc~ape" "feed~back" | ||
| 1576 | "flagger" "flu~sh" "hea~ding" "heads~ep" "instance" | ||
| 1577 | "lin~esize" "lobof~fset" "long" "longc~hunksize" | ||
| 1578 | "mark~up" "newp~age" "null" "numf~ormat" "num~width" | ||
| 1579 | "pages~ize" "pau~se" "recsep" "recsepchar" | ||
| 1580 | "scan" "serverout~put" "shift~inout" "show~mode" | ||
| 1581 | "sqlbl~anklines" "sqlc~ase" "sqlco~ntinue" | ||
| 1582 | "sqln~umber" "sqlpluscompat~ibility" "sqlpre~fix" | ||
| 1583 | "sqlp~rompt" "sqlt~erminator" "suf~fix" "tab" | ||
| 1584 | "term~out" "ti~me" "timi~ng" "trim~out" "trims~pool" | ||
| 1585 | "und~erline" "ver~ify" "wra~p") | ||
| 1586 | "\\)") | ||
| 1587 | |||
| 1588 | "\\)\\(?:\\s-.*\\)?\\(?:[-]\n.*\\)*$") | ||
| 1589 | 0 'font-lock-doc-face t) | ||
| 1463 | 1590 | ||
| 1464 | ;; Oracle Functions | 1591 | ;; Oracle Functions |
| 1465 | (sql-font-lock-keywords-builder 'font-lock-builtin-face nil | 1592 | (sql-font-lock-keywords-builder 'font-lock-builtin-face nil |
| 1466 | "abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2" | 1593 | "abs" "acos" "add_months" "appendchildxml" "ascii" "asciistr" "asin" |
| 1467 | "avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid" | 1594 | "atan" "atan2" "avg" "bfilename" "bin_to_num" "bitand" "cardinality" |
| 1468 | "chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh" | 1595 | "cast" "ceil" "chartorowid" "chr" "cluster_id" "cluster_probability" |
| 1469 | "count" "covar_pop" "covar_samp" "cume_dist" "current_date" | 1596 | "cluster_set" "coalesce" "collect" "compose" "concat" "convert" "corr" |
| 1470 | "current_timestamp" "current_user" "dbtimezone" "decode" "decompose" | 1597 | "corr_k" "corr_s" "cos" "cosh" "count" "covar_pop" "covar_samp" |
| 1471 | "dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp" | 1598 | "cube_table" "cume_dist" "currrent_date" "currrent_timestamp" "cv" |
| 1472 | "extract" "extractvalue" "first" "first_value" "floor" "following" | 1599 | "dataobj_to_partition" "dbtimezone" "decode" "decompose" "deletexml" |
| 1473 | "from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap" | 1600 | "dense_rank" "depth" "deref" "dump" "empty_blob" "empty_clob" |
| 1474 | "instr" "lag" "last" "last_day" "last_value" "lead" "least" "length" | 1601 | "existsnode" "exp" "extract" "extractvalue" "feature_id" "feature_set" |
| 1475 | "ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min" | 1602 | "feature_value" "first" "first_value" "floor" "from_tz" "greatest" |
| 1476 | "mod" "months_between" "new_time" "next_day" "nls_charset_decl_len" | 1603 | "grouping" "grouping_id" "group_id" "hextoraw" "initcap" |
| 1604 | "insertchildxml" "insertchildxmlafter" "insertchildxmlbefore" | ||
| 1605 | "insertxmlafter" "insertxmlbefore" "instr" "instr2" "instr4" "instrb" | ||
| 1606 | "instrc" "iteration_number" "lag" "last" "last_day" "last_value" | ||
| 1607 | "lead" "least" "length" "length2" "length4" "lengthb" "lengthc" | ||
| 1608 | "listagg" "ln" "lnnvl" "localtimestamp" "log" "lower" "lpad" "ltrim" | ||
| 1609 | "make_ref" "max" "median" "min" "mod" "months_between" "nanvl" "nchr" | ||
| 1610 | "new_time" "next_day" "nlssort" "nls_charset_decl_len" | ||
| 1477 | "nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower" | 1611 | "nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower" |
| 1478 | "nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval" | 1612 | "nls_upper" "nth_value" "ntile" "nullif" "numtodsinterval" |
| 1479 | "numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank" | 1613 | "numtoyminterval" "nvl" "nvl2" "ora_dst_affected" "ora_dst_convert" |
| 1480 | "percentile_cont" "percentile_disc" "power" "preceding" "rank" | 1614 | "ora_dst_error" "ora_hash" "path" "percentile_cont" "percentile_disc" |
| 1481 | "ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_" | 1615 | "percent_rank" "power" "powermultiset" "powermultiset_by_cardinality" |
| 1482 | "regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2" | 1616 | "prediction" "prediction_bounds" "prediction_cost" |
| 1483 | "regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round" | 1617 | "prediction_details" "prediction_probability" "prediction_set" |
| 1484 | "row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim" | 1618 | "presentnnv" "presentv" "previous" "rank" "ratio_to_report" "rawtohex" |
| 1485 | "sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev" | 1619 | "rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr" |
| 1486 | "stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path" | 1620 | "regexp_replace" "regexp_substr" "regr_avgx" "regr_avgy" "regr_count" |
| 1487 | "sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" | 1621 | "regr_intercept" "regr_r2" "regr_slope" "regr_sxx" "regr_sxy" |
| 1488 | "sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh" | 1622 | "regr_syy" "remainder" "replace" "round" "rowidtochar" "rowidtonchar" |
| 1623 | "row_number" "rpad" "rtrim" "scn_to_timestamp" "sessiontimezone" "set" | ||
| 1624 | "sign" "sin" "sinh" "soundex" "sqrt" "stats_binomial_test" | ||
| 1625 | "stats_crosstab" "stats_f_test" "stats_ks_test" "stats_mode" | ||
| 1626 | "stats_mw_test" "stats_one_way_anova" "stats_t_test_indep" | ||
| 1627 | "stats_t_test_indepu" "stats_t_test_one" "stats_t_test_paired" | ||
| 1628 | "stats_wsr_test" "stddev" "stddev_pop" "stddev_samp" "substr" | ||
| 1629 | "substr2" "substr4" "substrb" "substrc" "sum" "sysdate" "systimestamp" | ||
| 1630 | "sys_connect_by_path" "sys_context" "sys_dburigen" "sys_extract_utc" | ||
| 1631 | "sys_guid" "sys_typeid" "sys_xmlagg" "sys_xmlgen" "tan" "tanh" | ||
| 1632 | "timestamp_to_scn" "to_binary_double" "to_binary_float" "to_blob" | ||
| 1489 | "to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" | 1633 | "to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" |
| 1490 | "to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" | 1634 | "to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" |
| 1491 | "to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" | 1635 | "to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" |
| 1492 | "tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user" | 1636 | "tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv" |
| 1493 | "userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml" | 1637 | "value" "variance" "var_pop" "var_samp" "vsize" "width_bucket" |
| 1494 | "xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement" | 1638 | "xmlagg" "xmlcast" "xmlcdata" "xmlcolattval" "xmlcomment" "xmlconcat" |
| 1495 | "xmlforest" "xmlsequence" "xmltransform" | 1639 | "xmldiff" "xmlelement" "xmlexists" "xmlforest" "xmlisvalid" "xmlparse" |
| 1640 | "xmlpatch" "xmlpi" "xmlquery" "xmlroot" "xmlsequence" "xmlserialize" | ||
| 1641 | "xmltable" "xmltransform" | ||
| 1496 | ) | 1642 | ) |
| 1643 | |||
| 1644 | ;; See the table V$RESERVED_WORDS | ||
| 1497 | ;; Oracle Keywords | 1645 | ;; Oracle Keywords |
| 1498 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil | 1646 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil |
| 1499 | "abort" "access" "accessed" "account" "activate" "add" "admin" | 1647 | "abort" "access" "accessed" "account" "activate" "add" "admin" |
| @@ -1582,52 +1730,120 @@ to add functions and PL/SQL keywords.") | |||
| 1582 | "varray" "version" "view" "wait" "when" "whenever" "where" "with" | 1730 | "varray" "version" "view" "wait" "when" "whenever" "where" "with" |
| 1583 | "without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype" | 1731 | "without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype" |
| 1584 | ) | 1732 | ) |
| 1733 | |||
| 1585 | ;; Oracle Data Types | 1734 | ;; Oracle Data Types |
| 1586 | (sql-font-lock-keywords-builder 'font-lock-type-face nil | 1735 | (sql-font-lock-keywords-builder 'font-lock-type-face nil |
| 1587 | "bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal" | 1736 | "bfile" "binary_double" "binary_float" "blob" "byte" "char" "charbyte" |
| 1588 | "double" "float" "int" "integer" "interval" "long" "national" "nchar" | 1737 | "clob" "date" "day" "float" "interval" "local" "long" "longraw" |
| 1589 | "nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real" | 1738 | "minute" "month" "nchar" "nclob" "number" "nvarchar2" "raw" "rowid" "second" |
| 1590 | "rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar" | 1739 | "time" "timestamp" "urowid" "varchar2" "with" "year" "zone" |
| 1591 | "varchar2" "varying" "year" "zone" | ||
| 1592 | ) | 1740 | ) |
| 1593 | 1741 | ||
| 1594 | ;; Oracle PL/SQL Attributes | 1742 | ;; Oracle PL/SQL Attributes |
| 1595 | (sql-font-lock-keywords-builder 'font-lock-builtin-face '("" . "\\b") | 1743 | (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b") |
| 1596 | "%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype" | 1744 | "bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound" |
| 1597 | "%type" | 1745 | "rowcount" "rowtype" "type" |
| 1598 | ) | 1746 | ) |
| 1599 | 1747 | ||
| 1600 | ;; Oracle PL/SQL Functions | 1748 | ;; Oracle PL/SQL Functions |
| 1601 | (sql-font-lock-keywords-builder 'font-lock-builtin-face nil | 1749 | (sql-font-lock-keywords-builder 'font-lock-builtin-face nil |
| 1602 | "extend" "prior" | 1750 | "delete" "trim" "extend" "exists" "first" "last" "count" "limit" |
| 1751 | "prior" "next" | ||
| 1752 | ) | ||
| 1753 | |||
| 1754 | ;; Oracle PL/SQL Reserved words | ||
| 1755 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil | ||
| 1756 | "all" "alter" "and" "any" "as" "asc" "at" "begin" "between" "by" | ||
| 1757 | "case" "check" "clusters" "cluster" "colauth" "columns" "compress" | ||
| 1758 | "connect" "crash" "create" "cursor" "declare" "default" "desc" | ||
| 1759 | "distinct" "drop" "else" "end" "exception" "exclusive" "fetch" "for" | ||
| 1760 | "from" "function" "goto" "grant" "group" "having" "identified" "if" | ||
| 1761 | "in" "index" "indexes" "insert" "intersect" "into" "is" "like" "lock" | ||
| 1762 | "minus" "mode" "nocompress" "not" "nowait" "null" "of" "on" "option" | ||
| 1763 | "or" "order" "overlaps" "procedure" "public" "resource" "revoke" | ||
| 1764 | "select" "share" "size" "sql" "start" "subtype" "tabauth" "table" | ||
| 1765 | "then" "to" "type" "union" "unique" "update" "values" "view" "views" | ||
| 1766 | "when" "where" "with" | ||
| 1767 | |||
| 1768 | "true" "false" | ||
| 1769 | "raise_application_error" | ||
| 1603 | ) | 1770 | ) |
| 1604 | 1771 | ||
| 1605 | ;; Oracle PL/SQL Keywords | 1772 | ;; Oracle PL/SQL Keywords |
| 1606 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil | 1773 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil |
| 1607 | "autonomous_transaction" "bulk" "char_base" "collect" "constant" | 1774 | "a" "add" "agent" "aggregate" "array" "attribute" "authid" "avg" |
| 1608 | "cursor" "declare" "do" "elsif" "exception_init" "execute" "exit" | 1775 | "bfile_base" "binary" "blob_base" "block" "body" "both" "bound" "bulk" |
| 1609 | "extends" "false" "fetch" "forall" "goto" "hour" "if" "interface" | 1776 | "byte" "c" "call" "calling" "cascade" "char" "char_base" "character" |
| 1610 | "loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype" | 1777 | "charset" "charsetform" "charsetid" "clob_base" "close" "collect" |
| 1611 | "separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype" | 1778 | "comment" "commit" "committed" "compiled" "constant" "constructor" |
| 1612 | "the" "timezone_abbr" "timezone_hour" "timezone_minute" | 1779 | "context" "continue" "convert" "count" "current" "customdatum" |
| 1613 | "timezone_region" "true" "varrying" "while" | 1780 | "dangling" "data" "date" "date_base" "day" "define" "delete" |
| 1781 | "deterministic" "double" "duration" "element" "elsif" "empty" "escape" | ||
| 1782 | "except" "exceptions" "execute" "exists" "exit" "external" "final" | ||
| 1783 | "fixed" "float" "forall" "force" "general" "hash" "heap" "hidden" | ||
| 1784 | "hour" "immediate" "including" "indicator" "indices" "infinite" | ||
| 1785 | "instantiable" "int" "interface" "interval" "invalidate" "isolation" | ||
| 1786 | "java" "language" "large" "leading" "length" "level" "library" "like2" | ||
| 1787 | "like4" "likec" "limit" "limited" "local" "long" "loop" "map" "max" | ||
| 1788 | "maxlen" "member" "merge" "min" "minute" "mod" "modify" "month" | ||
| 1789 | "multiset" "name" "nan" "national" "native" "nchar" "new" "nocopy" | ||
| 1790 | "number_base" "object" "ocicoll" "ocidate" "ocidatetime" "ociduration" | ||
| 1791 | "ociinterval" "ociloblocator" "ocinumber" "ociraw" "ociref" | ||
| 1792 | "ocirefcursor" "ocirowid" "ocistring" "ocitype" "old" "only" "opaque" | ||
| 1793 | "open" "operator" "oracle" "oradata" "organization" "orlany" "orlvary" | ||
| 1794 | "others" "out" "overriding" "package" "parallel_enable" "parameter" | ||
| 1795 | "parameters" "parent" "partition" "pascal" "pipe" "pipelined" "pragma" | ||
| 1796 | "precision" "prior" "private" "raise" "range" "raw" "read" "record" | ||
| 1797 | "ref" "reference" "relies_on" "rem" "remainder" "rename" "result" | ||
| 1798 | "result_cache" "return" "returning" "reverse" "rollback" "row" | ||
| 1799 | "sample" "save" "savepoint" "sb1" "sb2" "sb4" "second" "segment" | ||
| 1800 | "self" "separate" "sequence" "serializable" "set" "short" "size_t" | ||
| 1801 | "some" "sparse" "sqlcode" "sqldata" "sqlname" "sqlstate" "standard" | ||
| 1802 | "static" "stddev" "stored" "string" "struct" "style" "submultiset" | ||
| 1803 | "subpartition" "substitutable" "sum" "synonym" "tdo" "the" "time" | ||
| 1804 | "timestamp" "timezone_abbr" "timezone_hour" "timezone_minute" | ||
| 1805 | "timezone_region" "trailing" "transaction" "transactional" "trusted" | ||
| 1806 | "ub1" "ub2" "ub4" "under" "unsigned" "untrusted" "use" "using" | ||
| 1807 | "valist" "value" "variable" "variance" "varray" "varying" "void" | ||
| 1808 | "while" "work" "wrapped" "write" "year" "zone" | ||
| 1809 | ;; Pragma | ||
| 1810 | "autonomous_transaction" "exception_init" "inline" | ||
| 1811 | "restrict_references" "serially_reusable" | ||
| 1614 | ) | 1812 | ) |
| 1615 | 1813 | ||
| 1616 | ;; Oracle PL/SQL Data Types | 1814 | ;; Oracle PL/SQL Data Types |
| 1617 | (sql-font-lock-keywords-builder 'font-lock-type-face nil | 1815 | (sql-font-lock-keywords-builder 'font-lock-type-face nil |
| 1618 | "binary_integer" "boolean" "naturaln" "pls_integer" "positive" | 1816 | "\"BINARY LARGE OBJECT\"" "\"CHAR LARGE OBJECT\"" "\"CHAR VARYING\"" |
| 1619 | "positiven" "record" "signtype" "string" | 1817 | "\"CHARACTER LARGE OBJECT\"" "\"CHARACTER VARYING\"" |
| 1818 | "\"DOUBLE PRECISION\"" "\"INTERVAL DAY TO SECOND\"" | ||
| 1819 | "\"INTERVAL YEAR TO MONTH\"" "\"LONG RAW\"" "\"NATIONAL CHAR\"" | ||
| 1820 | "\"NATIONAL CHARACTER LARGE OBJECT\"" "\"NATIONAL CHARACTER\"" | ||
| 1821 | "\"NCHAR LARGE OBJECT\"" "\"NCHAR\"" "\"NCLOB\"" "\"NVARCHAR2\"" | ||
| 1822 | "\"TIME WITH TIME ZONE\"" "\"TIMESTAMP WITH LOCAL TIME ZONE\"" | ||
| 1823 | "\"TIMESTAMP WITH TIME ZONE\"" | ||
| 1824 | "bfile" "bfile_base" "binary_double" "binary_float" "binary_integer" | ||
| 1825 | "blob" "blob_base" "boolean" "char" "character" "char_base" "clob" | ||
| 1826 | "clob_base" "cursor" "date" "day" "dec" "decimal" | ||
| 1827 | "dsinterval_unconstrained" "float" "int" "integer" "interval" "local" | ||
| 1828 | "long" "mlslabel" "month" "natural" "naturaln" "nchar_cs" "number" | ||
| 1829 | "number_base" "numeric" "pls_integer" "positive" "positiven" "raw" | ||
| 1830 | "real" "ref" "rowid" "second" "signtype" "simple_double" | ||
| 1831 | "simple_float" "simple_integer" "smallint" "string" "time" "timestamp" | ||
| 1832 | "timestamp_ltz_unconstrained" "timestamp_tz_unconstrained" | ||
| 1833 | "timestamp_unconstrained" "time_tz_unconstrained" "time_unconstrained" | ||
| 1834 | "to" "urowid" "varchar" "varchar2" "with" "year" | ||
| 1835 | "yminterval_unconstrained" "zone" | ||
| 1620 | ) | 1836 | ) |
| 1621 | 1837 | ||
| 1622 | ;; Oracle PL/SQL Exceptions | 1838 | ;; Oracle PL/SQL Exceptions |
| 1623 | (sql-font-lock-keywords-builder 'font-lock-warning-face nil | 1839 | (sql-font-lock-keywords-builder 'font-lock-warning-face nil |
| 1624 | "access_into_null" "case_not_found" "collection_is_null" | 1840 | "access_into_null" "case_not_found" "collection_is_null" |
| 1625 | "cursor_already_open" "dup_val_on_index" "invalid_cursor" | 1841 | "cursor_already_open" "dup_val_on_index" "invalid_cursor" |
| 1626 | "invalid_number" "login_denied" "no_data_found" "not_logged_on" | 1842 | "invalid_number" "login_denied" "no_data_found" "no_data_needed" |
| 1627 | "program_error" "rowtype_mismatch" "self_is_null" "storage_error" | 1843 | "not_logged_on" "program_error" "rowtype_mismatch" "self_is_null" |
| 1628 | "subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid" | 1844 | "storage_error" "subscript_beyond_count" "subscript_outside_limit" |
| 1629 | "timeout_on_resource" "too_many_rows" "value_error" "zero_divide" | 1845 | "sys_invalid_rowid" "timeout_on_resource" "too_many_rows" |
| 1630 | "exception" "notfound" | 1846 | "value_error" "zero_divide" |
| 1631 | ))) | 1847 | ))) |
| 1632 | 1848 | ||
| 1633 | "Oracle SQL keywords used by font-lock. | 1849 | "Oracle SQL keywords used by font-lock. |
| @@ -2296,10 +2512,7 @@ also be configured." | |||
| 2296 | 2512 | ||
| 2297 | (let | 2513 | (let |
| 2298 | ;; Get the product-specific syntax-alist. | 2514 | ;; Get the product-specific syntax-alist. |
| 2299 | ((syntax-alist | 2515 | ((syntax-alist (sql-product-font-lock-syntax-alist))) |
| 2300 | (append | ||
| 2301 | (sql-get-product-feature sql-product :syntax-alist) | ||
| 2302 | '((?_ . "w") (?. . "w"))))) | ||
| 2303 | 2516 | ||
| 2304 | ;; Get the product-specific keywords. | 2517 | ;; Get the product-specific keywords. |
| 2305 | (set (make-local-variable 'sql-mode-font-lock-keywords) | 2518 | (set (make-local-variable 'sql-mode-font-lock-keywords) |
| @@ -2388,9 +2601,30 @@ adds a fontification pattern to fontify identifiers ending in | |||
| 2388 | 2601 | ||
| 2389 | ;;; Functions to switch highlighting | 2602 | ;;; Functions to switch highlighting |
| 2390 | 2603 | ||
| 2604 | (defun sql-product-syntax-table () | ||
| 2605 | (let ((table (copy-syntax-table sql-mode-syntax-table))) | ||
| 2606 | (mapc (lambda (entry) | ||
| 2607 | (modify-syntax-entry (car entry) (cdr entry) table)) | ||
| 2608 | (sql-get-product-feature sql-product :syntax-alist)) | ||
| 2609 | table)) | ||
| 2610 | |||
| 2611 | (defun sql-product-font-lock-syntax-alist () | ||
| 2612 | (append | ||
| 2613 | ;; Change all symbol character to word characters | ||
| 2614 | (mapcar | ||
| 2615 | (lambda (entry) (if (string= (substring (cdr entry) 0 1) "_") | ||
| 2616 | (cons (car entry) | ||
| 2617 | (concat "w" (substring (cdr entry) 1))) | ||
| 2618 | entry)) | ||
| 2619 | (sql-get-product-feature sql-product :syntax-alist)) | ||
| 2620 | '((?_ . "w")))) | ||
| 2621 | |||
| 2391 | (defun sql-highlight-product () | 2622 | (defun sql-highlight-product () |
| 2392 | "Turn on the font highlighting for the SQL product selected." | 2623 | "Turn on the font highlighting for the SQL product selected." |
| 2393 | (when (derived-mode-p 'sql-mode) | 2624 | (when (derived-mode-p 'sql-mode) |
| 2625 | ;; Enhance the syntax table for the product | ||
| 2626 | (set-syntax-table (sql-product-syntax-table)) | ||
| 2627 | |||
| 2394 | ;; Setup font-lock | 2628 | ;; Setup font-lock |
| 2395 | (sql-product-font-lock nil t) | 2629 | (sql-product-font-lock nil t) |
| 2396 | 2630 | ||
| @@ -2418,11 +2652,77 @@ adds a fontification pattern to fontify identifiers ending in | |||
| 2418 | ;; comint-line-beginning-position is defined in Emacs 21 | 2652 | ;; comint-line-beginning-position is defined in Emacs 21 |
| 2419 | (defun comint-line-beginning-position () | 2653 | (defun comint-line-beginning-position () |
| 2420 | "Return the buffer position of the beginning of the line, after any prompt. | 2654 | "Return the buffer position of the beginning of the line, after any prompt. |
| 2421 | The prompt is assumed to be any text at the beginning of the line matching | 2655 | The prompt is assumed to be any text at the beginning of the line |
| 2422 | the regular expression `comint-prompt-regexp', a buffer local variable." | 2656 | matching the regular expression `comint-prompt-regexp', a buffer |
| 2657 | local variable." | ||
| 2423 | (save-excursion (comint-bol nil) (point)))) | 2658 | (save-excursion (comint-bol nil) (point)))) |
| 2424 | 2659 | ||
| 2425 | 2660 | ;;; Motion Functions | |
| 2661 | |||
| 2662 | (defun sql-statement-regexp (prod) | ||
| 2663 | (let* ((ansi-stmt (sql-get-product-feature 'ansi :statement)) | ||
| 2664 | (prod-stmt (sql-get-product-feature prod :statement))) | ||
| 2665 | (concat "^\\<" | ||
| 2666 | (if prod-stmt | ||
| 2667 | ansi-stmt | ||
| 2668 | (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)")) | ||
| 2669 | "\\>"))) | ||
| 2670 | |||
| 2671 | (defun sql-beginning-of-statement (arg) | ||
| 2672 | "Moves the cursor to the beginning of the current SQL statement." | ||
| 2673 | (interactive "p") | ||
| 2674 | |||
| 2675 | (let ((here (point)) | ||
| 2676 | (regexp (sql-statement-regexp sql-product)) | ||
| 2677 | last next) | ||
| 2678 | |||
| 2679 | ;; Go to the end of the statement before the start we desire | ||
| 2680 | (setq last (or (sql-end-of-statement (- arg)) | ||
| 2681 | (point-min))) | ||
| 2682 | ;; And find the end after that | ||
| 2683 | (setq next (or (sql-end-of-statement 1) | ||
| 2684 | (point-max))) | ||
| 2685 | |||
| 2686 | ;; Our start must be between them | ||
| 2687 | (goto-char last) | ||
| 2688 | ;; Find an beginning-of-stmt that's not in a comment | ||
| 2689 | (while (and (re-search-forward regexp next t 1) | ||
| 2690 | (nth 7 (syntax-ppss))) | ||
| 2691 | (goto-char (match-end 0))) | ||
| 2692 | (goto-char | ||
| 2693 | (if (match-data) | ||
| 2694 | (match-beginning 0) | ||
| 2695 | last)) | ||
| 2696 | (beginning-of-line) | ||
| 2697 | ;; If we didn't move, try again | ||
| 2698 | (when (= here (point)) | ||
| 2699 | (sql-beginning-of-statement (* 2 (sql-signum arg)))))) | ||
| 2700 | |||
| 2701 | (defun sql-end-of-statement (arg) | ||
| 2702 | "Moves the cursor to the end of the current SQL statement." | ||
| 2703 | (interactive "p") | ||
| 2704 | (let ((term (sql-get-product-feature sql-product :terminator)) | ||
| 2705 | (re-search (if (> 0 arg) 're-search-backward 're-search-forward)) | ||
| 2706 | (here (point)) | ||
| 2707 | (n 0)) | ||
| 2708 | (when (consp term) | ||
| 2709 | (setq term (car term))) | ||
| 2710 | ;; Iterate until we've moved the desired number of stmt ends | ||
| 2711 | (while (not (= (sql-signum arg) 0)) | ||
| 2712 | ;; if we're looking at the terminator, jump by 2 | ||
| 2713 | (if (or (and (> 0 arg) (looking-back term)) | ||
| 2714 | (and (< 0 arg) (looking-at term))) | ||
| 2715 | (setq n 2) | ||
| 2716 | (setq n 1)) | ||
| 2717 | ;; If we found another end-of-stmt | ||
| 2718 | (if (not (apply re-search term nil t n nil)) | ||
| 2719 | (setq arg 0) | ||
| 2720 | ;; count it if we're not in a comment | ||
| 2721 | (unless (nth 7 (syntax-ppss)) | ||
| 2722 | (setq arg (- arg (sql-signum arg)))))) | ||
| 2723 | (goto-char (if (match-data) | ||
| 2724 | (match-end 0) | ||
| 2725 | here)))) | ||
| 2426 | 2726 | ||
| 2427 | ;;; Small functions | 2727 | ;;; Small functions |
| 2428 | 2728 | ||
| @@ -2456,7 +2756,7 @@ the regular expression `comint-prompt-regexp', a buffer local variable." | |||
| 2456 | (defun sql-help-list-products (indent freep) | 2756 | (defun sql-help-list-products (indent freep) |
| 2457 | "Generate listing of products available for use under SQLi. | 2757 | "Generate listing of products available for use under SQLi. |
| 2458 | 2758 | ||
| 2459 | List products with :free-softare attribute set to FREEP. Indent | 2759 | List products with :free-software attribute set to FREEP. Indent |
| 2460 | each line with INDENT." | 2760 | each line with INDENT." |
| 2461 | 2761 | ||
| 2462 | (let (sqli-func doc) | 2762 | (let (sqli-func doc) |
| @@ -2649,7 +2949,7 @@ function like this: (sql-get-login 'user 'password 'database)." | |||
| 2649 | nil (append '(:number t) plist))))))) | 2949 | nil (append '(:number t) plist))))))) |
| 2650 | what)) | 2950 | what)) |
| 2651 | 2951 | ||
| 2652 | (defun sql-find-sqli-buffer (&optional product) | 2952 | (defun sql-find-sqli-buffer (&optional product connection) |
| 2653 | "Returns the name of the current default SQLi buffer or nil. | 2953 | "Returns the name of the current default SQLi buffer or nil. |
| 2654 | In order to qualify, the SQLi buffer must be alive, be in | 2954 | In order to qualify, the SQLi buffer must be alive, be in |
| 2655 | `sql-interactive-mode' and have a process." | 2955 | `sql-interactive-mode' and have a process." |
| @@ -2657,16 +2957,16 @@ In order to qualify, the SQLi buffer must be alive, be in | |||
| 2657 | (prod (or product sql-product))) | 2957 | (prod (or product sql-product))) |
| 2658 | (or | 2958 | (or |
| 2659 | ;; Current sql-buffer, if there is one. | 2959 | ;; Current sql-buffer, if there is one. |
| 2660 | (and (sql-buffer-live-p buf prod) | 2960 | (and (sql-buffer-live-p buf prod connection) |
| 2661 | buf) | 2961 | buf) |
| 2662 | ;; Global sql-buffer | 2962 | ;; Global sql-buffer |
| 2663 | (and (setq buf (default-value 'sql-buffer)) | 2963 | (and (setq buf (default-value 'sql-buffer)) |
| 2664 | (sql-buffer-live-p buf prod) | 2964 | (sql-buffer-live-p buf prod connection) |
| 2665 | buf) | 2965 | buf) |
| 2666 | ;; Look thru each buffer | 2966 | ;; Look thru each buffer |
| 2667 | (car (apply 'append | 2967 | (car (apply 'append |
| 2668 | (mapcar (lambda (b) | 2968 | (mapcar (lambda (b) |
| 2669 | (and (sql-buffer-live-p b prod) | 2969 | (and (sql-buffer-live-p b prod connection) |
| 2670 | (list (buffer-name b)))) | 2970 | (list (buffer-name b)))) |
| 2671 | (buffer-list))))))) | 2971 | (buffer-list))))))) |
| 2672 | 2972 | ||
| @@ -2722,7 +3022,8 @@ If you call it from anywhere else, it sets the global copy of | |||
| 2722 | This is the buffer SQL strings are sent to. It is stored in the | 3022 | This is the buffer SQL strings are sent to. It is stored in the |
| 2723 | variable `sql-buffer'. See `sql-help' on how to create such a buffer." | 3023 | variable `sql-buffer'. See `sql-help' on how to create such a buffer." |
| 2724 | (interactive) | 3024 | (interactive) |
| 2725 | (if (null (buffer-live-p (get-buffer sql-buffer))) | 3025 | (if (or (null sql-buffer) |
| 3026 | (null (buffer-live-p (get-buffer sql-buffer)))) | ||
| 2726 | (message "%s has no SQLi buffer set." (buffer-name (current-buffer))) | 3027 | (message "%s has no SQLi buffer set." (buffer-name (current-buffer))) |
| 2727 | (if (null (get-buffer-process sql-buffer)) | 3028 | (if (null (get-buffer-process sql-buffer)) |
| 2728 | (message "Buffer %s has no process." sql-buffer) | 3029 | (message "Buffer %s has no process." sql-buffer) |
| @@ -2932,37 +3233,58 @@ Allows the suppression of continuation prompts.") | |||
| 2932 | 3233 | ||
| 2933 | ;;; Strip out continuation prompts | 3234 | ;;; Strip out continuation prompts |
| 2934 | 3235 | ||
| 3236 | (defvar sql-preoutput-hold nil) | ||
| 3237 | |||
| 2935 | (defun sql-interactive-remove-continuation-prompt (oline) | 3238 | (defun sql-interactive-remove-continuation-prompt (oline) |
| 2936 | "Strip out continuation prompts out of the OLINE. | 3239 | "Strip out continuation prompts out of the OLINE. |
| 2937 | 3240 | ||
| 2938 | Added to the `comint-preoutput-filter-functions' hook in a SQL | 3241 | Added to the `comint-preoutput-filter-functions' hook in a SQL |
| 2939 | interactive buffer. If `sql-outut-newline-count' is greater than | 3242 | interactive buffer. If `sql-output-newline-count' is greater than |
| 2940 | zero, then an output line matching the continuation prompt is filtered | 3243 | zero, then an output line matching the continuation prompt is filtered |
| 2941 | out. If the count is one, then the prompt is replaced with a newline | 3244 | out. If the count is zero, then a newline is inserted into the output |
| 2942 | to force the output from the query to appear on a new line." | 3245 | to force the output from the query to appear on a new line. |
| 2943 | (if (and sql-prompt-cont-regexp | 3246 | |
| 2944 | sql-output-newline-count | 3247 | The complication to this filter is that the continuation prompts |
| 2945 | (numberp sql-output-newline-count) | 3248 | may arrive in multiple chunks. If they do, then the function |
| 2946 | (>= sql-output-newline-count 1)) | 3249 | saves any unfiltered output in a buffer and prepends that buffer |
| 2947 | (progn | 3250 | to the next chunk to properly match the broken-up prompt. |
| 2948 | (while (and oline | 3251 | |
| 2949 | sql-output-newline-count | 3252 | If the filter gets confused, it should reset and stop filtering |
| 2950 | (> sql-output-newline-count 0) | 3253 | to avoid deleting non-prompt output." |
| 2951 | (string-match sql-prompt-cont-regexp oline)) | 3254 | |
| 2952 | 3255 | (let (did-filter) | |
| 2953 | (setq oline | 3256 | (setq oline (concat (or sql-preoutput-hold "") oline) |
| 2954 | (replace-match (if (and | 3257 | sql-preoutput-hold nil) |
| 2955 | (= 1 sql-output-newline-count) | 3258 | |
| 2956 | sql-output-by-send) | 3259 | (if (and comint-prompt-regexp |
| 2957 | "\n" "") | 3260 | (integerp sql-output-newline-count) |
| 2958 | nil nil oline) | 3261 | (>= sql-output-newline-count 1)) |
| 2959 | sql-output-newline-count | 3262 | (progn |
| 2960 | (1- sql-output-newline-count))) | 3263 | (while (and (not (string= oline "")) |
| 2961 | (if (= sql-output-newline-count 0) | 3264 | (> sql-output-newline-count 0) |
| 2962 | (setq sql-output-newline-count nil)) | 3265 | (string-match comint-prompt-regexp oline) |
| 2963 | (setq sql-output-by-send nil)) | 3266 | (= (match-beginning 0) 0)) |
| 2964 | (setq sql-output-newline-count nil)) | 3267 | |
| 2965 | oline) | 3268 | (setq oline (replace-match "" nil nil oline) |
| 3269 | sql-output-newline-count (1- sql-output-newline-count) | ||
| 3270 | did-filter t)) | ||
| 3271 | |||
| 3272 | (if (= sql-output-newline-count 0) | ||
| 3273 | (setq sql-output-newline-count nil | ||
| 3274 | oline (concat "\n" oline) | ||
| 3275 | sql-output-by-send nil) | ||
| 3276 | |||
| 3277 | (setq sql-preoutput-hold oline | ||
| 3278 | oline "")) | ||
| 3279 | |||
| 3280 | (unless did-filter | ||
| 3281 | (setq oline (or sql-preoutput-hold "") | ||
| 3282 | sql-preoutput-hold nil | ||
| 3283 | sql-output-newline-count nil))) | ||
| 3284 | |||
| 3285 | (setq sql-output-newline-count nil)) | ||
| 3286 | |||
| 3287 | oline)) | ||
| 2966 | 3288 | ||
| 2967 | ;;; Sending the region to the SQLi buffer. | 3289 | ;;; Sending the region to the SQLi buffer. |
| 2968 | 3290 | ||
| @@ -3066,16 +3388,35 @@ If given the optional parameter VALUE, sets | |||
| 3066 | 3388 | ||
| 3067 | ;;; Redirect output functions | 3389 | ;;; Redirect output functions |
| 3068 | 3390 | ||
| 3069 | (defun sql-redirect (command combuf &optional outbuf save-prior) | 3391 | (defvar sql-debug-redirect nil |
| 3392 | "If non-nil, display messages related to the use of redirection.") | ||
| 3393 | |||
| 3394 | (defun sql-str-literal (s) | ||
| 3395 | (concat "'" (replace-regexp-in-string "[']" "''" s) "'")) | ||
| 3396 | |||
| 3397 | (defun sql-redirect (sqlbuf command &optional outbuf save-prior) | ||
| 3070 | "Execute the SQL command and send output to OUTBUF. | 3398 | "Execute the SQL command and send output to OUTBUF. |
| 3071 | 3399 | ||
| 3072 | COMBUF must be an active SQL interactive buffer. OUTBUF may be | 3400 | SQLBUF must be an active SQL interactive buffer. OUTBUF may be |
| 3073 | an existing buffer, or the name of a non-existing buffer. If | 3401 | an existing buffer, or the name of a non-existing buffer. If |
| 3074 | omitted the output is sent to a temporary buffer which will be | 3402 | omitted the output is sent to a temporary buffer which will be |
| 3075 | killed after the command completes. COMMAND should be a string | 3403 | killed after the command completes. COMMAND should be a string |
| 3076 | of commands accepted by the SQLi program." | 3404 | of commands accepted by the SQLi program. COMMAND may also be a |
| 3077 | 3405 | list of SQLi command strings." | |
| 3078 | (with-current-buffer combuf | 3406 | |
| 3407 | (let* ((visible (and outbuf | ||
| 3408 | (not (string= " " (substring outbuf 0 1)))))) | ||
| 3409 | (when visible | ||
| 3410 | (message "Executing SQL command...")) | ||
| 3411 | (if (consp command) | ||
| 3412 | (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior)) | ||
| 3413 | command) | ||
| 3414 | (sql-redirect-one sqlbuf command outbuf save-prior)) | ||
| 3415 | (when visible | ||
| 3416 | (message "Executing SQL command...done")))) | ||
| 3417 | |||
| 3418 | (defun sql-redirect-one (sqlbuf command outbuf save-prior) | ||
| 3419 | (with-current-buffer sqlbuf | ||
| 3079 | (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*"))) | 3420 | (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*"))) |
| 3080 | (proc (get-buffer-process (current-buffer))) | 3421 | (proc (get-buffer-process (current-buffer))) |
| 3081 | (comint-prompt-regexp (sql-get-product-feature sql-product | 3422 | (comint-prompt-regexp (sql-get-product-feature sql-product |
| @@ -3090,12 +3431,13 @@ of commands accepted by the SQLi program." | |||
| 3090 | (insert "\n")) | 3431 | (insert "\n")) |
| 3091 | (setq start (point))) | 3432 | (setq start (point))) |
| 3092 | 3433 | ||
| 3434 | (when sql-debug-redirect | ||
| 3435 | (message ">>SQL> %S" command)) | ||
| 3436 | |||
| 3093 | ;; Run the command | 3437 | ;; Run the command |
| 3094 | (message "Executing SQL command...") | ||
| 3095 | (comint-redirect-send-command-to-process command buf proc nil t) | 3438 | (comint-redirect-send-command-to-process command buf proc nil t) |
| 3096 | (while (null comint-redirect-completed) | 3439 | (while (null comint-redirect-completed) |
| 3097 | (accept-process-output nil 1)) | 3440 | (accept-process-output nil 1)) |
| 3098 | (message "Executing SQL command...done") | ||
| 3099 | 3441 | ||
| 3100 | ;; Clean up the output results | 3442 | ;; Clean up the output results |
| 3101 | (with-current-buffer buf | 3443 | (with-current-buffer buf |
| @@ -3107,12 +3449,16 @@ of commands accepted by the SQLi program." | |||
| 3107 | (goto-char start) | 3449 | (goto-char start) |
| 3108 | (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) | 3450 | (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) |
| 3109 | (delete-region (match-beginning 0) (match-end 0))) | 3451 | (delete-region (match-beginning 0) (match-end 0))) |
| 3452 | ;; Remove Ctrl-Ms | ||
| 3453 | (goto-char start) | ||
| 3454 | (while (re-search-forward "\r+$" nil t) | ||
| 3455 | (replace-match "" t t)) | ||
| 3110 | (goto-char start))))) | 3456 | (goto-char start))))) |
| 3111 | 3457 | ||
| 3112 | (defun sql-redirect-value (command combuf regexp &optional regexp-groups) | 3458 | (defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups) |
| 3113 | "Execute the SQL command and return part of result. | 3459 | "Execute the SQL command and return part of result. |
| 3114 | 3460 | ||
| 3115 | COMBUF must be an active SQL interactive buffer. COMMAND should | 3461 | SQLBUF must be an active SQL interactive buffer. COMMAND should |
| 3116 | be a string of commands accepted by the SQLi program. From the | 3462 | be a string of commands accepted by the SQLi program. From the |
| 3117 | output, the REGEXP is repeatedly matched and the list of | 3463 | output, the REGEXP is repeatedly matched and the list of |
| 3118 | REGEXP-GROUPS submatches is returned. This behaves much like | 3464 | REGEXP-GROUPS submatches is returned. This behaves much like |
| @@ -3122,18 +3468,19 @@ for each match." | |||
| 3122 | 3468 | ||
| 3123 | (let ((outbuf " *SQL-Redirect-values*") | 3469 | (let ((outbuf " *SQL-Redirect-values*") |
| 3124 | (results nil)) | 3470 | (results nil)) |
| 3125 | (sql-redirect command combuf outbuf nil) | 3471 | (sql-redirect sqlbuf command outbuf nil) |
| 3126 | (with-current-buffer outbuf | 3472 | (with-current-buffer outbuf |
| 3127 | (while (re-search-forward regexp nil t) | 3473 | (while (re-search-forward regexp nil t) |
| 3128 | (push | 3474 | (push |
| 3129 | (cond | 3475 | (cond |
| 3130 | ;; no groups-return all of them | 3476 | ;; no groups-return all of them |
| 3131 | ((null regexp-groups) | 3477 | ((null regexp-groups) |
| 3132 | (let ((i 1) | 3478 | (let ((i (/ (length (match-data)) 2)) |
| 3133 | (r nil)) | 3479 | (r nil)) |
| 3134 | (while (match-beginning i) | 3480 | (while (> i 0) |
| 3481 | (setq i (1- i)) | ||
| 3135 | (push (match-string i) r)) | 3482 | (push (match-string i) r)) |
| 3136 | (nreverse r))) | 3483 | r)) |
| 3137 | ;; one group specified | 3484 | ;; one group specified |
| 3138 | ((numberp regexp-groups) | 3485 | ((numberp regexp-groups) |
| 3139 | (match-string regexp-groups)) | 3486 | (match-string regexp-groups)) |
| @@ -3152,10 +3499,14 @@ for each match." | |||
| 3152 | (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" | 3499 | (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" |
| 3153 | regexp-groups))) | 3500 | regexp-groups))) |
| 3154 | results))) | 3501 | results))) |
| 3155 | (nreverse results))) | ||
| 3156 | 3502 | ||
| 3157 | (defun sql-execute (sqlbuf outbuf command arg) | 3503 | (when sql-debug-redirect |
| 3158 | "Executes a command in a SQL interacive buffer and captures the output. | 3504 | (message ">>SQL> = %S" (reverse results))) |
| 3505 | |||
| 3506 | (nreverse results))) | ||
| 3507 | |||
| 3508 | (defun sql-execute (sqlbuf outbuf command enhanced arg) | ||
| 3509 | "Executes a command in a SQL interactive buffer and captures the output. | ||
| 3159 | 3510 | ||
| 3160 | The commands are run in SQLBUF and the output saved in OUTBUF. | 3511 | The commands are run in SQLBUF and the output saved in OUTBUF. |
| 3161 | COMMAND must be a string, a function or a list of such elements. | 3512 | COMMAND must be a string, a function or a list of such elements. |
| @@ -3168,9 +3519,9 @@ buffer is popped into a view window. " | |||
| 3168 | (lambda (c) | 3519 | (lambda (c) |
| 3169 | (cond | 3520 | (cond |
| 3170 | ((stringp c) | 3521 | ((stringp c) |
| 3171 | (sql-redirect (if arg (format c arg) c) sqlbuf outbuf) t) | 3522 | (sql-redirect sqlbuf (if arg (format c arg) c) outbuf) t) |
| 3172 | ((functionp c) | 3523 | ((functionp c) |
| 3173 | (apply c sqlbuf outbuf arg)) | 3524 | (apply c sqlbuf outbuf enhanced arg nil)) |
| 3174 | (t (error "Unknown sql-execute item %s" c)))) | 3525 | (t (error "Unknown sql-execute item %s" c)))) |
| 3175 | (if (consp command) command (cons command nil))) | 3526 | (if (consp command) command (cons command nil))) |
| 3176 | 3527 | ||
| @@ -3197,14 +3548,92 @@ buffer is popped into a view window. " | |||
| 3197 | (setq command (if enhanced | 3548 | (setq command (if enhanced |
| 3198 | (cdr command) | 3549 | (cdr command) |
| 3199 | (car command)))) | 3550 | (car command)))) |
| 3200 | (sql-execute sqlbuf outbuf command arg))) | 3551 | (sql-execute sqlbuf outbuf command enhanced arg))) |
| 3552 | |||
| 3553 | (defvar sql-completion-object nil | ||
| 3554 | "A list of database objects used for completion. | ||
| 3555 | |||
| 3556 | The list is maintained in SQL interactive buffers.") | ||
| 3557 | |||
| 3558 | (defvar sql-completion-column nil | ||
| 3559 | "A list of column names used for completion. | ||
| 3560 | |||
| 3561 | The list is maintained in SQL interactive buffers.") | ||
| 3562 | |||
| 3563 | (defun sql-build-completions-1 (schema completion-list feature) | ||
| 3564 | "Generate a list of objects in the database for use as completions." | ||
| 3565 | (let ((f (sql-get-product-feature sql-product feature))) | ||
| 3566 | (when f | ||
| 3567 | (set completion-list | ||
| 3568 | (let (cl) | ||
| 3569 | (dolist (e (append (symbol-value completion-list) | ||
| 3570 | (apply f (current-buffer) (cons schema nil))) | ||
| 3571 | cl) | ||
| 3572 | (unless (member e cl) (setq cl (cons e cl)))) | ||
| 3573 | (sort cl (function string<))))))) | ||
| 3574 | |||
| 3575 | (defun sql-build-completions (schema) | ||
| 3576 | "Generate a list of names in the database for use as completions." | ||
| 3577 | (sql-build-completions-1 schema 'sql-completion-object :completion-object) | ||
| 3578 | (sql-build-completions-1 schema 'sql-completion-column :completion-column)) | ||
| 3579 | |||
| 3580 | (defvar sql-completion-sqlbuf nil) | ||
| 3581 | |||
| 3582 | (defun sql-try-completion (string collection &optional predicate) | ||
| 3583 | (when sql-completion-sqlbuf | ||
| 3584 | (with-current-buffer sql-completion-sqlbuf | ||
| 3585 | (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string) | ||
| 3586 | (downcase (match-string 1 string))))) | ||
| 3587 | |||
| 3588 | ;; If we haven't loaded any object name yet, load local schema | ||
| 3589 | (unless sql-completion-object | ||
| 3590 | (sql-build-completions nil)) | ||
| 3591 | |||
| 3592 | ;; If they want another schema, load it if we haven't yet | ||
| 3593 | (when schema | ||
| 3594 | (let ((schema-dot (concat schema ".")) | ||
| 3595 | (schema-len (1+ (length schema))) | ||
| 3596 | (names sql-completion-object) | ||
| 3597 | has-schema) | ||
| 3598 | |||
| 3599 | (while (and (not has-schema) names) | ||
| 3600 | (setq has-schema (and | ||
| 3601 | (>= (length (car names)) schema-len) | ||
| 3602 | (string= schema-dot | ||
| 3603 | (downcase (substring (car names) | ||
| 3604 | 0 schema-len)))) | ||
| 3605 | names (cdr names))) | ||
| 3606 | (unless has-schema | ||
| 3607 | (sql-build-completions schema))))) | ||
| 3608 | |||
| 3609 | ;; Try to find the completion | ||
| 3610 | (cond | ||
| 3611 | ((not predicate) | ||
| 3612 | (try-completion string sql-completion-object)) | ||
| 3613 | ((eq predicate t) | ||
| 3614 | (all-completions string sql-completion-object)) | ||
| 3615 | ((eq predicate 'lambda) | ||
| 3616 | (test-completion string sql-completion-object)) | ||
| 3617 | ((eq (car predicate) 'boundaries) | ||
| 3618 | (completion-boundaries string sql-completion-object nil (cdr predicate))))))) | ||
| 3201 | 3619 | ||
| 3202 | (defun sql-read-table-name (prompt) | 3620 | (defun sql-read-table-name (prompt) |
| 3203 | "Read the name of a database table." | 3621 | "Read the name of a database table." |
| 3204 | ;; TODO: Fetch table/view names from database and provide completion. | 3622 | (let* ((tname |
| 3205 | ;; Also implement thing-at-point if the buffer has valid names in it | 3623 | (and (buffer-local-value 'sql-contains-names (current-buffer)) |
| 3206 | ;; (i.e. sql-mode, sql-interactive-mode, or sql-list-all buffers) | 3624 | (thing-at-point-looking-at |
| 3207 | (read-from-minibuffer prompt)) | 3625 | (concat "\\_<\\sw\\(:?\\sw\\|\\s_\\)*" |
| 3626 | "\\(?:[.]+\\sw\\(?:\\sw\\|\\s_\\)*\\)*\\_>")) | ||
| 3627 | (buffer-substring-no-properties (match-beginning 0) | ||
| 3628 | (match-end 0)))) | ||
| 3629 | (sql-completion-sqlbuf (sql-find-sqli-buffer)) | ||
| 3630 | (product (with-current-buffer sql-completion-sqlbuf sql-product)) | ||
| 3631 | (completion-ignore-case t)) | ||
| 3632 | |||
| 3633 | (if (sql-get-product-feature product :completion-object) | ||
| 3634 | (completing-read prompt (function sql-try-completion) | ||
| 3635 | nil nil tname) | ||
| 3636 | (read-from-minibuffer prompt tname)))) | ||
| 3208 | 3637 | ||
| 3209 | (defun sql-list-all (&optional enhanced) | 3638 | (defun sql-list-all (&optional enhanced) |
| 3210 | "List all database objects." | 3639 | "List all database objects." |
| @@ -3212,7 +3641,11 @@ buffer is popped into a view window. " | |||
| 3212 | (let ((sqlbuf (sql-find-sqli-buffer))) | 3641 | (let ((sqlbuf (sql-find-sqli-buffer))) |
| 3213 | (unless sqlbuf | 3642 | (unless sqlbuf |
| 3214 | (error "No SQL interactive buffer found")) | 3643 | (error "No SQL interactive buffer found")) |
| 3215 | (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil))) | 3644 | (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil) |
| 3645 | (with-current-buffer sqlbuf | ||
| 3646 | ;; Contains the name of database objects | ||
| 3647 | (set (make-local-variable 'sql-contains-names) t) | ||
| 3648 | (set (make-local-variable 'sql-buffer) sqlbuf)))) | ||
| 3216 | 3649 | ||
| 3217 | (defun sql-list-table (name &optional enhanced) | 3650 | (defun sql-list-table (name &optional enhanced) |
| 3218 | "List the details of a database table. " | 3651 | "List the details of a database table. " |
| @@ -3226,7 +3659,6 @@ buffer is popped into a view window. " | |||
| 3226 | (error "No table name specified")) | 3659 | (error "No table name specified")) |
| 3227 | (sql-execute-feature sqlbuf (format "*List %s*" name) | 3660 | (sql-execute-feature sqlbuf (format "*List %s*" name) |
| 3228 | :list-table enhanced name))) | 3661 | :list-table enhanced name))) |
| 3229 | |||
| 3230 | 3662 | ||
| 3231 | 3663 | ||
| 3232 | ;;; SQL mode -- uses SQL interactive mode | 3664 | ;;; SQL mode -- uses SQL interactive mode |
| @@ -3277,6 +3709,8 @@ you must tell Emacs. Here's how to do that in your `~/.emacs' file: | |||
| 3277 | (set (make-local-variable 'paragraph-start) "[\n\f]") | 3709 | (set (make-local-variable 'paragraph-start) "[\n\f]") |
| 3278 | ;; Abbrevs | 3710 | ;; Abbrevs |
| 3279 | (setq abbrev-all-caps 1) | 3711 | (setq abbrev-all-caps 1) |
| 3712 | ;; Contains the name of database objects | ||
| 3713 | (set (make-local-variable 'sql-contains-names) t) | ||
| 3280 | ;; Catch changes to sql-product and highlight accordingly | 3714 | ;; Catch changes to sql-product and highlight accordingly |
| 3281 | (add-hook 'hack-local-variables-hook 'sql-highlight-product t t)) | 3715 | (add-hook 'hack-local-variables-hook 'sql-highlight-product t t)) |
| 3282 | 3716 | ||
| @@ -3362,7 +3796,7 @@ you entered, right above the output it created. | |||
| 3362 | sql-product)) | 3796 | sql-product)) |
| 3363 | 3797 | ||
| 3364 | ;; Setup the mode. | 3798 | ;; Setup the mode. |
| 3365 | (setq major-mode 'sql-interactive-mode) ;FIXME: Use define-derived-mode. | 3799 | (setq major-mode 'sql-interactive-mode) |
| 3366 | (setq mode-name | 3800 | (setq mode-name |
| 3367 | (concat "SQLi[" (or (sql-get-product-feature sql-product :name) | 3801 | (concat "SQLi[" (or (sql-get-product-feature sql-product :name) |
| 3368 | (symbol-name sql-product)) "]")) | 3802 | (symbol-name sql-product)) "]")) |
| @@ -3385,9 +3819,18 @@ you entered, right above the output it created. | |||
| 3385 | (setq abbrev-all-caps 1) | 3819 | (setq abbrev-all-caps 1) |
| 3386 | ;; Exiting the process will call sql-stop. | 3820 | ;; Exiting the process will call sql-stop. |
| 3387 | (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop) | 3821 | (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop) |
| 3388 | ;; Save the connection name | 3822 | ;; Save the connection and login params |
| 3389 | (make-local-variable 'sql-connection) | 3823 | (set (make-local-variable 'sql-user) sql-user) |
| 3390 | ;; Create a usefull name for renaming this buffer later. | 3824 | (set (make-local-variable 'sql-database) sql-database) |
| 3825 | (set (make-local-variable 'sql-server) sql-server) | ||
| 3826 | (set (make-local-variable 'sql-port) sql-port) | ||
| 3827 | (set (make-local-variable 'sql-connection) sql-connection) | ||
| 3828 | ;; Contains the name of database objects | ||
| 3829 | (set (make-local-variable 'sql-contains-names) t) | ||
| 3830 | ;; Keep track of existing object names | ||
| 3831 | (set (make-local-variable 'sql-completion-object) nil) | ||
| 3832 | (set (make-local-variable 'sql-completion-column) nil) | ||
| 3833 | ;; Create a useful name for renaming this buffer later. | ||
| 3391 | (set (make-local-variable 'sql-alternate-buffer-name) | 3834 | (set (make-local-variable 'sql-alternate-buffer-name) |
| 3392 | (sql-make-alternate-buffer-name)) | 3835 | (sql-make-alternate-buffer-name)) |
| 3393 | ;; User stuff. Initialize before the hook. | 3836 | ;; User stuff. Initialize before the hook. |
| @@ -3398,6 +3841,7 @@ you entered, right above the output it created. | |||
| 3398 | (set (make-local-variable 'sql-prompt-cont-regexp) | 3841 | (set (make-local-variable 'sql-prompt-cont-regexp) |
| 3399 | (sql-get-product-feature sql-product :prompt-cont-regexp)) | 3842 | (sql-get-product-feature sql-product :prompt-cont-regexp)) |
| 3400 | (make-local-variable 'sql-output-newline-count) | 3843 | (make-local-variable 'sql-output-newline-count) |
| 3844 | (make-local-variable 'sql-preoutput-hold) | ||
| 3401 | (make-local-variable 'sql-output-by-send) | 3845 | (make-local-variable 'sql-output-by-send) |
| 3402 | (add-hook 'comint-preoutput-filter-functions | 3846 | (add-hook 'comint-preoutput-filter-functions |
| 3403 | 'sql-interactive-remove-continuation-prompt nil t) | 3847 | 'sql-interactive-remove-continuation-prompt nil t) |
| @@ -3450,7 +3894,7 @@ Sentinels will always get the two parameters PROCESS and EVENT." | |||
| 3450 | nil t initial 'sql-connection-history default))) | 3894 | nil t initial 'sql-connection-history default))) |
| 3451 | 3895 | ||
| 3452 | ;;;###autoload | 3896 | ;;;###autoload |
| 3453 | (defun sql-connect (connection) | 3897 | (defun sql-connect (connection &optional new-name) |
| 3454 | "Connect to an interactive session using CONNECTION settings. | 3898 | "Connect to an interactive session using CONNECTION settings. |
| 3455 | 3899 | ||
| 3456 | See `sql-connection-alist' to see how to define connections and | 3900 | See `sql-connection-alist' to see how to define connections and |
| @@ -3462,7 +3906,8 @@ is specified in the connection settings." | |||
| 3462 | ;; Prompt for the connection from those defined in the alist | 3906 | ;; Prompt for the connection from those defined in the alist |
| 3463 | (interactive | 3907 | (interactive |
| 3464 | (if sql-connection-alist | 3908 | (if sql-connection-alist |
| 3465 | (list (sql-read-connection "Connection: " nil '(nil))) | 3909 | (list (sql-read-connection "Connection: " nil '(nil)) |
| 3910 | current-prefix-arg) | ||
| 3466 | nil)) | 3911 | nil)) |
| 3467 | 3912 | ||
| 3468 | ;; Are there connections defined | 3913 | ;; Are there connections defined |
| @@ -3500,14 +3945,15 @@ is specified in the connection settings." | |||
| 3500 | (unless (member token set-params) | 3945 | (unless (member token set-params) |
| 3501 | (if plist | 3946 | (if plist |
| 3502 | (cons token plist) | 3947 | (cons token plist) |
| 3503 | token))))) | 3948 | token)))))) |
| 3504 | ;; Remember the connection | ||
| 3505 | (sql-connection connection)) | ||
| 3506 | 3949 | ||
| 3507 | ;; Set the remaining parameters and start the | 3950 | ;; Set the remaining parameters and start the |
| 3508 | ;; interactive session | 3951 | ;; interactive session |
| 3509 | (eval `(let ((,param-var ',rem-params)) | 3952 | (eval `(let ((sql-connection ,connection) |
| 3510 | (sql-product-interactive sql-product))))) | 3953 | (,param-var ',rem-params)) |
| 3954 | (sql-product-interactive sql-product | ||
| 3955 | new-name))))) | ||
| 3956 | |||
| 3511 | (message "SQL Connection <%s> does not exist" connection) | 3957 | (message "SQL Connection <%s> does not exist" connection) |
| 3512 | nil))) | 3958 | nil))) |
| 3513 | (message "No SQL Connections defined") | 3959 | (message "No SQL Connections defined") |
| @@ -3521,39 +3967,51 @@ optionally is saved to the user's init file." | |||
| 3521 | 3967 | ||
| 3522 | (interactive "sNew connection name: ") | 3968 | (interactive "sNew connection name: ") |
| 3523 | 3969 | ||
| 3524 | (if sql-connection | 3970 | (unless (derived-mode-p 'sql-interactive-mode) |
| 3525 | (message "This session was started by a connection; it's already been saved.") | 3971 | (error "Not in a SQL interactive mode!")) |
| 3526 | 3972 | ||
| 3527 | (let ((login (sql-get-product-feature sql-product :sqli-login)) | 3973 | ;; Capture the buffer local settings |
| 3528 | (alist sql-connection-alist) | 3974 | (let* ((buf (current-buffer)) |
| 3529 | connect) | 3975 | (connection (buffer-local-value 'sql-connection buf)) |
| 3530 | 3976 | (product (buffer-local-value 'sql-product buf)) | |
| 3531 | ;; Remove the existing connection if the user says so | 3977 | (user (buffer-local-value 'sql-user buf)) |
| 3532 | (when (and (assoc name alist) | 3978 | (database (buffer-local-value 'sql-database buf)) |
| 3533 | (yes-or-no-p (format "Replace connection definition <%s>? " name))) | 3979 | (server (buffer-local-value 'sql-server buf)) |
| 3534 | (setq alist (assq-delete-all name alist))) | 3980 | (port (buffer-local-value 'sql-port buf))) |
| 3535 | 3981 | ||
| 3536 | ;; Add the new connection if it doesn't exist | 3982 | (if connection |
| 3537 | (if (assoc name alist) | 3983 | (message "This session was started by a connection; it's already been saved.") |
| 3538 | (message "Connection <%s> already exists" name) | 3984 | |
| 3539 | (setq connect | 3985 | (let ((login (sql-get-product-feature product :sqli-login)) |
| 3540 | (append (list name) | 3986 | (alist sql-connection-alist) |
| 3541 | (sql-for-each-login | 3987 | connect) |
| 3542 | `(product ,@login) | 3988 | |
| 3543 | (lambda (token _plist) | 3989 | ;; Remove the existing connection if the user says so |
| 3544 | (cond | 3990 | (when (and (assoc name alist) |
| 3545 | ((eq token 'product) `(sql-product ',sql-product)) | 3991 | (yes-or-no-p (format "Replace connection definition <%s>? " name))) |
| 3546 | ((eq token 'user) `(sql-user ,sql-user)) | 3992 | (setq alist (assq-delete-all name alist))) |
| 3547 | ((eq token 'database) `(sql-database ,sql-database)) | 3993 | |
| 3548 | ((eq token 'server) `(sql-server ,sql-server)) | 3994 | ;; Add the new connection if it doesn't exist |
| 3549 | ((eq token 'port) `(sql-port ,sql-port))))))) | 3995 | (if (assoc name alist) |
| 3550 | 3996 | (message "Connection <%s> already exists" name) | |
| 3551 | (setq alist (append alist (list connect))) | 3997 | (setq connect |
| 3552 | 3998 | (append (list name) | |
| 3553 | ;; confirm whether we want to save the connections | 3999 | (sql-for-each-login |
| 3554 | (if (yes-or-no-p "Save the connections for future sessions? ") | 4000 | `(product ,@login) |
| 3555 | (customize-save-variable 'sql-connection-alist alist) | 4001 | (lambda (token _plist) |
| 3556 | (customize-set-variable 'sql-connection-alist alist)))))) | 4002 | (cond |
| 4003 | ((eq token 'product) `(sql-product ',product)) | ||
| 4004 | ((eq token 'user) `(sql-user ,user)) | ||
| 4005 | ((eq token 'database) `(sql-database ,database)) | ||
| 4006 | ((eq token 'server) `(sql-server ,server)) | ||
| 4007 | ((eq token 'port) `(sql-port ,port))))))) | ||
| 4008 | |||
| 4009 | (setq alist (append alist (list connect))) | ||
| 4010 | |||
| 4011 | ;; confirm whether we want to save the connections | ||
| 4012 | (if (yes-or-no-p "Save the connections for future sessions? ") | ||
| 4013 | (customize-save-variable 'sql-connection-alist alist) | ||
| 4014 | (customize-set-variable 'sql-connection-alist alist))))))) | ||
| 3557 | 4015 | ||
| 3558 | (defun sql-connection-menu-filter (tail) | 4016 | (defun sql-connection-menu-filter (tail) |
| 3559 | "Generates menu entries for using each connection." | 4017 | "Generates menu entries for using each connection." |
| @@ -3561,7 +4019,10 @@ optionally is saved to the user's init file." | |||
| 3561 | (mapcar | 4019 | (mapcar |
| 3562 | (lambda (conn) | 4020 | (lambda (conn) |
| 3563 | (vector | 4021 | (vector |
| 3564 | (format "Connection <%s>" (car conn)) | 4022 | (format "Connection <%s>\t%s" (car conn) |
| 4023 | (let ((sql-user "") (sql-database "") | ||
| 4024 | (sql-server "") (sql-port 0)) | ||
| 4025 | (eval `(let ,(cdr conn) (sql-make-alternate-buffer-name))))) | ||
| 3565 | (list 'sql-connect (car conn)) | 4026 | (list 'sql-connect (car conn)) |
| 3566 | t)) | 4027 | t)) |
| 3567 | sql-connection-alist) | 4028 | sql-connection-alist) |
| @@ -3599,10 +4060,10 @@ the call to \\[sql-product-interactive] with | |||
| 3599 | ;; Get the value of product that we need | 4060 | ;; Get the value of product that we need |
| 3600 | (setq product | 4061 | (setq product |
| 3601 | (cond | 4062 | (cond |
| 3602 | ((and product ; Product specified | ||
| 3603 | (symbolp product)) product) | ||
| 3604 | ((= (prefix-numeric-value product) 4) ; C-u, prompt for product | 4063 | ((= (prefix-numeric-value product) 4) ; C-u, prompt for product |
| 3605 | (sql-read-product "SQL product: " sql-product)) | 4064 | (sql-read-product "SQL product: " sql-product)) |
| 4065 | ((and product ; Product specified | ||
| 4066 | (symbolp product)) product) | ||
| 3606 | (t sql-product))) ; Default to sql-product | 4067 | (t sql-product))) ; Default to sql-product |
| 3607 | 4068 | ||
| 3608 | ;; If we have a product and it has a interactive mode | 4069 | ;; If we have a product and it has a interactive mode |
| @@ -3610,7 +4071,7 @@ the call to \\[sql-product-interactive] with | |||
| 3610 | (when (sql-get-product-feature product :sqli-comint-func) | 4071 | (when (sql-get-product-feature product :sqli-comint-func) |
| 3611 | ;; If no new name specified, try to pop to an active SQL | 4072 | ;; If no new name specified, try to pop to an active SQL |
| 3612 | ;; interactive for the same product | 4073 | ;; interactive for the same product |
| 3613 | (let ((buf (sql-find-sqli-buffer product))) | 4074 | (let ((buf (sql-find-sqli-buffer product sql-connection))) |
| 3614 | (if (and (not new-name) buf) | 4075 | (if (and (not new-name) buf) |
| 3615 | (pop-to-buffer buf) | 4076 | (pop-to-buffer buf) |
| 3616 | 4077 | ||
| @@ -3629,23 +4090,24 @@ the call to \\[sql-product-interactive] with | |||
| 3629 | (sql-get-product-feature product :sqli-options)) | 4090 | (sql-get-product-feature product :sqli-options)) |
| 3630 | 4091 | ||
| 3631 | ;; Set SQLi mode. | 4092 | ;; Set SQLi mode. |
| 3632 | (setq new-sqli-buffer (current-buffer)) | ||
| 3633 | (let ((sql-interactive-product product)) | 4093 | (let ((sql-interactive-product product)) |
| 3634 | (sql-interactive-mode)) | 4094 | (sql-interactive-mode)) |
| 3635 | 4095 | ||
| 3636 | ;; Set the new buffer name | 4096 | ;; Set the new buffer name |
| 4097 | (setq new-sqli-buffer (current-buffer)) | ||
| 3637 | (when new-name | 4098 | (when new-name |
| 3638 | (sql-rename-buffer new-name)) | 4099 | (sql-rename-buffer new-name)) |
| 3639 | |||
| 3640 | ;; Set `sql-buffer' in the new buffer and the start buffer | ||
| 3641 | (setq sql-buffer (buffer-name new-sqli-buffer)) | 4100 | (setq sql-buffer (buffer-name new-sqli-buffer)) |
| 4101 | |||
| 4102 | ;; Set `sql-buffer' in the start buffer | ||
| 3642 | (with-current-buffer start-buffer | 4103 | (with-current-buffer start-buffer |
| 3643 | (setq sql-buffer (buffer-name new-sqli-buffer)) | 4104 | (when (derived-mode-p 'sql-mode) |
| 3644 | (run-hooks 'sql-set-sqli-hook)) | 4105 | (setq sql-buffer (buffer-name new-sqli-buffer)) |
| 4106 | (run-hooks 'sql-set-sqli-hook))) | ||
| 3645 | 4107 | ||
| 3646 | ;; All done. | 4108 | ;; All done. |
| 3647 | (message "Login...done") | 4109 | (message "Login...done") |
| 3648 | (pop-to-buffer sql-buffer))))) | 4110 | (pop-to-buffer new-sqli-buffer))))) |
| 3649 | (message "No default SQL product defined. Set `sql-product'."))) | 4111 | (message "No default SQL product defined. Set `sql-product'."))) |
| 3650 | 4112 | ||
| 3651 | (defun sql-comint (product params) | 4113 | (defun sql-comint (product params) |
| @@ -3720,6 +4182,157 @@ The default comes from `process-coding-system-alist' and | |||
| 3720 | (setq parameter options)) | 4182 | (setq parameter options)) |
| 3721 | (sql-comint product parameter))) | 4183 | (sql-comint product parameter))) |
| 3722 | 4184 | ||
| 4185 | (defun sql-oracle-save-settings (sqlbuf) | ||
| 4186 | "Saves most SQL*Plus settings so they may be reset by \\[sql-redirect]." | ||
| 4187 | ;; Note: does not capture the following settings: | ||
| 4188 | ;; | ||
| 4189 | ;; APPINFO | ||
| 4190 | ;; BTITLE | ||
| 4191 | ;; COMPATIBILITY | ||
| 4192 | ;; COPYTYPECHECK | ||
| 4193 | ;; MARKUP | ||
| 4194 | ;; RELEASE | ||
| 4195 | ;; REPFOOTER | ||
| 4196 | ;; REPHEADER | ||
| 4197 | ;; SQLPLUSCOMPATIBILITY | ||
| 4198 | ;; TTITLE | ||
| 4199 | ;; USER | ||
| 4200 | ;; | ||
| 4201 | |||
| 4202 | (append | ||
| 4203 | ;; (apply 'concat (append | ||
| 4204 | ;; '("SET") | ||
| 4205 | |||
| 4206 | ;; option value... | ||
| 4207 | (sql-redirect-value | ||
| 4208 | sqlbuf | ||
| 4209 | (concat "SHOW ARRAYSIZE AUTOCOMMIT AUTOPRINT AUTORECOVERY AUTOTRACE" | ||
| 4210 | " CMDSEP COLSEP COPYCOMMIT DESCRIBE ECHO EDITFILE EMBEDDED" | ||
| 4211 | " ESCAPE FLAGGER FLUSH HEADING INSTANCE LINESIZE LNO LOBOFFSET" | ||
| 4212 | " LOGSOURCE LONG LONGCHUNKSIZE NEWPAGE NULL NUMFORMAT NUMWIDTH" | ||
| 4213 | " PAGESIZE PAUSE PNO RECSEP SERVEROUTPUT SHIFTINOUT SHOWMODE" | ||
| 4214 | " SPOOL SQLBLANKLINES SQLCASE SQLCODE SQLCONTINUE SQLNUMBER" | ||
| 4215 | " SQLPROMPT SUFFIX TAB TERMOUT TIMING TRIMOUT TRIMSPOOL VERIFY") | ||
| 4216 | "^.+$" | ||
| 4217 | "SET \\&") | ||
| 4218 | |||
| 4219 | ;; option "c" (hex xx) | ||
| 4220 | (sql-redirect-value | ||
| 4221 | sqlbuf | ||
| 4222 | (concat "SHOW BLOCKTERMINATOR CONCAT DEFINE SQLPREFIX SQLTERMINATOR" | ||
| 4223 | " UNDERLINE HEADSEP RECSEPCHAR") | ||
| 4224 | "^\\(.+\\) (hex ..)$" | ||
| 4225 | "SET \\1") | ||
| 4226 | |||
| 4227 | ;; FEDDBACK ON for 99 or more rows | ||
| 4228 | ;; feedback OFF | ||
| 4229 | (sql-redirect-value | ||
| 4230 | sqlbuf | ||
| 4231 | "SHOW FEEDBACK" | ||
| 4232 | "^\\(?:FEEDBACK ON for \\([[:digit:]]+\\) or more rows\\|feedback \\(OFF\\)\\)" | ||
| 4233 | "SET FEEDBACK \\1\\2") | ||
| 4234 | |||
| 4235 | ;; wrap : lines will be wrapped | ||
| 4236 | ;; wrap : lines will be truncated | ||
| 4237 | (list (concat "SET WRAP " | ||
| 4238 | (if (string= | ||
| 4239 | (car (sql-redirect-value | ||
| 4240 | sqlbuf | ||
| 4241 | "SHOW WRAP" | ||
| 4242 | "^wrap : lines will be \\(wrapped\\|truncated\\)" 1)) | ||
| 4243 | "wrapped") | ||
| 4244 | "ON" "OFF"))))) | ||
| 4245 | |||
| 4246 | (defun sql-oracle-restore-settings (sqlbuf saved-settings) | ||
| 4247 | "Restore the SQL*Plus settings in SAVED-SETTINGS." | ||
| 4248 | |||
| 4249 | ;; Remove any settings that haven't changed | ||
| 4250 | (mapc | ||
| 4251 | (lambda (one-cur-setting) | ||
| 4252 | (setq saved-settings (delete one-cur-setting saved-settings))) | ||
| 4253 | (sql-oracle-save-settings sqlbuf)) | ||
| 4254 | |||
| 4255 | ;; Restore the changed settings | ||
| 4256 | (sql-redirect sqlbuf saved-settings)) | ||
| 4257 | |||
| 4258 | (defun sql-oracle-list-all (sqlbuf outbuf enhanced table-name) | ||
| 4259 | ;; Query from USER_OBJECTS or ALL_OBJECTS | ||
| 4260 | (let ((settings (sql-oracle-save-settings sqlbuf)) | ||
| 4261 | (simple-sql | ||
| 4262 | (concat | ||
| 4263 | "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE " | ||
| 4264 | ", x.object_name AS SQL_EL_NAME " | ||
| 4265 | "FROM user_objects x " | ||
| 4266 | "WHERE x.object_type NOT LIKE '%% BODY' " | ||
| 4267 | "ORDER BY 2, 1;")) | ||
| 4268 | (enhanced-sql | ||
| 4269 | (concat | ||
| 4270 | "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE " | ||
| 4271 | ", x.owner ||'.'|| x.object_name AS SQL_EL_NAME " | ||
| 4272 | "FROM all_objects x " | ||
| 4273 | "WHERE x.object_type NOT LIKE '%% BODY' " | ||
| 4274 | "AND x.owner <> 'SYS' " | ||
| 4275 | "ORDER BY 2, 1;"))) | ||
| 4276 | |||
| 4277 | (sql-redirect sqlbuf | ||
| 4278 | (concat "SET LINESIZE 80 PAGESIZE 50000 TRIMOUT ON" | ||
| 4279 | " TAB OFF TIMING OFF FEEDBACK OFF")) | ||
| 4280 | |||
| 4281 | (sql-redirect sqlbuf | ||
| 4282 | (list "COLUMN SQL_EL_TYPE HEADING \"Type\" FORMAT A19" | ||
| 4283 | "COLUMN SQL_EL_NAME HEADING \"Name\"" | ||
| 4284 | (format "COLUMN SQL_EL_NAME FORMAT A%d" | ||
| 4285 | (if enhanced 60 35)))) | ||
| 4286 | |||
| 4287 | (sql-redirect sqlbuf | ||
| 4288 | (if enhanced enhanced-sql simple-sql) | ||
| 4289 | outbuf) | ||
| 4290 | |||
| 4291 | (sql-redirect sqlbuf | ||
| 4292 | '("COLUMN SQL_EL_NAME CLEAR" | ||
| 4293 | "COLUMN SQL_EL_TYPE CLEAR")) | ||
| 4294 | |||
| 4295 | (sql-oracle-restore-settings sqlbuf settings))) | ||
| 4296 | |||
| 4297 | (defun sql-oracle-list-table (sqlbuf outbuf enhanced table-name) | ||
| 4298 | "Implements :list-table under Oracle." | ||
| 4299 | (let ((settings (sql-oracle-save-settings sqlbuf))) | ||
| 4300 | |||
| 4301 | (sql-redirect sqlbuf | ||
| 4302 | (format | ||
| 4303 | (concat "SET LINESIZE %d PAGESIZE 50000" | ||
| 4304 | " DESCRIBE DEPTH 1 LINENUM OFF INDENT ON") | ||
| 4305 | (max 65 (min 120 (window-width))))) | ||
| 4306 | |||
| 4307 | (sql-redirect sqlbuf (format "DESCRIBE %s" table-name) | ||
| 4308 | outbuf) | ||
| 4309 | |||
| 4310 | (sql-oracle-restore-settings sqlbuf settings))) | ||
| 4311 | |||
| 4312 | (defcustom sql-oracle-completion-types '("FUNCTION" "PACKAGE" "PROCEDURE" | ||
| 4313 | "SEQUENCE" "SYNONYM" "TABLE" "TRIGGER" | ||
| 4314 | "TYPE" "VIEW") | ||
| 4315 | "List of object types to include for completion under Oracle. | ||
| 4316 | |||
| 4317 | See the distinct values in ALL_OBJECTS.OBJECT_TYPE for possible values." | ||
| 4318 | :version "24.1" | ||
| 4319 | :type '(repeat string) | ||
| 4320 | :group 'SQL) | ||
| 4321 | |||
| 4322 | (defun sql-oracle-completion-object (sqlbuf schema) | ||
| 4323 | (sql-redirect-value | ||
| 4324 | sqlbuf | ||
| 4325 | (concat | ||
| 4326 | "SELECT CHR(1)||" | ||
| 4327 | (if schema | ||
| 4328 | (format "owner||'.'||object_name AS o FROM all_objects WHERE owner = %s AND " | ||
| 4329 | (sql-str-literal (upcase schema))) | ||
| 4330 | "object_name AS o FROM user_objects WHERE ") | ||
| 4331 | "temporary = 'N' AND generated = 'N' AND secondary = 'N' AND " | ||
| 4332 | "object_type IN (" | ||
| 4333 | (mapconcat (function sql-str-literal) sql-oracle-completion-types ",") | ||
| 4334 | ");") | ||
| 4335 | "^[\001]\\(.+\\)$" 1)) | ||
| 3723 | 4336 | ||
| 3724 | 4337 | ||
| 3725 | ;;;###autoload | 4338 | ;;;###autoload |
| @@ -3858,6 +4471,9 @@ The default comes from `process-coding-system-alist' and | |||
| 3858 | (setq params (append options params)) | 4471 | (setq params (append options params)) |
| 3859 | (sql-comint product params))) | 4472 | (sql-comint product params))) |
| 3860 | 4473 | ||
| 4474 | (defun sql-sqlite-completion-object (sqlbuf schema) | ||
| 4475 | (sql-redirect-value sqlbuf ".tables" "\\sw\\(?:\\sw\\|\\s_\\)*" 0)) | ||
| 4476 | |||
| 3861 | 4477 | ||
| 3862 | 4478 | ||
| 3863 | ;;;###autoload | 4479 | ;;;###autoload |
| @@ -4112,6 +4728,33 @@ Try to set `comint-output-filter-functions' like this: | |||
| 4112 | (setq params (append (list "-p" sql-port) params))) | 4728 | (setq params (append (list "-p" sql-port) params))) |
| 4113 | (sql-comint product params))) | 4729 | (sql-comint product params))) |
| 4114 | 4730 | ||
| 4731 | (defun sql-postgres-completion-object (sqlbuf schema) | ||
| 4732 | (let (cl re fs a r) | ||
| 4733 | (sql-redirect sqlbuf "\\t on") | ||
| 4734 | (setq a (car (sql-redirect-value sqlbuf "\\a" "Output format is \\(.*\\)[.]$" 1))) | ||
| 4735 | (when (string= a "aligned") | ||
| 4736 | (sql-redirect sqlbuf "\\a")) | ||
| 4737 | (setq fs (or (car (sql-redirect-value sqlbuf "\\f" "Field separator is \"\\(.\\)[.]$" 1)) "|")) | ||
| 4738 | |||
| 4739 | (setq re (concat "^\\([^" fs "]*\\)" fs "\\([^" fs "]*\\)" fs "[^" fs "]*" fs "[^" fs "]*$")) | ||
| 4740 | (setq cl (if (not schema) | ||
| 4741 | (sql-redirect-value sqlbuf "\\d" re '(1 2)) | ||
| 4742 | (append (sql-redirect-value sqlbuf (format "\\dt %s.*" schema) re '(1 2)) | ||
| 4743 | (sql-redirect-value sqlbuf (format "\\dv %s.*" schema) re '(1 2)) | ||
| 4744 | (sql-redirect-value sqlbuf (format "\\ds %s.*" schema) re '(1 2))))) | ||
| 4745 | |||
| 4746 | ;; Restore tuples and alignment to what they were | ||
| 4747 | (sql-redirect sqlbuf "\\t off") | ||
| 4748 | (when (not (string= a "aligned")) | ||
| 4749 | (sql-redirect sqlbuf "\\a")) | ||
| 4750 | |||
| 4751 | ;; Return the list of table names (public schema name can be omitted) | ||
| 4752 | (mapcar (lambda (tbl) | ||
| 4753 | (if (string= (car tbl) "public") | ||
| 4754 | (cadr tbl) | ||
| 4755 | (format "%s.%s" (car tbl) (cadr tbl)))) | ||
| 4756 | cl))) | ||
| 4757 | |||
| 4115 | 4758 | ||
| 4116 | 4759 | ||
| 4117 | ;;;###autoload | 4760 | ;;;###autoload |
| @@ -4199,8 +4842,7 @@ The default comes from `process-coding-system-alist' and | |||
| 4199 | "Create comint buffer and connect to DB2." | 4842 | "Create comint buffer and connect to DB2." |
| 4200 | ;; Put all parameters to the program (if defined) in a list and call | 4843 | ;; Put all parameters to the program (if defined) in a list and call |
| 4201 | ;; make-comint. | 4844 | ;; make-comint. |
| 4202 | (sql-comint product options) | 4845 | (sql-comint product options)) |
| 4203 | ) | ||
| 4204 | 4846 | ||
| 4205 | ;;;###autoload | 4847 | ;;;###autoload |
| 4206 | (defun sql-linter (&optional buffer) | 4848 | (defun sql-linter (&optional buffer) |
| @@ -4257,3 +4899,6 @@ buffer. | |||
| 4257 | (provide 'sql) | 4899 | (provide 'sql) |
| 4258 | 4900 | ||
| 4259 | ;;; sql.el ends here | 4901 | ;;; sql.el ends here |
| 4902 | |||
| 4903 | ; LocalWords: sql SQL SQLite sqlite Sybase Informix MySQL | ||
| 4904 | ; LocalWords: Postgres SQLServer SQLi | ||