Heroku + MongoLab 環境に Casbah を使って MongoDB に接続する Play 2.0 で作成したアプリケーションをデプロイしようとしました。
それで Heroku 上で MONGOLAB_URI の設定値として提供される MongoDB の接続 URI を com.mongodb.casbah.MongoURI(com.mongodb.MongoURI)に食わせたらまったくもってでたらめなパースをするので自分でなんとかするコードを書きました。使い方は以下のコード内のコメント参照。MongoDB の接続 URI は conf/application.conf 内で mongodb.default.uri で設定するか、起動時に -D オプションで与えるようにしてください。
package mongodb import play.api._ import Play.current import com.mongodb.casbah.Imports._ /** * MongoDB をサクッと使うためのオブジェクトです。 */ object Mongo { /** * MongoDB 接続用 URI をパースするための正規表現 */ val uriPattern = "mongodb://(?:([^:^@]+)(?::([^@]+))?@)?([^:^/]+)(?::(\\d+))?/(.+)".r /** * MongoDB に接続されたブロックを提供します。 * 接続 URI は mongodb.default.uri の設定値を使用します。 * * 使い方の例 * {{{ * MongoDB.withDB { db => * db("employee").findAll().toSeq * } * }}} */ def withDB[A](f: MongoDB => A): A = withDB("default")(f) /** * MongoDB に接続されたブロックを提供します。 * * 使い方の例 * {{{ * MongoDB.withDB("mydb") { db => * db("employee").findAll().toSeq * } * }}} * * @param name 設定名 */ def withDB[A](name: String)(f: MongoDB => A): A = { // Play を使わない場合は↓このあたりを変えるといい val uri = Play.configuration.getString("mongodb." + name + ".uri").getOrElse("mongodb://localhost/test") // URI のパース val (usernameOpt, passwordOpt, host, portOpt, database) = parseURI(uri) // MongoDB に接続 val conn = portOpt map { port => MongoConnection(host, port.toInt) } getOrElse { MongoConnection(host) } try { // DB 取得 val db = conn(database) // 必要とあれば認証処理を行う (usernameOpt, passwordOpt) match { case (Some(username), Some(password)) => db.authenticate(username, password) case _ => } // 引数で指定された処理を実行 f(db) } finally { conn.close() } } /** * MongoDB 接続 URI をパースします。 */ def parseURI(uri: String) = { uri match { case uriPattern(username, password, host, port, database) => (Option(username), Option(password), host, Option(port), database) } } }