RDBMSにOracleを利用している時にCRUDify(list)が動かない

Liftの CRUDify はコーディングをほとんどせずに、CRUD機能を提供してくれる、とても便利な機構です。Ruby On Rails(/AR)のscaffoldみたいな。

で、OracleRDBMSとしているときに、CRUDifyの"List"機能がまったく動いてくれない、と思って四苦八苦していたのです。こんな例外が出ます。

Message: java.sql.SQLException: ORA-00933: SQLコマンドが正しく終了されていません。

で、どんなSQLが出来ているか、など追いかけていたら、どうやら LiftMapperの MetaMapperクラスの以下のメソッドが原因の様子

  def addEndStuffs(in: String, params: List[QueryParam[A]], conn: SuperConnection): (String, Box[Long], Box[Long]) = {
(略)
      val ret = (max, start) match {
        case (Full(max), Full(start)) => tmp + " LIMIT "+max+" OFFSET "+start
        case (Full(max), _) => tmp + " LIMIT "+max
        case (_, Full(start)) => tmp + " LIMIT "+conn.driverType.maxSelectLimit+" OFFSET "+start
        case _ => tmp
      }
(略)

ご覧のとおり、で、LIMIT句とOFFSET句が使われており、私が使っているRDBMS(Oracle10g)ではこの構文がサポートされていません。そりゃエラーにもなります。

こういうRDBMSのDialectを吸収する仕掛けにはまだなっていないようで、残念ながら現在のLiftMapperで、addEndStuffsを使って件数制限やページングのようなことをしている箇所は使えない、ということになりそうです。

ああ、CRUDify使いたい…

ただ、 たとえば

  with MetaMapperなんとか { override def addEndStuffs..

とかするのは、あまりにやっつけというか、設計的にはあまり美しくないように思います。どうしても使いたいなら仕方ないのですが、どうしたもんかなあ、などと考える。

OracleDialect、みたいな感じでうまく委譲されていればいいのでしょうが、いまのところそうはなっていない様子。