Skip to content

Adding filterIf and filterOpt utility methods to Select #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,130 @@ ShippingInfo.select



### Select.filterIf.filter not added



```scala
ShippingInfo.select.filterIf(false)(_.buyerId `=` 2)
```


*
```sql
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
```



*
```scala
Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
)
```



### Select.filterIf.filter added



```scala
ShippingInfo.select.filterIf(true)(_.buyerId `=` 2)
```


*
```sql
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
WHERE (shipping_info0.buyer_id = ?)
```



*
```scala
Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
)
```



### Select.filterOpt.filter not added



```scala
ShippingInfo.select.filterOpt[Int](None)((table, value) => table.buyerId `=` value)
```


*
```sql
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
```



*
```scala
Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
)
```



### Select.filterOpt.filter added



```scala
ShippingInfo.select.filterOpt(Some(2))((table, value) => table.buyerId `=` value)
```


*
```sql
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
WHERE (shipping_info0.buyer_id = ?)
```



*
```scala
Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
)
```



### Select.map.single

`.map` allows you to select exactly what you want to return from
Expand Down
24 changes: 24 additions & 0 deletions scalasql/query/src/Select.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,21 @@ trait Select[Q, R]
*/
def withFilter(f: Q => Expr[Boolean]): Select[Q, R] = filter(f)

/**
* Filters this [[Select]] with the given predicate, if [[cond]] evaluates to true
*/
def filterIf(cond: Boolean)(
f: Q => Expr[Boolean]
): Select[Q, R]

/**
* Filters this [[Select]] with the given predicate consuming provided option as a part of predicate's input,
* if this option is Some[T]
*/
def filterOpt[T](option: Option[T])(
f: (Q, T) => Expr[Boolean]
): Select[Q, R]

/**
* Performs one or more aggregates in a single [[Select]]
*/
Expand Down Expand Up @@ -214,6 +229,9 @@ trait Select[Q, R]
*/
def head: Query.Single[R] = take(1).single

// TODO
// def headOption: Query.Single[Option[R]] = take(1).single

/**
* Converts this [[Select]] into an [[Expr]], assuming it returns a single row and
* a single column. Note that if this returns multiple rows, behavior is database-specific,
Expand Down Expand Up @@ -325,6 +343,12 @@ object Select {

override def filter(f: Q => Expr[Boolean]): Select[Q, R] = selectToSimpleSelect().filter(f)

override def filterIf(cond: Boolean)(f: Q => Expr[Boolean]): Select[Q, R] =
selectToSimpleSelect().filterIf(cond)(f)

override def filterOpt[T](option: Option[T])(f: (Q, T) => Expr[Boolean]): Select[Q, R] =
selectToSimpleSelect().filterOpt(option)(f)

override def aggregate[E, V](f: Aggregatable.Proxy[Q] => E)(
implicit qr: Queryable.Row[E, V]
): Aggregate[E, V] = selectToSimpleSelect().aggregate(f)
Expand Down
8 changes: 8 additions & 0 deletions scalasql/query/src/SimpleSelect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ class SimpleSelect[Q, R](
else copy(groupBy0 = groupBy0.map(g => g.copy(having = g.having ++ Seq(f(expr)))))
}

def filterIf(cond: Boolean)(f: Q => Expr[Boolean]): Select[Q, R] =
if (cond) this.filter(f) else this

def filterOpt[T](option: Option[T])(f: (Q, T) => Expr[Boolean]): Select[Q, R] = option match {
case None => this
case Some(opt) => this.filter(q => f(q, opt))
}

def join0[Q2, R2, QF, RF](
prefix: String,
other: Joinable[Q2, R2],
Expand Down
74 changes: 74 additions & 0 deletions scalasql/test/src/query/SelectTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,80 @@ trait SelectTests extends ScalaSqlSuite {
)
}

test("filterIf") {
test("filter not added") - checker(
query = Text { ShippingInfo.select.filterIf(false)(_.buyerId `=` 2) },
sql = """
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
""",
value = Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
),
docs = ""
)
test("filter added") - checker(
query = Text { ShippingInfo.select.filterIf(true)(_.buyerId `=` 2) },
sql = """
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
WHERE (shipping_info0.buyer_id = ?)
""",
value = Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
),
docs = ""
)
}

test("filterOpt") {
test("filter not added") - checker(
query = Text {
ShippingInfo.select.filterOpt[Int](None)((table, value) => table.buyerId `=` value)
},
sql = """
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
""",
value = Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
),
docs = ""
)
test("filter added") - checker(
query = Text {
ShippingInfo.select.filterOpt(Some(2))((table, value) => table.buyerId `=` value)
},
sql = """
SELECT
shipping_info0.id AS id,
shipping_info0.buyer_id AS buyer_id,
shipping_info0.shipping_date AS shipping_date
FROM shipping_info shipping_info0
WHERE (shipping_info0.buyer_id = ?)
""",
value = Seq(
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
),
docs = ""
)
}

test("map") {
test("single") - checker(
query = Text { Buyer.select.map(_.name) },
Expand Down