(sql-help): Doc fix.
[emacs.git] / lisp / progmodes / sql.el
blob48ae7af0ac3afafa1666625590533a79c7c2cb9c
1 ;;; sql.el --- specialized comint.el for SQL interpreters
3 ;; Copyright (C) 1998, 1999 Free Software Foundation, Inc.
5 ;; Author: Alex Schroeder <a.schroeder@bsiag.ch>
6 ;; Maintainer: Alex Schroeder <a.schroeder@bsiag.ch>
7 ;; Version: 1.2.1
8 ;; Keywords: processes SQL
10 ;; This file is part of GNU Emacs.
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
27 ;;; Commentary:
29 ;; Please send me bug reports and bug fixes so that I can merge them
30 ;; into the master source.
32 ;; You can get the latest version of this file from my homepage
33 ;; <URL:http://www.geocities.com/TimesSquare/6120/emacs.html>.
35 ;; This file provides a sql-mode and a sql-interactive-mode. My goals
36 ;; were two simple modes providing syntactic hilighting. The
37 ;; interactive mode had to provide a command-line history; the other
38 ;; mode had to provide "send region/buffer to SQL interpreter"
39 ;; functions. "simple" in this context means easy to use, easy to
40 ;; maintain and little or no bells and whistles.
42 ;; If anybody feels like extending this sql mode, take a look at the
43 ;; above mentioned modes and write a sqlx-mode on top of this one. If
44 ;; this proves to be difficult, please suggest changes that will
45 ;; facilitate your plans.
47 ;; sql-interactive-mode is used to interact with a SQL interpreter
48 ;; process in the *SQL* buffer. The *SQL* buffer is created by
49 ;; calling a SQL interpreter-specific entry function. Do *not* call
50 ;; sql-interactive-mode by itself.
52 ;; The list of currently supported interpreters and the corresponding
53 ;; entry function used to create the *SQL* buffers is shown with
54 ;; `sql-help' (M-x sql-help).
56 ;; Since sql-interactive-mode is built on top of the general
57 ;; command-interpreter-in-a-buffer mode (comint mode), it shares a
58 ;; common base functionality, and a common set of bindings, with all
59 ;; modes derived from comint mode. This makes these modes easier to
60 ;; use.
62 ;; sql-mode can be used to enable syntactic hilighting for SQL
63 ;; statements in another buffer. SQL statements can then be sent to
64 ;; the SQL process in the *SQL* buffer. sql-mode has already been
65 ;; used as a template to a simple PL/SQL mode.
67 ;; For documentation on the functionality provided by comint mode, and
68 ;; the hooks available for customising it, see the file `comint.el'.
70 ;; Hint for newbies: take a look at `dabbrev-expand' and `abbrev-mode'.
72 ;;; Requirements for Emacs 19.34:
74 ;; If you are using Emacs 19.34, you will have to get and install
75 ;; the file regexp-opt.el
76 ;; <URL:ftp://ftp.ifi.uio.no/pub/emacs/emacs-20.3/lisp/emacs-lisp/regexp-opt.el>
77 ;; and the custom package
78 ;; <URL:http://www.dina.kvl.dk/~abraham/custom/>.
80 ;;; Bugs:
82 ;; Using sql-ms (isql by Microsoft): When commands with syntax errors
83 ;; or execution errors are executed, there is no server feedback.
84 ;; This happens in stored procedures for example. The server messages
85 ;; only appear after the process is exited. This makes things
86 ;; somewhat unreliable.
88 ;;; To Do:
90 ;; Add better hilight support for other brands; there is a bias towards
91 ;; Oracle because that's what I use at work. Anybody else just send in
92 ;; your lists of reserved words, keywords and builtin functions!
94 ;; Add different hilighting levels.
96 ;;; Thanks to all the people who helped me out:
98 ;; Kai Blauberg <kai.blauberg@metla.fi>
99 ;; <ibalaban@dalet.com>
100 ;; Yair Friedman <yfriedma@JohnBryce.Co.Il>
101 ;; Gregor Zych <zych@pool.informatik.rwth-aachen.de>
102 ;; nino <nino@inform.dk>
105 ;;; Code:
107 (require 'comint)
108 ;; Need the following to allow GNU Emacs 19 to compile the file.
109 (require 'regexp-opt)
110 (require 'custom)
112 ;;; Allow customization
114 (defgroup SQL nil
115 "Running a SQL interpreter from within Emacs buffers"
116 :group 'processes)
118 ;; These three variables will be used as defaults, if set.
120 (defcustom sql-user ""
121 "*Default username."
122 :type 'string
123 :group 'SQL)
125 (defcustom sql-password ""
126 "*Default password.
128 Storing your password in a textfile such as ~/.emacs could be dangerous.
129 Customizing your password will store it in your ~/.emacs file."
130 :type 'string
131 :group 'SQL)
133 (defcustom sql-database ""
134 "*Default database."
135 :type 'string
136 :group 'SQL)
138 (defcustom sql-server ""
139 "*Default server.
141 Currently, this is only used by MS isql."
142 :type 'string
143 :group 'SQL)
145 (defcustom sql-pop-to-buffer-after-send-region nil
146 "*If t, pop to the buffer SQL statements are sent to.
148 After a call to `sql-send-region' or `sql-send-buffer',
149 the window is split and the SQLi buffer is shown. If this
150 variable is not nil, that buffer's window will be selected
151 by calling `pop-to-buffer'. If this variable is nil, that
152 buffer is shown using `display-buffer'."
153 :type 'string
154 :group 'SQL)
156 ;; The usual hooks
158 (defcustom sql-interactive-mode-hook '()
159 "*Hook for customising `sql-interactive-mode'."
160 :type 'hook
161 :group 'SQL)
163 (defcustom sql-mode-hook '()
164 "*Hook for customising `sql-mode'."
165 :type 'hook
166 :group 'SQL)
168 ;; Customisation for Oracle
170 (defcustom sql-oracle-program "sqlplus"
171 "*Command to start sqlplus by Oracle.
173 Starts `sql-interactive-mode' after doing some setup.
175 Under NT, \"sqlplus\" usually starts the sqlplus \"GUI\". In order to
176 start the sqlplus console, use \"plus33\" or something similar. You
177 will find the file in your Orant\\bin directory.
179 The program can also specify a TCP connection. See `make-comint'."
180 :type 'file
181 :group 'SQL)
183 ;; Customisation for MySql
185 (defcustom sql-mysql-program "mysql"
186 "*Command to start mysql by TcX.
188 Starts `sql-interactive-mode' after doing some setup.
190 The program can also specify a TCP connection. See `make-comint'."
191 :type 'file
192 :group 'SQL)
194 ;; Customisation for SyBase
196 (defcustom sql-sybase-program "isql"
197 "*Command to start isql by SyBase.
199 Starts `sql-interactive-mode' after doing some setup.
201 The program can also specify a TCP connection. See `make-comint'."
202 :type 'file
203 :group 'SQL)
205 ;; Customisation for Informix
207 (defcustom sql-informix-program "dbaccess"
208 "*Command to start dbaccess by Informix.
210 Starts `sql-interactive-mode' after doing some setup.
212 The program can also specify a TCP connection. See `make-comint'."
213 :type 'file
214 :group 'SQL)
216 ;; Customisation for Ingres
218 (defcustom sql-ingres-program "sql"
219 "*Command to start sql by Ingres.
221 Starts `sql-interactive-mode' after doing some setup.
223 The program can also specify a TCP connection. See `make-comint'."
224 :type 'file
225 :group 'SQL)
227 ;; Customisation for Microsoft
229 (defcustom sql-ms-program "isql"
230 "*Command to start isql by Microsoft.
232 Starts `sql-interactive-mode' after doing some setup.
234 The program can also specify a TCP connection. See `make-comint'."
235 :type 'file
236 :group 'SQL)
238 ;; Customisation for Postgres
240 (defcustom sql-postgres-program "psql"
241 "Command to start psql by Postgres.
243 Starts `sql-interactive-mode' after doing some setup.
245 The program can also specify a TCP connection. See `make-comint'."
246 :type 'file
247 :group 'SQL)
251 ;;; Variables which do not need customization
253 (defvar sql-user-history nil
254 "History of usernames used.")
256 (defvar sql-database-history nil
257 "History of databases used.")
259 (defvar sql-server-history nil
260 "History of servers used.")
262 ;; Passwords are not kept in a history.
264 (defvar sql-buffer nil
265 "Current *SQL* buffer.")
267 (defvar sql-prompt-regexp nil
268 "Prompt used to initialize `comint-prompt-regexp'.
270 You can change `comint-prompt-regexp' on `sql-interactive-mode-hook'.")
272 (defvar sql-prompt-length 0
273 "Prompt used to set `left-margin' in `sql-interactive-mode'.
275 You can change it on `sql-interactive-mode-hook'.")
277 ;; Keymap for sql-interactive-mode, based on comint-mode-map.
279 (if (not (string-match "XEmacs\\|Lucid" emacs-version))
280 (defvar sql-interactive-mode-map
281 (let ((map (nconc (make-sparse-keymap) comint-mode-map)))
282 (define-key map "\C-j" 'sql-accumulate-and-indent)
283 (define-key map "\C-c\C-w" 'sql-copy-column)
284 map)
285 "Mode map used for `sql-interactive-mode'.")
286 ;; XEmacs
287 (defvar sql-interactive-mode-map nil)
288 (if (not sql-interactive-mode-map)
289 (let ((map (make-keymap)))
290 (set-keymap-parents map (list comint-mode-map))
291 (set-keymap-name map 'sql-interactive-mode-map)
292 (define-key map "\C-j" 'sql-accumulate-and-indent)
293 (define-key map "\C-c\C-w" 'sql-copy-column)
294 (setq sql-interactive-mode-map map))))
296 ;; Keymap for sql-mode.
298 (defvar sql-mode-map
299 (let ((map (make-sparse-keymap)))
300 (define-key map "\C-c\C-r" 'sql-send-region)
301 (define-key map "\C-c\C-b" 'sql-send-buffer)
302 (define-key map "\t" 'indent-relative)
303 map)
304 "Mode map used for `sql-mode'.")
306 ;; easy menu for sql-mode.
308 (easy-menu-define
309 sql-mode-menu sql-mode-map
310 "Menu for `sql-mode'."
311 '("SQL"
312 ["Send Region" sql-send-region mark-active]
313 ["Send Buffer" sql-send-buffer t]
314 ["Pop to SQLi buffer after send"
315 sql-toggle-pop-to-buffer-after-send-region
316 :style toggle
317 :selected sql-pop-to-buffer-after-send-region]))
319 ;; Abbreviations -- if you want more of them, define them in your
320 ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
322 (defvar sql-mode-abbrev-table nil
323 "Abbrev table used in `sql-mode' and `sql-interactive-mode'.")
324 (if sql-mode-abbrev-table
326 (let ((wrapper))
327 (define-abbrev-table 'sql-mode-abbrev-table ())
328 (define-abbrev sql-mode-abbrev-table "ins" "insert" nil)
329 (define-abbrev sql-mode-abbrev-table "upd" "update" nil)
330 (define-abbrev sql-mode-abbrev-table "del" "delete" nil)
331 (define-abbrev sql-mode-abbrev-table "sel" "select" nil)))
333 ;; Syntax Table
335 (defvar sql-mode-syntax-table
336 (let ((table (make-syntax-table)))
337 ;; C-style comments /**/ (see elisp manual "Syntax Flags"))
338 (modify-syntax-entry ?/ ". 14" table)
339 (modify-syntax-entry ?* ". 23" table)
340 ;; double-dash starts comment
341 (modify-syntax-entry ?- ". 12b" table)
342 ;; newline and formfeed end coments
343 (modify-syntax-entry ?\n "> b" table)
344 (modify-syntax-entry ?\f "> b" table)
345 ;; single quotes (') quotes delimit strings
346 (modify-syntax-entry ?' "\"" table)
347 table)
348 "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
350 ;; Font lock support
352 (defvar sql-mode-ansi-font-lock-keywords nil
353 "ANSI SQL keywords used by font-lock.
355 This variable is used by `sql-mode' and `sql-interactive-mode'. The
356 regular expressions are created during compilation by calling the
357 function `regexp-opt'. Therefore, take a look at the source before
358 you define your own sql-mode-ansi-font-lock-keywords. You may want to
359 add functions and PL/SQL keywords.")
360 (if sql-mode-ansi-font-lock-keywords
362 (let ((ansi-keywords (eval-when-compile
363 (concat "\\b"
364 (regexp-opt '(
365 "authorization" "avg" "begin" "close" "cobol" "commit"
366 "continue" "count" "declare" "double" "end" "escape"
367 "exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator"
368 "key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli"
369 "precision" "primary" "procedure" "references" "rollback"
370 "schema" "section" "some" "sqlcode" "sqlerror" "sum" "work") t) "\\b")))
371 (ansi-reserved-words (eval-when-compile
372 (concat "\\b"
373 (regexp-opt '(
374 "all" "and" "any" "as" "asc" "between" "by" "check" "create"
375 "current" "default" "delete" "desc" "distinct" "exists" "float" "for"
376 "from" "grant" "group" "having" "in" "insert" "into" "is"
377 "like" "not" "null" "of" "on" "option" "or" "order" "privileges"
378 "public" "select" "set" "table" "to" "union" "unique"
379 "update" "user" "values" "view" "where" "with") t) "\\b")))
380 (ansi-types (eval-when-compile
381 (concat "\\b"
382 (regexp-opt '(
383 ;; ANSI Keywords that look like types
384 "character" "cursor" "dec" "int" "real"
385 ;; ANSI Reserved Word that look like types
386 "char" "integer" "smallint" ) t) "\\b"))))
387 (setq sql-mode-ansi-font-lock-keywords
388 (list (cons ansi-keywords 'font-lock-function-name-face)
389 (cons ansi-reserved-words 'font-lock-keyword-face)
390 (cons ansi-types 'font-lock-type-face)))))
392 (defvar sql-mode-oracle-font-lock-keywords nil
393 "Oracle SQL keywords used by font-lock.
395 This variable is used by `sql-mode' and `sql-interactive-mode'. The
396 regular expressions are created during compilation by calling the
397 function `regexp-opt'. Therefore, take a look at the source before
398 you define your own sql-mode-oracle-font-lock-keywords. You may want
399 to add functions and PL/SQL keywords.")
400 (if sql-mode-oracle-font-lock-keywords
402 (let ((oracle-keywords (eval-when-compile
403 (concat "\\b"
404 (regexp-opt '(
405 "admin" "after" "allocate" "analyze" "archive" "archivelog" "backup"
406 "become" "before" "block" "body" "cache" "cancel" "cascade" "change"
407 "checkpoint" "compile" "constraint" "constraints" "contents"
408 "controlfile" "cycle" "database" "datafile" "dba" "disable" "dismount"
409 "dump" "each" "enable" "events" "except" "exceptions" "execute"
410 "explain" "extent" "externally" "flush" "force" "freelist" "freelists"
411 "function" "groups" "including" "initrans" "instance" "layer" "link"
412 "lists" "logfile" "manage" "manual" "maxdatafiles" "maxinistances"
413 "maxlogfiles" "maxloghistory" "maxlogmembers" "maxtrans" "maxvalue"
414 "minextents" "minvalue" "mount" "new" "next" "noarchivelog" "nocache"
415 "nocycle" "nomaxvalue" "nominvalue" "none" "noorder" "noresetlogs"
416 "normal" "nosort" "off" "old" "only" "optimal" "own" "package"
417 "parallel" "pctincrease" "pctused" "plan" "private" "profile" "quota"
418 "read" "recover" "referencing" "resetlogs" "restricted" "reuse" "role"
419 "roles" "savepoint" "scn" "segment" "sequence" "shared" "snapshot"
420 "sort" "statement_id" "statistics" "stop" "storage" "switch" "system"
421 "tables" "tablespace" "temporary" "thread" "time" "tracing"
422 "transaction" "triggers" "truncate" "under" "unlimited" "until" "use"
423 "using" "when" "write") t) "\\b")))
424 (oracle-reserved-words (eval-when-compile
425 (concat "\\b"
426 (regexp-opt '(
427 "access" "add" "alter" "audit" "cluster" "column" "comment" "compress"
428 "connect" "drop" "else" "exclusive" "file" "grant"
429 "identified" "immediate" "increment" "index" "initial" "intersect"
430 "level" "lock" "long" "maxextents" "minus" "mode" "modify" "noaudit"
431 "nocompress" "nowait" "number" "offline" "online" "pctfree" "prior"
432 "raw" "rename" "resource" "revoke" "row" "rowlabel" "rownum"
433 "rows" "session" "share" "size" "start" "successful" "synonym" "sysdate"
434 "then" "trigger" "uid" "validate" "whenever") t) "\\b")))
435 (oracle-types (eval-when-compile
436 (concat "\\b"
437 (regexp-opt '(
438 ;; Oracle Keywords that look like types
439 ;; Oracle Reserved Words that look like types
440 "date" "decimal" "rowid" "varchar" "varchar2") t) "\\b")))
441 (oracle-builtin-functions (eval-when-compile
442 (concat "\\b"
443 (regexp-opt '(
444 ;; Misc Oracle builtin functions
445 "abs" "add_months" "ascii" "avg" "ceil" "chartorowid" "chr" "concat"
446 "convert" "cos" "cosh" "count" "currval" "decode" "dump" "exp" "floor"
447 "glb" "greatest" "greatest_lb" "hextoraw" "initcap" "instr" "instrb"
448 "last_day" "least" "least_ub" "length" "lengthb" "ln" "log" "lower"
449 "lpad" "ltrim" "lub" "max" "min" "mod" "months_between" "new_time"
450 "next_day" "nextval" "nls_initcap" "nls_lower" "nls_upper" "nlssort"
451 "nvl" "power" "rawtohex" "replace" "round" "rowidtochar" "rpad"
452 "rtrim" "sign" "sin" "sinh" "soundex" "sqlcode" "sqlerrm" "sqrt"
453 "stddev" "sum" "substr" "substrb" "tan" "tanh" "to_char"
454 "to_date" "to_label" "to_multi_byte" "to_number" "to_single_byte"
455 "translate" "trunc" "uid" "upper" "userenv" "variance" "vsize") t) "\\b"))))
456 (setq sql-mode-oracle-font-lock-keywords
457 (append sql-mode-ansi-font-lock-keywords
458 (list (cons oracle-keywords 'font-lock-function-name-face)
459 (cons oracle-reserved-words 'font-lock-keyword-face)
460 ;; XEmacs doesn't have font-lock-builtin-face
461 (if (string-match "XEmacs\\|Lucid" emacs-version)
462 (cons oracle-builtin-functions 'font-lock-preprocessor-face)
463 ;; GNU Emacs 19 doesn't have it either
464 (if (string-match "GNU Emacs 19" emacs-version)
465 (cons oracle-builtin-functions 'font-lock-function-name-face)
466 ;; Emacs
467 (cons oracle-builtin-functions 'font-lock-builtin-face)))
468 (cons oracle-types 'font-lock-type-face))))))
470 (defvar sql-mode-postgres-font-lock-keywords nil
471 "Postgres SQL keywords used by font-lock.
473 This variable is used by `sql-mode' and `sql-interactive-mode'. The
474 regular expressions are created during compilation by calling the
475 function `regexp-opt'. Therefore, take a look at the source before
476 you define your own sql-mode-postgres-font-lock-keywords.")
478 (if sql-mode-postgres-font-lock-keywords
480 (let ((postgres-reserved-words (eval-when-compile
481 (concat "\\b"
482 (regexp-opt '(
483 "language"
484 ) t) "\\b")))
485 (postgres-types (eval-when-compile
486 (concat "\\b"
487 (regexp-opt '(
488 "bool" "box" "circle" "char" "char2" "char4" "char8" "char16" "date"
489 "float4" "float8" "int2" "int4" "int8" "line" "lseg" "money" "path"
490 "point" "polygon" "serial" "text" "time" "timespan" "timestamp" "varchar"
491 ) t)"\\b")))
492 (postgres-builtin-functions (eval-when-compile
493 (concat "\\b"
494 (regexp-opt '(
495 ;; Misc Postgres builtin functions
496 "abstime" "age" "area" "box" "center" "date_part" "date_trunc"
497 "datetime" "dexp" "diameter" "dpow" "float" "float4" "height"
498 "initcap" "integer" "isclosed" "isfinite" "isoldpath" "isopen"
499 "length" "lower" "lpad" "ltrim" "pclose" "point" "points" "popen"
500 "position" "radius" "reltime" "revertpoly" "rpad" "rtrim" "substr"
501 "substring" "text" "timespan" "translate" "trim" "upgradepath"
502 "upgradepoly" "upper" "varchar" "width"
503 ) t) "\\b"))))
504 (setq sql-mode-postgres-font-lock-keywords
505 (append sql-mode-ansi-font-lock-keywords
506 (list (cons postgres-reserved-words 'font-lock-keyword-face)
507 ;; XEmacs doesn't have 'font-lock-builtin-face
508 (if (string-match "XEmacs\\|Lucid" emacs-version)
509 (cons postgres-builtin-functions 'font-lock-preprocessor-face)
510 ;; Emacs
511 (cons postgres-builtin-functions 'font-lock-builtin-face))
512 (cons postgres-types 'font-lock-type-face))))))
515 (defvar sql-mode-font-lock-keywords sql-mode-ansi-font-lock-keywords
516 "SQL keywords used by font-lock.
518 This variable defaults to `sql-mode-ansi-font-lock-keywords'. This is
519 used for the default `font-lock-defaults' value in `sql-mode'. This
520 can be changed by some entry functions to provide more hilighting.")
524 ;;; Small functions
526 (defun sql-accumulate-and-indent ()
527 "Continue SQL statement on the next line."
528 (interactive)
529 ;; comint-accumulate is a Emacs 20.X thingie
530 (if (not (string-match "XEmacs\\|Lucid\\|GNU Emacs 19" emacs-version))
531 (comint-accumulate))
532 (indent-according-to-mode))
534 ;;;###autoload
535 (defun sql-help ()
536 "Shows short help for the SQL modes.
538 Use an entry function to open an interactive SQL buffer. This buffer is
539 usually named *SQL*. The name of the major mode is SQLi.
541 Use the following commands to start a specific SQL interpreter:
543 psql (PostGres): \\[sql-postgres]
545 Other non-free SQL implementations are also supported:
547 mysql: \\[sql-mysql]
548 SQL*Plus: \\[sql-oracle]
549 dbaccess Informix: \\[sql-informix]
550 Sybase: \\[sql-sybase]
551 Ingres: \\[sql-ingres]
552 Microsoft: \\[sql-ms]
554 But we urge you to choose a free implementation instead of these.
556 Once you have the SQLi buffer, you can enter SQL statements in the
557 buffer. The output generated is appended to the buffer and a new prompt
558 is generated. See the In/Out menu in the SQLi buffer for some functions
559 that help you navigate through the buffer, the input history, etc.
561 Put a line with a call to autoload into your `~/.emacs' file for each
562 entry function you want to use regularly:
564 \(autoload 'sql-postgres \"sql\" \"Interactive SQL mode.\" t)
566 If you have a really complex SQL statement or if you are writing a
567 procedure, you can do this in a separate buffer. Put the new buffer in
568 `sql-mode' by calling \\[sql-mode]. The name of this buffer can be
569 anything. The name of the major mode is SQL.
571 In this SQL buffer (SQL mode), you can send the region or the entire
572 buffer to the interactive SQL buffer (SQLi mode). The results are
573 appended to the SQLi buffer without disturbing your SQL buffer."
574 (interactive)
575 (describe-function 'sql-help))
577 (defun sql-read-passwd (prompt &optional default)
578 "Read a password using PROMPT.
579 Optional DEFAULT is password to start with. This function calls
580 `read-passwd' if it is available. If not, function
581 `ange-ftp-read-passwd' is called. This should always be available,
582 even in old versions of Emacs."
583 (if (fboundp 'read-passwd)
584 (read-passwd prompt nil default)
585 (unless (fboundp 'ange-ftp-read-passwd)
586 (autoload 'ange-ftp-read-passwd "ange-ftp"))
587 (ange-ftp-read-passwd prompt default)))
589 (defun sql-get-login (&rest what)
590 "Get username, password and database from the user.
592 The variables `sql-user', `sql-password', `sql-server' and
593 `sql-database' can be customised. They are used as the default
594 values. Usernames, servers and databases are stored in
595 `sql-user-history', `sql-server-history' and `database-history'.
596 Passwords are not stored in a history.
598 Parameter WHAT is a list of the arguments passed to this function.
599 The function asks for the username if WHAT contains symbol `user', for
600 the password if it contains symbol `password', for the server if it
601 contains symbol `server', and for the database if it contains symbol
602 `database'.
604 In order to ask the user for username, password and database, call the
605 function like this: (sql-get-login 'user 'password 'database)."
606 (interactive)
607 (if (memq 'user what)
608 (setq sql-user
609 (read-from-minibuffer "User: " sql-user nil nil
610 sql-user-history)))
611 (if (memq 'password what)
612 (setq sql-password
613 (sql-read-passwd "Password: " sql-password)))
614 (if (memq 'server what)
615 (setq sql-server
616 (read-from-minibuffer "Server: " sql-server nil nil
617 sql-server-history)))
618 (if (memq 'database what)
619 (setq sql-database
620 (read-from-minibuffer "Database: " sql-database nil nil
621 sql-database-history))))
623 (defun sql-copy-column ()
624 "Copy current column to the end of buffer.
625 Inserts SELECT or commas if appropriate."
626 (interactive)
627 (let ((column))
628 (save-excursion
629 (setq column (buffer-substring
630 (progn (forward-char 1) (backward-sexp 1) (point))
631 (progn (forward-sexp 1) (point))))
632 (goto-char (point-max))
633 (cond
634 ;; if empty command line, insert SELECT
635 ((save-excursion (beginning-of-line)
636 (looking-at (concat comint-prompt-regexp "$")))
637 (insert "SELECT "))
638 ;; else if appending to SELECT or ORDER BY, insert a comma
639 ((save-excursion
640 (re-search-backward "\\b\\(select\\|order by\\) .+"
641 (save-excursion (beginning-of-line) (point)) t))
642 (insert ", "))
643 ;; else insert a space
645 (if (eq (preceding-char) ? )
647 (insert " "))))
648 ;; in any case, insert the column
649 (insert column)
650 (message "%s" column))))
654 ;;; Sending the region to the SQLi buffer.
656 (defun sql-send-region (start end)
657 "Send a region to the SQL process."
658 (interactive "r")
659 (if (buffer-live-p sql-buffer)
660 (save-excursion
661 (comint-send-region sql-buffer start end)
662 (if (string-match "\n$" (buffer-substring start end))
664 (comint-send-string sql-buffer "\n"))
665 (message "Sent string to buffer %s." (buffer-name sql-buffer))
666 (if sql-pop-to-buffer-after-send-region
667 (pop-to-buffer sql-buffer)
668 (display-buffer sql-buffer)))
669 (message "No SQL process started.")))
671 (defun sql-send-buffer ()
672 "Send the buffer contents to the SQL process."
673 (interactive)
674 (sql-send-region (point-min) (point-max)))
676 (defun sql-toggle-pop-to-buffer-after-send-region (&optional value)
677 "Toggle `sql-pop-to-buffer-after-send-region'.
679 If given the optional parameter VALUE, sets
680 sql-toggle-pop-to-buffer-after-send-region to VALUE."
681 (interactive "P")
682 (if value
683 (setq sql-pop-to-buffer-after-send-region value)
684 (setq sql-pop-to-buffer-after-send-region
685 (null sql-pop-to-buffer-after-send-region ))))
689 ;;; SQL mode -- uses SQL interactive mode
691 ;;;###autoload
692 (defun sql-mode ()
693 "Major mode to edit SQL.
695 You can send SQL statements to the *SQL* buffer using
696 \\[sql-send-region]. Such a buffer must exist before you can do this.
697 See `sql-help'.
699 \\{sql-mode-map}
700 Customization: Entry to this mode runs the `sql-mode-hook'.
702 Here is an example for your .emacs file. It opens every file ending in
703 .sql with sql-mode.
705 \(setq auto-mode-alist (append auto-mode-alist
706 \(list '(\"\\\\.sql$\" . sql-mode))))"
707 (interactive)
708 (kill-all-local-variables)
709 (setq major-mode 'sql-mode)
710 (setq mode-name "SQL")
711 (use-local-map sql-mode-map)
712 (set-syntax-table sql-mode-syntax-table)
713 (make-local-variable 'font-lock-defaults)
714 (setq font-lock-defaults '(sql-mode-font-lock-keywords
715 nil t ((95 . "w") (46 . "w"))))
716 (make-local-variable 'comment-start)
717 (setq comment-start "--")
718 (setq local-abbrev-table sql-mode-abbrev-table)
719 (setq abbrev-all-caps 1)
720 (run-hooks 'sql-mode-hook))
724 ;;; SQL interactive mode
726 (put 'sql-interactive-mode 'mode-class 'special)
728 (defun sql-interactive-mode ()
729 "Major mode to use a SQL interpreter interactively.
731 Do not call this function by yourself. The environment must be
732 initialized by an entry function specific for the SQL interpreter. See
733 `sql-help' for a list of available entry functions.
735 \\[comint-send-input] after the end of the process' output sends the
736 text from the end of process to the end of the current line.
737 \\[comint-send-input] before end of process output copies the current
738 line minus the prompt to the end of the buffer and sends it.
739 \\[comint-copy-old-input] just copies the current line.
740 Use \\[sql-accumulate-and-indent] to enter multi-line statements.
742 If you want to make multiple SQL buffers, rename the `*SQL*' buffer
743 using \\[rename-buffer] or \\[rename-uniquely] and start a new process.
745 If you accidentally suspend your process, use \\[comint-continue-subjob]
746 to continue it.
748 \\{sql-interactive-mode-map}
749 Customization: Entry to this mode runs the hooks on `comint-mode-hook'
750 and `sql-interactive-mode-hook' (in that order). Before each input, the
751 hooks on `comint-input-filter-functions' are run. After each SQL
752 interpreter output, the hooks on `comint-output-filter-functions' are
753 run.
755 Variable `comint-input-ring-file-name' controls the initialisation of
756 the input ring history.
758 Variables `comint-output-filter-functions', a hook, and
759 `comint-scroll-to-bottom-on-input' and
760 `comint-scroll-to-bottom-on-output' control whether input and output
761 cause the window to scroll to the end of the buffer.
763 If you want to make SQL buffers limited in length, add the function
764 `comint-truncate-buffer' to `comint-output-filter-functions'.
766 Here is an example for your .emacs file. It keeps the *SQL* Buffer a
767 certain length and stores all inputs in an input-ring file.
769 \(add-hook 'sql-interactive-mode-hook
770 \(function (lambda ()
771 \(setq comint-input-ring-file-name \"~/.sql_history\")
772 \(setq comint-output-filter-functions 'comint-truncate-buffer))))
774 Here is another example. It will always put point back to the statement
775 you entered, right above the output it created.
777 \(setq comint-output-filter-functions
778 \(function (lambda (STR) (comint-show-output))))"
779 (comint-mode)
780 (setq comint-prompt-regexp sql-prompt-regexp)
781 (setq left-margin sql-prompt-length)
782 (setq major-mode 'sql-interactive-mode)
783 (setq mode-name "SQLi")
784 (use-local-map sql-interactive-mode-map)
785 (set-syntax-table sql-mode-syntax-table)
786 (make-local-variable 'font-lock-defaults)
787 ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
788 ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the
789 ;; column will have just one quote. Therefore syntactic hilighting
790 ;; is disabled for interactive buffers.
791 (setq font-lock-defaults '(sql-mode-font-lock-keywords
792 t t ((95 . "w") (46 . "w"))))
793 (make-local-variable 'comment-start)
794 (setq comment-start "--")
795 (setq local-abbrev-table sql-mode-abbrev-table)
796 (setq abbrev-all-caps 1)
797 (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop)
798 (run-hooks 'sql-interactive-mode-hook)
799 ;; calling the hook before calling comint-read-input-ring allows users
800 ;; to set comint-input-ring-file-name in sql-interactive-mode-hook.
801 (comint-read-input-ring t))
803 (defun sql-stop (process event)
804 "Called when the SQL process is stopped.
806 Writes the input history to a history file using `comint-write-input-ring'
807 and inserts a short message in the SQL buffer.
809 This function is a sentinel watching the SQL interpreter process.
810 Sentinels will always get the two parameters PROCESS and EVENT."
811 (comint-write-input-ring)
812 (if (buffer-live-p sql-buffer)
813 (insert (format "\nProcess %s %s\n" process event))))
817 ;;; Entry functions for different SQL interpreters.
819 (defun sql-oracle ()
820 "Run sqlplus by Oracle as an inferior process.
822 If buffer *SQL* exists but no process is running, make a new process.
823 If buffer exists and a process is running, just switch to buffer
824 `*SQL*'.
826 Interpreter used comes from variable `sql-oracle-program'. Login
827 uses the variables `sql-user', `sql-password' and `sql-database' as
828 defaults, if set.
830 The buffer is put in sql-interactive-mode, giving commands for sending
831 input. See `sql-interactive-mode'.
833 To specify a coding system for converting non-ASCII characters
834 in the input and output to the process, use \\[universal-coding-system-argument]
835 before \\[sql-oracle]. You can also specify this with \\[set-buffer-process-coding-system]
836 in the SQL buffer, after you start the process.
837 The default comes from `process-coding-system-alist' and
838 `default-process-coding-system'.
840 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
841 (interactive)
842 (if (comint-check-proc "*SQL*")
843 (pop-to-buffer "*SQL*")
844 (sql-get-login 'user 'password 'database)
845 (message "Login...")
846 ;; Produce user/password@database construct. Password without user
847 ;; is meaningless; database without user/password is meaningless,
848 ;; because "@param" will ask sqlplus to interpret the script
849 ;; "param".
850 (let ((parameter nil))
851 (if (not (string= "" sql-user))
852 (if (not (string= "" sql-password))
853 (setq parameter (concat sql-user "/" sql-password))
854 (setq parameter sql-user)))
855 (if (and parameter (not (string= "" sql-database)))
856 (setq parameter (concat parameter "@" sql-database)))
857 (if parameter
858 (set-buffer (make-comint "SQL" sql-oracle-program nil parameter))
859 (set-buffer (make-comint "SQL" sql-oracle-program nil))))
860 (setq sql-prompt-regexp "^SQL> ")
861 (setq sql-prompt-length 5)
862 (setq sql-buffer (current-buffer))
863 ;; set sql-mode-font-lock-keywords to something different before
864 ;; calling sql-interactive-mode.
865 (setq sql-mode-font-lock-keywords sql-mode-oracle-font-lock-keywords)
866 (sql-interactive-mode)
867 (message "Login...done")
868 (pop-to-buffer sql-buffer)))
872 (defun sql-sybase ()
873 "Run isql by SyBase as an inferior process.
875 If buffer *SQL* exists but no process is running, make a new process.
876 If buffer exists and a process is running, just switch to buffer
877 `*SQL*'.
879 Interpreter used comes from variable `sql-sybase-program'. Login uses
880 the variables `sql-user', `sql-password' and `sql-database' as defaults,
881 if set.
883 The buffer is put in sql-interactive-mode, giving commands for sending
884 input. See `sql-interactive-mode'.
886 To specify a coding system for converting non-ASCII characters
887 in the input and output to the process, use \\[universal-coding-system-argument]
888 before \\[sql-sybase]. You can also specify this with \\[set-buffer-process-coding-system]
889 in the SQL buffer, after you start the process.
890 The default comes from `process-coding-system-alist' and
891 `default-process-coding-system'.
893 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
894 (interactive)
895 (if (comint-check-proc "*SQL*")
896 (pop-to-buffer "*SQL*")
897 (sql-get-login 'user 'password 'database)
898 (message "Login...")
899 ;; Put all parameters to the program (if defined) in a list and call
900 ;; make-comint.
901 (let ((params '("-w" "2048" "-n")))
902 ;; I had a zillion versions of this using nconc and mapcar,
903 ;; mixtures of eval, list and quotes -- you have been warned.
904 (if (not (string= "" sql-database))
905 (setq params (append (list "-S" sql-database) params)))
906 (if (not (string= "" sql-password))
907 (setq params (append (list "-P" sql-password) params)))
908 (if (not (string= "" sql-user))
909 (setq params (append (list "-U" sql-user) params)))
910 (set-buffer (apply 'make-comint "SQL" sql-sybase-program
911 nil params)))
912 (setq sql-prompt-regexp "^SQL> ")
913 (setq sql-prompt-length 5)
914 (setq sql-buffer (current-buffer))
915 (sql-interactive-mode)
916 (message "Login...done")
917 (pop-to-buffer sql-buffer)))
921 (defun sql-informix ()
922 "Run dbaccess by Informix as an inferior process.
924 If buffer *SQL* exists but no process is running, make a new process.
925 If buffer exists and a process is running, just switch to buffer
926 `*SQL*'.
928 Interpreter used comes from variable `sql-informix-program'. Login uses
929 the variable `sql-database' as default, if set.
931 The buffer is put in sql-interactive-mode, giving commands for sending
932 input. See `sql-interactive-mode'.
934 To specify a coding system for converting non-ASCII characters
935 in the input and output to the process, use \\[universal-coding-system-argument]
936 before \\[sql-informix]. You can also specify this with \\[set-buffer-process-coding-system]
937 in the SQL buffer, after you start the process.
938 The default comes from `process-coding-system-alist' and
939 `default-process-coding-system'.
941 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
942 (interactive)
943 (if (comint-check-proc "*SQL*")
944 (pop-to-buffer "*SQL*")
945 (sql-get-login 'database)
946 (message "Login...")
947 ;; username and password are ignored.
948 (if (string= "" sql-database)
949 (set-buffer (make-comint "SQL" sql-informix-program nil))
950 (set-buffer (make-comint "SQL" sql-informix-program nil sql-database)))
951 (setq sql-prompt-regexp "^SQL> ")
952 (setq sql-prompt-length 5)
953 (setq sql-buffer (current-buffer))
954 (sql-interactive-mode)
955 (message "Login...done")
956 (pop-to-buffer sql-buffer)))
960 (defun sql-mysql ()
961 "Run mysql by TcX as an inferior process.
962 Note that the widespread idea that mysql is free software
963 is inaccurate; its license is too restrictive.
964 We urge you to use PostGres instead.
966 If buffer `*SQL*' exists but no process is running, make a new process.
967 If buffer exists and a process is running, just switch to buffer
968 `*SQL*'.
970 Interpreter used comes from variable `sql-mysql-program'. Login uses
971 the variable `sql-database' as default, if set.
973 The buffer is put in sql-interactive-mode, giving commands for sending
974 input. See `sql-interactive-mode'.
976 To specify a coding system for converting non-ASCII characters
977 in the input and output to the process, use \\[universal-coding-system-argument]
978 before \\[sql-informix]. You can also specify this with \\[set-buffer-process-coding-system]
979 in the SQL buffer, after you start the process.
980 The default comes from `process-coding-system-alist' and
981 `default-process-coding-system'.
983 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
984 (interactive)
985 (if (comint-check-proc "*SQL*")
986 (pop-to-buffer "*SQL*")
987 (sql-get-login 'user 'password 'database)
988 (message "Login...")
989 ;; Put all parameters to the program (if defined) in a list and call
990 ;; make-comint.
991 (let ((params))
992 (if (not (string= "" sql-database))
993 (setq params (append (list (concat "--host=" sql-database)) params)))
994 (if (not (string= "" sql-password))
995 (setq params (append (list (concat "--password=" sql-password)) params)))
996 (if (not (string= "" sql-user))
997 (setq params (append (list (concat "--user=" sql-user)) params)))
998 (set-buffer (apply 'make-comint "SQL" sql-mysql-program
999 nil params)))
1000 (setq sql-prompt-regexp "^mysql>")
1001 (setq sql-prompt-length 6)
1002 (setq sql-buffer (current-buffer))
1003 (sql-interactive-mode)
1004 (message "Login...done")
1005 (pop-to-buffer sql-buffer)))
1009 (defun sql-ingres ()
1010 "Run sql by Ingres as an inferior process.
1012 If buffer *SQL* exists but no process is running, make a new process.
1013 If buffer exists and a process is running, just switch to buffer
1014 `*SQL*'.
1016 Interpreter used comes from variable `sql-ingres-program'. Login uses
1017 the variable `sql-database' as default, if set.
1019 The buffer is put in sql-interactive-mode, giving commands for sending
1020 input. See `sql-interactive-mode'.
1022 To specify a coding system for converting non-ASCII characters
1023 in the input and output to the process, use \\[universal-coding-system-argument]
1024 before \\[sql-ingres]. You can also specify this with \\[set-buffer-process-coding-system]
1025 in the SQL buffer, after you start the process.
1026 The default comes from `process-coding-system-alist' and
1027 `default-process-coding-system'.
1029 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1030 (interactive)
1031 (if (comint-check-proc "*SQL*")
1032 (pop-to-buffer "*SQL*")
1033 (sql-get-login 'database)
1034 (message "Login...")
1035 ;; username and password are ignored.
1036 (if (string= "" sql-database)
1037 (set-buffer (make-comint "SQL" sql-ingres-program nil))
1038 (set-buffer (make-comint "SQL" sql-ingres-program nil sql-database)))
1039 (setq sql-prompt-regexp "^\* ")
1040 (setq sql-prompt-length 2)
1041 (setq sql-buffer (current-buffer))
1042 (sql-interactive-mode)
1043 (message "Login...done")
1044 (pop-to-buffer sql-buffer)))
1048 (defun sql-ms ()
1049 "Run isql by Microsoft as an inferior process.
1051 If buffer *SQL* exists but no process is running, make a new process.
1052 If buffer exists and a process is running, just switch to buffer
1053 `*SQL*'.
1055 Interpreter used comes from variable `sql-ms-program'. Login uses the
1056 variables `sql-user', `sql-password', `sql-server' and `sql-database'
1057 as defaults, if set.
1059 The buffer is put in sql-interactive-mode, giving commands for sending
1060 input. See `sql-interactive-mode'.
1062 To specify a coding system for converting non-ASCII characters
1063 in the input and output to the process, use \\[universal-coding-system-argument]
1064 before \\[sql-sybase]. You can also specify this with \\[set-buffer-process-coding-system]
1065 in the SQL buffer, after you start the process.
1066 The default comes from `process-coding-system-alist' and
1067 `default-process-coding-system'.
1069 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1070 (interactive)
1071 (if (comint-check-proc "*SQL*")
1072 (pop-to-buffer "*SQL*")
1073 (sql-get-login 'user 'password 'database 'server)
1074 (message "Login...")
1075 ;; Put all parameters to the program (if defined) in a list and call
1076 ;; make-comint.
1077 (let ((params '("-w 300")))
1078 (if (not (string= "" sql-server))
1079 (setq params (append (list "-S" sql-server) params)))
1080 (if (not (string= "" sql-database))
1081 (setq params (append (list "-d" sql-database) params)))
1082 (if (not (string= "" sql-user))
1083 (setq params (append (list "-U" sql-user) params)))
1084 (if (not (string= "" sql-password))
1085 (setq params (append (list "-P" sql-password) params))
1086 ;; If -P is passed to ISQL as the last argument without a password,
1087 ;; it's considered null.
1088 (setq params (append params (list "-P"))))
1089 (set-buffer (apply 'make-comint "SQL" sql-ms-program
1090 nil params)))
1091 (setq sql-prompt-regexp "^[0-9]*>")
1092 (setq sql-prompt-length 5)
1093 (setq sql-buffer (current-buffer))
1094 (sql-interactive-mode)
1095 (message "Login...done")
1096 (pop-to-buffer sql-buffer)))
1101 ;;;###autoload
1102 (defun sql-postgres ()
1103 "Run psql by Postgres as an inferior process.
1105 If buffer *SQL* exists but no process is running, make a new process.
1106 If buffer exists and a process is running, just switch to buffer
1107 `*SQL*'.
1109 Interpreter used comes from variable `sql-postgres-program'. Login uses
1110 the variable `sql-database' as default, if set.
1112 The buffer is put in sql-interactive-mode, giving commands for sending
1113 input. See `sql-interactive-mode'.
1115 To specify a coding system for converting non-ASCII characters
1116 in the input and output to the process, use \\[universal-coding-system-argument]
1117 before \\[sql-postgres]. You can also specify this with \\[set-buffer-process-coding-system]
1118 in the SQL buffer, after you start the process.
1119 The default comes from `process-coding-system-alist' and
1120 `default-process-coding-system'. If your output lines end with ^M,
1121 your might try undecided-dos as a coding system. If this doesn't help,
1122 Try to set `comint-output-filter-functions' like this:
1124 \(setq comint-output-filter-functions (append comint-output-filter-functions
1125 '(comint-strip-ctrl-m)))
1127 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1128 (interactive)
1129 (if (comint-check-proc "*SQL*")
1130 (pop-to-buffer "*SQL*")
1131 (sql-get-login 'database)
1132 (message "Login...")
1133 ;; username and password are ignored.
1134 (if (string= "" sql-database)
1135 (set-buffer (make-comint "SQL" sql-postgres-program nil))
1136 (set-buffer (make-comint "SQL" sql-postgres-program nil sql-database)))
1137 (setq sql-prompt-regexp "^.*> *")
1138 (setq sql-prompt-length 5)
1139 ;; This is a lousy hack to prevent psql from truncating it's output
1140 ;; and giving stupid warnings. If s.o. knows a way to prevent psql
1141 ;; from acting this way, then I would be very thankful to
1142 ;; incorporate this (Gregor Zych <zych@pool.informatik.rwth-aachen.de>)
1143 (comint-send-string "*SQL*" "\\o \| cat\n")
1144 (setq sql-mode-font-lock-keywords sql-mode-postgres-font-lock-keywords)
1145 (setq sql-buffer (current-buffer))
1146 (sql-interactive-mode)
1147 (message "Login...done")
1148 (pop-to-buffer sql-buffer)))
1150 (provide 'sql)
1152 ;;; sql.el ends here