Try add insert support

This commit is contained in:
jilen 2025-06-22 21:20:23 +08:00
parent 184ab0b884
commit 3a9d15f015
2 changed files with 67 additions and 5 deletions

View file

@ -28,6 +28,28 @@ opaque type Action[E] <: Quoted = Quoted
opaque type Insert <: Action[Long] = Quoted
private inline def quotedLift[X](x: X)(using
e: ParamEncoder[X]
): ast.ScalarValueLift = ${
quotedLiftImpl[X]('x, 'e)
}
private def quotedLiftImpl[X: Type](
x: Expr[X],
e: Expr[ParamEncoder[X]]
)(using Quotes): Expr[ast.ScalarValueLift] = {
import quotes.reflect.*
val name = x.asTerm.symbol.fullName
val liftId = x.asTerm.symbol.owner.fullName + "@" + name
'{
ast.ScalarValueLift(
${ Expr(name) },
${ Expr(liftId) },
Some(($x, $e))
)
}
}
object Query {
extension [E](inline e: Query[E]) {
@ -62,10 +84,48 @@ object EntityQuery {
}
inline def insert(v: E)(using m: Mirror.ProductOf[E]): Insert = {
???
val entity = e.asInstanceOf[ast.Entity]
val assignments = transformCaseClassToAssignments[E](v, entity.name)
ast.Insert(entity, assignments)
}
}
}
private inline def transformCaseClassToAssignments[E](
v: E,
entityName: String
)(using m: Mirror.ProductOf[E]): List[ast.Assignment] = ${
transformCaseClassToAssignmentsImpl[E]('v, 'entityName)
}
private def transformCaseClassToAssignmentsImpl[E: Type](
v: Expr[E],
entityName: Expr[String]
)(using Quotes): Expr[List[ast.Assignment]] = {
import quotes.reflect.*
val fields = TypeRepr.of[E].typeSymbol.caseFields
val assignments = fields.map { field =>
val fieldName = field.name
val fieldType = field.tree match {
case v: ValDef => v.tpt.tpe
case _ => report.errorAndAbort(s"Expected ValDef for field $fieldName")
}
fieldType.asType match {
case '[t] =>
'{
ast.Assignment(
ast.Ident($entityName),
ast.Property(ast.Ident($entityName), ${ Expr(fieldName) }),
quotedLift[t](${ Select.unique(v.asTerm, fieldName).asExprOf[t] })(
using summonInline[ParamEncoder[t]]
)
)
}
}
}
}
Expr.ofList(assignments)
}
private inline def transform[A, B](inline q1: Quoted)(
@ -102,9 +162,7 @@ def lift[X](x: X)(using e: ParamEncoder[X]): X = throw NonQuotedException()
class NonQuotedException extends Exception("Cannot be used at runtime")
private[minisql] inline def compileTimeAst(inline q: Quoted): Option[String] =
${
compileTimeAstImpl('q)
}
${ compileTimeAstImpl('q) }
private def compileTimeAstImpl(e: Expr[Quoted])(using
Quotes

View file

@ -24,4 +24,8 @@ class QuotedSuite extends munit.FunSuite {
o
}
test("Insert") {
???
}
}