ElixirのMariaDB/MySQLドライバでmariaexというのがあります。
使い方は以下のような感じで難しくはないです。
{:ok, p} = Mariaex.Connection.start_link(username: "ecto", database: "ecto_test")
Mariaex.Connection.query(p, "CREATE TABLE test1 (id serial, title text)")
で、稼働時のエラー、たとえばSQLのSyntaxErrorやらDB落ちてるとかはいくらでもリトライなり、プロセスの再起動なりをすればいいんですが、DB名を間違えた…とかだと致命的なので即刻終了する必要があります。
IO.inspect Mariaex.Connection.start_link(database: "testx")
case文で{:error, pid}をハンドルすればいいかと思ったら、コンソールにエラーメッセージが。
まあエラーはいたり死んだりするのはいいんですけど、適切にエラーをハンドリングして整形したメッセージ出して終了したいんですよ。(loggerのフォーマットをいじるのも全体に影響するし、なんか対処が違う気が)
じゃあProcess.monitor(pid)してメッセージを捕まえようとしてもstart_linkで死ぬのでどうにもこうにも。
GenServerでラップしたり、非同期にしたりといろいろやったんですが、最終的に以下のように。
# 要mariaex ~> 0.6.1
# 失敗時
Agent.start(fn ->
Mariaex.Connection.start_link(database: "testx", sync_connect: true)
end)
# => {:error,
# %Mariaex.Error{mariadb: %{code: 1044,
# message: "Access denied for user ''@'localhost' to database 'testx'"},
# message: nil}}
# 成功時
{:ok, agent} = Agent.start(fn ->
Mariaex.Connection.start_link(database: "test", sync_connect: true)
end)
{:ok, mysql} = Agent.get(agent, fn mysql -> mysql end)
Agent.stop(agent) # あるいはAgentにコネクション入れっぱなしにして使い続ける?
IO.inspect Mariaex.Connection.query(mysql, "SHOW VARIABLES")
その場でエラーハンドリングできるし、変なところにもメッセージを投げない!
…しかし無理矢理感があるような…
識者の方がいたらぜひご教授いただきたいです。
(なんとなーくstart_linkでfailする設計がよくない気もするんですが、mariaexの場合、start_linkと接続処理が明示的に分かれてない。sync_connect: falseとやっても結局タイミングがあわないとpidをモニタリングする前に死ぬし)
