diff --git a/README.md b/README.md index 5d79b60..a32d9d0 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy index 6f42040..afd58bc 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy @@ -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() { @@ -23,6 +24,7 @@ class HstoreCriterias { return addToCriteria(new PgHstoreValueFunction(propertyName, propertyValue, "exist")) } } + void addPgHstoreContains() { HibernateCriteriaBuilder.metaClass.pgHstoreContains = { String propertyName, Map values -> if (!validateSimpleExpression()) { @@ -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)) + } + } } diff --git a/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.java b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.java new file mode 100644 index 0000000..d3ee1db --- /dev/null +++ b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.java @@ -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); + } +} diff --git a/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.java b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.java index 31973d2..4ebcd41 100644 --- a/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.java +++ b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.java @@ -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; @@ -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