Skip to content

Commit

Permalink
added head and tail type parameters to selection so information is no…
Browse files Browse the repository at this point in the history
…t forgotten
  • Loading branch information
sviezypan committed Aug 28, 2021
1 parent 33fbf68 commit d400999
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 101 deletions.
24 changes: 12 additions & 12 deletions core/jvm/src/main/scala/zio/sql/select.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait SelectModule { self: ExprModule with TableModule =>
sealed case class SelectBuilder[F, Source, B <: SelectionSet[Source]](selection: Selection[F, Source, B]) {

def from[Source0 <: Source](table: Table.Aux[Source0])
(implicit ev: B <:< SelectionSet.Cons[Source0, selection.value.ColumnHead, selection.value.SelectionTail]): Read.Select[F, selection.value.ResultTypeRepr, Source0] = {
(implicit ev: B <:< SelectionSet.Cons[Source0, selection.value.ColumnHead, selection.value.SelectionTail]): Read.Select[F, selection.value.ResultTypeRepr, Source0, selection.value.ColumnHead, selection.value.SelectionTail] = {
type B0 = SelectionSet.ConsAux[selection.value.ResultTypeRepr, Source0, selection.value.ColumnHead, selection.value.SelectionTail]
val b: B0 = selection.value.asInstanceOf[B0]

Expand All @@ -20,7 +20,7 @@ trait SelectModule { self: ExprModule with TableModule =>
implicit def noTable[F, Source >: Any, B <: SelectionSet[Source]](
selectBuilder: SelectBuilder[F, Source, B]
)(implicit ev: B <:< SelectionSet.Cons[Source, selectBuilder.selection.value.ColumnHead, selectBuilder.selection.value.SelectionTail]
): Read.Select[F, selectBuilder.selection.value.ResultTypeRepr, Source] = {
): Read.Select[F, selectBuilder.selection.value.ResultTypeRepr, Source, selectBuilder.selection.value.ColumnHead, selectBuilder.selection.value.SelectionTail] = {
type B0 = SelectionSet.ConsAux[selectBuilder.selection.value.ResultTypeRepr, Source, selectBuilder.selection.value.ColumnHead, selectBuilder.selection.value.SelectionTail]
val b: B0 = selectBuilder.selection.value.asInstanceOf[B0]

Expand All @@ -44,7 +44,7 @@ trait SelectModule { self: ExprModule with TableModule =>

val columnSet : CS

def asTable(tableName: TableName): columnSet.TableSource = columnSet.table(tableName)
def asTable(tableName: TableName): columnSet.TableSource = columnSet.table(tableName)

/**
* Maps the [[Read]] query's output to another type by providing a function
Expand Down Expand Up @@ -256,8 +256,8 @@ trait SelectModule { self: ExprModule with TableModule =>
override type ColumnsRepr[X] = read.ColumnsRepr[X]
}

sealed case class Select[F, Repr, Source](
selection: Selection[F, Source, SelectionSet.ConsAux[Repr, Source, _, _ <: SelectionSet[Source]]],
sealed case class Select[F, Repr, Source, Head, Tail <: SelectionSet[Source]](
selection: Selection[F, Source, SelectionSet.ConsAux[Repr, Source, Head, Tail]],
table: Option[Table.Aux[Source]],
whereExpr: Expr[_, Source, Boolean],
groupBy: List[Expr[_, Source, Any]],
Expand All @@ -270,26 +270,26 @@ trait SelectModule { self: ExprModule with TableModule =>

val mapper: Repr => Repr = identity(_)

def where(whereExpr2: Expr[_, Source, Boolean]): Select[F, Repr, Source] =
def where(whereExpr2: Expr[_, Source, Boolean]): Select[F, Repr, Source, Head, Tail] =
copy(whereExpr = self.whereExpr && whereExpr2)

def limit(n: Long): Select[F, Repr, Source] = copy(limit = Some(n))
def limit(n: Long): Select[F, Repr, Source, Head, Tail] = copy(limit = Some(n))

def offset(n: Long): Select[F, Repr, Source] = copy(offset = Some(n))
def offset(n: Long): Select[F, Repr, Source, Head, Tail] = copy(offset = Some(n))

def orderBy(o: Ordering[Expr[_, Source, Any]], os: Ordering[Expr[_, Source, Any]]*): Select[F, Repr, Source] =
def orderBy(o: Ordering[Expr[_, Source, Any]], os: Ordering[Expr[_, Source, Any]]*): Select[F, Repr, Source, Head, Tail] =
copy(orderBy = self.orderBy ++ (o :: os.toList))

def groupBy(key: Expr[_, Source, Any], keys: Expr[_, Source, Any]*)(implicit
ev: Features.IsAggregated[F]
): Select[F, Repr, Source] = {
): Select[F, Repr, Source, Head, Tail] = {
val _ = ev
copy(groupBy = groupBy ++ (key :: keys.toList))
}

def having(havingExpr2: Expr[_, Source, Boolean])(implicit
ev: Features.IsAggregated[F]
): Select[F, Repr, Source] = {
): Select[F, Repr, Source, Head, Tail] = {
val _ = ev
copy(havingExpr = self.havingExpr && havingExpr2)
}
Expand Down Expand Up @@ -498,7 +498,7 @@ trait SelectModule { self: ExprModule with TableModule =>
Cons[Source1, A, tail.Append[Source1, That]](head, tail ++ that)

override def selectionsUntyped: List[ColumnSelection[Source, _]] = head :: tail.selectionsUntyped

override def selections[Source1 <: Source, T]: SelectionsRepr[Source1, T] = (head, tail.selections[Source1, T])
}
}
Expand Down
10 changes: 8 additions & 2 deletions mysql/src/main/scala/zio/sql/mysql/MysqlModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,14 @@ trait MysqlModule extends Jdbc { self =>
case Read.Mapped(read, _) =>
renderReadImpl(read)
case read0 @ Read.Select(_, _, _, _, _, _, _, _) =>
object Dummy { type F; type A; type B <: SelectionSet[A] }
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.A, Dummy.B]]
object Dummy {
type F
type Repr
type Source
type Head
type Tail <: SelectionSet[Source]
}
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.Repr, Dummy.Source, Dummy.Head, Dummy.Tail]]
import read._

render("SELECT ")
Expand Down
12 changes: 7 additions & 5 deletions oracle/src/main/scala/zio/sql/oracle/OracleModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,13 @@ trait OracleModule extends Jdbc { self =>

case read0 @ Read.Select(_, _, _, _, _, _, _, _) =>
object Dummy {
type F
type A
type B <: SelectionSet[A]
}
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.A, Dummy.B]]
type F
type Repr
type Source
type Head
type Tail <: SelectionSet[Source]
}
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.Repr, Dummy.Source, Dummy.Head, Dummy.Tail]]
import read._

builder.append("SELECT ")
Expand Down
10 changes: 8 additions & 2 deletions postgres/src/main/scala/zio/sql/postgresql/PostgresModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,14 @@ trait PostgresModule extends Jdbc { self =>
read match {
case Read.Mapped(read, _) => renderReadImpl(read)
case read0 @ Read.Select(_, _, _, _, _, _, _, _) =>
object Dummy { type F; type A; type B <: SelectionSet[A] }
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.A, Dummy.B]]
object Dummy {
type F
type Repr
type Source
type Head
type Tail <: SelectionSet[Source]
}
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.Repr, Dummy.Source, Dummy.Head, Dummy.Tail]]
import read._

render("SELECT ")
Expand Down
157 changes: 77 additions & 80 deletions sqlserver/src/main/scala/zio/sql/sqlserver/SqlServerModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package zio.sql.sqlserver

import zio.sql.Jdbc

import scala.language.implicitConversions

trait SqlServerModule extends Jdbc { self =>

import self.ColumnSet._
Expand All @@ -14,59 +12,55 @@ trait SqlServerModule extends Jdbc { self =>

sealed trait SqlServerTable[+A] extends Table.TableEx

object SqlServerTable {

sealed case class SelectedTable[F1, F2, ColumnsRepr[_], Cols, A, B](
crossType: CrossType,
left: Table.Source.Aux[ColumnsRepr, A, Cols],
//tableValuedFuctnion : TableValuedFunction ???
select: Read.Select[F1, Cols, B],
expr: Expr[_, A with B, Boolean]
) extends SqlServerTable[A with B] { self =>

// def where(whereExpr: Expr[F1 :||: F2, A with B, Boolean]): SelectedTable[F1, F2, ColumnsRepr, Cols, A, B] =
// self.copy(expr = whereExpr)

def columnsUntyped: List[Column.Untyped] = left.columnsUntyped ++ select.table.get.columnsUntyped
}

implicit def tableSourceToSelectedBuilder[ColumnsRepr[_], A, Cols](
table: Table.Source.Aux[ColumnsRepr, A, Cols]
): SelectedTableBuilder[ColumnsRepr, A, Cols] =
new SelectedTableBuilder(table)

sealed case class SelectedTableBuilder[ColumnsRepr[_], A, Cols](table: Table.Source.Aux[ColumnsRepr, A, Cols]) {
self =>

/**
* Instead of Read.Select we need to accept some 'TableValuedFunction' which would:
* (or we could accept Select and turn it into TableValuedFunction - but we need to make sure only sensible things compile)
* - contain selection, table and optionally where clause
* - create new Table of type B created out of columns in select.selection
* - where clause need to access Table.Aux[A] and origin select.Table to create Expr.
*/
final def crossApply[F1, F2, SelectionCols, SelectTableType](
select: Read.Select[F1, SelectionCols, SelectTableType]
): SelectedTable[F1, F2, ColumnsRepr, Cols, table.TableType, SelectTableType] = {

select.selection.value.selectionsUntyped.map(_.asInstanceOf[ColumnSelection[_, _]]).map {
case t @ ColumnSelection.Constant(value, _) => t.typeTag
case t @ ColumnSelection.Computed(expr, _) => expr
}
???
}

final def outerApply[F1, F2, SelectTableType](
select: Read.Select[F1, Cols, SelectTableType]
): SelectedTable[F1, F2, ColumnsRepr, Cols, table.TableType, SelectTableType] =
SelectedTable[F1, F2, ColumnsRepr, Cols, A, SelectTableType](
CrossType.OuterApply,
table,
select,
Expr.literal(false)
)
}
}
// object SqlServerTable {

// sealed case class SelectedTable[F1, F2, ColumnsRepr[_], Cols, A, B](
// crossType: CrossType,
// left: Table.Source.Aux[ColumnsRepr, A, Cols],
// //tableValuedFuctnion : TableValuedFunction ???
// select: Read.Select[F1, Cols, B],
// expr: Expr[_, A with B, Boolean]
// ) extends SqlServerTable[A with B] { self =>

// // def where(whereExpr: Expr[F1 :||: F2, A with B, Boolean]): SelectedTable[F1, F2, ColumnsRepr, Cols, A, B] =
// // self.copy(expr = whereExpr)

// def columnsUntyped: List[Column.Untyped] = left.columnsUntyped ++ select.table.get.columnsUntyped
// }

// implicit def tableSourceToSelectedBuilder[ColumnsRepr[_], A, Cols](
// table: Table.Source.Aux[ColumnsRepr, A, Cols]
// ): SelectedTableBuilder[ColumnsRepr, A, Cols] =
// new SelectedTableBuilder(table)

// sealed case class SelectedTableBuilder[ColumnsRepr[_], A, Cols](table: Table.Source.Aux[ColumnsRepr, A, Cols]) {
// self =>

// /**
// * Instead of Read.Select we need to accept some 'TableValuedFunction' which would:
// * (or we could accept Select and turn it into TableValuedFunction - but we need to make sure only sensible things compile)
// * - contain selection, table and optionally where clause
// * - create new Table of type B created out of columns in select.selection
// * - where clause need to access Table.Aux[A] and origin select.Table to create Expr.
// */
// final def crossApply[F1, F2, SelectionCols, SelectTableType](
// select: Read.Select[F1, SelectionCols, SelectTableType]
// ): SelectedTable[F1, F2, ColumnsRepr, Cols, table.TableType, SelectTableType] = {

// ???
// }

// final def outerApply[F1, F2, SelectTableType](
// select: Read.Select[F1, Cols, SelectTableType]
// ): SelectedTable[F1, F2, ColumnsRepr, Cols, table.TableType, SelectTableType] =
// SelectedTable[F1, F2, ColumnsRepr, Cols, A, SelectTableType](
// CrossType.OuterApply,
// table,
// select,
// Expr.literal(false)
// )
// }
// }

sealed trait CrossType
object CrossType {
Expand All @@ -84,19 +78,20 @@ trait SqlServerModule extends Jdbc { self =>
// val customerId :*: fName :*: lName :*: verified :*: dob :*: _ =
// customers.columns

val customers: Table.Source{type Repr[X] = (SqlServerModule.this.Expr[SqlServerModule.this.Features.Source,X,java.util.UUID], (SqlServerModule.this.Expr[SqlServerModule.this.Features.Source,X,String], (SqlServerModule.this.Expr[SqlServerModule.this.Features.Source,X,String], Unit))); type Cols = SqlServerModule.this.ColumnSet.Cons[java.util.UUID,SqlServerModule.this.ColumnSet.Cons[String,SqlServerModule.this.ColumnSet.Cons[String,SqlServerModule.this.ColumnSet.Empty.type]]]} =
(uuid("id") ++ string("first_name") ++ string("last_name")).table("customers")
val customers = (uuid("id") ++ string("first_name") ++ string("last_name")).table("customers")

val customerId :*: fName :*: lName :*: _ = customers.columns

val orders = (uuid("id") ++ uuid("customer_id") ++ localDate("order_date")).table("orders")

val orderId :*: fkCustomerId :*: orderDate :*: _ = orders.columns

// val derived = //: Table.Source{type Repr[X] = (SqlServerModule.this.Expr[SqlServerModule.this.Features.Source,X,_$1], _1.type#columnSet.tail.ColumnsRepr[X]); type Cols = SqlServerModule.this.ColumnSet.Cons[_$1,_1.type#selection.value.tail.CS]}( forSome { type _$1; val _1: Read.Select[Features.Union[Features.Source,Features.Source],(UUID, (String, Unit)),customers.TableType]; val stabilizer$1: SelectBuilder[Features.Union[Features.Source,Features.Source],customers.TableType,SelectionSet.Cons[customers.TableType,UUID,SelectionSet.Cons[customers.TableType,String,SelectionSet.Empty]]] })
// select(customerId ++ fName).from(customers).asTable("derivedCustomers")
val derived =
select(customerId ++ fName).from(customers).asTable("derivedCustomers")

val derivedId :*: derivedName = derived.columns

// val e = select(fName ++ lName).from(customers).asTable(TableName.Source("derivedCustomers"))
val e = select(fName ++ lName).from(customers).asTable(TableName.Source("derivedCustomers"))

//JOIN example
val joinQuery = select(fName ++ lName ++ orderDate).from(customers.join(orders).on(customerId === fkCustomerId))
Expand Down Expand Up @@ -244,10 +239,12 @@ trait SqlServerModule extends Jdbc { self =>
case read0 @ Read.Select(_, _, _, _, _, _, _, _) =>
object Dummy {
type F
type A
type B <: SelectionSet[A]
type Repr
type Source
type Head
type Tail <: SelectionSet[Source]
}
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.A, Dummy.B]]
val read = read0.asInstanceOf[Read.Select[Dummy.F, Dummy.Repr, Dummy.Source, Dummy.Head, Dummy.Tail]]
import read._

builder.append("select ")
Expand Down Expand Up @@ -373,27 +370,27 @@ trait SqlServerModule extends Jdbc { self =>
case sourceTable: self.Table.Source =>
val _ = builder.append(sourceTable.name)

case Table.DialectSpecificTable(table) =>
table match {
case SqlServerSpecific.SqlServerTable.SelectedTable(crossType, left, select, on) =>
buildTable(left)
case Table.DialectSpecificTable(table) =>
// table match {
// case SqlServerSpecific.SqlServerTable.SelectedTable(crossType, left, select, on) =>
// buildTable(left)

crossType match {
case SqlServerSpecific.CrossType.CrossApply => builder.append(" CROSS APPLY ( ")
case SqlServerSpecific.CrossType.OuterApply => builder.append(" OUTER APPLY ( ")
}
// crossType match {
// case SqlServerSpecific.CrossType.CrossApply => builder.append(" CROSS APPLY ( ")
// case SqlServerSpecific.CrossType.OuterApply => builder.append(" OUTER APPLY ( ")
// }

builder.append("SELECT ")
buildSelection(select.selection.value)
builder.append(" FROM ")
buildTable(select.table.get)
builder.append(" WHERE ")
buildExpr(on)
// builder.append("SELECT ")
// buildSelection(select.selection.value)
// builder.append(" FROM ")
// buildTable(select.table.get)
// builder.append(" WHERE ")
// buildExpr(on)

builder.append(" ) ")
val _ = buildTable(select.table.get)
// builder.append(" ) ")
// val _ = buildTable(select.table.get)

}
// }

case Table.Joined(joinType, left, right, on) =>
buildTable(left)
Expand Down

0 comments on commit d400999

Please sign in to comment.