Skip to content

Commit 6cf41b2

Browse files
committed
remove some wrapper classes
1 parent 9efa287 commit 6cf41b2

File tree

1 file changed

+66
-53
lines changed

1 file changed

+66
-53
lines changed

scalasql/namedtuples/src/SimpleTableMacros.scala

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ object SimpleTableMacros {
2727
)[U: ClassTag](f: (T, Int) => IterableOnce[U]): IArray[U] = {
2828
IArray.from(t.productIterator.asInstanceOf[Iterator[T]].zipWithIndex.flatMap(f.tupled))
2929
}
30-
def asIArrayUnwrap[T](t: Tuple)[U: ClassTag](f: T => U): IArray[U] = {
31-
IArray.from(t.productIterator.asInstanceOf[Iterator[T]].map(f))
32-
}
3330
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)
3535
}
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)
3838
}
3939
def make[C](m: Mirror.ProductOf[C], data: IArray[AnyRef]): C = {
4040
class ArrayProduct extends Product {
@@ -47,21 +47,6 @@ object SimpleTableMacros {
4747
m.fromProduct(ArrayProduct())
4848
}
4949

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-
6550
opaque type ContraMapper[T] = DialectTypeMappers => T
6651

6752
object ContraMapper {
@@ -71,6 +56,18 @@ object SimpleTableMacros {
7156
compiletime.summonInline[T]
7257
}
7358

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+
7471
opaque type BaseRowExpr[T] = Queryable.Row[?, ?]
7572
object BaseRowExpr {
7673
given summonDelegate[T](
@@ -87,32 +84,32 @@ object SimpleTableMacros {
8784
): BaseRowExpr[T] = delegate
8885
}
8986

90-
class BaseColumn[L, T](val value: AnyRef)
87+
opaque type BaseColumn[L, T] = AnyRef
9188
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] =
9592
val col = new Column[T](
9693
ref,
9794
Table.columnNameOverride(ref.value)(l.value)
98-
)(using compiletime.summonInline[TypeMapper[T]])
99-
BaseColumn(col)
95+
)
96+
col
10097
}
10198
object BaseColumn extends BaseColumnLowPrio {
10299
given foundMeta: [L <: String, T]
103100
=> (mappers: DialectTypeMappers, ref: TableRef, m: SimpleTable.WrappedMetadata[T])
104101
=> BaseColumn[L, T] =
105-
BaseColumn(m.metadata.metadata0.vExpr(ref, mappers).asInstanceOf[AnyRef])
102+
m.metadata.metadata0.vExpr(ref, mappers).asInstanceOf[AnyRef]
106103
}
107104

108-
class BaseLabels[L, C](val fetch: String => Seq[String])
105+
opaque type BaseLabels[L, C] = String => Seq[String]
109106
trait BaseLabelsLowPrio {
110107
given notFound: [L <: String, C] => BaseLabels[L, C] =
111-
new BaseLabels(fetch = label => Seq(label))
108+
label => Seq(label)
112109
}
113110
object BaseLabels extends BaseLabelsLowPrio {
114111
given foundMeta: [L, C] => (m: SimpleTable.WrappedMetadata[C]) => BaseLabels[L, C] =
115-
new BaseLabels(fetch = _ => m.metadata.metadata0.walkLabels0())
112+
_ => m.metadata.metadata0.walkLabels0()
116113
}
117114

118115
def setNonNull[T](r: AtomicReference[T | Null])(f: => T): T = {
@@ -175,17 +172,37 @@ object SimpleTableMacros {
175172

176173
def labels(t: Tuple): IArray[String] = asIArray(t)
177174

178-
inline def getMirror[C]: (IArray[String], Mirror.ProductOf[C]) = {
175+
inline def getMirror[C]: (Tuple, Mirror.ProductOf[C]) = {
179176
compiletime.summonFrom { case m: Mirror.ProductOf[C] =>
180-
(labels(compiletime.constValueTuple[m.MirroredElemLabels]), m)
177+
(compiletime.constValueTuple[m.MirroredElemLabels], m)
181178
}
182179
}
183180

184181
}
185182

186183
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+
187205
inline given initTableMetadata[C <: Product]: SimpleTable.Metadata[C] =
188-
lazy val mirrorPair = SimpleTableMacros.getMirror[C]
189206
type Impl[T[_]] = SimpleTable.MapOver[C, T]
190207
type Labels = NamedTuple.Names[NamedTuple.From[C]]
191208
type Values = NamedTuple.DropNames[NamedTuple.From[C]]
@@ -196,24 +213,24 @@ trait SimpleTableMacros {
196213
}
197214
]
198215
type FlatLabels = Pairs[SimpleTableMacros.BaseLabels]
199-
type Columns = Pairs[SimpleTableMacros.BaseColumn]
216+
type Columns = Pairs[[L,
217+
T] =>> SimpleTableMacros.ContraRefMapper[SimpleTableMacros.BaseColumn[L, T]]]
200218
type Rows = Tuple.Map[
201219
Values,
202220
[T] =>> SimpleTableMacros.ContraMapper[SimpleTableMacros.BaseRowExpr[T]]
203221
]
204222

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+
)
207229

208230
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)
212232

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
217234

218235
def queryable(
219236
walkLabels0: () => Seq[String],
@@ -223,13 +240,11 @@ trait SimpleTableMacros {
223240
walkLabels0,
224241
walkExprs0 = SimpleTableMacros.walkAllExprs(queryable),
225242
construct0 = args =>
226-
val (labels, mirror) = mirrorPair
227243
SimpleTableMacros.construct(queryable)(
228-
size = labels.size,
244+
size = state.labels.size,
229245
args = args,
230-
factory = SimpleTableMacros.make(mirror, _)
231-
)
232-
,
246+
factory = SimpleTableMacros.make(state.mirror, _)
247+
),
233248
deconstruct0 = values => SimpleTableMacros.deconstruct[Impl[Expr]](queryable)(values)
234249
)
235250

@@ -238,13 +253,11 @@ trait SimpleTableMacros {
238253
mappers: DialectTypeMappers,
239254
@nowarn("msg=unused") queryable: Table.Metadata.QueryableProxy
240255
): 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))
244257
SimpleTable.Record.fromIArray(columns).asInstanceOf[Impl[Column]]
245258

246259
val metadata0 =
247-
Table.Metadata[Impl](queryables, walkLabels0(mirrorPair(0)), queryable, vExpr0)
260+
Table.Metadata[Impl](queryables, walkLabels0, queryable, vExpr0)
248261

249262
SimpleTable.Metadata(metadata0)
250263
}

0 commit comments

Comments
 (0)