Skip to content

Instantly share code, notes, and snippets.

@kariyayo
Last active August 30, 2015 13:22
Show Gist options
  • Save kariyayo/d9c9d8bcbac8ff0f81d7 to your computer and use it in GitHub Desktop.
Save kariyayo/d9c9d8bcbac8ff0f81d7 to your computer and use it in GitHub Desktop.
Slickで素のSQLを使うときにマクロでちょっと楽をする ref: http://qiita.com/bati11/items/35ebf1af173afe43b8bf
case class User(id: Int, email: String, name: String, age: Option[Int], address: Option[String])
def selectUsers: DBIO[Seq[User]] = sql"""
SELECT
id,
email,
name,
age,
address
FROM
users
""".as[User]
implicit def getUserResult = GetResult { r=> User(r.nextInt, r.nextString, r.nextString, r.nextInt, r.nextString) }
implicit def getUserResult = GetResult { r => User(r.<<, r.<<, r.<<, r.<<, r.<<) }
implicit def getUserResult = GetResult { r => createObj[User](r) }
implicit def getUserResult = GetResult { createObj[User](_) }
package mymacros
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
import slick.jdbc.PositionedResult
object MyMacro {
// マクロを利用する側から呼び出すメソッド
def createObj[A](r: PositionedResult): A = macro createObjImpl[A]
// マクロの実装
def createObjImpl[A: c.WeakTypeTag](c: blackbox.Context)(r: c.Expr[PositionedResult]) = {
import c.universe._
// ケースクラス名のシンボルを取得
val caseClassSym: c.universe.Symbol = c.weakTypeOf[A].typeSymbol
if (!caseClassSym.isClass || !caseClassSym.asClass.isCaseClass) c.abort(c.enclosingPosition, s"$caseClassSym is not a case class")
// ケースクラスのフィールドを取得
val fields = caseClassSym.typeSignature.decls.filter {
case x: TermSymbol => x.isVal && x.isCaseAccessor
case _ => false
}
// rr.<<, rr.<<・・・
val params = fields.map(_ => q"rr.<<")
// User(r.<<, r.<< ・・・) っていうコード
val code = q"""
val rr = $r
${caseClassSym.name.toTermName}(..$params)
"""
code
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment