Skip to content

Commit

Permalink
Add Fields#compositeIdIn and Fields#compositeIdIs (#102)
Browse files Browse the repository at this point in the history
* Add `Fields#compositeIdIn` and `Fields#compositeIdIs`

Can now query things like this:
```scala
        query2 = emailaddressRepo.select.where(_.compositeIdIn(Array(emailaddress2.compositeId, emailaddress3.compositeId)))
```

* expose `joinOn` and `leftJoinOn`

after #101 they do make a lot of sense to use
  • Loading branch information
oyvindberg authored May 28, 2024
1 parent ccc188f commit f70055f
Show file tree
Hide file tree
Showing 86 changed files with 1,017 additions and 73 deletions.
4 changes: 2 additions & 2 deletions typo-dsl-anorm/src/scala/typo/dsl/SelectBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ trait SelectBuilder[Fields, Row] {

protected def withParams(sqlParams: SelectParams[Fields, Row]): SelectBuilder[Fields, Row]

protected def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[Joined[Fields, Fields2], (Row, Row2)]

protected def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[LeftJoined[Fields, Fields2], (Row, Option[Row2])]
}
29 changes: 24 additions & 5 deletions typo-dsl-anorm/src/scala/typo/dsl/SqlExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,30 @@ object SqlExpr {
}
}

case class CompositeIn[Tuple, Row](tuples: Array[Tuple])(val parts: CompositeIn.TuplePart[Tuple, ?, Row]*) extends SqlExpr[Boolean, Required] {
override def render(ctx: RenderCtx, counter: AtomicInteger): Fragment = {
val fieldNames: Seq[Fragment] =
parts.map(part => frag"${part.field.render(ctx, counter)}")

val unnests: Seq[Fragment] =
parts.map { case part: CompositeIn.TuplePart[Tuple, t, Row] =>
val partExpr: Const[Array[t], Required] = part.asConst(tuples.map(part.extract)(using part.CT))
frag"unnest(${partExpr.render(ctx, counter)})"
}

frag"(${fieldNames.mkFragment(", ")}) in (select ${unnests.mkFragment(", ")})"
}
}

object CompositeIn {
case class TuplePart[Tuple, T, Row](field: IdField[T, Row])(val extract: Tuple => T)(implicit val asConst: Const.As[Array[T], Required], val CT: ClassTag[T])
}

case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
override def render(ctx: RenderCtx, counter: AtomicInteger): Fragment =
frag"(" ++ exprs.map(_.render(ctx, counter)).mkFragment(",") ++ frag")"
}

final case class IsNull[T](expr: SqlExpr[T, Option]) extends SqlExpr[Boolean, Required] {
override def render(ctx: RenderCtx, counter: AtomicInteger): Fragment =
frag"${expr.render(ctx, counter)} IS NULL"
Expand Down Expand Up @@ -227,11 +251,6 @@ object SqlExpr {
def desc(implicit O: Ordering[T], N: Nullability[N]): SortOrder[T, N] = SortOrder(expr, ascending = false, nullsFirst = false)
}

final case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
override def render(ctx: RenderCtx, counter: AtomicInteger): Fragment =
frag"(" ++ exprs.map(_.render(ctx, counter)).mkFragment(",") ++ frag")"
}

implicit class SqlExprArraySyntax[T, N[_]](private val expr: SqlExpr[Array[T], N]) extends AnyVal {

/** look up an element in an array at index `idx` */
Expand Down
4 changes: 2 additions & 2 deletions typo-dsl-doobie/src/scala/typo/dsl/SelectBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ trait SelectBuilder[Fields, Row] {

protected def withParams(sqlParams: SelectParams[Fields, Row]): SelectBuilder[Fields, Row]

protected def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[Joined[Fields, Fields2], (Row, Row2)]

protected def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[LeftJoined[Fields, Fields2], (Row, Option[Row2])]
}
28 changes: 24 additions & 4 deletions typo-dsl-doobie/src/scala/typo/dsl/SqlExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.implicits.toFoldableOps
import doobie.Fragment
import doobie.implicits.toSqlInterpolator
import doobie.util.{Put, Write}
import typo.dsl.internal.mkFragment.FragmentOps

import scala.reflect.ClassTag

Expand Down Expand Up @@ -199,6 +200,29 @@ object SqlExpr {
fr"${expr.render(ctx)} = ANY(${Write.fromPut(ev).toFragment(values)})"
}

case class CompositeIn[Tuple, Row](tuples: Array[Tuple])(val parts: CompositeIn.TuplePart[Tuple, ?, Row]*) extends SqlExpr[Boolean, Required] {
override def render(ctx: RenderCtx): Fragment = {
val fieldNames: Seq[Fragment] =
parts.map(part => fr"${part.field.render(ctx)}")

val unnests: Seq[Fragment] =
parts.map { case part: CompositeIn.TuplePart[Tuple, t, Row] =>
val partExpr: Const[Array[t], Required] = part.asConst(tuples.map(part.extract)(part.CT))
sql"unnest(${partExpr.render(ctx)})"
}

sql"(${fieldNames.mkFragment(fr",")}) in (select ${unnests.mkFragment(fr",")})"
}
}

object CompositeIn {
case class TuplePart[Tuple, T, Row](field: IdField[T, Row])(val extract: Tuple => T)(implicit val asConst: Const.As[Array[T], Required], val CT: ClassTag[T])
}

case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
override def render(ctx: RenderCtx): Fragment = fr"(${exprs.map(_.render(ctx)).intercalate(fr",")})"
}

final case class IsNull[T](expr: SqlExpr[T, Option]) extends SqlExpr[Boolean, Required] {
override def render(ctx: RenderCtx): Fragment =
fr"${expr.render(ctx)} IS NULL"
Expand Down Expand Up @@ -227,10 +251,6 @@ object SqlExpr {
def desc(implicit O: Ordering[T], N: Nullability[N]): SortOrder[T, N] = SortOrder(expr, ascending = false, nullsFirst = false)
}

final case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
override def render(ctx: RenderCtx): Fragment = fr"(${exprs.map(_.render(ctx)).intercalate(fr",")})"
}

implicit class SqlExprArraySyntax[T, N[_]](private val expr: SqlExpr[Array[T], N]) extends AnyVal {

/** look up an element in an array at index `idx` */
Expand Down
12 changes: 12 additions & 0 deletions typo-dsl-doobie/src/scala/typo/dsl/internal/mkFragment.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package typo.dsl.internal

import doobie.util.fragment.Fragment

object mkFragment {
implicit class FragmentOps[I[t] <: Iterable[t]](fragments: I[Fragment]) {
def mkFragment(sep: Fragment): Fragment = {
fragments.reduceOption((a, b) => a ++ sep ++ b).getOrElse(Fragment.empty)
}
}

}
6 changes: 6 additions & 0 deletions typo-dsl-shared/typo/dsl/Structure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ trait Structure[Fields, Row] {
x.N.toOpt(untypedEval(x.expr, row))
case x: SqlExpr.RowExpr =>
x.exprs.map(expr => untypedEval(expr, row))
case x: SqlExpr.CompositeIn[t, Row] @unchecked /* for 2.13 */ =>
val thisRow: Seq[?] = x.parts.map(part => untypedEval(part.field, row))
x.tuples.exists { tuple =>
val thatRow: Seq[?] = x.parts.map(part => part.extract(tuple))
thisRow == thatRow
}
}

final def join[Fields2, Row2](other: Structure[Fields2, Row2]): Structure[Joined[Fields, Fields2], (Row, Row2)] =
Expand Down
6 changes: 2 additions & 4 deletions typo-dsl-zio-jdbc/src/scala/typo/dsl/SelectBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,9 @@ trait SelectBuilder[Fields, Row] {

protected def withParams(sqlParams: SelectParams[Fields, Row]): SelectBuilder[Fields, Row]

protected def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[Joined[Fields, Fields2], (Row, Row2)]
def joinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]): SelectBuilder[Joined[Fields, Fields2], (Row, Row2)]

protected def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
def leftJoinOn[Fields2, N[_]: Nullability, Row2](other: SelectBuilder[Fields2, Row2])(
pred: Joined[Fields, Fields2] => SqlExpr[Boolean, N]
): SelectBuilder[LeftJoined[Fields, Fields2], (Row, Option[Row2])]
}
22 changes: 21 additions & 1 deletion typo-dsl-zio-jdbc/src/scala/typo/dsl/SqlExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,27 @@ object SqlExpr {
def desc(implicit O: Ordering[T], N: Nullability[N]): SortOrder[T, N] = SortOrder(expr, ascending = false, nullsFirst = false)
}

final case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
case class CompositeIn[Tuple, Row](tuples: Array[Tuple])(val parts: CompositeIn.TuplePart[Tuple, ?, Row]*) extends SqlExpr[Boolean, Required] {
override def render(ctx: RenderCtx): SqlFragment = {
val fieldNames: Seq[SqlFragment] =
parts.map(part => sql"${part.field.render(ctx)}")

val unnests: Seq[SqlFragment] =
parts
.map { case part: CompositeIn.TuplePart[Tuple, t, Row] =>
val partExpr: Const[Array[t], Required] = part.asConst(tuples.map(part.extract)(part.CT))
sql"unnest(${partExpr.render(ctx)})"
}

sql"(${fieldNames.mkFragment(", ")}) in (select ${unnests.mkFragment(", ")})"
}
}

object CompositeIn {
case class TuplePart[Tuple, T, Row](field: IdField[T, Row])(val extract: Tuple => T)(implicit val asConst: Const.As[Array[T], Required], val CT: ClassTag[T])
}

case class RowExpr(exprs: List[SqlExpr.SqlExprNoHkt[?]]) extends SqlExpr[List[?], Required] {
override def render(ctx: RenderCtx): SqlFragment = exprs.map(_.render(ctx)).mkFragment(sql"(", sql",", sql")")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import adventureworks.humanresources.shift.ShiftRow
import adventureworks.person.businessentity.BusinessentityId
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -42,6 +46,11 @@ trait EmployeedepartmenthistoryFields {
def fkShift: ForeignKey[ShiftFields, ShiftRow] =
ForeignKey[ShiftFields, ShiftRow]("humanresources.FK_EmployeeDepartmentHistory_Shift_ShiftID", Nil)
.withColumnPair(shiftid, _.shiftid)
def compositeIdIs(compositeId: EmployeedepartmenthistoryId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(startdate.isEqual(compositeId.startdate)).and(departmentid.isEqual(compositeId.departmentid)).and(shiftid.isEqual(compositeId.shiftid))
def compositeIdIn(compositeIds: Array[EmployeedepartmenthistoryId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(startdate)(_.startdate), TuplePart(departmentid)(_.departmentid), TuplePart(shiftid)(_.shiftid))

}

object EmployeedepartmenthistoryFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import adventureworks.humanresources.employee.EmployeeRow
import adventureworks.person.businessentity.BusinessentityId
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -28,6 +32,11 @@ trait EmployeepayhistoryFields {
def fkEmployee: ForeignKey[EmployeeFields, EmployeeRow] =
ForeignKey[EmployeeFields, EmployeeRow]("humanresources.FK_EmployeePayHistory_Employee_BusinessEntityID", Nil)
.withColumnPair(businessentityid, _.businessentityid)
def compositeIdIs(compositeId: EmployeepayhistoryId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(ratechangedate.isEqual(compositeId.ratechangedate))
def compositeIdIn(compositeIds: Array[EmployeepayhistoryId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(ratechangedate)(_.ratechangedate))

}

object EmployeepayhistoryFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import adventureworks.person.businessentity.BusinessentityId
import adventureworks.person.businessentity.BusinessentityRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -40,6 +44,11 @@ trait BusinessentityaddressFields {
def fkBusinessentity: ForeignKey[BusinessentityFields, BusinessentityRow] =
ForeignKey[BusinessentityFields, BusinessentityRow]("person.FK_BusinessEntityAddress_BusinessEntity_BusinessEntityID", Nil)
.withColumnPair(businessentityid, _.businessentityid)
def compositeIdIs(compositeId: BusinessentityaddressId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(addressid.isEqual(compositeId.addressid)).and(addresstypeid.isEqual(compositeId.addresstypeid))
def compositeIdIn(compositeIds: Array[BusinessentityaddressId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(addressid)(_.addressid), TuplePart(addresstypeid)(_.addresstypeid))

}

object BusinessentityaddressFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import adventureworks.person.person.PersonFields
import adventureworks.person.person.PersonRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -39,6 +43,11 @@ trait BusinessentitycontactFields {
def fkBusinessentity: ForeignKey[BusinessentityFields, BusinessentityRow] =
ForeignKey[BusinessentityFields, BusinessentityRow]("person.FK_BusinessEntityContact_BusinessEntity_BusinessEntityID", Nil)
.withColumnPair(businessentityid, _.businessentityid)
def compositeIdIs(compositeId: BusinessentitycontactId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(personid.isEqual(compositeId.personid)).and(contacttypeid.isEqual(compositeId.contacttypeid))
def compositeIdIn(compositeIds: Array[BusinessentitycontactId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(personid)(_.personid), TuplePart(contacttypeid)(_.contacttypeid))

}

object BusinessentitycontactFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import adventureworks.person.person.PersonFields
import adventureworks.person.person.PersonRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -29,6 +33,11 @@ trait EmailaddressFields {
def fkPerson: ForeignKey[PersonFields, PersonRow] =
ForeignKey[PersonFields, PersonRow]("person.FK_EmailAddress_Person_BusinessEntityID", Nil)
.withColumnPair(businessentityid, _.businessentityid)
def compositeIdIs(compositeId: EmailaddressId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(emailaddressid.isEqual(compositeId.emailaddressid))
def compositeIdIn(compositeIds: Array[EmailaddressId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(emailaddressid)(_.emailaddressid))

}

object EmailaddressFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import adventureworks.person.phonenumbertype.PhonenumbertypeRow
import adventureworks.public.Phone
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -33,6 +37,11 @@ trait PersonphoneFields {
def fkPhonenumbertype: ForeignKey[PhonenumbertypeFields, PhonenumbertypeRow] =
ForeignKey[PhonenumbertypeFields, PhonenumbertypeRow]("person.FK_PersonPhone_PhoneNumberType_PhoneNumberTypeID", Nil)
.withColumnPair(phonenumbertypeid, _.phonenumbertypeid)
def compositeIdIs(compositeId: PersonphoneId): SqlExpr[Boolean, Required] =
businessentityid.isEqual(compositeId.businessentityid).and(phonenumber.isEqual(compositeId.phonenumber)).and(phonenumbertypeid.isEqual(compositeId.phonenumbertypeid))
def compositeIdIn(compositeIds: Array[PersonphoneId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(businessentityid)(_.businessentityid), TuplePart(phonenumber)(_.phonenumber), TuplePart(phonenumbertypeid)(_.phonenumbertypeid))

}

object PersonphoneFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import adventureworks.production.product.ProductId
import adventureworks.production.product.ProductRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -28,6 +32,11 @@ trait ProductcosthistoryFields {
def fkProduct: ForeignKey[ProductFields, ProductRow] =
ForeignKey[ProductFields, ProductRow]("production.FK_ProductCostHistory_Product_ProductID", Nil)
.withColumnPair(productid, _.productid)
def compositeIdIs(compositeId: ProductcosthistoryId): SqlExpr[Boolean, Required] =
productid.isEqual(compositeId.productid).and(startdate.isEqual(compositeId.startdate))
def compositeIdIn(compositeIds: Array[ProductcosthistoryId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(productid)(_.productid), TuplePart(startdate)(_.startdate))

}

object ProductcosthistoryFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import adventureworks.production.product.ProductId
import adventureworks.production.product.ProductRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -31,6 +35,11 @@ trait ProductdocumentFields {
def fkDocument: ForeignKey[DocumentFields, DocumentRow] =
ForeignKey[DocumentFields, DocumentRow]("production.FK_ProductDocument_Document_DocumentNode", Nil)
.withColumnPair(documentnode, _.documentnode)
def compositeIdIs(compositeId: ProductdocumentId): SqlExpr[Boolean, Required] =
productid.isEqual(compositeId.productid).and(documentnode.isEqual(compositeId.documentnode))
def compositeIdIn(compositeIds: Array[ProductdocumentId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(productid)(_.productid), TuplePart(documentnode)(_.documentnode))

}

object ProductdocumentFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import adventureworks.production.product.ProductId
import adventureworks.production.product.ProductRow
import typo.dsl.ForeignKey
import typo.dsl.Path
import typo.dsl.Required
import typo.dsl.SqlExpr
import typo.dsl.SqlExpr.CompositeIn
import typo.dsl.SqlExpr.CompositeIn.TuplePart
import typo.dsl.SqlExpr.Field
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
Expand All @@ -37,6 +41,11 @@ trait ProductinventoryFields {
def fkProduct: ForeignKey[ProductFields, ProductRow] =
ForeignKey[ProductFields, ProductRow]("production.FK_ProductInventory_Product_ProductID", Nil)
.withColumnPair(productid, _.productid)
def compositeIdIs(compositeId: ProductinventoryId): SqlExpr[Boolean, Required] =
productid.isEqual(compositeId.productid).and(locationid.isEqual(compositeId.locationid))
def compositeIdIn(compositeIds: Array[ProductinventoryId]): SqlExpr[Boolean, Required] =
new CompositeIn(compositeIds)(TuplePart(productid)(_.productid), TuplePart(locationid)(_.locationid))

}

object ProductinventoryFields {
Expand Down
Loading

0 comments on commit f70055f

Please sign in to comment.