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