11package au.com.console.jpaspecificationdsl
22
33import org.springframework.data.jpa.domain.Specification
4- import org.springframework.data.jpa.domain.Specifications
54import javax.persistence.criteria.*
65import kotlin.reflect.KProperty1
76
@@ -11,22 +10,22 @@ fun <Z, T, R> From<Z, T>.join(prop: KProperty1<T, R?>): Join<T, R> = this.join<T
1110// Helper to enable get by Property
1211fun <R > Path <* >.get (prop : KProperty1 <* , R ?>): Path <R > = this .get<R >(prop.name)
1312
14- // Version of Specifications .where that makes the CriteriaBuilder implicit
15- fun <T > where (makePredicate : CriteriaBuilder .(Root <T >) -> Predicate ): Specifications <T > =
16- Specifications .where<T > { root, _, criteriaBuilder -> criteriaBuilder.makePredicate(root) }
13+ // Version of Specification .where that makes the CriteriaBuilder implicit
14+ fun <T > where (makePredicate : CriteriaBuilder .(Root <T >) -> Predicate ): Specification <T > =
15+ Specification .where<T > { root, _, criteriaBuilder -> criteriaBuilder.makePredicate(root) }
1716
18- // helper function for defining Specifications that take a Path to a property and send it to a CriteriaBuilder
19- private fun <T , R > KProperty1 <T , R ?>.spec (makePredicate : CriteriaBuilder .(path: Path <R >) -> Predicate ): Specifications <T > =
17+ // helper function for defining Specification that take a Path to a property and send it to a CriteriaBuilder
18+ private fun <T , R > KProperty1 <T , R ?>.spec (makePredicate : CriteriaBuilder .(path: Path <R >) -> Predicate ): Specification <T > =
2019 this .let { property -> where { root -> makePredicate(root.get(property)) } }
2120
2221// Equality
23- fun <T , R > KProperty1 <T , R ?>.equal (x : R ): Specifications <T > = spec { equal(it, x) }
24- fun <T , R > KProperty1 <T , R ?>.notEqual (x : R ): Specifications <T > = spec { notEqual(it, x) }
22+ fun <T , R > KProperty1 <T , R ?>.equal (x : R ): Specification <T > = spec { equal(it, x) }
23+ fun <T , R > KProperty1 <T , R ?>.notEqual (x : R ): Specification <T > = spec { notEqual(it, x) }
2524
2625// Ignores empty collection otherwise an empty 'in' predicate will be generated which will never match any results
27- fun <T , R : Any > KProperty1 <T , R ?>.`in` (values : Collection <R >): Specifications <T > = if (values.isNotEmpty()) spec { path ->
26+ fun <T , R : Any > KProperty1 <T , R ?>.`in` (values : Collection <R >): Specification <T > = if (values.isNotEmpty()) spec { path ->
2827 `in `(path).apply { values.forEach { this .value(it) } }
29- } else Specifications .where<T >(null )
28+ } else Specification .where<T >(null )
3029
3130// Comparison
3231fun <T > KProperty1 <T , Number ?>.le (x : Number ) = spec { le(it, x) }
@@ -54,36 +53,36 @@ fun <T, E, R : Collection<E>> KProperty1<T, R?>.isMember(elem: E) = spec { isMem
5453fun <T , E , R : Collection <E >> KProperty1 <T , R ?>.isNotMember (elem : E ) = spec { isNotMember(elem, it) }
5554
5655// Strings
57- fun <T > KProperty1 <T , String ?>.like (x : String ): Specifications <T > = spec { like(it, x) }
58- fun <T > KProperty1 <T , String ?>.like (x : String , escapeChar : Char ): Specifications <T > = spec { like(it, x, escapeChar) }
59- fun <T > KProperty1 <T , String ?>.notLike (x : String ): Specifications <T > = spec { notLike(it, x) }
60- fun <T > KProperty1 <T , String ?>.notLike (x : String , escapeChar : Char ): Specifications <T > = spec { notLike(it, x, escapeChar) }
56+ fun <T > KProperty1 <T , String ?>.like (x : String ): Specification <T > = spec { like(it, x) }
57+ fun <T > KProperty1 <T , String ?>.like (x : String , escapeChar : Char ): Specification <T > = spec { like(it, x, escapeChar) }
58+ fun <T > KProperty1 <T , String ?>.notLike (x : String ): Specification <T > = spec { notLike(it, x) }
59+ fun <T > KProperty1 <T , String ?>.notLike (x : String , escapeChar : Char ): Specification <T > = spec { notLike(it, x, escapeChar) }
6160
6261// And
63- infix fun <T > Specifications <T>.and (other : Specification <T >): Specifications <T > = this .and (other)
64- inline fun <reified T > and (vararg specs : Specifications <T >? ): Specifications <T > {
62+ infix fun <T > Specification <T>.and (other : Specification <T >): Specification <T > = this .and (other)
63+ inline fun <reified T > and (vararg specs : Specification <T >? ): Specification <T > {
6564 return and (specs.toList())
6665}
67- inline fun <reified T > and (specs : Iterable <Specifications <T >? >): Specifications <T > {
68- return combineSpecifications (specs, Specifications <T >::and )
66+ inline fun <reified T > and (specs : Iterable <Specification <T >? >): Specification <T > {
67+ return combineSpecification (specs, Specification <T >::and )
6968}
7069
7170// Or
72- infix fun <T > Specifications <T>.or (other : Specification <T >) : Specifications <T > = this .or (other)
73- inline fun <reified T > or (vararg specs : Specifications <T >? ): Specifications <T > {
71+ infix fun <T > Specification <T>.or (other : Specification <T >) : Specification <T > = this .or (other)
72+ inline fun <reified T > or (vararg specs : Specification <T >? ): Specification <T > {
7473 return or (specs.toList())
7574}
76- inline fun <reified T > or (specs : Iterable <Specifications <T >? >): Specifications <T > {
77- return combineSpecifications (specs, Specifications <T >::or )
75+ inline fun <reified T > or (specs : Iterable <Specification <T >? >): Specification <T > {
76+ return combineSpecification (specs, Specification <T >::or )
7877}
7978
8079// Not
81- operator fun <T > Specifications <T>.not (): Specifications <T > = Specifications .not (this )
80+ operator fun <T > Specification <T>.not (): Specification <T > = Specification .not (this )
8281
83- // Combines Specifications with an operation
84- inline fun <reified T > combineSpecifications (specs : Iterable <Specification <T >? >, operation : Specifications <T >.(Specification <T >) -> Specifications <T >): Specifications <T > {
82+ // Combines Specification with an operation
83+ inline fun <reified T > combineSpecification (specs : Iterable <Specification <T >? >, operation : Specification <T >.(Specification <T >) -> Specification <T >): Specification <T > {
8584 return specs.filterNotNull().fold(emptySpecification()) { existing, new -> existing.operation(new) }
8685}
8786
8887// Empty Specification
89- inline fun <reified T > emptySpecification (): Specifications <T > = Specifications .where<T >(null )
88+ inline fun <reified T > emptySpecification (): Specification <T > = Specification .where<T >(null )
0 commit comments