Skip to content

Commit

Permalink
New hstore function: PgHstoreILikeValue
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloalba committed May 21, 2015
1 parent 1b90d71 commit 3c052f2
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
11 changes: 11 additions & 0 deletions README.md
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
Expand Up @@ -2,13 +2,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

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

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

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))
}
}

void addPgHstoreContains() {
HibernateCriteriaBuilder.metaClass.pgHstoreContains = { String propertyName, Map<String,String> values ->
if (!validateSimpleExpression()) {
Expand Down
@@ -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);
}
}
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 Down
@@ -0,0 +1,43 @@
package net.kaleidos.hibernate.hstore

import grails.plugin.spock.*
import spock.lang.*

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": "test"]).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": "test"]).save(flush: true)
new TestHstore(name: "test4", testAttributes: ["c": "test", "b": "3"]).save(flush: true)

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

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

0 comments on commit 3c052f2

Please sign in to comment.