Ich hatte ein ähnliches Problem und beschloss, mein eigenes Backend zu erstellen. Eines der vorhandenen Backends (C ++?) Wurde als Vorlage verwendet und ich habe es geändert, um das neue Backend zu erstellen, das sich wie ein Wörterbuch verhält.
In meinem Setup werden SQLi-Puffer automatisch so benannt, dass sie mit der Datenbank übereinstimmen, mit der eine Verbindung hergestellt wird, z. *DB:DBASE1DM*
. Das Backend enthält eine Liste für jede Datenbank mit den Schemas, Tabellen und Spalten. Wenn ich etwas vervollständigen möchte, wird der Name des Puffers verwendet, um die richtige Liste der Kandidaten für diese Datenbank zu erhalten.
(defun ry/company-sql-upper-lower (&rest lst)
(nconc (sort (mapcar 'upcase lst) 'string<) lst))
(defvar ry/company-sql-alist
`(("DBASE1" ;; Database name w/o environment suffix.
"DBASE1DM" "DBASE1UM" ;; Database name with environment suffix.
"SCHEMA1" "SCHEMA2"
"TABLE1" "TABLE2"
"COLUMN1" "COLUMN2")
("DBASE2"
"DBASE2DM" "DBASE2UM"
"SCHEMA1" "SCHEMA2"
"TABLE1" "TABLE2"
"COLUMN1" "COLUMN2"))
"Alist mapping sql-mode to candidates.")
(defun ry/company-sql (command &optional arg &rest ignored)
"`company-mode' back-end for SQL mode based on database name."
(interactive (list 'interactive))
(cl-case command
(interactive (company-begin-backend 'ry/company-sql))
(prefix (and (assoc (substring (buffer-name (current-buffer)) 4 -3) ry/company-sql-alist)
(not (company-in-string-or-comment))
(or (company-grab-symbol) 'stop)))
(candidates
(let ((completion-ignore-case t)
(symbols (cdr (assoc (substring (buffer-name (current-buffer)) 4 -3) ry/company-sql-alist))))
(all-completions arg (if (consp symbols)
symbols
(cdr (assoc symbols company-sql-alist))))))
(sorted t)))
Dies hat den Nachteil, dass es sich nicht um eine intelligente Vervollständigung handelt und dass das Einfügen neuer Datenbanken oder das Vornehmen von Änderungen an vorhandenen Datenbanken ein manueller Vorgang ist. Ein paar Abfragen können verwendet werden, um die Daten zu sammeln, und dann ist es nicht sehr schwierig, sie in das für das Backend erforderliche Format zu massieren.
Die folgende Funktion behandelt das Herstellen einer Verbindung zu einer Datenbank und das Ändern der Namen der Puffer, um sie an die Datenbank anzupassen, mit der eine Verbindung besteht.
(defun ry/sql-open-database (database username password)
"Open a SQLI process and name the SQL statement window with the name provided."
(interactive (list
(read-string "Database: ")
(read-string "Username: ")
(read-passwd "Password: ")))
(let ((u-dbname (upcase database)))
(setq sql-set-product "db2")
(sql-db2 u-dbname)
(sql-rename-buffer u-dbname)
(setq sql-buffer (current-buffer))
(sql-send-string (concat "CONNECT TO " database " USER " username " USING " password ";"))
(other-window 1)
(switch-to-buffer (concat "*DB:" u-dbname "*"))
(sql-mode)
(sql-set-product "db2")
(setq sql-buffer (concat "*SQL: " u-dbname "*"))))