Changeset 4600


Ignore:
Timestamp:
Oct 24, 2008, 1:43:13 PM (14 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1156: Add support for ALL and ANY constructs to the Query API

Location:
trunk/src/core/net/sf/basedb/core
Files:
2 added
6 edited

Legend:

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

    r4517 r4600  
    2626import net.sf.basedb.core.query.EntityQuery;
    2727import net.sf.basedb.core.query.JoinType;
     28import net.sf.basedb.core.query.QueryParameter;
    2829import net.sf.basedb.core.query.Select;
    2930import net.sf.basedb.core.query.Expression;
     
    414415    lastMainDc = dc;
    415416    lastMainQuery.setCacheable(isCachingResult());
    416     setParameters(lastMainQuery, getPermanentParameters());
    417417    setParameters(lastMainQuery, getParameters());
    418418    if (getFirstResult() >= 0) lastMainQuery.setFirstResult(getFirstResult());
     
    447447    lastCountDc = dc;
    448448    lastCountQuery.setCacheable(true);
    449     setParameters(lastCountQuery, getPermanentParameters());
    450449    setParameters(lastCountQuery, getParameters());
    451450    return lastCountQuery;
     
    497496    @param parameters A map containing parameter names and values
    498497  */
    499   private void setParameters(org.hibernate.Query query, Map<String, Object> parameters)
     498  private void setParameters(org.hibernate.Query query, Map<String, QueryParameter> parameters)
    500499  {
    501500    if (parameters == null) return;
     
    504503      logParam.debug("Binding parameters to query: " + query.getQueryString());
    505504    }
    506     for (Map.Entry<String, Object> entry : parameters.entrySet())
     505    for (Map.Entry<String, QueryParameter> entry : parameters.entrySet())
    507506    {
    508507      String name = entry.getKey();
    509       Object value = entry.getValue();
    510       Type valueType = getParameterType(name);
     508      QueryParameter qp = entry.getValue();
     509      Type valueType = qp.getType();
     510      Object value = qp.getValue();
    511511      if (value instanceof Collection)
    512512      {
  • trunk/src/core/net/sf/basedb/core/AbstractQuery.java

    r4517 r4600  
    2727import net.sf.basedb.core.query.Query;
    2828import net.sf.basedb.core.query.QueryElement;
     29import net.sf.basedb.core.query.QueryParameter;
    2930import net.sf.basedb.core.query.QuerySection;
    3031import net.sf.basedb.core.query.Select;
     
    3536import net.sf.basedb.util.NestedIterator;
    3637
     38import java.util.Collections;
    3739import java.util.HashSet;
    3840import java.util.Iterator;
     
    152154    Parameters values added to the query.
    153155  */
    154   private Map<String, Object> parameters;
    155 
    156   /**
    157     Permanent parameter values added to the query.
    158   */
    159   private Map<String, Object> permanentParameters;
    160 
    161   /**
    162     Maps parameters to types.
    163   */
    164   private Map<String, Type> parameterTypes;
    165  
     156  private Map<String, QueryParameter> parameters;
     157
    166158  /**
    167159    The index of the first result that should be returned by the query.
     
    354346  }
    355347 
    356   public void setParameter(String name, Object value, Type valueType)
    357     throws InvalidDataException, BaseException
     348  private void setParameter(String name, boolean permanent, Object value, Type valueType)
    358349  {
    359350    if (name == null) throw new InvalidUseOfNullException("name");
    360351    if (value == null) throw new InvalidUseOfNullException("value");
    361     if (permanentParameters != null && permanentParameters.containsKey(name))
    362     {
    363       throw new InvalidDataException("The parameter "+name+" has already been permanently set and cannot be changed");
    364     }
    365     if (valueType != null)
    366     {
    367       if (value != null) validateParameterType(name, value, valueType);
    368       if (parameterTypes == null) parameterTypes = new HashMap<String, Type>();
    369       parameterTypes.put(name, valueType);
    370     }
    371     if (parameters == null) parameters = new HashMap<String, Object>();
    372     parameters.put(name, value);
    373   }
     352    if (parameters == null) parameters = new HashMap<String, QueryParameter>();
     353    QueryParameter qp = parameters.get(name);
     354    if (qp != null && qp.isPermanent())
     355    {
     356      throw new InvalidDataException("The parameter '"+name+
     357          "' has already been permanently set and cannot be changed");
     358    }
     359    if (valueType != null && value != null) validateParameterType(name, value, valueType);
     360    parameters.put(name, new QueryParameter(name, permanent, valueType, value));
     361  }
     362 
     363  public void setParameter(String name, Object value, Type valueType)
     364    throws InvalidDataException, BaseException
     365  {
     366    setParameter(name, false, value, valueType);
     367  }
     368 
    374369  public void setPermanentParameter(String name, Object value, Type valueType)
    375370    throws InvalidDataException, BaseException
    376371  {
    377     if (name == null) throw new InvalidUseOfNullException("name");
    378     if (value == null) throw new InvalidUseOfNullException("value");
    379     if (permanentParameters == null) permanentParameters = new HashMap<String, Object>();
    380     if (valueType != null)
    381     {
    382       if (value != null) validateParameterType(name, value, valueType);
    383       if (parameterTypes == null) parameterTypes = new HashMap<String, Type>();
    384       parameterTypes.put(name, valueType);
    385     }
    386     if (permanentParameters.containsKey(name))
    387     {
    388       throw new InvalidDataException("The parameter "+name+" has already been permanently set and cannot be changed");
    389     }
    390     permanentParameters.put(name, value);
     372    setParameter(name, true, value, valueType);
    391373  }
    392374
    393375  public boolean hasParameterValue(String name)
    394376  {
    395     return (parameters != null && parameters.containsKey(name)) ||
    396       (permanentParameters != null && permanentParameters.containsKey(name));
     377    return (parameters != null && parameters.containsKey(name));
     378  }
     379 
     380  /**
     381    @since 2.9
     382  */
     383  @Override
     384  public Set<String> getParameterNames()
     385  {
     386    if (parameters == null)
     387    {
     388      return Collections.emptySet();
     389    }
     390    else
     391    {
     392      return parameters.keySet();
     393    }
     394  }
     395 
     396  /**
     397    @since 2.9
     398  */
     399  @Override
     400  public QueryParameter getQueryParameter(String name)
     401  {
     402    return parameters == null ? null : parameters.get(name);
    397403  }
    398404 
     
    468474    return querySection;
    469475  }
     476 
     477  @Override
     478  public String toQl(DbControl dc)
     479  {
     480    return getMainQuery(dc, true);
     481  }
    470482  // -------------------------------------------
    471483
     
    530542 
    531543  /**
    532     Get all permanent parameter values.
    533   */
    534   Map<String, Object> getPermanentParameters()
    535   {
    536     return permanentParameters;
    537   }
    538  
    539   /**
    540     Get all non-permanent parameter values.
    541   */
    542   Map<String, Object> getParameters()
     544    Get all query parameters.
     545  */
     546  Map<String, QueryParameter> getParameters()
    543547  {
    544548    return parameters;
    545   }
    546  
    547   /**
    548     Get the types of all parameters.
    549   */
    550   Map<String, Type> getParameterTypes()
    551   {
    552     return parameterTypes;
    553549  }
    554550 
     
    561557  Object getParameterValue(String name)
    562558  {
    563     if (permanentParameters != null && permanentParameters.containsKey(name))
    564     {
    565       return permanentParameters.get(name);
    566     }
    567     else if (parameters != null)
    568     {
    569       return parameters.get(name);
    570     }
    571     return null;
     559    QueryParameter qp = getQueryParameter(name);
     560    return qp == null ? null : qp.getValue();
    572561  }
    573562
     
    577566  Type getParameterType(String name)
    578567  {
    579     return parameterTypes == null ? null : parameterTypes.get(name);
     568    QueryParameter qp = getQueryParameter(name);
     569    return qp == null ? null : qp.getType();
    580570  }
    581571 
     
    595585    // Append SELECT elements
    596586    appended = appendSelects(ql, dc, temporarySelects, 0);
    597     appended += appendSelects(ql,dc, permanentSelects, appended);
    598     appended += appendSelects(ql,dc, selects, appended);
     587    appended += appendSelects(ql, dc, permanentSelects, appended);
     588    appended += appendSelects(ql, dc, selects, appended);
    599589   
    600590    querySection = QuerySection.FROM;
     
    657647      // Append SELECT elements
    658648      appended = appendSelects(ql, dc, temporarySelects, 0);
    659       appended += appendSelects(ql,dc, permanentSelects, appended);
    660       appended += appendSelects(ql,dc, selects, appended);
     649      appended += appendSelects(ql, dc, permanentSelects, appended);
     650      appended += appendSelects(ql, dc, selects, appended);
    661651      ql.append(") ");
    662652    }
     
    725715  }
    726716
    727   private int appendJoins(StringBuilder ql, DbControl dc, List<Join> joins, boolean useThetaJoin, int alreadyAppended)
     717  private int appendJoins(StringBuilder ql, DbControl dc,
     718    List<Join> joins, boolean useThetaJoin, int alreadyAppended)
    728719    throws BaseException
    729720  {
  • trunk/src/core/net/sf/basedb/core/AbstractSqlQuery.java

    r4517 r4600  
    2525
    2626import net.sf.basedb.core.hibernate.ResultSetWork;
     27import net.sf.basedb.core.query.QueryParameter;
    2728import net.sf.basedb.core.query.SqlQuery;
    2829import net.sf.basedb.core.query.QueryType;
     
    311312    for (String name : parameterOrder)
    312313    {
    313       Object parameterValue = getParameterValue(name);
    314       Type valueType = getParameterType(name);
     314      QueryParameter qp = getQueryParameter(name);
     315      Object parameterValue = qp == null ? null : qp.getValue();
     316      Type valueType = qp == null ? null : qp.getType();
    315317      if (parameterValue instanceof Collection)
    316318      {
  • trunk/src/core/net/sf/basedb/core/query/Expressions.java

    r4516 r4600  
    360360 
    361361  /**
     362    Create a subquery expression: <code>ANY (subquery)</code>.
     363    The expression is useful in the WHERE part of a query only.
     364    For example, to find all users that are members of a group
     365    having a name starting with A.
     366    <pre class="code">
     367Query groupFilter = User.getQuery();
     368groupFilter.join(Hql.innerJoin("groups", "grp"));
     369groupFilter.restrict(Restrictions.like(Hql.property("grp", "name"), Expressions.string("A%")));
     370Query userQuery = User.getQuery();
     371userQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.any(groupFilter)));
     372</pre>
     373   
     374    @param subquery The subquery
     375    @return The new expression
     376    @throws InvalidDataException If the subquery is null
     377    @since 2.9
     378  */
     379  public static Expression any(Query subquery)
     380  {
     381    if (subquery == null) throw new InvalidUseOfNullException("subquery");
     382    return new SubqueryExpression("ANY", subquery);
     383  }
     384 
     385  /**
     386    Create a subquery expression: <code>ANY (subquery)</code>.
     387    @param subquery The subquery
     388    @return The new expression
     389    @throws InvalidDataException If the subquery is null
     390    @see #any(Query)
     391    @since 2.9
     392  */
     393  public static Expression all(Query subquery)
     394  {
     395    if (subquery == null) throw new InvalidUseOfNullException("subquery");
     396    return new SubqueryExpression("ALL", subquery);
     397  }
     398 
     399  /**
    362400    Test if there is null in the array.
    363401    @return The index of the first null element,
  • trunk/src/core/net/sf/basedb/core/query/HqlPropertyExpression.java

    r4516 r4600  
    8282  public String toString()
    8383  {
    84     return (alias == null ? "" : alias + ".") + property;
     84    if (alias != null && property != null)
     85    {
     86      return alias + "." + property;
     87    }
     88    return property == null ? alias : property;
    8589  }
    8690  // -------------------------------------------
  • trunk/src/core/net/sf/basedb/core/query/Query.java

    r4516 r4600  
    2222*/
    2323package net.sf.basedb.core.query;
     24
     25import java.util.Set;
    2426
    2527import net.sf.basedb.core.DbControl;
     
    226228
    227229  /**
     230    Get a set with the names for all parameters in this
     231    query.
     232    @return A set (empty if no parameters exists)
     233    @since 2.9
     234  */
     235  public Set<String> getParameterNames();
     236 
     237  /**
     238    Get parameter information for the parameter with given name.
     239    @param name The name of the parameter
     240    @return A QueryParameter object or null if no parameter with
     241      that name exists
     242    @since 2.9
     243  */
     244  public QueryParameter getQueryParameter(String name);
     245 
     246  /**
    228247    Specify that the query should start returning rows from the
    229248    specified row number. 0 = start returning from the first row. If the
     
    345364  public QuerySection getQuerySection();
    346365 
     366  /**
     367    Generate the query string that is going to be sent to the
     368    underlying query system (eg. HQL/Hibernate or SQL/JDBC).
     369   
     370    @param dc The DbControl that is going to be used for
     371      executing the query
     372    @return The query string
     373    @since 2.9
     374  */
     375  public String toQl(DbControl dc);
    347376}
Note: See TracChangeset for help on using the changeset viewer.