Skip to content

Instantly share code, notes, and snippets.

@jto
Last active January 28, 2016 16:03
Show Gist options
  • Save jto/e0b8233ad1eded3a26e9 to your computer and use it in GitHub Desktop.
Save jto/e0b8233ad1eded3a26e9 to your computer and use it in GitHub Desktop.
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)))
}
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)) }
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)
}
}
def someDbCall(implicit ctx: DBExeCtx): Future[TestResult] = // execute a SQL query
val parser =
(
get[String]("firstname") ~
get[String]("lastname") ~
get[Int]("age")
).map{ case firstname ~ lastname ~ age =>
UntypedUser(firstname, lastname, age)
}
def getUser(id: User.Id): Option[User]
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)
}
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)
}
import Contexts._, Implicits._
for {
result <- test()
} yield result
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)
}
}
val gen = Generic[UntypedUser]
val parser =
(
get[String]("firstname") ~
get[String]("lastname") ~
get[Int]("age")
).map{ u => gen.from(ToHList(u)) }
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)) }
case class UntypedUser(lastname: String, firstname: String, age: Int)
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
}
object User {
def all(): List[(Long, User)] = ???
}
object User {
def all(): List[(User.Id, User)] = ???
}
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