Có một công ty phụ trợ để hoàn thành trong chế độ tương tác sql không?


9

Tôi đang sử dụng sql-interactive-modevà tôi đang cần một phụ trợ Công ty sẽ hoàn thành các từ khóa SQL và tốt nhất là tên cột / bảng của cơ sở dữ liệu đã sử dụng.

Khi tìm kiếm bất kỳ sự hoàn thành nào, tôi ngạc nhiên, không có phần phụ trợ nào cho SQL. Tôi đã tìm thấy đoạn trích này , nhưng nó không hoạt động đúng.

Có thể nó chưa tồn tại và tôi có thể tạo một phụ trợ riêng cho SQL. Nhưng tôi thấy khó tin rằng không có phụ trợ Công ty cho một trong những ngôn ngữ phổ biến nhất.


Hoàn thành từ khóa phải đủ đơn giản với một trong những phụ trợ giống như chính tả. Dữ liệu dành riêng cho cơ sở dữ liệu khó hơn nhiều, đặc biệt nếu bạn muốn nó hoạt động cho nhiều hơn một cơ sở dữ liệu ...
wasamasa

iNếu hoàn thành từ khóa sẽ đủ đơn giản, bạn có biết tại sao chưa có SQL-backend cho Company không? Và tôi đồng ý với bạn về điều này, điều đó thật khó khăn, nhưng khi bạn có nội dung cột trong bộ đệm của mình, nó sẽ được hoàn thành với company-dabbrevtôi đoán?
ReneFroger

Nó chỉ đơn thuần là một mục mới company-keywords.el, vì vậy hãy đóng góp! Và vâng, phần cuối của dabbrev sẽ nắm bắt được điều đó (và mọi thứ khác trong bộ đệm của bạn) ...
wasamasa

Câu trả lời:


4

Tôi đã có một vấn đề tương tự và quyết định tạo phụ trợ của riêng tôi. Một trong những phụ trợ hiện có (C ++?) Đã được sử dụng làm mẫu và tôi đã sửa đổi nó để tạo phần cuối mới hoạt động giống như một từ điển.

Trong thiết lập của tôi, bộ đệm SQLi được tự động đặt tên để khớp với cơ sở dữ liệu đang được kết nối, vd. *DB:DBASE1DM*. Phần cuối chứa một bản sao cho mỗi cơ sở dữ liệu với các lược đồ, bảng và cột. Khi tôi muốn hoàn thành một cái gì đó, tên của bộ đệm được sử dụng để có được danh sách chính xác các ứng cử viên cho cơ sở dữ liệu đó.

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

Điều này có nhược điểm là nó không phải là một sự hoàn thành thông minh và bao gồm các cơ sở dữ liệu mới hoặc sửa đổi các cơ sở dữ liệu hiện tại là một quy trình thủ công. Một vài truy vấn có thể được sử dụng để thu thập dữ liệu và sau đó không khó để đưa dữ liệu vào định dạng cần thiết cho phụ trợ.

Hàm bên dưới xử lý kết nối với cơ sở dữ liệu và thay đổi tên của bộ đệm để khớp với cơ sở dữ liệu được kết nối.

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

cảm ơn câu trả lời của bạn, nó thực sự đánh giá cao! Tuy nhiên, tôi đã gặp một số khó khăn khi thử chức năng của bạn. Sau khi thêm vào công ty (add-to-list 'company-backends 'ry/company-sql) (add-to-list 'company-backends 'ry/company-sql-alist), tôi đã gặp lỗi M-x sql-mysqlsau khi thử một từ : Company: An error occurred in auto-begin Args out of range: "*SQL*", 4, -3. Làm thế nào tôi có thể giải thích thông báo lỗi này?
ReneFroger

Tôi đã cập nhật câu trả lời để bao gồm chức năng mà tôi sử dụng để kết nối với cơ sở dữ liệu. Nó xử lý thay đổi tên bộ đệm để phù hợp với cơ sở dữ liệu có liên quan đến bộ đệm. Tên bộ đệm của bạn quá ngắn nên chuỗi con bị lỗi. Chuỗi con được sử dụng để loại bỏ *DB:hậu tố và môi trường khỏi tên bộ đệm để lấy tên cơ sở dữ liệu để danh sách hoàn thành chính xác được sử dụng. Hàm giả định rằng tên bộ đệm cho các lần hoàn thành sẽ ở dạng *DB:ACCOUNTSDM*. Chuỗi con sẽ kéo ACCOUNTStừ tên bộ đệm.
Jonakand

Cảm ơn vì đã trả lời. Tôi rõ ràng cần phải học Lisp, vì tôi không thể tìm ra cách tôi có thể sửa đổi nó mysqlthay vì db2. Nhưng đóng góp của bạn thực sự được đánh giá cao, vì vậy tôi xác nhận trả lời của bạn. Cảm ơn vì điều đó.
ReneFroger

Có lẽ câu trả lời này nên đóng góp cho Emacs.
stardiviner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.