読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

Play Framework2.0 いじってみる。

日記 scala Playframework

https://github.com/playframework/Play20/wiki

このへんのチュートリアルに沿ってインストールはできると。
SBT ベースになってるので、そのままいけるかなーと思ったけど、コレが案外ハマった。

まず、SBT-Idea突っ込もうとして、「project/plugins.sbt」に

resolvers ++= Seq(
    DefaultMavenRepository,
    Resolver.url("Play", url("http://download.playframework.org/ivy-releases/"))(Resolver.ivyStylePatterns),
    "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
    "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"
)

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "0.11.0")

libraryDependencies ++= Seq("play" %% "play" % "2.0-beta")

としたまでは良かった。
問題は、依存ライブラリの設定だった。
ここで libraryDependencies にいくら設定しても入らない謎現象に悩まされた。というか、書くと本来取って欲しいURLとは違うURL参照して、依存を解決できないとかビルドエラーを起こす。
結果から言うと、「project/Build.scala」に書くのが正しいらしく、

    val appDependencies = Seq(
      // Add your project dependencies here,
      "postgresql" % "postgresql" % "9.0-801.jdbc4",
      "org.squeryl" %% "squeryl" % "0.9.5-RC1"
    )

と書いて何とか入った。SBTの仕様なのか、、、、よくわからん。

後、使い慣れた squeryl 使いたい。
極論言ってしまえば、java.sql.Connection インスタンスさえ引っこ抜ければSquerylでも全く問題なく使える。 http://www.7sudos.com/blog/scalatra-mysql-and-star-wars-droids
PlayFramework2.0 のデフォルトDBライブラリは scalaquery で、「play.api.db.DB」で設定の読み込み→コネクションの取得までやっている。

https://github.com/playframework/Play20/tree/master/framework/src/play/src/main/scala/play/api/db

でソースを眺めると、DB.getConnection で拾ってこれそう。
なので、Squeryl 的にはコネクションプールから拾ってくる感覚でコレ呼べばいいのかなってコトで、

package models

import play.api.db.DB
import play.api.Play.current
import org.squeryl.{Session => SqSession}
import org.squeryl.SessionFactory
import org.squeryl.adapters.PostgreSqlAdapter

trait DatabaseInitializer {
  def initDatabase = {
    SessionFactory.concreteFactory = Some(() => connection)

    def connection = {
      SqSession.create(DB.getConnection(autocommit = false), new PostgreSqlAdapter)
    }
  }
}

trait ConnectionSupport {
  def withConnection[T](f: => T):T = {
    val session = SqSession.currentSession
    session.bindToCurrentThread
    try {
      f
    } finally {
      session.close
      session.unbindFromCurrentThread
    }
  }
}

アダプタのインスタンスは設定引っこ抜いて作れば動的にできる(と思う)けど、今作ってるクランサイトは Postgresql オンリーなのでコレでいいやと放置。
なにげに「import play.api.Play.current」忘れると動かないので注意が必要。
てーか initDatabase はコントローラオブジェクトで必ず呼ぶんだから、Controller 継承して $init$ でやっとけって話かもしれない。