Hatena::ブログ(Diary)

falsusのアウトプット日記

2011-06-13

ScalaでどうしてもSQLっぽく書きたかった

反省はしていない。
falsus/mysqala ? GitHub
Scalaの勉強用に極力MySQLっぽくScalaの通常の機構のみでかけないかをやってみた。
あとでサンプルコード貼ります

create table users(id int primary key, name varchar(255));

って言うテーブルがある場合


class User(val id: Int, val name: String) {
}

class Users(connManager: ConnectionManager) extends Table[User](connManager) {
  val id = getIntColumn("id")
  val name = getStringColumn("name")

  def print(offset: Int, max: Int) {
    val query = select (id, name) from this limit max offset offset

    query.execute(_(0) match { case u: User => println(u.id + ":" + u.name) })
  }

  def find(id_ : Int) = {
    val query = select this.* from this where id == id_
    var user: Option[User] = None

    query.execute(_(0) match { case u: User => user = u })
    user
  }
}


こんな感じになる。executeの中の一つを返すコードがきったないなあ。

O/Rマッパーとしての使い勝手を考慮していないし、リフレクションそのまま使っててパフォーマンスも気にしていない。
英語力が皆無なためgithubに上記言い訳を書くことすらできない。

結果としてわかったのは以下のような結果だった。

  • 可変長引数を受け取るSELECT等の場合は()を付けないと無理
  • ORDER BYのようなパラメーター0で()無しで関数をチェインできない
  • INSERT INTOのようにレシーバーからスタートする場合は引数0個でも行ける
  • =演算子は書き換えられるけどUnit

まだScala勉強中の身なので、こうすればもっとSQLっぽくかけるよ!とか、Scalaっぽく書くにはこうだよ!と言ったご意見を頂けるとありがたいです。

kmizushimakmizushima 2011/12/22 21:30 SQLっぽく書けるScala用O/Rマッパーですと、
Squeryl http://squeryl.org/ なんてのがあります。サンプルコード
見るとわかりますが、割とSQL Likeにかけます。

falsusfalsus 2011/12/23 15:30 ありがとうございます。
Squerylはこのコード書いてしばらくしてから被ってるものがあったことを知ってしょんぼりしたのですが、サンプルコードをみたらSQLっぽさよりも使い勝手を重視しているようで(ライブラリとしては当たり前なんですが)、もうちょっと足りないなあと言う気持ちになりました。
自作のほうで==を使ってる所が気持ち悪かったのですが、Squerylにあるような演算子を使えば良いことが分かったり、Scalaもある程度覚えてきたのでもう少しScalaとして健全な形に書き換えてみようかと思います。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/falsus/20110613/1307981971