|
17 | 17 | package skunk.tables.internal
|
18 | 18 |
|
19 | 19 | import java.rmi.server.ServerNotActiveException
|
20 |
| - |
21 | 20 | import scala.deriving.Mirror
|
22 | 21 | import scala.Singleton as SSingleton
|
23 | 22 | import scala.quoted.*
|
24 |
| - |
25 | 23 | import cats.data.NonEmptyList
|
26 |
| - |
27 | 24 | import quotidian.{MacroMirror, MirrorElem}
|
28 |
| - |
| 25 | +import skunk.tables.ast.{Select, TableH} |
29 | 26 | import skunk.tables.{IsColumn, TypedColumn}
|
30 | 27 |
|
31 | 28 | /** MacroTable is a class containing all information necessary for `Table` synthezis. It can be of
|
@@ -86,7 +83,61 @@ sealed trait MacroTable[Q <: Quotes & Singleton, A]:
|
86 | 83 |
|
87 | 84 | object MacroTable:
|
88 | 85 |
|
89 |
| - /** Init phase is when `TableBuilder` knows only information derived from `A` type |
| 86 | + import skunk.tables.ast |
| 87 | + |
| 88 | + extension [T <: ast.Select.SelectH](select: T) |
| 89 | + transparent inline def where[F](inline f: F) = |
| 90 | + ${ whereImpl[T, F]('{f}) } |
| 91 | + |
| 92 | + private def whereImpl[T: Type, F: Type](f: Expr[F])(using Quotes) = |
| 93 | + import quotes.reflect.* |
| 94 | + |
| 95 | + (Type.of[T], f.asTerm) match |
| 96 | + case ('[ast.Select.SelectH { type Columns = cols; type From = from }], Inlined(_, _, Literal(constant))) => |
| 97 | + ConstantType(constant).asType match |
| 98 | + case '[where] => |
| 99 | + mkSelectH[cols, false, from, where] |
| 100 | + case ('[ast.Select.SelectH { type Columns = cols; type From = from }], f) => |
| 101 | + println(TypeRepr.of[from].widen.dealias.simplified.show) |
| 102 | + println(f) |
| 103 | + ??? |
| 104 | + |
| 105 | + inline transparent def select[F, N, C](inline f: F) = |
| 106 | + ${ selectImpl[F, N, C] } |
| 107 | + |
| 108 | + private def selectImpl[F: Type, N: Type, C: Type](using Quotes) = |
| 109 | + import quotes.reflect.* |
| 110 | + |
| 111 | + |
| 112 | + val fromType = (TypeRepr.of[C].dealias.asType, Type.of[N]) match |
| 113 | + case ('[columns], '[name]) => |
| 114 | + val expr = '{ |
| 115 | + new TableH { }.asInstanceOf[TableH { |
| 116 | + type NameH = name |
| 117 | + type ColumnsH = columns |
| 118 | + }] |
| 119 | + } |
| 120 | + expr.asTerm.tpe.asType |
| 121 | + |
| 122 | + (Type.of[F], fromType) match |
| 123 | + case ('[Function1[?, cols]], '[from]) => |
| 124 | + mkSelectH[cols, false, from, Nothing] |
| 125 | + |
| 126 | + |
| 127 | + private def mkSelectH[C: Type, D: Type, F: Type, W: Type](using Quotes) = |
| 128 | + import quotes.reflect.* |
| 129 | + |
| 130 | + '{ |
| 131 | + new ast.Select.SelectH { }.asInstanceOf[ast.Select.SelectH { |
| 132 | + type Columns = C |
| 133 | + type Distinct = D |
| 134 | + type From = F |
| 135 | + type Where = W |
| 136 | + }] |
| 137 | + } |
| 138 | + |
| 139 | + |
| 140 | +/** Init phase is when `TableBuilder` knows only information derived from `A` type |
90 | 141 | *
|
91 | 142 | * @param columnMap
|
92 | 143 | * an ordered list of columns, where key is column name, value is a pair of `TypeRepr` of that
|
@@ -135,7 +186,7 @@ object MacroTable:
|
135 | 186 | def columnMap = columns.map(c => c.name -> c.tpe.asInstanceOf[TypeRepr])
|
136 | 187 |
|
137 | 188 | /** Get a tuple of fully-typed constraints for a particular column */
|
138 |
| - def getConstraints(label: String): quotes.reflect.TypeRepr = |
| 189 | + def getConstraints(label: String): TypeRepr = |
139 | 190 | columns.find(column => column.name == label) match
|
140 | 191 | case Some(column) =>
|
141 | 192 | MacroColumn.constraintsTuple(quotes)(column.constraints)
|
|
0 commit comments