Existe-t-il un backend d'entreprise pour l'achèvement en mode interactif sql?


9

J'utilise sql-interactive-modeet j'ai besoin de backends d'entreprise qui complèteront les mots clés SQL et, de préférence, également les noms de colonne / table de la base de données utilisée.

À la recherche d'un achèvement, à ma grande surprise, il n'y avait pas encore de backend pour SQL. J'ai trouvé cet extrait , mais cela n'a pas fonctionné correctement.

Il est possible qu'il n'existe pas encore, et je pourrais créer un propre backend pour SQL. Mais j'ai du mal à croire qu'il n'y a pas de backend d'entreprise pour l'une des langues les plus courantes.


La saisie de mots clés doit être assez simple avec l'un des backends de type dict. Les données spécifiques aux bases de données sont beaucoup plus difficiles, surtout si vous voulez qu'elles fonctionnent pour plus d'une base de données ...
wasamasa

Si la saisie de mots clés serait assez simple, avez-vous une idée pourquoi il n'y a pas encore de backend SQL pour la société? Et je suis d'accord avec vous sur ce dernier, ce serait difficile, mais quand vous avez le contenu des colonnes dans votre tampon, ce serait complété avec company-dabbrevje suppose?
ReneFroger

Ce ne serait qu'une nouvelle entrée company-keywords.el, alors n'hésitez pas à contribuer! Et oui, le backend dabbrev attraperait cela (et tout le reste dans votre tampon) ...
wasamasa

Réponses:


4

J'ai eu un problème similaire et j'ai décidé de créer mon propre backend. L'un des backends existants (C ++?) A été utilisé comme modèle et je l'ai modifié pour créer le nouveau backend qui se comporte comme un dictionnaire.

Dans ma configuration, les tampons SQLi sont automatiquement nommés pour correspondre à la base de données qui est connectée, par exemple. *DB:DBASE1DM*. Le backend contient une liste pour chaque base de données avec les schémas, les tables et les colonnes. Lorsque je veux terminer quelque chose, le nom du tampon est utilisé pour obtenir la liste correcte des candidats pour cette base de données.

(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)))

Cela présente l'inconvénient qu'il ne s'agit pas d'une opération intelligente et que l'inclusion de nouvelles bases de données ou la modification de bases de données existantes est un processus manuel. Quelques requêtes peuvent être utilisées pour collecter les données, puis il n'est pas très difficile de les masser dans le format requis pour le backend.

La fonction ci-dessous gère la connexion à une base de données et la modification des noms des tampons pour correspondre à la base de données qui est connectée.

(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 "*"))))

merci pour votre réponse, c'est vraiment apprécié! Cependant, j'ai eu quelques difficultés en essayant votre fonction. Après avoir ajouté à l' entreprise avec (add-to-list 'company-backends 'ry/company-sql) (add-to-list 'company-backends 'ry/company-sql-alist), je suis l'erreur suivante dans M-x sql-mysqlaprès avoir essayé un mot: Company: An error occurred in auto-begin Args out of range: "*SQL*", 4, -3. Comment pourrais-je interpréter ce message d'erreur?
ReneFroger

J'ai mis à jour la réponse pour inclure la fonction que j'utilise pour me connecter à une base de données. Il gère la modification des noms de tampons pour correspondre à la base de données associée aux tampons. Le nom de votre tampon est trop court, la sous-chaîne échoue. La sous-chaîne est utilisée pour supprimer le *DB:suffixe d'environnement et du nom du tampon afin d'obtenir le nom de la base de données afin que la liste correcte des complétions soit utilisée. La fonction suppose que le nom du tampon pour les complétions sera dans le formulaire *DB:ACCOUNTSDM*. La sous-chaîne serait ACCOUNTSextraite du nom du tampon.
Jonakand

Merci pour votre réponse. J'ai clairement besoin d'apprendre Lisp, car je ne savais pas comment le modifier au mysqllieu de db2. Mais votre contribution est vraiment appréciée, j'ai donc validé votre réponse. Merci pour ça.
ReneFroger

Peut-être que cette réponse devrait contribuer à Emacs.
stardiviner
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.