@@ -27,14 +27,14 @@ object SimpleTableMacros {
27
27
)[U : ClassTag ](f : (T , Int ) => IterableOnce [U ]): IArray [U ] = {
28
28
IArray .from(t.productIterator.asInstanceOf [Iterator [T ]].zipWithIndex.flatMap(f.tupled))
29
29
}
30
- def asIArrayUnwrap [T ](t : Tuple )[U : ClassTag ](f : T => U ): IArray [U ] = {
31
- IArray .from(t.productIterator.asInstanceOf [Iterator [T ]].map(f))
32
- }
33
30
def unwrapLabels (t : Tuple , labels : IArray [String ]): IndexedSeq [String ] = {
34
- asIArrayFlatUnwrapWithIndex[BaseLabels [? , ? ]](t)((l, i) => l.fetch(labels(i))).toIndexedSeq
31
+ asIArrayFlatUnwrapWithIndex[BaseLabels [Any , Any ]](t)((l, i) => l(labels(i))).toIndexedSeq
32
+ }
33
+ def unwrapColumns (t : Tuple ): IArray [(DialectTypeMappers , TableRef ) => AnyRef ] = {
34
+ asIArray[ContraRefMapper [BaseColumn [Any , Any ]]](t)
35
35
}
36
- def unwrapColumns (t : Tuple ): IArray [AnyRef ] = {
37
- asIArrayUnwrap[ BaseColumn [ ? , ? ]](t)(_.value )
36
+ def unwrapRows (t : Tuple ): IArray [DialectTypeMappers => Queryable . Row [ ? , ? ] ] = {
37
+ asIArray[ ContraMapper [ SimpleTableMacros . BaseRowExpr [ Any ]]](t )
38
38
}
39
39
def make [C ](m : Mirror .ProductOf [C ], data : IArray [AnyRef ]): C = {
40
40
class ArrayProduct extends Product {
@@ -47,21 +47,6 @@ object SimpleTableMacros {
47
47
m.fromProduct(ArrayProduct ())
48
48
}
49
49
50
- inline def computeColumns [Columns <: Tuple ](
51
- mappers : DialectTypeMappers ,
52
- tableRef : TableRef
53
- ): IArray [AnyRef ] = {
54
- val cols = mappers match
55
- case given DialectTypeMappers =>
56
- tableRef match
57
- case given TableRef => compiletime.summonAll[Columns ]
58
- unwrapColumns(cols)
59
- }
60
-
61
- def computeRows0 (t : Tuple ): IArray [DialectTypeMappers => Queryable .Row [? , ? ]] = {
62
- asIArray[ContraMapper [SimpleTableMacros .BaseRowExpr [Any ]]](t)
63
- }
64
-
65
50
opaque type ContraMapper [T ] = DialectTypeMappers => T
66
51
67
52
object ContraMapper {
@@ -71,6 +56,18 @@ object SimpleTableMacros {
71
56
compiletime.summonInline[T ]
72
57
}
73
58
59
+ opaque type ContraRefMapper [T ] = (DialectTypeMappers , TableRef ) => T
60
+
61
+ object ContraRefMapper {
62
+ @ nowarn(" msg=inline given alias" )
63
+ inline given [T ]: ContraRefMapper [T ] =
64
+ (mappers, tableRef) =>
65
+ tableRef match
66
+ case given TableRef =>
67
+ import mappers .given
68
+ compiletime.summonInline[T ]
69
+ }
70
+
74
71
opaque type BaseRowExpr [T ] = Queryable .Row [? , ? ]
75
72
object BaseRowExpr {
76
73
given summonDelegate [T ](
@@ -87,32 +84,32 @@ object SimpleTableMacros {
87
84
): BaseRowExpr [T ] = delegate
88
85
}
89
86
90
- class BaseColumn [L , T ]( val value : AnyRef )
87
+ opaque type BaseColumn [L , T ] = AnyRef
91
88
trait BaseColumnLowPrio {
92
- inline given notFound : [L <: String , T ]
93
- => (l : ValueOf [L ], mappers : DialectTypeMappers , ref : TableRef ) => BaseColumn [ L , T ] =
94
- import mappers .{ * , given }
89
+ given notFound : [L <: String , T ]
90
+ => (l : ValueOf [L ], ref : TableRef , mapper : TypeMapper [ T ])
91
+ => BaseColumn [ L , T ] =
95
92
val col = new Column [T ](
96
93
ref,
97
94
Table .columnNameOverride(ref.value)(l.value)
98
- )( using compiletime.summonInline[ TypeMapper [ T ]])
99
- BaseColumn ( col)
95
+ )
96
+ col
100
97
}
101
98
object BaseColumn extends BaseColumnLowPrio {
102
99
given foundMeta : [L <: String , T ]
103
100
=> (mappers : DialectTypeMappers , ref : TableRef , m : SimpleTable .WrappedMetadata [T ])
104
101
=> BaseColumn [L , T ] =
105
- BaseColumn ( m.metadata.metadata0.vExpr(ref, mappers).asInstanceOf [AnyRef ])
102
+ m.metadata.metadata0.vExpr(ref, mappers).asInstanceOf [AnyRef ]
106
103
}
107
104
108
- class BaseLabels [L , C ]( val fetch : String => Seq [String ])
105
+ opaque type BaseLabels [L , C ] = String => Seq [String ]
109
106
trait BaseLabelsLowPrio {
110
107
given notFound : [L <: String , C ] => BaseLabels [L , C ] =
111
- new BaseLabels (fetch = label => Seq (label) )
108
+ label => Seq (label)
112
109
}
113
110
object BaseLabels extends BaseLabelsLowPrio {
114
111
given foundMeta : [L , C ] => (m : SimpleTable .WrappedMetadata [C ]) => BaseLabels [L , C ] =
115
- new BaseLabels (fetch = _ => m.metadata.metadata0.walkLabels0() )
112
+ _ => m.metadata.metadata0.walkLabels0()
116
113
}
117
114
118
115
def setNonNull [T ](r : AtomicReference [T | Null ])(f : => T ): T = {
@@ -175,17 +172,37 @@ object SimpleTableMacros {
175
172
176
173
def labels (t : Tuple ): IArray [String ] = asIArray(t)
177
174
178
- inline def getMirror [C ]: (IArray [ String ] , Mirror .ProductOf [C ]) = {
175
+ inline def getMirror [C ]: (Tuple , Mirror .ProductOf [C ]) = {
179
176
compiletime.summonFrom { case m : Mirror .ProductOf [C ] =>
180
- (labels( compiletime.constValueTuple[m.MirroredElemLabels ]) , m)
177
+ (compiletime.constValueTuple[m.MirroredElemLabels ], m)
181
178
}
182
179
}
183
180
184
181
}
185
182
186
183
trait SimpleTableMacros {
184
+ class SimpleTableState [C <: Product ](
185
+ mirrorPair0 : => (Tuple , Mirror .ProductOf [C ]),
186
+ rowsRef0 : => Tuple ,
187
+ colsRef0 : => Tuple ,
188
+ labelsRef0 : => Tuple
189
+ ):
190
+ private lazy val mirrorPair =
191
+ val (names0, mirror0) = mirrorPair0
192
+ (
193
+ SimpleTableMacros .labels(names0),
194
+ mirror0
195
+ )
196
+ def labels : IArray [String ] = mirrorPair(0 )
197
+ def mirror : Mirror .ProductOf [C ] = mirrorPair(1 )
198
+ lazy val rowsRef : IArray [DialectTypeMappers => Queryable .Row [? , ? ]] =
199
+ SimpleTableMacros .unwrapRows(rowsRef0)
200
+ lazy val colsRef : IArray [(DialectTypeMappers , TableRef ) => AnyRef ] =
201
+ SimpleTableMacros .unwrapColumns(colsRef0)
202
+ lazy val labelsRef : IndexedSeq [String ] =
203
+ SimpleTableMacros .unwrapLabels(labelsRef0, labels)
204
+
187
205
inline given initTableMetadata [C <: Product ]: SimpleTable .Metadata [C ] =
188
- lazy val mirrorPair = SimpleTableMacros .getMirror[C ]
189
206
type Impl [T [_]] = SimpleTable .MapOver [C , T ]
190
207
type Labels = NamedTuple .Names [NamedTuple .From [C ]]
191
208
type Values = NamedTuple .DropNames [NamedTuple .From [C ]]
@@ -196,24 +213,24 @@ trait SimpleTableMacros {
196
213
}
197
214
]
198
215
type FlatLabels = Pairs [SimpleTableMacros .BaseLabels ]
199
- type Columns = Pairs [SimpleTableMacros .BaseColumn ]
216
+ type Columns = Pairs [[L ,
217
+ T ] =>> SimpleTableMacros .ContraRefMapper [SimpleTableMacros .BaseColumn [L , T ]]]
200
218
type Rows = Tuple .Map [
201
219
Values ,
202
220
[T ] =>> SimpleTableMacros .ContraMapper [SimpleTableMacros .BaseRowExpr [T ]]
203
221
]
204
222
205
- val rowsRef = AtomicReference [IArray [DialectTypeMappers => Queryable .Row [? , ? ]] | Null ](null )
206
- val labelsRef = AtomicReference [IndexedSeq [String ] | Null ](null )
223
+ val state = new SimpleTableState [C ](
224
+ mirrorPair0 = SimpleTableMacros .getMirror[C ],
225
+ rowsRef0 = compiletime.summonAll[Rows ],
226
+ colsRef0 = compiletime.summonAll[Columns ],
227
+ labelsRef0 = compiletime.summonAll[FlatLabels ]
228
+ )
207
229
208
230
def queryables (mappers : DialectTypeMappers , idx : Int ): Queryable .Row [? , ? ] =
209
- SimpleTableMacros .setNonNull(rowsRef)(
210
- SimpleTableMacros .computeRows0(compiletime.summonAll[Rows ])
211
- )(idx)(mappers)
231
+ state.rowsRef(idx)(mappers)
212
232
213
- def walkLabels0 (labelsArr : => IArray [String ])(): Seq [String ] =
214
- SimpleTableMacros .setNonNull(labelsRef)(
215
- SimpleTableMacros .unwrapLabels(compiletime.summonAll[FlatLabels ], labelsArr)
216
- )
233
+ def walkLabels0 (): Seq [String ] = state.labelsRef
217
234
218
235
def queryable (
219
236
walkLabels0 : () => Seq [String ],
@@ -223,13 +240,11 @@ trait SimpleTableMacros {
223
240
walkLabels0,
224
241
walkExprs0 = SimpleTableMacros .walkAllExprs(queryable),
225
242
construct0 = args =>
226
- val (labels, mirror) = mirrorPair
227
243
SimpleTableMacros .construct(queryable)(
228
- size = labels.size,
244
+ size = state. labels.size,
229
245
args = args,
230
- factory = SimpleTableMacros .make(mirror, _)
231
- )
232
- ,
246
+ factory = SimpleTableMacros .make(state.mirror, _)
247
+ ),
233
248
deconstruct0 = values => SimpleTableMacros .deconstruct[Impl [Expr ]](queryable)(values)
234
249
)
235
250
@@ -238,13 +253,11 @@ trait SimpleTableMacros {
238
253
mappers : DialectTypeMappers ,
239
254
@ nowarn(" msg=unused" ) queryable : Table .Metadata .QueryableProxy
240
255
): Impl [Column ] =
241
- // TODO: we should not cache the columns here because this can be called multiple times,
242
- // and each time the captured tableRef should be treated as a fresh value.
243
- val columns = SimpleTableMacros .computeColumns[Columns ](mappers, tableRef)
256
+ val columns = state.colsRef.map(_(mappers, tableRef))
244
257
SimpleTable .Record .fromIArray(columns).asInstanceOf [Impl [Column ]]
245
258
246
259
val metadata0 =
247
- Table .Metadata [Impl ](queryables, walkLabels0(mirrorPair( 0 )) , queryable, vExpr0)
260
+ Table .Metadata [Impl ](queryables, walkLabels0, queryable, vExpr0)
248
261
249
262
SimpleTable .Metadata (metadata0)
250
263
}
0 commit comments