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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Currently the plugin supports array, hstore and json fields as well as some quer
* [Contains Key](#contains-key)
* [Contains](#contains)
* [Is Contained](#is-contained)
* [ILike Value](#ilike-value)
* [JSON](#json)
* [Criterias](#criterias)
* [Has field value](#has-field-value)
Expand Down Expand Up @@ -446,6 +447,16 @@ testAttributes = ["1" : "a", "2" : "b"]
```
This criteria can also be used to look for exact matches

##### ILike Value

With this operation you can search for rows that contains an Hstore in which any value matches (ilike) to the parameter. It uses the ilike syntaxis, so you can do for example:

```groovy
def wantedValue = "%my-value%"
def result = MyDomain.withCriteria {
pgHstoreILikeValue "attributes", wantedKey
}
```

### JSON

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

import grails.orm.HibernateCriteriaBuilder
import net.kaleidos.hibernate.criterion.hstore.PgHstoreValueFunction
import net.kaleidos.hibernate.criterion.hstore.PgHstoreILikeValueFunction
import net.kaleidos.hibernate.criterion.hstore.PgHstoreOperatorExpression
import net.kaleidos.hibernate.criterion.hstore.PgHstoreValueFunction

class HstoreCriterias {
HstoreCriterias() {
addPgHstoreContainsKey()
addPgHstoreContains()
addPgHstoreIsContained()
addPgHstoreILikeValueFunction()
}

void addPgHstoreContainsKey() {
Expand All @@ -23,6 +24,7 @@ class HstoreCriterias {
return addToCriteria(new PgHstoreValueFunction(propertyName, propertyValue, "exist"))
}
}

void addPgHstoreContains() {
HibernateCriteriaBuilder.metaClass.pgHstoreContains = { String propertyName, Map<String,String> values ->
if (!validateSimpleExpression()) {
Expand All @@ -44,4 +46,17 @@ class HstoreCriterias {
return addToCriteria(new PgHstoreOperatorExpression(propertyName, values, "<@"))
}
}

void addPgHstoreILikeValueFunction() {
HibernateCriteriaBuilder.metaClass.pgHstoreILikeValue = { String propertyName, propertyValue ->
if (!validateSimpleExpression()) {
throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreILikeValue] with propertyName [" +
propertyName + "] and value [" + propertyValue + "] not allowed here."))
}
propertyName = calculatePropertyName(propertyName)
propertyValue = calculatePropertyValue(propertyValue)

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

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.criterion.CriteriaQuery;

/**
* Do an hstore content any value that ilikes the parameter?
*/
public class PgHstoreILikeValueFunction extends PgHstoreValueFunction {

protected PgHstoreILikeValueFunction(String propertyName, Object value) {
super(propertyName, 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(avals(" + columns[i] + ")) ilike ?";
}
return StringHelper.join(" and ", columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
public class PgHstoreValueFunction implements Criterion {
private static final long serialVersionUID = 2872183637309166619L;

private final String propertyName;
private final Object value;
private final String function;
protected final String propertyName;
protected final Object value;
protected final String function;

protected PgHstoreValueFunction(String propertyName, Object value, String function) {
this.propertyName = propertyName;
Expand All @@ -27,10 +27,10 @@ protected PgHstoreValueFunction(String propertyName, Object value, String functi
@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++) {
for (int i = 0; i < columns.length; i++) {
columns[i] = function + "(" + columns[i] + "," + "?)";
}
return StringHelper.join( " and ", columns);
return StringHelper.join(" and ", columns);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package net.kaleidos.hibernate.hstore

import grails.plugin.spock.*
import spock.lang.Specification
import test.hstore.TestHstore

class PgHstoreILikeValueFunctionIntegrationSpec extends Specification {
def pgHstoreTestSearchService

void 'Test find hstore that ilikes value'() {
setup:
new TestHstore(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true)
new TestHstore(name: "test2", testAttributes: ["b": "2"]).save(flush: true)
new TestHstore(name: "test3", testAttributes: ["a": "test2"]).save(flush: true)
new TestHstore(name: "test4", testAttributes: ["c": "test", "b": "3"]).save(flush: true)

when:
def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%test%')

then:
result.size() == 3
result.find { it.name == "test1" } != null
result.find { it.name == "test2" } == null
result.find { it.name == "test3" } != null
result.find { it.name == "test4" } != null
}

void 'Test find hstore that no ilikes value'() {
setup:
new TestHstore(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true)
new TestHstore(name: "test2", testAttributes: ["b": "2"]).save(flush: true)
new TestHstore(name: "test3", testAttributes: ["a": "test2"]).save(flush: true)
new TestHstore(name: "test4", testAttributes: ["c": "Xa", "b": "3"]).save(flush: true)

when:
def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%X')

then:
result.size() == 0
}
}