Changeset 4071


Ignore:
Timestamp:
Dec 19, 2007, 2:02:39 PM (15 years ago)
Author:
Martin Svensson
Message:

References #762 The functionality is now completely implemented. It needs to be documented before this ticket can be closed.

Location:
trunk/src
Files:
5 edited

Legend:

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

    r4058 r4071  
    568568                      (isList ? Operator.IN : Operator.EQ);
    569569                value = value.substring(1);
    570               }
     570              }             
    571571              if ("".equals(value)) value = null;
    572572              if (valueType == Type.DATE && value != null)
     
    577577                try
    578578                {
    579                   Date d = dateFormatter != null ? dateFormatter.parseString(value) : DateUtil.parseString(value);
    580                   value = d == null ? null : Long.toString(d.getTime());
     579                  if (isList)
     580                  {
     581                    String[] dates = value.split("\\" + filter.getValueSeparator());
     582                    value = "";
     583                    boolean addSeparator = false;
     584                    for (String s : dates)
     585                    {
     586                      Date d = dateFormatter != null ? dateFormatter.parseString(s) : DateUtil.parseString(s);                     
     587                      if (d != null)
     588                      {                       
     589                        value += (addSeparator ? filter.getValueSeparator() : "") + Long.toString(d.getTime());
     590                        addSeparator = true;
     591                      }
     592                    }
     593                    value = value.length() == 0 ? null : value;                   
     594                  }
     595                  else
     596                  {
     597                    Date d = dateFormatter != null ? dateFormatter.parseString(value) : DateUtil.parseString(value);
     598                    value = d == null ? null : Long.toString(d.getTime());
     599                  }
    581600                }
    582601                catch (Throwable t)
     
    675694          // Dates are stored as long time values; reformat according to date formatter
    676695          // or as yyyy-MM-dd if no formatter is specified
    677           Date d = new Date(Long.parseLong(value));
    678           if (dateFormatter != null)
     696          if (!op.isListOperator())
    679697          {
    680             value = dateFormatter.format(d);
     698            Date d = new Date(Long.parseLong(value));
     699            if (dateFormatter != null)
     700            {
     701              value = dateFormatter.format(d);
     702            }
     703            else
     704            {
     705              value = DateUtil.formatDate(d);
     706            }
    681707          }
    682708          else
    683709          {
    684             value = DateUtil.formatDate(d);
     710            String[] dates = value.split("\\" + filter.getValueSeparator());
     711            boolean addSeparator = false;
     712            for (String s : dates)
     713            {
     714              Date d = new Date(Long.parseLong(s));
     715              value = addSeparator ? value + filter.getValueSeparator() : "";
     716              if (dateFormatter != null)
     717              {
     718                value += dateFormatter.format(d);               
     719              }
     720              else
     721              {
     722                value += DateUtil.formatDate(d);
     723              }
     724              addSeparator = true;
     725            }
    685726          }
    686727        }
     
    692733        result = "=";
    693734      }
    694       else if (op == Operator.NEQ || op == Operator.NOTLIKE)
     735      else if (op == Operator.NEQ || op == Operator.NOTLIKE ||
     736          op == Operator.NOTLIKE_IN || op == Operator.NOTIN)
    695737      {
    696738        result = "<>";
     
    711753      {
    712754        result = "<=";
     755      }
     756      else if (op == Operator.EQ && value.contains(filter.getValueSeparator()))
     757      {
     758        result = "==";
    713759      }
    714760      result += value == null ? "" : value;
  • trunk/src/core/net/sf/basedb/core/AnnotationSimpleRestriction.java

    r3679 r4071  
    2727
    2828import net.sf.basedb.core.query.Query;
     29
     30import java.util.List;
    2931
    3032import org.hibernate.SQLQuery;
     
    4446  private final Operator operator;
    4547  private final Object value;
     48  private final List<Object> values;
    4649
    4750  /**
     
    9497    this.operator = operator;
    9598    this.value = value;
     99    this.values = null;
    96100  }
    97101
     
    144148    this.operator = operator;
    145149    this.value = value;
     150    this.values = null;
     151  }
     152 
     153  /**
     154    Creates a new annotation restriction for a specific <code>valueType</code>.
     155    The restriction is with a list of values.
     156   
     157    @param alias The alias of a joined item where the annotations are
     158      located or null to use the root entity of the query
     159      @param annotationTypeId the id of the annotation type to use in the query
     160    @param valueType the type of values for annotations
     161      @param operator The operator, it must be one of the expression
     162      operators, EQ, NEQ, etc., not a boolean operator, AND, OR, etc.
     163      @param values The list of values that should be used in the query, they must be of the
     164      correct value type for the annotation as defined by the
     165      {@link AnnotationType#getValueType()} property.
     166      @param includeInheriting TRUE if items inheriting the annotation should be returned by the query, FALSE otherwise
     167      @throws InvalidDataException If any of the parameters are null
     168      or not follow the rules above
     169    @since 2.5
     170  */
     171  public AnnotationSimpleRestriction(String alias, int annotationTypeId, Type valueType, Operator operator, List<Object> values, boolean includeInheriting)
     172    throws InvalidDataException
     173  {
     174    super(alias, annotationTypeId, valueType, includeInheriting);
     175    if (operator == null) throw new InvalidUseOfNullException("operator");
     176    if (values == null) throw new InvalidUseOfNullException("values");
     177    if (!operator.isExpressionOperator())
     178    {
     179      throw new InvalidDataException("Invalid operator for expression: "+operator);
     180    }
     181    for (Object obj : values)
     182    {
     183      if (!valueType.isCorrectType(obj))
     184      {
     185        throw new InvalidDataException("Value '"+obj+"' is a "+
     186          obj.getClass()+", not a "+valueType);
     187      }
     188    }
     189    this.operator = operator;
     190    this.values = values;
     191    this.value = null;
    146192  }
    147193 
     
    153199    throws BaseException
    154200  {
    155     org.hibernate.dialect.Dialect dialect = HibernateUtil.getDialect();
    156     return "v."+dialect.openQuote()+"value"+dialect.closeQuote()+" "+operator.getSqlSymbol()+" :value";
     201    org.hibernate.dialect.Dialect dialect = HibernateUtil.getDialect();   
     202    String restriction = null;
     203    if (!operator.isListOperator())
     204    {
     205      restriction = "v."+dialect.openQuote()+"value"+dialect.closeQuote()+" "+operator.getSqlSymbol()+ " :value";
     206    }
     207    else
     208    {
     209      if (operator == Operator.IN || operator == Operator.NOTIN)
     210      {
     211        restriction = "v."+dialect.openQuote()+"value"+dialect.closeQuote()+" "+operator.getSqlSymbol()+ " (:value)";
     212      }
     213      else if (operator == Operator.NOTLIKE_IN || operator == Operator.LIKE_IN)
     214      {
     215        boolean isFirst = true;
     216        restriction = "(";
     217        for (Object obj : values)
     218        {
     219          restriction += isFirst ? "" :
     220            operator == Operator.NOTLIKE_IN ? " AND ": " OR ";
     221          restriction += "v."+dialect.openQuote()+"value"+dialect.closeQuote()+" "+operator.getSqlSymbol()+ " :value"+System.identityHashCode(obj);
     222          isFirst = false;
     223        }
     224        restriction += ")";
     225      }
     226    }
     227    return restriction;
    157228  }
    158229 
    159230  void setRestrictionParameters(SQLQuery query)
    160231  {
    161     query.setParameter("value", value);
     232    if (!operator.isListOperator())
     233    {
     234      query.setParameter("value", value);
     235    }
     236    else
     237    {
     238      if (operator == Operator.IN || operator == Operator.NOTIN)
     239      {
     240        query.setParameterList("value", values);
     241      }
     242      else if (operator == Operator.LIKE_IN || operator == Operator.NOTLIKE_IN)
     243      {
     244        for (Object obj : values)
     245        {
     246          query.setParameter("value"+System.identityHashCode(obj), obj);
     247        }
     248      }
     249    }
     250   
    162251  }
    163252  // -----------------------------------------
  • trunk/src/core/net/sf/basedb/core/Operator.java

    r4058 r4071  
    204204 
    205205  /**
    206     @since 2.5
     206    @since 2.6
    207207   */
    208208  IN(12, "IN", "IN", true, true)
     
    223223 
    224224  /**
    225     @since 2.5
     225    @since 2.6
    226226   */
    227227  NOTIN(13, "NOT IN", "NOT IN", true, true)
     
    242242 
    243243  /**
    244     @since 2.5
     244    @since 2.6
    245245   */
    246246  LIKE_IN(14, "LIKE", "LIKE", true, true)
     
    261261
    262262  /**
    263     @since 2.5
    264    */
    265   NOTLIKE_IN(15, "LIKE", "LIKE", true, true)
     263    @since 2.6
     264   */
     265  NOTLIKE_IN(15, "NOT LIKE", "NOT LIKE", true, true)
    266266  {
    267267    public Restriction getRestriction(Expression lvalue, Expression rvalue)
     
    275275      throws InvalidDataException
    276276    {
    277       return Restrictions.not(Restrictions.like_in(lvalue, rvalues));
     277      return Restrictions.notLike_in(lvalue, rvalues);
    278278    }
    279279  };
  • trunk/src/core/net/sf/basedb/core/PropertyFilter.java

    r4067 r4071  
    5252{
    5353
     54  /**
     55    The string/characters used as a separator in a string with more then one filter values.
     56   */
     57  private final String value_separator = "|";
     58 
    5459  private final String property;
    5560  private Type valueType;
    5661  private Operator operator;
    5762  private String value;
    58 
     63 
    5964 
    6065  /**
     
    187192    Splits the value string at each "|" and creates
    188193    a list with objects from the substrings that were found.
    189     @return A list with objects.
     194    @return A list with objects, or null if splitting string of values returns null.
    190195    @throws InvalidDataException If any of the string values can't be parsed.
    191196    @sine 2.5
     
    193198  public List<Object> getValuesAsObjects()
    194199  {
    195     String[] values = value.split("|");
     200    String[] values = value.split("\\"+getValueSeparator());
     201    if (values == null) return null;
    196202    List<Object> objects = new ArrayList<Object>(values.length);
    197203    for (String v : values)
     
    254260      if (operator.isListOperator())
    255261      {
    256        
     262        restriction = new AnnotationSimpleRestriction(alias,annotationTypeId, getValueType(), getOperator(), getValuesAsObjects(), searchInherited);
    257263      }
    258264      else
     
    265271    {
    266272      String parameterName = "p" + System.identityHashCode(this);
    267       Expression parameter = getValue() == null ? null :
     273      Expression parameter = (getValue() == null || operator.isListOperator()) ? null :
    268274        Expressions.parameter(parameterName, getValueAsObject(), getValueType());
    269275
     
    306312              // property >= date + 24H
    307313              restriction = Restrictions.gteq(propertyExpression, parameterPlus24H);
    308             }
     314            }           
    309315          }
    310316          else
     
    320326                  Expressions.parameter(parameterName+"24h", filterPlus24H, Type.DATE);
    321327              Expression dateParameter = Expressions.parameter(parameterName, obj, getValueType());
    322               if (operator == Operator.IN)
    323               {
    324                 restrictions.add(Restrictions.between(propertyExpression, dateParameter, parameterPlus24H));
    325               }
    326               else if (operator == Operator.NOTIN)
    327               {
    328                 restrictions.add(Restrictions.not(Restrictions.between(propertyExpression, dateParameter, parameterPlus24H)));
    329               }
    330             }
    331             restriction = Restrictions.or(restrictions.toArray(new Restriction[restrictions.size()]));
     328              restrictions.add(Restrictions.between(propertyExpression, dateParameter, parameterPlus24H));
     329            }
     330            if (operator == Operator.IN)
     331            {
     332              restriction = Restrictions.or(restrictions.toArray(new Restriction[restrictions.size()]));
     333            }
     334            else if (operator == Operator.NOTIN)
     335            {
     336              restriction = Restrictions.not(Restrictions.or(restrictions.toArray(new Restriction[restrictions.size()])));
     337            }
    332338          }
    333          
    334339        }
    335340        if (restriction == null)
     
    365370    String value = getValue();
    366371    Expression parameter = null;
     372    List<Expression> parameters = null;
    367373    // Experimental - allows expressions like: >ch1
    368374    if (value != null && (valueType == Type.FLOAT || valueType == Type.DOUBLE || valueType == Type.INT || valueType == Type.LONG))
    369375    {
    370       if (value.matches("^ch\\d+$"))
     376      if (!getOperator().isListOperator() && value.matches("^ch\\d+$"))
    371377      {
    372378        int channel = Integer.parseInt(value.substring(2));
    373379        parameter = Dynamic.column(VirtualColumn.channel(channel));
    374380      }
    375     }
    376     if (parameter == null)
    377     {
    378       parameter = value == null ? null : Expressions.parameter(parameterName, getValueAsObject());
    379     }
    380     restriction = operator.getRestriction(propertyExpression, parameter);
     381      else if (getOperator().isListOperator())
     382      {
     383        String[] values = value.split("\\"+getValueSeparator());
     384        for (String s : values)
     385        {
     386          if (s.matches("^ch\\d+$"))
     387          {
     388            int channel = Integer.parseInt(s.substring(2));
     389            if (parameters == null)
     390            {
     391              parameters = new ArrayList<Expression>();
     392            }
     393            parameters.add(Dynamic.column(VirtualColumn.channel(channel)));
     394          }
     395        }
     396      }     
     397    }
     398    if (parameter == null && parameters == null)
     399    {
     400      if (getOperator().isListOperator())
     401      {
     402        List<Object> objects = getValuesAsObjects();       
     403        parameters = objects == null ? null : new ArrayList<Expression>(objects.size());
     404        for (Object obj : objects)
     405        {
     406          parameterName = "p" + System.identityHashCode(obj);
     407          parameters.add(Expressions.parameter(parameterName,obj));
     408        }       
     409      }
     410      else
     411      {
     412        parameter = value == null ? null : Expressions.parameter(parameterName, getValueAsObject());
     413      }
     414    }
     415    if (parameters != null)
     416    {
     417      restriction = operator.getRestriction(propertyExpression, parameters.toArray(new Expression[parameters.size()]));
     418    }
     419    else
     420    {
     421      restriction = operator.getRestriction(propertyExpression, parameter);
     422    }
    381423    return restriction;
    382424  }
     425 
     426  public String getValueSeparator()
     427  {
     428    return value_separator;
     429  }
    383430
    384431}
  • trunk/src/core/net/sf/basedb/core/query/Restrictions.java

    r4058 r4071  
    256256  /**
    257257    Check if one expression matches any expressions in an array:
    258     (e1 LIKE e2) OR (e1 LIKE e3) OR ....
     258    (e1 LIKE e2.1) OR (e1 LIKE e2.2) OR ....
    259259    @param e1 The left expression
    260260    @param e2 The array with expression to match against.
     
    281281 
    282282  /**
     283    Check if one expression doesn't matches any of the expressions in an array.
     284    (e1 NOT LIKE e2.1) AND (e1 NOT LIKE e2.2) AND...
     285      @param e1 The left expression. Null is not allowed
     286      @param e2 The array with expressions that shouldn't match. Values in the array can't be null.
     287      @return The new restriction
     288      @throws InvalidDataException If any of the required expressions are null.
     289      @since 2.6
     290   */
     291  public static Restriction notLike_in(Expression e1, Expression...e2)
     292  {
     293    if (e1 == null) throw new InvalidUseOfNullException("e1");
     294    int firstNull = getFirstNull(e2);
     295    if (firstNull >= 0 || e2 == null)
     296    {
     297      throw new InvalidUseOfNullException("e2[" + firstNull + "]");
     298    }
     299    if (e2.length < 1) throw new InvalidDataException("'e2' must contain at least one element");
     300    List<Restriction> restrictions = new ArrayList<Restriction>(e2.length);   
     301    for (Expression e : e2)
     302    {
     303      restrictions.add(Restrictions.not(Restrictions.like(e1, e)));
     304    }   
     305    return Restrictions.and(restrictions.toArray(new Restriction[restrictions.size()]));
     306  }
     307 
     308  /**
    283309    Test if there is null in the array.
    284310    @return The index of the first null element,
Note: See TracChangeset for help on using the changeset viewer.