Skip to content

Instantly share code, notes, and snippets.

@gigiigig
Created November 12, 2015 15:50
Show Gist options
  • Save gigiigig/0bab2fb35f7b494cc673 to your computer and use it in GitHub Desktop.
Save gigiigig/0bab2fb35f7b494cc673 to your computer and use it in GitHub Desktop.
import shapeless._
import shapeless.record._
import shapeless.ops.record._
import shapeless.ops.hlist._
object console extends App {
object sql {
trait ToSql[T] {
def toSql(t: T): String
}
implicit class ToSqlOps[T](t: T) {
def toSql(implicit ts: ToSql[T]): String = ts.toSql(t)
}
object ToSql {
def mk[T](f: T => String): ToSql[T] = new ToSql[T] { def toSql(t: T) = f(t) }
object toSql extends Poly1 {
implicit def default[T](implicit T: ToSql[T]) = at[T](t => T.toSql(t))
}
implicit def optToSql[T](implicit st: ToSql[T]): ToSql[Option[T]] = mk[Option[T]](_.fold("NULL")(_.toSql))
implicit val stToSql: ToSql[String] = mk[String](s => s"'${s.replace("'", "''").replace("\\", "\\\\")}'")
implicit def anyValToSql[T <: AnyVal]: ToSql[T] = mk[T](_.toString)
implicit def productToSql[P, R <: HList, VS <: HList, MP <: HList](
implicit lg: LabelledGeneric.Aux[P, R],
vs: Values.Aux[R, VS],
mp: Mapper.Aux[toSql.type, VS, MP],
tt: ToTraversable.Aux[MP, List, String]): ToSql[P] =
mk[P] { pr =>
val repr = lg.to(pr).values
val ls: List[String] = repr.map(toSql).toList
ls.mkString("(", ",", ")")
}
}
}
import sql._
def foo[T](t: T)(implicit tsql: ToSql[T]) = tsql.toSql(t)
case class Foo(i: Int, s: String)
val res = foo(Foo(1, "ciao"))
println(s"res: ${res}")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment