先日からblocking-slickというSlick3にSlick2風のブロッキングAPIを追加するライブラリを作っています。
基本的にはQuery
オブジェクトにimplicit conversionで同期実行用のメソッドを生やすという方式で実装していたのですが、更新系のメソッドがSlick3のDBIO生成用のメソッドとの衝突してしまったため、当初衝突を避けるため別のメソッド名にしていました。これによってDBIO生成用のメソッドとブロッキング用のメソッドを利用者側で使い分ける必要があり、間違えてしまう危険がありました。
そこでインポートするAPIを丸ごと別のものにしてしまうことでDBIO生成用のメソッドを無効にし、メソッド名の衝突が起こらないようにしました。また、ブロッキング用のドライバも予め提供するようにしたので自分でブロッキング用のプロファイルをミックスインしたドライバを定義する必要はなくなりました。
import com.github.takezoe.slick.blocking.BlockingH2Driver._ import com.github.takezoe.slick.blocking.BlockingH2Driver.blockingApi._ db.withSession { implicit session => // Insert Users.insert(UsersRow(1, "takezoe")) // Update Users.filter(t => t.id === 1.bind).update(UsersRow(1, "naoki")) // Delete Users.filter(t => t.id === 1.bind).delete }
一部Future
をawaitすることで誤魔化している部分はあったりしますが、Plain SQL用のString Interpolationやreturningも含め基本的なメソッドは概ねカバーできています。
これを使ってGitBucketをSlick3に移行してみたところ、以下のように非常に少ない修正で移行することができました。
インポート文や一部のDSLが変わっていますが、使い勝手はSlick2とほぼ変わりません。これなら最小限のコストでSlick3でのクエリコンパイラの改善のメリットを享受できるのではないのでしょうか。