try implement context
This commit is contained in:
parent
6be96aba2c
commit
87f1b70b27
4 changed files with 71 additions and 18 deletions
|
@ -385,8 +385,9 @@ case class ScalarValueLift(
|
||||||
|
|
||||||
case class ScalarQueryLift(
|
case class ScalarQueryLift(
|
||||||
name: String,
|
name: String,
|
||||||
liftId: String
|
liftId: String,
|
||||||
) extends ScalarLift {}
|
value: Option[(Seq[Any], ParamEncoder[?])]
|
||||||
|
) extends ScalarLift
|
||||||
|
|
||||||
object ScalarLift {
|
object ScalarLift {
|
||||||
given ToExpr[ScalarLift] with {
|
given ToExpr[ScalarLift] with {
|
||||||
|
|
|
@ -4,9 +4,10 @@ import scala.deriving.*
|
||||||
import scala.compiletime.*
|
import scala.compiletime.*
|
||||||
import scala.util.Try
|
import scala.util.Try
|
||||||
import minisql.util.*
|
import minisql.util.*
|
||||||
import minisql.idiom.{Idiom, Statement}
|
import minisql.idiom.{Idiom, Statement, ReifyStatement}
|
||||||
import minisql.{NamingStrategy, ParamEncoder}
|
import minisql.{NamingStrategy, ParamEncoder}
|
||||||
import minisql.ColumnDecoder
|
import minisql.ColumnDecoder
|
||||||
|
import minisql.ast.{Ast, ScalarValueLift, CollectAst}
|
||||||
|
|
||||||
trait Context[I <: Idiom, N <: NamingStrategy] { selft =>
|
trait Context[I <: Idiom, N <: NamingStrategy] { selft =>
|
||||||
|
|
||||||
|
@ -50,21 +51,40 @@ trait Context[I <: Idiom, N <: NamingStrategy] { selft =>
|
||||||
|
|
||||||
type Decoder[X] = ColumnDecoder.Aux[DBRow, X]
|
type Decoder[X] = ColumnDecoder.Aux[DBRow, X]
|
||||||
|
|
||||||
type DBIO[X] = (
|
type DBIO[E] = (
|
||||||
statement: Statement,
|
sql: String,
|
||||||
params: (Any, Encoder[?]),
|
params: List[(Any, Encoder[?])],
|
||||||
extract: RowExtract[X]
|
mapper: Iterable[DBRow] => Try[E]
|
||||||
)
|
)
|
||||||
|
|
||||||
extension (ast: Ast) {
|
extension (ast: Ast) {
|
||||||
extractParams
|
private def liftMap = {
|
||||||
|
val lifts = CollectAst.byType[ScalarValueLift](ast)
|
||||||
|
lifts.map(l => l.liftId -> l.value.get).toMap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension (stmt: Statement) {
|
||||||
|
def expand(liftMap: Map[String, (Any, ParamEncoder[?])]) =
|
||||||
|
ReifyStatement(
|
||||||
|
idiom.liftingPlaceholder,
|
||||||
|
idiom.emptySetContainsToken,
|
||||||
|
stmt,
|
||||||
|
liftMap
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline def io[E](
|
inline def io[E](
|
||||||
inline q: minisql.Query[E]
|
inline q: minisql.Query[E]
|
||||||
)(using r: RowExtract[E]): DBIO[Seq[E]] = {
|
)(using r: RowExtract[E]): DBIO[IArray[E]] = {
|
||||||
val statement = minisql.compile(q, idiom, naming)
|
val lifts = q.liftMap
|
||||||
???
|
val stmt = minisql.compile(q, idiom, naming)
|
||||||
|
val (sql, params) = stmt.expand(lifts)
|
||||||
|
(
|
||||||
|
sql = sql,
|
||||||
|
params = params.map(_.value.get.asInstanceOf),
|
||||||
|
mapper = (rows) => rows.traverse(r.extract)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package minisql.idiom
|
package minisql.idiom
|
||||||
|
|
||||||
import minisql.ast._
|
import minisql.ParamEncoder
|
||||||
|
import minisql.ast.*
|
||||||
import minisql.util.Interleave
|
import minisql.util.Interleave
|
||||||
import minisql.idiom.StatementInterpolator._
|
import minisql.idiom.StatementInterpolator.*
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.collection.immutable.{Map => SMap}
|
import scala.collection.immutable.{Map => SMap}
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ object ReifyStatement {
|
||||||
liftingPlaceholder: Int => String,
|
liftingPlaceholder: Int => String,
|
||||||
emptySetContainsToken: Token => Token,
|
emptySetContainsToken: Token => Token,
|
||||||
statement: Statement,
|
statement: Statement,
|
||||||
liftMap: SMap[String, (Any, Any)]
|
liftMap: SMap[String, (Any, ParamEncoder[?])]
|
||||||
): (String, List[ScalarValueLift]) = {
|
): (String, List[ScalarValueLift]) = {
|
||||||
val expanded = expandLiftings(statement, emptySetContainsToken, liftMap)
|
val expanded = expandLiftings(statement, emptySetContainsToken, liftMap)
|
||||||
token2string(expanded, liftingPlaceholder)
|
token2string(expanded, liftingPlaceholder)
|
||||||
|
@ -61,8 +62,39 @@ object ReifyStatement {
|
||||||
private def expandLiftings(
|
private def expandLiftings(
|
||||||
statement: Statement,
|
statement: Statement,
|
||||||
emptySetContainsToken: Token => Token,
|
emptySetContainsToken: Token => Token,
|
||||||
liftMap: SMap[String, (Any, Any)]
|
liftMap: SMap[String, (Any, ParamEncoder[?])]
|
||||||
): Token = {
|
): (Token) = {
|
||||||
???
|
Statement {
|
||||||
|
val lb = List.newBuilder[Token]
|
||||||
|
statement.tokens.foldLeft(lb) {
|
||||||
|
case (
|
||||||
|
tokens,
|
||||||
|
SetContainsToken(a, op, ScalarLiftToken(lift: ScalarQueryLift))
|
||||||
|
) =>
|
||||||
|
val (lv, le) = liftMap(lift.liftId)
|
||||||
|
lv.asInstanceOf[Iterable[Any]].toVector match {
|
||||||
|
case Vector() => tokens += emptySetContainsToken(a)
|
||||||
|
case values =>
|
||||||
|
val liftings = values.zipWithIndex.map {
|
||||||
|
case (v, i) =>
|
||||||
|
ScalarLiftToken(
|
||||||
|
ScalarValueLift(
|
||||||
|
s"${lift.name}[${i}]",
|
||||||
|
s"${lift.liftId}[${i}]",
|
||||||
|
Some(v -> le)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val separators = Vector.fill(liftings.size - 1)(StringToken(", "))
|
||||||
|
(tokens += stmt"$a $op (") ++= Interleave(
|
||||||
|
liftings,
|
||||||
|
separators
|
||||||
|
) += StringToken(")")
|
||||||
|
}
|
||||||
|
case (tokens, token) =>
|
||||||
|
tokens += token
|
||||||
|
}
|
||||||
|
lb.result()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package minisql.util
|
||||||
|
|
||||||
import scala.util.*
|
import scala.util.*
|
||||||
|
|
||||||
extension [A](xs: IArray[A]) {
|
extension [A](xs: Iterable[A]) {
|
||||||
private[minisql] def traverse[B](f: A => Try[B]): Try[IArray[B]] = {
|
private[minisql] def traverse[B](f: A => Try[B]): Try[IArray[B]] = {
|
||||||
val out = IArray.newBuilder[Any]
|
val out = IArray.newBuilder[Any]
|
||||||
var left: Option[Throwable] = None
|
var left: Option[Throwable] = None
|
||||||
|
|
Loading…
Reference in a new issue