Skip to content

Commit

Permalink
[apoc] Support apoc.do.case call.
Browse files Browse the repository at this point in the history
  • Loading branch information
fehu committed Jun 19, 2020
1 parent 476f20f commit 1b3725a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ object APOC {

object `case` extends ProductArgs {
def applyProduct[Cases <: HList](cases: Cases)(implicit b: Case.Builder[Cases]): Case.OtherwiseSyntax[b.Params, b.Out] =
new Case.OtherwiseSyntax(b.toList(cases))
new Case.OtherwiseSyntax(b.toList(cases), write = false)

def writeProduct[Cases <: HList](cases: Cases)(implicit b: Case.Builder[Cases]): Case.OtherwiseSyntax[b.Params, b.Out] =
new Case.OtherwiseSyntax(b.toList(cases), write = true)
}

def assertNot[R](pred: Expr[Boolean], msg: Expr[String], msgParams: Expr[Any]*)(res: Query[R]): Query[R] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,29 @@ object Case {
implicit def impl[A]: Case.Aux[A, Expr[A]] = null
}

protected[cypher] class OtherwiseSyntax[CasesParams <: HList, A](cases: List[Case[_, A]]) {
protected[cypher] class OtherwiseSyntax[CasesParams <: HList, A](cases: List[Case[_, A]], write: Boolean) {
def otherwise[OtherwiseParams <: HList, AllParams <: HList, ParamExprs <: HList]
(default: ParameterizedCypherQuery[OtherwiseParams, A])
(implicit mergeParams: ops.record.Merger.Aux[CasesParams, OtherwiseParams, AllParams],
paramsExprs: ops.record.MapValues.Aux[WrapCypherExprPoly.type, AllParams, ParamExprs],
paramsToMap: ops.record.ToMap.Aux[ParamExprs, _ <: Symbol, _ <: Expr[_]]
): ParamsSyntax[ParamExprs, A] = new ParamsSyntax(cases, default)
): ParamsSyntax[ParamExprs, A] = new ParamsSyntax(cases, default, write)
}

protected[cypher] class ParamsSyntax[ParamExprs <: HList, A]
(cases: Seq[Case[_, A]], default: ParameterizedCypherQuery[_, A])
(cases: Seq[Case[_, A]], default: ParameterizedCypherQuery[_, A], write: Boolean)
(implicit toMap: ops.record.ToMap.Aux[ParamExprs, _ <: Symbol, _ <: Expr[_]]) extends RecordArgs {
def withParamsRecord(params: ParamExprs): QuerySyntax[A] =
new QuerySyntax(cases, default, toMap(params).map{ case (k, v) => k.name -> v })
new QuerySyntax(cases, default, toMap(params).map{ case (k, v) => k.name -> v }, write)
}

protected[cypher] class QuerySyntax[A](
protected val cases0: Seq[Case[_, A]],
protected val default: ParameterizedCypherQuery[_, A],
protected val params: Map[String, Expr[_]]
protected val params: Map[String, Expr[_]],
protected val write: Boolean
) {
private def procedure = if (write) "apoc.do.case" else "apoc.case"
private val cases = cases0.flatMap(c => c.condition :: lit(c.query.statement.template) :: Nil)

def withOneColumn[R](f: Expr[A] => Query[R]): Query[R] =
Expand All @@ -98,7 +100,7 @@ object Case {
}

def withAllColumns[R](f: Expr[Map[String, Any]] => Query[R]): Query[R] =
Call("apoc.case",
Call(procedure,
list(cases: _*), // [cond, query, ...]
lit(default.statement.template), // else
dict(params) // params
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,24 @@ class ApocSyntaxSpec extends CypherSyntaxBaseSpec {
"RETURN `replace`(\"Result: %n\", \"%n\", `toString`(`v1`))"
).returns[String]

"support `apoc.do.case` call" in test(
APOC.`case`.write(
lit(true) -> parameterized { () => `return`[Int](lit(123)) }
).otherwise(parameterized { () => `return`[Int](lit(321)) })
.withParams()
.withOneColumn( res =>
lit("Result: %n").replace(lit("%n"), res.asString)
),
"CALL `apoc`.`do`.`case`(" +
"[" +
"true, \"RETURN 123\"" +
"], " +
"\"RETURN 321\", " +
"{ }) " +
"YIELD `value` AS `yielded0` " +
"WITH *, `yielded0`[`head`(`keys`(`yielded0`))] AS `v0` " +
"RETURN `replace`(\"Result: %n\", \"%n\", `toString`(`v0`))"
).returns[String]

}
}

0 comments on commit 1b3725a

Please sign in to comment.