Changeset 4607


Ignore:
Timestamp:
Oct 28, 2008, 9:16:02 AM (15 years ago)
Author:
Nicklas Nordborg
Message:

References #1129: Filtering of child/parent items in table listing

Added support in core and test case for experiments in raw bioassays list is done.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/AbstractQuery.java

    r4600 r4607  
    488488  public String toString()
    489489  {
    490     return this.getClass().getSimpleName() + ": " + getMainQuery(null, !isReadonly());
     490    return getMainQuery(null, !isReadonly());
    491491  }
    492492  // -------------------------------------------
  • trunk/src/core/net/sf/basedb/core/ItemContext.java

    r4517 r4607  
    10561056        try
    10571057        {
    1058           Restriction r = filter.getRestriction(dc);
     1058          Restriction r = filter.getRestriction(dc, query);
    10591059          if (r != null)
    10601060          {
     
    10661066              String filterProperty = filter.getProperty();
    10671067              int dotIndex = filterProperty == null ? -1 : filterProperty.lastIndexOf(".");
    1068               if (dotIndex >= 0 && !filterProperty.startsWith("$") && !filterProperty.startsWith("£"))
     1068              if (dotIndex >= 0 && !filterProperty.startsWith("$") && !filterProperty.startsWith("£") && !filterProperty.startsWith("&"))
    10691069              {
    10701070                leftJoins.add(filterProperty.substring(0, dotIndex));
     
    10991099      {
    11001100        boolean fetch = selectOrderBy && sortedProperties.contains(property);
    1101         if (property.startsWith("@") || property.startsWith("£"))
     1101        if (property.startsWith("@") || property.startsWith("£") || property.startsWith("&"))
    11021102        {
    11031103          property = property.substring(1);
  • trunk/src/core/net/sf/basedb/core/PropertyFilter.java

    r4555 r4607  
    2727import java.util.Date;
    2828import java.util.List;
     29import java.util.regex.Matcher;
     30import java.util.regex.Pattern;
    2931
    3032import net.sf.basedb.core.data.AnnotationTypeData;
     
    3234import net.sf.basedb.core.data.ReporterData;
    3335import net.sf.basedb.core.data.UnitData;
     36import net.sf.basedb.core.query.EntityQuery;
     37import net.sf.basedb.core.query.Query;
    3438import net.sf.basedb.core.query.Restriction;
    3539import net.sf.basedb.core.query.Restrictions;
     
    6468   */
    6569  private final String value_separator = "|";
     70 
     71  private final Pattern ENTITY_COLLECTION = Pattern.compile("\\&([\\w\\.]+)\\((.+)\\)");
    6672 
    6773  private final String property;
     
    379385 
    380386  /**
    381     This method will fail if used to filter on reporter lists.
    382     @deprecated Use {@link #getRestriction(DbControl)} instead
     387    This method will fail if used to filter on reporter lists or collections.
     388    @deprecated Use {@link #getRestriction(DbControl, EntityQuery)} instead
    383389  */
    384390  public Restriction getRestriction()
    385391  {
    386     return getRestriction(null);
     392    return getRestriction(null, null);
     393  }
     394
     395  /**
     396    This method will fail if used to filter on collections.
     397    @deprecated Use {@link #getRestriction(DbControl, EntityQuery)} instead
     398  */
     399  public Restriction getRestriction(DbControl dc)
     400  {
     401    return getRestriction(dc, null);
    387402  }
    388403
     
    407422    we always use an IN restriction, ignoring the specified operator.
    408423    <p>
     424    If the property starts with & it is a collection of entities. The property
     425    must end with a property name from the entity in the collection within paranthesis.
     426    Eg. &experiments(name). The filter is applied as a subquery.
     427    <p>
    409428    The property may also start with $@.
    410429    @return The restriction
    411430    @since 2.8
    412431  */
    413   public Restriction getRestriction(DbControl dc)
     432  public Restriction getRestriction(DbControl dc, EntityQuery query)
    414433  {
    415434   
     
    562581        }
    563582      }
     583      else if (property != null && property.startsWith("&"))
     584      {
     585        // Property is an entity collection: collection(filter-property)
     586        Matcher m = ENTITY_COLLECTION.matcher(property);
     587        if (!m.matches())
     588        {
     589          throw new InvalidDataException("Invalid collection filter: " + property);
     590        }
     591        String entityCollection = m.group(1);
     592        String collectionFilter = m.group(2);
     593       
     594        /*
     595          We are going to create a subquery like:
     596          root-entity = ANY(
     597            SELECT root-entity FROM root-entity
     598            LEFT JOIN collection-path cp
     599            WHERE cp.filter-property ........
     600          )
     601        */
     602        Query subquery = new AbstractEntityQuery(query.getItemType(), null, false, null)
     603        {};
     604        // LEFT JOIN the parts in the collection path
     605        String[] cPath = entityCollection.split("\\.");
     606        String thisAlias = null;
     607        for (int i = 0; i < cPath.length; ++i)
     608        {
     609          String nextAlias = "cp" + i;
     610          subquery.join(Hql.leftJoin(thisAlias, cPath[i], nextAlias, null, false));
     611          thisAlias = nextAlias;
     612        }
     613       
     614        // Restrict the subquery
     615        PropertyFilter pp = new PropertyFilter("$" + thisAlias + "." + collectionFilter,
     616            operator, getValue(), getValueType());
     617        subquery.restrict(pp.getRestriction(dc, query));
     618       
     619        // Create the main restriction
     620        restriction = Restrictions.eq(Hql.alias(query.getRootAlias()),
     621            Expressions.any(subquery));
     622      }
    564623      else
    565       {
     624      {   
    566625        Expression propertyExpression = Hql.property(alias, property);
    567626        if (getValueType() == Type.DATE)
  • trunk/www/views/rawbioassays/list_rawbioassays.jsp

    r4596 r4607  
    424424        id="experiments"
    425425        title="Experiments"
     426        property="&experiments(name)"
     427        datatype="string"
     428        filterable="true"
    426429      />
    427430      <tbl:columndef
Note: See TracChangeset for help on using the changeset viewer.