Skip to content

Commit 80bbc04

Browse files
committed
Merge pull request #69 from kaleidos/PgArrayILikeFunction
Add new function for arrays: PgArrayILikeFunction
2 parents 4c52c7b + be63daa commit 80bbc04

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Currently the plugin supports array, hstore and json fields as well as some quer
2222
* [Is Empty or Contains](#is-empty-or-contains)
2323
* [Equals](#equals)
2424
* [Not Equals](#not-equals)
25+
* [Ilike](#ilike)
2526
* [Hstore](#hstore)
2627
* [Grails 2.2.5 and 2.3.1+](#grails-225-and-231)
2728
* [Old Grails versions](#old-grails-versions)
@@ -292,6 +293,20 @@ def result = Like.withCriteria {
292293
}
293294
```
294295

296+
#### ILike
297+
298+
With this criteria you can get all the rows that are ilike to a value. To use it just use the new criteria `pgArrayILike`.
299+
300+
It only can be used on arrays of string.
301+
302+
It uses the ilike syntaxis, so you can do for example:
303+
304+
```groovy
305+
def result = Like.withCriteria {
306+
pgArrayILike 'favoriteMovies', "%tarwar%"
307+
}
308+
```
309+
295310

296311
### Hstore
297312

src/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.kaleidos.hibernate.postgresql.criteria
2-
32
import grails.orm.HibernateCriteriaBuilder
43
import net.kaleidos.hibernate.criterion.array.PgArrayExpression
4+
import net.kaleidos.hibernate.criterion.array.PgArrayILikeFunction
55
import net.kaleidos.hibernate.criterion.array.PgEmptinessExpression
66

77
class ArrayCriterias {
@@ -15,6 +15,7 @@ class ArrayCriterias {
1515
addIsEmptyOrContainsOperator()
1616
addEqualsOperator()
1717
addNotEqualsOperator()
18+
addILikeOperator()
1819
}
1920

2021
private void addContainsOperator() {
@@ -179,4 +180,24 @@ class ArrayCriterias {
179180
return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "<>"))
180181
}
181182
}
183+
184+
private void addILikeOperator() {
185+
/**
186+
* Creates a "ilike in native array" Criterion based on the specified property name and value
187+
* @param propertyName The property name
188+
* @param propertyValue The property value
189+
* @return A Criterion instance
190+
*/
191+
HibernateCriteriaBuilder.metaClass.pgArrayILike = { String propertyName, String propertyValue ->
192+
if (!validateSimpleExpression()) {
193+
throwRuntimeException(new IllegalArgumentException("Call to [pgArrayILike] with propertyName [" +
194+
propertyName + "] and value [" + propertyValue + "] not allowed here."))
195+
}
196+
197+
propertyName = calculatePropertyName(propertyName)
198+
propertyValue = calculatePropertyValue(propertyValue)
199+
200+
return addToCriteria(new PgArrayILikeFunction(propertyName, propertyValue))
201+
}
202+
}
182203
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package net.kaleidos.hibernate.criterion.array;
2+
3+
import org.hibernate.Criteria;
4+
import org.hibernate.HibernateException;
5+
import org.hibernate.annotations.common.util.StringHelper;
6+
import org.hibernate.criterion.CriteriaQuery;
7+
import org.hibernate.criterion.Criterion;
8+
import org.hibernate.engine.spi.TypedValue;
9+
import org.hibernate.type.StringType;
10+
11+
/**
12+
* Constrains a value "ilike" in an array
13+
*/
14+
public class PgArrayILikeFunction implements Criterion {
15+
16+
private static final long serialVersionUID = 7475136611436979257L;
17+
18+
private final String propertyName;
19+
private final String value;
20+
21+
protected PgArrayILikeFunction(String propertyName, String value) {
22+
this.propertyName = propertyName;
23+
this.value = value;
24+
}
25+
26+
@Override
27+
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
28+
String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "");
29+
for (int i = 0; i < columns.length; i++) {
30+
columns[i] = "text(" + columns[i] + ") ilike ?";
31+
}
32+
return StringHelper.join(" and ", columns);
33+
}
34+
35+
@Override
36+
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
37+
return new TypedValue[]{
38+
new TypedValue(new StringType(), value)
39+
};
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.kaleidos.hibernate.array
2+
3+
import spock.lang.Specification
4+
import spock.lang.Unroll
5+
import test.criteria.array.Like
6+
7+
class PgILikeCriteriaTestServiceIntegrationSpec extends Specification {
8+
9+
def pgArrayTestSearchService
10+
11+
@Unroll
12+
void "check ilike for #movie in an array of strings"() {
13+
setup:
14+
new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save()
15+
new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save()
16+
new Like(favoriteMovies: ["Starwars"]).save()
17+
new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save()
18+
new Like(favoriteMovies: []).save()
19+
20+
when:
21+
def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayILike', movie)
22+
23+
then:
24+
result.size() == resultSize
25+
26+
where:
27+
movie | resultSize
28+
"%tarwar%" | 2
29+
"%ider%" | 1
30+
"%Suspects%" | 0
31+
"" | 0
32+
"%" | 5
33+
}
34+
35+
}

0 commit comments

Comments
 (0)