Created
April 9, 2021 18:15
-
-
Save deusaquilus/29bffed4abcb8a90fccd7db61227a992 to your computer and use it in GitHub Desktop.
Need to Manually Uninline in Cases with Subclassing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I first found this in PeopleSpec that was being used by PeoplePostgresAsyncSpec | |
trait PeopleSpec extends Spec { | |
inline def peopleInsert = | |
quote((p: Person) => query[Person].insert(p)) | |
inline def couplesInsert = | |
quote((c: Couple) => query[Couple].insert(c)) | |
} | |
// Then this stuff was used in PeoplePostgresAsyncSpec | |
class PeoplePostgresAsyncSpec extends PeopleSpec { | |
def beforeAll() = | |
await { | |
testContext.transaction { implicit ec => | |
for { | |
// This stuff broke | |
_ <- testContext.run(liftQuery(peopleEntries).foreach(e => peopleInsert(e))) | |
_ <- testContext.run(liftQuery(couplesEntries).foreach(e => couplesInsert(e))) | |
} yield {} | |
} | |
} | |
} | |
// The error I got looked like this: | |
// // Malformed batch entity. Batch insertion entities must have the form Insert(Entity, Nil: List[Assignment]) | |
// object DummyEnclosure { // just so formatting won't blow up which it does here anyway but that's a separate issue | |
// { | |
// val Context_this: testContext.type = testContext | |
// (EagerEntitiesPlanter.apply[Person, Any](PeoplePostgresAsyncSpec.this.peopleEntries.asInstanceOf[Iterable[Person]], "aa18eeca-d268-41fc-8257-dfdcf5911052").unquote: Query[Person]) | |
// }.foreach[Insert[Person], Insert[Person]](((e: Person) => (Unquote.apply[Function1[Person, Insert[Person]]]({ | |
// val PeopleSpec_this: PeoplePostgresAsyncSpec.this = PeoplePostgresAsyncSpec.this | |
// ((Quoted.apply[Function1[Person, Insert[Person]]](Function.apply(List.apply[Ident](Ident.apply("p", io.getquill.quat.Quat.Product.WithRenamesCompact.apply(io.getquill.quat.Quat.Product.Type.Concrete)("name", "age")(io.getquill.quat.Quat.Value, io.getquill.quat.Quat.Value)()())), Insert.apply(Entity.apply("Person", Nil, io.getquill.quat.Quat.Product.WithRenamesCompact.apply(io.getquill.quat.Quat.Product.Type.Concrete)("name", "age")(io.getquill.quat.Quat.Value, io.getquill.quat.Quat.Value)()()), Nil)), Nil, Nil): Quoted[Function1[Person, Insert[Person]]]): Quoted[Function1[Person, Insert[Person]]]) | |
// }, "b8715a3b-cdb7-43a7-b540-2b0897611e19").unquote: Function1[Person, Insert[Person]]).apply(e)))($conforms[Insert[Person]] | |
// } | |
// issue here is that there's actually an inline block that 'underlyingArgument' didn't get rid of. | |
//You can see that in the AST detail there are 'Inline(...)' sections. The simple thing to do use to have something to just | |
// choose the last argument of the inline: | |
object Uninline { | |
def unapply(any: Expr[Any]): Option[Expr[Any]] = Some(Term.apply(any.asTerm).asExpr) | |
def apply(any: Expr[Any]): Expr[Any] = Term.apply(any.asTerm).asExpr | |
object Term: | |
def unapply(any: Term): Option[Term] = Some(Term.apply(any)) | |
def apply(any: Term) = | |
any match | |
case Inlined(_, _, v) => v | |
case _ => any | |
} | |
// then use it in ExprModel | |
object Unquoted { | |
def apply(expr: Expr[Any])(using Quotes): QuotationLotExpr = | |
import quotes.reflect._ | |
unapply(expr).getOrElse { quotes.reflect.report.throwError(s"The expression: ${Format(Printer.TreeShortCode.show(expr.asTerm))} is not a valid unquotation of a Quoted Expression (i.e. a [quoted-expression].unqoute) and cannot be unquoted.") } | |
def unapply(expr: Expr[Any])(using Quotes): Option[QuotationLotExpr] = | |
import io.getquill.metaprog.Extractors._ | |
expr match { | |
// In certain situations even after doing 'underlyingArgument', there are still inline blocks | |
// remaining in the AST. | |
case `(QuotationLot).unquote`(tmc.Uninline(QuotationLotExpr(vaseExpr))) => | |
Some(vaseExpr) | |
case _ => | |
//println("=============== NOT MATCHED ===============") | |
None | |
} | |
} | |
// Also use it in other places. May need to be more frequent | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment