D言語でdubを叩いてMySQLに接続する
D言語でもMySQLしたい!
Rubyで書いたプログラムが結構非現実的な時間を返してきたのでD言語にポートしてみました(結果だけ言うとDのほうが遅くて悲しい気持ちになりました(コードの書き方が悪かったのかもしれないけど)).
当然MySQLライブラリを使う必要がありますが,D言語にはDUBというRubyで言うbundlerのような便利ツールがあるのでそれを使ってみました.DUBのHPはここ
Find, Use and Share DUB Packages - DUB - The D package registry
Macの場合はHomebrewにdubが入っているので brew install dub
で入ります.そうでなくてもOSごとにprecompiled binaryが用意されています.優しい世界.入れたら,リポジトリディレクトリを作りたいディレクトリに移動して dub init [リポジトリ名]
します.
$ dub init hoge Successfully created an empty project in '/home/nagoyan/Documents/hoge'. $ cd hoge $ ls -a . .. .gitignore dub.json source
.gitignore
には既に .dub
や *.o
,*.obj
などバージョン管理から除外すべきファイルが入力されています.dub.json
にリポジトリの情報や依存パッケージをJSONで入力します.今回はdubのサイトでmysqlでヒットした3件のうち一番単純に使えそうな Package mysql-d version 0.3.1 - DUB - The D package registry を使うことにするので,dub.json
に
{ ... "dependencies": { "mysql-d": "~>0.3.1" } }
と入力します.サイトに載っている例では特定のバージョンを持ってくるようにしていますが,常に最新のものが欲しければ,バージョンに当たる部分に ~master
と書けば最新のコードが降ってきます.
source/app.d
に,エントリポイントである main
関数を書きます.これはinitした時に既に以下の様な内容で作成されています:
import std.stdio; void main() { writeln("Edit source/app.d to start your project."); }
dub build
で,リポジトリ内のソースコードをビルドしてくれます.依存パッケージはこの時ダウンロードします.が,この時なぜかdubがldconfigのキャッシュを無視して /usr/lib64/mysql
を見てくれなかったので,dub.json
のトップレベルに "lflags": ["L/usr/lib64/mysql"]
を追加します(実はこの作業はもともとCentOS上でやっていました).
$ dub build Target mysql-d 0.3.1 is up to date. Use --force to rebuild. Building hoge ~master configuration "application", build type debug. Compiling using dmd... Linking... $ dub > $ dub Target mysql-d 0.3.1 is up to date. Use --force to rebuild. Target hoge ~master is up to date. Use --force to rebuild. Running ./hoge Edit source/app.d to start your project.
最後のメッセージは app.d
の中の writeln
に書かれているやつです.あとは app.d
をゴニョゴニョするだけ.mysql-dのページのREADMEに使用例が書かれているのでそれを真似するだけ.インスタンスを1個作って,query
関数の引数にSQLを書く.可変長引数でSQLの ?
を使ったバインディング機構にも対応しています.SELECT
などの結果が返ってくるタイプのクエリではMysqlResultというクラスのインスタンスが返ってきます(そうでないCRUD操作でも返ってくると思いますが).このクラスはforeach range要件を満たしているので,foreachに渡すことでMysqlRowというクラスのインスタンスを1個ずつ渡してくれます.MysqlRowは文字列として出力してやるとただの文字列配列のように見えますが,内部でカラム名と値の位置をマッピングしているため,数値の添字だけでなくカラム名でも要素にアクセスできます.
MySQLサーバとの接続を終了する時に .close
とかしなくていいの? と思って調べてみたのですが, https://github.com/Paxa/mysql.d/blob/master/source/mysql/mysql.d#L122-L124 を見るとデストラクタの中でやってくれているようなので書かなくても大丈夫そうです(安易にこういうこと書くと刺されそうですが).
参考
Problem linking mysqlclient when compiling mysql-d - RejectedSoftware Forums
備考:LDFLAGSを追加しないと……
以下のような結果が返ってきます.これを解決するのに一番時間がかかった.
$ dub build Target mysql-d 0.3.1 is up to date. Use --force to rebuild. Building hoge ~master configuration "application", build type debug. Compiling using dmd... Linking... /usr/bin/ld: cannot find -lmysqlclient collect2: ld はステータス 1 で終了しました --- errorlevel 1 FAIL .dub/build/application-debug-linux.posix-x86_64-dmd_2067-D139BA4168D82F8FB70F3EB71271D775/ hoge executable Error executing command build: dmd failed with exit code 1.