Skip to content

Commit

Permalink
Merge pull request #829 from sviezypan/select_all_from
Browse files Browse the repository at this point in the history
select(*).from(table)
  • Loading branch information
jczuchnowski committed Feb 13, 2023
2 parents a2e30b7 + abf0c01 commit 50deb4b
Show file tree
Hide file tree
Showing 11 changed files with 1,080 additions and 20 deletions.
9 changes: 9 additions & 0 deletions core/jvm/src/main/scala/zio/sql/Sql.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ trait Sql
with UpdateModule
with ExprModule
with TableModule
with AllColumnsModule
with InsertModule
with UtilsModule
with SelectUtilsModule
Expand All @@ -28,6 +29,14 @@ trait Sql
*/
val select: SelectByCommaBuilder = SelectByCommaBuilder()

sealed trait Star
val * : Star = new Star {}

def select(star: Star): SelectAll = {
val _ = star
new SelectAll()
}

def select[F, A, B <: SelectionSet[A]](selection: Selection[F, A, B]): SelectBuilder[F, A, B] =
SelectBuilder[F, A, B](selection)

Expand Down
945 changes: 945 additions & 0 deletions core/jvm/src/main/scala/zio/sql/allcolumns.scala

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions core/jvm/src/main/scala/zio/sql/select.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>

def from[Source0 <: Source](table: Table.Aux[Source0])(implicit
ev: B <:< SelectionSet.Cons[Source0, selection.value.ColumnHead, selection.value.SelectionTail],
normalizer: TrailingUnitNormalizer[selection.value.ResultTypeRepr]
normalizer: Normalizer[selection.value.ResultTypeRepr]
): Read.Select[
F0,
normalizer.Out,
Expand Down Expand Up @@ -39,7 +39,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
builder.selection.value.ColumnHead,
builder.selection.value.SelectionTail
],
normalizer: TrailingUnitNormalizer[builder.selection.value.ResultTypeRepr]
normalizer: Normalizer[builder.selection.value.ResultTypeRepr]
): Read.Select[
F,
normalizer.Out,
Expand All @@ -65,7 +65,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
def from[Source0](table: Table.Aux[Source0])(implicit
ev1: Source0 with ParentTable <:< Source,
ev2: B <:< SelectionSet.Cons[Source, selection.value.ColumnHead, selection.value.SelectionTail],
normalizer: TrailingUnitNormalizer[selection.value.ResultTypeRepr]
normalizer: Normalizer[selection.value.ResultTypeRepr]
): Read.Subselect[
F,
normalizer.Out,
Expand Down Expand Up @@ -297,7 +297,7 @@ trait SelectModule { self: ExprModule with TableModule with UtilsModule =>
//format: on

def normalize(implicit
instance: TrailingUnitNormalizer[ResultType]
instance: Normalizer[ResultType]
): Subselect[F, instance.Out, Source, Subsource, Head, Tail] =
self.asInstanceOf[Subselect[F, instance.Out, Source, Subsource, Head, Tail]]

Expand Down
26 changes: 25 additions & 1 deletion core/jvm/src/main/scala/zio/sql/selectutils.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
package zio.sql

// format: off
trait SelectUtilsModule { self: TableModule with ExprModule with InsertModule with SelectModule =>
trait SelectUtilsModule { self: TableModule with ExprModule with InsertModule with SelectModule with AllColumnsModule =>

sealed case class SelectAll() {

def from[A](table: Table.Source.Aux[A])(implicit helper: ColumnsHelper[table.ColumnsOut, A]): Read.Select[
helper.F,
helper.ResultTypeRepr,
A,
helper.ColumnHead,
helper.SelectionTail
] = {
type B0 = SelectionSet.ConsAux[
helper.ResultTypeRepr,
A,
helper.ColumnHead,
helper.SelectionTail
]
val b: B0 = table.all.selection.value.asInstanceOf[B0]

Read.Subselect[helper.F, helper.ResultTypeRepr, A, A, helper.ColumnHead, helper.SelectionTail](
Selection[helper.F, A, B0](b), Some(table), true
)
}
}

sealed case class SelectByCommaBuilder() {

def apply[F1, Source, B1](expr1: Expr[F1, Source, B1]) = {
SelectBuilder[F1, Source, SelectionSet.Cons[Source, B1, SelectionSet.Empty]](expr1)
}
Expand Down
30 changes: 20 additions & 10 deletions core/jvm/src/main/scala/zio/sql/table.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object TableAnnotation {
case class name(name: String) extends StaticAnnotation
}

trait TableModule { self: ExprModule with SelectModule with UtilsModule with SelectUtilsModule =>
trait TableModule { self: ExprModule with SelectModule with UtilsModule with SelectUtilsModule with AllColumnsModule =>

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

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

val exprAccessorBuilder = new ExprAccessorBuilder(tableName)
protected[sql] val exprAccessorBuilder = new ExprAccessorBuilder(tableName)

override type AllColumnIdentities = schema.Terms
override protected[sql] type AllColumnIdentities = schema.Terms

override type TableType = T
override protected[sql] type TableType = T

override type ColumnsOut =
override protected[sql] type ColumnsOut =
schema.Accessors[exprAccessorBuilder.Lens, exprAccessorBuilder.Prism, exprAccessorBuilder.Traversal]

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

override protected[sql] def all(implicit
helper: ColumnsHelper[ColumnsOut, TableType]
): SelectBuilder[helper.F, TableType, helper.SelSet] =
helper.apply(columns)

override val name: TableName = tableName.toLowerCase()
}

Expand Down Expand Up @@ -177,7 +183,7 @@ trait TableModule { self: ExprModule with SelectModule with UtilsModule with Sel
}

sealed trait Table { self =>
type TableType
protected[sql] type TableType

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

trait Insanity {
def ahhhhhhhhhhhhh[A]: A
protected[sql] def ahhhhhhhhhhhhh[A]: A
}

sealed trait Source extends Table with Insanity {
type AllColumnIdentities
protected[sql] type AllColumnIdentities

val name: TableName

type ColumnsOut
protected[sql] type ColumnsOut

val columns: ColumnsOut

override def ahhhhhhhhhhhhh[A]: A = ??? // don't remove or it'll break
protected[sql] def all(implicit
helper: ColumnsHelper[ColumnsOut, TableType]
): SelectBuilder[helper.F, TableType, helper.SelSet]

override protected[sql] def ahhhhhhhhhhhhh[A]: A = ??? // don't remove or it'll break
}

object Source {
Expand Down
6 changes: 4 additions & 2 deletions examples/src/main/scala/zio/sql/Examples.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ object Examples extends App with PostgresJdbcModule {
import this.Orders._
import this.Users._

// SELECT "users"."first_name", "users"."last_name" FROM "users"
val basicSelect =
select(fName, lName).from(users)

println(renderRead(basicSelect))

val selectAll1 = select(*).from(orderDetails)
val selectAll2 = select(*).from(users)

// 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
val selectWithFunctions =
select(age + 2, ConcatWs3(fName, " ", lName), Abs(-42.0))
Expand Down Expand Up @@ -66,7 +68,7 @@ object Examples extends App with PostgresJdbcModule {

/*
SELECT "users"."id", "users"."first_name", "users"."last_name", sum("order_details"."quantity" * "order_details"."unit_price"), sum(abs("order_details"."quantity"))
FROM "users"
FROM "users"x
INNER JOIN "orders" ON "users"."id" = "orders"."usr_id"
LEFT JOIN "order_details" ON "orders"."id" = "order_details"."order_id"
GROUP BY "users"."id", "users"."first_name", "users"."last_name" */
Expand Down
42 changes: 42 additions & 0 deletions macros/src/main/scala-2/zio/sql/macros/Normalizer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package zio.sql.macros

import scala.reflect.macros.whitebox
import scala.language.experimental.macros

sealed trait Normalizer[In] {
type Out
}

object Normalizer {

final case class Instance[In, Out2]() extends Normalizer[In] {
override type Out = Out2
}

implicit def createNormalizer[In, Out]: Instance[In, Out] = macro createNormalizerImpl[In, Out]

def createNormalizerImpl[In: c.WeakTypeTag, Out: c.WeakTypeTag](
c: whitebox.Context
): c.Tree = {
import c.universe._

val inType = weakTypeOf[In]
val _ = weakTypeOf[Out]

def deconstructType(t: Type): List[Type] =
t.dealias match {
case TypeRef(_, y, types) if (types != Nil && (y == symbolOf[scala.Tuple2[_, _]])) =>
types.head :: deconstructType(types.tail.head)
case TypeRef(_, _, types) if (types == Nil) =>
Nil
case s =>
c.abort(c.enclosingPosition, s"Error ${showRaw(s)}")
}

val values = deconstructType(inType)
val outType = tq"(..$values)"

q"""zio.sql.macros.Normalizer.Instance[${q"$inType"}, $outType]()"""
}

}
2 changes: 1 addition & 1 deletion macros/src/main/scala-2/zio/sql/macros/insertlike.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ sealed trait InsertLike[F, ColsRepr, AllColumnIdentities, Z]
*/
object InsertLike {

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

Expand Down
20 changes: 20 additions & 0 deletions macros/src/main/scala-3/zio/sql/macros/normalizer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package zio.sql.macros

import scala.language.experimental.macros

sealed trait Normalizer[In] {
type Out
}

// TODO transparent inline
object Normalizer {

// final case class Instance[In, Out2]() extends Normalizer[In] {
// override type Out = Out2
// }

implicit def createNormalizer[In]: Normalizer[In] = {
new Normalizer[In] {}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,15 @@ object PostgresSqlModuleSpec extends PostgresRunnableSpec with DbSchema {
for {
result <- execute(update(persons).set(personsName, Some("Charlie")).where(personsName === Some("Murray")))
} yield assertTrue(result == 1)
},
test("select all rows") {
import CustomerSchema._

val query = select(*).from(customers)

for {
result <- execute(query).runCollect
} yield assertTrue(result.length == 2)
}
) @@ sequential
}
3 changes: 1 addition & 2 deletions project/BuildHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ object BuildHelper {
def stdSettings(prjName: String) = Seq(
name := s"$prjName",
scalacOptions := stdOptions,
crossScalaVersions := Seq(Scala213, Scala212, ScalaDotty),
// ThisBuild / scalaVersion := ScalaDotty,
crossScalaVersions := Seq(Scala213, Scala212),
ThisBuild / scalaVersion := Scala213,
scalacOptions := stdOptions ++ extraOptions(scalaVersion.value, optimize = !isSnapshot.value),
libraryDependencies ++= {
Expand Down

0 comments on commit 50deb4b

Please sign in to comment.