=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/QueryFilter.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/QueryFilter.java 2014-05-08 17:33:45 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/QueryFilter.java 2014-06-14 17:58:11 +0000 @@ -76,6 +76,11 @@ return operator != null && filter != null && !filter.isEmpty(); } + public boolean isOperator( QueryOperator op ) + { + return operator != null && operator.equals( op ); + } + public String getSqlOperator() { if ( operator == null ) === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/trackedentity/TrackedEntityInstanceQueryParams.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/trackedentity/TrackedEntityInstanceQueryParams.java 2014-06-14 07:44:15 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/trackedentity/TrackedEntityInstanceQueryParams.java 2014-06-14 17:58:11 +0000 @@ -36,6 +36,7 @@ import java.util.Set; import org.hisp.dhis.common.OrganisationUnitSelectionMode; +import org.hisp.dhis.common.QueryFilter; import org.hisp.dhis.common.QueryItem; import org.hisp.dhis.common.SetMap; import org.hisp.dhis.event.EventStatus; @@ -62,7 +63,7 @@ /** * Query value, will apply to all relevant attributes. */ - private String query; + private QueryFilter query; /** * Attributes to be included in the response. Can be used to filter response. @@ -276,7 +277,7 @@ */ public boolean hasQuery() { - return query != null && !query.isEmpty(); + return query != null && query.isFilter(); } /** @@ -486,12 +487,12 @@ // Getters and setters // ------------------------------------------------------------------------- - public String getQuery() + public QueryFilter getQuery() { return query; } - public void setQuery( String query ) + public void setQuery( QueryFilter query ) { this.query = query; } === modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/DefaultTrackedEntityInstanceService.java' --- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/DefaultTrackedEntityInstanceService.java 2014-06-14 07:44:15 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/DefaultTrackedEntityInstanceService.java 2014-06-14 17:58:11 +0000 @@ -52,6 +52,7 @@ import org.hisp.dhis.common.IllegalQueryException; import org.hisp.dhis.common.OrganisationUnitSelectionMode; import org.hisp.dhis.common.Pager; +import org.hisp.dhis.common.QueryFilter; import org.hisp.dhis.common.QueryItem; import org.hisp.dhis.common.QueryOperator; import org.hisp.dhis.event.EventStatus; @@ -361,6 +362,8 @@ { TrackedEntityInstanceQueryParams params = new TrackedEntityInstanceQueryParams(); + QueryFilter queryFilter = getQueryFilter( query ); + if ( attribute != null ) { for ( String attr : attribute ) @@ -410,7 +413,7 @@ throw new IllegalQueryException( "Tracked entity does not exist: " + program ); } - params.setQuery( query ); + params.setQuery( queryFilter ); params.setProgram( pr ); params.setProgramStatus( programStatus ); params.setFollowUp( followUp ); @@ -428,14 +431,17 @@ return params; } + /** + * Creates a QueryItem from the given item string. Item is on format + * {attribute-id}:{operator}:{filter-value}. Only the attribute-id is mandatory. + */ private QueryItem getQueryItem( String item ) { if ( !item.contains( DimensionalObjectUtils.DIMENSION_NAME_SEP ) ) { return getItem( item, null, null ); } - else - // Filter + else // Filter { String[] split = item.split( DimensionalObjectUtils.DIMENSION_NAME_SEP ); @@ -448,6 +454,9 @@ } } + /** + * Creates a QueryItem from the given item, operator and filter strings. + */ private QueryItem getItem( String item, String operator, String filter ) { TrackedEntityAttribute at = attributeService.getTrackedEntityAttribute( item ); @@ -468,6 +477,37 @@ return new QueryItem( at, at.isNumericType() ); } } + + /** + * Creates a QueryFilter from the given query string. Query is on format + * {operator}:{filter-value}. Only the filter-value is mandatory. The EQ + * QueryOperator is used as operator if not specified. + */ + private QueryFilter getQueryFilter( String query ) + { + if ( query == null || query.isEmpty() ) + { + return null; + } + + if ( !query.contains( DimensionalObjectUtils.DIMENSION_NAME_SEP ) ) + { + return new QueryFilter( QueryOperator.EQ, query ); + } + else + { + String[] split = query.split( DimensionalObjectUtils.DIMENSION_NAME_SEP ); + + if ( split == null || split.length != 2 ) + { + throw new IllegalQueryException( "Query has invalid format: " + query ); + } + + QueryOperator op = QueryOperator.fromString( split[0] ); + + return new QueryFilter( op, split[1] ); + } + } @Override public int addTrackedEntityInstance( TrackedEntityInstance instance ) @@ -494,6 +534,7 @@ if ( representativeId != null ) { TrackedEntityInstance representative = trackedEntityInstanceStore.getByUid( representativeId ); + if ( representative != null ) { instance.setRepresentative( representative ); @@ -505,6 +546,7 @@ if ( relationshipTypeId != null ) { RelationshipType relType = relationshipTypeService.getRelationshipType( relationshipTypeId ); + if ( relType != null ) { rel.setRelationshipType( relType ); === modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java' --- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java 2014-06-14 17:08:42 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java 2014-06-14 17:58:11 +0000 @@ -56,6 +56,7 @@ import org.hisp.dhis.common.OrganisationUnitSelectionMode; import org.hisp.dhis.common.QueryFilter; import org.hisp.dhis.common.QueryItem; +import org.hisp.dhis.common.QueryOperator; import org.hisp.dhis.common.SetMap; import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore; import org.hisp.dhis.event.EventStatus; @@ -215,6 +216,7 @@ final String regexp = statementBuilder.getRegexpMatch(); final String wordStart = statementBuilder.getRegexpWordStart(); final String wordEnd = statementBuilder.getRegexpWordEnd(); + final String anyChar = "\\.*?"; String sql = "from trackedentityinstance tei " + "inner join trackedentity te on tei.trackedentityid = te.trackedentityid " + @@ -322,9 +324,12 @@ if ( params.isOrQuery() && params.hasAttributesOrFilters() ) { + final String start = params.getQuery().isOperator( QueryOperator.LIKE ) ? anyChar : wordStart; + final String end = params.getQuery().isOperator( QueryOperator.LIKE ) ? anyChar : wordEnd; + sql += hlp.whereAnd() + " ("; - List queryTokens = getTokens( params.getQuery() ); + List queryTokens = getTokens( params.getQuery().getFilter() ); for ( String queryToken : queryTokens ) { @@ -337,8 +342,8 @@ final String col = statementBuilder.columnQuote( item.getItemId() ); sql += - col + ".value " + regexp + " '" + wordStart + - StringUtils.lowerCase( query ) + wordEnd + "' or "; + col + ".value " + regexp + " '" + start + + StringUtils.lowerCase( query ) + end + "' or "; } sql = removeLastOr( sql ) + ") and ";