Skip to content

Instantly share code, notes, and snippets.

@sgrankin
Created August 23, 2017 14:20
Show Gist options
  • Save sgrankin/1862c194c6544be10dceb4b19a1259f3 to your computer and use it in GitHub Desktop.
Save sgrankin/1862c194c6544be10dceb4b19a1259f3 to your computer and use it in GitHub Desktop.
// WARNING: mysql versions before 5.7.3 do not properly use index lookups for this construction.
trait TupleQuery { self: io.getquill.context.Context[_, _] =>
/**
* Allows `where (x, y) in ((c1, c2))` queries via `liftTuples(tuples).contains((p.name, p.age))`
* See https://github.com/getquill/quill/issues/651
*/
def liftTuples[T1: Encoder, T2: Encoder](
tuples: Seq[(T1, T2)]
): Quoted[Query[(T1, T2)]] =
liftTuplesRec(2, tuples, (t: (T1, T2)) => infix"(${lift(t._1)}, ${lift(t._2)})")
def liftTuples[T1: Encoder, T2: Encoder, T3: Encoder](
tuples: Seq[(T1, T2, T3)]
): Quoted[Query[(T1, T2, T3)]] =
liftTuplesRec(
3,
tuples,
(t: (T1, T2, T3)) => infix"(${lift(t._1)}, ${lift(t._2)}, ${lift(t._3)})")
def liftTuples[T1: Encoder, T2: Encoder, T3: Encoder, T4: Encoder](
tuples: Seq[(T1, T2, T3, T4)]
): Quoted[Query[(T1, T2, T3, T4)]] =
liftTuplesRec(
4,
tuples,
(t: (T1, T2, T3, T4)) => infix"(${lift(t._1)}, ${lift(t._2)}, ${lift(t._3)}, ${lift(t._4)})")
private def liftTuplesRec[T, U](arity: Int, l: Seq[T], f: T => Quoted[Any]): Quoted[Query[U]] = {
l match {
case Seq() if arity == 2 =>
infix"SELECT NULL, NULL FROM DUAL WHERE FALSE".as[Query[U]]
case Seq() if arity == 3 =>
infix"SELECT NULL, NULL, NULL FROM DUAL WHERE FALSE".as[Query[U]]
case Seq() if arity == 4 =>
infix"SELECT NULL, NULL, NULL, NULL FROM DUAL WHERE FALSE".as[Query[U]]
case Seq(head) => infix"${f(head)}".as[Query[U]]
case head +: tail =>
infix"${f(head)}, ${liftTuplesRec(arity, tail, f)}".as[Query[U]]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment