Last active
January 28, 2016 16:03
-
-
Save jto/e0b8233ad1eded3a26e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ColumnDerivations { | |
import shapeless.Generic | |
import shapeless.{ ::, HList, HNil } | |
implicit def hlistColumn[H](implicit c: Column[H]): Column[H :: HNil] = | |
Column(c(_, _).map(_ :: HNil)) | |
implicit def anyvalDerivation[N <: AnyVal, H <: HList](implicit gen: Generic.Aux[N, H], c: Column[H]): Column[N] = | |
Column(c(_, _).map(r => gen.from(r))) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import User._ | |
import shapeless.Generic | |
import ColumnDerivations._ | |
val gen = Generic[User] | |
val parser = | |
( | |
get[LastName]("lastname") ~ | |
get[FirstName]("firstname") ~ | |
get[Age]("age") | |
).map{ u => gen.from(ToHlist(u)) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.concurrent.ExecutionContext | |
import play.api.libs.concurrent.Akka | |
object Contexts { | |
case class DBExeCtx(val underlying: ExecutionContext) extends AnyVal | |
case class DefaultExeCtx(val underlying: ExecutionContext) extends AnyVal | |
implicit def dbToEC(implicit ec: DBExeCtx) = ec.underlying | |
implicit def defaultToEC(implicit ec: DefaultExeCtx) = ec.underlying | |
object Implicits { | |
implicit val dbCtx = DBExeCtx(Akka.system.dispatchers.lookup("contexts.db-context")) | |
implicit val defaultCtx = DefaultExeCtx(play.api.libs.concurrent.Execution.defaultContext) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def someDbCall(implicit ctx: DBExeCtx): Future[TestResult] = // execute a SQL query |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val parser = | |
( | |
get[String]("firstname") ~ | |
get[String]("lastname") ~ | |
get[Int]("age") | |
).map{ case firstname ~ lastname ~ age => | |
UntypedUser(firstname, lastname, age) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def getUser(id: User.Id): Option[User] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val gen = Generic[UserWithFavoriteSongs] | |
val parser = | |
( | |
get[Id]("id") ~ | |
get[LastName]("lastname") ~ | |
get[FirstName]("firstname") ~ | |
get[Age]("age") ~ | |
get[Song]("song") | |
).map(a => ToHlist(a)) | |
import scalaz.syntax.std.list._ | |
val users: List[UserWithFavoriteSongs] = | |
SQL""" | |
SELECT * FROM USER u | |
LEFT JOIN SONGS s ON u.id = s.user_id | |
""".as(parser *) | |
.groupWhen(_.select[Id] == _.select[Id]) | |
.map { byUser => | |
val user = byUser.head.tail.init | |
val songs = byUser.map(_.select[Song]).list.toList | |
gen.from(user :+ songs) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val parser = | |
get[Id]("id") ~ | |
get[LastName]("lastname") ~ | |
get[FirstName]("firstname") ~ | |
get[Age]("age") ~ | |
get[Song]("song") | |
import scalaz.syntax.std.list._ | |
val users: List[UserWithFavoriteSongs] = | |
SQL""" | |
SELECT * FROM USER u | |
LEFT JOIN SONGS s ON u.id = s.user_id | |
""".as(parser *) | |
.groupWhen{ (u1, u2) => | |
val id1 ~ _ ~ _ ~ _ ~ _ ~ _ = u1 | |
val id2 ~ _ ~ _ ~ _ ~ _ ~ _ = u2 | |
id1 == id2 | |
}.map { byUser => | |
val _ ~ lastname ~ firstname ~ age ~ _ = byUser.head | |
val songs = | |
byUser.map { case _ ~ _ ~ _ ~ _ ~ song => | |
song | |
}.list.toList | |
UserWithFavoriteSongs(lastname, firstname, age, songs) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Contexts._, Implicits._ | |
for { | |
result <- test() | |
} yield result |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless.{ ::, HList, HNil } | |
import shapeless.ops.hlist._ | |
import anorm._, SqlParser._ | |
trait ToHlist[S] { | |
type Out <: HList | |
def apply(s: S): Out | |
} | |
trait LowPriorityToHlist { | |
implicit def toHlist0[A, B] = new ToHlist[A ~ B] { | |
type Out = A :: B :: HNil | |
def apply(s: A ~ B): Out = s._1 :: s._2 :: HNil | |
} | |
} | |
object ToHlist extends LowPriorityToHlist { | |
type Aux[A, O] = ToHlist[A] { type Out = O } | |
def apply[A, B](p: A ~ B)(implicit u: ToHlist[A ~ B]) = u(p) | |
implicit def toHlistN[A, B, O <: HList](implicit u: ToHlist.Aux[A, O], p: Prepend[O, B :: HNil]) = new ToHlist[A ~ B] { | |
type Out = p.Out | |
def apply(s: A ~ B): Out = p(u(s._1), s._2 :: HNil) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val gen = Generic[UntypedUser] | |
val parser = | |
( | |
get[String]("firstname") ~ | |
get[String]("lastname") ~ | |
get[Int]("age") | |
).map{ u => gen.from(ToHList(u)) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import User._ | |
import shapeless.Generic | |
implicit val firstNameColumn: Column[FirstName] = ??? | |
implicit val lastNameColumn: Column[LastName] = ??? | |
implicit val ageNameColumn: Column[Age] = ??? | |
val gen = Generic[User] | |
val parser = | |
( | |
get[LastName]("lastname") ~ | |
get[FirstName]("firstname") ~ | |
get[Age]("age") | |
).map{ u => gen.from(ToHlist(u)) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class UntypedUser(lastname: String, firstname: String, age: Int) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class User(lastname: User.LastName, firstname: User.FirstName, age: User.Age) | |
object User { | |
case class Id(value: Long) extends AnyVal | |
case class FirstName(value: String) extends AnyVal | |
case class LastName(value: String) extends AnyVal | |
case class Age(value: Int) extends AnyVal | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object User { | |
def all(): List[(Long, User)] = ??? | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object User { | |
def all(): List[(User.Id, User)] = ??? | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UserWithFavoriteSongs._ | |
case class UserWithFavoriteSongs(lastname: LastName, firstname: FirstName, age: Age, songs: List[Song]) | |
object UserWithFavoriteSongs { | |
case class Id(value: Long) extends AnyVal | |
case class FirstName(value: String) extends AnyVal | |
case class LastName(value: String) extends AnyVal | |
case class Age(value: Int) extends AnyVal | |
case class Song(value: String) extends AnyVal | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment