comparison lisp/progmodes/sql.el @ 109489:b4b02bfd4d95

SQL Mode Version2.4 - Improved login prompting * progmodes/sql.el: Version 2.4. Improved Login prompting. (sql-login-params): New widget definition. (sql-oracle-login-params, sql-mysql-login-params) (sql-solid-login-params, sql-sybase-login-params) (sql-informix-login-params, sql-ingres-login-params) (sql-ms-login-params, sql-postgres-login-params) (sql-interbase-login-params, sql-db2-login-params) (sql-linter-login-params): Use it. (sql-sqlite-login-params): Use it; Define "database" parameter as a file name. (sql-sqlite-program): Change to "sqlite3" (sql-comint-sqlite): Make sure database name is complete. (sql-for-each-login): New function. (sql-connect, sql-save-connection): Use it. (sql-get-login-ext): New function. (sql-get-login): Use it. (sql-make-alternate-buffer-name): Handle :file parameters.
author Michael Mauger <mmaug@yahoo.com>
date Thu, 22 Jul 2010 20:59:43 -0400
parents c9df47f7bbf3
children 232ba164887b
comparison
equal deleted inserted replaced
109488:ced3f5ab1023 109489:b4b02bfd4d95
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.3 8 ;; Version: 2.4
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 11 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
12 12
13 ;; This file is part of GNU Emacs. 13 ;; This file is part of GNU Emacs.
150 150
151 ;; 5) Define login parameters and command line formatting. 151 ;; 5) Define login parameters and command line formatting.
152 152
153 ;; (defcustom my-sql-xyz-login-params '(user password server database) 153 ;; (defcustom my-sql-xyz-login-params '(user password server database)
154 ;; "Login parameters to needed to connect to XyzDB." 154 ;; "Login parameters to needed to connect to XyzDB."
155 ;; :type '(repeat (choice 155 ;; :type 'sql-login-params
156 ;; (const user)
157 ;; (const password)
158 ;; (const server)
159 ;; (const database)
160 ;; (const port)))
161 ;; :group 'SQL) 156 ;; :group 'SQL)
162 ;; 157 ;;
163 ;; (sql-set-product-feature 'xyz 158 ;; (sql-set-product-feature 'xyz
164 ;; :sqli-login 'my-sql-xyz-login-params) 159 ;; :sqli-login 'my-sql-xyz-login-params)
165 160
284 "Default server or host." 279 "Default server or host."
285 :version "24.1" 280 :version "24.1"
286 :type 'number 281 :type 'number
287 :group 'SQL 282 :group 'SQL
288 :safe 'numberp) 283 :safe 'numberp)
284
285 ;; Login parameter type
286
287 (define-widget 'sql-login-params 'lazy
288 "Widget definition of the login parameters list"
289 :tag "Login Parameters"
290 :type '(repeat (choice
291 (const user)
292 (const password)
293 (choice :tag "server"
294 (const server)
295 (list :tag "file"
296 (const :format "" server)
297 (const :format "" :file)
298 regexp)
299 (list :tag "completion"
300 (const :format "" server)
301 (const :format "" :completion)
302 (restricted-sexp
303 :match-alternatives (listp symbolp))))
304 (choice :tag "database"
305 (const database)
306 (list :tag "file"
307 (const :format "" database)
308 (const :format "" :file)
309 regexp)
310 (list :tag "completion"
311 (const :format "" database)
312 (const :format "" :completion)
313 (restricted-sexp
314 :match-alternatives (listp symbolp))))
315 (const port))))
289 316
290 ;; SQL Product support 317 ;; SQL Product support
291 318
292 (defvar sql-interactive-product nil 319 (defvar sql-interactive-product nil
293 "Product under `sql-interactive-mode'.") 320 "Product under `sql-interactive-mode'.")
726 :version "20.8" 753 :version "20.8"
727 :group 'SQL) 754 :group 'SQL)
728 755
729 (defcustom sql-oracle-login-params '(user password database) 756 (defcustom sql-oracle-login-params '(user password database)
730 "List of login parameters needed to connect to Oracle." 757 "List of login parameters needed to connect to Oracle."
731 :type '(repeat (choice 758 :type 'sql-login-params
732 (const user)
733 (const password)
734 (const server)
735 (const database)
736 (const port)))
737 :version "24.1" 759 :version "24.1"
738 :group 'SQL) 760 :group 'SQL)
739 761
740 (defcustom sql-oracle-scan-on t 762 (defcustom sql-oracle-scan-on t
741 "Non-nil if placeholders should be replaced in Oracle SQLi. 763 "Non-nil if placeholders should be replaced in Oracle SQLi.
752 :type 'boolean 774 :type 'boolean
753 :group 'SQL) 775 :group 'SQL)
754 776
755 ;; Customization for SQLite 777 ;; Customization for SQLite
756 778
757 (defcustom sql-sqlite-program "sqlite" 779 (defcustom sql-sqlite-program "sqlite3"
758 "Command to start SQLite. 780 "Command to start SQLite.
759 781
760 Starts `sql-interactive-mode' after doing some setup." 782 Starts `sql-interactive-mode' after doing some setup."
761 :type 'file 783 :type 'file
762 :group 'SQL) 784 :group 'SQL)
765 "List of additional options for `sql-sqlite-program'." 787 "List of additional options for `sql-sqlite-program'."
766 :type '(repeat string) 788 :type '(repeat string)
767 :version "20.8" 789 :version "20.8"
768 :group 'SQL) 790 :group 'SQL)
769 791
770 (defcustom sql-sqlite-login-params '(database) 792 (defcustom sql-sqlite-login-params '((database :file ".*\\.db"))
771 "List of login parameters needed to connect to SQLite." 793 "List of login parameters needed to connect to SQLite."
772 :type '(repeat (choice 794 :type 'sql-login-params
773 (const user)
774 (const password)
775 (const server)
776 (const database)
777 (const port)))
778 :version "24.1" 795 :version "24.1"
779 :group 'SQL) 796 :group 'SQL)
780 797
781 ;; Customization for MySql 798 ;; Customization for MySql
782 799
795 :version "20.8" 812 :version "20.8"
796 :group 'SQL) 813 :group 'SQL)
797 814
798 (defcustom sql-mysql-login-params '(user password database server) 815 (defcustom sql-mysql-login-params '(user password database server)
799 "List of login parameters needed to connect to MySql." 816 "List of login parameters needed to connect to MySql."
800 :type '(repeat (choice 817 :type 'sql-login-params
801 (const user)
802 (const password)
803 (const server)
804 (const database)
805 (const port)))
806 :version "24.1" 818 :version "24.1"
807 :group 'SQL) 819 :group 'SQL)
808 820
809 ;; Customization for Solid 821 ;; Customization for Solid
810 822
815 :type 'file 827 :type 'file
816 :group 'SQL) 828 :group 'SQL)
817 829
818 (defcustom sql-solid-login-params '(user password server) 830 (defcustom sql-solid-login-params '(user password server)
819 "List of login parameters needed to connect to Solid." 831 "List of login parameters needed to connect to Solid."
820 :type '(repeat (choice 832 :type 'sql-login-params
821 (const user)
822 (const password)
823 (const server)
824 (const database)
825 (const port)))
826 :version "24.1" 833 :version "24.1"
827 :group 'SQL) 834 :group 'SQL)
828 835
829 ;; Customization for Sybase 836 ;; Customization for Sybase
830 837
842 :version "20.8" 849 :version "20.8"
843 :group 'SQL) 850 :group 'SQL)
844 851
845 (defcustom sql-sybase-login-params '(server user password database) 852 (defcustom sql-sybase-login-params '(server user password database)
846 "List of login parameters needed to connect to Sybase." 853 "List of login parameters needed to connect to Sybase."
847 :type '(repeat (choice 854 :type 'sql-login-params
848 (const user)
849 (const password)
850 (const server)
851 (const database)
852 (const port)))
853 :version "24.1" 855 :version "24.1"
854 :group 'SQL) 856 :group 'SQL)
855 857
856 ;; Customization for Informix 858 ;; Customization for Informix
857 859
862 :type 'file 864 :type 'file
863 :group 'SQL) 865 :group 'SQL)
864 866
865 (defcustom sql-informix-login-params '(database) 867 (defcustom sql-informix-login-params '(database)
866 "List of login parameters needed to connect to Informix." 868 "List of login parameters needed to connect to Informix."
867 :type '(repeat (choice 869 :type 'sql-login-params
868 (const user)
869 (const password)
870 (const server)
871 (const database)
872 (const port)))
873 :version "24.1" 870 :version "24.1"
874 :group 'SQL) 871 :group 'SQL)
875 872
876 ;; Customization for Ingres 873 ;; Customization for Ingres
877 874
882 :type 'file 879 :type 'file
883 :group 'SQL) 880 :group 'SQL)
884 881
885 (defcustom sql-ingres-login-params '(database) 882 (defcustom sql-ingres-login-params '(database)
886 "List of login parameters needed to connect to Ingres." 883 "List of login parameters needed to connect to Ingres."
887 :type '(repeat (choice 884 :type 'sql-login-params
888 (const user)
889 (const password)
890 (const server)
891 (const database)
892 (const port)))
893 :version "24.1" 885 :version "24.1"
894 :group 'SQL) 886 :group 'SQL)
895 887
896 ;; Customization for Microsoft 888 ;; Customization for Microsoft
897 889
909 :version "22.1" 901 :version "22.1"
910 :group 'SQL) 902 :group 'SQL)
911 903
912 (defcustom sql-ms-login-params '(user password server database) 904 (defcustom sql-ms-login-params '(user password server database)
913 "List of login parameters needed to connect to Microsoft." 905 "List of login parameters needed to connect to Microsoft."
914 :type '(repeat (choice 906 :type 'sql-login-params
915 (const user)
916 (const password)
917 (const server)
918 (const database)
919 (const port)))
920 :version "24.1" 907 :version "24.1"
921 :group 'SQL) 908 :group 'SQL)
922 909
923 ;; Customization for Postgres 910 ;; Customization for Postgres
924 911
941 :version "20.8" 928 :version "20.8"
942 :group 'SQL) 929 :group 'SQL)
943 930
944 (defcustom sql-postgres-login-params '(user database server) 931 (defcustom sql-postgres-login-params '(user database server)
945 "List of login parameters needed to connect to Postgres." 932 "List of login parameters needed to connect to Postgres."
946 :type '(repeat (choice 933 :type 'sql-login-params
947 (const user)
948 (const password)
949 (const server)
950 (const database)
951 (const port)))
952 :version "24.1" 934 :version "24.1"
953 :group 'SQL) 935 :group 'SQL)
954 936
955 ;; Customization for Interbase 937 ;; Customization for Interbase
956 938
967 :version "20.8" 949 :version "20.8"
968 :group 'SQL) 950 :group 'SQL)
969 951
970 (defcustom sql-interbase-login-params '(user password database) 952 (defcustom sql-interbase-login-params '(user password database)
971 "List of login parameters needed to connect to Interbase." 953 "List of login parameters needed to connect to Interbase."
972 :type '(repeat (choice 954 :type 'sql-login-params
973 (const user)
974 (const password)
975 (const server)
976 (const database)
977 (const port)))
978 :version "24.1" 955 :version "24.1"
979 :group 'SQL) 956 :group 'SQL)
980 957
981 ;; Customization for DB2 958 ;; Customization for DB2
982 959
993 :version "20.8" 970 :version "20.8"
994 :group 'SQL) 971 :group 'SQL)
995 972
996 (defcustom sql-db2-login-params nil 973 (defcustom sql-db2-login-params nil
997 "List of login parameters needed to connect to DB2." 974 "List of login parameters needed to connect to DB2."
998 :type '(repeat (choice 975 :type 'sql-login-params
999 (const user)
1000 (const password)
1001 (const server)
1002 (const database)
1003 (const port)))
1004 :version "24.1" 976 :version "24.1"
1005 :group 'SQL) 977 :group 'SQL)
1006 978
1007 ;; Customization for Linter 979 ;; Customization for Linter
1008 980
1019 :version "21.3" 991 :version "21.3"
1020 :group 'SQL) 992 :group 'SQL)
1021 993
1022 (defcustom sql-linter-login-params '(user password database server) 994 (defcustom sql-linter-login-params '(user password database server)
1023 "Login parameters to needed to connect to Linter." 995 "Login parameters to needed to connect to Linter."
1024 :type '(repeat (choice 996 :type 'sql-login-params
1025 (const user)
1026 (const password)
1027 (const server)
1028 (const database)
1029 (const port)))
1030 :version "24.1" 997 :version "24.1"
1031 :group 'SQL) 998 :group 'SQL)
1032 999
1033 1000
1034 1001
2202 keywords 2169 keywords
2203 (if append 2170 (if append
2204 (append old-val keywords) 2171 (append old-val keywords)
2205 (append keywords old-val)))))) 2172 (append keywords old-val))))))
2206 2173
2174 (defun sql-for-each-login (login-params body)
2175 "Iterates through login parameters and returns a list of results."
2176
2177 (delq nil
2178 (mapcar
2179 (lambda (param)
2180 (let ((token (or (and (listp param) (car param)) param))
2181 (type (or (and (listp param) (nth 1 param)) nil))
2182 (arg (or (and (listp param) (nth 2 param)) nil)))
2183
2184 (funcall body token type arg)))
2185 login-params)))
2186
2207 2187
2208 2188
2209 ;;; Functions to switch highlighting 2189 ;;; Functions to switch highlighting
2210 2190
2211 (defun sql-highlight-product () 2191 (defun sql-highlight-product ()
2363 2343
2364 (defun sql-read-passwd (prompt &optional default) 2344 (defun sql-read-passwd (prompt &optional default)
2365 "Read a password using PROMPT. Optional DEFAULT is password to start with." 2345 "Read a password using PROMPT. Optional DEFAULT is password to start with."
2366 (read-passwd prompt nil default)) 2346 (read-passwd prompt nil default))
2367 2347
2348 (defun sql-get-login-ext (prompt last-value history-var type arg)
2349 "Prompt user with extended login parameters.
2350
2351 If TYPE is nil, then the user is simply prompted for a string
2352 value.
2353
2354 If TYPE is `:file', then the user is prompted for a file
2355 name that must match the regexp pattern specified in the ARG
2356 argument.
2357
2358 If TYPE is `:completion', then the user is prompted for a string
2359 specified by ARG. (ARG is used as the PREDICATE argument to
2360 `completing-read'.)"
2361 (cond
2362 ((eq type nil)
2363 (read-from-minibuffer prompt last-value nil nil history-var))
2364
2365 ((eq type :file)
2366 (let ((use-dialog-box nil))
2367 (expand-file-name
2368 (read-file-name prompt
2369 (file-name-directory last-value) nil t
2370 (file-name-nondirectory last-value)
2371 (if arg
2372 `(lambda (f)
2373 (string-match (concat "\\<" ,arg "\\>")
2374 (file-name-nondirectory f)))
2375 nil)))))
2376
2377 ((eq type :completion)
2378 (completing-read prompt arg nil t last-value history-var))))
2379
2368 (defun sql-get-login (&rest what) 2380 (defun sql-get-login (&rest what)
2369 "Get username, password and database from the user. 2381 "Get username, password and database from the user.
2370 2382
2371 The variables `sql-user', `sql-password', `sql-server', and 2383 The variables `sql-user', `sql-password', `sql-server', and
2372 `sql-database' can be customized. They are used as the default values. 2384 `sql-database' can be customized. They are used as the default values.
2380 symbol `password', for the server if it contains the symbol 2392 symbol `password', for the server if it contains the symbol
2381 `server', and for the database if it contains the symbol 2393 `server', and for the database if it contains the symbol
2382 `database'. The members of WHAT are processed in the order in 2394 `database'. The members of WHAT are processed in the order in
2383 which they are provided. 2395 which they are provided.
2384 2396
2397 The tokens for `database' and `server' may also be lists to
2398 control or limit the values that can be supplied. These can be
2399 of the form:
2400
2401 \(database :file \".+\\\\.EXT\")
2402 \(database :completion FUNCTION)
2403
2404 The `server' token supports the same forms.
2405
2385 In order to ask the user for username, password and database, call the 2406 In order to ask the user for username, password and database, call the
2386 function like this: (sql-get-login 'user 'password 'database)." 2407 function like this: (sql-get-login 'user 'password 'database)."
2387 (interactive) 2408 (interactive)
2388 (while what 2409 (mapcar
2389 (cond 2410 (lambda (w)
2390 ((eq (car what) 'user) ; user 2411 (let ((token (or (and (listp w) (car w)) w))
2391 (setq sql-user 2412 (type (or (and (listp w) (nth 1 w)) nil))
2392 (read-from-minibuffer "User: " sql-user nil nil 2413 (arg (or (and (listp w) (nth 2 w)) nil)))
2393 'sql-user-history))) 2414
2394 ((eq (car what) 'password) ; password 2415 (cond
2395 (setq sql-password 2416 ((eq token 'user) ; user
2396 (sql-read-passwd "Password: " sql-password))) 2417 (setq sql-user
2397 2418 (read-from-minibuffer "User: " sql-user nil nil
2398 ((eq (car what) 'server) ; server 2419 'sql-user-history)))
2399 (setq sql-server 2420
2400 (read-from-minibuffer "Server: " sql-server nil nil 2421 ((eq token 'password) ; password
2401 'sql-server-history))) 2422 (setq sql-password
2402 ((eq (car what) 'port) ; port 2423 (sql-read-passwd "Password: " sql-password)))
2403 (setq sql-port 2424
2404 (read-from-minibuffer "Port: " sql-port nil nil 2425 ((eq token 'server) ; server
2405 'sql-port-history))) 2426 (setq sql-server
2406 ((eq (car what) 'database) ; database 2427 (sql-get-login-ext "Server: " sql-server
2407 (setq sql-database 2428 'sql-server-history type arg)))
2408 (read-from-minibuffer "Database: " sql-database nil nil 2429
2409 'sql-database-history)))) 2430 ((eq token 'database) ; database
2410 2431 (setq sql-database
2411 (setq what (cdr what)))) 2432 (sql-get-login-ext "Database: " sql-database
2433 'sql-database-history type arg)))
2434
2435 ((eq token 'port) ; port
2436 (setq sql-port
2437 (read-number "Port: " sql-port))))))
2438 what))
2412 2439
2413 (defun sql-find-sqli-buffer () 2440 (defun sql-find-sqli-buffer ()
2414 "Returns the current default SQLi buffer or nil. 2441 "Returns the current default SQLi buffer or nil.
2415 In order to qualify, the SQLi buffer must be alive, 2442 In order to qualify, the SQLi buffer must be alive,
2416 be in `sql-interactive-mode' and have a process." 2443 be in `sql-interactive-mode' and have a process."
2509 If all else fails, the alternate name would be the user and 2536 If all else fails, the alternate name would be the user and
2510 server/database name." 2537 server/database name."
2511 2538
2512 (let ((name "")) 2539 (let ((name ""))
2513 2540
2514 ;; Try using the :sqli-login setting 2541 ;; Build a name using the :sqli-login setting
2515 (when (string= "" (or name "")) 2542 (setq name
2516 (setq name 2543 (apply 'concat
2517 (apply 'concat 2544 (apply 'append nil
2518 (apply 'append nil 2545 (sql-for-each-login
2519 (mapcar 2546 (sql-get-product-feature sql-product :sqli-login)
2520 (lambda (v) 2547 (lambda (token type arg)
2521 (cond 2548 (cond
2522 ((eq v 'user) (list "/" sql-user)) 2549 ((eq token 'user) (list "/" sql-user))
2523 ((eq v 'server) (list "." sql-server)) 2550 ((eq token 'port) (list ":" sql-port))
2524 ((eq v 'database) (list "@" sql-database)) 2551 ((eq token 'server)
2525 ((eq v 'port) (list ":" sql-port)) 2552 (list "." (if (eq type :file)
2526 2553 (file-name-nondirectory sql-server)
2527 ((eq v 'password) nil) 2554 sql-server)))
2528 (t nil))) 2555 ((eq token 'database)
2529 (sql-get-product-feature sql-product :sqli-login)))))) 2556 (list "@" (if (eq type :file)
2530 2557 (file-name-nondirectory sql-database)
2531 ;; Default: username/server format 2558 sql-database)))
2532 (when (string= "" (or name "")) 2559
2533 (setq name 2560 ((eq token 'password) nil)
2534 (concat " " 2561 (t nil)))))))
2535 (if (string= "" sql-user) 2562
2536 (if (string= "" (user-login-name)) 2563
2537 () 2564 ;; If there's a connection, use it and the name thus far
2538 (concat (user-login-name) "/"))
2539 (concat sql-user "/"))
2540 (if (string= "" sql-database)
2541 (if (string= "" sql-server)
2542 (system-name)
2543 sql-server)
2544 sql-database))))
2545
2546 ;; Return the final string; prefixed by the connection name
2547 (if sql-connection 2565 (if sql-connection
2548 (format "<%s>%s" sql-connection (or name "")) 2566 (format "<%s>%s" sql-connection (or name ""))
2549 (substring (or name " ") 1)))) 2567
2568 ;; If there is no name, try to create something meaningful
2569 (if (string= "" (or name ""))
2570 (concat
2571 (if (string= "" sql-user)
2572 (if (string= "" (user-login-name))
2573 ()
2574 (concat (user-login-name) "/"))
2575 (concat sql-user "/"))
2576 (if (string= "" sql-database)
2577 (if (string= "" sql-server)
2578 (system-name)
2579 sql-server)
2580 sql-database))
2581
2582 ;; We've got a name, go with it (without the first punctuation char)
2583 (substring name 1)))))
2550 2584
2551 (defun sql-rename-buffer () 2585 (defun sql-rename-buffer ()
2552 "Rename a SQLi buffer." 2586 "Rename a SQLi buffer."
2553 (interactive) 2587 (interactive)
2554 (rename-buffer (format "*SQL: %s*" sql-alternate-buffer-name) t)) 2588 (rename-buffer (format "*SQL: %s*" sql-alternate-buffer-name) t))
2948 (insert (format "\nProcess %s %s\n" process event)) 2982 (insert (format "\nProcess %s %s\n" process event))
2949 (message "Process %s %s" process event))) 2983 (message "Process %s %s" process event)))
2950 2984
2951 2985
2952 2986
2953 ;;; Entry functions for different SQL interpreters. 2987 ;;; Connection handling
2954
2955 ;;;###autoload
2956 (defun sql-product-interactive (&optional product)
2957 "Run PRODUCT interpreter as an inferior process.
2958
2959 If buffer `*SQL*' exists but no process is running, make a new process.
2960 If buffer exists and a process is running, just switch to buffer `*SQL*'.
2961
2962 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2963 (interactive "P")
2964
2965 (setq product
2966 (cond
2967 ((equal product '(4)) ; Universal arg, prompt for product
2968 (intern (completing-read "SQL product: "
2969 (mapcar (lambda (info) (symbol-name (car info)))
2970 sql-product-alist)
2971 nil 'require-match
2972 (or (and sql-product (symbol-name sql-product)) "ansi"))))
2973 ((and product ; Product specified
2974 (symbolp product)) product)
2975 (t sql-product))) ; Default to sql-product
2976
2977 (if product
2978 (when (sql-get-product-feature product :sqli-comint-func)
2979 (if (and sql-buffer
2980 (buffer-live-p sql-buffer)
2981 (comint-check-proc sql-buffer))
2982 (pop-to-buffer sql-buffer)
2983
2984 ;; Is the current buffer in sql-mode and
2985 ;; there is a buffer local setting of sql-buffer
2986 (let* ((start-buffer
2987 (and (derived-mode-p 'sql-mode)
2988 (current-buffer)))
2989 (start-sql-buffer
2990 (and start-buffer
2991 (let (found)
2992 (dolist (var (buffer-local-variables))
2993 (and (consp var)
2994 (eq (car var) 'sql-buffer)
2995 (buffer-live-p (cdr var))
2996 (get-buffer-process (cdr var))
2997 (setq found (cdr var))))
2998 found)))
2999 new-sqli-buffer)
3000
3001 ;; Get credentials.
3002 (apply 'sql-get-login (sql-get-product-feature product :sqli-login))
3003
3004 ;; Connect to database.
3005 (message "Login...")
3006 (funcall (sql-get-product-feature product :sqli-comint-func)
3007 product
3008 (sql-get-product-feature product :sqli-options))
3009
3010 ;; Set SQLi mode.
3011 (setq sql-interactive-product product
3012 new-sqli-buffer (current-buffer)
3013 sql-buffer new-sqli-buffer)
3014 (sql-interactive-mode)
3015
3016 ;; Set `sql-buffer' in the start buffer
3017 (when (and start-buffer (not start-sql-buffer))
3018 (with-current-buffer start-buffer
3019 (setq sql-buffer new-sqli-buffer)))
3020
3021 ;; All done.
3022 (message "Login...done")
3023 (pop-to-buffer sql-buffer))))
3024 (message "No default SQL product defined. Set `sql-product'.")))
3025
3026 (defun sql-comint (product params)
3027 "Set up a comint buffer to run the SQL processor.
3028
3029 PRODUCT is the SQL product. PARAMS is a list of strings which are
3030 passed as command line arguments."
3031 (let ((program (sql-get-product-feature product :sqli-program)))
3032 (set-buffer
3033 (apply 'make-comint "SQL" program nil params))))
3034 2988
3035 ;;;###autoload 2989 ;;;###autoload
3036 (defun sql-connect (connection) 2990 (defun sql-connect (connection)
3037 "Connect to an interactive session using CONNECTION settings. 2991 "Connect to an interactive session using CONNECTION settings.
3038 2992
3080 ((eq (car v) 'sql-database) 'database) 3034 ((eq (car v) 'sql-database) 'database)
3081 ((eq (car v) 'sql-port) 'port) 3035 ((eq (car v) 'sql-port) 'port)
3082 (t (car v)))) 3036 (t (car v))))
3083 (cdr connect-set))) 3037 (cdr connect-set)))
3084 ;; the remaining params (w/o the connection params) 3038 ;; the remaining params (w/o the connection params)
3085 (rem-params (delq nil 3039 (rem-params (sql-for-each-login
3086 (mapcar 3040 login-params
3087 (lambda (l) 3041 (lambda (token type arg)
3088 (unless (member l set-params) 3042 (unless (member token set-params)
3089 l)) 3043 (if (or type arg)
3090 login-params))) 3044 (list token type arg)
3045 token)))))
3091 ;; Remember the connection 3046 ;; Remember the connection
3092 (sql-connection connection)) 3047 (sql-connection connection))
3093 3048
3094 ;; Set the remaining parameters and start the 3049 ;; Set the remaining parameters and start the
3095 ;; interactive session 3050 ;; interactive session
3123 ;; Add the new connection if it doesn't exist 3078 ;; Add the new connection if it doesn't exist
3124 (if (assoc name alist) 3079 (if (assoc name alist)
3125 (message "Connection <%s> already exists" name) 3080 (message "Connection <%s> already exists" name)
3126 (setq connect 3081 (setq connect
3127 (append (list name) 3082 (append (list name)
3128 (delq nil 3083 (sql-for-each-login
3129 (mapcar 3084 `(product ,@login)
3130 (lambda (param) 3085 (lambda (token type arg)
3131 (cond 3086 (cond
3132 ((eq param 'product) `(sql-product (quote ,sql-product))) 3087 ((eq token 'product) `(sql-product ',sql-product))
3133 ((eq param 'user) `(sql-user ,sql-user)) 3088 ((eq token 'user) `(sql-user ,sql-user))
3134 ((eq param 'database) `(sql-database ,sql-database)) 3089 ((eq token 'database) `(sql-database ,sql-database))
3135 ((eq param 'server) `(sql-server ,sql-server)) 3090 ((eq token 'server) `(sql-server ,sql-server))
3136 ((eq param 'port) `(sql-port ,sql-port)))) 3091 ((eq token 'port) `(sql-port ,sql-port)))))))
3137 (append (list 'product) login)))))
3138 3092
3139 (setq alist (append alist (list connect))) 3093 (setq alist (append alist (list connect)))
3140 3094
3141 ;; confirm whether we want to save the connections 3095 ;; confirm whether we want to save the connections
3142 (if (yes-or-no-p "Save the connections for future sessions? ") 3096 (if (yes-or-no-p "Save the connections for future sessions? ")
3152 (format "Connection <%s>" (car conn)) 3106 (format "Connection <%s>" (car conn))
3153 (list 'sql-connect (car conn)) 3107 (list 'sql-connect (car conn))
3154 t)) 3108 t))
3155 sql-connection-alist) 3109 sql-connection-alist)
3156 tail)) 3110 tail))
3111
3112
3113
3114 ;;; Entry functions for different SQL interpreters.
3115
3116 ;;;###autoload
3117 (defun sql-product-interactive (&optional product)
3118 "Run PRODUCT interpreter as an inferior process.
3119
3120 If buffer `*SQL*' exists but no process is running, make a new process.
3121 If buffer exists and a process is running, just switch to buffer `*SQL*'.
3122
3123 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
3124 (interactive "P")
3125
3126 (setq product
3127 (cond
3128 ((equal product '(4)) ; Universal arg, prompt for product
3129 (intern (completing-read "SQL product: "
3130 (mapcar (lambda (info) (symbol-name (car info)))
3131 sql-product-alist)
3132 nil 'require-match
3133 (or (and sql-product (symbol-name sql-product)) "ansi"))))
3134 ((and product ; Product specified
3135 (symbolp product)) product)
3136 (t sql-product))) ; Default to sql-product
3137
3138 (if product
3139 (when (sql-get-product-feature product :sqli-comint-func)
3140 (if (and sql-buffer
3141 (buffer-live-p sql-buffer)
3142 (comint-check-proc sql-buffer))
3143 (pop-to-buffer sql-buffer)
3144
3145 ;; Is the current buffer in sql-mode and
3146 ;; there is a buffer local setting of sql-buffer
3147 (let* ((start-buffer
3148 (and (derived-mode-p 'sql-mode)
3149 (current-buffer)))
3150 (start-sql-buffer
3151 (and start-buffer
3152 (let (found)
3153 (dolist (var (buffer-local-variables))
3154 (and (consp var)
3155 (eq (car var) 'sql-buffer)
3156 (buffer-live-p (cdr var))
3157 (get-buffer-process (cdr var))
3158 (setq found (cdr var))))
3159 found)))
3160 new-sqli-buffer)
3161
3162 ;; Get credentials.
3163 (apply 'sql-get-login (sql-get-product-feature product :sqli-login))
3164
3165 ;; Connect to database.
3166 (message "Login...")
3167 (funcall (sql-get-product-feature product :sqli-comint-func)
3168 product
3169 (sql-get-product-feature product :sqli-options))
3170
3171 ;; Set SQLi mode.
3172 (setq sql-interactive-product product
3173 new-sqli-buffer (current-buffer)
3174 sql-buffer new-sqli-buffer)
3175 (sql-interactive-mode)
3176
3177 ;; Set `sql-buffer' in the start buffer
3178 (when (and start-buffer (not start-sql-buffer))
3179 (with-current-buffer start-buffer
3180 (setq sql-buffer new-sqli-buffer)))
3181
3182 ;; All done.
3183 (message "Login...done")
3184 (pop-to-buffer sql-buffer))))
3185 (message "No default SQL product defined. Set `sql-product'.")))
3186
3187 (defun sql-comint (product params)
3188 "Set up a comint buffer to run the SQL processor.
3189
3190 PRODUCT is the SQL product. PARAMS is a list of strings which are
3191 passed as command line arguments."
3192 (let ((program (sql-get-product-feature product :sqli-program)))
3193 (set-buffer
3194 (apply 'make-comint "SQL" program nil params))))
3157 3195
3158 ;;;###autoload 3196 ;;;###autoload
3159 (defun sql-oracle () 3197 (defun sql-oracle ()
3160 "Run sqlplus by Oracle as an inferior process. 3198 "Run sqlplus by Oracle as an inferior process.
3161 3199
3316 "Create comint buffer and connect to SQLite." 3354 "Create comint buffer and connect to SQLite."
3317 ;; Put all parameters to the program (if defined) in a list and call 3355 ;; Put all parameters to the program (if defined) in a list and call
3318 ;; make-comint. 3356 ;; make-comint.
3319 (let ((params)) 3357 (let ((params))
3320 (if (not (string= "" sql-database)) 3358 (if (not (string= "" sql-database))
3321 (setq params (append (list sql-database) params))) 3359 (setq params (append (list (expand-file-name sql-database))
3360 params)))
3322 (setq params (append options params)) 3361 (setq params (append options params))
3323 (sql-comint product params))) 3362 (sql-comint product params)))
3324 3363
3325 3364
3326 3365