Skip to content
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Currently the plugin supports array, hstore and json fields as well as some quer
* [Is Empty or Contains](#is-empty-or-contains)
* [Equals](#equals)
* [Not Equals](#not-equals)
* [Ilike](#ilike)
* [Hstore](#hstore)
* [Grails 2.2.5 and 2.3.1+](#grails-225-and-231)
* [Old Grails versions](#old-grails-versions)
Expand Down Expand Up @@ -292,6 +293,20 @@ def result = Like.withCriteria {
}
```

#### ILike

With this criteria you can get all the rows that are ilike to a value. To use it just use the new criteria `pgArrayILike`.

It only can be used on arrays of string.

It uses the ilike syntaxis, so you can do for example:

```groovy
def result = Like.withCriteria {
pgArrayILike 'favoriteMovies', "%tarwar%"
}
```


### Hstore

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.kaleidos.hibernate.postgresql.criteria

import grails.orm.HibernateCriteriaBuilder
import net.kaleidos.hibernate.criterion.array.PgArrayExpression
import net.kaleidos.hibernate.criterion.array.PgArrayILikeFunction
import net.kaleidos.hibernate.criterion.array.PgEmptinessExpression

class ArrayCriterias {
Expand All @@ -15,6 +15,7 @@ class ArrayCriterias {
addIsEmptyOrContainsOperator()
addEqualsOperator()
addNotEqualsOperator()
addILikeOperator()
}

private void addContainsOperator() {
Expand Down Expand Up @@ -179,4 +180,24 @@ class ArrayCriterias {
return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "<>"))
}
}

private void addILikeOperator() {
/**
* Creates a "ilike in native array" Criterion based on the specified property name and value
* @param propertyName The property name
* @param propertyValue The property value
* @return A Criterion instance
*/
HibernateCriteriaBuilder.metaClass.pgArrayILike = { String propertyName, String propertyValue ->
if (!validateSimpleExpression()) {
throwRuntimeException(new IllegalArgumentException("Call to [pgArrayILike] with propertyName [" +
propertyName + "] and value [" + propertyValue + "] not allowed here."))
}

propertyName = calculatePropertyName(propertyName)
propertyValue = calculatePropertyValue(propertyValue)

return addToCriteria(new PgArrayILikeFunction(propertyName, propertyValue))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package net.kaleidos.hibernate.criterion.array;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.type.StringType;

/**
* Constrains a value "ilike" in an array
*/
public class PgArrayILikeFunction implements Criterion {

private static final long serialVersionUID = 7475136611436979257L;

private final String propertyName;
private final String value;

protected PgArrayILikeFunction(String propertyName, String value) {
this.propertyName = propertyName;
this.value = value;
}

@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "");
for (int i = 0; i < columns.length; i++) {
columns[i] = "text(" + columns[i] + ") ilike ?";
}
return StringHelper.join(" and ", columns);
}

@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[]{
new TypedValue(new StringType(), value)
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package net.kaleidos.hibernate.array

import spock.lang.Specification
import spock.lang.Unroll
import test.criteria.array.Like

class PgILikeCriteriaTestServiceIntegrationSpec extends Specification {

def pgArrayTestSearchService

@Unroll
void "check ilike for #movie in an array of strings"() {
setup:
new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save()
new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save()
new Like(favoriteMovies: ["Starwars"]).save()
new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save()
new Like(favoriteMovies: []).save()

when:
def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayILike', movie)

then:
result.size() == resultSize

where:
movie | resultSize
"%tarwar%" | 2
"%ider%" | 1
"%Suspects%" | 0
"" | 0
"%" | 5
}

}