= Circumflex ORM = == 参考 == * [[http://circumflex.ru/projects/orm/index.html|本家]] * [[http://circumflex.ru/docs/orm/assembly.html|本家ドキュメント]] '''※ひどいことに、mavenリポジトリにあるもの(2011/10時点)は、おそらくScala2.8用。2.9で動作させるとNoSuchMethodException等が発生するので注意。''' == 評価 == === 良い点 === * タイプセーフに(中途半端ではあるが)こだわっている。普通ならどうやってもなりようがないSQLをかなりタイプセーフなものに仕立て上げている。正解かどうかはおいておいても、この点は他のORMと一線を画している。 * コード量が非常に小さく、とりまわしが楽。 * 様々なRDBの方言に対応可能なようだ、コードを書けば。 === 悪い点 === * circumflexというウェブフレームワークを前提としており、「一つのデータベース」しか扱うことができない(この点はPlay Frameworkのanormとも全く同じ)。複数のデータベースを切り替えたり、同時に使用したりすることは不可能。つまり、そこから切り離して「一般的なORM」として使うのはそのままではできず、改造が必要になる。なぜなら、ウェブフレームワークの起動時に与えられたデータベース接続定義をあらゆるところから「静的に」参照しているから。 == とにかく動かしてみる == Circumflex ORMはCircumflexというウェブフレームワークの一部だが、ここでは単体で使用する。 DBはH2を用いた。 === テーブルの定義とデータベース生成 === Country, Cityはサンプルそのまま {{{ import ru.circumflex._ import ru.circumflex.orm._ import ru.circumflex.core._ class Country extends Record[String, Country] { val code = "code".VARCHAR(2).NOT_NULL.DEFAULT("'ch'") val name = "name".TEXT.NOT_NULL def cities = inverseMany(City.country) def relation = Country def PRIMARY_KEY = code } object Country extends Country with Table[String, Country] class City extends Record[Long, City] with SequenceGenerator[Long, City] { val id = "id".BIGINT.NOT_NULL.AUTO_INCREMENT val name = "name".TEXT val country = "country_code".TEXT.NOT_NULL .REFERENCES(Country) .ON_DELETE(CASCADE) .ON_UPDATE(CASCADE) def relation = City def PRIMARY_KEY = id } object City extends City with Table[Long, City] object Creation { def main(args: Array[String]) { val cx = Circumflex cx("orm.connection.driver") = "org.h2.Driver" cx("orm.connection.url") = "jdbc:h2:sample" cx("orm.connection.username") = "sa" cx("orm.connection.password") = "" val unit = new DDLUnit(Country, City) unit.CREATE() } } }}} どんなDDLが生成されているのか? {{{ println(Country.sqlCreate) println(City.sqlCreate) }}} === レコードの挿入 === {{{ val country = new Country country.code := "jp" country.name := "japan" try { country.INSERT_!() COMMIT() } catch { case e:Exception => { e.printStackTrace(); } } }}} == バグ == git上では修正されているが、バイナリリリースはされていない(2011/10/24) dialect.scalaの207行目付近 {{{ def columnDefinition[R <: Record[_, R]](field: Field[_, R]): String = { var result = field.name + " " + field.sqlType if (field.notNull_?) result += " NOT NULL" if (field.unique_?) result += " UNIQUE" // <-- これが抜けてる result += defaultExpression(field) return result } }}} == ドキュメント翻訳 == - [[Circumflex_ORM/Manual|本家ドキュメント翻訳]]