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