]> code.delx.au - gnu-emacs/blob - lisp/progmodes/sql.el
(makefile-mode-abbrev-table): Remove
[gnu-emacs] / lisp / progmodes / sql.el
1 ;;; sql.el --- specialized comint.el for SQL interpreters
2
3 ;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4
5 ;; Author: Alex Schroeder <alex@gnu.org>
6 ;; Maintainer: Alex Schroeder <alex@gnu.org>
7 ;; Version: 1.4.13
8 ;; Keywords: comm languages processes
9
10 ;; This file is part of GNU Emacs.
11
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.
16
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.
21
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.
26
27 ;;; Commentary:
28
29 ;; Please send bug reports and bug fixes to the mailing list at
30 ;; sql.el@gnu.org. If you want to subscribe to the mailing list, send
31 ;; mail to sql.el-request@gnu.org with `subscribe sql.el FIRSTNAME
32 ;; LASTNAME' in the mail body.
33
34 ;; This file provides a sql-mode and a sql-interactive-mode. My goals
35 ;; were two simple modes providing syntactic hilighting. The
36 ;; interactive mode had to provide a command-line history; the other
37 ;; mode had to provide "send region/buffer to SQL interpreter"
38 ;; functions. "simple" in this context means easy to use, easy to
39 ;; maintain and little or no bells and whistles.
40
41 ;; If anybody feels like extending this sql mode, take a look at the
42 ;; above mentioned modes and write a sqlx-mode on top of this one. If
43 ;; this proves to be difficult, please suggest changes that will
44 ;; facilitate your plans.
45
46 ;; sql-interactive-mode is used to interact with a SQL interpreter
47 ;; process in a SQLi buffer (usually called `*SQL*'). The SQLi buffer
48 ;; is created by calling a SQL interpreter-specific entry function. Do
49 ;; *not* call sql-interactive-mode by itself.
50
51 ;; The list of currently supported interpreters and the corresponding
52 ;; entry function used to create the SQLi buffers is shown with
53 ;; `sql-help' (M-x sql-help).
54
55 ;; Since sql-interactive-mode is built on top of the general
56 ;; command-interpreter-in-a-buffer mode (comint mode), it shares a
57 ;; common base functionality, and a common set of bindings, with all
58 ;; modes derived from comint mode. This makes these modes easier to
59 ;; use.
60
61 ;; sql-mode can be used to enable syntactic hilighting for SQL
62 ;; statements in another buffer. SQL statements can then be sent to
63 ;; the SQL process in the SQLi buffer. sql-mode has already been
64 ;; used as a template to a simple PL/SQL mode.
65
66 ;; For documentation on the functionality provided by comint mode, and
67 ;; the hooks available for customising it, see the file `comint.el'.
68
69 ;; Hint for newbies: take a look at `dabbrev-expand', `abbrev-mode', and
70 ;; `imenu-add-menubar-index'.
71
72 ;;; Requirements for Emacs 19.34:
73
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/>.
79
80 ;;; Bugs:
81
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.
87
88 ;; ChangeLog available on request.
89
90 ;;; To Do:
91
92 ;; Add better hilight support for other brands; there is a bias towards
93 ;; Oracle because that's what I use at work. Anybody else just send in
94 ;; your lists of reserved words, keywords and builtin functions! As
95 ;; long as I don't receive any feedback, everything is hilighted with
96 ;; ANSI keywords only. I received the list of ANSI keywords from a
97 ;; user; if you know of any changes, let me know.
98
99 ;; Add different hilighting levels.
100
101 ;;; Thanks to all the people who helped me out:
102
103 ;; Kai Blauberg <kai.blauberg@metla.fi>
104 ;; <ibalaban@dalet.com>
105 ;; Yair Friedman <yfriedma@JohnBryce.Co.Il>
106 ;; Gregor Zych <zych@pool.informatik.rwth-aachen.de>
107 ;; nino <nino@inform.dk>
108 ;; Berend de Boer <berend@pobox.com>
109
110 \f
111
112 ;;; Code:
113
114 (require 'comint)
115 ;; Need the following to allow GNU Emacs 19 to compile the file.
116 (require 'regexp-opt)
117 (require 'custom)
118
119 ;;; Allow customization
120
121 (defgroup SQL nil
122 "Running a SQL interpreter from within Emacs buffers"
123 :version "20.4"
124 :group 'processes)
125
126 ;; These three variables will be used as defaults, if set.
127
128 (defcustom sql-user ""
129 "*Default username."
130 :type 'string
131 :group 'SQL)
132
133 (defcustom sql-password ""
134 "*Default password.
135
136 Storing your password in a textfile such as ~/.emacs could be dangerous.
137 Customizing your password will store it in your ~/.emacs file."
138 :type 'string
139 :group 'SQL)
140
141 (defcustom sql-database ""
142 "*Default database."
143 :type 'string
144 :group 'SQL)
145
146 (defcustom sql-server ""
147 "*Default server or host."
148 :type 'string
149 :group 'SQL)
150
151 ;; misc customization of sql.el behaviour
152
153 (defcustom sql-electric-stuff nil
154 "Treat some input as electric.
155 If set to the symbol `semicolon', then hitting `;' will send current
156 input in the SQLi buffer to the process.
157 If set to the symbol `go', then hitting `go' on a line by itself will
158 send current input in the SQLi buffer to the process.
159 If set to nil, then you must use \\[comint-send-input] in order to send
160 current input in the SQLi buffer to the process."
161 :type '(choice (const :tag "Nothing" nil)
162 (const :tag "The semikolon `;'" semicolon)
163 (const :tag "The string `go' by itself" go))
164 :version "20.8"
165 :group 'SQL)
166
167 (defcustom sql-pop-to-buffer-after-send-region nil
168 "*If t, pop to the buffer SQL statements are sent to.
169
170 After a call to `sql-send-region' or `sql-send-buffer',
171 the window is split and the SQLi buffer is shown. If this
172 variable is not nil, that buffer's window will be selected
173 by calling `pop-to-buffer'. If this variable is nil, that
174 buffer is shown using `display-buffer'."
175 :type 'boolean
176 :group 'SQL)
177
178 ;; imenu support for sql-mode.
179
180 (defvar sql-imenu-generic-expression
181 '(("Tables" "^\\s-*create\\s-+table\\s-+\\(\\w+\\)" 1)
182 ("Indexes" "^\\s-*create\\s-+index\\s-+\\(\\w+\\)" 1))
183 "Define interesting points in the SQL buffer for `imenu'.
184
185 This is used to set `imenu-generic-expression' when SQL mode is
186 entered. Subsequent changes to sql-imenu-generic-expression will not
187 affect existing SQL buffers because imenu-generic-expression is a
188 local variable.")
189
190 ;; history file
191
192 (defcustom sql-input-ring-file-name nil
193 "*If non-nil, name of the file to read/write input history.
194
195 You have to set this variable if you want the history of your commands
196 saved from one Emacs session to the next. If this variable is set,
197 exiting the SQL interpreter in an SQLi buffer will write the input
198 history to the specified file. Starting a new process in a SQLi buffer
199 will read the input history from the specified file.
200
201 This is used to locally set `comint-input-ring-file-name' when reading
202 or writing the input history."
203 :type '(choice (const :tag "none" nil)
204 (file))
205 :group 'SQL)
206
207 (defcustom sql-input-ring-separator "\n--\n"
208 "*Separator between commands in the history file.
209
210 If set to \"\\n\", each line in the history file will be interpreted as
211 one command. Multi-line commands are split into several commands when
212 the input ring is initialized from a history file.
213
214 This variable used to locally set `comint-input-ring-separator' when
215 reading or writing the history file. `comint-input-ring-separator' is
216 not yet part of Emacs; if your Emacs does not have it, setting
217 `sql-input-ring-separator' will have no effect. In that case multiline
218 commands will be split into several commands when the input history is
219 read, as if you had set `sql-input-ring-separator' to \"\\n\".
220
221 The source code contains a link to a homepage that might have a patch
222 for comint.el to download."
223 :type 'string
224 :group 'SQL)
225
226 ;; The usual hooks
227
228 (defcustom sql-interactive-mode-hook '()
229 "*Hook for customising `sql-interactive-mode'."
230 :type 'hook
231 :group 'SQL)
232
233 (defcustom sql-mode-hook '()
234 "*Hook for customising `sql-mode'."
235 :type 'hook
236 :group 'SQL)
237
238 (defcustom sql-set-sqli-hook '()
239 "*Hook for reacting to changes of `sql-buffer'.
240
241 This is called by `sql-set-sqli-buffer' when the value of `sql-buffer'
242 is changed."
243 :type 'hook
244 :group 'SQL)
245
246 ;; Customisation for Oracle
247
248 (defcustom sql-oracle-program "sqlplus"
249 "*Command to start sqlplus by Oracle.
250
251 Starts `sql-interactive-mode' after doing some setup.
252
253 Under NT, \"sqlplus\" usually starts the sqlplus \"GUI\". In order to
254 start the sqlplus console, use \"plus33\" or something similar. You
255 will find the file in your Orant\\bin directory.
256
257 The program can also specify a TCP connection. See `make-comint'."
258 :type 'file
259 :group 'SQL)
260
261 (defcustom sql-oracle-options nil
262 "*List of additional options for `sql-oracle-program'."
263 :type '(repeat string)
264 :version "20.8"
265 :group 'SQL)
266
267 ;; Customisation for MySql
268
269 (defcustom sql-mysql-program "mysql"
270 "*Command to start mysql by TcX.
271
272 Starts `sql-interactive-mode' after doing some setup.
273
274 The program can also specify a TCP connection. See `make-comint'."
275 :type 'file
276 :group 'SQL)
277
278 ;; Customisation for Solid
279
280 (defcustom sql-solid-program "solsql"
281 "*Command to start SOLID SQL Editor.
282
283 Starts `sql-interactive-mode' after doing some setup.
284
285 The program can also specify a TCP connection. See `make-comint'."
286 :type 'file
287 :group 'SQL)
288
289 ;; Customisation for SyBase
290
291 (defcustom sql-sybase-program "isql"
292 "*Command to start isql by SyBase.
293
294 Starts `sql-interactive-mode' after doing some setup.
295
296 The program can also specify a TCP connection. See `make-comint'."
297 :type 'file
298 :group 'SQL)
299
300 ;; Customisation for Informix
301
302 (defcustom sql-informix-program "dbaccess"
303 "*Command to start dbaccess by Informix.
304
305 Starts `sql-interactive-mode' after doing some setup.
306
307 The program can also specify a TCP connection. See `make-comint'."
308 :type 'file
309 :group 'SQL)
310
311 ;; Customisation for Ingres
312
313 (defcustom sql-ingres-program "sql"
314 "*Command to start sql by Ingres.
315
316 Starts `sql-interactive-mode' after doing some setup.
317
318 The program can also specify a TCP connection. See `make-comint'."
319 :type 'file
320 :group 'SQL)
321
322 ;; Customisation for Microsoft
323
324 (defcustom sql-ms-program "isql"
325 "*Command to start isql by Microsoft.
326
327 Starts `sql-interactive-mode' after doing some setup.
328
329 The program can also specify a TCP connection. See `make-comint'."
330 :type 'file
331 :group 'SQL)
332
333 ;; Customisation for Postgres
334
335 (defcustom sql-postgres-program "psql"
336 "Command to start psql by Postgres.
337
338 Starts `sql-interactive-mode' after doing some setup.
339
340 The program can also specify a TCP connection. See `make-comint'."
341 :type 'file
342 :group 'SQL)
343
344 \f
345
346 ;;; Variables which do not need customization
347
348 (defvar sql-user-history nil
349 "History of usernames used.")
350
351 (defvar sql-database-history nil
352 "History of databases used.")
353
354 (defvar sql-server-history nil
355 "History of servers used.")
356
357 ;; Passwords are not kept in a history.
358
359 (defvar sql-buffer nil
360 "Current SQLi buffer.
361
362 The global value of sql-buffer is the name of the latest SQLi buffer
363 created. Any SQL buffer created will make a local copy of this value.
364 See `sql-interactive-mode' for more on multiple sessions. If you want
365 to change the SQLi buffer a SQL mode sends its SQL strings to, change
366 the local value of `sql-buffer' using \\[sql-set-sqli-buffer].")
367
368 (defvar sql-prompt-regexp nil
369 "Prompt used to initialize `comint-prompt-regexp'.
370
371 You can change `comint-prompt-regexp' on `sql-interactive-mode-hook'.")
372
373 (defvar sql-prompt-length 0
374 "Prompt used to set `left-margin' in `sql-interactive-mode'.
375
376 You can change it on `sql-interactive-mode-hook'.")
377
378 (defvar sql-alternate-buffer-name nil
379 "Buffer-local string used to possibly rename the SQLi buffer.
380
381 Used by `sql-rename-buffer'.")
382
383 ;; Keymap for sql-interactive-mode.
384
385 (defvar sql-interactive-mode-map
386 (let ((map (make-sparse-keymap)))
387 (if (functionp 'set-keymap-parent)
388 (set-keymap-parent map comint-mode-map); Emacs
389 (set-keymap-parents map (list comint-mode-map))); XEmacs
390 (if (functionp 'set-keymap-name)
391 (set-keymap-name map 'sql-interactive-mode-map)); XEmacs
392 (define-key map (kbd "C-j") 'sql-accumulate-and-indent)
393 (define-key map (kbd "C-c C-w") 'sql-copy-column)
394 (define-key map (kbd "O") 'sql-magic-go)
395 (define-key map (kbd "o") 'sql-magic-go)
396 (define-key map (kbd ";") 'sql-magic-semicolon)
397 map)
398 "Mode map used for `sql-interactive-mode'.
399 Based on `comint-mode-map'.")
400
401 ;; Keymap for sql-mode.
402
403 (defvar sql-mode-map
404 (let ((map (make-sparse-keymap)))
405 (define-key map (kbd "C-c C-c") 'sql-send-paragraph)
406 (define-key map (kbd "C-c C-r") 'sql-send-region)
407 (define-key map (kbd "C-c C-b") 'sql-send-buffer)
408 (define-key map (kbd "<tab>") 'indent-relative)
409 map)
410 "Mode map used for `sql-mode'.")
411
412 ;; easy menu for sql-mode.
413
414 (easy-menu-define
415 sql-mode-menu sql-mode-map
416 "Menu for `sql-mode'."
417 '("SQL"
418 ["Send Paragraph" sql-send-paragraph (and (buffer-live-p sql-buffer)
419 (get-buffer-process sql-buffer))]
420 ["Send Region" sql-send-region (and mark-active
421 (buffer-live-p sql-buffer)
422 (get-buffer-process sql-buffer))]
423 ["Send Buffer" sql-send-buffer (and (buffer-live-p sql-buffer)
424 (get-buffer-process sql-buffer))]
425 ["Show SQLi buffer" sql-show-sqli-buffer t]
426 ["Set SQLi buffer" sql-set-sqli-buffer t]
427 ["Pop to SQLi buffer after send"
428 sql-toggle-pop-to-buffer-after-send-region
429 :style toggle
430 :selected sql-pop-to-buffer-after-send-region]))
431
432 ;; easy menu for sql-interactive-mode.
433
434 (easy-menu-define
435 sql-interactive-mode-menu sql-interactive-mode-map
436 "Menu for `sql-interactive-mode'."
437 '("SQL"
438 ["Rename Buffer" sql-rename-buffer t]))
439
440 ;; Abbreviations -- if you want more of them, define them in your
441 ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
442
443 (defvar sql-mode-abbrev-table nil
444 "Abbrev table used in `sql-mode' and `sql-interactive-mode'.")
445 (if sql-mode-abbrev-table
446 ()
447 (let ((wrapper))
448 (define-abbrev-table 'sql-mode-abbrev-table ())
449 (define-abbrev sql-mode-abbrev-table "ins" "insert" nil)
450 (define-abbrev sql-mode-abbrev-table "upd" "update" nil)
451 (define-abbrev sql-mode-abbrev-table "del" "delete" nil)
452 (define-abbrev sql-mode-abbrev-table "sel" "select" nil)))
453
454 ;; Syntax Table
455
456 (defvar sql-mode-syntax-table
457 (let ((table (make-syntax-table)))
458 ;; C-style comments /**/ (see elisp manual "Syntax Flags"))
459 (modify-syntax-entry ?/ ". 14" table)
460 (modify-syntax-entry ?* ". 23" table)
461 ;; double-dash starts comment
462 (if (string-match "XEmacs\\|Lucid" emacs-version)
463 (modify-syntax-entry ?- ". 56" table)
464 (modify-syntax-entry ?- ". 12b" table))
465 ;; newline and formfeed end coments
466 (modify-syntax-entry ?\n "> b" table)
467 (modify-syntax-entry ?\f "> b" table)
468 ;; single quotes (') quotes delimit strings
469 (modify-syntax-entry ?' "\"" table)
470 table)
471 "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
472
473 ;; Font lock support
474
475 (defvar sql-mode-ansi-font-lock-keywords nil
476 "ANSI SQL keywords used by font-lock.
477
478 This variable is used by `sql-mode' and `sql-interactive-mode'. The
479 regular expressions are created during compilation by calling the
480 function `regexp-opt'. Therefore, take a look at the source before
481 you define your own sql-mode-ansi-font-lock-keywords. You may want to
482 add functions and PL/SQL keywords.")
483 (if sql-mode-ansi-font-lock-keywords
484 ()
485 (let ((ansi-keywords (eval-when-compile
486 (concat "\\b"
487 (regexp-opt '(
488 "authorization" "avg" "begin" "close" "cobol" "commit"
489 "continue" "count" "declare" "double" "end" "escape"
490 "exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator"
491 "key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli"
492 "precision" "primary" "procedure" "references" "rollback"
493 "schema" "section" "some" "sqlcode" "sqlerror" "sum" "work") t) "\\b")))
494 (ansi-reserved-words (eval-when-compile
495 (concat "\\b"
496 (regexp-opt '(
497 "all" "and" "any" "as" "asc" "between" "by" "check" "create"
498 "current" "default" "delete" "desc" "distinct" "exists" "float" "for"
499 "from" "grant" "group" "having" "in" "insert" "into" "is"
500 "like" "not" "null" "of" "on" "option" "or" "order" "privileges"
501 "public" "select" "set" "table" "to" "union" "unique"
502 "update" "user" "values" "view" "where" "with") t) "\\b")))
503 (ansi-types (eval-when-compile
504 (concat "\\b"
505 (regexp-opt '(
506 ;; ANSI Keywords that look like types
507 "character" "cursor" "dec" "int" "real"
508 ;; ANSI Reserved Word that look like types
509 "char" "integer" "smallint" ) t) "\\b"))))
510 (setq sql-mode-ansi-font-lock-keywords
511 (list (cons ansi-keywords 'font-lock-function-name-face)
512 (cons ansi-reserved-words 'font-lock-keyword-face)
513 (cons ansi-types 'font-lock-type-face)))))
514
515 (defvar sql-mode-oracle-font-lock-keywords nil
516 "Oracle SQL keywords used by font-lock.
517
518 This variable is used by `sql-mode' and `sql-interactive-mode'. The
519 regular expressions are created during compilation by calling the
520 function `regexp-opt'. Therefore, take a look at the source before
521 you define your own sql-mode-oracle-font-lock-keywords. You may want
522 to add functions and PL/SQL keywords.")
523 (if sql-mode-oracle-font-lock-keywords
524 ()
525 (let ((oracle-keywords (eval-when-compile
526 (concat "\\b"
527 (regexp-opt '(
528 "admin" "after" "allocate" "analyze" "archive" "archivelog" "backup"
529 "become" "before" "block" "body" "cache" "cancel" "cascade" "change"
530 "checkpoint" "compile" "constraint" "constraints" "contents"
531 "controlfile" "cycle" "database" "datafile" "dba" "disable" "dismount"
532 "dump" "each" "enable" "events" "except" "exceptions" "execute"
533 "explain" "extent" "externally" "flush" "force" "freelist" "freelists"
534 "function" "groups" "including" "initrans" "instance" "layer" "link"
535 "lists" "logfile" "manage" "manual" "maxdatafiles" "maxinistances"
536 "maxlogfiles" "maxloghistory" "maxlogmembers" "maxtrans" "maxvalue"
537 "minextents" "minvalue" "mount" "new" "next" "noarchivelog" "nocache"
538 "nocycle" "nomaxvalue" "nominvalue" "none" "noorder" "noresetlogs"
539 "normal" "nosort" "off" "old" "only" "optimal" "own" "package"
540 "parallel" "pctincrease" "pctused" "plan" "private" "profile" "quota"
541 "read" "recover" "referencing" "resetlogs" "restricted" "reuse" "role"
542 "roles" "savepoint" "scn" "segment" "sequence" "shared" "snapshot"
543 "sort" "statement_id" "statistics" "stop" "storage" "switch" "system"
544 "tables" "tablespace" "temporary" "thread" "time" "tracing"
545 "transaction" "triggers" "truncate" "under" "unlimited" "until" "use"
546 "using" "when" "write") t) "\\b")))
547 (oracle-reserved-words (eval-when-compile
548 (concat "\\b"
549 (regexp-opt '(
550 "access" "add" "alter" "audit" "cluster" "column" "comment" "compress"
551 "connect" "drop" "else" "exclusive" "file" "grant"
552 "identified" "immediate" "increment" "index" "initial" "intersect"
553 "level" "lock" "long" "maxextents" "minus" "mode" "modify" "noaudit"
554 "nocompress" "nowait" "number" "offline" "online" "pctfree" "prior"
555 "raw" "rename" "resource" "revoke" "row" "rowlabel" "rownum"
556 "rows" "session" "share" "size" "start" "successful" "synonym" "sysdate"
557 "then" "trigger" "uid" "validate" "whenever") t) "\\b")))
558 (oracle-types (eval-when-compile
559 (concat "\\b"
560 (regexp-opt '(
561 ;; Oracle Keywords that look like types
562 ;; Oracle Reserved Words that look like types
563 "date" "decimal" "rowid" "varchar" "varchar2") t) "\\b")))
564 (oracle-builtin-functions (eval-when-compile
565 (concat "\\b"
566 (regexp-opt '(
567 ;; Misc Oracle builtin functions
568 "abs" "add_months" "ascii" "avg" "ceil" "chartorowid" "chr" "concat"
569 "convert" "cos" "cosh" "count" "currval" "decode" "dump" "exp" "floor"
570 "glb" "greatest" "greatest_lb" "hextoraw" "initcap" "instr" "instrb"
571 "last_day" "least" "least_ub" "length" "lengthb" "ln" "log" "lower"
572 "lpad" "ltrim" "lub" "max" "min" "mod" "months_between" "new_time"
573 "next_day" "nextval" "nls_initcap" "nls_lower" "nls_upper" "nlssort"
574 "nvl" "power" "rawtohex" "replace" "round" "rowidtochar" "rpad"
575 "rtrim" "sign" "sin" "sinh" "soundex" "sqlcode" "sqlerrm" "sqrt"
576 "stddev" "sum" "substr" "substrb" "tan" "tanh" "to_char"
577 "to_date" "to_label" "to_multi_byte" "to_number" "to_single_byte"
578 "translate" "trunc" "uid" "upper" "userenv" "variance" "vsize") t) "\\b"))))
579 (setq sql-mode-oracle-font-lock-keywords
580 (append sql-mode-ansi-font-lock-keywords
581 (list (cons oracle-keywords 'font-lock-function-name-face)
582 (cons oracle-reserved-words 'font-lock-keyword-face)
583 ;; XEmacs doesn't have font-lock-builtin-face
584 (if (string-match "XEmacs\\|Lucid" emacs-version)
585 (cons oracle-builtin-functions 'font-lock-preprocessor-face)
586 ;; GNU Emacs 19 doesn't have it either
587 (if (string-match "GNU Emacs 19" emacs-version)
588 (cons oracle-builtin-functions 'font-lock-function-name-face)
589 ;; Emacs
590 (cons oracle-builtin-functions 'font-lock-builtin-face)))
591 (cons oracle-types 'font-lock-type-face))))))
592
593 (defvar sql-mode-postgres-font-lock-keywords nil
594 "Postgres SQL keywords used by font-lock.
595
596 This variable is used by `sql-mode' and `sql-interactive-mode'. The
597 regular expressions are created during compilation by calling the
598 function `regexp-opt'. Therefore, take a look at the source before
599 you define your own sql-mode-postgres-font-lock-keywords.")
600
601 (if sql-mode-postgres-font-lock-keywords
602 ()
603 (let ((postgres-reserved-words (eval-when-compile
604 (concat "\\b"
605 (regexp-opt '(
606 "language"
607 ) t) "\\b")))
608 (postgres-types (eval-when-compile
609 (concat "\\b"
610 (regexp-opt '(
611 "bool" "box" "circle" "char" "char2" "char4" "char8" "char16" "date"
612 "float4" "float8" "int2" "int4" "int8" "line" "lseg" "money" "path"
613 "point" "polygon" "serial" "text" "time" "timespan" "timestamp" "varchar"
614 ) t)"\\b")))
615 (postgres-builtin-functions (eval-when-compile
616 (concat "\\b"
617 (regexp-opt '(
618 ;; Misc Postgres builtin functions
619 "abstime" "age" "area" "box" "center" "date_part" "date_trunc"
620 "datetime" "dexp" "diameter" "dpow" "float" "float4" "height"
621 "initcap" "integer" "isclosed" "isfinite" "isoldpath" "isopen"
622 "length" "lower" "lpad" "ltrim" "pclose" "point" "points" "popen"
623 "position" "radius" "reltime" "revertpoly" "rpad" "rtrim" "substr"
624 "substring" "text" "timespan" "translate" "trim" "upgradepath"
625 "upgradepoly" "upper" "varchar" "width"
626 ) t) "\\b"))))
627 (setq sql-mode-postgres-font-lock-keywords
628 (append sql-mode-ansi-font-lock-keywords
629 (list (cons postgres-reserved-words 'font-lock-keyword-face)
630 ;; XEmacs doesn't have 'font-lock-builtin-face
631 (if (string-match "XEmacs\\|Lucid" emacs-version)
632 (cons postgres-builtin-functions 'font-lock-preprocessor-face)
633 ;; Emacs
634 (cons postgres-builtin-functions 'font-lock-builtin-face))
635 (cons postgres-types 'font-lock-type-face))))))
636
637
638 (defvar sql-mode-font-lock-keywords sql-mode-ansi-font-lock-keywords
639 "SQL keywords used by font-lock.
640
641 This variable defaults to `sql-mode-ansi-font-lock-keywords'. This is
642 used for the default `font-lock-defaults' value in `sql-mode'. This
643 can be changed by some entry functions to provide more hilighting.")
644
645 \f
646
647 ;;; Small functions
648
649 (defun sql-magic-go (arg)
650 "Insert \"o\" and call `comint-send-input'.
651 `sql-electric-stuff' must be the symbol `go'."
652 (interactive "P")
653 (self-insert-command (prefix-numeric-value arg))
654 (if (and (equal sql-electric-stuff 'go)
655 (save-excursion
656 (beginning-of-line)
657 (looking-at (concat sql-prompt-regexp "go\\b"))))
658 (comint-send-input)))
659
660 (defun sql-magic-semicolon (arg)
661 "Insert semicolon and call `comint-send-input'.
662 `sql-electric-stuff' must be the symbol `semicolon'."
663 (interactive "P")
664 (self-insert-command (prefix-numeric-value arg))
665 (if (equal sql-electric-stuff 'semicolon)
666 (comint-send-input)))
667
668 (defun sql-accumulate-and-indent ()
669 "Continue SQL statement on the next line."
670 (interactive)
671 (if (fboundp 'comint-accumulate)
672 (comint-accumulate)
673 (newline))
674 (indent-according-to-mode))
675
676 ;;;###autoload
677 (defun sql-help ()
678 "Show short help for the SQL modes.
679
680 Use an entry function to open an interactive SQL buffer. This buffer is
681 usually named `*SQL*'. The name of the major mode is SQLi.
682
683 Use the following commands to start a specific SQL interpreter:
684
685 PostGres: \\[sql-postgres]
686
687 Other non-free SQL implementations are also supported:
688
689 MySQL: \\[sql-mysql]
690 Solid: \\[sql-solid]
691 Oracle: \\[sql-oracle]
692 Informix: \\[sql-informix]
693 Sybase: \\[sql-sybase]
694 Ingres: \\[sql-ingres]
695 Microsoft: \\[sql-ms]
696
697 But we urge you to choose a free implementation instead of these.
698
699 Once you have the SQLi buffer, you can enter SQL statements in the
700 buffer. The output generated is appended to the buffer and a new prompt
701 is generated. See the In/Out menu in the SQLi buffer for some functions
702 that help you navigate through the buffer, the input history, etc.
703
704 Put a line with a call to autoload into your `~/.emacs' file for each
705 entry function you want to use regularly:
706
707 \(autoload 'sql-postgres \"sql\" \"Interactive SQL mode.\" t)
708
709 If you have a really complex SQL statement or if you are writing a
710 procedure, you can do this in a separate buffer. Put the new buffer in
711 `sql-mode' by calling \\[sql-mode]. The name of this buffer can be
712 anything. The name of the major mode is SQL.
713
714 In this SQL buffer (SQL mode), you can send the region or the entire
715 buffer to the interactive SQL buffer (SQLi mode). The results are
716 appended to the SQLi buffer without disturbing your SQL buffer."
717 (interactive)
718 (describe-function 'sql-help))
719
720 (defun sql-read-passwd (prompt &optional default)
721 "Read a password using PROMPT.
722 Optional DEFAULT is password to start with. This function calls
723 `read-passwd' if it is available. If not, function
724 `ange-ftp-read-passwd' is called. This should always be available,
725 even in old versions of Emacs."
726 (if (fboundp 'read-passwd)
727 (read-passwd prompt nil default)
728 (unless (fboundp 'ange-ftp-read-passwd)
729 (autoload 'ange-ftp-read-passwd "ange-ftp"))
730 (ange-ftp-read-passwd prompt default)))
731
732 (defun sql-get-login (&rest what)
733 "Get username, password and database from the user.
734
735 The variables `sql-user', `sql-password', `sql-server', and
736 `sql-database' can be customised. They are used as the default values.
737 Usernames, servers and databases are stored in `sql-user-history',
738 `sql-server-history' and `database-history'. Passwords are not stored
739 in a history.
740
741 Parameter WHAT is a list of the arguments passed to this function.
742 The function asks for the username if WHAT contains symbol `user', for
743 the password if it contains symbol `password', for the server if it
744 contains symbol `server', and for the database if it contains symbol
745 `database'.
746
747 In order to ask the user for username, password and database, call the
748 function like this: (sql-get-login 'user 'password 'database)."
749 (interactive)
750 (if (memq 'user what)
751 (setq sql-user
752 (read-from-minibuffer "User: " sql-user nil nil
753 sql-user-history)))
754 (if (memq 'password what)
755 (setq sql-password
756 (sql-read-passwd "Password: " sql-password)))
757 (if (memq 'server what)
758 (setq sql-server
759 (read-from-minibuffer "Server: " sql-server nil nil
760 sql-server-history)))
761 (if (memq 'database what)
762 (setq sql-database
763 (read-from-minibuffer "Database: " sql-database nil nil
764 sql-database-history))))
765
766 (defun sql-find-sqli-buffer ()
767 "Return the current default SQLi buffer or nil.
768 In order to qualify, the SQLi buffer must be alive,
769 be in `sql-interactive-mode' and have a process."
770 (let ((default-buffer (default-value 'sql-buffer)))
771 (if (and (buffer-live-p default-buffer)
772 (get-buffer-process default-buffer))
773 default-buffer
774 (save-excursion
775 (let ((buflist (buffer-list))
776 (found))
777 (while (not (or (null buflist)
778 found))
779 (let ((candidate (car buflist)))
780 (set-buffer candidate)
781 (if (and (equal major-mode 'sql-interactive-mode)
782 (get-buffer-process candidate))
783 (setq found candidate))
784 (setq buflist (cdr buflist))))
785 found)))))
786
787 (defun sql-set-sqli-buffer-generally ()
788 "Set SQLi buffer for all SQL buffers that have none.
789 This function checks all SQL buffers for their SQLi buffer. If their
790 SQLi buffer is nonexistent or has no process, it is set to the current
791 default SQLi buffer. The current default SQLi buffer is determined
792 using `sql-find-sqli-buffer'. If `sql-buffer' is set,
793 `sql-set-sqli-hook' is run."
794 (interactive)
795 (save-excursion
796 (let ((buflist (buffer-list))
797 (default-sqli-buffer (sql-find-sqli-buffer)))
798 (setq-default sql-buffer default-sqli-buffer)
799 (while (not (null buflist))
800 (let ((candidate (car buflist)))
801 (set-buffer candidate)
802 (if (and (equal major-mode 'sql-mode)
803 (not (buffer-live-p sql-buffer)))
804 (progn
805 (setq sql-buffer default-sqli-buffer)
806 (run-hooks 'sql-set-sqli-hook))))
807 (setq buflist (cdr buflist))))))
808
809 (defun sql-set-sqli-buffer ()
810 "Set the SQLi buffer SQL strings are sent to.
811
812 Call this function in a SQL buffer in order to set the SQLi buffer SQL
813 strings are sent to. Calling this function sets `sql-buffer' and runs
814 `sql-set-sqli-hook'.
815
816 If you call it from a SQL buffer, this sets the local copy of
817 `sql-buffer'.
818
819 If you call it from anywhere else, it sets the global copy of
820 `sql-buffer'."
821 (interactive)
822 (let ((default-buffer (sql-find-sqli-buffer)))
823 (if (null default-buffer)
824 (error "There is no suitable SQLi buffer"))
825 (let ((new-buffer
826 (get-buffer
827 (read-buffer "New SQLi buffer: " default-buffer t))))
828 (if (null (get-buffer-process new-buffer))
829 (error "Buffer %s has no process" (buffer-name new-buffer)))
830 (if (null (save-excursion
831 (set-buffer new-buffer)
832 (equal major-mode 'sql-interactive-mode)))
833 (error "Buffer %s is no SQLi buffer" (buffer-name new-buffer)))
834 (if new-buffer
835 (progn
836 (setq sql-buffer new-buffer)
837 (run-hooks 'sql-set-sqli-hook))))))
838
839 (defun sql-show-sqli-buffer ()
840 "Show the name of current SQLi buffer.
841
842 This is the buffer SQL strings are sent to. It is stored in the
843 variable `sql-buffer'. See `sql-help' on how to create such a buffer."
844 (interactive)
845 (if (null (buffer-live-p sql-buffer))
846 (message "%s has no SQLi buffer set." (buffer-name (current-buffer)))
847 (if (null (get-buffer-process sql-buffer))
848 (message "Buffer %s has no process." (buffer-name sql-buffer))
849 (message "Current SQLi buffer is %s." (buffer-name sql-buffer)))))
850
851 (defun sql-make-alternate-buffer-name ()
852 "Return a string that can be used to rename a SQLi buffer.
853
854 This is used to set `sql-alternate-buffer-name' within
855 `sql-interactive-mode'."
856 (concat (if (string= "" sql-user)
857 (if (string= "" (user-login-name))
858 ()
859 (concat (user-login-name) "/"))
860 (concat sql-user "/"))
861 (if (string= "" sql-database)
862 (if (string= "" sql-server)
863 (system-name)
864 sql-server)
865 sql-database)))
866
867 (defun sql-rename-buffer ()
868 "Renames a SQLi buffer."
869 (interactive)
870 (rename-buffer (format "*SQL: %s*" sql-alternate-buffer-name) t))
871
872 (defun sql-copy-column ()
873 "Copy current column to the end of buffer.
874 Inserts SELECT or commas if appropriate."
875 (interactive)
876 (let ((column))
877 (save-excursion
878 (setq column (buffer-substring
879 (progn (forward-char 1) (backward-sexp 1) (point))
880 (progn (forward-sexp 1) (point))))
881 (goto-char (point-max))
882 (cond
883 ;; if empty command line, insert SELECT
884 ((save-excursion (beginning-of-line)
885 (looking-at (concat comint-prompt-regexp "$")))
886 (insert "SELECT "))
887 ;; else if appending to INTO .* (, SELECT or ORDER BY, insert a comma
888 ((save-excursion
889 (re-search-backward "\\b\\(\\(into\\s-+\\S-+\\s-+(\\)\\|select\\|order by\\) .+"
890 (save-excursion (beginning-of-line) (point)) t))
891 (insert ", "))
892 ;; else insert a space
893 (t
894 (if (eq (preceding-char) ? )
895 nil
896 (insert " "))))
897 ;; in any case, insert the column
898 (insert column)
899 (message "%s" column))))
900
901 \f
902
903 ;;; Sending the region to the SQLi buffer.
904
905 (defun sql-send-region (start end)
906 "Send a region to the SQL process."
907 (interactive "r")
908 (if (buffer-live-p sql-buffer)
909 (save-excursion
910 (comint-send-region sql-buffer start end)
911 (if (string-match "\n$" (buffer-substring start end))
912 ()
913 (comint-send-string sql-buffer "\n"))
914 (message "Sent string to buffer %s." (buffer-name sql-buffer))
915 (if sql-pop-to-buffer-after-send-region
916 (pop-to-buffer sql-buffer)
917 (display-buffer sql-buffer)))
918 (message "No SQL process started.")))
919
920 (defun sql-send-paragraph ()
921 "Send the current paragraph to the SQL process."
922 (interactive)
923 (let ((start (save-excursion
924 (backward-paragraph)
925 (point)))
926 (end (save-excursion
927 (forward-paragraph)
928 (point))))
929 (sql-send-region start end)))
930
931 (defun sql-send-buffer ()
932 "Send the buffer contents to the SQL process."
933 (interactive)
934 (sql-send-region (point-min) (point-max)))
935
936 (defun sql-toggle-pop-to-buffer-after-send-region (&optional value)
937 "Toggle `sql-pop-to-buffer-after-send-region'.
938
939 If given the optional parameter VALUE, sets
940 sql-toggle-pop-to-buffer-after-send-region to VALUE."
941 (interactive "P")
942 (if value
943 (setq sql-pop-to-buffer-after-send-region value)
944 (setq sql-pop-to-buffer-after-send-region
945 (null sql-pop-to-buffer-after-send-region ))))
946
947 \f
948
949 ;;; SQL mode -- uses SQL interactive mode
950
951 ;;;###autoload
952 (defun sql-mode ()
953 "Major mode to edit SQL.
954
955 You can send SQL statements to the SQLi buffer using
956 \\[sql-send-region]. Such a buffer must exist before you can do this.
957 See `sql-help' on how to create SQLi buffers.
958
959 \\{sql-mode-map}
960 Customization: Entry to this mode runs the `sql-mode-hook'.
961
962 When you put a buffer in SQL mode, the buffer stores the last SQLi
963 buffer created as its destination in the variable `sql-buffer'. This
964 will be the buffer \\[sql-send-region] sends the region to. If this
965 SQLi buffer is killed, \\[sql-send-region] is no longer able to
966 determine where the strings should be sent to. You can set the
967 value of `sql-buffer' using \\[sql-set-sqli-buffer].
968
969 For information on how to create multiple SQLi buffers, see
970 `sql-interactive-mode'."
971 (interactive)
972 (kill-all-local-variables)
973 (setq major-mode 'sql-mode)
974 (setq mode-name "SQL")
975 (use-local-map sql-mode-map)
976 (set-syntax-table sql-mode-syntax-table)
977 (make-local-variable 'font-lock-defaults)
978 ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
979 ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
980 ;; will have just one quote. Therefore syntactic hilighting is
981 ;; disabled for interactive buffers. `_' and `.' are considered part
982 ;; of words.
983 (setq font-lock-defaults '(sql-mode-font-lock-keywords
984 nil t ((?_ . "w") (?. . "w"))))
985 (make-local-variable 'comment-start)
986 (setq comment-start "--")
987 ;; Make each buffer in sql-mode remember the "current" SQLi buffer.
988 (make-local-variable 'sql-buffer)
989 ;; Add imenu support for sql-mode. Note that imenu-generic-expression
990 ;; is buffer-local, so we don't need a local-variable for it. SQL is
991 ;; case-insensitive, that's why we have to set imenu-case-fold-search.
992 ;; imenu-syntax-alist makes sure that `_' is considered part of object
993 ;; names.
994 (setq imenu-generic-expression sql-imenu-generic-expression
995 imenu-case-fold-search t
996 imenu-syntax-alist '(("_" . "w")))
997 ;; Make `sql-send-paragraph' work on paragraphs that contain indented
998 ;; lines.
999 (make-local-variable 'paragraph-separate)
1000 (make-local-variable 'paragraph-start)
1001 (setq paragraph-separate "[\f]*$"
1002 paragraph-start "[\n\f]")
1003 ;; Abbrevs
1004 (setq local-abbrev-table sql-mode-abbrev-table)
1005 (setq abbrev-all-caps 1)
1006 ;; Run hook
1007 (run-hooks 'sql-mode-hook))
1008
1009 \f
1010
1011 ;;; SQL interactive mode
1012
1013 (put 'sql-interactive-mode 'mode-class 'special)
1014
1015 (defun sql-interactive-mode ()
1016 "Major mode to use a SQL interpreter interactively.
1017
1018 Do not call this function by yourself. The environment must be
1019 initialized by an entry function specific for the SQL interpreter. See
1020 `sql-help' for a list of available entry functions.
1021
1022 \\[comint-send-input] after the end of the process' output sends the
1023 text from the end of process to the end of the current line.
1024 \\[comint-send-input] before end of process output copies the current
1025 line minus the prompt to the end of the buffer and sends it.
1026 \\[comint-copy-old-input] just copies the current line.
1027 Use \\[sql-accumulate-and-indent] to enter multi-line statements.
1028
1029 If you want to make multiple SQL buffers, rename the `*SQL*' buffer
1030 using \\[rename-buffer] or \\[rename-uniquely] and start a new process.
1031 See `sql-help' for a list of available entry functions. The last buffer
1032 created by such an entry function is the current SQLi buffer. SQL
1033 buffers will send strings to the SQLi buffer current at the time of
1034 their creation. See `sql-mode' for details.
1035
1036 Sample session using two connections:
1037
1038 1. Create first SQLi buffer by calling an entry function.
1039 2. Rename buffer \"*SQL*\" to \"*Connection 1*\".
1040 3. Create a SQL buffer \"test1.sql\".
1041 4. Create second SQLi buffer by calling an entry function.
1042 5. Rename buffer \"*SQL*\" to \"*Connection 2*\".
1043 6. Create a SQL buffer \"test2.sql\".
1044
1045 Now \\[sql-send-region] in buffer \"test1.sql\" will send the region to
1046 buffer \"*Connection 1*\", \\[sql-send-region] in buffer \"test2.sql\"
1047 will send the region to buffer \"*Connection 2*\".
1048
1049 If you accidentally suspend your process, use \\[comint-continue-subjob]
1050 to continue it. On some operating systems, this will not work because
1051 the signals are not supported.
1052
1053 \\{sql-interactive-mode-map}
1054 Customization: Entry to this mode runs the hooks on `comint-mode-hook'
1055 and `sql-interactive-mode-hook' (in that order). Before each input, the
1056 hooks on `comint-input-filter-functions' are run. After each SQL
1057 interpreter output, the hooks on `comint-output-filter-functions' are
1058 run.
1059
1060 Variable `sql-input-ring-file-name' controls the initialisation of the
1061 input ring history. `comint-input-ring-file-name' is temporarily bound
1062 to `sql-input-ring-file-name' when reading the input history.
1063
1064 Variables `comint-output-filter-functions', a hook, and
1065 `comint-scroll-to-bottom-on-input' and
1066 `comint-scroll-to-bottom-on-output' control whether input and output
1067 cause the window to scroll to the end of the buffer.
1068
1069 If you want to make SQL buffers limited in length, add the function
1070 `comint-truncate-buffer' to `comint-output-filter-functions'.
1071
1072 Here is an example for your .emacs file. It keeps the SQLi buffer a
1073 certain length.
1074
1075 \(add-hook 'sql-interactive-mode-hook
1076 \(function (lambda ()
1077 \(setq comint-output-filter-functions 'comint-truncate-buffer))))
1078
1079 Here is another example. It will always put point back to the statement
1080 you entered, right above the output it created.
1081
1082 \(setq comint-output-filter-functions
1083 \(function (lambda (STR) (comint-show-output))))"
1084 (comint-mode)
1085 (setq comint-prompt-regexp sql-prompt-regexp)
1086 (setq left-margin sql-prompt-length)
1087 (setq major-mode 'sql-interactive-mode)
1088 (setq mode-name "SQLi")
1089 (use-local-map sql-interactive-mode-map)
1090 (set-syntax-table sql-mode-syntax-table)
1091 (make-local-variable 'font-lock-defaults)
1092 ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
1093 ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
1094 ;; will have just one quote. Therefore syntactic hilighting is
1095 ;; disabled for interactive buffers. `_' and `.' are considered part
1096 ;; of words.
1097 (setq font-lock-defaults '(sql-mode-font-lock-keywords
1098 t t ((?_ . "w") (?. . "w"))))
1099 ;; Enable commenting and uncommenting of the region.
1100 (make-local-variable 'comment-start)
1101 (setq comment-start "--")
1102 ;; Abbreviation table init and case-insensitive. It is not activatet
1103 ;; by default.
1104 (setq local-abbrev-table sql-mode-abbrev-table)
1105 (setq abbrev-all-caps 1)
1106 ;; Exiting the process will call sql-stop.
1107 (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop)
1108 ;; Make input-ring stuff buffer local so that people who want a
1109 ;; different history file for each buffer/process/client/whatever can
1110 ;; change separator and file-name on the sql-interactive-mode-hook.
1111 (make-local-variable 'sql-input-ring-separator)
1112 (make-local-variable 'sql-input-ring-file-name)
1113 ;; Create a usefull name for renaming this buffer later.
1114 (make-local-variable 'sql-alternate-buffer-name)
1115 (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name))
1116 ;; User stuff.
1117 (run-hooks 'sql-interactive-mode-hook)
1118 ;; Calling the hook before calling comint-read-input-ring allows users
1119 ;; to set comint-input-ring-file-name in sql-interactive-mode-hook.
1120 ;; While reading the history, file-name and history are rebound...
1121 (let ((comint-input-ring-file-name sql-input-ring-file-name)
1122 (comint-input-ring-separator sql-input-ring-separator))
1123 (comint-read-input-ring t)))
1124
1125 (defun sql-stop (process event)
1126 "Called when the SQL process is stopped.
1127
1128 Writes the input history to a history file using
1129 `comint-write-input-ring' and inserts a short message in the SQL buffer.
1130 `comint-comint-input-ring-file-name' is temporarily bound to
1131 `sql-input-ring-file-name'.
1132
1133 This function is a sentinel watching the SQL interpreter process.
1134 Sentinels will always get the two parameters PROCESS and EVENT."
1135 ;; Write history.
1136 ;; While reading the history, file-name and history are rebound...
1137 (let ((comint-input-ring-file-name sql-input-ring-file-name)
1138 (comint-input-ring-separator sql-input-ring-separator))
1139 (comint-write-input-ring))
1140 (if (buffer-live-p sql-buffer)
1141 (insert (format "\nProcess %s %s\n" process event))))
1142
1143 \f
1144
1145 ;;; Entry functions for different SQL interpreters.
1146
1147 (defun sql-oracle ()
1148 "Run sqlplus by Oracle as an inferior process.
1149
1150 If buffer `*SQL*' exists but no process is running, make a new process.
1151 If buffer exists and a process is running, just switch to buffer
1152 `*SQL*'.
1153
1154 Interpreter used comes from variable `sql-oracle-program'. Login uses
1155 the variables `sql-user', `sql-password', and `sql-database' as
1156 defaults, if set. Additional command line parameters can be stored in
1157 the list `sql-oracle-options'.
1158
1159 The buffer is put in sql-interactive-mode, giving commands for sending
1160 input. See `sql-interactive-mode'.
1161
1162 To specify a coding system for converting non-ASCII characters
1163 in the input and output to the process, use \\[universal-coding-system-argument]
1164 before \\[sql-oracle]. You can also specify this with \\[set-buffer-process-coding-system]
1165 in the SQL buffer, after you start the process.
1166 The default comes from `process-coding-system-alist' and
1167 `default-process-coding-system'.
1168
1169 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1170 (interactive)
1171 (if (comint-check-proc "*SQL*")
1172 (pop-to-buffer "*SQL*")
1173 (sql-get-login 'user 'password 'database)
1174 (message "Login...")
1175 ;; Produce user/password@database construct. Password without user
1176 ;; is meaningless; database without user/password is meaningless,
1177 ;; because "@param" will ask sqlplus to interpret the script
1178 ;; "param".
1179 (let ((parameter nil))
1180 (if (not (string= "" sql-user))
1181 (if (not (string= "" sql-password))
1182 (setq parameter (concat sql-user "/" sql-password))
1183 (setq parameter sql-user)))
1184 (if (and parameter (not (string= "" sql-database)))
1185 (setq parameter (concat parameter "@" sql-database)))
1186 (if parameter
1187 (setq parameter (nconc (list parameter) sql-oracle-options))
1188 (setq parameter sql-oracle-options))
1189 (if parameter
1190 (set-buffer (apply 'make-comint "SQL" sql-oracle-program nil
1191 parameter))
1192 (set-buffer (make-comint "SQL" sql-oracle-program nil))))
1193 (setq sql-prompt-regexp "^SQL> ")
1194 (setq sql-prompt-length 5)
1195 (setq sql-buffer (current-buffer))
1196 ;; set sql-mode-font-lock-keywords to something different before
1197 ;; calling sql-interactive-mode.
1198 (setq sql-mode-font-lock-keywords sql-mode-oracle-font-lock-keywords)
1199 (sql-interactive-mode)
1200 (message "Login...done")
1201 (pop-to-buffer sql-buffer)))
1202
1203 \f
1204
1205 (defun sql-sybase ()
1206 "Run isql by SyBase as an inferior process.
1207
1208 If buffer `*SQL*' exists but no process is running, make a new process.
1209 If buffer exists and a process is running, just switch to buffer
1210 `*SQL*'.
1211
1212 Interpreter used comes from variable `sql-sybase-program'. Login uses
1213 the variables `sql-user', `sql-password', and `sql-server' as
1214 defaults, if set.
1215
1216 The buffer is put in sql-interactive-mode, giving commands for sending
1217 input. See `sql-interactive-mode'.
1218
1219 To specify a coding system for converting non-ASCII characters
1220 in the input and output to the process, use \\[universal-coding-system-argument]
1221 before \\[sql-sybase]. You can also specify this with \\[set-buffer-process-coding-system]
1222 in the SQL buffer, after you start the process.
1223 The default comes from `process-coding-system-alist' and
1224 `default-process-coding-system'.
1225
1226 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1227 (interactive)
1228 (if (comint-check-proc "*SQL*")
1229 (pop-to-buffer "*SQL*")
1230 (sql-get-login 'user 'password 'server)
1231 (message "Login...")
1232 ;; Put all parameters to the program (if defined) in a list and call
1233 ;; make-comint.
1234 (let ((params '("-w" "2048" "-n")))
1235 ;; There is no way to specify the database via command line
1236 ;; parameters. The -S option specifies the server.
1237 (if (not (string= "" sql-server))
1238 (setq params (append (list "-S" sql-server) params)))
1239 (if (not (string= "" sql-password))
1240 (setq params (append (list "-P" sql-password) params)))
1241 (if (not (string= "" sql-user))
1242 (setq params (append (list "-U" sql-user) params)))
1243 (set-buffer (apply 'make-comint "SQL" sql-sybase-program
1244 nil params)))
1245 (setq sql-prompt-regexp "^SQL> ")
1246 (setq sql-prompt-length 5)
1247 (setq sql-buffer (current-buffer))
1248 (sql-interactive-mode)
1249 (message "Login...done")
1250 (pop-to-buffer sql-buffer)))
1251
1252 \f
1253
1254 (defun sql-informix ()
1255 "Run dbaccess by Informix as an inferior process.
1256
1257 If buffer `*SQL*' exists but no process is running, make a new process.
1258 If buffer exists and a process is running, just switch to buffer
1259 `*SQL*'.
1260
1261 Interpreter used comes from variable `sql-informix-program'. Login uses
1262 the variable `sql-database' as default, if set.
1263
1264 The buffer is put in sql-interactive-mode, giving commands for sending
1265 input. See `sql-interactive-mode'.
1266
1267 To specify a coding system for converting non-ASCII characters
1268 in the input and output to the process, use \\[universal-coding-system-argument]
1269 before \\[sql-informix]. You can also specify this with \\[set-buffer-process-coding-system]
1270 in the SQL buffer, after you start the process.
1271 The default comes from `process-coding-system-alist' and
1272 `default-process-coding-system'.
1273
1274 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1275 (interactive)
1276 (if (comint-check-proc "*SQL*")
1277 (pop-to-buffer "*SQL*")
1278 (sql-get-login 'database)
1279 (message "Login...")
1280 ;; username and password are ignored.
1281 (if (string= "" sql-database)
1282 (set-buffer (make-comint "SQL" sql-informix-program nil))
1283 (set-buffer (make-comint "SQL" sql-informix-program nil sql-database "-")))
1284 (setq sql-prompt-regexp "^SQL> ")
1285 (setq sql-prompt-length 5)
1286 (setq sql-buffer (current-buffer))
1287 (sql-interactive-mode)
1288 (message "Login...done")
1289 (pop-to-buffer sql-buffer)))
1290
1291 \f
1292
1293 (defun sql-mysql ()
1294 "Run mysql by TcX as an inferior process.
1295
1296 Note that the widespread idea that mysql is free software is inaccurate;
1297 its license is too restrictive. We urge you to use PostGres instead.
1298
1299 If buffer `*SQL*' exists but no process is running, make a new process.
1300 If buffer exists and a process is running, just switch to buffer
1301 `*SQL*'.
1302
1303 Interpreter used comes from variable `sql-mysql-program'. Login uses
1304 the variables `sql-user', `sql-password', `sql-database', and
1305 `sql-server' as defaults, if set.
1306
1307 The buffer is put in sql-interactive-mode, giving commands for sending
1308 input. See `sql-interactive-mode'.
1309
1310 To specify a coding system for converting non-ASCII characters
1311 in the input and output to the process, use \\[universal-coding-system-argument]
1312 before \\[sql-mysql]. You can also specify this with \\[set-buffer-process-coding-system]
1313 in the SQL buffer, after you start the process.
1314 The default comes from `process-coding-system-alist' and
1315 `default-process-coding-system'.
1316
1317 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1318 (interactive)
1319 (if (comint-check-proc "*SQL*")
1320 (pop-to-buffer "*SQL*")
1321 (sql-get-login 'user 'password 'database 'server)
1322 (message "Login...")
1323 ;; Put all parameters to the program (if defined) in a list and call
1324 ;; make-comint.
1325 (let ((params))
1326 (if (not (string= "" sql-database))
1327 (setq params (append (list sql-database) params)))
1328 (if (not (string= "" sql-server))
1329 (setq params (append (list (concat "--host=" sql-server)) params)))
1330 (if (not (string= "" sql-password))
1331 (setq params (append (list (concat "--password=" sql-password)) params)))
1332 (if (not (string= "" sql-user))
1333 (setq params (append (list (concat "--user=" sql-user)) params)))
1334 (set-buffer (apply 'make-comint "SQL" sql-mysql-program
1335 nil params)))
1336 (setq sql-prompt-regexp "^mysql>")
1337 (setq sql-prompt-length 6)
1338 (setq sql-buffer (current-buffer))
1339 (sql-interactive-mode)
1340 (message "Login...done")
1341 (pop-to-buffer sql-buffer)))
1342
1343 \f
1344
1345 (defun sql-solid ()
1346 "Run solsql by Solid as an inferior process.
1347
1348 If buffer `*SQL*' exists but no process is running, make a new process.
1349 If buffer exists and a process is running, just switch to buffer
1350 `*SQL*'.
1351
1352 Interpreter used comes from variable `sql-solid-program'. Login uses
1353 the variables `sql-user', `sql-password', and `sql-server' as
1354 defaults, if set.
1355
1356 The buffer is put in sql-interactive-mode, giving commands for sending
1357 input. See `sql-interactive-mode'.
1358
1359 To specify a coding system for converting non-ASCII characters
1360 in the input and output to the process, use \\[universal-coding-system-argument]
1361 before \\[sql-solid]. You can also specify this with \\[set-buffer-process-coding-system]
1362 in the SQL buffer, after you start the process.
1363 The default comes from `process-coding-system-alist' and
1364 `default-process-coding-system'.
1365
1366 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1367 (interactive)
1368 (if (comint-check-proc "*SQL*")
1369 (pop-to-buffer "*SQL*")
1370 (sql-get-login 'user 'password 'server)
1371 (message "Login...")
1372 ;; Put all parameters to the program (if defined) in a list and call
1373 ;; make-comint.
1374 (let ((params))
1375 ;; It only makes sense if both username and password are there.
1376 (if (not (or (string= "" sql-user)
1377 (string= "" sql-password)))
1378 (setq params (append (list sql-user sql-password) params)))
1379 (if (not (string= "" sql-server))
1380 (setq params (append (list sql-server) params)))
1381 (set-buffer (apply 'make-comint "SQL" sql-solid-program
1382 nil params)))
1383 (setq sql-prompt-regexp "^")
1384 (setq sql-prompt-length 0)
1385 (setq sql-buffer (current-buffer))
1386 (sql-interactive-mode)
1387 (message "Login...done")
1388 (pop-to-buffer sql-buffer)))
1389
1390 \f
1391
1392 (defun sql-ingres ()
1393 "Run sql by Ingres as an inferior process.
1394
1395 If buffer `*SQL*' exists but no process is running, make a new process.
1396 If buffer exists and a process is running, just switch to buffer
1397 `*SQL*'.
1398
1399 Interpreter used comes from variable `sql-ingres-program'. Login uses
1400 the variable `sql-database' as default, if set.
1401
1402 The buffer is put in sql-interactive-mode, giving commands for sending
1403 input. See `sql-interactive-mode'.
1404
1405 To specify a coding system for converting non-ASCII characters
1406 in the input and output to the process, use \\[universal-coding-system-argument]
1407 before \\[sql-ingres]. You can also specify this with \\[set-buffer-process-coding-system]
1408 in the SQL buffer, after you start the process.
1409 The default comes from `process-coding-system-alist' and
1410 `default-process-coding-system'.
1411
1412 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1413 (interactive)
1414 (if (comint-check-proc "*SQL*")
1415 (pop-to-buffer "*SQL*")
1416 (sql-get-login 'database)
1417 (message "Login...")
1418 ;; username and password are ignored.
1419 (if (string= "" sql-database)
1420 (set-buffer (make-comint "SQL" sql-ingres-program nil))
1421 (set-buffer (make-comint "SQL" sql-ingres-program nil sql-database)))
1422 (setq sql-prompt-regexp "^\* ")
1423 (setq sql-prompt-length 2)
1424 (setq sql-buffer (current-buffer))
1425 (sql-interactive-mode)
1426 (message "Login...done")
1427 (pop-to-buffer sql-buffer)))
1428
1429 \f
1430
1431 (defun sql-ms ()
1432 "Run isql by Microsoft as an inferior process.
1433
1434 If buffer `*SQL*' exists but no process is running, make a new process.
1435 If buffer exists and a process is running, just switch to buffer
1436 `*SQL*'.
1437
1438 Interpreter used comes from variable `sql-ms-program'. Login uses the
1439 variables `sql-user', `sql-password', `sql-database', and `sql-server'
1440 as defaults, if set.
1441
1442 The buffer is put in sql-interactive-mode, giving commands for sending
1443 input. See `sql-interactive-mode'.
1444
1445 To specify a coding system for converting non-ASCII characters
1446 in the input and output to the process, use \\[universal-coding-system-argument]
1447 before \\[sql-ms]. You can also specify this with \\[set-buffer-process-coding-system]
1448 in the SQL buffer, after you start the process.
1449 The default comes from `process-coding-system-alist' and
1450 `default-process-coding-system'.
1451
1452 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1453 (interactive)
1454 (if (comint-check-proc "*SQL*")
1455 (pop-to-buffer "*SQL*")
1456 (sql-get-login 'user 'password 'database 'server)
1457 (message "Login...")
1458 ;; Put all parameters to the program (if defined) in a list and call
1459 ;; make-comint.
1460 (let ((params '("-w 300")))
1461 (if (not (string= "" sql-server))
1462 (setq params (append (list "-S" sql-server) params)))
1463 (if (not (string= "" sql-database))
1464 (setq params (append (list "-d" sql-database) params)))
1465 (if (not (string= "" sql-user))
1466 (setq params (append (list "-U" sql-user) params)))
1467 (if (not (string= "" sql-password))
1468 (setq params (append (list "-P" sql-password) params))
1469 ;; If -P is passed to ISQL as the last argument without a password,
1470 ;; it's considered null.
1471 (setq params (append params (list "-P"))))
1472 (set-buffer (apply 'make-comint "SQL" sql-ms-program
1473 nil params)))
1474 (setq sql-prompt-regexp "^[0-9]*>")
1475 (setq sql-prompt-length 5)
1476 (setq sql-buffer (current-buffer))
1477 (sql-interactive-mode)
1478 (message "Login...done")
1479 (pop-to-buffer sql-buffer)))
1480
1481
1482 \f
1483
1484 ;;;###autoload
1485 (defun sql-postgres ()
1486 "Run psql by Postgres as an inferior process.
1487
1488 If buffer `*SQL*' exists but no process is running, make a new process.
1489 If buffer exists and a process is running, just switch to buffer
1490 `*SQL*'.
1491
1492 Interpreter used comes from variable `sql-postgres-program'. Login uses
1493 the variables `sql-database' and `sql-server' as default, if set.
1494
1495 The buffer is put in sql-interactive-mode, giving commands for sending
1496 input. See `sql-interactive-mode'.
1497
1498 To specify a coding system for converting non-ASCII characters
1499 in the input and output to the process, use \\[universal-coding-system-argument]
1500 before \\[sql-postgres]. You can also specify this with \\[set-buffer-process-coding-system]
1501 in the SQL buffer, after you start the process.
1502 The default comes from `process-coding-system-alist' and
1503 `default-process-coding-system'. If your output lines end with ^M,
1504 your might try undecided-dos as a coding system. If this doesn't help,
1505 Try to set `comint-output-filter-functions' like this:
1506
1507 \(setq comint-output-filter-functions (append comint-output-filter-functions
1508 '(comint-strip-ctrl-m)))
1509
1510 \(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
1511 (interactive)
1512 (if (comint-check-proc "*SQL*")
1513 (pop-to-buffer "*SQL*")
1514 (sql-get-login 'database 'server)
1515 (message "Login...")
1516 ;; username and password are ignored.
1517 (let ((params))
1518 (if (not (string= "" sql-database))
1519 (setq params (append (list sql-database) params)))
1520 (if (not (string= "" sql-server))
1521 (setq params (append (list "-h" sql-server) params)))
1522 (set-buffer (apply 'make-comint "SQL" sql-postgres-program
1523 nil params)))
1524 (setq sql-prompt-regexp "^.*> *")
1525 (setq sql-prompt-length 5)
1526 ;; This is a lousy hack to prevent psql from truncating it's output
1527 ;; and giving stupid warnings. If s.o. knows a way to prevent psql
1528 ;; from acting this way, then I would be very thankful to
1529 ;; incorporate this (Gregor Zych <zych@pool.informatik.rwth-aachen.de>)
1530 (comint-send-string "*SQL*" "\\o \| cat\n")
1531 (setq sql-mode-font-lock-keywords sql-mode-postgres-font-lock-keywords)
1532 (setq sql-buffer (current-buffer))
1533 (sql-interactive-mode)
1534 (message "Login...done")
1535 (pop-to-buffer sql-buffer)))
1536
1537 (provide 'sql)
1538
1539 ;;; sql.el ends here