Skip to content

Commit

Permalink
Merge pull request #5 from tarao/pluggable-placeholders
Browse files Browse the repository at this point in the history
Make placeholders pluggable.
  • Loading branch information
tarao committed Jul 20, 2016
2 parents bdfb580 + dbaac7c commit 6170fb3
Show file tree
Hide file tree
Showing 7 changed files with 859 additions and 57 deletions.
Expand Up @@ -27,28 +27,3 @@ class SimpleString(value: String) extends Literal {
override def toString = value
}
case class TableName(name: String) extends SimpleString(name)

class Placeholders(val value: Any, val topLevel: Boolean = true)
extends Literal {
def toCompleteString: String = {
def rec(v: Any) = new Placeholders(v, false).toString
val (single, elements) = value match {
case s: Tuple1[_] => (false, Iterator.single(rec(s._1)))
case p: Product if p.productArity <= 0 =>
throw new java.sql.SQLException("No value to bind for " + p)
case p: Product => (p.productArity == 1, p.productIterator.map(rec))
case l: NonEmpty[_] => (false, l.toSeq.map(rec))
case _ => (true, Iterator.single(new Placeholders(this, false) {
override def toCompleteString: String = "?"
}.toString) )
}
if (single) elements.toSeq.head
else s"""(${stripParen(elements.mkString(", "))})"""
}
private def stripParen(str: String) = str.stripPrefix("(").stripSuffix(")")
private def dropLast(str: String) = str.stripSuffix("?")
override def toString = {
val s = toCompleteString
if (topLevel) dropLast(stripParen(s)) else s
}
}
Expand Up @@ -42,6 +42,10 @@ private[interpolation] class MacroTreeBuilder(val c: Context) {
tq"""$interpolation.${TypeName("CheckOption")}"""
private def checkParameter(required: Type, base: Tree = CheckParameter) =
q"implicitly[$base[$required]]"
private val ToPlaceholder =
tq"""$interpolation.${TypeName("ToPlaceholder")}"""
private def toPlaceholder(target: Type, base: Tree = ToPlaceholder) =
q"implicitly[$base[$target]]"
private val Translators =
tq"Traversable[$NS.query.Translator]"

Expand Down Expand Up @@ -119,7 +123,11 @@ private[interpolation] class MacroTreeBuilder(val c: Context) {

mayCompleteParen(param, s) {
// for "?, ?, ?, ..."
params.append(c.Expr(q"new $interpolation.Placeholders(${param})"))
params.append(c.Expr(q"""
${toPlaceholder(param.actualType)}
.apply(${param})
.toTopLevelString
"""))
queryParts.append(q""" ${"#"} """)
// for the last "?" (inserted by ActionBasedSQLInterpolation)
params.append(param)
Expand Down
@@ -0,0 +1,27 @@
package com.github.tarao
package slickjdbc
package interpolation

class Placeholder extends Literal {
import Placeholder.{stripParen, dropLast}
def toSeq: Seq[Placeholder] = Seq(this)
def toTopLevelString: String = dropLast(stripParen(toString))
override def toString: String = "?"
}
object Placeholder {
private def stripParen(str: String) = str.stripPrefix("(").stripSuffix(")")
private def dropLast(str: String) = str.stripSuffix("?")

def apply(): Placeholder = new Placeholder
def repeat(n: Int): Seq[Placeholder] = (1 to n).map(_ => apply())

class Nested(children: Placeholder*) extends Placeholder {
override def toSeq: Seq[Placeholder] = children
override def toString: String =
s"""(${stripParen(children.map(_.toString).mkString(", "))})"""
}
object Nested {
def apply(children: Placeholder*): Nested = new Nested(children: _*)
def apply(n: Int): Nested = new Nested(Placeholder.repeat(n): _*)
}
}
Expand Up @@ -7,14 +7,23 @@ import scala.annotation.implicitNotFound
import slick.jdbc.{SetParameter => SP, PositionedParameters}

trait CompoundParameter {
implicit def createSetProduct[T](implicit
@inline implicit def createSetProduct[T](implicit
check1: T <:< Product,
check2: IsNotTuple[T]
): SP[T] = new SetProduct[T]

@inline implicit
def createSetList[T](implicit c: SP[T]): SetList[T, NonEmpty[T]] =
new SetList[T, NonEmpty[T]](c)
@inline implicit def createSetList[T](implicit
c: SP[T]
): SP[NonEmpty[T]] = new SetList[T, NonEmpty[T]](c)

@inline implicit def productToPlaceholder[T](implicit
check1: T <:< Product,
check2: IsNotTuple[T]
): ToPlaceholder[T] = new ToPlaceholder.FromProduct[T]

@inline implicit def listToPlaceholder[T](implicit
p: ToPlaceholder[T]
): ToPlaceholder[NonEmpty[T]] = new ToPlaceholder.FromList[T, NonEmpty[T]](p)
}
object CompoundParameter extends CompoundParameter

Expand Down

0 comments on commit 6170fb3

Please sign in to comment.