Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 50deb4b

Browse files
authored
Merge pull request #829 from sviezypan/select_all_from
select(*).from(table)
2 parents a2e30b7 + abf0c01 commit 50deb4b

File tree

11 files changed

+1080
-20
lines changed

11 files changed

+1080
-20
lines changed

core/jvm/src/main/scala/zio/sql/Sql.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait Sql
88
with UpdateModule
99
with ExprModule
1010
with TableModule
11+
with AllColumnsModule
1112
with InsertModule
1213
with UtilsModule
1314
with SelectUtilsModule
@@ -28,6 +29,14 @@ trait Sql
2829
*/
2930
val select: SelectByCommaBuilder = SelectByCommaBuilder()
3031

32+
sealed trait Star
33+
val * : Star = new Star {}
34+
35+
def select(star: Star): SelectAll = {
36+
val _ = star
37+
new SelectAll()
38+
}
39+
3140
def select[F, A, B <: SelectionSet[A]](selection: Selection[F, A, B]): SelectBuilder[F, A, B] =
3241
SelectBuilder[F, A, B](selection)
3342

core/jvm/src/main/scala/zio/sql/allcolumns.scala

Lines changed: 945 additions & 0 deletions
Large diffs are not rendered by default.

core/jvm/src/main/scala/zio/sql/select.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
99

1010
def from[Source0 <: Source](table: Table.Aux[Source0])(implicit
1111
ev: B <:< SelectionSet.Cons[Source0, selection.value.ColumnHead, selection.value.SelectionTail],
12-
normalizer: TrailingUnitNormalizer[selection.value.ResultTypeRepr]
12+
normalizer: Normalizer[selection.value.ResultTypeRepr]
1313
): Read.Select[
1414
F0,
1515
normalizer.Out,
@@ -39,7 +39,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
3939
builder.selection.value.ColumnHead,
4040
builder.selection.value.SelectionTail
4141
],
42-
normalizer: TrailingUnitNormalizer[builder.selection.value.ResultTypeRepr]
42+
normalizer: Normalizer[builder.selection.value.ResultTypeRepr]
4343
): Read.Select[
4444
F,
4545
normalizer.Out,
@@ -65,7 +65,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
6565
def from[Source0](table: Table.Aux[Source0])(implicit
6666
ev1: Source0 with ParentTable <:< Source,
6767
ev2: B <:< SelectionSet.Cons[Source, selection.value.ColumnHead, selection.value.SelectionTail],
68-
normalizer: TrailingUnitNormalizer[selection.value.ResultTypeRepr]
68+
normalizer: Normalizer[selection.value.ResultTypeRepr]
6969
): Read.Subselect[
7070
F,
7171
normalizer.Out,
@@ -297,7 +297,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
297297
//format: on
298298

299299
def normalize(implicit
300-
instance: TrailingUnitNormalizer[ResultType]
300+
instance: Normalizer[ResultType]
301301
): Subselect[F, instance.Out, Source, Subsource, Head, Tail] =
302302
self.asInstanceOf[Subselect[F, instance.Out, Source, Subsource, Head, Tail]]
303303

core/jvm/src/main/scala/zio/sql/selectutils.scala

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
package zio.sql
22

33
// format: off
4-
trait SelectUtilsModule { self: TableModule with ExprModule with InsertModule with SelectModule =>
4+
trait SelectUtilsModule { self: TableModule with ExprModule with InsertModule with SelectModule with AllColumnsModule =>
5+
6+
sealed case class SelectAll() {
7+
8+
def from[A](table: Table.Source.Aux[A])(implicit helper: ColumnsHelper[table.ColumnsOut, A]): Read.Select[
9+
helper.F,
10+
helper.ResultTypeRepr,
11+
A,
12+
helper.ColumnHead,
13+
helper.SelectionTail
14+
] = {
15+
type B0 = SelectionSet.ConsAux[
16+
helper.ResultTypeRepr,
17+
A,
18+
helper.ColumnHead,
19+
helper.SelectionTail
20+
]
21+
val b: B0 = table.all.selection.value.asInstanceOf[B0]
22+
23+
Read.Subselect[helper.F, helper.ResultTypeRepr, A, A, helper.ColumnHead, helper.SelectionTail](
24+
Selection[helper.F, A, B0](b), Some(table), true
25+
)
26+
}
27+
}
528

629
sealed case class SelectByCommaBuilder() {
30+
731
def apply[F1, Source, B1](expr1: Expr[F1, Source, B1]) = {
832
SelectBuilder[F1, Source, SelectionSet.Cons[Source, B1, SelectionSet.Empty]](expr1)
933
}

core/jvm/src/main/scala/zio/sql/table.scala

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object TableAnnotation {
1010
case class name(name: String) extends StaticAnnotation
1111
}
1212

13-
trait TableModule { self: ExprModule with SelectModule with UtilsModule with SelectUtilsModule =>
13+
trait TableModule { self: ExprModule with SelectModule with UtilsModule with SelectUtilsModule with AllColumnsModule =>
1414

1515
type Lens[F, S, A] = Expr[Features.Source[F, S], S, A]
1616

@@ -22,6 +22,7 @@ trait TableModule { self: ExprModule with SelectModule with UtilsModule with Sel
2222
* Creates a table descripton from the Schema of T.
2323
* Table name is taken either from @name annotation or schema id type and pluralized.
2424
*/
25+
// TODO do not allow CaseClass0 with macro
2526
def defineTableSmart[T](implicit
2627
schema: Schema.Record[T],
2728
tableLike: TableSchema[T]
@@ -67,17 +68,22 @@ trait TableModule { self: ExprModule with SelectModule with UtilsModule with Sel
6768
): Table.Source.WithTableDetails[schema.Terms, T, schema.Accessors[Lens, Prism, Traversal]] =
6869
new Table.Source {
6970

70-
val exprAccessorBuilder = new ExprAccessorBuilder(tableName)
71+
protected[sql] val exprAccessorBuilder = new ExprAccessorBuilder(tableName)
7172

72-
override type AllColumnIdentities = schema.Terms
73+
override protected[sql] type AllColumnIdentities = schema.Terms
7374

74-
override type TableType = T
75+
override protected[sql] type TableType = T
7576

76-
override type ColumnsOut =
77+
override protected[sql] type ColumnsOut =
7778
schema.Accessors[exprAccessorBuilder.Lens, exprAccessorBuilder.Prism, exprAccessorBuilder.Traversal]
7879

7980
override val columns: ColumnsOut = schema.makeAccessors(exprAccessorBuilder)
8081

82+
override protected[sql] def all(implicit
83+
helper: ColumnsHelper[ColumnsOut, TableType]
84+
): SelectBuilder[helper.F, TableType, helper.SelSet] =
85+
helper.apply(columns)
86+
8187
override val name: TableName = tableName.toLowerCase()
8288
}
8389

@@ -177,7 +183,7 @@ trait TableModule { self: ExprModule with SelectModule with UtilsModule with Sel
177183
}
178184

179185
sealed trait Table { self =>
180-
type TableType
186+
protected[sql] type TableType
181187

182188
final def fullOuter[That](that: Table.Aux[That]): Table.JoinBuilder[self.TableType, That] =
183189
new Table.JoinBuilder[self.TableType, That](JoinType.FullOuter, self, that)
@@ -209,19 +215,23 @@ trait TableModule { self: ExprModule with SelectModule with UtilsModule with Sel
209215
}
210216

211217
trait Insanity {
212-
def ahhhhhhhhhhhhh[A]: A
218+
protected[sql] def ahhhhhhhhhhhhh[A]: A
213219
}
214220

215221
sealed trait Source extends Table with Insanity {
216-
type AllColumnIdentities
222+
protected[sql] type AllColumnIdentities
217223

218224
val name: TableName
219225

220-
type ColumnsOut
226+
protected[sql] type ColumnsOut
221227

222228
val columns: ColumnsOut
223229

224-
override def ahhhhhhhhhhhhh[A]: A = ??? // don't remove or it'll break
230+
protected[sql] def all(implicit
231+
helper: ColumnsHelper[ColumnsOut, TableType]
232+
): SelectBuilder[helper.F, TableType, helper.SelSet]
233+
234+
override protected[sql] def ahhhhhhhhhhhhh[A]: A = ??? // don't remove or it'll break
225235
}
226236

227237
object Source {

examples/src/main/scala/zio/sql/Examples.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ object Examples extends App with PostgresJdbcModule {
1212
import this.Orders._
1313
import this.Users._
1414

15-
// SELECT "users"."first_name", "users"."last_name" FROM "users"
1615
val basicSelect =
1716
select(fName, lName).from(users)
1817

1918
println(renderRead(basicSelect))
2019

20+
val selectAll1 = select(*).from(orderDetails)
21+
val selectAll2 = select(*).from(users)
22+
2123
// SELECT "users"."age" + 2, concat_ws("users"."first_name",' ',"users"."last_name"), abs(-42.0) FROM "users" ORDER BY "users"."age" DESC LIMIT 10 OFFSET 20
2224
val selectWithFunctions =
2325
select(age + 2, ConcatWs3(fName, " ", lName), Abs(-42.0))
@@ -66,7 +68,7 @@ object Examples extends App with PostgresJdbcModule {
6668

6769
/*
6870
SELECT "users"."id", "users"."first_name", "users"."last_name", sum("order_details"."quantity" * "order_details"."unit_price"), sum(abs("order_details"."quantity"))
69-
FROM "users"
71+
FROM "users"x
7072
INNER JOIN "orders" ON "users"."id" = "orders"."usr_id"
7173
LEFT JOIN "order_details" ON "orders"."id" = "order_details"."order_id"
7274
GROUP BY "users"."id", "users"."first_name", "users"."last_name" */
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package zio.sql.macros
2+
3+
import scala.reflect.macros.whitebox
4+
import scala.language.experimental.macros
5+
6+
sealed trait Normalizer[In] {
7+
type Out
8+
}
9+
10+
object Normalizer {
11+
12+
final case class Instance[In, Out2]() extends Normalizer[In] {
13+
override type Out = Out2
14+
}
15+
16+
implicit def createNormalizer[In, Out]: Instance[In, Out] = macro createNormalizerImpl[In, Out]
17+
18+
def createNormalizerImpl[In: c.WeakTypeTag, Out: c.WeakTypeTag](
19+
c: whitebox.Context
20+
): c.Tree = {
21+
import c.universe._
22+
23+
val inType = weakTypeOf[In]
24+
val _ = weakTypeOf[Out]
25+
26+
def deconstructType(t: Type): List[Type] =
27+
t.dealias match {
28+
case TypeRef(_, y, types) if (types != Nil && (y == symbolOf[scala.Tuple2[_, _]])) =>
29+
types.head :: deconstructType(types.tail.head)
30+
case TypeRef(_, _, types) if (types == Nil) =>
31+
Nil
32+
case s =>
33+
c.abort(c.enclosingPosition, s"Error ${showRaw(s)}")
34+
}
35+
36+
val values = deconstructType(inType)
37+
val outType = tq"(..$values)"
38+
39+
q"""zio.sql.macros.Normalizer.Instance[${q"$inType"}, $outType]()"""
40+
}
41+
42+
}

macros/src/main/scala-2/zio/sql/macros/insertlike.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ sealed trait InsertLike[F, ColsRepr, AllColumnIdentities, Z]
1313
*/
1414
object InsertLike {
1515

16-
// TODO check arity and if > 22 AllColumnIdentites is a nested tuple
16+
// TODO check when arity > 22 is AllColumnIdentites is a nested tuple?
1717
final case class CanBeInserted[F, ColsRepr, AllColumnIdentities, Z]()
1818
extends InsertLike[F, ColsRepr, AllColumnIdentities, Z]
1919

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package zio.sql.macros
2+
3+
import scala.language.experimental.macros
4+
5+
sealed trait Normalizer[In] {
6+
type Out
7+
}
8+
9+
// TODO transparent inline
10+
object Normalizer {
11+
12+
// final case class Instance[In, Out2]() extends Normalizer[In] {
13+
// override type Out = Out2
14+
// }
15+
16+
implicit def createNormalizer[In]: Normalizer[In] = {
17+
new Normalizer[In] {}
18+
}
19+
20+
}

postgres/src/test/scala/zio/sql/postgresql/PostgresSqlModuleSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,15 @@ object PostgresSqlModuleSpec extends PostgresRunnableSpec with DbSchema {
687687
for {
688688
result <- execute(update(persons).set(personsName, Some("Charlie")).where(personsName === Some("Murray")))
689689
} yield assertTrue(result == 1)
690+
},
691+
test("select all rows") {
692+
import CustomerSchema._
693+
694+
val query = select(*).from(customers)
695+
696+
for {
697+
result <- execute(query).runCollect
698+
} yield assertTrue(result.length == 2)
690699
}
691700
) @@ sequential
692701
}

0 commit comments

Comments
 (0)