Skip to content

Commit b505d60

Browse files
authored
Adding filterIf and filterOpt utility methods to Select (#77)
fixes #63
1 parent 8acd9b2 commit b505d60

File tree

4 files changed

+230
-0
lines changed

4 files changed

+230
-0
lines changed

docs/reference.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,130 @@ ShippingInfo.select
738738
739739
740740
741+
### Select.filterIf.filter not added
742+
743+
744+
745+
```scala
746+
ShippingInfo.select.filterIf(false)(_.buyerId `=` 2)
747+
```
748+
749+
750+
*
751+
```sql
752+
SELECT
753+
shipping_info0.id AS id,
754+
shipping_info0.buyer_id AS buyer_id,
755+
shipping_info0.shipping_date AS shipping_date
756+
FROM shipping_info shipping_info0
757+
```
758+
759+
760+
761+
*
762+
```scala
763+
Seq(
764+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
765+
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
766+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
767+
)
768+
```
769+
770+
771+
772+
### Select.filterIf.filter added
773+
774+
775+
776+
```scala
777+
ShippingInfo.select.filterIf(true)(_.buyerId `=` 2)
778+
```
779+
780+
781+
*
782+
```sql
783+
SELECT
784+
shipping_info0.id AS id,
785+
shipping_info0.buyer_id AS buyer_id,
786+
shipping_info0.shipping_date AS shipping_date
787+
FROM shipping_info shipping_info0
788+
WHERE (shipping_info0.buyer_id = ?)
789+
```
790+
791+
792+
793+
*
794+
```scala
795+
Seq(
796+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
797+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
798+
)
799+
```
800+
801+
802+
803+
### Select.filterOpt.filter not added
804+
805+
806+
807+
```scala
808+
ShippingInfo.select.filterOpt[Int](None)((table, value) => table.buyerId `=` value)
809+
```
810+
811+
812+
*
813+
```sql
814+
SELECT
815+
shipping_info0.id AS id,
816+
shipping_info0.buyer_id AS buyer_id,
817+
shipping_info0.shipping_date AS shipping_date
818+
FROM shipping_info shipping_info0
819+
```
820+
821+
822+
823+
*
824+
```scala
825+
Seq(
826+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
827+
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
828+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
829+
)
830+
```
831+
832+
833+
834+
### Select.filterOpt.filter added
835+
836+
837+
838+
```scala
839+
ShippingInfo.select.filterOpt(Some(2))((table, value) => table.buyerId `=` value)
840+
```
841+
842+
843+
*
844+
```sql
845+
SELECT
846+
shipping_info0.id AS id,
847+
shipping_info0.buyer_id AS buyer_id,
848+
shipping_info0.shipping_date AS shipping_date
849+
FROM shipping_info shipping_info0
850+
WHERE (shipping_info0.buyer_id = ?)
851+
```
852+
853+
854+
855+
*
856+
```scala
857+
Seq(
858+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
859+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
860+
)
861+
```
862+
863+
864+
741865
### Select.map.single
742866
743867
`.map` allows you to select exactly what you want to return from

scalasql/query/src/Select.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ trait Select[Q, R]
101101
*/
102102
def withFilter(f: Q => Expr[Boolean]): Select[Q, R] = filter(f)
103103

104+
/**
105+
* Filters this [[Select]] with the given predicate, if [[cond]] evaluates to true
106+
*/
107+
def filterIf(cond: Boolean)(
108+
f: Q => Expr[Boolean]
109+
): Select[Q, R]
110+
111+
/**
112+
* Filters this [[Select]] with the given predicate consuming provided option as a part of predicate's input,
113+
* if this option is Some[T]
114+
*/
115+
def filterOpt[T](option: Option[T])(
116+
f: (Q, T) => Expr[Boolean]
117+
): Select[Q, R]
118+
104119
/**
105120
* Performs one or more aggregates in a single [[Select]]
106121
*/
@@ -214,6 +229,9 @@ trait Select[Q, R]
214229
*/
215230
def head: Query.Single[R] = take(1).single
216231

232+
// TODO
233+
// def headOption: Query.Single[Option[R]] = take(1).single
234+
217235
/**
218236
* Converts this [[Select]] into an [[Expr]], assuming it returns a single row and
219237
* a single column. Note that if this returns multiple rows, behavior is database-specific,
@@ -325,6 +343,12 @@ object Select {
325343

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

346+
override def filterIf(cond: Boolean)(f: Q => Expr[Boolean]): Select[Q, R] =
347+
selectToSimpleSelect().filterIf(cond)(f)
348+
349+
override def filterOpt[T](option: Option[T])(f: (Q, T) => Expr[Boolean]): Select[Q, R] =
350+
selectToSimpleSelect().filterOpt(option)(f)
351+
328352
override def aggregate[E, V](f: Aggregatable.Proxy[Q] => E)(
329353
implicit qr: Queryable.Row[E, V]
330354
): Aggregate[E, V] = selectToSimpleSelect().aggregate(f)

scalasql/query/src/SimpleSelect.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ class SimpleSelect[Q, R](
9595
else copy(groupBy0 = groupBy0.map(g => g.copy(having = g.having ++ Seq(f(expr)))))
9696
}
9797

98+
def filterIf(cond: Boolean)(f: Q => Expr[Boolean]): Select[Q, R] =
99+
if (cond) this.filter(f) else this
100+
101+
def filterOpt[T](option: Option[T])(f: (Q, T) => Expr[Boolean]): Select[Q, R] = option match {
102+
case None => this
103+
case Some(opt) => this.filter(q => f(q, opt))
104+
}
105+
98106
def join0[Q2, R2, QF, RF](
99107
prefix: String,
100108
other: Joinable[Q2, R2],

scalasql/test/src/query/SelectTests.scala

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,80 @@ trait SelectTests extends ScalaSqlSuite {
141141
)
142142
}
143143

144+
test("filterIf") {
145+
test("filter not added") - checker(
146+
query = Text { ShippingInfo.select.filterIf(false)(_.buyerId `=` 2) },
147+
sql = """
148+
SELECT
149+
shipping_info0.id AS id,
150+
shipping_info0.buyer_id AS buyer_id,
151+
shipping_info0.shipping_date AS shipping_date
152+
FROM shipping_info shipping_info0
153+
""",
154+
value = Seq(
155+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
156+
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
157+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
158+
),
159+
docs = ""
160+
)
161+
test("filter added") - checker(
162+
query = Text { ShippingInfo.select.filterIf(true)(_.buyerId `=` 2) },
163+
sql = """
164+
SELECT
165+
shipping_info0.id AS id,
166+
shipping_info0.buyer_id AS buyer_id,
167+
shipping_info0.shipping_date AS shipping_date
168+
FROM shipping_info shipping_info0
169+
WHERE (shipping_info0.buyer_id = ?)
170+
""",
171+
value = Seq(
172+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
173+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
174+
),
175+
docs = ""
176+
)
177+
}
178+
179+
test("filterOpt") {
180+
test("filter not added") - checker(
181+
query = Text {
182+
ShippingInfo.select.filterOpt[Int](None)((table, value) => table.buyerId `=` value)
183+
},
184+
sql = """
185+
SELECT
186+
shipping_info0.id AS id,
187+
shipping_info0.buyer_id AS buyer_id,
188+
shipping_info0.shipping_date AS shipping_date
189+
FROM shipping_info shipping_info0
190+
""",
191+
value = Seq(
192+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
193+
ShippingInfo[Sc](2, 1, LocalDate.parse("2012-04-05")),
194+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
195+
),
196+
docs = ""
197+
)
198+
test("filter added") - checker(
199+
query = Text {
200+
ShippingInfo.select.filterOpt(Some(2))((table, value) => table.buyerId `=` value)
201+
},
202+
sql = """
203+
SELECT
204+
shipping_info0.id AS id,
205+
shipping_info0.buyer_id AS buyer_id,
206+
shipping_info0.shipping_date AS shipping_date
207+
FROM shipping_info shipping_info0
208+
WHERE (shipping_info0.buyer_id = ?)
209+
""",
210+
value = Seq(
211+
ShippingInfo[Sc](1, 2, LocalDate.parse("2010-02-03")),
212+
ShippingInfo[Sc](3, 2, LocalDate.parse("2012-05-06"))
213+
),
214+
docs = ""
215+
)
216+
}
217+
144218
test("map") {
145219
test("single") - checker(
146220
query = Text { Buyer.select.map(_.name) },

0 commit comments

Comments
 (0)