Mercurial > emacs
comparison lisp/progmodes/sql.el @ 110424:03a492f2d1ce
SQL Mode, Version 2.8 - sql-list-all and sql-list-table functions.
* progmodes/sql.el: Version 2.8
(sql-login-params): Updated widget structure; changes still
needed.
(sql-product-alist): Add :list-all and :list-table features for
SQLite, Postgres and MySQL products.
(sql-redirect): Handle default value.
(sql-execute, sql-execute-feature): New functions.
(sql-read-table-name): New function.
(sql-list-all, sql-list-table): New functions. User API
(sql-mode-map, sql-interactive-mode-map): Add key definitions
for above functions.
(sql-mode-menu, sql-interactive-mode-menu): Add menu definitions
for above functions.
(sql-postgres-login-params): Add user and database defaults.
(sql-buffer-live-p): Bug fix.
(sql-product-history); New variable.
(sql-read-product): New function. Use it.
(sql-set-product, sql-product-interactive): Use it.
(sql-connection-history): New variable.
(sql-read-connection): New function. Use it.
(sql-connect): New function.
(sql-for-each-login): Redesign function interface.
(sql-make-alternate-buffer-name, sql-save-connection): Use it.
(sql-get-login-ext, sql-get-login): Use it. Handle default values.
(sql-comint): Check for program. Existing live buffer.
(sql-comint-postgres): Add port parameter.
author | Michael Mauger <mmaug@yahoo.com> |
---|---|
date | Sat, 18 Sep 2010 22:11:18 -0400 |
parents | ba7558616802 |
children | 029e4783cbae |
comparison
equal
deleted
inserted
replaced
110423:6c2baabc9d98 | 110424:03a492f2d1ce |
---|---|
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, | 3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, |
4 ;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. | 4 ;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Alex Schroeder <alex@gnu.org> | 6 ;; Author: Alex Schroeder <alex@gnu.org> |
7 ;; Maintainer: Michael Mauger <mmaug@yahoo.com> | 7 ;; Maintainer: Michael Mauger <mmaug@yahoo.com> |
8 ;; Version: 2.7 | 8 ;; Version: 2.8 |
9 ;; Keywords: comm languages processes | 9 ;; Keywords: comm languages processes |
10 ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el | 10 ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el |
11 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode | |
12 | 11 |
13 ;; This file is part of GNU Emacs. | 12 ;; This file is part of GNU Emacs. |
14 | 13 |
15 ;; GNU Emacs is free software: you can redistribute it and/or modify | 14 ;; GNU Emacs is free software: you can redistribute it and/or modify |
16 ;; it under the terms of the GNU General Public License as published by | 15 ;; it under the terms of the GNU General Public License as published by |
284 | 283 |
285 ;; Login parameter type | 284 ;; Login parameter type |
286 | 285 |
287 (define-widget 'sql-login-params 'lazy | 286 (define-widget 'sql-login-params 'lazy |
288 "Widget definition of the login parameters list" | 287 "Widget definition of the login parameters list" |
288 ;; FIXME: does not implement :default property for the user, | |
289 ;; database and server options. Anybody have some guidance on how to | |
290 ;; do this. | |
289 :tag "Login Parameters" | 291 :tag "Login Parameters" |
290 :type '(repeat (choice | 292 :type '(repeat (choice |
291 (const user) | 293 (const user) |
292 (const password) | 294 (const password) |
293 (choice :tag "server" | 295 (choice :tag "server" |
298 regexp) | 300 regexp) |
299 (list :tag "completion" | 301 (list :tag "completion" |
300 (const :format "" server) | 302 (const :format "" server) |
301 (const :format "" :completion) | 303 (const :format "" :completion) |
302 (restricted-sexp | 304 (restricted-sexp |
303 :match-alternatives (listp symbolp)))) | 305 :match-alternatives (listp stringp)))) |
304 (choice :tag "database" | 306 (choice :tag "database" |
305 (const database) | 307 (const database) |
306 (list :tag "file" | 308 (list :tag "file" |
307 (const :format "" database) | 309 (const :format "" database) |
308 (const :format "" :file) | 310 (const :format "" :file) |
309 regexp) | 311 regexp) |
310 (list :tag "completion" | 312 (list :tag "completion" |
311 (const :format "" database) | 313 (const :format "" database) |
312 (const :format "" :completion) | 314 (const :format "" :completion) |
313 (restricted-sexp | 315 (restricted-sexp |
314 :match-alternatives (listp symbolp)))) | 316 :match-alternatives (listp stringp)))) |
315 (const port)))) | 317 (const port)))) |
316 | 318 |
317 ;; SQL Product support | 319 ;; SQL Product support |
318 | 320 |
319 (defvar sql-interactive-product nil | 321 (defvar sql-interactive-product nil |
399 :font-lock sql-mode-mysql-font-lock-keywords | 401 :font-lock sql-mode-mysql-font-lock-keywords |
400 :sqli-program sql-mysql-program | 402 :sqli-program sql-mysql-program |
401 :sqli-options sql-mysql-options | 403 :sqli-options sql-mysql-options |
402 :sqli-login sql-mysql-login-params | 404 :sqli-login sql-mysql-login-params |
403 :sqli-comint-func sql-comint-mysql | 405 :sqli-comint-func sql-comint-mysql |
406 :list-all "SHOW TABLES;" | |
407 :list-table "DESCRIBE %s;" | |
404 :prompt-regexp "^mysql> " | 408 :prompt-regexp "^mysql> " |
405 :prompt-length 6 | 409 :prompt-length 6 |
406 :prompt-cont-regexp "^ -> " | 410 :prompt-cont-regexp "^ -> " |
407 :input-filter sql-remove-tabs-filter) | 411 :input-filter sql-remove-tabs-filter) |
408 | 412 |
426 :font-lock sql-mode-postgres-font-lock-keywords | 430 :font-lock sql-mode-postgres-font-lock-keywords |
427 :sqli-program sql-postgres-program | 431 :sqli-program sql-postgres-program |
428 :sqli-options sql-postgres-options | 432 :sqli-options sql-postgres-options |
429 :sqli-login sql-postgres-login-params | 433 :sqli-login sql-postgres-login-params |
430 :sqli-comint-func sql-comint-postgres | 434 :sqli-comint-func sql-comint-postgres |
435 :list-all ("\\d+" . "\\dS+") | |
436 :list-table ("\\d+ %s" . "\\dS+ %s") | |
431 :prompt-regexp "^.*=[#>] " | 437 :prompt-regexp "^.*=[#>] " |
432 :prompt-length 5 | 438 :prompt-length 5 |
433 :prompt-cont-regexp "^.*[-(][#>] " | 439 :prompt-cont-regexp "^.*[-(][#>] " |
434 :input-filter sql-remove-tabs-filter | 440 :input-filter sql-remove-tabs-filter |
435 :terminator ("\\(^\\s-*\\\\g\\|;\\)" . ";")) | 441 :terminator ("\\(^\\s-*\\\\g\\|;\\)" . ";")) |
450 :font-lock sql-mode-sqlite-font-lock-keywords | 456 :font-lock sql-mode-sqlite-font-lock-keywords |
451 :sqli-program sql-sqlite-program | 457 :sqli-program sql-sqlite-program |
452 :sqli-options sql-sqlite-options | 458 :sqli-options sql-sqlite-options |
453 :sqli-login sql-sqlite-login-params | 459 :sqli-login sql-sqlite-login-params |
454 :sqli-comint-func sql-comint-sqlite | 460 :sqli-comint-func sql-comint-sqlite |
461 :list-all ".tables" | |
462 :list-table ".schema %s" | |
455 :prompt-regexp "^sqlite> " | 463 :prompt-regexp "^sqlite> " |
456 :prompt-length 8 | 464 :prompt-length 8 |
457 :prompt-cont-regexp "^ ...> " | 465 :prompt-cont-regexp "^ ...> " |
458 :terminator ";") | 466 :terminator ";") |
459 | 467 |
507 `sql-user', `sql-password', | 515 `sql-user', `sql-password', |
508 `sql-database' and `sql-server' to open a | 516 `sql-database' and `sql-server' to open a |
509 comint buffer and connect to the | 517 comint buffer and connect to the |
510 database. Do product specific | 518 database. Do product specific |
511 configuration of comint in this function. | 519 configuration of comint in this function. |
520 | |
521 :list-all Command string or function which produces | |
522 a listing of all objects in the database. | |
523 If it's a cons cell, then the car | |
524 produces the standard list of objects and | |
525 the cdr produces an enhanced list of | |
526 objects. What \"enhanced\" means is | |
527 dependent on the SQL product and may not | |
528 exist. In general though, the | |
529 \"enhanced\" list should include visible | |
530 objects from other schemas. | |
531 | |
532 :list-table Command string or function which produces | |
533 a detailed listing of a specific database | |
534 table. If its a cons cell, then the car | |
535 produces the standard list and the cdr | |
536 produces an enhanced list. | |
512 | 537 |
513 :prompt-regexp regular expression string that matches | 538 :prompt-regexp regular expression string that matches |
514 the prompt issued by the product | 539 the prompt issued by the product |
515 interpreter. | 540 interpreter. |
516 | 541 |
939 add your name with a \"-U\" prefix (such as \"-Umark\") to the list." | 964 add your name with a \"-U\" prefix (such as \"-Umark\") to the list." |
940 :type '(repeat string) | 965 :type '(repeat string) |
941 :version "20.8" | 966 :version "20.8" |
942 :group 'SQL) | 967 :group 'SQL) |
943 | 968 |
944 (defcustom sql-postgres-login-params '(user database server) | 969 (defcustom sql-postgres-login-params `((user :default ,(user-login-name)) |
970 (database :default ,(user-login-name)) | |
971 server) | |
945 "List of login parameters needed to connect to Postgres." | 972 "List of login parameters needed to connect to Postgres." |
946 :type 'sql-login-params | 973 :type 'sql-login-params |
947 :version "24.1" | 974 :version "24.1" |
948 :group 'SQL) | 975 :group 'SQL) |
949 | 976 |
1022 | 1049 |
1023 (defvar sql-server-history nil | 1050 (defvar sql-server-history nil |
1024 "History of servers used.") | 1051 "History of servers used.") |
1025 | 1052 |
1026 ;; Passwords are not kept in a history. | 1053 ;; Passwords are not kept in a history. |
1054 | |
1055 (defvar sql-product-history nil | |
1056 "History of products used.") | |
1057 | |
1058 (defvar sql-connection-history nil | |
1059 "History of connections used.") | |
1027 | 1060 |
1028 (defvar sql-buffer nil | 1061 (defvar sql-buffer nil |
1029 "Current SQLi buffer. | 1062 "Current SQLi buffer. |
1030 | 1063 |
1031 The global value of `sql-buffer' is the name of the latest SQLi buffer | 1064 The global value of `sql-buffer' is the name of the latest SQLi buffer |
1065 (and buffer | 1098 (and buffer |
1066 (buffer-live-p buffer) | 1099 (buffer-live-p buffer) |
1067 (get-buffer-process buffer) | 1100 (get-buffer-process buffer) |
1068 (comint-check-proc buffer) | 1101 (comint-check-proc buffer) |
1069 (with-current-buffer buffer | 1102 (with-current-buffer buffer |
1070 (and (derived-mode-p 'sql-product-interactive) | 1103 (and (derived-mode-p 'sql-interactive-mode) |
1071 (or (not product) | 1104 (or (not product) |
1072 (eq product sql-product))))))) | 1105 (eq product sql-product))))))) |
1073 | 1106 |
1074 ;; Keymap for sql-interactive-mode. | 1107 ;; Keymap for sql-interactive-mode. |
1075 | 1108 |
1084 (define-key map (kbd "C-j") 'sql-accumulate-and-indent) | 1117 (define-key map (kbd "C-j") 'sql-accumulate-and-indent) |
1085 (define-key map (kbd "C-c C-w") 'sql-copy-column) | 1118 (define-key map (kbd "C-c C-w") 'sql-copy-column) |
1086 (define-key map (kbd "O") 'sql-magic-go) | 1119 (define-key map (kbd "O") 'sql-magic-go) |
1087 (define-key map (kbd "o") 'sql-magic-go) | 1120 (define-key map (kbd "o") 'sql-magic-go) |
1088 (define-key map (kbd ";") 'sql-magic-semicolon) | 1121 (define-key map (kbd ";") 'sql-magic-semicolon) |
1122 (define-key map (kbd "C-c C-l a") 'sql-list-all) | |
1123 (define-key map (kbd "C-c C-l t") 'sql-list-table) | |
1089 map) | 1124 map) |
1090 "Mode map used for `sql-interactive-mode'. | 1125 "Mode map used for `sql-interactive-mode'. |
1091 Based on `comint-mode-map'.") | 1126 Based on `comint-mode-map'.") |
1092 | 1127 |
1093 ;; Keymap for sql-mode. | 1128 ;; Keymap for sql-mode. |
1097 (define-key map (kbd "C-c C-c") 'sql-send-paragraph) | 1132 (define-key map (kbd "C-c C-c") 'sql-send-paragraph) |
1098 (define-key map (kbd "C-c C-r") 'sql-send-region) | 1133 (define-key map (kbd "C-c C-r") 'sql-send-region) |
1099 (define-key map (kbd "C-c C-s") 'sql-send-string) | 1134 (define-key map (kbd "C-c C-s") 'sql-send-string) |
1100 (define-key map (kbd "C-c C-b") 'sql-send-buffer) | 1135 (define-key map (kbd "C-c C-b") 'sql-send-buffer) |
1101 (define-key map (kbd "C-c C-i") 'sql-product-interactive) | 1136 (define-key map (kbd "C-c C-i") 'sql-product-interactive) |
1137 (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) | |
1102 map) | 1139 map) |
1103 "Mode map used for `sql-mode'.") | 1140 "Mode map used for `sql-mode'.") |
1104 | 1141 |
1105 ;; easy menu for sql-mode. | 1142 ;; easy menu for sql-mode. |
1106 | 1143 |
1111 ["Send Paragraph" sql-send-paragraph (sql-buffer-live-p sql-buffer)] | 1148 ["Send Paragraph" sql-send-paragraph (sql-buffer-live-p sql-buffer)] |
1112 ["Send Region" sql-send-region (and mark-active | 1149 ["Send Region" sql-send-region (and mark-active |
1113 (sql-buffer-live-p sql-buffer))] | 1150 (sql-buffer-live-p sql-buffer))] |
1114 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] | 1151 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] |
1115 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] | 1152 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] |
1153 "--" | |
1154 ["List all objects" sql-list-all (sql-buffer-live-p sql-buffer)] | |
1155 ["List table details" sql-list-table (sql-buffer-live-p sql-buffer)] | |
1116 "--" | 1156 "--" |
1117 ["Start SQLi session" sql-product-interactive | 1157 ["Start SQLi session" sql-product-interactive |
1118 :visible (not sql-connection-alist) | 1158 :visible (not sql-connection-alist) |
1119 :enable (sql-get-product-feature sql-product :sqli-comint-func)] | 1159 :enable (sql-get-product-feature sql-product :sqli-comint-func)] |
1120 ("Start..." | 1160 ("Start..." |
1150 (easy-menu-define | 1190 (easy-menu-define |
1151 sql-interactive-mode-menu sql-interactive-mode-map | 1191 sql-interactive-mode-menu sql-interactive-mode-map |
1152 "Menu for `sql-interactive-mode'." | 1192 "Menu for `sql-interactive-mode'." |
1153 '("SQL" | 1193 '("SQL" |
1154 ["Rename Buffer" sql-rename-buffer t] | 1194 ["Rename Buffer" sql-rename-buffer t] |
1155 ["Save Connection" sql-save-connection (not sql-connection)])) | 1195 ["Save Connection" sql-save-connection (not sql-connection)] |
1196 "--" | |
1197 ["List all objects" sql-list-all t] | |
1198 ["List table details" sql-list-table t])) | |
1156 | 1199 |
1157 ;; Abbreviations -- if you want more of them, define them in your | 1200 ;; Abbreviations -- if you want more of them, define them in your |
1158 ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. | 1201 ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. |
1159 | 1202 |
1160 (defvar sql-mode-abbrev-table nil | 1203 (defvar sql-mode-abbrev-table nil |
2133 | 2176 |
2134 | 2177 |
2135 | 2178 |
2136 ;;; SQL Product support functions | 2179 ;;; SQL Product support functions |
2137 | 2180 |
2181 (defun sql-read-product (prompt &optional initial) | |
2182 "Read a valid SQL product." | |
2183 (let ((init (or (and initial (symbol-name initial)) "ansi"))) | |
2184 (intern (completing-read | |
2185 prompt | |
2186 (mapcar (lambda (info) (symbol-name (car info))) | |
2187 sql-product-alist) | |
2188 nil 'require-match | |
2189 init 'sql-product-history init)))) | |
2190 | |
2138 (defun sql-add-product (product display &rest plist) | 2191 (defun sql-add-product (product display &rest plist) |
2139 "Add support for a database product in `sql-mode'. | 2192 "Add support for a database product in `sql-mode'. |
2140 | 2193 |
2141 Add PRODUCT to `sql-product-alist' which enables `sql-mode' to | 2194 Add PRODUCT to `sql-product-alist' which enables `sql-mode' to |
2142 properly support syntax highlighting and interactive interaction. | 2195 properly support syntax highlighting and interactive interaction. |
2323 | 2376 |
2324 (delq nil | 2377 (delq nil |
2325 (mapcar | 2378 (mapcar |
2326 (lambda (param) | 2379 (lambda (param) |
2327 (let ((token (or (and (listp param) (car param)) param)) | 2380 (let ((token (or (and (listp param) (car param)) param)) |
2328 (type (or (and (listp param) (nth 1 param)) nil)) | 2381 (plist (or (and (listp param) (cdr param)) nil))) |
2329 (arg (or (and (listp param) (nth 2 param)) nil))) | 2382 |
2330 | 2383 (funcall body token plist))) |
2331 (funcall body token type arg))) | |
2332 login-params))) | 2384 login-params))) |
2333 | 2385 |
2334 | 2386 |
2335 | 2387 |
2336 ;;; Functions to switch highlighting | 2388 ;;; Functions to switch highlighting |
2346 (symbol-name sql-product)) "]")))) | 2398 (symbol-name sql-product)) "]")))) |
2347 | 2399 |
2348 (defun sql-set-product (product) | 2400 (defun sql-set-product (product) |
2349 "Set `sql-product' to PRODUCT and enable appropriate highlighting." | 2401 "Set `sql-product' to PRODUCT and enable appropriate highlighting." |
2350 (interactive | 2402 (interactive |
2351 (list (completing-read "SQL product: " | 2403 (list (sql-read-product "SQL product: "))) |
2352 (mapcar (lambda (info) (symbol-name (car info))) | |
2353 sql-product-alist) | |
2354 nil 'require-match | |
2355 (or (and sql-product (symbol-name sql-product)) "ansi")))) | |
2356 (if (stringp product) (setq product (intern product))) | 2404 (if (stringp product) (setq product (intern product))) |
2357 (when (not (assoc product sql-product-alist)) | 2405 (when (not (assoc product sql-product-alist)) |
2358 (error "SQL product %s is not supported; treated as ANSI" product) | 2406 (error "SQL product %s is not supported; treated as ANSI" product) |
2359 (setq product 'ansi)) | 2407 (setq product 'ansi)) |
2360 | 2408 |
2490 | 2538 |
2491 (defun sql-read-passwd (prompt &optional default) | 2539 (defun sql-read-passwd (prompt &optional default) |
2492 "Read a password using PROMPT. Optional DEFAULT is password to start with." | 2540 "Read a password using PROMPT. Optional DEFAULT is password to start with." |
2493 (read-passwd prompt nil default)) | 2541 (read-passwd prompt nil default)) |
2494 | 2542 |
2495 (defun sql-get-login-ext (prompt last-value history-var type arg) | 2543 (defun sql-get-login-ext (prompt last-value history-var plist) |
2496 "Prompt user with extended login parameters. | 2544 "Prompt user with extended login parameters. |
2497 | 2545 |
2498 If TYPE is nil, then the user is simply prompted for a string | 2546 If PLIST is nil, then the user is simply prompted for a string |
2499 value. | 2547 value. |
2500 | 2548 |
2501 If TYPE is `:file', then the user is prompted for a file | 2549 The property `:default' specifies the default value. If the |
2502 name that must match the regexp pattern specified in the ARG | 2550 `:number' property is non-nil then ask for a number. |
2503 argument. | 2551 |
2504 | 2552 The `:file' property prompts for a file name that must match the |
2505 If TYPE is `:completion', then the user is prompted for a string | 2553 regexp pattern specified in its value. |
2506 specified by ARG. (ARG is used as the PREDICATE argument to | 2554 |
2555 The `:completion' property prompts for a string specified by its | |
2556 value. (The property value is used as the PREDICATE argument to | |
2507 `completing-read'.)" | 2557 `completing-read'.)" |
2508 (cond | 2558 (let* ((default (plist-get plist :default)) |
2509 ((eq type nil) | 2559 (prompt-def |
2510 (read-from-minibuffer prompt last-value nil nil history-var)) | 2560 (if default |
2511 | 2561 (if (string-match "\\(\\):[ \t]*\\'" prompt) |
2512 ((eq type :file) | 2562 (replace-match (format " (default \"%s\")" default) t t prompt 1) |
2513 (let ((use-dialog-box nil)) | 2563 (replace-regexp-in-string "[ \t]*\\'" |
2564 (format " (default \"%s\") " default) | |
2565 prompt t t)) | |
2566 prompt)) | |
2567 (use-dialog-box nil)) | |
2568 (cond | |
2569 ((plist-member plist :file) | |
2514 (expand-file-name | 2570 (expand-file-name |
2515 (read-file-name prompt | 2571 (read-file-name prompt |
2516 (file-name-directory last-value) nil t | 2572 (file-name-directory last-value) default t |
2517 (file-name-nondirectory last-value) | 2573 (file-name-nondirectory last-value) |
2518 (if arg | 2574 (when (plist-get plist :file) |
2519 `(lambda (f) | 2575 `(lambda (f) |
2520 (string-match (concat "\\<" ,arg "\\>") | 2576 (string-match |
2521 (file-name-nondirectory f))) | 2577 (concat "\\<" ,(plist-get plist :file) "\\>") |
2522 nil))))) | 2578 (file-name-nondirectory f))))))) |
2523 | 2579 |
2524 ((eq type :completion) | 2580 ((plist-member plist :completion) |
2525 (completing-read prompt arg nil t last-value history-var)))) | 2581 (completing-read prompt-def (plist-get plist :completion) nil t |
2582 last-value history-var default)) | |
2583 | |
2584 ((plist-get plist :number) | |
2585 (read-number prompt (or default last-value 0))) | |
2586 | |
2587 (t | |
2588 (let ((r (read-from-minibuffer prompt-def last-value nil nil history-var nil))) | |
2589 (if (string= "" r) (or default "") r)))))) | |
2526 | 2590 |
2527 (defun sql-get-login (&rest what) | 2591 (defun sql-get-login (&rest what) |
2528 "Get username, password and database from the user. | 2592 "Get username, password and database from the user. |
2529 | 2593 |
2530 The variables `sql-user', `sql-password', `sql-server', and | 2594 The variables `sql-user', `sql-password', `sql-server', and |
2539 symbol `password', for the server if it contains the symbol | 2603 symbol `password', for the server if it contains the symbol |
2540 `server', and for the database if it contains the symbol | 2604 `server', and for the database if it contains the symbol |
2541 `database'. The members of WHAT are processed in the order in | 2605 `database'. The members of WHAT are processed in the order in |
2542 which they are provided. | 2606 which they are provided. |
2543 | 2607 |
2544 The tokens for `database' and `server' may also be lists to | 2608 Each token may also be a list with the token in the car and a |
2545 control or limit the values that can be supplied. These can be | 2609 plist of options as the cdr. The following properties are |
2546 of the form: | 2610 supported: |
2547 | 2611 |
2548 \(database :file \".+\\\\.EXT\") | 2612 :file <filename-regexp> |
2549 \(database :completion FUNCTION) | 2613 :completion <list-of-strings-or-function> |
2550 | 2614 :default <default-value> |
2551 The `server' token supports the same forms. | 2615 :number t |
2552 | 2616 |
2553 In order to ask the user for username, password and database, call the | 2617 In order to ask the user for username, password and database, call the |
2554 function like this: (sql-get-login 'user 'password 'database)." | 2618 function like this: (sql-get-login 'user 'password 'database)." |
2555 (interactive) | 2619 (interactive) |
2556 (mapcar | 2620 (mapcar |
2557 (lambda (w) | 2621 (lambda (w) |
2558 (let ((token (or (and (listp w) (car w)) w)) | 2622 (let ((token (or (and (consp w) (car w)) w)) |
2559 (type (or (and (listp w) (nth 1 w)) nil)) | 2623 (plist (or (and (consp w) (cdr w)) nil))) |
2560 (arg (or (and (listp w) (nth 2 w)) nil))) | 2624 |
2561 | 2625 (cond |
2562 (cond | 2626 ((eq token 'user) ; user |
2563 ((eq token 'user) ; user | 2627 (setq sql-user |
2564 (setq sql-user | 2628 (sql-get-login-ext "User: " sql-user |
2565 (read-from-minibuffer "User: " sql-user nil nil | 2629 'sql-user-history plist))) |
2566 'sql-user-history))) | 2630 |
2567 | 2631 ((eq token 'password) ; password |
2568 ((eq token 'password) ; password | 2632 (setq sql-password |
2569 (setq sql-password | 2633 (sql-read-passwd "Password: " sql-password))) |
2570 (sql-read-passwd "Password: " sql-password))) | 2634 |
2571 | 2635 ((eq token 'server) ; server |
2572 ((eq token 'server) ; server | 2636 (setq sql-server |
2573 (setq sql-server | 2637 (sql-get-login-ext "Server: " sql-server |
2574 (sql-get-login-ext "Server: " sql-server | 2638 'sql-server-history plist))) |
2575 'sql-server-history type arg))) | 2639 |
2576 | 2640 ((eq token 'database) ; database |
2577 ((eq token 'database) ; database | 2641 (setq sql-database |
2578 (setq sql-database | 2642 (sql-get-login-ext "Database: " sql-database |
2579 (sql-get-login-ext "Database: " sql-database | 2643 'sql-database-history plist))) |
2580 'sql-database-history type arg))) | 2644 |
2581 | 2645 ((eq token 'port) ; port |
2582 ((eq token 'port) ; port | 2646 (setq sql-port |
2583 (setq sql-port | 2647 (sql-get-login-ext "Port: " sql-port |
2584 (read-number "Port: " (if (numberp sql-port) | 2648 nil (append '(:number t) plist))))))) |
2585 sql-port | 2649 what)) |
2586 0))))))) | 2650 |
2587 what)) | 2651 (defun sql-find-sqli-buffer (&optional product) |
2588 | |
2589 (defun sql-find-sqli-buffer () | |
2590 "Returns the name of the current default SQLi buffer or nil. | 2652 "Returns the name of the current default SQLi buffer or nil. |
2591 In order to qualify, the SQLi buffer must be alive, be in | 2653 In order to qualify, the SQLi buffer must be alive, be in |
2592 `sql-interactive-mode' and have a process." | 2654 `sql-interactive-mode' and have a process." |
2593 (let ((buf sql-buffer) | 2655 (let ((buf sql-buffer) |
2594 (prod sql-product)) | 2656 (prod (or product sql-product))) |
2595 (or | 2657 (or |
2596 ;; Current sql-buffer, if there is one. | 2658 ;; Current sql-buffer, if there is one. |
2597 (and (sql-buffer-live-p buf prod) | 2659 (and (sql-buffer-live-p buf prod) |
2598 buf) | 2660 buf) |
2599 ;; Global sql-buffer | 2661 ;; Global sql-buffer |
2687 (apply 'concat | 2749 (apply 'concat |
2688 (cdr | 2750 (cdr |
2689 (apply 'append nil | 2751 (apply 'append nil |
2690 (sql-for-each-login | 2752 (sql-for-each-login |
2691 (sql-get-product-feature sql-product :sqli-login) | 2753 (sql-get-product-feature sql-product :sqli-login) |
2692 (lambda (token type arg) | 2754 (lambda (token plist) |
2693 (cond | 2755 (cond |
2694 ((eq token 'user) | 2756 ((eq token 'user) |
2695 (unless (string= "" sql-user) | 2757 (unless (string= "" sql-user) |
2696 (list "/" sql-user))) | 2758 (list "/" sql-user))) |
2697 ((eq token 'port) | 2759 ((eq token 'port) |
2699 (= 0 sql-port)) | 2761 (= 0 sql-port)) |
2700 (list ":" (number-to-string sql-port)))) | 2762 (list ":" (number-to-string sql-port)))) |
2701 ((eq token 'server) | 2763 ((eq token 'server) |
2702 (unless (string= "" sql-server) | 2764 (unless (string= "" sql-server) |
2703 (list "." | 2765 (list "." |
2704 (if (eq type :file) | 2766 (if (plist-member plist :file) |
2705 (file-name-nondirectory sql-server) | 2767 (file-name-nondirectory sql-server) |
2706 sql-server)))) | 2768 sql-server)))) |
2707 ((eq token 'database) | 2769 ((eq token 'database) |
2708 (unless (string= "" sql-database) | 2770 (unless (string= "" sql-database) |
2709 (list "@" | 2771 (list "@" |
2710 (if (eq type :file) | 2772 (if (plist-member plist :file) |
2711 (file-name-nondirectory sql-database) | 2773 (file-name-nondirectory sql-database) |
2712 sql-database)))) | 2774 sql-database)))) |
2713 | 2775 |
2714 ((eq token 'password) nil) | 2776 ((eq token 'password) nil) |
2715 (t nil)))))))) | 2777 (t nil)))))))) |
3017 (proc (get-buffer-process (current-buffer))) | 3079 (proc (get-buffer-process (current-buffer))) |
3018 (comint-prompt-regexp (sql-get-product-feature sql-product | 3080 (comint-prompt-regexp (sql-get-product-feature sql-product |
3019 :prompt-regexp)) | 3081 :prompt-regexp)) |
3020 (start nil)) | 3082 (start nil)) |
3021 (with-current-buffer buf | 3083 (with-current-buffer buf |
3084 (toggle-read-only -1) | |
3022 (unless save-prior | 3085 (unless save-prior |
3023 (erase-buffer)) | 3086 (erase-buffer)) |
3024 (goto-char (point-max)) | 3087 (goto-char (point-max)) |
3088 (unless (zerop (buffer-size)) | |
3089 (insert "\n")) | |
3025 (setq start (point))) | 3090 (setq start (point))) |
3026 | 3091 |
3027 ;; Run the command | 3092 ;; Run the command |
3093 (message "Executing SQL command...") | |
3028 (comint-redirect-send-command-to-process command buf proc nil t) | 3094 (comint-redirect-send-command-to-process command buf proc nil t) |
3029 (while (null comint-redirect-completed) | 3095 (while (null comint-redirect-completed) |
3030 (accept-process-output nil 1)) | 3096 (accept-process-output nil 1)) |
3031 | 3097 (message "Executing SQL command...done") |
3032 ;; Remove echo if there was one | 3098 |
3099 ;; Clean up the output results | |
3033 (with-current-buffer buf | 3100 (with-current-buffer buf |
3101 ;; Remove trailing whitespace | |
3102 (goto-char (point-max)) | |
3103 (when (looking-back "[ \t\f\n\r]*" start) | |
3104 (delete-region (match-beginning 0) (match-end 0))) | |
3105 ;; Remove echo if there was one | |
3034 (goto-char start) | 3106 (goto-char start) |
3035 (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) | 3107 (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) |
3036 (delete-region (match-beginning 0) (match-end 0))) | 3108 (delete-region (match-beginning 0) (match-end 0))) |
3037 (goto-char start))))) | 3109 (goto-char start))))) |
3038 | 3110 |
3062 (push (match-string i) r)) | 3134 (push (match-string i) r)) |
3063 (nreverse r))) | 3135 (nreverse r))) |
3064 ;; one group specified | 3136 ;; one group specified |
3065 ((numberp regexp-groups) | 3137 ((numberp regexp-groups) |
3066 (match-string regexp-groups)) | 3138 (match-string regexp-groups)) |
3067 ;; (buffer-substring-no-properties | |
3068 ;; (match-beginning regexp-groups) | |
3069 ;; (match-end regexp-groups))) | |
3070 ;; list of numbers; return the specified matches only | 3139 ;; list of numbers; return the specified matches only |
3071 ((consp regexp-groups) | 3140 ((consp regexp-groups) |
3072 (mapcar (lambda (c) | 3141 (mapcar (lambda (c) |
3073 (cond | 3142 (cond |
3074 ((numberp c) (match-string c)) | 3143 ((numberp c) (match-string c)) |
3081 (t | 3150 (t |
3082 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" | 3151 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" |
3083 regexp-groups))) | 3152 regexp-groups))) |
3084 results))) | 3153 results))) |
3085 (nreverse results))) | 3154 (nreverse results))) |
3155 | |
3156 (defun sql-execute (sqlbuf outbuf command arg) | |
3157 "Executes a command in a SQL interacive buffer and captures the output. | |
3158 | |
3159 The commands are run in SQLBUF and the output saved in OUTBUF. | |
3160 COMMAND must be a string, a function or a list of such elements. | |
3161 Functions are called with SQLBUF, OUTBUF and ARG as parameters; | |
3162 strings are formatted with ARG and executed. | |
3163 | |
3164 If the results are empty the OUTBUF is deleted, otherwise the | |
3165 buffer is popped into a view window. " | |
3166 (mapc | |
3167 (lambda (c) | |
3168 (cond | |
3169 ((stringp c) | |
3170 (sql-redirect (if arg (format c arg) c) sqlbuf outbuf) t) | |
3171 ((functionp c) | |
3172 (apply c sqlbuf outbuf arg)) | |
3173 (t (error "Unknown sql-execute item %s" c)))) | |
3174 (if (consp command) command (cons command nil))) | |
3175 | |
3176 (setq outbuf (get-buffer outbuf)) | |
3177 (if (zerop (buffer-size outbuf)) | |
3178 (kill-buffer outbuf) | |
3179 (let ((one-win (eq (selected-window) | |
3180 (get-lru-window)))) | |
3181 (with-current-buffer outbuf | |
3182 (set-buffer-modified-p nil) | |
3183 (toggle-read-only 1)) | |
3184 (view-buffer-other-window outbuf) | |
3185 (when one-win | |
3186 (shrink-window-if-larger-than-buffer))))) | |
3187 | |
3188 (defun sql-execute-feature (sqlbuf outbuf feature enhanced arg) | |
3189 "List objects or details in a separate display buffer." | |
3190 (let (command) | |
3191 (with-current-buffer sqlbuf | |
3192 (setq command (sql-get-product-feature sql-product feature))) | |
3193 (unless command | |
3194 (error "%s does not support %s" sql-product feature)) | |
3195 (when (consp command) | |
3196 (setq command (if enhanced | |
3197 (cdr command) | |
3198 (car command)))) | |
3199 (sql-execute sqlbuf outbuf command arg))) | |
3200 | |
3201 (defun sql-read-table-name (prompt) | |
3202 "Read the name of a database table." | |
3203 ;; TODO: Fetch table/view names from database and provide completion. | |
3204 ;; Also implement thing-at-point if the buffer has valid names in it | |
3205 ;; (i.e. sql-mode, sql-interactive-mode, or sql-list-all buffers) | |
3206 (read-from-minibuffer prompt)) | |
3207 | |
3208 (defun sql-list-all (&optional enhanced) | |
3209 "List all database objects." | |
3210 (interactive "P") | |
3211 (let ((sqlbuf (sql-find-sqli-buffer))) | |
3212 (unless sqlbuf | |
3213 (error "No SQL interactive buffer found")) | |
3214 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil))) | |
3215 | |
3216 (defun sql-list-table (name &optional enhanced) | |
3217 "List the details of a database table. " | |
3218 (interactive | |
3219 (list (sql-read-table-name "Table name: ") | |
3220 current-prefix-arg)) | |
3221 (let ((sqlbuf (sql-find-sqli-buffer))) | |
3222 (unless sqlbuf | |
3223 (error "No SQL interactive buffer found")) | |
3224 (unless name | |
3225 (error "No table name specified")) | |
3226 (sql-execute-feature sqlbuf (format "*List %s*" name) | |
3227 :list-table enhanced name))) | |
3086 | 3228 |
3087 | 3229 |
3088 | 3230 |
3089 ;;; SQL mode -- uses SQL interactive mode | 3231 ;;; SQL mode -- uses SQL interactive mode |
3090 | 3232 |
3311 | 3453 |
3312 | 3454 |
3313 | 3455 |
3314 ;;; Connection handling | 3456 ;;; Connection handling |
3315 | 3457 |
3458 (defun sql-read-connection (prompt &optional initial default) | |
3459 "Read a connection name." | |
3460 (let ((completion-ignore-case t)) | |
3461 (completing-read prompt | |
3462 (mapcar (lambda (c) (car c)) | |
3463 sql-connection-alist) | |
3464 nil t initial 'sql-connection-history default))) | |
3465 | |
3316 ;;;###autoload | 3466 ;;;###autoload |
3317 (defun sql-connect (connection) | 3467 (defun sql-connect (connection) |
3318 "Connect to an interactive session using CONNECTION settings. | 3468 "Connect to an interactive session using CONNECTION settings. |
3319 | 3469 |
3320 See `sql-connection-alist' to see how to define connections and | 3470 See `sql-connection-alist' to see how to define connections and |
3324 is specified in the connection settings." | 3474 is specified in the connection settings." |
3325 | 3475 |
3326 ;; Prompt for the connection from those defined in the alist | 3476 ;; Prompt for the connection from those defined in the alist |
3327 (interactive | 3477 (interactive |
3328 (if sql-connection-alist | 3478 (if sql-connection-alist |
3329 (list | 3479 (list (sql-read-connection "Connection: " nil '(nil))) |
3330 (let ((completion-ignore-case t)) | |
3331 (completing-read "Connection: " | |
3332 (mapcar (lambda (c) (car c)) | |
3333 sql-connection-alist) | |
3334 nil t nil nil '(())))) | |
3335 nil)) | 3480 nil)) |
3336 | 3481 |
3337 ;; Are there connections defined | 3482 ;; Are there connections defined |
3338 (if sql-connection-alist | 3483 (if sql-connection-alist |
3339 ;; Was one selected | 3484 ;; Was one selected |
3363 (t (car v)))) | 3508 (t (car v)))) |
3364 (cdr connect-set))) | 3509 (cdr connect-set))) |
3365 ;; the remaining params (w/o the connection params) | 3510 ;; the remaining params (w/o the connection params) |
3366 (rem-params (sql-for-each-login | 3511 (rem-params (sql-for-each-login |
3367 login-params | 3512 login-params |
3368 (lambda (token type arg) | 3513 (lambda (token plist) |
3369 (unless (member token set-params) | 3514 (unless (member token set-params) |
3370 (if (or type arg) | 3515 (if plist |
3371 (list token type arg) | 3516 (cons token plist) |
3372 token))))) | 3517 token))))) |
3373 ;; Remember the connection | 3518 ;; Remember the connection |
3374 (sql-connection connection)) | 3519 (sql-connection connection)) |
3375 | 3520 |
3376 ;; Set the remaining parameters and start the | 3521 ;; Set the remaining parameters and start the |
3407 (message "Connection <%s> already exists" name) | 3552 (message "Connection <%s> already exists" name) |
3408 (setq connect | 3553 (setq connect |
3409 (append (list name) | 3554 (append (list name) |
3410 (sql-for-each-login | 3555 (sql-for-each-login |
3411 `(product ,@login) | 3556 `(product ,@login) |
3412 (lambda (token type arg) | 3557 (lambda (token plist) |
3413 (cond | 3558 (cond |
3414 ((eq token 'product) `(sql-product ',sql-product)) | 3559 ((eq token 'product) `(sql-product ',sql-product)) |
3415 ((eq token 'user) `(sql-user ,sql-user)) | 3560 ((eq token 'user) `(sql-user ,sql-user)) |
3416 ((eq token 'database) `(sql-database ,sql-database)) | 3561 ((eq token 'database) `(sql-database ,sql-database)) |
3417 ((eq token 'server) `(sql-server ,sql-server)) | 3562 ((eq token 'server) `(sql-server ,sql-server)) |
3458 ;; Handle universal arguments if specified | 3603 ;; Handle universal arguments if specified |
3459 (when (not (or executing-kbd-macro noninteractive)) | 3604 (when (not (or executing-kbd-macro noninteractive)) |
3460 (when (and (consp product) | 3605 (when (and (consp product) |
3461 (not (cdr product)) | 3606 (not (cdr product)) |
3462 (numberp (car product))) | 3607 (numberp (car product))) |
3463 (when (>= (car product) 16) | 3608 (when (>= (prefix-numeric-value product) 16) |
3464 (when (not new-name) | 3609 (when (not new-name) |
3465 (setq new-name '(4))) | 3610 (setq new-name '(4))) |
3466 (setq product '(4))))) | 3611 (setq product '(4))))) |
3467 | 3612 |
3468 ;; Get the value of product that we need | 3613 ;; Get the value of product that we need |
3469 (setq product | 3614 (setq product |
3470 (cond | 3615 (cond |
3471 ((equal product '(4)) ; C-u, prompt for product | |
3472 (intern (completing-read "SQL product: " | |
3473 (mapcar (lambda (info) (symbol-name (car info))) | |
3474 sql-product-alist) | |
3475 nil 'require-match | |
3476 (or (and sql-product | |
3477 (symbol-name sql-product)) | |
3478 "ansi")))) | |
3479 ((and product ; Product specified | 3616 ((and product ; Product specified |
3480 (symbolp product)) product) | 3617 (symbolp product)) product) |
3618 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product | |
3619 (sql-read-product "SQL product: " sql-product)) | |
3481 (t sql-product))) ; Default to sql-product | 3620 (t sql-product))) ; Default to sql-product |
3482 | 3621 |
3483 ;; If we have a product and it has a interactive mode | 3622 ;; If we have a product and it has a interactive mode |
3484 (if product | 3623 (if product |
3485 (when (sql-get-product-feature product :sqli-comint-func) | 3624 (when (sql-get-product-feature product :sqli-comint-func) |
3486 ;; If no new name specified, fall back on sql-buffer if its for | 3625 ;; If no new name specified, try to pop to an active SQL |
3487 ;; the same product | 3626 ;; interactive for the same product |
3488 (if (and (not new-name) | 3627 (let ((buf (sql-find-sqli-buffer product))) |
3489 (sql-buffer-live-p sql-buffer product)) | 3628 (if (and (not new-name) buf) |
3490 (pop-to-buffer sql-buffer) | 3629 (pop-to-buffer buf) |
3491 | 3630 |
3492 ;; We have a new name or sql-buffer doesn't exist or match | 3631 ;; We have a new name or sql-buffer doesn't exist or match |
3493 ;; Start by remembering where we start | 3632 ;; Start by remembering where we start |
3494 (let* ((start-buffer (current-buffer)) | 3633 (let ((start-buffer (current-buffer)) |
3495 new-sqli-buffer) | 3634 new-sqli-buffer) |
3496 | 3635 |
3497 ;; Get credentials. | 3636 ;; Get credentials. |
3498 (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) | 3637 (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) |
3499 | 3638 |
3500 ;; Connect to database. | 3639 ;; Connect to database. |
3501 (message "Login...") | 3640 (message "Login...") |
3502 (funcall (sql-get-product-feature product :sqli-comint-func) | 3641 (funcall (sql-get-product-feature product :sqli-comint-func) |
3503 product | 3642 product |
3504 (sql-get-product-feature product :sqli-options)) | 3643 (sql-get-product-feature product :sqli-options)) |
3505 | 3644 |
3506 ;; Set SQLi mode. | 3645 ;; Set SQLi mode. |
3507 (setq new-sqli-buffer (current-buffer)) | 3646 (setq new-sqli-buffer (current-buffer)) |
3508 (let ((sql-interactive-product product)) | 3647 (let ((sql-interactive-product product)) |
3509 (sql-interactive-mode)) | 3648 (sql-interactive-mode)) |
3510 | 3649 |
3511 ;; Set the new buffer name | 3650 ;; Set the new buffer name |
3512 (when new-name | 3651 (when new-name |
3513 (sql-rename-buffer new-name)) | 3652 (sql-rename-buffer new-name)) |
3514 | 3653 |
3515 ;; Set `sql-buffer' in the new buffer and the start buffer | 3654 ;; Set `sql-buffer' in the new buffer and the start buffer |
3516 (setq sql-buffer (buffer-name new-sqli-buffer)) | |
3517 (with-current-buffer start-buffer | |
3518 (setq sql-buffer (buffer-name new-sqli-buffer)) | 3655 (setq sql-buffer (buffer-name new-sqli-buffer)) |
3519 (run-hooks 'sql-set-sqli-hook)) | 3656 (with-current-buffer start-buffer |
3520 | 3657 (setq sql-buffer (buffer-name new-sqli-buffer)) |
3521 ;; All done. | 3658 (run-hooks 'sql-set-sqli-hook)) |
3522 (message "Login...done") | 3659 |
3523 (pop-to-buffer sql-buffer)))) | 3660 ;; All done. |
3661 (message "Login...done") | |
3662 (pop-to-buffer sql-buffer))))) | |
3524 (message "No default SQL product defined. Set `sql-product'."))) | 3663 (message "No default SQL product defined. Set `sql-product'."))) |
3525 | 3664 |
3526 (defun sql-comint (product params) | 3665 (defun sql-comint (product params) |
3527 "Set up a comint buffer to run the SQL processor. | 3666 "Set up a comint buffer to run the SQL processor. |
3528 | 3667 |
3529 PRODUCT is the SQL product. PARAMS is a list of strings which are | 3668 PRODUCT is the SQL product. PARAMS is a list of strings which are |
3530 passed as command line arguments." | 3669 passed as command line arguments." |
3531 (let ((program (sql-get-product-feature product :sqli-program)) | 3670 (let ((program (sql-get-product-feature product :sqli-program)) |
3532 (buf-name "SQL")) | 3671 (buf-name "SQL")) |
3672 ;; make sure we can find the program | |
3673 (unless (executable-find program) | |
3674 (error "Unable to locate SQL program \'%s\'" program)) | |
3533 ;; Make sure buffer name is unique | 3675 ;; Make sure buffer name is unique |
3534 (when (get-buffer (format "*%s*" buf-name)) | 3676 (when (sql-buffer-live-p (format "*%s*" buf-name)) |
3535 (setq buf-name (format "SQL-%s" product)) | 3677 (setq buf-name (format "SQL-%s" product)) |
3536 (when (get-buffer (format "*%s*" buf-name)) | 3678 (when (sql-buffer-live-p (format "*%s*" buf-name)) |
3537 (let ((i 1)) | 3679 (let ((i 1)) |
3538 (while (get-buffer (format "*%s*" | 3680 (while (sql-buffer-live-p |
3539 (setq buf-name | 3681 (format "*%s*" |
3540 (format "SQL-%s%d" product i)))) | 3682 (setq buf-name (format "SQL-%s%d" product i)))) |
3541 (setq i (1+ i)))))) | 3683 (setq i (1+ i)))))) |
3542 (set-buffer | 3684 (set-buffer |
3543 (apply 'make-comint buf-name program nil params)))) | 3685 (apply 'make-comint buf-name program nil params)))) |
3544 | 3686 |
3545 ;;;###autoload | 3687 ;;;###autoload |
3978 (setq params (append params (list sql-database)))) | 4120 (setq params (append params (list sql-database)))) |
3979 (if (not (string= "" sql-server)) | 4121 (if (not (string= "" sql-server)) |
3980 (setq params (append (list "-h" sql-server) params))) | 4122 (setq params (append (list "-h" sql-server) params))) |
3981 (if (not (string= "" sql-user)) | 4123 (if (not (string= "" sql-user)) |
3982 (setq params (append (list "-U" sql-user) params))) | 4124 (setq params (append (list "-U" sql-user) params))) |
4125 (if (not (= 0 sql-port)) | |
4126 (setq params (append (list "-p" sql-port) params))) | |
3983 (sql-comint product params))) | 4127 (sql-comint product params))) |
3984 | 4128 |
3985 | 4129 |
3986 | 4130 |
3987 ;;;###autoload | 4131 ;;;###autoload |