mysql emacs sql-mode

¿Cómo puedo obtener emacs sql-mode para usar el archivo de configuración de mysql(.my.cnf)?



(3)

Cuando mysql dbname en el indicador bash, me conecto automáticamente a la base de datos dbname con el username , la password y la información del dbname incluida en mi archivo .my.cnf .

Cuando uso Mx sql-mysql en emacs, me vuelven a solicitar toda esta información.

¿Hay alguna manera de que pueda obtener el modo sql de emacs para usar la información en mi archivo .my.cnf ?


No creo que esto sea posible, pero puedes configurarlo en la configuración del modo en sí:

(setq sql-connection-alist ''((pool-a (sql-product ''mysql) (sql-server "1.2.3.4") (sql-user "me") (sql-password "mypassword") (sql-database "thedb") (sql-port 3306)) (pool-b (sql-product ''mysql) (sql-server "1.2.3.4") (sql-user "me") (sql-password "mypassword") (sql-database "thedb") (sql-port 3307)))) (defun sql-connect-preset (name) "Connect to a predefined SQL connection listed in `sql-connection-alist''" (eval `(let ,(cdr (assoc name sql-connection-alist)) (flet ((sql-get-login (&rest what))) (sql-product-interactive sql-product))))) (defun sql-pool-a () (interactive) (sql-connect-preset ''pool-a))

Echa un vistazo a este artículo para más información.


Simplemente presiona return, se recogió por defecto.


Claro que es posible. Aunque es bastante complicado.

Aproximadamente, los pasos son:

  1. Lectura y análisis del archivo ini usando ini.el.
  2. Fusionando la configuración de los diferentes hosts con la configuración de los clientes porque esta última se aplica globalmente.
  3. Transformando cada host a un formato adecuado para sql-connection-alist
  4. Poblando sql-connection-alist
  5. Usando Mx sql-connect (¡que se completa automáticamente!)

El siguiente código también incluye un analizador .pgpass, por las dudas. Notarás que la implementación es más simple.

;;; .pgpass parser (defun read-file (file) "Returns file as list of lines." (with-temp-buffer (insert-file-contents file) (split-string (buffer-string) "/n" t))) (defun pgpass-to-sql-connection (config) "Returns a suitable list for sql-connection-alist from a pgpass file." (append sql-connection-alist (let ((server (lambda (host port db user _pass) (list (concat db ":" user ":" port ":" host) (list ''sql-product ''''postgres) (list ''sql-server host) (list ''sql-user user) (list ''sql-port (string-to-number port)) (list ''sql-database db)))) (pgpass-line (lambda (line) (apply server (split-string line ":" t))))) (mapcar pgpass-line config)))) ;;; .my.cnf parser ;;; Copied verbatim from https://github.com/daniel-ness/ini.el/blob/master/ini.el (defun ini-decode (ini_text) ;; text -> alist (interactive) (if (not (stringp ini_text)) (error "Must be a string")) (let ((lines (split-string ini_text "/n")) (section) (section-list) (alist)) (dolist (l lines) ;; skip comments (unless (or (string-match "^;" l) (string-match "^[ /t]$" l)) ;; catch sections (if (string-match "^//[//(.*//)//]$" l) (progn (if section ;; add as sub-list (setq alist (cons `(,section . ,section-list) alist)) (setq alist section-list)) (setq section (match-string 1 l)) (setq section-list nil))) ;; catch properties (if (string-match "^//([^/s/t]+//)[/s/t]*=[/s/t]*//(.+//)$" l) (let ((property (match-string 1 l)) (value (match-string 2 l))) (progn (setq section-list (cons `(,property . ,value) section-list))))))) (if section ;; add as sub-list (setq alist (cons `(,section . ,section-list) alist)) (setq alist section-list)) alist)) (defun read-ini (file) "Returns ini file as alist." (with-temp-buffer (insert-file-contents file) (ini-decode (buffer-string)))) (defun filter-alist (wanted-members alist) "Returns a copy of given alist, with only fields from wanted-members." (let ((result nil) (add-if-member (lambda (elt) (when (member (car elt) wanted-members) (add-to-list ''result elt t))))) (mapc add-if-member alist) result)) (defun merge-alist (original override) "Returns a union of original and override alist. On key conflict, the latter wins." (let ((result (copy-alist override)) (add (lambda (elt) (setq result (add-to-list ''result elt t (lambda (left right) (equal (car left) (car right)))))))) (mapc add original) result)) (defun map-alist-keys (f alist) "Maps on alist''s keys and returns new alist with new keys." (mapcar (lambda (elt) (list (funcall f (car elt)) (cdr elt))) alist)) (defun map-alist-values (f alist) "Maps on alist''s values and returns new alist with new values." (mapcar (lambda (elt) (list (car elt) (funcall f (cdr elt)))) alist)) (defun parse-mycnf-hosts (file-path) "Returns list of hosts with clients'' section applied to all hosts." (let ((hosts nil) (global nil) (fields ''("user" "host" "database" "password" "port")) (section-parse (lambda(section) (if (equal (car section) "client") (setq global (filter-alist fields (cdr section))) (let ((host (car section)) (config (filter-alist fields (cdr section)))) (when config (add-to-list ''hosts (cons host config) t)))))) (merge-host-with-global (lambda (host) (cons (car host) (merge-alist global (cdr host)))))) (mapc section-parse (read-ini file-path)) (mapcar merge-host-with-global hosts))) (defun mycnf-to-sql-connection (config) (let ((key-to-sql-connection (lambda (key) (cond ((equal key "host") ''sql-server) ((equal key "user") ''sql-user) ((equal key "port") ''sql-port) ((equal key "database") ''sql-database) ((equal key "password") ''sql-password) (t (error (format "Unknown key %s" key))))))) (map-alist-values (apply-partially ''map-alist-keys key-to-sql-connection) config))) ;;; Actually populating sql-connection-alist (setq sql-connection-alist (append (mycnf-to-sql-connection (parse-mycnf-hosts "~/.my.cnf")) (pgpass-to-sql-connection (read-file "~/.pgpass")) ))

Con el siguiente .my.cnf :

[client] user=me [host1] database=db1 host=db.host1.com [host2] database=db2 user=notme host=db.host2.com

Ejecutar la expresión (mycnf-to-sql-connection (parse-mycnf-hosts "~/.my.cnf")) me da (bastante impreso a mano):

(("host2" ((sql-server "db.host2.com") (sql-user "notme") (sql-database "db2"))) ("host1" ((sql-server "db.host1.com") (sql-database "db1") (sql-user "me"))))

Finalmente, en lugar de usar Mx sql-mysql , use Mx sql-connect y podrá conectarse usando el alias, con finalización automática.