Changeset 6771


Ignore:
Timestamp:
Mar 16, 2015, 9:43:00 AM (7 years ago)
Author:
Nicklas Nordborg
Message:

References #1325: Lists of items

Added Re-sync functionality to the web client and started to implement this in the core. Only items on the same level are current synced. Parent/child syncing has not been implemented, except that a count is made to find the number of matching items.

Location:
trunk
Files:
3 added
8 edited

Legend:

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

    r6444 r6771  
    3535import java.util.Collection;
    3636import java.util.EnumSet;
     37import java.util.List;
    3738
    3839/**
     
    319320    return permission;
    320321  }
     322  @Override
     323  public List<Integer> idList(DbControl dc)
     324  {
     325    enableFilters(dc);
     326    List<Integer> result = null;
     327    try
     328    {
     329      SessionControl sc = dc.getSessionControl();
     330      result = HibernateUtil.loadList(Integer.class, getIdHqlQuery(dc), sc);
     331    }
     332    finally
     333    {
     334      disableFilters(dc);
     335    }
     336    return result;
     337  }
    321338  // -------------------------------------------
    322339 
  • trunk/src/core/net/sf/basedb/core/AbstractHqlQuery.java

    r6444 r6771  
    9292 
    9393  /**
     94    The most recent DbControl used to build/execute the ID query.
     95    @since 3.5
     96  */
     97  private DbControl lastIdDc;
     98 
     99  /**
    94100    The most recent main query.
    95101  */
     
    100106  */
    101107  private org.hibernate.Query lastCountQuery;
     108 
     109  /**
     110    The most recent id query.
     111    @since 3.5
     112  */
     113  private org.hibernate.Query lastIdQuery;
    102114 
    103115  /**
     
    267279  }
    268280 
     281  /**
     282    Build the ID query and set parameter values for it. If the query has been
     283    executed with the same <code>DbControl</code> before and hasn't been {@link #reset()}
     284    the cached query is returned. If the parameters values have been changed the new
     285    values are used.
     286   
     287    @param dc The DbControl to use for executing the query
     288    @return A <code>org.hibernate.Query</code> object
     289    @since 3.5
     290  */
     291  org.hibernate.Query getIdHqlQuery(DbControl dc)
     292  {
     293    if (lastIdQuery == null || lastIdDc != dc)
     294    {
     295      // If we are using the same DbControl as before we don't have to rebuild the query
     296      String idHql = getIdQuery(dc, true);
     297      if (stateless)
     298      {
     299        lastIdQuery =  HibernateUtil.createQuery(dc.getStatelessSession(), idHql);
     300      }
     301      else
     302      {
     303        lastIdQuery =  HibernateUtil.createQuery(dc.getHibernateSession(), idHql);
     304      }
     305    }
     306    lastIdDc = dc;
     307    lastIdQuery.setCacheable(isCachingResult());
     308    setParameters(lastIdQuery, getParameters());
     309    if (getFirstResult() >= 0) lastIdQuery.setFirstResult(getFirstResult());
     310    if (getMaxResults() > 0) lastIdQuery.setMaxResults(getMaxResults());
     311    return lastIdQuery;
     312  }
     313
    269314  /**
    270315    If queries are using the stateless Hibernate session or the regular
  • trunk/src/core/net/sf/basedb/core/AbstractQuery.java

    r6444 r6771  
    660660  }
    661661 
     662 
     663  /**
     664    Build a query string that is identical to the main query but only return the ID values.
     665    @since 3.5
     666  */
     667  String getIdQuery(DbControl dc, boolean autoJoin)
     668    throws BaseException
     669  {
     670    if (autoJoin) autoJoin();
     671   
     672    StringBuilder ql = new StringBuilder();
     673    ql.append(isDistinct() ? "SELECT DISTINCT " : "SELECT ");
     674    ql.append(getRootAlias() + ".id");
     675
     676    int appended = 0;
     677    final boolean useThetaJoin = HibernateUtil.useThetaJoin(getQueryType());
     678   
     679    querySection = QuerySection.FROM;
     680    ql.append(" FROM ").append(rootEntity).append(" ").append(getRootAlias());
     681   
     682    // Append JOIN elements
     683    thetaJoinConditions =  useThetaJoin ? new LinkedList<String>() : null;
     684    appended = appendJoins(ql, dc, temporaryJoins, useThetaJoin, 0);
     685    appended += appendJoins(ql, dc, permanentJoins, useThetaJoin, appended);
     686    appended += appendJoins(ql, dc, joins, useThetaJoin, appended);
     687 
     688    // Append WHERE elements
     689    appended = 0;
     690    if (thetaJoinConditions != null)
     691    {
     692      String deliminator = "WHERE ";
     693      for (String thetaJoinCondition : thetaJoinConditions)
     694      {
     695        ql.append(deliminator).append(thetaJoinCondition);
     696        appended++;
     697        deliminator = " AND ";
     698      }
     699    }
     700   
     701    // Append WHERE elements
     702    appended += appendRestrictions(ql, dc, permanentRestrictions, appended);
     703    appended += appendRestrictions(ql, dc, restrictions, appended);
     704   
     705    // Append GROUP BY elements
     706    appended = appendGroups(ql, dc, permanentGroups, 0);
     707    appended += appendGroups(ql, dc, groups, appended);
     708   
     709    // Append HAVING elements
     710    appended = appendHavings(ql, dc, permanentHavings, 0);
     711    appended += appendHavings(ql, dc, havings, appended);
     712   
     713    // Append ORDER BY elements
     714    appended = appendOrders(ql, dc, permanentOrders, 0);
     715    appended += appendOrders(ql, dc, orders, appended);
     716    String query = postProcessQuery(ql.toString());
     717    if (debugEnabled) logSql.debug("ID query(" + getQueryType()+ "): " +query);
     718    return query;
     719  }
     720
     721 
    662722  /**
    663723    Build the query string for returning the total count.
  • trunk/src/core/net/sf/basedb/core/ItemList.java

    r6770 r6771  
    3333import org.apache.commons.collections.Predicate;
    3434
     35import net.sf.basedb.core.query.Expressions;
    3536import net.sf.basedb.core.query.Hql;
     37import net.sf.basedb.core.query.Restrictions;
    3638import net.sf.basedb.core.SyncFilter.SourceItemTransform;
    3739import net.sf.basedb.core.data.ItemListData;
     
    938940    @return The number of members in the list after applying the filter
    939941  */
    940   /*
    941   public int resyncFilter(DbControl dc, SynchronizeOption syncOptions)
     942  public int resyncFilter(DbControl dc, SynchronizeOption syncOptions, boolean applySubtypeFilter)
    942943  {
    943944    checkPermission(Permission.WRITE);
     
    949950    for (ItemListSyncFilterData sf : syncFilters)
    950951    {
     952      // Ignore empty filters
     953      if (sf.getPropertyFilters().isEmpty()) continue;
     954     
     955      Item sourceItemType = Item.fromValue(sf.getSourceItemType());
     956     
     957      ItemQuery<? extends BasicItem> query = sourceItemType.getQuery();
     958      ItemContext syncContext = new ItemContext(sourceItemType, sf);
     959      syncContext.configureQuery(dc, query, true);
     960
     961      // Load all matching items and save their id:s
     962      Set<Integer> matching = new HashSet<Integer>(query.idList(dc));
     963      sf.setMatching(matching.size());
     964     
     965      // For now, ignore parent/child transforms
     966      if (sf.getSourceItemTransform() != SourceItemTransform.NONE.ordinal()) continue;
     967     
     968      if (intersection == null)
     969      {
     970        intersection = matching;
     971      }
     972      else
     973      {
     974        intersection.retainAll(matching);
     975      }
     976    }
     977   
     978    if (applySubtypeFilter)
     979    {
     980      ItemSubtype subtype = getItemSubtype();
     981      RawDataType rawDataType = getRawDataType();
    951982      ItemQuery<? extends Listable> query = getAllItems();
    952       ItemContext syncContext = new ItemContext(getMemberType(), sf);
    953       syncContext.configureQuery(dc, query, true);
    954 
    955       // Load all matching items and save their id:s
    956       Set<Integer> matching = new HashSet<Integer>();
    957       Iterator<? extends Listable> it = query.iterate(dc);
    958       while (it.hasNext())
    959       {
    960         matching.add(it.next().getId());
    961       }
    962       sf.setMatching(matching.size());
     983      query.setIncludes(Include.ALL);
     984     
     985      if (subtype != null)
     986      {
     987        query.restrict(Restrictions.eq(Hql.property("itemSubtype"), Hql.entity(subtype)));
     988      }
     989      else if (rawDataType != null)
     990      {
     991        query.restrict(Restrictions.eq(Hql.property("rawDataType"), Expressions.string(rawDataType.getId())));
     992      }
     993      Set<Integer> matching = new HashSet<Integer>(query.idList(dc));
    963994      if (intersection == null)
    964995      {
     
    9701001      }
    9711002    }
    972  
     1003   
    9731004    Set<Integer> members = getData().getMembers();
    974     syncOptions.synchronize(members, intersection);
     1005    if (intersection != null)
     1006    {
     1007      syncOptions.synchronize(members, intersection);
     1008    }
    9751009   
    9761010    getData().setSyncDate(new Date());
    9771011    getData().setSize(members.size());
    9781012    return members.size();
    979   }
    980   */
    981  
     1013  }
    9821014 
    9831015  /**
  • trunk/src/core/net/sf/basedb/core/query/EntityQuery.java

    r5319 r6771  
    2525
    2626import java.util.Collection;
     27import java.util.List;
    2728
     29import net.sf.basedb.core.BaseException;
     30import net.sf.basedb.core.DbControl;
    2831import net.sf.basedb.core.Item;
    2932import net.sf.basedb.core.Include;
     
    129132  */
    130133  public Permission getItemPermission();
     134
     135
     136  /**
     137    Execute the query and return the ID values of all items matching
     138    the query.
     139    @param dc The <code>DbControl</code> used to access the database
     140      and check permissions
     141    @throws BaseException If there is an error
     142    @since 3.5
     143  */
     144  public List<Integer> idList(DbControl dc);
     145
    131146}
  • trunk/www/views/itemlists/index.jsp

    r6770 r6771  
    2929  import="net.sf.basedb.core.Include"
    3030  import="net.sf.basedb.core.ItemList"
     31  import="net.sf.basedb.core.ItemList.SynchronizeOption"
    3132  import="net.sf.basedb.core.RawDataTypes"
    3233  import="net.sf.basedb.core.ItemSubtype"
     
    244245    }
    245246  }
    246   /*
    247   else if ("ReSyncFilter".equals(cmd))
     247  else if ("ReSync".equals(cmd))
    248248  {
    249249    dc = sc.newDbControl();
    250250    ItemList list = ItemList.getById(dc, Values.getInt(itemId));
    251     list.resyncFilter(dc, ItemList.SynchronizeOption.FULL);
    252     dc.commit();
    253     forward = viewPage;
    254   }
    255   */
     251   
     252    SynchronizeOption syncOption = SynchronizeOption.valueOf(request.getParameter("syncoption"));
     253    boolean subtypeFilter = Values.getBoolean(request.getParameter("subtype"));
     254    boolean rawDataTypeFilter = Values.getBoolean(request.getParameter("rawdatatype"));
     255   
     256    int numBefore = list.getSize();
     257    int numAfter = list.resyncFilter(dc, syncOption, subtypeFilter || rawDataTypeFilter);
     258   
     259    dc.commit();
     260   
     261    message = "List synchronized successfully; " + numAfter + " members ("+numBefore+")";
     262  }
    256263  else if ("DeleteItem".equals(cmd))
    257264  {
  • trunk/www/views/itemlists/lists.js

    r6770 r6771  
    9090      Buttons.addClickHandler('btnAddSyncFilter', Buttons.newItem);
    9191      Buttons.addClickHandler('btnRemoveSyncFilter', lists.removeSyncFilterOnClick);
     92      Buttons.addClickHandler('btnResync', lists.resyncFilters);
    9293     
    9394      TabControl.addTabActivateListener('main.annotations', AnnotationsList.loadOnce);
     
    158159  }
    159160 
     161  lists.resyncFilters = function()
     162  {
     163    var listId = Data.get('page-data', 'item-id');
     164    var url = 'resync.jsp?ID='+App.getSessionId();
     165    url += '&item_id='+listId;
     166    Dialogs.openPopup(url, 'ReSync', 600, 400);
     167  }
     168 
    160169  lists.validateList = function()
    161170  {
  • trunk/www/views/itemlists/view_list.jsp

    r6770 r6771  
    278278      </tr>
    279279      <tr>
     280        <th>Last sync</th>
     281        <td><%=list.getSyncDate() == null ? "<i>never</i>" : timeFormatter.format(list.getSyncDate())%></td>
     282      </tr>
     283      <tr>
    280284        <th>External ID</th>
    281285        <td><%=HTML.encodeTags(list.getExternalId())%></td>
     
    344348              tooltip="<%=writePermission ? "Remove the selected filters" : "You do not have permission to modify the filters"%>" 
    345349              title="Remove&hellip;"
     350            />
     351            <tbl:button
     352              id="btnResync"
     353              image="resync.png"
     354              disabled="<%=!writePermission || syncFilters.size() == 0%>"
     355              tooltip="Re-sync all filters" 
     356              title="Re-sync&hellip;"
    346357            />
    347358          </tbl:toolbar>
Note: See TracChangeset for help on using the changeset viewer.