diff options
Diffstat (limited to 'lisp/progmodes/sql.el')
| -rw-r--r-- | lisp/progmodes/sql.el | 898 |
1 files changed, 657 insertions, 241 deletions
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 19e60da7ea2..e44504688f2 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | ;; Author: Alex Schroeder <alex@gnu.org> | 6 | ;; Author: Alex Schroeder <alex@gnu.org> |
| 7 | ;; Maintainer: Michael Mauger <mmaug@yahoo.com> | 7 | ;; Maintainer: Michael Mauger <mmaug@yahoo.com> |
| 8 | ;; Version: 2.1 | 8 | ;; Version: 2.5 |
| 9 | ;; Keywords: comm languages processes | 9 | ;; Keywords: comm languages processes |
| 10 | ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el | 10 | ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el |
| 11 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode | 11 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode |
| @@ -152,11 +152,7 @@ | |||
| 152 | 152 | ||
| 153 | ;; (defcustom my-sql-xyz-login-params '(user password server database) | 153 | ;; (defcustom my-sql-xyz-login-params '(user password server database) |
| 154 | ;; "Login parameters to needed to connect to XyzDB." | 154 | ;; "Login parameters to needed to connect to XyzDB." |
| 155 | ;; :type '(repeat (choice | 155 | ;; :type 'sql-login-params |
| 156 | ;; (const user) | ||
| 157 | ;; (const password) | ||
| 158 | ;; (const server) | ||
| 159 | ;; (const database))) | ||
| 160 | ;; :group 'SQL) | 156 | ;; :group 'SQL) |
| 161 | ;; | 157 | ;; |
| 162 | ;; (sql-set-product-feature 'xyz | 158 | ;; (sql-set-product-feature 'xyz |
| @@ -170,7 +166,7 @@ | |||
| 170 | ;; (sql-set-product-feature 'xyz | 166 | ;; (sql-set-product-feature 'xyz |
| 171 | ;; :sqli-options 'my-sql-xyz-options)) | 167 | ;; :sqli-options 'my-sql-xyz-options)) |
| 172 | 168 | ||
| 173 | ;; (defun my-sql-connect-xyz (product options) | 169 | ;; (defun my-sql-comint-xyz (product options) |
| 174 | ;; "Connect ti XyzDB in a comint buffer." | 170 | ;; "Connect ti XyzDB in a comint buffer." |
| 175 | ;; | 171 | ;; |
| 176 | ;; ;; Do something with `sql-user', `sql-password', | 172 | ;; ;; Do something with `sql-user', `sql-password', |
| @@ -184,10 +180,10 @@ | |||
| 184 | ;; (setq params (append (list "-P" sql-password) params))) | 180 | ;; (setq params (append (list "-P" sql-password) params))) |
| 185 | ;; (if (not (string= "" sql-user)) | 181 | ;; (if (not (string= "" sql-user)) |
| 186 | ;; (setq params (append (list "-U" sql-user) params))) | 182 | ;; (setq params (append (list "-U" sql-user) params))) |
| 187 | ;; (sql-connect product params))) | 183 | ;; (sql-comint product params))) |
| 188 | ;; | 184 | ;; |
| 189 | ;; (sql-set-product-feature 'xyz | 185 | ;; (sql-set-product-feature 'xyz |
| 190 | ;; :sqli-connect-func 'my-sql-connect-xyz) | 186 | ;; :sqli-comint-func 'my-sql-comint-xyz) |
| 191 | 187 | ||
| 192 | ;; 6) Define a convienence function to invoke the SQL interpreter. | 188 | ;; 6) Define a convienence function to invoke the SQL interpreter. |
| 193 | 189 | ||
| @@ -236,7 +232,7 @@ | |||
| 236 | (require 'regexp-opt)) | 232 | (require 'regexp-opt)) |
| 237 | (require 'custom) | 233 | (require 'custom) |
| 238 | (eval-when-compile ;; needed in Emacs 19, 20 | 234 | (eval-when-compile ;; needed in Emacs 19, 20 |
| 239 | (setq max-specpdl-size 2000)) | 235 | (setq max-specpdl-size (max max-specpdl-size 2000))) |
| 240 | 236 | ||
| 241 | (defvar font-lock-keyword-face) | 237 | (defvar font-lock-keyword-face) |
| 242 | (defvar font-lock-set-defaults) | 238 | (defvar font-lock-set-defaults) |
| @@ -255,8 +251,8 @@ | |||
| 255 | (defcustom sql-user "" | 251 | (defcustom sql-user "" |
| 256 | "Default username." | 252 | "Default username." |
| 257 | :type 'string | 253 | :type 'string |
| 258 | :group 'SQL) | 254 | :group 'SQL |
| 259 | (put 'sql-user 'safe-local-variable 'stringp) | 255 | :safe 'stringp) |
| 260 | 256 | ||
| 261 | (defcustom sql-password "" | 257 | (defcustom sql-password "" |
| 262 | "Default password. | 258 | "Default password. |
| @@ -264,32 +260,68 @@ | |||
| 264 | Storing your password in a textfile such as ~/.emacs could be dangerous. | 260 | Storing your password in a textfile such as ~/.emacs could be dangerous. |
| 265 | Customizing your password will store it in your ~/.emacs file." | 261 | Customizing your password will store it in your ~/.emacs file." |
| 266 | :type 'string | 262 | :type 'string |
| 267 | :group 'SQL) | 263 | :group 'SQL |
| 268 | (put 'sql-password 'risky-local-variable t) | 264 | :risky t) |
| 269 | 265 | ||
| 270 | (defcustom sql-database "" | 266 | (defcustom sql-database "" |
| 271 | "Default database." | 267 | "Default database." |
| 272 | :type 'string | 268 | :type 'string |
| 273 | :group 'SQL) | 269 | :group 'SQL |
| 274 | (put 'sql-database 'safe-local-variable 'stringp) | 270 | :safe 'stringp) |
| 275 | 271 | ||
| 276 | (defcustom sql-server "" | 272 | (defcustom sql-server "" |
| 277 | "Default server or host." | 273 | "Default server or host." |
| 278 | :type 'string | 274 | :type 'string |
| 279 | :group 'SQL) | 275 | :group 'SQL |
| 280 | (put 'sql-server 'safe-local-variable 'stringp) | 276 | :safe 'stringp) |
| 281 | 277 | ||
| 282 | (defcustom sql-port nil | 278 | (defcustom sql-port nil |
| 283 | "Default server or host." | 279 | "Default server or host." |
| 280 | :version "24.1" | ||
| 284 | :type 'number | 281 | :type 'number |
| 285 | :group 'SQL) | 282 | :group 'SQL |
| 286 | (put 'sql-port 'safe-local-variable 'numberp) | 283 | :safe 'numberp) |
| 284 | |||
| 285 | ;; Login parameter type | ||
| 286 | |||
| 287 | (define-widget 'sql-login-params 'lazy | ||
| 288 | "Widget definition of the login parameters list" | ||
| 289 | :tag "Login Parameters" | ||
| 290 | :type '(repeat (choice | ||
| 291 | (const user) | ||
| 292 | (const password) | ||
| 293 | (choice :tag "server" | ||
| 294 | (const server) | ||
| 295 | (list :tag "file" | ||
| 296 | (const :format "" server) | ||
| 297 | (const :format "" :file) | ||
| 298 | regexp) | ||
| 299 | (list :tag "completion" | ||
| 300 | (const :format "" server) | ||
| 301 | (const :format "" :completion) | ||
| 302 | (restricted-sexp | ||
| 303 | :match-alternatives (listp symbolp)))) | ||
| 304 | (choice :tag "database" | ||
| 305 | (const database) | ||
| 306 | (list :tag "file" | ||
| 307 | (const :format "" database) | ||
| 308 | (const :format "" :file) | ||
| 309 | regexp) | ||
| 310 | (list :tag "completion" | ||
| 311 | (const :format "" database) | ||
| 312 | (const :format "" :completion) | ||
| 313 | (restricted-sexp | ||
| 314 | :match-alternatives (listp symbolp)))) | ||
| 315 | (const port)))) | ||
| 287 | 316 | ||
| 288 | ;; SQL Product support | 317 | ;; SQL Product support |
| 289 | 318 | ||
| 290 | (defvar sql-interactive-product nil | 319 | (defvar sql-interactive-product nil |
| 291 | "Product under `sql-interactive-mode'.") | 320 | "Product under `sql-interactive-mode'.") |
| 292 | 321 | ||
| 322 | (defvar sql-connection nil | ||
| 323 | "Connection name if interactive session started by `sql-connect'.") | ||
| 324 | |||
| 293 | (defvar sql-product-alist | 325 | (defvar sql-product-alist |
| 294 | '((ansi | 326 | '((ansi |
| 295 | :name "ANSI" | 327 | :name "ANSI" |
| @@ -301,9 +333,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 301 | :sqli-program sql-db2-program | 333 | :sqli-program sql-db2-program |
| 302 | :sqli-options sql-db2-options | 334 | :sqli-options sql-db2-options |
| 303 | :sqli-login sql-db2-login-params | 335 | :sqli-login sql-db2-login-params |
| 304 | :sqli-connect-func sql-connect-db2 | 336 | :sqli-comint-func sql-comint-db2 |
| 305 | :prompt-regexp "^db2 => " | 337 | :prompt-regexp "^db2 => " |
| 306 | :prompt-length 7 | 338 | :prompt-length 7 |
| 339 | :prompt-cont-regexp "^db2 (cont\.) => " | ||
| 307 | :input-filter sql-escape-newlines-filter) | 340 | :input-filter sql-escape-newlines-filter) |
| 308 | 341 | ||
| 309 | (informix | 342 | (informix |
| @@ -312,7 +345,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 312 | :sqli-program sql-informix-program | 345 | :sqli-program sql-informix-program |
| 313 | :sqli-options sql-informix-options | 346 | :sqli-options sql-informix-options |
| 314 | :sqli-login sql-informix-login-params | 347 | :sqli-login sql-informix-login-params |
| 315 | :sqli-connect-func sql-connect-informix | 348 | :sqli-comint-func sql-comint-informix |
| 316 | :prompt-regexp "^> " | 349 | :prompt-regexp "^> " |
| 317 | :prompt-length 2 | 350 | :prompt-length 2 |
| 318 | :syntax-alist ((?{ . "<") (?} . ">"))) | 351 | :syntax-alist ((?{ . "<") (?} . ">"))) |
| @@ -323,9 +356,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 323 | :sqli-program sql-ingres-program | 356 | :sqli-program sql-ingres-program |
| 324 | :sqli-options sql-ingres-options | 357 | :sqli-options sql-ingres-options |
| 325 | :sqli-login sql-ingres-login-params | 358 | :sqli-login sql-ingres-login-params |
| 326 | :sqli-connect-func sql-connect-ingres | 359 | :sqli-comint-func sql-comint-ingres |
| 327 | :prompt-regexp "^\* " | 360 | :prompt-regexp "^\* " |
| 328 | :prompt-length 2) | 361 | :prompt-length 2 |
| 362 | :prompt-cont-regexp "^\* ") | ||
| 329 | 363 | ||
| 330 | (interbase | 364 | (interbase |
| 331 | :name "Interbase" | 365 | :name "Interbase" |
| @@ -333,7 +367,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 333 | :sqli-program sql-interbase-program | 367 | :sqli-program sql-interbase-program |
| 334 | :sqli-options sql-interbase-options | 368 | :sqli-options sql-interbase-options |
| 335 | :sqli-login sql-interbase-login-params | 369 | :sqli-login sql-interbase-login-params |
| 336 | :sqli-connect-func sql-connect-interbase | 370 | :sqli-comint-func sql-comint-interbase |
| 337 | :prompt-regexp "^SQL> " | 371 | :prompt-regexp "^SQL> " |
| 338 | :prompt-length 5) | 372 | :prompt-length 5) |
| 339 | 373 | ||
| @@ -343,7 +377,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 343 | :sqli-program sql-linter-program | 377 | :sqli-program sql-linter-program |
| 344 | :sqli-options sql-linter-options | 378 | :sqli-options sql-linter-options |
| 345 | :sqli-login sql-linter-login-params | 379 | :sqli-login sql-linter-login-params |
| 346 | :sqli-connect-func sql-connect-linter | 380 | :sqli-comint-func sql-comint-linter |
| 347 | :prompt-regexp "^SQL>" | 381 | :prompt-regexp "^SQL>" |
| 348 | :prompt-length 4) | 382 | :prompt-length 4) |
| 349 | 383 | ||
| @@ -353,7 +387,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 353 | :sqli-program sql-ms-program | 387 | :sqli-program sql-ms-program |
| 354 | :sqli-options sql-ms-options | 388 | :sqli-options sql-ms-options |
| 355 | :sqli-login sql-ms-login-params | 389 | :sqli-login sql-ms-login-params |
| 356 | :sqli-connect-func sql-connect-ms | 390 | :sqli-comint-func sql-comint-ms |
| 357 | :prompt-regexp "^[0-9]*>" | 391 | :prompt-regexp "^[0-9]*>" |
| 358 | :prompt-length 5 | 392 | :prompt-length 5 |
| 359 | :syntax-alist ((?@ . "w")) | 393 | :syntax-alist ((?@ . "w")) |
| @@ -366,9 +400,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 366 | :sqli-program sql-mysql-program | 400 | :sqli-program sql-mysql-program |
| 367 | :sqli-options sql-mysql-options | 401 | :sqli-options sql-mysql-options |
| 368 | :sqli-login sql-mysql-login-params | 402 | :sqli-login sql-mysql-login-params |
| 369 | :sqli-connect-func sql-connect-mysql | 403 | :sqli-comint-func sql-comint-mysql |
| 370 | :prompt-regexp "^mysql> " | 404 | :prompt-regexp "^mysql> " |
| 371 | :prompt-length 6 | 405 | :prompt-length 6 |
| 406 | :prompt-cont-regexp "^ -> " | ||
| 372 | :input-filter sql-remove-tabs-filter) | 407 | :input-filter sql-remove-tabs-filter) |
| 373 | 408 | ||
| 374 | (oracle | 409 | (oracle |
| @@ -377,9 +412,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 377 | :sqli-program sql-oracle-program | 412 | :sqli-program sql-oracle-program |
| 378 | :sqli-options sql-oracle-options | 413 | :sqli-options sql-oracle-options |
| 379 | :sqli-login sql-oracle-login-params | 414 | :sqli-login sql-oracle-login-params |
| 380 | :sqli-connect-func sql-connect-oracle | 415 | :sqli-comint-func sql-comint-oracle |
| 381 | :prompt-regexp "^SQL> " | 416 | :prompt-regexp "^SQL> " |
| 382 | :prompt-length 5 | 417 | :prompt-length 5 |
| 418 | :prompt-cont-regexp "^\\s-*\\d+> " | ||
| 383 | :syntax-alist ((?$ . "w") (?# . "w")) | 419 | :syntax-alist ((?$ . "w") (?# . "w")) |
| 384 | :terminator ("\\(^/\\|;\\)" . "/") | 420 | :terminator ("\\(^/\\|;\\)" . "/") |
| 385 | :input-filter sql-placeholders-filter) | 421 | :input-filter sql-placeholders-filter) |
| @@ -391,9 +427,10 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 391 | :sqli-program sql-postgres-program | 427 | :sqli-program sql-postgres-program |
| 392 | :sqli-options sql-postgres-options | 428 | :sqli-options sql-postgres-options |
| 393 | :sqli-login sql-postgres-login-params | 429 | :sqli-login sql-postgres-login-params |
| 394 | :sqli-connect-func sql-connect-postgres | 430 | :sqli-comint-func sql-comint-postgres |
| 395 | :prompt-regexp "^.*[#>] *" | 431 | :prompt-regexp "^.*=[#>] " |
| 396 | :prompt-length 5 | 432 | :prompt-length 5 |
| 433 | :prompt-cont-regexp "^.*-[#>] " | ||
| 397 | :input-filter sql-remove-tabs-filter | 434 | :input-filter sql-remove-tabs-filter |
| 398 | :terminator ("\\(^[\\]g\\|;\\)" . ";")) | 435 | :terminator ("\\(^[\\]g\\|;\\)" . ";")) |
| 399 | 436 | ||
| @@ -403,7 +440,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 403 | :sqli-program sql-solid-program | 440 | :sqli-program sql-solid-program |
| 404 | :sqli-options sql-solid-options | 441 | :sqli-options sql-solid-options |
| 405 | :sqli-login sql-solid-login-params | 442 | :sqli-login sql-solid-login-params |
| 406 | :sqli-connect-func sql-connect-solid | 443 | :sqli-comint-func sql-comint-solid |
| 407 | :prompt-regexp "^" | 444 | :prompt-regexp "^" |
| 408 | :prompt-length 0) | 445 | :prompt-length 0) |
| 409 | 446 | ||
| @@ -414,9 +451,11 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 414 | :sqli-program sql-sqlite-program | 451 | :sqli-program sql-sqlite-program |
| 415 | :sqli-options sql-sqlite-options | 452 | :sqli-options sql-sqlite-options |
| 416 | :sqli-login sql-sqlite-login-params | 453 | :sqli-login sql-sqlite-login-params |
| 417 | :sqli-connect-func sql-connect-sqlite | 454 | :sqli-comint-func sql-comint-sqlite |
| 418 | :prompt-regexp "^sqlite> " | 455 | :prompt-regexp "^sqlite> " |
| 419 | :prompt-length 8) | 456 | :prompt-length 8 |
| 457 | :prompt-cont-regexp "^ ...> " | ||
| 458 | :terminator ";") | ||
| 420 | 459 | ||
| 421 | (sybase | 460 | (sybase |
| 422 | :name "Sybase" | 461 | :name "Sybase" |
| @@ -424,7 +463,7 @@ Customizing your password will store it in your ~/.emacs file." | |||
| 424 | :sqli-program sql-sybase-program | 463 | :sqli-program sql-sybase-program |
| 425 | :sqli-options sql-sybase-options | 464 | :sqli-options sql-sybase-options |
| 426 | :sqli-login sql-sybase-login-params | 465 | :sqli-login sql-sybase-login-params |
| 427 | :sqli-connect-func sql-connect-sybase | 466 | :sqli-comint-func sql-comint-sybase |
| 428 | :prompt-regexp "^SQL> " | 467 | :prompt-regexp "^SQL> " |
| 429 | :prompt-length 5 | 468 | :prompt-length 5 |
| 430 | :syntax-alist ((?@ . "w")) | 469 | :syntax-alist ((?@ . "w")) |
| @@ -463,7 +502,7 @@ may be any one of the following: | |||
| 463 | database and server) needed to connect to | 502 | database and server) needed to connect to |
| 464 | the database. | 503 | the database. |
| 465 | 504 | ||
| 466 | :sqli-connect-func name of a function which accepts no | 505 | :sqli-comint-func name of a function which accepts no |
| 467 | parameters that will use the values of | 506 | parameters that will use the values of |
| 468 | `sql-user', `sql-password', | 507 | `sql-user', `sql-password', |
| 469 | `sql-database' and `sql-server' to open a | 508 | `sql-database' and `sql-server' to open a |
| @@ -477,6 +516,10 @@ may be any one of the following: | |||
| 477 | 516 | ||
| 478 | :prompt-length length of the prompt on the line. | 517 | :prompt-length length of the prompt on the line. |
| 479 | 518 | ||
| 519 | :prompt-cont-regexp regular expression string that matches | ||
| 520 | the continuation prompt issued by the | ||
| 521 | product interpreter. | ||
| 522 | |||
| 480 | :input-filter function which can filter strings sent to | 523 | :input-filter function which can filter strings sent to |
| 481 | the command interpreter. It is also used | 524 | the command interpreter. It is also used |
| 482 | by the `sql-send-string', | 525 | by the `sql-send-string', |
| @@ -484,7 +527,8 @@ may be any one of the following: | |||
| 484 | and `sql-send-buffer' functions. The | 527 | and `sql-send-buffer' functions. The |
| 485 | function is passed the string sent to the | 528 | function is passed the string sent to the |
| 486 | command interpreter and must return the | 529 | command interpreter and must return the |
| 487 | filtered string. | 530 | filtered string. May also be a list of |
| 531 | such functions. | ||
| 488 | 532 | ||
| 489 | :terminator the terminator to be sent after a | 533 | :terminator the terminator to be sent after a |
| 490 | `sql-send-string', `sql-send-region', | 534 | `sql-send-string', `sql-send-region', |
| @@ -508,6 +552,55 @@ settings.") | |||
| 508 | '(:font-lock :sqli-program :sqli-options :sqli-login)) | 552 | '(:font-lock :sqli-program :sqli-options :sqli-login)) |
| 509 | 553 | ||
| 510 | ;;;###autoload | 554 | ;;;###autoload |
| 555 | (defcustom sql-connection-alist nil | ||
| 556 | "An alist of connection parameters for interacting with a SQL | ||
| 557 | product. | ||
| 558 | |||
| 559 | Each element of the alist is as follows: | ||
| 560 | |||
| 561 | \(CONNECTION \(SQL-VARIABLE VALUE) ...) | ||
| 562 | |||
| 563 | Where CONNECTION is a symbol identifying the connection, SQL-VARIABLE | ||
| 564 | is the symbol name of a SQL mode variable, and VALUE is the value to | ||
| 565 | be assigned to the variable. | ||
| 566 | |||
| 567 | The most common SQL-VARIABLE settings associated with a connection | ||
| 568 | are: | ||
| 569 | |||
| 570 | `sql-product' | ||
| 571 | `sql-user' | ||
| 572 | `sql-password' | ||
| 573 | `sql-port' | ||
| 574 | `sql-server' | ||
| 575 | `sql-database' | ||
| 576 | |||
| 577 | If a SQL-VARIABLE is part of the connection, it will not be | ||
| 578 | prompted for during login." | ||
| 579 | |||
| 580 | :type `(alist :key-type (string :tag "Connection") | ||
| 581 | :value-type | ||
| 582 | (set | ||
| 583 | (group (const :tag "Product" sql-product) | ||
| 584 | (choice | ||
| 585 | ,@(mapcar (lambda (prod-info) | ||
| 586 | `(const :tag | ||
| 587 | ,(or (plist-get (cdr prod-info) :name) | ||
| 588 | (capitalize (symbol-name (car prod-info)))) | ||
| 589 | (quote ,(car prod-info)))) | ||
| 590 | sql-product-alist))) | ||
| 591 | (group (const :tag "Username" sql-user) string) | ||
| 592 | (group (const :tag "Password" sql-password) string) | ||
| 593 | (group (const :tag "Server" sql-server) string) | ||
| 594 | (group (const :tag "Database" sql-database) string) | ||
| 595 | (group (const :tag "Port" sql-port) integer) | ||
| 596 | (repeat :inline t | ||
| 597 | (list :tab "Other" | ||
| 598 | (symbol :tag " Variable Symbol") | ||
| 599 | (sexp :tag "Value Expression"))))) | ||
| 600 | :version "24.1" | ||
| 601 | :group 'SQL) | ||
| 602 | |||
| 603 | ;;;###autoload | ||
| 511 | (defcustom sql-product 'ansi | 604 | (defcustom sql-product 'ansi |
| 512 | "Select the SQL database product used so that buffers can be | 605 | "Select the SQL database product used so that buffers can be |
| 513 | highlighted properly when you open them." | 606 | highlighted properly when you open them." |
| @@ -518,11 +611,8 @@ highlighted properly when you open them." | |||
| 518 | (capitalize (symbol-name (car prod-info)))) | 611 | (capitalize (symbol-name (car prod-info)))) |
| 519 | ,(car prod-info))) | 612 | ,(car prod-info))) |
| 520 | sql-product-alist)) | 613 | sql-product-alist)) |
| 521 | :group 'SQL) | 614 | :group 'SQL |
| 522 | (put 'sql-product 'safe-local-variable 'symbolp) | 615 | :safe 'symbolp) |
| 523 | |||
| 524 | (defvar sql-interactive-product nil | ||
| 525 | "Product under `sql-interactive-mode'.") | ||
| 526 | 616 | ||
| 527 | ;; misc customization of sql.el behaviour | 617 | ;; misc customization of sql.el behaviour |
| 528 | 618 | ||
| @@ -677,11 +767,7 @@ You will find the file in your Orant\\bin directory." | |||
| 677 | 767 | ||
| 678 | (defcustom sql-oracle-login-params '(user password database) | 768 | (defcustom sql-oracle-login-params '(user password database) |
| 679 | "List of login parameters needed to connect to Oracle." | 769 | "List of login parameters needed to connect to Oracle." |
| 680 | :type '(repeat (choice | 770 | :type 'sql-login-params |
| 681 | (const user) | ||
| 682 | (const password) | ||
| 683 | (const server) | ||
| 684 | (const database))) | ||
| 685 | :version "24.1" | 771 | :version "24.1" |
| 686 | :group 'SQL) | 772 | :group 'SQL) |
| 687 | 773 | ||
| @@ -702,7 +788,7 @@ to be safe: | |||
| 702 | 788 | ||
| 703 | ;; Customization for SQLite | 789 | ;; Customization for SQLite |
| 704 | 790 | ||
| 705 | (defcustom sql-sqlite-program "sqlite" | 791 | (defcustom sql-sqlite-program "sqlite3" |
| 706 | "Command to start SQLite. | 792 | "Command to start SQLite. |
| 707 | 793 | ||
| 708 | Starts `sql-interactive-mode' after doing some setup." | 794 | Starts `sql-interactive-mode' after doing some setup." |
| @@ -715,13 +801,9 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 715 | :version "20.8" | 801 | :version "20.8" |
| 716 | :group 'SQL) | 802 | :group 'SQL) |
| 717 | 803 | ||
| 718 | (defcustom sql-sqlite-login-params '(database) | 804 | (defcustom sql-sqlite-login-params '((database :file ".*\\.db")) |
| 719 | "List of login parameters needed to connect to SQLite." | 805 | "List of login parameters needed to connect to SQLite." |
| 720 | :type '(repeat (choice | 806 | :type 'sql-login-params |
| 721 | (const user) | ||
| 722 | (const password) | ||
| 723 | (const server) | ||
| 724 | (const database))) | ||
| 725 | :version "24.1" | 807 | :version "24.1" |
| 726 | :group 'SQL) | 808 | :group 'SQL) |
| 727 | 809 | ||
| @@ -744,12 +826,7 @@ on Windows: \"-C\" \"-t\" \"-f\" \"-n\"." | |||
| 744 | 826 | ||
| 745 | (defcustom sql-mysql-login-params '(user password database server) | 827 | (defcustom sql-mysql-login-params '(user password database server) |
| 746 | "List of login parameters needed to connect to MySql." | 828 | "List of login parameters needed to connect to MySql." |
| 747 | :type '(repeat (choice | 829 | :type 'sql-login-params |
| 748 | (const user) | ||
| 749 | (const password) | ||
| 750 | (const server) | ||
| 751 | (const database) | ||
| 752 | (const port))) | ||
| 753 | :version "24.1" | 830 | :version "24.1" |
| 754 | :group 'SQL) | 831 | :group 'SQL) |
| 755 | 832 | ||
| @@ -764,11 +841,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 764 | 841 | ||
| 765 | (defcustom sql-solid-login-params '(user password server) | 842 | (defcustom sql-solid-login-params '(user password server) |
| 766 | "List of login parameters needed to connect to Solid." | 843 | "List of login parameters needed to connect to Solid." |
| 767 | :type '(repeat (choice | 844 | :type 'sql-login-params |
| 768 | (const user) | ||
| 769 | (const password) | ||
| 770 | (const server) | ||
| 771 | (const database))) | ||
| 772 | :version "24.1" | 845 | :version "24.1" |
| 773 | :group 'SQL) | 846 | :group 'SQL) |
| 774 | 847 | ||
| @@ -790,11 +863,7 @@ Some versions of isql might require the -n option in order to work." | |||
| 790 | 863 | ||
| 791 | (defcustom sql-sybase-login-params '(server user password database) | 864 | (defcustom sql-sybase-login-params '(server user password database) |
| 792 | "List of login parameters needed to connect to Sybase." | 865 | "List of login parameters needed to connect to Sybase." |
| 793 | :type '(repeat (choice | 866 | :type 'sql-login-params |
| 794 | (const user) | ||
| 795 | (const password) | ||
| 796 | (const server) | ||
| 797 | (const database))) | ||
| 798 | :version "24.1" | 867 | :version "24.1" |
| 799 | :group 'SQL) | 868 | :group 'SQL) |
| 800 | 869 | ||
| @@ -809,11 +878,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 809 | 878 | ||
| 810 | (defcustom sql-informix-login-params '(database) | 879 | (defcustom sql-informix-login-params '(database) |
| 811 | "List of login parameters needed to connect to Informix." | 880 | "List of login parameters needed to connect to Informix." |
| 812 | :type '(repeat (choice | 881 | :type 'sql-login-params |
| 813 | (const user) | ||
| 814 | (const password) | ||
| 815 | (const server) | ||
| 816 | (const database))) | ||
| 817 | :version "24.1" | 882 | :version "24.1" |
| 818 | :group 'SQL) | 883 | :group 'SQL) |
| 819 | 884 | ||
| @@ -828,11 +893,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 828 | 893 | ||
| 829 | (defcustom sql-ingres-login-params '(database) | 894 | (defcustom sql-ingres-login-params '(database) |
| 830 | "List of login parameters needed to connect to Ingres." | 895 | "List of login parameters needed to connect to Ingres." |
| 831 | :type '(repeat (choice | 896 | :type 'sql-login-params |
| 832 | (const user) | ||
| 833 | (const password) | ||
| 834 | (const server) | ||
| 835 | (const database))) | ||
| 836 | :version "24.1" | 897 | :version "24.1" |
| 837 | :group 'SQL) | 898 | :group 'SQL) |
| 838 | 899 | ||
| @@ -854,11 +915,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 854 | 915 | ||
| 855 | (defcustom sql-ms-login-params '(user password server database) | 916 | (defcustom sql-ms-login-params '(user password server database) |
| 856 | "List of login parameters needed to connect to Microsoft." | 917 | "List of login parameters needed to connect to Microsoft." |
| 857 | :type '(repeat (choice | 918 | :type 'sql-login-params |
| 858 | (const user) | ||
| 859 | (const password) | ||
| 860 | (const server) | ||
| 861 | (const database))) | ||
| 862 | :version "24.1" | 919 | :version "24.1" |
| 863 | :group 'SQL) | 920 | :group 'SQL) |
| 864 | 921 | ||
| @@ -885,11 +942,7 @@ add your name with a \"-U\" prefix (such as \"-Umark\") to the list." | |||
| 885 | 942 | ||
| 886 | (defcustom sql-postgres-login-params '(user database server) | 943 | (defcustom sql-postgres-login-params '(user database server) |
| 887 | "List of login parameters needed to connect to Postgres." | 944 | "List of login parameters needed to connect to Postgres." |
| 888 | :type '(repeat (choice | 945 | :type 'sql-login-params |
| 889 | (const user) | ||
| 890 | (const password) | ||
| 891 | (const server) | ||
| 892 | (const database))) | ||
| 893 | :version "24.1" | 946 | :version "24.1" |
| 894 | :group 'SQL) | 947 | :group 'SQL) |
| 895 | 948 | ||
| @@ -910,11 +963,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 910 | 963 | ||
| 911 | (defcustom sql-interbase-login-params '(user password database) | 964 | (defcustom sql-interbase-login-params '(user password database) |
| 912 | "List of login parameters needed to connect to Interbase." | 965 | "List of login parameters needed to connect to Interbase." |
| 913 | :type '(repeat (choice | 966 | :type 'sql-login-params |
| 914 | (const user) | ||
| 915 | (const password) | ||
| 916 | (const server) | ||
| 917 | (const database))) | ||
| 918 | :version "24.1" | 967 | :version "24.1" |
| 919 | :group 'SQL) | 968 | :group 'SQL) |
| 920 | 969 | ||
| @@ -935,11 +984,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 935 | 984 | ||
| 936 | (defcustom sql-db2-login-params nil | 985 | (defcustom sql-db2-login-params nil |
| 937 | "List of login parameters needed to connect to DB2." | 986 | "List of login parameters needed to connect to DB2." |
| 938 | :type '(repeat (choice | 987 | :type 'sql-login-params |
| 939 | (const user) | ||
| 940 | (const password) | ||
| 941 | (const server) | ||
| 942 | (const database))) | ||
| 943 | :version "24.1" | 988 | :version "24.1" |
| 944 | :group 'SQL) | 989 | :group 'SQL) |
| 945 | 990 | ||
| @@ -960,11 +1005,7 @@ Starts `sql-interactive-mode' after doing some setup." | |||
| 960 | 1005 | ||
| 961 | (defcustom sql-linter-login-params '(user password database server) | 1006 | (defcustom sql-linter-login-params '(user password database server) |
| 962 | "Login parameters to needed to connect to Linter." | 1007 | "Login parameters to needed to connect to Linter." |
| 963 | :type '(repeat (choice | 1008 | :type 'sql-login-params |
| 964 | (const user) | ||
| 965 | (const password) | ||
| 966 | (const server) | ||
| 967 | (const database))) | ||
| 968 | :version "24.1" | 1009 | :version "24.1" |
| 969 | :group 'SQL) | 1010 | :group 'SQL) |
| 970 | 1011 | ||
| @@ -1005,6 +1046,9 @@ You can change `sql-prompt-regexp' on `sql-interactive-mode-hook'.") | |||
| 1005 | 1046 | ||
| 1006 | You can change `sql-prompt-length' on `sql-interactive-mode-hook'.") | 1047 | You can change `sql-prompt-length' on `sql-interactive-mode-hook'.") |
| 1007 | 1048 | ||
| 1049 | (defvar sql-prompt-cont-regexp nil | ||
| 1050 | "Prompt pattern of statement continuation prompts.") | ||
| 1051 | |||
| 1008 | (defvar sql-alternate-buffer-name nil | 1052 | (defvar sql-alternate-buffer-name nil |
| 1009 | "Buffer-local string used to possibly rename the SQLi buffer. | 1053 | "Buffer-local string used to possibly rename the SQLi buffer. |
| 1010 | 1054 | ||
| @@ -1056,8 +1100,17 @@ Based on `comint-mode-map'.") | |||
| 1056 | (get-buffer-process sql-buffer))] | 1100 | (get-buffer-process sql-buffer))] |
| 1057 | ["Send String" sql-send-string (and (buffer-live-p sql-buffer) | 1101 | ["Send String" sql-send-string (and (buffer-live-p sql-buffer) |
| 1058 | (get-buffer-process sql-buffer))] | 1102 | (get-buffer-process sql-buffer))] |
| 1059 | ["--" nil nil] | 1103 | "--" |
| 1060 | ["Start SQLi session" sql-product-interactive (sql-get-product-feature sql-product :sqli-connect-func)] | 1104 | ["Start SQLi session" sql-product-interactive |
| 1105 | :visible (not sql-connection-alist) | ||
| 1106 | :enable (sql-get-product-feature sql-product :sqli-comint-func)] | ||
| 1107 | ("Start..." | ||
| 1108 | :visible sql-connection-alist | ||
| 1109 | :filter sql-connection-menu-filter | ||
| 1110 | "--" | ||
| 1111 | ["New SQLi Session" sql-product-interactive (sql-get-product-feature sql-product :sqli-comint-func)]) | ||
| 1112 | ["--" | ||
| 1113 | :visible sql-connection-alist] | ||
| 1061 | ["Show SQLi buffer" sql-show-sqli-buffer t] | 1114 | ["Show SQLi buffer" sql-show-sqli-buffer t] |
| 1062 | ["Set SQLi buffer" sql-set-sqli-buffer t] | 1115 | ["Set SQLi buffer" sql-set-sqli-buffer t] |
| 1063 | ["Pop to SQLi buffer after send" | 1116 | ["Pop to SQLi buffer after send" |
| @@ -1085,7 +1138,8 @@ Based on `comint-mode-map'.") | |||
| 1085 | sql-interactive-mode-menu sql-interactive-mode-map | 1138 | sql-interactive-mode-menu sql-interactive-mode-map |
| 1086 | "Menu for `sql-interactive-mode'." | 1139 | "Menu for `sql-interactive-mode'." |
| 1087 | '("SQL" | 1140 | '("SQL" |
| 1088 | ["Rename Buffer" sql-rename-buffer t])) | 1141 | ["Rename Buffer" sql-rename-buffer t] |
| 1142 | ["Save Connection" sql-save-connection (not sql-connection)])) | ||
| 1089 | 1143 | ||
| 1090 | ;; Abbreviations -- if you want more of them, define them in your | 1144 | ;; Abbreviations -- if you want more of them, define them in your |
| 1091 | ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. | 1145 | ;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. |
| @@ -1922,7 +1976,51 @@ regular expressions are created during compilation by calling the | |||
| 1922 | function `regexp-opt'. Therefore, take a look at the source before | 1976 | function `regexp-opt'. Therefore, take a look at the source before |
| 1923 | you define your own `sql-mode-mysql-font-lock-keywords'.") | 1977 | you define your own `sql-mode-mysql-font-lock-keywords'.") |
| 1924 | 1978 | ||
| 1925 | (defvar sql-mode-sqlite-font-lock-keywords nil | 1979 | (defvar sql-mode-sqlite-font-lock-keywords |
| 1980 | (eval-when-compile | ||
| 1981 | (list | ||
| 1982 | ;; SQLite Keyword | ||
| 1983 | (sql-font-lock-keywords-builder 'font-lock-keyword-face nil | ||
| 1984 | "abort" "action" "add" "after" "all" "alter" "analyze" "and" "as" | ||
| 1985 | "asc" "attach" "autoincrement" "before" "begin" "between" "by" | ||
| 1986 | "cascade" "case" "cast" "check" "collate" "column" "commit" "conflict" | ||
| 1987 | "constraint" "create" "cross" "database" "default" "deferrable" | ||
| 1988 | "deferred" "delete" "desc" "detach" "distinct" "drop" "each" "else" | ||
| 1989 | "end" "escape" "except" "exclusive" "exists" "explain" "fail" "for" | ||
| 1990 | "foreign" "from" "full" "glob" "group" "having" "if" "ignore" | ||
| 1991 | "immediate" "in" "index" "indexed" "initially" "inner" "insert" | ||
| 1992 | "instead" "intersect" "into" "is" "isnull" "join" "key" "left" "like" | ||
| 1993 | "limit" "match" "natural" "no" "not" "notnull" "null" "of" "offset" | ||
| 1994 | "on" "or" "order" "outer" "plan" "pragma" "primary" "query" "raise" | ||
| 1995 | "references" "regexp" "reindex" "release" "rename" "replace" | ||
| 1996 | "restrict" "right" "rollback" "row" "savepoint" "select" "set" "table" | ||
| 1997 | "temp" "temporary" "then" "to" "transaction" "trigger" "union" | ||
| 1998 | "unique" "update" "using" "vacuum" "values" "view" "virtual" "when" | ||
| 1999 | "where" | ||
| 2000 | ) | ||
| 2001 | ;; SQLite Data types | ||
| 2002 | (sql-font-lock-keywords-builder 'font-lock-type-face nil | ||
| 2003 | "int" "integer" "tinyint" "smallint" "mediumint" "bigint" "unsigned" | ||
| 2004 | "big" "int2" "int8" "character" "varchar" "varying" "nchar" "native" | ||
| 2005 | "nvarchar" "text" "clob" "blob" "real" "double" "precision" "float" | ||
| 2006 | "numeric" "number" "decimal" "boolean" "date" "datetime" | ||
| 2007 | ) | ||
| 2008 | ;; SQLite Functions | ||
| 2009 | (sql-font-lock-keywords-builder 'font-lock-builtin-face nil | ||
| 2010 | ;; Core functions | ||
| 2011 | "abs" "changes" "coalesce" "glob" "ifnull" "hex" "last_insert_rowid" | ||
| 2012 | "length" "like" "load_extension" "lower" "ltrim" "max" "min" "nullif" | ||
| 2013 | "quote" "random" "randomblob" "replace" "round" "rtrim" "soundex" | ||
| 2014 | "sqlite_compileoption_get" "sqlite_compileoption_used" | ||
| 2015 | "sqlite_source_id" "sqlite_version" "substr" "total_changes" "trim" | ||
| 2016 | "typeof" "upper" "zeroblob" | ||
| 2017 | ;; Date/time functions | ||
| 2018 | "time" "julianday" "strftime" | ||
| 2019 | "current_date" "current_time" "current_timestamp" | ||
| 2020 | ;; Aggregate functions | ||
| 2021 | "avg" "count" "group_concat" "max" "min" "sum" "total" | ||
| 2022 | ))) | ||
| 2023 | |||
| 1926 | "SQLite SQL keywords used by font-lock. | 2024 | "SQLite SQL keywords used by font-lock. |
| 1927 | 2025 | ||
| 1928 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 2026 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1969,7 +2067,7 @@ configuration." | |||
| 1969 | ;; Each product is represented by a radio | 2067 | ;; Each product is represented by a radio |
| 1970 | ;; button with it's display name. | 2068 | ;; button with it's display name. |
| 1971 | `[,display | 2069 | `[,display |
| 1972 | (lambda () (interactive) (sql-set-product ',product)) | 2070 | (sql-set-product ',product) |
| 1973 | :style radio | 2071 | :style radio |
| 1974 | :selected (eq sql-product ',product)] | 2072 | :selected (eq sql-product ',product)] |
| 1975 | ;; Maintain the product list in | 2073 | ;; Maintain the product list in |
| @@ -2016,13 +2114,17 @@ argument must be a plist keyword accepted by | |||
| 2016 | (setcdr p (plist-put (cdr p) feature newvalue))) | 2114 | (setcdr p (plist-put (cdr p) feature newvalue))) |
| 2017 | (message "`%s' is not a known product; use `sql-add-product' to add it first." product)))) | 2115 | (message "`%s' is not a known product; use `sql-add-product' to add it first." product)))) |
| 2018 | 2116 | ||
| 2019 | (defun sql-get-product-feature (product feature &optional fallback) | 2117 | (defun sql-get-product-feature (product feature &optional fallback not-indirect) |
| 2020 | "Lookup FEATURE associated with a SQL PRODUCT. | 2118 | "Lookup FEATURE associated with a SQL PRODUCT. |
| 2021 | 2119 | ||
| 2022 | If the FEATURE is nil for PRODUCT, and FALLBACK is specified, | 2120 | If the FEATURE is nil for PRODUCT, and FALLBACK is specified, |
| 2023 | then the FEATURE associated with the FALLBACK product is | 2121 | then the FEATURE associated with the FALLBACK product is |
| 2024 | returned. | 2122 | returned. |
| 2025 | 2123 | ||
| 2124 | If the FEATURE is in the list `sql-indirect-features', and the | ||
| 2125 | NOT-INDIRECT parameter is not set, then the value of the symbol | ||
| 2126 | stored in the connect alist is returned. | ||
| 2127 | |||
| 2026 | See `sql-product-alist' for a list of products and supported features." | 2128 | See `sql-product-alist' for a list of products and supported features." |
| 2027 | (let* ((p (assoc product sql-product-alist)) | 2129 | (let* ((p (assoc product sql-product-alist)) |
| 2028 | (v (plist-get (cdr p) feature))) | 2130 | (v (plist-get (cdr p) feature))) |
| @@ -2036,10 +2138,12 @@ See `sql-product-alist' for a list of products and supported features." | |||
| 2036 | 2138 | ||
| 2037 | (if (and | 2139 | (if (and |
| 2038 | (member feature sql-indirect-features) | 2140 | (member feature sql-indirect-features) |
| 2141 | (not not-indirect) | ||
| 2039 | (symbolp v)) | 2142 | (symbolp v)) |
| 2040 | (symbol-value v) | 2143 | (symbol-value v) |
| 2041 | v)) | 2144 | v)) |
| 2042 | (message "`%s' is not a known product; use `sql-add-product' to add it first." product)))) | 2145 | (message "`%s' is not a known product; use `sql-add-product' to add it first." product) |
| 2146 | nil))) | ||
| 2043 | 2147 | ||
| 2044 | (defun sql-product-font-lock (keywords-only imenu) | 2148 | (defun sql-product-font-lock (keywords-only imenu) |
| 2045 | "Configure font-lock and imenu with product-specific settings. | 2149 | "Configure font-lock and imenu with product-specific settings. |
| @@ -2126,6 +2230,19 @@ adds a fontification pattern to fontify identifiers ending in | |||
| 2126 | (append old-val keywords) | 2230 | (append old-val keywords) |
| 2127 | (append keywords old-val)))))) | 2231 | (append keywords old-val)))))) |
| 2128 | 2232 | ||
| 2233 | (defun sql-for-each-login (login-params body) | ||
| 2234 | "Iterates through login parameters and returns a list of results." | ||
| 2235 | |||
| 2236 | (delq nil | ||
| 2237 | (mapcar | ||
| 2238 | (lambda (param) | ||
| 2239 | (let ((token (or (and (listp param) (car param)) param)) | ||
| 2240 | (type (or (and (listp param) (nth 1 param)) nil)) | ||
| 2241 | (arg (or (and (listp param) (nth 2 param)) nil))) | ||
| 2242 | |||
| 2243 | (funcall body token type arg))) | ||
| 2244 | login-params))) | ||
| 2245 | |||
| 2129 | 2246 | ||
| 2130 | 2247 | ||
| 2131 | ;;; Functions to switch highlighting | 2248 | ;;; Functions to switch highlighting |
| @@ -2287,6 +2404,38 @@ appended to the SQLi buffer without disturbing your SQL buffer." | |||
| 2287 | "Read a password using PROMPT. Optional DEFAULT is password to start with." | 2404 | "Read a password using PROMPT. Optional DEFAULT is password to start with." |
| 2288 | (read-passwd prompt nil default)) | 2405 | (read-passwd prompt nil default)) |
| 2289 | 2406 | ||
| 2407 | (defun sql-get-login-ext (prompt last-value history-var type arg) | ||
| 2408 | "Prompt user with extended login parameters. | ||
| 2409 | |||
| 2410 | If TYPE is nil, then the user is simply prompted for a string | ||
| 2411 | value. | ||
| 2412 | |||
| 2413 | If TYPE is `:file', then the user is prompted for a file | ||
| 2414 | name that must match the regexp pattern specified in the ARG | ||
| 2415 | argument. | ||
| 2416 | |||
| 2417 | If TYPE is `:completion', then the user is prompted for a string | ||
| 2418 | specified by ARG. (ARG is used as the PREDICATE argument to | ||
| 2419 | `completing-read'.)" | ||
| 2420 | (cond | ||
| 2421 | ((eq type nil) | ||
| 2422 | (read-from-minibuffer prompt last-value nil nil history-var)) | ||
| 2423 | |||
| 2424 | ((eq type :file) | ||
| 2425 | (let ((use-dialog-box nil)) | ||
| 2426 | (expand-file-name | ||
| 2427 | (read-file-name prompt | ||
| 2428 | (file-name-directory last-value) nil t | ||
| 2429 | (file-name-nondirectory last-value) | ||
| 2430 | (if arg | ||
| 2431 | `(lambda (f) | ||
| 2432 | (string-match (concat "\\<" ,arg "\\>") | ||
| 2433 | (file-name-nondirectory f))) | ||
| 2434 | nil))))) | ||
| 2435 | |||
| 2436 | ((eq type :completion) | ||
| 2437 | (completing-read prompt arg nil t last-value history-var)))) | ||
| 2438 | |||
| 2290 | (defun sql-get-login (&rest what) | 2439 | (defun sql-get-login (&rest what) |
| 2291 | "Get username, password and database from the user. | 2440 | "Get username, password and database from the user. |
| 2292 | 2441 | ||
| @@ -2304,32 +2453,48 @@ symbol `password', for the server if it contains the symbol | |||
| 2304 | `database'. The members of WHAT are processed in the order in | 2453 | `database'. The members of WHAT are processed in the order in |
| 2305 | which they are provided. | 2454 | which they are provided. |
| 2306 | 2455 | ||
| 2456 | The tokens for `database' and `server' may also be lists to | ||
| 2457 | control or limit the values that can be supplied. These can be | ||
| 2458 | of the form: | ||
| 2459 | |||
| 2460 | \(database :file \".+\\\\.EXT\") | ||
| 2461 | \(database :completion FUNCTION) | ||
| 2462 | |||
| 2463 | The `server' token supports the same forms. | ||
| 2464 | |||
| 2307 | In order to ask the user for username, password and database, call the | 2465 | In order to ask the user for username, password and database, call the |
| 2308 | function like this: (sql-get-login 'user 'password 'database)." | 2466 | function like this: (sql-get-login 'user 'password 'database)." |
| 2309 | (interactive) | 2467 | (interactive) |
| 2310 | (while what | 2468 | (mapcar |
| 2311 | (cond | 2469 | (lambda (w) |
| 2312 | ((eq (car what) 'user) ; user | 2470 | (let ((token (or (and (listp w) (car w)) w)) |
| 2313 | (setq sql-user | 2471 | (type (or (and (listp w) (nth 1 w)) nil)) |
| 2314 | (read-from-minibuffer "User: " sql-user nil nil | 2472 | (arg (or (and (listp w) (nth 2 w)) nil))) |
| 2315 | 'sql-user-history))) | 2473 | |
| 2316 | ((eq (car what) 'password) ; password | 2474 | (cond |
| 2317 | (setq sql-password | 2475 | ((eq token 'user) ; user |
| 2318 | (sql-read-passwd "Password: " sql-password))) | 2476 | (setq sql-user |
| 2319 | 2477 | (read-from-minibuffer "User: " sql-user nil nil | |
| 2320 | ((eq (car what) 'server) ; server | 2478 | 'sql-user-history))) |
| 2321 | (setq sql-server | 2479 | |
| 2322 | (read-from-minibuffer "Server: " sql-server nil nil | 2480 | ((eq token 'password) ; password |
| 2323 | 'sql-server-history))) | 2481 | (setq sql-password |
| 2324 | ((eq (car what) 'port) ; port | 2482 | (sql-read-passwd "Password: " sql-password))) |
| 2325 | (setq sql-port | 2483 | |
| 2326 | (read-from-minibuffer "Port: " sql-port nil nil | 2484 | ((eq token 'server) ; server |
| 2327 | 'sql-port-history))) | 2485 | (setq sql-server |
| 2328 | ((eq (car what) 'database) ; database | 2486 | (sql-get-login-ext "Server: " sql-server |
| 2329 | (setq sql-database | 2487 | 'sql-server-history type arg))) |
| 2330 | (read-from-minibuffer "Database: " sql-database nil nil | 2488 | |
| 2331 | 'sql-database-history)))) | 2489 | ((eq token 'database) ; database |
| 2332 | (setq what (cdr what)))) | 2490 | (setq sql-database |
| 2491 | (sql-get-login-ext "Database: " sql-database | ||
| 2492 | 'sql-database-history type arg))) | ||
| 2493 | |||
| 2494 | ((eq token 'port) ; port | ||
| 2495 | (setq sql-port | ||
| 2496 | (read-number "Port: " sql-port)))))) | ||
| 2497 | what)) | ||
| 2333 | 2498 | ||
| 2334 | (defun sql-find-sqli-buffer () | 2499 | (defun sql-find-sqli-buffer () |
| 2335 | "Returns the current default SQLi buffer or nil. | 2500 | "Returns the current default SQLi buffer or nil. |
| @@ -2419,17 +2584,70 @@ variable `sql-buffer'. See `sql-help' on how to create such a buffer." | |||
| 2419 | "Return a string that can be used to rename a SQLi buffer. | 2584 | "Return a string that can be used to rename a SQLi buffer. |
| 2420 | 2585 | ||
| 2421 | This is used to set `sql-alternate-buffer-name' within | 2586 | This is used to set `sql-alternate-buffer-name' within |
| 2422 | `sql-interactive-mode'." | 2587 | `sql-interactive-mode'. |
| 2423 | (concat (if (string= "" sql-user) | 2588 | |
| 2424 | (if (string= "" (user-login-name)) | 2589 | If the session was started with `sql-connect' then the alternate |
| 2425 | () | 2590 | name would be the name of the connection. |
| 2426 | (concat (user-login-name) "/")) | 2591 | |
| 2427 | (concat sql-user "/")) | 2592 | Otherwise, it uses the parameters identified by the :sqlilogin |
| 2428 | (if (string= "" sql-database) | 2593 | parameter. |
| 2429 | (if (string= "" sql-server) | 2594 | |
| 2430 | (system-name) | 2595 | If all else fails, the alternate name would be the user and |
| 2431 | sql-server) | 2596 | server/database name." |
| 2432 | sql-database))) | 2597 | |
| 2598 | (let ((name "")) | ||
| 2599 | |||
| 2600 | ;; Build a name using the :sqli-login setting | ||
| 2601 | (setq name | ||
| 2602 | (apply 'concat | ||
| 2603 | (cdr | ||
| 2604 | (apply 'append nil | ||
| 2605 | (sql-for-each-login | ||
| 2606 | (sql-get-product-feature sql-product :sqli-login) | ||
| 2607 | (lambda (token type arg) | ||
| 2608 | (cond | ||
| 2609 | ((eq token 'user) | ||
| 2610 | (unless (string= "" sql-user) | ||
| 2611 | (list "/" sql-user))) | ||
| 2612 | ((eq token 'port) | ||
| 2613 | (unless (= 0 sql-port) | ||
| 2614 | (list ":" sql-port))) | ||
| 2615 | ((eq token 'server) | ||
| 2616 | (unless (string= "" sql-server) | ||
| 2617 | (list "." | ||
| 2618 | (if (eq type :file) | ||
| 2619 | (file-name-nondirectory sql-server) | ||
| 2620 | sql-server)))) | ||
| 2621 | ((eq token 'database) | ||
| 2622 | (when (string= "" sql-database) | ||
| 2623 | (list "@" | ||
| 2624 | (if (eq type :file) | ||
| 2625 | (file-name-nondirectory sql-database) | ||
| 2626 | sql-database)))) | ||
| 2627 | |||
| 2628 | ((eq token 'password) nil) | ||
| 2629 | (t nil)))))))) | ||
| 2630 | |||
| 2631 | ;; If there's a connection, use it and the name thus far | ||
| 2632 | (if sql-connection | ||
| 2633 | (format "<%s>%s" sql-connection (or name "")) | ||
| 2634 | |||
| 2635 | ;; If there is no name, try to create something meaningful | ||
| 2636 | (if (string= "" (or name "")) | ||
| 2637 | (concat | ||
| 2638 | (if (string= "" sql-user) | ||
| 2639 | (if (string= "" (user-login-name)) | ||
| 2640 | () | ||
| 2641 | (concat (user-login-name) "/")) | ||
| 2642 | (concat sql-user "/")) | ||
| 2643 | (if (string= "" sql-database) | ||
| 2644 | (if (string= "" sql-server) | ||
| 2645 | (system-name) | ||
| 2646 | sql-server) | ||
| 2647 | sql-database)) | ||
| 2648 | |||
| 2649 | ;; Use the name we've got | ||
| 2650 | name)))) | ||
| 2433 | 2651 | ||
| 2434 | (defun sql-rename-buffer () | 2652 | (defun sql-rename-buffer () |
| 2435 | "Rename a SQLi buffer." | 2653 | "Rename a SQLi buffer." |
| @@ -2507,14 +2725,73 @@ Every newline in STRING will be preceded with a space and a backslash." | |||
| 2507 | 2725 | ||
| 2508 | ;;; Input sender for SQLi buffers | 2726 | ;;; Input sender for SQLi buffers |
| 2509 | 2727 | ||
| 2728 | (defvar sql-output-newline-count 0 | ||
| 2729 | "Number of newlines in the input string. | ||
| 2730 | |||
| 2731 | Allows the suppression of continuation prompts.") | ||
| 2732 | |||
| 2733 | (defvar sql-output-by-send nil | ||
| 2734 | "Non-nil if the command in the input was generated by `sql-send-string'.") | ||
| 2735 | |||
| 2510 | (defun sql-input-sender (proc string) | 2736 | (defun sql-input-sender (proc string) |
| 2511 | "Send STRING to PROC after applying filters." | 2737 | "Send STRING to PROC after applying filters." |
| 2512 | 2738 | ||
| 2513 | (let* ((product (with-current-buffer (process-buffer proc) sql-product)) | 2739 | (let* ((product (with-current-buffer (process-buffer proc) sql-product)) |
| 2514 | (filter (sql-get-product-feature product :input-filter))) | 2740 | (filter (sql-get-product-feature product :input-filter))) |
| 2515 | 2741 | ||
| 2742 | ;; Apply filter(s) | ||
| 2743 | (cond | ||
| 2744 | ((not filter) | ||
| 2745 | nil) | ||
| 2746 | ((functionp filter) | ||
| 2747 | (setq string (funcall filter string))) | ||
| 2748 | ((listp filter) | ||
| 2749 | (mapc (lambda (f) (setq string (funcall f string))) filter)) | ||
| 2750 | (t nil)) | ||
| 2751 | |||
| 2752 | ;; Count how many newlines in the string | ||
| 2753 | (setq sql-output-newline-count 0) | ||
| 2754 | (mapc (lambda (ch) | ||
| 2755 | (when (eq ch ?\n) | ||
| 2756 | (setq sql-output-newline-count (1+ sql-output-newline-count)))) | ||
| 2757 | string) | ||
| 2758 | |||
| 2516 | ;; Send the string | 2759 | ;; Send the string |
| 2517 | (comint-simple-send proc (if filter (funcall filter string) string)))) | 2760 | (comint-simple-send proc string))) |
| 2761 | |||
| 2762 | ;;; Strip out continuation prompts | ||
| 2763 | |||
| 2764 | (defun sql-interactive-remove-continuation-prompt (oline) | ||
| 2765 | "Strip out continuation prompts out of the OLINE. | ||
| 2766 | |||
| 2767 | Added to the `comint-preoutput-filter-functions' hook in a SQL | ||
| 2768 | interactive buffer. If `sql-outut-newline-count' is greater than | ||
| 2769 | zero, then an output line matching the continuation prompt is filtered | ||
| 2770 | out. If the count is one, then the prompt is replaced with a newline | ||
| 2771 | to force the output from the query to appear on a new line." | ||
| 2772 | (if (and sql-prompt-cont-regexp | ||
| 2773 | sql-output-newline-count | ||
| 2774 | (numberp sql-output-newline-count) | ||
| 2775 | (>= sql-output-newline-count 1)) | ||
| 2776 | (progn | ||
| 2777 | (while (and oline | ||
| 2778 | sql-output-newline-count | ||
| 2779 | (> sql-output-newline-count 0) | ||
| 2780 | (string-match sql-prompt-cont-regexp oline)) | ||
| 2781 | |||
| 2782 | (setq oline | ||
| 2783 | (replace-match (if (and | ||
| 2784 | (= 1 sql-output-newline-count) | ||
| 2785 | sql-output-by-send) | ||
| 2786 | "\n" "") | ||
| 2787 | nil nil oline) | ||
| 2788 | sql-output-newline-count | ||
| 2789 | (1- sql-output-newline-count))) | ||
| 2790 | (if (= sql-output-newline-count 0) | ||
| 2791 | (setq sql-output-newline-count nil)) | ||
| 2792 | (setq sql-output-by-send nil)) | ||
| 2793 | (setq sql-output-newline-count nil)) | ||
| 2794 | oline) | ||
| 2518 | 2795 | ||
| 2519 | ;;; Sending the region to the SQLi buffer. | 2796 | ;;; Sending the region to the SQLi buffer. |
| 2520 | 2797 | ||
| @@ -2522,26 +2799,20 @@ Every newline in STRING will be preceded with a space and a backslash." | |||
| 2522 | "Send the string STR to the SQL process." | 2799 | "Send the string STR to the SQL process." |
| 2523 | (interactive "sSQL Text: ") | 2800 | (interactive "sSQL Text: ") |
| 2524 | 2801 | ||
| 2525 | (let (comint-input-sender-no-newline proc) | 2802 | (let ((comint-input-sender-no-newline nil) |
| 2803 | (s (replace-regexp-in-string "[[:space:]\n\r]+\\'" "" str))) | ||
| 2526 | (if (buffer-live-p sql-buffer) | 2804 | (if (buffer-live-p sql-buffer) |
| 2527 | (progn | 2805 | (progn |
| 2528 | ;; Ignore the hoping around... | 2806 | ;; Ignore the hoping around... |
| 2529 | (save-excursion | 2807 | (save-excursion |
| 2530 | ;; Get the process | ||
| 2531 | (setq proc (get-buffer-process sql-buffer)) | ||
| 2532 | |||
| 2533 | ;; Set product context | 2808 | ;; Set product context |
| 2534 | (with-current-buffer sql-buffer | 2809 | (with-current-buffer sql-buffer |
| 2535 | ;; Send the string | 2810 | ;; Send the string (trim the trailing whitespace) |
| 2536 | (sql-input-sender proc str) | 2811 | (sql-input-sender (get-buffer-process sql-buffer) s) |
| 2537 | |||
| 2538 | ;; Send a newline if there wasn't one on the end of the string | ||
| 2539 | (unless (string-equal "\n" (substring str (1- (length str)))) | ||
| 2540 | (comint-send-string proc "\n")) | ||
| 2541 | 2812 | ||
| 2542 | ;; Send a command terminator if we must | 2813 | ;; Send a command terminator if we must |
| 2543 | (if sql-send-terminator | 2814 | (if sql-send-terminator |
| 2544 | (sql-send-magic-terminator sql-buffer str sql-send-terminator)) | 2815 | (sql-send-magic-terminator sql-buffer s sql-send-terminator)) |
| 2545 | 2816 | ||
| 2546 | (message "Sent string to buffer %s." (buffer-name sql-buffer)))) | 2817 | (message "Sent string to buffer %s." (buffer-name sql-buffer)))) |
| 2547 | 2818 | ||
| @@ -2576,7 +2847,7 @@ Every newline in STRING will be preceded with a space and a backslash." | |||
| 2576 | 2847 | ||
| 2577 | (defun sql-send-magic-terminator (buf str terminator) | 2848 | (defun sql-send-magic-terminator (buf str terminator) |
| 2578 | "Send TERMINATOR to buffer BUF if its not present in STR." | 2849 | "Send TERMINATOR to buffer BUF if its not present in STR." |
| 2579 | (let (pat term) | 2850 | (let (comint-input-sender-no-newline pat term) |
| 2580 | ;; If flag is merely on(t), get product-specific terminator | 2851 | ;; If flag is merely on(t), get product-specific terminator |
| 2581 | (if (eq terminator t) | 2852 | (if (eq terminator t) |
| 2582 | (setq terminator (sql-get-product-feature sql-product :terminator))) | 2853 | (setq terminator (sql-get-product-feature sql-product :terminator))) |
| @@ -2597,8 +2868,13 @@ Every newline in STRING will be preceded with a space and a backslash." | |||
| 2597 | 2868 | ||
| 2598 | ;; Check to see if the pattern is present in the str already sent | 2869 | ;; Check to see if the pattern is present in the str already sent |
| 2599 | (unless (and pat term | 2870 | (unless (and pat term |
| 2600 | (string-match (concat pat "\n?\\'") str)) | 2871 | (string-match (concat pat "\\'") str)) |
| 2601 | (comint-send-string buf (concat term "\n"))))) | 2872 | (comint-simple-send (get-buffer-process buf) term) |
| 2873 | (setq sql-output-newline-count | ||
| 2874 | (if sql-output-newline-count | ||
| 2875 | (1+ sql-output-newline-count) | ||
| 2876 | 1))) | ||
| 2877 | (setq sql-output-by-send t))) | ||
| 2602 | 2878 | ||
| 2603 | (defun sql-remove-tabs-filter (str) | 2879 | (defun sql-remove-tabs-filter (str) |
| 2604 | "Replace tab characters with spaces." | 2880 | "Replace tab characters with spaces." |
| @@ -2788,6 +3064,8 @@ you entered, right above the output it created. | |||
| 2788 | (setq abbrev-all-caps 1) | 3064 | (setq abbrev-all-caps 1) |
| 2789 | ;; Exiting the process will call sql-stop. | 3065 | ;; Exiting the process will call sql-stop. |
| 2790 | (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop) | 3066 | (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop) |
| 3067 | ;; Save the connection name | ||
| 3068 | (make-local-variable 'sql-connection) | ||
| 2791 | ;; Create a usefull name for renaming this buffer later. | 3069 | ;; Create a usefull name for renaming this buffer later. |
| 2792 | (make-local-variable 'sql-alternate-buffer-name) | 3070 | (make-local-variable 'sql-alternate-buffer-name) |
| 2793 | (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name)) | 3071 | (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name)) |
| @@ -2796,13 +3074,22 @@ you entered, right above the output it created. | |||
| 2796 | (sql-get-product-feature sql-product :prompt-regexp)) | 3074 | (sql-get-product-feature sql-product :prompt-regexp)) |
| 2797 | (set (make-local-variable 'sql-prompt-length) | 3075 | (set (make-local-variable 'sql-prompt-length) |
| 2798 | (sql-get-product-feature sql-product :prompt-length)) | 3076 | (sql-get-product-feature sql-product :prompt-length)) |
| 3077 | (set (make-local-variable 'sql-prompt-cont-regexp) | ||
| 3078 | (sql-get-product-feature sql-product :prompt-cont-regexp)) | ||
| 3079 | (make-local-variable 'sql-output-newline-count) | ||
| 3080 | (make-local-variable 'sql-output-by-send) | ||
| 3081 | (add-hook 'comint-preoutput-filter-functions | ||
| 3082 | 'sql-interactive-remove-continuation-prompt nil t) | ||
| 2799 | (make-local-variable 'sql-input-ring-separator) | 3083 | (make-local-variable 'sql-input-ring-separator) |
| 2800 | (make-local-variable 'sql-input-ring-file-name) | 3084 | (make-local-variable 'sql-input-ring-file-name) |
| 2801 | (setq comint-process-echoes t) | ||
| 2802 | ;; Run the mode hook (along with comint's hooks). | 3085 | ;; Run the mode hook (along with comint's hooks). |
| 2803 | (run-mode-hooks 'sql-interactive-mode-hook) | 3086 | (run-mode-hooks 'sql-interactive-mode-hook) |
| 2804 | ;; Set comint based on user overrides. | 3087 | ;; Set comint based on user overrides. |
| 2805 | (setq comint-prompt-regexp sql-prompt-regexp) | 3088 | (setq comint-prompt-regexp |
| 3089 | (if sql-prompt-cont-regexp | ||
| 3090 | (concat "\\(" sql-prompt-regexp | ||
| 3091 | "\\|" sql-prompt-cont-regexp "\\)") | ||
| 3092 | sql-prompt-regexp)) | ||
| 2806 | (setq left-margin sql-prompt-length) | 3093 | (setq left-margin sql-prompt-length) |
| 2807 | ;; Install input sender | 3094 | ;; Install input sender |
| 2808 | (set (make-local-variable 'comint-input-sender) 'sql-input-sender) | 3095 | (set (make-local-variable 'comint-input-sender) 'sql-input-sender) |
| @@ -2831,6 +3118,133 @@ Sentinels will always get the two parameters PROCESS and EVENT." | |||
| 2831 | 3118 | ||
| 2832 | 3119 | ||
| 2833 | 3120 | ||
| 3121 | ;;; Connection handling | ||
| 3122 | |||
| 3123 | ;;;###autoload | ||
| 3124 | (defun sql-connect (connection) | ||
| 3125 | "Connect to an interactive session using CONNECTION settings. | ||
| 3126 | |||
| 3127 | See `sql-connection-alist' to see how to define connections and | ||
| 3128 | their settings. | ||
| 3129 | |||
| 3130 | The user will not be prompted for any login parameters if a value | ||
| 3131 | is specified in the connection settings." | ||
| 3132 | |||
| 3133 | ;; Prompt for the connection from those defined in the alist | ||
| 3134 | (interactive | ||
| 3135 | (if sql-connection-alist | ||
| 3136 | (list | ||
| 3137 | (let ((completion-ignore-case t)) | ||
| 3138 | (completing-read "Connection: " | ||
| 3139 | (mapcar (lambda (c) (car c)) | ||
| 3140 | sql-connection-alist) | ||
| 3141 | nil t nil nil '(())))) | ||
| 3142 | nil)) | ||
| 3143 | |||
| 3144 | ;; Are there connections defined | ||
| 3145 | (if sql-connection-alist | ||
| 3146 | ;; Was one selected | ||
| 3147 | (when connection | ||
| 3148 | ;; Get connection settings | ||
| 3149 | (let ((connect-set (assoc connection sql-connection-alist))) | ||
| 3150 | ;; Settings are defined | ||
| 3151 | (if connect-set | ||
| 3152 | ;; Set the desired parameters | ||
| 3153 | (eval `(let* | ||
| 3154 | (,@(cdr connect-set) | ||
| 3155 | ;; :sqli-login params variable | ||
| 3156 | (param-var (sql-get-product-feature sql-product | ||
| 3157 | :sqli-login nil t)) | ||
| 3158 | ;; :sqli-login params value | ||
| 3159 | (login-params (sql-get-product-feature sql-product | ||
| 3160 | :sqli-login)) | ||
| 3161 | ;; which params are in the connection | ||
| 3162 | (set-params (mapcar | ||
| 3163 | (lambda (v) | ||
| 3164 | (cond | ||
| 3165 | ((eq (car v) 'sql-user) 'user) | ||
| 3166 | ((eq (car v) 'sql-password) 'password) | ||
| 3167 | ((eq (car v) 'sql-server) 'server) | ||
| 3168 | ((eq (car v) 'sql-database) 'database) | ||
| 3169 | ((eq (car v) 'sql-port) 'port) | ||
| 3170 | (t (car v)))) | ||
| 3171 | (cdr connect-set))) | ||
| 3172 | ;; the remaining params (w/o the connection params) | ||
| 3173 | (rem-params (sql-for-each-login | ||
| 3174 | login-params | ||
| 3175 | (lambda (token type arg) | ||
| 3176 | (unless (member token set-params) | ||
| 3177 | (if (or type arg) | ||
| 3178 | (list token type arg) | ||
| 3179 | token))))) | ||
| 3180 | ;; Remember the connection | ||
| 3181 | (sql-connection connection)) | ||
| 3182 | |||
| 3183 | ;; Set the remaining parameters and start the | ||
| 3184 | ;; interactive session | ||
| 3185 | (eval `(let ((,param-var ',rem-params)) | ||
| 3186 | (sql-product-interactive sql-product))))) | ||
| 3187 | (message "SQL Connection <%s> does not exist" connection) | ||
| 3188 | nil))) | ||
| 3189 | (message "No SQL Connections defined") | ||
| 3190 | nil)) | ||
| 3191 | |||
| 3192 | (defun sql-save-connection (name) | ||
| 3193 | "Captures the connection information of the current SQLi session. | ||
| 3194 | |||
| 3195 | The information is appended to `sql-connection-alist' and | ||
| 3196 | optionally is saved to the user's init file." | ||
| 3197 | |||
| 3198 | (interactive "sNew connection name: ") | ||
| 3199 | |||
| 3200 | (if sql-connection | ||
| 3201 | (message "This session was started by a connection; it's already been saved.") | ||
| 3202 | |||
| 3203 | (let ((login (sql-get-product-feature sql-product :sqli-login)) | ||
| 3204 | (alist sql-connection-alist) | ||
| 3205 | connect) | ||
| 3206 | |||
| 3207 | ;; Remove the existing connection if the user says so | ||
| 3208 | (when (and (assoc name alist) | ||
| 3209 | (yes-or-no-p (format "Replace connection definition <%s>? " name))) | ||
| 3210 | (setq alist (assq-delete-all name alist))) | ||
| 3211 | |||
| 3212 | ;; Add the new connection if it doesn't exist | ||
| 3213 | (if (assoc name alist) | ||
| 3214 | (message "Connection <%s> already exists" name) | ||
| 3215 | (setq connect | ||
| 3216 | (append (list name) | ||
| 3217 | (sql-for-each-login | ||
| 3218 | `(product ,@login) | ||
| 3219 | (lambda (token type arg) | ||
| 3220 | (cond | ||
| 3221 | ((eq token 'product) `(sql-product ',sql-product)) | ||
| 3222 | ((eq token 'user) `(sql-user ,sql-user)) | ||
| 3223 | ((eq token 'database) `(sql-database ,sql-database)) | ||
| 3224 | ((eq token 'server) `(sql-server ,sql-server)) | ||
| 3225 | ((eq token 'port) `(sql-port ,sql-port))))))) | ||
| 3226 | |||
| 3227 | (setq alist (append alist (list connect))) | ||
| 3228 | |||
| 3229 | ;; confirm whether we want to save the connections | ||
| 3230 | (if (yes-or-no-p "Save the connections for future sessions? ") | ||
| 3231 | (customize-save-variable 'sql-connection-alist alist) | ||
| 3232 | (customize-set-variable 'sql-connection-alist alist)))))) | ||
| 3233 | |||
| 3234 | (defun sql-connection-menu-filter (tail) | ||
| 3235 | "Generates menu entries for using each connection." | ||
| 3236 | (append | ||
| 3237 | (mapcar | ||
| 3238 | (lambda (conn) | ||
| 3239 | (vector | ||
| 3240 | (format "Connection <%s>" (car conn)) | ||
| 3241 | (list 'sql-connect (car conn)) | ||
| 3242 | t)) | ||
| 3243 | sql-connection-alist) | ||
| 3244 | tail)) | ||
| 3245 | |||
| 3246 | |||
| 3247 | |||
| 2834 | ;;; Entry functions for different SQL interpreters. | 3248 | ;;; Entry functions for different SQL interpreters. |
| 2835 | 3249 | ||
| 2836 | ;;;###autoload | 3250 | ;;;###autoload |
| @@ -2851,66 +3265,67 @@ If buffer exists and a process is running, just switch to buffer `*SQL*'. | |||
| 2851 | sql-product-alist) | 3265 | sql-product-alist) |
| 2852 | nil 'require-match | 3266 | nil 'require-match |
| 2853 | (or (and sql-product (symbol-name sql-product)) "ansi")))) | 3267 | (or (and sql-product (symbol-name sql-product)) "ansi")))) |
| 2854 | ((symbolp product) product) ; Product specified | 3268 | ((and product ; Product specified |
| 3269 | (symbolp product)) product) | ||
| 2855 | (t sql-product))) ; Default to sql-product | 3270 | (t sql-product))) ; Default to sql-product |
| 2856 | 3271 | ||
| 2857 | (when (sql-get-product-feature product :sqli-connect-func) | 3272 | (if product |
| 2858 | (if (and sql-buffer | 3273 | (when (sql-get-product-feature product :sqli-comint-func) |
| 2859 | (buffer-live-p sql-buffer) | 3274 | (if (and sql-buffer |
| 2860 | (comint-check-proc sql-buffer)) | 3275 | (buffer-live-p sql-buffer) |
| 2861 | (pop-to-buffer sql-buffer) | 3276 | (comint-check-proc sql-buffer)) |
| 2862 | 3277 | (pop-to-buffer sql-buffer) | |
| 2863 | ;; Is the current buffer in sql-mode and | 3278 | |
| 2864 | ;; there is a buffer local setting of sql-buffer | 3279 | ;; Is the current buffer in sql-mode and |
| 2865 | (let* ((start-buffer | 3280 | ;; there is a buffer local setting of sql-buffer |
| 2866 | (and (derived-mode-p 'sql-mode) | 3281 | (let* ((start-buffer |
| 2867 | (current-buffer))) | 3282 | (and (derived-mode-p 'sql-mode) |
| 2868 | (start-sql-buffer | 3283 | (current-buffer))) |
| 2869 | (and start-buffer | 3284 | (start-sql-buffer |
| 2870 | (let (found) | 3285 | (and start-buffer |
| 2871 | (dolist (var (buffer-local-variables)) | 3286 | (let (found) |
| 2872 | (and (consp var) | 3287 | (dolist (var (buffer-local-variables)) |
| 2873 | (eq (car var) 'sql-buffer) | 3288 | (and (consp var) |
| 2874 | (buffer-live-p (cdr var)) | 3289 | (eq (car var) 'sql-buffer) |
| 2875 | (get-buffer-process (cdr var)) | 3290 | (buffer-live-p (cdr var)) |
| 2876 | (setq found (cdr var)))) | 3291 | (get-buffer-process (cdr var)) |
| 2877 | found))) | 3292 | (setq found (cdr var)))) |
| 2878 | new-sqli-buffer) | 3293 | found))) |
| 2879 | 3294 | new-sqli-buffer) | |
| 2880 | ;; Get credentials. | 3295 | |
| 2881 | (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) | 3296 | ;; Get credentials. |
| 2882 | 3297 | (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) | |
| 2883 | ;; Connect to database. | 3298 | |
| 2884 | (message "Login...") | 3299 | ;; Connect to database. |
| 2885 | (funcall (sql-get-product-feature product :sqli-connect-func) | 3300 | (message "Login...") |
| 2886 | product | 3301 | (funcall (sql-get-product-feature product :sqli-comint-func) |
| 2887 | (sql-get-product-feature product :sqli-options)) | 3302 | product |
| 2888 | 3303 | (sql-get-product-feature product :sqli-options)) | |
| 2889 | ;; Set SQLi mode. | 3304 | |
| 2890 | (setq sql-interactive-product product | 3305 | ;; Set SQLi mode. |
| 2891 | new-sqli-buffer (current-buffer) | 3306 | (setq sql-interactive-product product |
| 2892 | sql-buffer new-sqli-buffer) | 3307 | new-sqli-buffer (current-buffer) |
| 2893 | (sql-interactive-mode) | 3308 | sql-buffer new-sqli-buffer) |
| 2894 | 3309 | (sql-interactive-mode) | |
| 2895 | ;; Set `sql-buffer' in the start buffer | 3310 | |
| 2896 | (when (and start-buffer (not start-sql-buffer)) | 3311 | ;; Set `sql-buffer' in the start buffer |
| 2897 | (with-current-buffer start-buffer | 3312 | (when (and start-buffer (not start-sql-buffer)) |
| 2898 | (setq sql-buffer new-sqli-buffer))) | 3313 | (with-current-buffer start-buffer |
| 2899 | 3314 | (setq sql-buffer new-sqli-buffer))) | |
| 2900 | ;; All done. | 3315 | |
| 2901 | (message "Login...done") | 3316 | ;; All done. |
| 2902 | (pop-to-buffer sql-buffer))))) | 3317 | (message "Login...done") |
| 2903 | 3318 | (pop-to-buffer sql-buffer)))) | |
| 2904 | (defun sql-connect (product params) | 3319 | (message "No default SQL product defined. Set `sql-product'."))) |
| 2905 | "Set up a comint buffer to connect to the SQL processor. | 3320 | |
| 3321 | (defun sql-comint (product params) | ||
| 3322 | "Set up a comint buffer to run the SQL processor. | ||
| 2906 | 3323 | ||
| 2907 | PRODUCT is the SQL product. PARAMS is a list of strings which are | 3324 | PRODUCT is the SQL product. PARAMS is a list of strings which are |
| 2908 | passed as command line arguments." | 3325 | passed as command line arguments." |
| 2909 | (let ((program (sql-get-product-feature product :sqli-program))) | 3326 | (let ((program (sql-get-product-feature product :sqli-program))) |
| 2910 | (set-buffer | 3327 | (set-buffer |
| 2911 | (if params | 3328 | (apply 'make-comint "SQL" program nil params)))) |
| 2912 | (apply 'make-comint "SQL" program nil params) | ||
| 2913 | (make-comint "SQL" program nil))))) | ||
| 2914 | 3329 | ||
| 2915 | ;;;###autoload | 3330 | ;;;###autoload |
| 2916 | (defun sql-oracle () | 3331 | (defun sql-oracle () |
| @@ -2939,7 +3354,7 @@ The default comes from `process-coding-system-alist' and | |||
| 2939 | (interactive) | 3354 | (interactive) |
| 2940 | (sql-product-interactive 'oracle)) | 3355 | (sql-product-interactive 'oracle)) |
| 2941 | 3356 | ||
| 2942 | (defun sql-connect-oracle (product options) | 3357 | (defun sql-comint-oracle (product options) |
| 2943 | "Create comint buffer and connect to Oracle." | 3358 | "Create comint buffer and connect to Oracle." |
| 2944 | ;; Produce user/password@database construct. Password without user | 3359 | ;; Produce user/password@database construct. Password without user |
| 2945 | ;; is meaningless; database without user/password is meaningless, | 3360 | ;; is meaningless; database without user/password is meaningless, |
| @@ -2955,7 +3370,7 @@ The default comes from `process-coding-system-alist' and | |||
| 2955 | (if parameter | 3370 | (if parameter |
| 2956 | (setq parameter (nconc (list parameter) options)) | 3371 | (setq parameter (nconc (list parameter) options)) |
| 2957 | (setq parameter options)) | 3372 | (setq parameter options)) |
| 2958 | (sql-connect product parameter))) | 3373 | (sql-comint product parameter))) |
| 2959 | 3374 | ||
| 2960 | 3375 | ||
| 2961 | 3376 | ||
| @@ -2986,7 +3401,7 @@ The default comes from `process-coding-system-alist' and | |||
| 2986 | (interactive) | 3401 | (interactive) |
| 2987 | (sql-product-interactive 'sybase)) | 3402 | (sql-product-interactive 'sybase)) |
| 2988 | 3403 | ||
| 2989 | (defun sql-connect-sybase (product options) | 3404 | (defun sql-comint-sybase (product options) |
| 2990 | "Create comint buffer and connect to Sybase." | 3405 | "Create comint buffer and connect to Sybase." |
| 2991 | ;; Put all parameters to the program (if defined) in a list and call | 3406 | ;; Put all parameters to the program (if defined) in a list and call |
| 2992 | ;; make-comint. | 3407 | ;; make-comint. |
| @@ -2999,7 +3414,7 @@ The default comes from `process-coding-system-alist' and | |||
| 2999 | (setq params (append (list "-P" sql-password) params))) | 3414 | (setq params (append (list "-P" sql-password) params))) |
| 3000 | (if (not (string= "" sql-user)) | 3415 | (if (not (string= "" sql-user)) |
| 3001 | (setq params (append (list "-U" sql-user) params))) | 3416 | (setq params (append (list "-U" sql-user) params))) |
| 3002 | (sql-connect product params))) | 3417 | (sql-comint product params))) |
| 3003 | 3418 | ||
| 3004 | 3419 | ||
| 3005 | 3420 | ||
| @@ -3028,7 +3443,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3028 | (interactive) | 3443 | (interactive) |
| 3029 | (sql-product-interactive 'informix)) | 3444 | (sql-product-interactive 'informix)) |
| 3030 | 3445 | ||
| 3031 | (defun sql-connect-informix (product options) | 3446 | (defun sql-comint-informix (product options) |
| 3032 | "Create comint buffer and connect to Informix." | 3447 | "Create comint buffer and connect to Informix." |
| 3033 | ;; username and password are ignored. | 3448 | ;; username and password are ignored. |
| 3034 | (let ((db (if (string= "" sql-database) | 3449 | (let ((db (if (string= "" sql-database) |
| @@ -3036,7 +3451,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3036 | (if (string= "" sql-server) | 3451 | (if (string= "" sql-server) |
| 3037 | sql-database | 3452 | sql-database |
| 3038 | (concat sql-database "@" sql-server))))) | 3453 | (concat sql-database "@" sql-server))))) |
| 3039 | (sql-connect product (append `(,db "-") options)))) | 3454 | (sql-comint product (append `(,db "-") options)))) |
| 3040 | 3455 | ||
| 3041 | 3456 | ||
| 3042 | 3457 | ||
| @@ -3069,15 +3484,16 @@ The default comes from `process-coding-system-alist' and | |||
| 3069 | (interactive) | 3484 | (interactive) |
| 3070 | (sql-product-interactive 'sqlite)) | 3485 | (sql-product-interactive 'sqlite)) |
| 3071 | 3486 | ||
| 3072 | (defun sql-connect-sqlite (product options) | 3487 | (defun sql-comint-sqlite (product options) |
| 3073 | "Create comint buffer and connect to SQLite." | 3488 | "Create comint buffer and connect to SQLite." |
| 3074 | ;; Put all parameters to the program (if defined) in a list and call | 3489 | ;; Put all parameters to the program (if defined) in a list and call |
| 3075 | ;; make-comint. | 3490 | ;; make-comint. |
| 3076 | (let ((params)) | 3491 | (let ((params)) |
| 3077 | (if (not (string= "" sql-database)) | 3492 | (if (not (string= "" sql-database)) |
| 3078 | (setq params (append (list sql-database) params))) | 3493 | (setq params (append (list (expand-file-name sql-database)) |
| 3494 | params))) | ||
| 3079 | (setq params (append options params)) | 3495 | (setq params (append options params)) |
| 3080 | (sql-connect product params))) | 3496 | (sql-comint product params))) |
| 3081 | 3497 | ||
| 3082 | 3498 | ||
| 3083 | 3499 | ||
| @@ -3110,7 +3526,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3110 | (interactive) | 3526 | (interactive) |
| 3111 | (sql-product-interactive 'mysql)) | 3527 | (sql-product-interactive 'mysql)) |
| 3112 | 3528 | ||
| 3113 | (defun sql-connect-mysql (product options) | 3529 | (defun sql-comint-mysql (product options) |
| 3114 | "Create comint buffer and connect to MySQL." | 3530 | "Create comint buffer and connect to MySQL." |
| 3115 | ;; Put all parameters to the program (if defined) in a list and call | 3531 | ;; Put all parameters to the program (if defined) in a list and call |
| 3116 | ;; make-comint. | 3532 | ;; make-comint. |
| @@ -3126,7 +3542,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3126 | (if (not (string= "" sql-user)) | 3542 | (if (not (string= "" sql-user)) |
| 3127 | (setq params (append (list (concat "--user=" sql-user)) params))) | 3543 | (setq params (append (list (concat "--user=" sql-user)) params))) |
| 3128 | (setq params (append options params)) | 3544 | (setq params (append options params)) |
| 3129 | (sql-connect product params))) | 3545 | (sql-comint product params))) |
| 3130 | 3546 | ||
| 3131 | 3547 | ||
| 3132 | 3548 | ||
| @@ -3156,7 +3572,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3156 | (interactive) | 3572 | (interactive) |
| 3157 | (sql-product-interactive 'solid)) | 3573 | (sql-product-interactive 'solid)) |
| 3158 | 3574 | ||
| 3159 | (defun sql-connect-solid (product options) | 3575 | (defun sql-comint-solid (product options) |
| 3160 | "Create comint buffer and connect to Solid." | 3576 | "Create comint buffer and connect to Solid." |
| 3161 | ;; Put all parameters to the program (if defined) in a list and call | 3577 | ;; Put all parameters to the program (if defined) in a list and call |
| 3162 | ;; make-comint. | 3578 | ;; make-comint. |
| @@ -3167,7 +3583,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3167 | (setq params (append (list sql-user sql-password) params))) | 3583 | (setq params (append (list sql-user sql-password) params))) |
| 3168 | (if (not (string= "" sql-server)) | 3584 | (if (not (string= "" sql-server)) |
| 3169 | (setq params (append (list sql-server) params))) | 3585 | (setq params (append (list sql-server) params))) |
| 3170 | (sql-connect product params))) | 3586 | (sql-comint product params))) |
| 3171 | 3587 | ||
| 3172 | 3588 | ||
| 3173 | 3589 | ||
| @@ -3196,10 +3612,10 @@ The default comes from `process-coding-system-alist' and | |||
| 3196 | (interactive) | 3612 | (interactive) |
| 3197 | (sql-product-interactive 'ingres)) | 3613 | (sql-product-interactive 'ingres)) |
| 3198 | 3614 | ||
| 3199 | (defun sql-connect-ingres (product options) | 3615 | (defun sql-comint-ingres (product options) |
| 3200 | "Create comint buffer and connect to Ingres." | 3616 | "Create comint buffer and connect to Ingres." |
| 3201 | ;; username and password are ignored. | 3617 | ;; username and password are ignored. |
| 3202 | (sql-connect product | 3618 | (sql-comint product |
| 3203 | (append (if (string= "" sql-database) | 3619 | (append (if (string= "" sql-database) |
| 3204 | nil | 3620 | nil |
| 3205 | (list sql-database)) | 3621 | (list sql-database)) |
| @@ -3234,7 +3650,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3234 | (interactive) | 3650 | (interactive) |
| 3235 | (sql-product-interactive 'ms)) | 3651 | (sql-product-interactive 'ms)) |
| 3236 | 3652 | ||
| 3237 | (defun sql-connect-ms (product options) | 3653 | (defun sql-comint-ms (product options) |
| 3238 | "Create comint buffer and connect to Microsoft SQL Server." | 3654 | "Create comint buffer and connect to Microsoft SQL Server." |
| 3239 | ;; Put all parameters to the program (if defined) in a list and call | 3655 | ;; Put all parameters to the program (if defined) in a list and call |
| 3240 | ;; make-comint. | 3656 | ;; make-comint. |
| @@ -3254,7 +3670,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3254 | ;; If -P is passed to ISQL as the last argument without a | 3670 | ;; If -P is passed to ISQL as the last argument without a |
| 3255 | ;; password, it's considered null. | 3671 | ;; password, it's considered null. |
| 3256 | (setq params (append params (list "-P"))))) | 3672 | (setq params (append params (list "-P"))))) |
| 3257 | (sql-connect product params))) | 3673 | (sql-comint product params))) |
| 3258 | 3674 | ||
| 3259 | 3675 | ||
| 3260 | 3676 | ||
| @@ -3290,7 +3706,7 @@ Try to set `comint-output-filter-functions' like this: | |||
| 3290 | (interactive) | 3706 | (interactive) |
| 3291 | (sql-product-interactive 'postgres)) | 3707 | (sql-product-interactive 'postgres)) |
| 3292 | 3708 | ||
| 3293 | (defun sql-connect-postgres (product options) | 3709 | (defun sql-comint-postgres (product options) |
| 3294 | "Create comint buffer and connect to Postgres." | 3710 | "Create comint buffer and connect to Postgres." |
| 3295 | ;; username and password are ignored. Mark Stosberg suggest to add | 3711 | ;; username and password are ignored. Mark Stosberg suggest to add |
| 3296 | ;; the database at the end. Jason Beegan suggest using --pset and | 3712 | ;; the database at the end. Jason Beegan suggest using --pset and |
| @@ -3304,7 +3720,7 @@ Try to set `comint-output-filter-functions' like this: | |||
| 3304 | (setq params (append (list "-h" sql-server) params))) | 3720 | (setq params (append (list "-h" sql-server) params))) |
| 3305 | (if (not (string= "" sql-user)) | 3721 | (if (not (string= "" sql-user)) |
| 3306 | (setq params (append (list "-U" sql-user) params))) | 3722 | (setq params (append (list "-U" sql-user) params))) |
| 3307 | (sql-connect product params))) | 3723 | (sql-comint product params))) |
| 3308 | 3724 | ||
| 3309 | 3725 | ||
| 3310 | 3726 | ||
| @@ -3334,7 +3750,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3334 | (interactive) | 3750 | (interactive) |
| 3335 | (sql-product-interactive 'interbase)) | 3751 | (sql-product-interactive 'interbase)) |
| 3336 | 3752 | ||
| 3337 | (defun sql-connect-interbase (product options) | 3753 | (defun sql-comint-interbase (product options) |
| 3338 | "Create comint buffer and connect to Interbase." | 3754 | "Create comint buffer and connect to Interbase." |
| 3339 | ;; Put all parameters to the program (if defined) in a list and call | 3755 | ;; Put all parameters to the program (if defined) in a list and call |
| 3340 | ;; make-comint. | 3756 | ;; make-comint. |
| @@ -3345,7 +3761,7 @@ The default comes from `process-coding-system-alist' and | |||
| 3345 | (setq params (append (list "-p" sql-password) params))) | 3761 | (setq params (append (list "-p" sql-password) params))) |
| 3346 | (if (not (string= "" sql-database)) | 3762 | (if (not (string= "" sql-database)) |
| 3347 | (setq params (cons sql-database params))) ; add to the front! | 3763 | (setq params (cons sql-database params))) ; add to the front! |
| 3348 | (sql-connect product params))) | 3764 | (sql-comint product params))) |
| 3349 | 3765 | ||
| 3350 | 3766 | ||
| 3351 | 3767 | ||
| @@ -3379,11 +3795,11 @@ The default comes from `process-coding-system-alist' and | |||
| 3379 | (interactive) | 3795 | (interactive) |
| 3380 | (sql-product-interactive 'db2)) | 3796 | (sql-product-interactive 'db2)) |
| 3381 | 3797 | ||
| 3382 | (defun sql-connect-db2 (product options) | 3798 | (defun sql-comint-db2 (product options) |
| 3383 | "Create comint buffer and connect to DB2." | 3799 | "Create comint buffer and connect to DB2." |
| 3384 | ;; Put all parameters to the program (if defined) in a list and call | 3800 | ;; Put all parameters to the program (if defined) in a list and call |
| 3385 | ;; make-comint. | 3801 | ;; make-comint. |
| 3386 | (sql-connect product options) | 3802 | (sql-comint product options) |
| 3387 | ) | 3803 | ) |
| 3388 | ;; ;; Properly escape newlines when DB2 is interactive. | 3804 | ;; ;; Properly escape newlines when DB2 is interactive. |
| 3389 | ;; (setq comint-input-sender 'sql-escape-newlines-and-send)) | 3805 | ;; (setq comint-input-sender 'sql-escape-newlines-and-send)) |
| @@ -3415,7 +3831,7 @@ input. See `sql-interactive-mode'. | |||
| 3415 | (interactive) | 3831 | (interactive) |
| 3416 | (sql-product-interactive 'linter)) | 3832 | (sql-product-interactive 'linter)) |
| 3417 | 3833 | ||
| 3418 | (defun sql-connect-linter (product options) | 3834 | (defun sql-comint-linter (product options) |
| 3419 | "Create comint buffer and connect to Linter." | 3835 | "Create comint buffer and connect to Linter." |
| 3420 | ;; Put all parameters to the program (if defined) in a list and call | 3836 | ;; Put all parameters to the program (if defined) in a list and call |
| 3421 | ;; make-comint. | 3837 | ;; make-comint. |
| @@ -3430,7 +3846,7 @@ input. See `sql-interactive-mode'. | |||
| 3430 | (if (string= "" sql-database) | 3846 | (if (string= "" sql-database) |
| 3431 | (setenv "LINTER_MBX" nil) | 3847 | (setenv "LINTER_MBX" nil) |
| 3432 | (setenv "LINTER_MBX" sql-database)) | 3848 | (setenv "LINTER_MBX" sql-database)) |
| 3433 | (sql-connect product params) | 3849 | (sql-comint product params) |
| 3434 | (setenv "LINTER_MBX" old-mbx))) | 3850 | (setenv "LINTER_MBX" old-mbx))) |
| 3435 | 3851 | ||
| 3436 | 3852 | ||