Skip to content

Instantly share code, notes, and snippets.

def printSymbolsImpl(using q: Quotes) : Expr[Function0[Unit]] = {
import quotes.reflect._
val owner = Expr(Symbol.spliceOwner.name) // (1)
val parent = Expr(Symbol.spliceOwner.owner.name)
val grandParent = Expr(Symbol.spliceOwner.owner.owner.name)
val functionBody: Expr[Unit] = '{ // (2)
println(s"Splice owner: ${$owner}, parent ${$parent}, grandParent ${$grandParent}")
}
type Ident <: Ref
val Ident: IdentModule
/** Methods of the module object `val Ident` */
trait IdentModule { this: Ident.type =>
def apply(tmref: TermRef): Term
def copy(original: Tree)(name: String): Ident
/** Matches a term identifier and returns its name */
def unapply(tree: Ident): Some[String]
* +- Tree -+- PackageClause
* |
* +- Statement -+- Import
* | |
* | +- Term --------+- Ref -+- Ident
* | | +- Select
*
*
* +- TypeRepr -+- NamedType -+- TermRef
* | +- TypeRef
private def getDbType(typeRepr: TypeRepr): DbType = typeRepr.asType match {
case '[Int] => DbType.DbInt // (1)
case '[String] => DbType.DbString
case '[unknown] => // (2)
report.throwError("Unsupported type as DB column " + Type.show[unknown])
}
private def parseColumDef(columnDefTerm: Term) : ColumnInfo = {
columnDefTerm.asExprOf[ColDef[_]] match { // (1)
case '{ ColDef[a]($name) } => // (2)
val paramType = TypeRepr.of[a] // (3)
val nameValue = name.valueOrError // (4)
println(
s"Type: ${Type.show[a]} , value: $nameValue, name AST: ${name.asTerm
.show(using Printer.TreeStructure)}"
private def parseColumnInfo(paramMapping: Term): Seq[ColumnInfo] = { // (1)
paramMapping match {
case Inlined(None, Nil, Apply(TypeApply(_, _), columnDefs)) => // (2)
columnDefs.map(columnDefsTerm =>
println(
"Parameters term: " + columnDefsTerm.show(using Printer.TreeStructure)
)
def createPreparedStatementImpl[A <: Tuple: Type](
table: Expr[String],
columnMapping: Expr[A]
): Expr[PreparedStatement[CallArgs[A]]] = { // (1)
println(
"Generating prepared statement for arguments: " + columnMapping.asTerm
.show(using Printer.TreeStructure)
)
class StatementGenerator(using Quotes) { // (1)
val SchemaPath = "sql/schema.sql"
import quotes.reflect.* // (2)
object StatementGenerator {
private def callImplementation[A <: Tuple: Type]( // (1)
tableName: Expr[String],
columnMapping: Expr[A]
)(using Quotes): Expr[PreparedStatement[CallArgs[A]]] =
new StatementGenerator() // (2)
.createPreparedStatementImpl[A](tableName, columnMapping)
inline def createPreparedStatement[A <: Tuple](inline tableName: String)(
val statement: PreparedStatement[(Int, String)] =
StatementGenerator.createPreparedStatement("user")(ColDef[Int]("id"), ColDef[String]("username")) // (1)
statement.insert(1, "John") // (2)