Skip to content

Instantly share code, notes, and snippets.

@sgrankin
Created August 23, 2017 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgrankin/b6fe659aacb93e57b4483dbfc1377e49 to your computer and use it in GitHub Desktop.
Save sgrankin/b6fe659aacb93e57b4483dbfc1377e49 to your computer and use it in GitHub Desktop.
// Alternate construction of tupled where in queries for quill for mysql 5.6
// WARNING: triggers O(n^2) behavior so is CPU intensive for N > 100
trait TupleQuery { self: io.getquill.context.Context[_, _] =>
/**
* Allows (x = c1 AND y = c2) OR (x = c3 AND y = c4) queries via `inTuples(tuples).apply(r.x, r.y)`
*/
def inTuples[T1: Encoder, T2: Encoder](tuples: Seq[(T1, T2)]): Quoted[(T1, T2) => Boolean] = {
tuples match {
case Seq() =>
quote { (v1: T1, v2: T2) =>
infix"false".as[Boolean]
}
case (v1, v2) +: Nil =>
quote { (t1: T1, t2: T2) =>
infix"($t1 = ${lift(v1)} AND $t2 = ${lift(v2)})".as[Boolean]
}
case _ =>
val (left, right) = tuples.splitAt(tuples.size / 2)
quote { (t1: T1, t2: T2) =>
infix"(${inTuples(left).apply(t1, t2)} OR ${inTuples(right).apply(t1, t2)})".as[Boolean]
}
}
}
def inTuples[T1: Encoder, T2: Encoder, T3: Encoder](
tuples: Seq[(T1, T2, T3)]): Quoted[(T1, T2, T3) => Boolean] = {
tuples match {
case Seq() =>
quote { (t1: T1, t2: T2, t3: T3) =>
infix"false".as[Boolean]
}
case (v1, v2, v3) +: Nil =>
quote { (t1: T1, t2: T2, t3: T3) =>
infix"($t1 = ${lift(v1)} AND $t2 = ${lift(v2)} AND $t3 = ${lift(v3)})".as[Boolean]
}
case _ =>
val (left, right) = tuples.splitAt(tuples.size / 2)
quote { (t1: T1, t2: T2, t3: T3) =>
infix"(${inTuples(left).apply(t1, t2, t3)} OR ${inTuples(right).apply(t1, t2, t3)})"
.as[Boolean]
}
}
}
def inTuples[T1: Encoder, T2: Encoder, T3: Encoder, T4: Encoder](
tuples: Seq[(T1, T2, T3, T4)]): Quoted[(T1, T2, T3, T4) => Boolean] = {
tuples match {
case Seq() =>
quote { (t1: T1, t2: T2, t3: T3, t4: T4) =>
infix"false".as[Boolean]
}
case (v1, v2, v3, v4) +: Nil =>
quote { (t1: T1, t2: T2, t3: T3, t4: T4) =>
infix"($t1 = ${lift(v1)} AND $t2 = ${lift(v2)} AND $t3 = ${lift(v3)} AND $t4 = ${lift(v4)})"
.as[Boolean]
}
case _ =>
val (left, right) = tuples.splitAt(tuples.size / 2)
quote { (t1: T1, t2: T2, t3: T3, t4: T4) =>
infix"(${inTuples(left).apply(t1, t2, t3, t4)} OR ${inTuples(right).apply(t1, t2, t3, t4)})"
.as[Boolean]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment