« ^ »
[WIP]

EmacsからMySQLに接続する

所要時間: 約 4分

Emacs には lisp/progmodes 配下に sql.el があり、 SQL クライアントのためのフロントエンドを提供している。通常はそれを用いたり、カスタマイズしたりして、データベースに接続する。

sql.elの使い方をおさらいする。

使い方は概ね docstring に記述されている。翻訳しながら、説明を追加していく。

Run mysql by TcX as an inferior process.

TcX で mysql を下位プロセスとして実行します。

なるほど。TcXとは何の事だろう1

Mysql versions 3.23 and up are free software.

Mysql バージョン 3.23 以降はフリー ソフトウェアです。

なるほど。

If buffer `*SQL*' exists but no process is running, make a new process.

バッファ `*SQL*' が存在するがプロセスが実行されていない場合は、新しいプロセスを作成します。

M-x mysql-mysql を実行すると確かに *SQL* というバッファが作成される。SQL用のバッファをカスタマイズする事もできる。

If buffer exists and a process is running, just switch to buffer `*SQL*'.

バッファが存在し、プロセスが実行中の場合は、バッファ `*SQL*' に切り替えるだけです。

たしかに、そう動作している。

Interpreter used comes from variable `sql-mysql-program'. Login uses the variables `sql-user', `sql-password', `sql-database', and `sql-server' as defaults, if set. Additional command line parameters can be stored in the list `sql-mysql-options'.

使用されるインタープリターは変数 `sql-mysql-program' から取得されます。ログインでは、変数 `sql-user'、`sql-password'、`sql-database'、および `sql-server' がデフォルトとして使用されます (設定されている場合)。追加のコマンドラインパラメータはリスト `sql-mysql-options' に保存できます。

関連する変数は以下の6つ。

  • sql-mysql-program
  • sql-mysql-options
  • sql-password
  • sql-user
  • sql-database
  • sql-server

sql-mysql-programsql-mysql-options はMySQLの接続のみに使用されるけれど、他の変数は他のデータベースの接続時にも使われる。

The buffer is put in SQL interactive mode, giving commands for sending input. See `sql-interactive-mode'.

バッファは SQL 対話モードになり、入力を送信するためのコマンドが提供されます。 「sql-interactive-mode」を参照してください。

To set the buffer name directly, use \\[universal-argument] before \\[sql-mysql]. Once session has started, \\[sql-rename-buffer] can be called separately to rename the buffer.

バッファ名を直接設定するには、\[sql-mysql] の前に \[universal-argument] を使用します。セッションが開始されると、\[sql-rename-buffer] を個別に呼び出してバッファーの名前を変更できます。

To specify a coding system for converting non-ASCII characters in the input and output to the process, use \\[universal-coding-system-argument] before \\[sql-mysql]. You can also specify this with \\[set-buffer-process-coding-system] in the SQL buffer, after you start the process.

プロセスへの入力および出力内の非 ASCII 文字を変換するためのコーディング システムを指定するには、\[sql-mysql] の前に \[universal-coding-system-argument] を使用します。プロセスの開始後に、SQL バッファー内の \[set-buffer-process-coding-system] を使用してこれを指定することもできます。

The default comes from `process-coding-system-alist' and `default-process-coding-system'.

デフォルトは「process-coding-system-alist」と「default-process-coding-system」から来ています。

\(Type \\[describe-mode] in the SQL buffer for a list of commands.)

\(コマンドのリストを表示するには、SQL バッファに \[describe-mode] と入力します。)

MySQLのクライアント側のバージョン切り替えなど

僕はDockerを使う開発はあまりやりやすいとは思わないから、できればコンテナではない環境で開発したい。できるかぎり、構成要素を増やしたくないからだ。

とはいえmacOSで環境を入れていくと、複数のバージョンのソフトウェアが混在し、よくわからない状態になる。これは実際にはきちんとひもといていけば、取るに足らないような環境変数の問題だったりする。

Homebrew でインストールしているなら /usr/local/opt にそれぞれパッケージがあるから、それらを使うように上手く設定をしてあげればいい。ポイントは使わないものは設定しないという事だろう。

BashやZshなどのシェルでは、設定を同一にしてしまいそうだけれど、Emacsの場合はオンザフライに書き換えて実施したりする。関係する変数としては、Emacsがプログラムを実行する時にプログラムを探すパスを設定する exec-path 、BashやZshなどのシェルプログラムが実行ファイルを探しだす環境変数 PATH 、コンパイル時にコンパイルスイッチとして利用される環境変数 CFLAGS 、 ライブラリファイルを探しだす LD_LIBRARY_PATH などだろう。

多くのパッケージは xxx.pc といったファイルを梱包している。これは pkg-config コマンドで読み取る事ができ、ビルド時に設定するべきコンパイルスイッチなどの設定を出力してくれる。

ここまで書いたがMySQLの場合は以下のようにする事で設定できる。

(setq sql-mysql-program "/usr/local/opt/[email protected]/bin/mysql")
(setq sql-mysql-options nil)

接続情報はemacs-lispの世界で記述しても良いが、 .my.cfg に記述する方法もある。

[client]
user=root
password=yay
host=127.0.0.1
port=3306
database=testing
~/.my.cfg

DockerコンテナのMySQLをEmacsから接続する

ポートをホスト側に公開している場合は、通常の方法でEmacsからMySQLへ接続できる。ただDockerコンテナで起動しているデータベースのポートを公開したくない場合もあるだろう。

その場合は sql-mysql-programdocker を指定し、 sql-mysql-options'("exec" "-ti" "コンテナ名" "mysql" "mysql" "--local-infile=1") を設定する事で、Emacsの *SQL* バッファを利用できる。

(setq sql-mysql-program "docker")
(setq sql-mysql-options '("exec" "-ti" "mysqld" "mysql" "mysql" "--local-infile=1"))

MySQLのコンテナはSIGINTを送信(C-c C-c)したときに停止しないケースがある。そのため停止用にDockerで動作させているコンテナに対してSIGTERMを送信するためのコマンドを定義し利用していた。

(defun sql-mysqld-stop ()
  (interactive)
  (let ((vterm-shell "docker kill -s TERM mysqld")
	(vterm-buffer-name "SQL: MySQL: Stop"))
    (vterm)))