Changeset 5711


Ignore:
Timestamp:
Aug 30, 2011, 3:49:58 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1618: Improve "Reporter search" performance in experiment explorer

Different implementation on "Reporter search" that uses the cached reporter ids and use a regular query against the Reporters table only. As a result, the "Create reporter list" function needed to fixed as it can no longer use the query. Instead it also uses the cached reporter ids.

Added filter condition for bioassays when loading the "Reporter view" page since it seems to be a lot quicker (see comment 4).

Fixed an issue with generating incorrect SQL when filtering on a reporter list. I think this broke as part of #903, but has gone unnoticed since then. A join to the reporter list table was missing due to no auto-join support in DynamicPositionQuery and DynamicReporterQuery. Auto-join support has now been added to those query implementations.

Everything is a lot quicker now on my development machine. I have 2.5M reporters in the reporter table and an experiment with 24M rows of spot data in 500 bioassays. So far no action seems to take more than a couple of seconds to complete.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/ExperimentExplorer.java

    r5590 r5711  
    4949import net.sf.basedb.core.DbControl;
    5050import net.sf.basedb.core.DynamicPositionQuery;
    51 import net.sf.basedb.core.DynamicQuery;
     51import net.sf.basedb.core.DynamicReporterQuery;
    5252import net.sf.basedb.core.DynamicResultIterator;
    5353import net.sf.basedb.core.DynamicSpotQuery;
     
    7272import net.sf.basedb.core.query.JoinType;
    7373import net.sf.basedb.core.query.Orders;
     74import net.sf.basedb.core.query.Query;
     75import net.sf.basedb.core.query.QueryElement;
    7476import net.sf.basedb.core.query.Restriction;
    7577import net.sf.basedb.core.query.Restrictions;
     
    544546
    545547  /**
     548    Get the reporter id for the specified index. The index should be
     549    between 0 and the number of matching reporters minus 1. This method
     550    assumed that the reporter/position cache has already been initialized.
     551    @param index The index
     552    @return The internal id of the reporter, or 0 if the cache is not
     553      initialized or if the index is outside the allowed range
     554    @since 3.0
     555    @see #getMatchingReporters(DbControl)
     556  */
     557  public int getReporterId(int index)
     558  {
     559    if (cache == null) return 0;
     560    return index >= 0 && index < cache.length ? cache[index].id : 0;
     561  }
     562 
     563  /**
    546564    Get the number of unique positions the reporter of the specifed
    547565    index is present in among all the bioassays in the bioassay set.
     
    624642  /**
    625643    Get a query returning the reporter data used by the reporter search page.
    626     Note that the query is {@link DynamicSpotQuery} and not a
     644    Note that the query is {@link DynamicReporterQuery} and not a
    627645    {@link net.sf.basedb.core.DataQuery}. This means that we don't get
    628646    {@link ReporterData} objects as a result and that we must specify the
    629     properties to select (see {@link ItemContext#configureQuery(DbControl, DynamicQuery, List)}).
     647    properties to select (see {@link ItemContext#configureQuery(DbControl, net.sf.basedb.core.AbstractSqlQuery, List)}).
    630648    <p>
    631649    The reporter id is always included as the first selected property so it
    632650    doesn't have to be in the selection list.
     651    <p>
     652   
     653    NOTE! The query is restricted using information in the reporter/position cache
     654    to only return the exactly the reporter information that is displayed on the
     655    current page. Thus, some things do not work in the same way as
     656    most other queries used when listing items.
     657   
     658    <ul>
     659    <li>The query doesn't return a total count. Use {@link #getMatchingReporters(DbControl)}
     660      instead.
     661    <li>Paging options do not work (eg. {@link Query#setFirstResult(int)} and {@link Query#setMaxResults(int)})
     662    </ul>
    633663   
    634664    @param dc The DbControl for database access
    635665    @param selectionList The properties that the query should select
    636666    @return A query
    637     @see ItemContext#configureQuery(DbControl, DynamicQuery, List)
    638   */
    639   public DynamicSpotQuery getReporterQuery(DbControl dc, List<String> selectionList)
    640   {
    641     DynamicSpotQuery reporterQuery = getBioAssaySet(dc).getSpotData();
    642     reporterQuery.joinReporters(JoinType.INNER);
    643     reporterQuery.setDistinct(true);
     667    @see ItemContext#configureQuery(DbControl, net.sf.basedb.core.AbstractSqlQuery, List)
     668  */
     669  public DynamicReporterQuery getReporterQuery(DbControl dc, List<String> selectionList)
     670  {
     671    // Make sure the reporter/position cache is up to date
     672    if (cache == null) initReporterCache(dc);
     673
     674    ItemContext cc = dc.getSessionControl().getCurrentContext(Item.REPORTER, getSubContext(), null);
     675   
     676    // Get the reporter id:s to show on the current page
     677    List<Integer> reporterIds = new ArrayList<Integer>(cc.getRowsPerPage()+1);
     678    int start = cc.getRowsPerPage() * cc.getPage();
     679    int end = start + cc.getRowsPerPage();
     680    for (int index = start; index < end && index < cache.length; ++index)
     681    {
     682      int reporterId = cache[index].id;
     683      if (reporterId > 0) reporterIds.add(reporterId);
     684    }
     685   
     686    // Create reporter query
     687    DynamicReporterQuery reporterQuery = Reporter.getDynamicQuery();
     688    // Guard against no hits
     689    if (reporterIds.size() == 0) reporterIds.add(-1);
     690    reporterQuery.restrict(Restrictions.in(Dynamic.reporter("id"), new InExpression(reporterIds)));
     691   
    644692    reporterQuery.select(Selects.expression(Dynamic.reporter("id"), "id", true));
    645    
    646     ItemContext cc = dc.getSessionControl().getCurrentContext(Item.REPORTER, getSubContext(), null);
    647693    cc.configureQuery(dc, reporterQuery, selectionList);
     694   
     695    // Do not return the total count. Do not set paging options.
     696    reporterQuery.setReturnTotalCount(false);
     697    reporterQuery.setFirstResult(0);
     698    reporterQuery.setMaxResults(-1);
    648699   
    649700    return reporterQuery;
     
    678729    if (cache == null) initReporterCache(dc);
    679730    int[] positions = null;
    680     int reporterId = 0;
    681731    if (reporterIndex >= 0 && reporterIndex < cache.length)
    682732    {
    683       reporterId = cache[reporterIndex].id;
    684733      positions = cache[reporterIndex].pos;
    685734    }
     
    692741    spotQuery.select(Dynamic.select(VirtualColumn.COLUMN));
    693742   
     743    // Restricting on the data-cube column seems to give better
     744    // performance -- probably because the primary key index
     745    // can be used to lookup rows
     746    spotQuery.restrict(Restrictions.in(Dynamic.column(VirtualColumn.COLUMN), new InExpression(bioAssays.keySet())));
     747   
    694748    if (positionIndex == SPOT_ALL)
    695749    {
    696       // Get all spots for the current reporter
    697       // Select the position as well
     750      // Select the position number
    698751      spotQuery.select(Dynamic.select(VirtualColumn.POSITION));
    699       spotQuery.joinReporters(reporterId == 0 ? JoinType.LEFT : JoinType.INNER);
    700       spotQuery.restrict(
    701         Restrictions.eq(
    702           Dynamic.reporter("id"),
    703           reporterId == 0 ? null : Expressions.integer(reporterId)
    704         )
    705       );
     752     
     753      // Restrict by the positions known to have the given reporter
     754      spotQuery.restrict(Restrictions.in(Dynamic.column(VirtualColumn.POSITION), new InExpression(positions)));
    706755    }
    707756    else if (positionIndex == SPOT_AVG)
    708757    {
    709       // Average over spots in the same bioassay for the current reporter
    710758      // Select the number of spots we are averaging over
    711759      spotQuery.select(
     
    715763        )
    716764      );
    717       spotQuery.joinReporters(reporterId == 0 ? JoinType.LEFT : JoinType.INNER);
    718       spotQuery.restrict(
    719         Restrictions.eq(
    720           Dynamic.reporter("id"),
    721           reporterId == 0 ? null : Expressions.integer(reporterId)
    722         )
    723       );
     765     
     766      // Create group per bioassay
    724767      spotQuery.group(Dynamic.column(VirtualColumn.COLUMN));
     768     
     769      // Restrict by the positions known to have the given reporter
     770      spotQuery.restrict(Restrictions.in(Dynamic.column(VirtualColumn.POSITION), new InExpression(positions)));
    725771    }
    726772    else
    727773    {
    728       // Get spots for specific position
     774      // Select the position
     775      spotQuery.select(Dynamic.select(VirtualColumn.POSITION));
     776
     777      // Get spots for one specific position
    729778      int position = -1;
    730779      if (positions != null)
     
    735784        }
    736785      }
    737       // Select the position
    738       spotQuery.select(Dynamic.select(VirtualColumn.POSITION));
    739786      spotQuery.restrict(
    740787        Restrictions.eq(
     
    938985 
    939986  /**
     987    Creates a list of (numerical) values that can be used as the
     988    right-hand operand to the IN operator. Eg. foo IN (v1, v2, ...)
     989  */
     990  private static class InExpression
     991    implements Expression
     992  {
     993
     994    private final String in;
     995   
     996    InExpression(int... values)
     997    {
     998      StringBuilder sb = new StringBuilder();
     999      for (int v : values)
     1000      {
     1001        if (sb.length() > 0) sb.append(",");
     1002        sb.append(v);
     1003      }
     1004      in = sb.toString();
     1005    }
     1006   
     1007    InExpression(Collection<? extends Number> values)
     1008    {
     1009      StringBuilder sb = new StringBuilder();
     1010      for (Number v : values)
     1011      {
     1012        if (sb.length() > 0) sb.append(",");
     1013        sb.append(v);
     1014      }
     1015      in = sb.toString();
     1016    }
     1017   
     1018    @Override
     1019    public String toQl(Query query, DbControl dc)
     1020      throws BaseException
     1021    {
     1022      return in;
     1023    }
     1024
     1025    @Override
     1026    public Collection<? extends QueryElement> getChildren()
     1027    {
     1028      return null;
     1029    }
     1030   
     1031  }
     1032 
     1033  /**
    9401034    An annotation summary object keeps track of intensities and other
    9411035    statistical information based on the annotation group.
  • trunk/src/core/net/sf/basedb/core/DynamicPositionQuery.java

    r5319 r5711  
    164164 
    165165  /**
     166      Makes a join with a <code>ReporterList</code>
     167      @param reporterList To do the join on.
     168      @param joinType The join type to use.
     169      @see net.sf.basedb.core.query.JoinType
     170      @since 3.0
     171  */
     172  public void joinReporterList(ReporterList reporterList, JoinType joinType)
     173  {
     174    if (joinType == null) throw new InvalidUseOfNullException("joinType");
     175    if (reporterList == null) throw new InvalidUseOfNullException("reporterList");
     176    if (!joinedItems.contains(reporterList))
     177    {
     178      join(new ReporterListJoin(reporterList, joinType, VirtualTable.POSITION, VirtualColumn.REPORTER_ID));
     179      joinedItems.add(reporterList);
     180    }
     181  }
     182 
     183  /**
    166184    Join extra values in the query. Now it becomes possible to select
    167185    those extra values or use them for restrictions.
     
    206224    addAutoJoiner(DynamicPositionQueryJoiners.getExtraValueJoiner(joinType));
    207225    addAutoJoiner(DynamicPositionQueryJoiners.getReporterJoiner(joinType));
     226    addAutoJoiner(DynamicPositionQueryJoiners.getReporterListJoiner(joinType));
    208227  }
    209228
  • trunk/src/core/net/sf/basedb/core/DynamicPositionQueryJoiners.java

    r4928 r5711  
    2424import net.sf.basedb.core.query.AutoJoiner;
    2525import net.sf.basedb.core.query.JoinType;
     26import net.sf.basedb.core.query.ReporterListExpression;
    2627
    2728/**
     
    8182
    8283  /**
     84    This instance joins reporter lists with a left join, unless the
     85    {@link ReporterListExpression#getAutoJoinType()} method overrides
     86    the default.
     87    @since 3.0
     88  */
     89  public static final ReporterListJoiner REPORTER_LIST_LEFT =
     90    new ReporterListJoiner(JoinType.LEFT);
     91 
     92  /**
     93    This instance joins reporter lists with an inner join, unless the
     94    {@link ReporterListExpression#getAutoJoinType()} method overrides
     95    the default.
     96    @since 3.0
     97  */
     98  public static final ReporterListJoiner REPORTER_LIST_INNER =
     99    new ReporterListJoiner(JoinType.INNER);
     100 
     101  /**
     102    Get a joiner instance for reporter lists for the specified join type.
     103    @param joinType The type of join
     104    @return {@link #REPORTER_LIST_LEFT} or {@link #REPORTER_LIST_INNER}
     105    @since 3.0
     106  */
     107  public static ReporterListJoiner getReporterListJoiner(JoinType joinType)
     108  {
     109    return joinType == JoinType.LEFT ? REPORTER_LIST_LEFT : REPORTER_LIST_INNER;
     110  }
     111
     112 
     113  /**
    83114    Joiner for extra values.
    84115    @author nicklas
     
    156187  }
    157188
     189  /**
     190    Auto joiner for reporter lists.
     191    @author nicklas
     192    @since 3.0
     193    @base.modified $Date$
     194  */
     195  private static class ReporterListJoiner
     196    implements AutoJoiner<DynamicPositionQuery, ReporterListExpression>
     197  {
     198    private final JoinType joinType;
     199 
     200    private ReporterListJoiner(JoinType joinType)
     201    {
     202      this.joinType = joinType;
     203    }
     204   
     205    /*
     206      From the AutoJoiner interface
     207      -------------------------------------------
     208    */
     209    @Override
     210    public Class<DynamicPositionQuery> getQueryClass()
     211    {
     212      return DynamicPositionQuery.class;
     213    }
     214    @Override
     215    public Class<ReporterListExpression> getElementClass()
     216    {
     217      return ReporterListExpression.class;
     218    }
     219    @Override
     220    public void joinIfNeeded(DynamicPositionQuery query, ReporterListExpression element)
     221    {
     222      JoinType jt = element.getAutoJoinType();
     223      query.joinReporterList(element.getReporterList(), jt == null ? joinType : jt);
     224    }
     225    // -------------------------------------------
     226  }
     227
    158228}
  • trunk/src/core/net/sf/basedb/core/DynamicReporterQuery.java

    r4517 r5711  
    2222package net.sf.basedb.core;
    2323
     24import java.util.HashSet;
     25import java.util.Set;
     26
     27import net.sf.basedb.core.query.AutoJoiner;
     28import net.sf.basedb.core.query.JoinType;
     29import net.sf.basedb.core.query.ReporterListExpression;
    2430import net.sf.basedb.core.query.Select;
    2531
     
    4046
    4147  private final RealTable rootTable;
     48  private Set<Object> joinedItems;
    4249
    4350  /**
     
    4855    super(RealTable.REPORTERS.getQualifiedTableName());
    4956    this.rootTable = RealTable.REPORTERS;
     57    joinedItems = new HashSet<Object>();
     58    setAutoJoinType(JoinType.LEFT);
    5059  }
    5160 
     
    8695  }
    8796 
     97  /**
     98      Makes a join with a <code>ReporterList</code>
     99      @param reporterList To do the join on.
     100      @param joinType The join type to use.
     101      @see net.sf.basedb.core.query.JoinType
     102      @since 3.0
     103  */
     104  public void joinReporterList(ReporterList reporterList, JoinType joinType)
     105  {
     106    if (joinType == null) throw new InvalidUseOfNullException("joinType");
     107    if (reporterList == null) throw new InvalidUseOfNullException("reporterList");
     108    if (!joinedItems.contains(reporterList))
     109    {
     110      join(new ReporterListJoin(reporterList, joinType, RealTable.REPORTERS, "id"));
     111      joinedItems.add(reporterList);
     112    }
     113  }
     114 
     115  /**
     116    Specify the join type of automatic joins. The default join type is
     117    {@link JoinType#LEFT}. This setting doesn't affect joins that has been made
     118    directly to the query.
     119    @param joinType The type of the automatic joins
     120    @since 3.0
     121  */
     122  public void setAutoJoinType(JoinType joinType)
     123  {
     124    addAutoJoiner(getReporterListJoiner(joinType));
     125  }
     126
     127  /**
     128    Get a joiner instance for reporter lists for the specified join type.
     129    @param joinType The type of join
     130    @since 3.0
     131  */
     132  public static ReporterListJoiner getReporterListJoiner(JoinType joinType)
     133  {
     134    return new ReporterListJoiner(joinType);
     135  }
     136 
     137  /**
     138    Auto joiner for reporter lists.
     139    @since 3.0
     140  */
     141  private static class ReporterListJoiner
     142    implements AutoJoiner<DynamicReporterQuery, ReporterListExpression>
     143  {
     144    private final JoinType joinType;
     145 
     146    private ReporterListJoiner(JoinType joinType)
     147    {
     148      this.joinType = joinType;
     149    }
     150   
     151    /*
     152      From the AutoJoiner interface
     153      -------------------------------------------
     154    */
     155    @Override
     156    public Class<DynamicReporterQuery> getQueryClass()
     157    {
     158      return DynamicReporterQuery.class;
     159    }
     160    @Override
     161    public Class<ReporterListExpression> getElementClass()
     162    {
     163      return ReporterListExpression.class;
     164    }
     165    @Override
     166    public void joinIfNeeded(DynamicReporterQuery query, ReporterListExpression element)
     167    {
     168      JoinType jt = element.getAutoJoinType();
     169      query.joinReporterList(element.getReporterList(), jt == null ? joinType : jt);
     170    }
     171    // -------------------------------------------
     172  }
     173
    88174}
  • trunk/src/core/net/sf/basedb/core/DynamicSpotQuery.java

    r5689 r5711  
    226226  public void joinReporterList(ReporterList reporterList, JoinType joinType)
    227227  {
     228    if (joinType == null) throw new InvalidUseOfNullException("joinType");
     229    if (reporterList == null) throw new InvalidUseOfNullException("reporterList");
    228230    if (!joinedItems.contains(VirtualTable.POSITION))
    229231    {
     
    234236    if (!joinedItems.contains(reporterList))
    235237    {
    236       join(new ReporterListJoin(reporterList, joinType));
     238      join(new ReporterListJoin(reporterList, joinType, VirtualTable.POSITION, VirtualColumn.REPORTER_ID));
    237239      joinedItems.add(reporterList);
    238240    }
  • trunk/src/core/net/sf/basedb/core/ItemContext.java

    r5689 r5711  
    13881388    @throws BaseException If the configuring the query fails.
    13891389  */
    1390   public void configureQuery(DbControl dc, DynamicQuery query, List<String> selectionList)
     1390  public void configureQuery(DbControl dc, AbstractSqlQuery query, List<String> selectionList)
    13911391    throws BaseException
    13921392  {
  • trunk/src/core/net/sf/basedb/core/ReporterListJoin.java

    r5320 r5711  
    5252  private final ReporterList reporterList;
    5353  private final JoinType joinType;
    54   private final VirtualTable left;
     54  private final String leftAlias;
     55  private final String leftColumn;
    5556  private final RealTable right;
    5657 
    5758  /**
    58     Create a new join using the root entity table as the left table.
    59     <code><i>SELECT ... FROM rootTable</i> JOIN extraValueTable</code>.
    60     <p>
    61     The extra value table and which columns should be used in the join
    62     is found by examining the extra value properties, ie. value type
    63     and coordinate type.
    64 
    65     @param reporterList The extra value to join
     59    Create a new join to a reporter list using the given VirtualTable
     60    as the left table. The given VirtualColumn should hold the reporter
     61    id values.
     62   
     63    @param reporterList The reporter list to join
    6664    @param joinType The type of join
    67   */
    68   ReporterListJoin(ReporterList reporterList, JoinType joinType)
     65    @param left The left table
     66    @param leftColumn The column in the left table holding reporter id:s
     67    @since 3.0
     68  */
     69  ReporterListJoin(ReporterList reporterList, JoinType joinType, VirtualTable left, VirtualColumn leftColumn)
    6970  {
    7071    this.reporterList = reporterList;
    7172    this.joinType = joinType;
    72     this.left = VirtualTable.POSITION;
     73    this.leftAlias = left.getAlias();
     74    this.leftColumn = leftColumn.getColumn();
     75    this.right = RealTable.REPORTER_LIST_SCORES;
     76  }
     77 
     78  /**
     79    Create a new join to a reporter list using the given RealTable
     80    as the left table. The given leftColumn should hold the reporter
     81    id values.
     82   
     83    @param reporterList The reporter list to join
     84    @param joinType The type of join
     85    @param left The left table
     86    @param leftColumn The column in the left table holding reporter id:s
     87    @since 3.0
     88  */
     89  ReporterListJoin(ReporterList reporterList, JoinType joinType, RealTable left, String leftColumn)
     90  {
     91    this.reporterList = reporterList;
     92    this.joinType = joinType;
     93    this.leftAlias = left.getAlias();
     94    this.leftColumn = leftColumn;
    7395    this.right = RealTable.REPORTER_LIST_SCORES;
    7496  }
     
    83105    if (query.getQueryType() == QueryType.SQL)
    84106    {
    85       String leftAlias = HibernateUtil.quote(left.getAlias());
    86107      String rightAlias = HibernateUtil.quote(right.getAlias()+reporterList.getId());
    87108     
     
    91112      sb.append(" ON ");
    92113      sb.append(rightAlias).append(".").append(HibernateUtil.quote("reporter_id"));
    93       sb.append(" = ").append(leftAlias).append(".").append(VirtualColumn.REPORTER_ID.getColumn());
     114      sb.append(" = ").append(leftAlias).append(".").append(leftColumn);
    94115      sb.append(" AND ").append(rightAlias).append(".").append("reporterlist_id");
    95116      sb.append(" = ").append(reporterList.getId());
     
    134155    if (query.getQueryType() == QueryType.SQL)
    135156    {
    136       String leftAlias = HibernateUtil.quote(left.getAlias());
    137157      String rightAlias = HibernateUtil.quote(right.getAlias()+reporterList.getId());
    138158      StringBuilder sb = new StringBuilder();
    139159      sb.append(rightAlias).append(".").append(HibernateUtil.quote("reporter_id"));
    140       sb.append(" = ").append(leftAlias).append(".").append(VirtualColumn.REPORTER_ID.getColumn());
     160      sb.append(" = ").append(leftAlias).append(".").append(leftColumn);
    141161      if (joinType == JoinType.LEFT) sb.append("(+)");
    142162      sb.append(" AND ").append(rightAlias).append(".").append("reporterlist_id");
     
    159179  public String toString()
    160180  {
    161     String leftAlias = left.getAlias();
    162181    String rightAlias = right.getAlias()+reporterList.getId();
    163182
     
    168187   
    169188    sb.append(rightAlias).append(".").append("reporter_id");
    170     sb.append(" = ").append(leftAlias).append(".").append(VirtualColumn.REPORTER_ID.getName());
     189    sb.append(" = ").append(leftAlias).append(".").append(leftColumn);
    171190    sb.append(" AND ").append(rightAlias).append(".").append("reporterlist_id");
    172191    sb.append(" = ").append(reporterList.getId());
  • trunk/src/core/net/sf/basedb/core/query/QueryParameter.java

    r5564 r5711  
    190190        {
    191191          throw new InvalidDataException("Incorrect parameter type for '" +
    192             name + "[" + i + "]'. Expected " + type + "; found " + value.getClass().getName());
     192            name + "[" + i + "]'. Expected " + type + "; found " + o.getClass().getName());
    193193        }
    194194        i++;
  • trunk/www/views/experiments/explorer/search/index.jsp

    r5426 r5711  
    3131  import="net.sf.basedb.core.ItemContext"
    3232  import="net.sf.basedb.core.BioAssaySet"
    33   import="net.sf.basedb.core.DynamicSpotQuery"
     33  import="net.sf.basedb.core.DynamicReporterQuery"
    3434  import="net.sf.basedb.clients.web.Base"
    3535  import="net.sf.basedb.clients.web.ExperimentExplorer"
     
    7171  {
    7272    ItemContext cc = explorer.getAndSetReporterContext(sc, pageContext);
    73     DynamicSpotQuery query = explorer.getReporterQuery(dc, Collections.singletonList("@id"));
    74     cc.setQuery(query);
     73    cc.setObject("reporter-list-creator", explorer);
    7574    redirect = "../../../reporterlists/index.jsp?ID="+ID+
    7675        "&cmd=NewItem&addReporters=1&formId=reporters&fromContext=" + cc.getItemType().name() +
  • trunk/www/views/experiments/explorer/search/list.jsp

    r5426 r5711  
    3535  import="net.sf.basedb.core.ExtendedProperties"
    3636  import="net.sf.basedb.core.ExtendedProperty"
    37   import="net.sf.basedb.core.DynamicSpotQuery"
     37  import="net.sf.basedb.core.DynamicReporterQuery"
    3838  import="net.sf.basedb.core.DynamicResultIterator"
    3939  import="net.sf.basedb.core.VirtualColumn"
     
    7777final DbControl dc = sc.newDbControl();
    7878DynamicResultIterator reporters = null;
     79long totalReporters = 0;
    7980try
    8081{
     
    100101  try
    101102  {
    102     DynamicSpotQuery reporterQuery = explorer.getReporterQuery(dc, selected.selectedProperties);
     103    DynamicReporterQuery reporterQuery = explorer.getReporterQuery(dc, selected.selectedProperties);
     104    totalReporters = explorer.getMatchingReporters(dc);
    103105    reporters = reporterQuery.iterate(dc);
    104106  }
     
    106108  {
    107109    cc.setMessage(t.getMessage());
     110    t.printStackTrace();
    108111  }
    109112  int numListed = 0;
     
    247250        page="<%=cc.getPage()%>"
    248251        rowsperpage="<%=cc.getRowsPerPage()%>"
    249         totalrows="<%=reporters == null ? 0 : reporters.getTotalCount()%>"
     252        totalrows="<%=totalReporters%>"
    250253      />
    251254      <tbl:data>
     
    310313      {
    311314        %>
    312         <tbl:panel><%=reporters == null || reporters.getTotalCount() == 0 ? "No reporters were found" : "No reporters on this page. Please select another page!" %></tbl:panel>
     315        <tbl:panel><%=totalReporters == 0 ? "No reporters were found" : "No reporters on this page. Please select another page!" %></tbl:panel>
    313316        <%
    314317      }
     
    319322          page="<%=cc.getPage()%>"
    320323          rowsperpage="<%=cc.getRowsPerPage()%>"
    321           totalrows="<%=reporters == null ? 0 : reporters.getTotalCount()%>"
     324          totalrows="<%=totalReporters%>"
    322325          locked="true"
    323326        />
  • trunk/www/views/experiments/explorer/view/view.jsp

    r5426 r5711  
    183183    {
    184184      cc.setMessage(t.getMessage());
     185      t.printStackTrace();
    185186    }
    186187  }
  • trunk/www/views/reporterlists/index.jsp

    r5630 r5711  
    5454  import="net.sf.basedb.clients.web.WebException"
    5555  import="net.sf.basedb.util.Values"
     56  import="net.sf.basedb.clients.web.ExperimentExplorer"
    5657  import="net.sf.basedb.clients.web.util.HTML"
    5758  import="net.sf.basedb.core.plugin.GuiContext"
     
    156157        Item fromContext = Item.valueOf(request.getParameter("fromContext"));
    157158        String subContext = Values.getString(request.getParameter("subContext"), "");
    158         Query query = sc.getCurrentContext(fromContext, subContext).getQuery();
    159         if ("all".equals(which))
     159        ItemContext reporterContext = sc.getCurrentContext(fromContext, subContext);
     160        Query query = reporterContext.getQuery();
     161        Object listCreator = reporterContext.getObject("reporter-list-creator");
     162        if (query != null)
    160163        {
    161           query.setFirstResult(0);
    162           query.setMaxResults(-1);
     164          System.out.println("list-query: " + query.toQl(dc));
     165          if ("all".equals(which))
     166          {
     167            query.setFirstResult(0);
     168            query.setMaxResults(-1);
     169          }
     170          else if ("selected".equals(which))
     171          {
     172            query.setFirstResult(0);
     173            query.setMaxResults(-1);
     174            Integer[] itemIds = Values.getInt(request.getParameter("items").split(","));
     175            query.restrict(
     176              Restrictions.in(
     177                Hql.property("id"),
     178                Expressions.parameter("_selected_")
     179              )
     180            );
     181            query.setParameter("_selected_", Arrays.asList(itemIds), Type.INT);     
     182          }
     183          // else -- no modifications to the query mean that we only get the current page
     184         
     185          if (query instanceof DataQuery)
     186          {
     187            DataResultIterator<ReporterData> result = ((DataQuery<ReporterData>)query).iterate(dc);
     188            while (result.hasNext())
     189            {
     190              ReporterData reporter = result.next();
     191              if (reporter != null) rl.addReporter(reporter, null);
     192            }
     193          }
     194          else if (query instanceof DynamicQuery)
     195          {
     196            DynamicResultIterator result = ((DynamicQuery)query).iterate(dc);
     197            while (result.hasNext())
     198            {
     199              SqlResult i = result.next();
     200              int reporterId = i.getInt(1);
     201              if (reporterId != 0)
     202              {
     203                rl.addReporter(Reporter.getProxy(reporterId), null);
     204              }
     205            }
     206          }
    163207        }
    164         else if ("selected".equals(which))
     208        else if (listCreator instanceof ExperimentExplorer)
    165209        {
    166           query.setFirstResult(0);
    167           query.setMaxResults(-1);
    168           Integer[] itemIds = Values.getInt(request.getParameter("items").split(","));
    169           query.restrict(
    170             Restrictions.in(
    171               Hql.property("id"),
    172               Expressions.parameter("_selected_")
    173             )
    174           );
    175           query.setParameter("_selected_", Arrays.asList(itemIds), Type.INT);     
    176         }
    177         // else -- no modifications to the query mean that we only get the current page
    178        
    179         if (query instanceof DataQuery)
    180         {
    181           DataResultIterator<ReporterData> result = ((DataQuery<ReporterData>)query).iterate(dc);
    182           while (result.hasNext())
    183           {
    184             ReporterData reporter = result.next();
    185             if (reporter != null) rl.addReporter(reporter, null);
    186           }
    187         }
    188         else if (query instanceof DynamicQuery)
    189         {
    190           DynamicResultIterator result = ((DynamicQuery)query).iterate(dc);
    191           while (result.hasNext())
    192           {
    193             SqlResult i = result.next();
    194             int reporterId = i.getInt(1);
    195             if (reporterId != 0)
    196             {
    197               rl.addReporter(Reporter.getProxy(reporterId), null);
    198             }
     210          // Special case when creating reporter list from experiment explorer
     211          // since the desired reporter id:s are already cached
     212          ExperimentExplorer explorer = (ExperimentExplorer)listCreator;
     213          int start = 0;
     214          int end = 0;
     215          int totalReporters = explorer.getMatchingReporters(dc);
     216          if ("all".equals(which))
     217          {
     218            end = totalReporters;
     219          }
     220          else
     221          {
     222            start = reporterContext.getPage() * reporterContext.getRowsPerPage();
     223            end = start + reporterContext.getRowsPerPage();
     224          }
     225         
     226          for (int index = start; index < end && index < totalReporters; ++index)
     227          {
     228            rl.addReporter(Reporter.getProxy(explorer.getReporterId(index)), null);
    199229          }
    200230        }
Note: See TracChangeset for help on using the changeset viewer.