## 背景
[[Neovim]]で[[SQL]]ファイルを快適に編集するため[[LSP]]がないか探していたら、[[sqls]]を発見した。[[データベース]]と接続して、単なる補完だけでなくクエリ実行と結果表示機能まで提供されており、ミニマムな[[データベースクライアント]]としても利用できることが分かったので導入する。
## 環境
| 対象 | バージョン |
| ------------- | ------------------------ |
| [[Neovim]] | v0.10.3 |
| [[MySQL]] | 8.4.3-1.el9 |
| [[sqls]] | 0.2.28 |
| [[sqls.nvim]] | a514379 |
| [[Docker]] | 27.5.0, build a187fa5 |
| [[Ubuntu]] | 24.04.1 LTS (in [[WSL]]) |
## MySQLの準備
以下を参考に準備する。本題ではないのでここでは触れない。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
Docker ComposeでMySQLコンテナを作成
</div>
<div class="link-card-v2-content">公式イメージを使う。MySQLのバージョンは8。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/minerva-image.webp" />
<a data-href="Docker ComposeでMySQLコンテナを作成" class="internal-link"></a>
</div>
%%[[Docker ComposeでMySQLコンテナを作成]]%%
## sqlsのインストール
[[SQL]]の[[Language Server]]である[[sqls]]をインストール。[[mise]]を使っているので以下のコマンドで。
```console
mise use -g go:github.com/sqls-server/sqls
```
## sqls.nvimのインストール
[[nvim-lspconfig]]で利用する他の[[LSP]]と同じノリだと見落としがちな準備。[[データベース]]との接続周りは専用プラグイン[[sqls.nvim]]が必要。
```lua
{
"nanotee/sqls.nvim",
ft = "sql",
-- キー設定は好み. SQL実行はCtrl+Enterに統一しているので (<F12>は<C-CR>と同じ挙動になるようAHKで調整してる)
config = function()
vim.keymap.set({ "n", "i" }, "<F12>", "<cmd>SqlsExecuteQuery<CR>", { silent = true })
vim.keymap.set({ "x" }, "<F12>", ":'<,'>SqlsExecuteQuery<CR>", { silent = true })
vim.keymap.set({ "n", "i" }, "g<F12>", "<cmd>SqlsExecuteQueryVertical<CR>", { silent = true })
vim.keymap.set({ "x" }, "g<F12>", ":'<,'>SqlsExecuteQueryVertical<CR>", { silent = true })
end,
}
```
## nvim-lspconfigの設定
READMEに記載のとおり `on_attach` を設定。
```lua
lspconfig.sqls.setup({
capabilities = capabilities,
on_attach = function(client, bufnr)
require("sqls").on_attach(client, bufnr)
end,
})
```
## 接続設定ファイルの作成
[[Linux]]の場合は `~/.config/sqls/config.yml` を作成。
```yaml
lowercaseKeywords: false
connections:
- alias: mysql-sample
driver: mysql
proto: tcp
user: user
passwd: password
host: localhost
port: 13306
dbName: mydb
params:
autocommit: "true"
tls: skip-verify
```
`passwd` が `password` になってて滅茶苦茶ハマった。。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📝sqlsでSELECT文のFROM句を書いても補完されない
</div>
<div class="link-card-v2-content">sqls: database connection is not open sqls: cannot ping to database, Error 1045 (28000): Access denied for user 'user'@'172.18.0.1' (using password: NO)</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/troubleshooting.webp" />
<a data-href="📝sqlsでSELECT文のFROM句を書いても補完されない" class="internal-link"></a>
</div>
%%[[📝sqlsでSELECT文のFROM句を書いても補完されない]]%%
> [!note]
> `dataSourceName` を指定する場合は[README](https://github.com/sqls-server/sqls?tab=readme-ov-file#workspace-configuration-sample) を参照。[[MySQL]]と[[PostgreSQL]]で同じ書き方にはならないので注意。
>
> ```yaml
> # PostgreSQLの例
> lowercaseKeywords: false
> connections:
> - alias: local/db
> driver: postgresql
> dataSourceName: "host=localhost port=55432 user=postgres password=postgres dbname=postgres sslmode=disable"
> ```
## 良いところ
シンプルで必要十分な機能がとてもよい。
- 入力時に補完が出る
- 補完内容も直感的で無駄がない
- [[sqls]]([[LSP]])の機能でフォーマットがかかる
- 1コマンドで[[SQL]]の実行ができる
- [[Lspsaga]]の `code_action` から関連コマンドを2アクションで実行できる
- 接続情報やデータベースの切り替えに便利
## 気になるところ
### フォーマット
フォーマットが実用に支障をきたすことがある。たとえば `DELETE FROM` はテーブル名とくっついてしまう。(実行時にsyntax errorに)
```sql
DELETE FROMpets
WHERE
id = 'hoge'
```
回避策としては[[Sleek]]で自動フォーマットするようにすればOK。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
ファイル保存時にSQLをフォーマット (conform.nvim)
</div>
<div class="link-card-v2-content">SQLファイルにSleekを設定する。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/minerva-image.webp" />
<a data-href="ファイル保存時にSQLをフォーマット (conform.nvim)" class="internal-link"></a>
</div>
%%[[ファイル保存時にSQLをフォーマット (conform.nvim)]]%%
[[conform.nvim]]を使っている場合、[[LSP]]よりも優先される(fallback)ので、明示的に[[nvim-lspconfig]]の設定を無効化する必要はない。
### Switch Database や Switch Connectionsが使いにくい
右下に以下のような選択肢が表示されるが、番号で選択してからEnterを押す必要がある。UI的なフィードバックもフィルタリングもできない。
![[Pasted image 20250128220232.png]]
[[telescope-ui-select.nvim]]を導入することで解決できる。
![[Pasted image 20250128220350.png|frame]]
*画面中央に[[telescope.nvim]]のUIで表示される*