package org.apache.torque.util;
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.Torque;
import org.apache.torque.adapter.DB;
import org.apache.torque.om.DateKey;
import org.apache.torque.om.ObjectKey;
/**
* This is a utility class that is used for retrieving different types
* of values from a hashtable based on a simple name string. This
* class is meant to minimize the amount of casting that needs to be
* done when working with Hashtables.
*
* NOTE: other methods will be added as needed and as time permits.
*
* @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
* @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
* @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
* @author <a href="mailto:eric@dobbse.net">Eric Dobbs</a>
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
* @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
* @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
* @version $Id: Criteria.java,v 1.42.2.3 2004/05/20 04:36:06 seade Exp $
*/
public class Criteria extends Hashtable
{
/** Comparison type. */
public static final SqlEnum EQUAL = SqlEnum.EQUAL;
/** Comparison type. */
public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL;
/** Comparison type. */
public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL;
/** Comparison type. */
public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN;
/** Comparison type. */
public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN;
/** Comparison type. */
public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL;
/** Comparison type. */
public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL;
/** Comparison type. */
public static final SqlEnum LIKE = SqlEnum.LIKE;
/** Comparison type. */
public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE;
/** Comparison type. */
public static final SqlEnum ILIKE = SqlEnum.ILIKE;
/** Comparison type. */
public static final SqlEnum NOT_ILIKE = SqlEnum.NOT_ILIKE;
/** Comparison type. */
public static final SqlEnum CUSTOM = SqlEnum.CUSTOM;
/** Comparison type. */
public static final SqlEnum DISTINCT = SqlEnum.DISTINCT;
/** Comparison type. */
public static final SqlEnum IN = SqlEnum.IN;
/** Comparison type. */
public static final SqlEnum NOT_IN = SqlEnum.NOT_IN;
/** Comparison type. */
public static final SqlEnum ALL = SqlEnum.ALL;
/** Comparison type. */
public static final SqlEnum JOIN = SqlEnum.JOIN;
/** "Order by" qualifier - ascending */
private static final SqlEnum ASC = SqlEnum.ASC;
/** "Order by" qualifier - descending */
private static final SqlEnum DESC = SqlEnum.DESC;
/** "IS NULL" null comparison */
public static final SqlEnum ISNULL = SqlEnum.ISNULL;
/** "IS NOT NULL" null comparison */
public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL;
/** "CURRENT_DATE" ANSI SQL function */
public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE;
/** "CURRENT_TIME" ANSI SQL function */
public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME;
private static final int DEFAULT_CAPACITY = 10;
private boolean ignoreCase = false;
private boolean singleRecord = false;
private boolean cascade = false;
private UniqueList selectModifiers = new UniqueList();
private UniqueList selectColumns = new UniqueList();
private UniqueList orderByColumns = new UniqueList();
private UniqueList groupByColumns = new UniqueList();
private Criterion having = null;
private Hashtable asColumns = new Hashtable(8);
private ArrayList joinL = null;
private ArrayList joinR = null;
/** The name of the database. */
private String dbName;
/** The name of the database as given in the contructor. */
private String originalDbName;
/**
* To limit the number of rows to return. <code>-1</code> means return all
* rows.
*/
private int limit = -1;
/** To start the results at a row other than the first one. */
private int offset = 0;
private HashMap aliases = null;
private boolean useTransaction = false;
/** the log. */
private static Log log = LogFactory.getLog(Criteria.class);
/**
* Creates a new instance with the default capacity.
*/
public Criteria()
{
this(DEFAULT_CAPACITY);
}
/**
* Creates a new instance with the specified capacity.
*
* @param initialCapacity An int.
*/
public Criteria(int initialCapacity)
{
this(Torque.getDefaultDB(), initialCapacity);
}
/**
* Creates a new instance with the default capacity which corresponds to
* the specified database.
*
* @param dbName The dabase name.
*/
public Criteria(String dbName)
{
this(dbName, DEFAULT_CAPACITY);
}
/**
* Creates a new instance with the specified capacity which corresponds to
* the specified database.
*
* @param dbName The dabase name.
* @param initialCapacity The initial capacity.
*/
public Criteria(String dbName, int initialCapacity)
{
super(initialCapacity);
this.dbName = dbName;
this.originalDbName = dbName;
}
/**
* Brings this criteria back to its initial state, so that it
* can be reused as if it was new. Except if the criteria has grown in
* capacity, it is left at the current capacity.
*/
public void clear()
{
super.clear();
ignoreCase = false;
singleRecord = false;
cascade = false;
selectModifiers.clear();
selectColumns.clear();
orderByColumns.clear();
groupByColumns.clear();
having = null;
asColumns.clear();
joinL = null;
joinR = null;
dbName = originalDbName;
offset = 0;
limit = -1;
aliases = null;
useTransaction = false;
}
/**
* Add an AS clause to the select columns. Usage:
* <p>
* <code>
*
* Criteria myCrit = new Criteria();
* myCrit.addAsColumn("alias", "ALIAS("+MyPeer.ID+")");
*
* </code>
*
* @param name wanted Name of the column
* @param clause SQL clause to select from the table
*
* If the name already exists, it is replaced by the new clause.
*
* @return A modified Criteria object.
*/
public Criteria addAsColumn(String name, String clause)
{
asColumns.put(name, clause);
return this;
}
/**
* Get the column aliases.
*
* @return A Hashtable which map the column alias names
* to the alias clauses.
*/
public Hashtable getAsColumns()
{
return asColumns;
}
/**
* Allows one to specify an alias for a table that can
* be used in various parts of the SQL.
*
* @param alias a <code>String</code> value
* @param table a <code>String</code> value
*/
public void addAlias(String alias, String table)
{
if (aliases == null)
{
aliases = new HashMap(8);
}
aliases.put(alias, table);
}
/**
* Returns the table name associated with an alias.
*
* @param alias a <code>String</code> value
* @return a <code>String</code> value
*/
public String getTableForAlias(String alias)
{
if (aliases == null)
{
return null;
}
return (String) aliases.get(alias);
}
/**
* Does this Criteria Object contain the specified key?
*
* @param table The name of the table.
* @param column The name of the column.
* @return True if this Criteria Object contain the specified key.
*/
public boolean containsKey(String table, String column)
{
return containsKey(table + '.' + column);
}
/**
* Convenience method to return value as a boolean.
*
* @param column String name of column.
* @return A boolean.
*/
public boolean getBoolean(String column)
{
return ((Boolean) getCriterion(column).getValue()).booleanValue();
}
/**
* Convenience method to return value as a boolean.
*
* @param table String name of table.
* @param column String name of column.
* @return A boolean.
*/
public boolean getBoolean(String table, String column)
{
return getBoolean(new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Will force the sql represented by this criteria to be executed within
* a transaction. This is here primarily to support the oid type in
* postgresql. Though it can be used to require any single sql statement
* to use a transaction.
*/
public void setUseTransaction(boolean v)
{
useTransaction = v;
}
/**
* called by BasePeer to determine whether the sql command specified by
* this criteria must be wrapped in a transaction.
*
* @return a <code>boolean</code> value
*/
protected boolean isUseTransaction()
{
return useTransaction;
}
/**
* Method to return criteria related to columns in a table.
*
* @param column String name of column.
* @return A Criterion.
*/
public Criterion getCriterion(String column)
{
return (Criterion) super.get(column);
}
/**
* Method to return criteria related to a column in a table.
*
* @param table String name of table.
* @param column String name of column.
* @return A Criterion.
*/
public Criterion getCriterion(String table, String column)
{
return getCriterion(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Method to return criterion that is not added automatically
* to this Criteria. This can be used to chain the
* Criterions to form a more complex where clause.
*
* @param column String full name of column (for example TABLE.COLUMN).
* @return A Criterion.
*/
public Criterion getNewCriterion(String column, Object value,
SqlEnum comparison)
{
return new Criterion(column, value, comparison);
}
/**
* Method to return criterion that is not added automatically
* to this Criteria. This can be used to chain the
* Criterions to form a more complex where clause.
*
* @param table String name of table.
* @param column String name of column.
* @return A Criterion.
*/
public Criterion getNewCriterion(String table, String column,
Object value, SqlEnum comparison)
{
return new Criterion(table, column, value, comparison);
}
/**
* This method adds a prepared Criterion object to the Criteria.
* You can get a new, empty Criterion object with the
* getNewCriterion() method. If a criterion for the requested column
* already exists, it is replaced. This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria();
* Criteria.Criterion c = crit
* .getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
* crit.add(c);
* </code>
*
* @param c A Criterion object
*
* @return A modified Criteria object.
*/
public Criteria add(Criterion c)
{
StringBuffer sb = new StringBuffer(c.getTable().length()
+ c.getColumn().length() + 1);
sb.append(c.getTable());
sb.append('.');
sb.append(c.getColumn());
super.put(sb.toString(), c);
return this;
}
/**
* Method to return a String table name.
*
* @param name A String with the name of the key.
* @return A String with the value of the object at key.
*/
public String getColumnName(String name)
{
return getCriterion(name).getColumn();
}
/**
* Method to return a comparison String.
*
* @param key String name of the key.
* @return A String with the value of the object at key.
*/
public SqlEnum getComparison(String key)
{
return getCriterion(key).getComparison();
}
/**
* Method to return a comparison String.
*
* @param table String name of table.
* @param column String name of column.
* @return A String with the value of the object at key.
*/
public SqlEnum getComparison(String table, String column)
{
return getComparison(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return a Date.
*
* @param name column name (TABLE.COLUMN)
* @return A java.util.Date with the value of object at key.
*/
public java.util.Date getDate(String name)
{
return (java.util.Date) getCriterion(name).getValue();
}
/**
* Convenience method to return a Date.
*
* @param table String name of table.
* @param column String name of column.
* @return A java.util.Date with the value of object at key.
*/
public java.util.Date getDate(String table, String column)
{
return getDate(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Get the Database(Map) name.
*
* @return A String with the Database(Map) name. By default, this
* is PoolBrokerService.DEFAULT.
*/
public String getDbName()
{
return dbName;
}
/**
* Set the DatabaseMap name. If <code>null</code> is supplied, uses value
* provided by <code>Torque.getDefaultDB()</code>.
*
* @param dbName A String with the Database(Map) name.
*/
public void setDbName(String dbName)
{
this.dbName = (dbName == null ? Torque.getDefaultDB() : dbName.trim());
}
/**
* Convenience method to return a double.
*
* @param name A String with the name of the key.
* @return A double with the value of object at key.
*/
public double getDouble(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new Double((String) obj).doubleValue();
}
return ((Double) obj).doubleValue();
}
/**
* Convenience method to return a double.
*
* @param table String name of table.
* @param column String name of column.
* @return A double with the value of object at key.
*/
public double getDouble(String table, String column)
{
return getDouble(new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return a float.
*
* @param name A String with the name of the key.
* @return A float with the value of object at key.
*/
public float getFloat(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new Float((String) obj).floatValue();
}
return ((Float) obj).floatValue();
}
/**
* Convenience method to return a float.
*
* @param table String name of table.
* @param column String name of column.
* @return A float with the value of object at key.
*/
public float getFloat(String table, String column)
{
return getFloat(new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return an Integer.
*
* @param name A String with the name of the key.
* @return An Integer with the value of object at key.
*/
public Integer getInteger(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new Integer((String) obj);
}
return ((Integer) obj);
}
/**
* Convenience method to return an Integer.
*
* @param table String name of table.
* @param column String name of column.
* @return An Integer with the value of object at key.
*/
public Integer getInteger(String table, String column)
{
return getInteger(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return an int.
*
* @param name A String with the name of the key.
* @return An int with the value of object at key.
*/
public int getInt(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new Integer((String) obj).intValue();
}
return ((Integer) obj).intValue();
}
/**
* Convenience method to return an int.
*
* @param table String name of table.
* @param column String name of column.
* @return An int with the value of object at key.
*/
public int getInt(String table, String column)
{
return getInt(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return a BigDecimal.
*
* @param name A String with the name of the key.
* @return A BigDecimal with the value of object at key.
*/
public BigDecimal getBigDecimal(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new BigDecimal((String) obj);
}
return (BigDecimal) obj;
}
/**
* Convenience method to return a BigDecimal.
*
* @param table String name of table.
* @param column String name of column.
* @return A BigDecimal with the value of object at key.
*/
public BigDecimal getBigDecimal(String table, String column)
{
return getBigDecimal(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return a long.
*
* @param name A String with the name of the key.
* @return A long with the value of object at key.
*/
public long getLong(String name)
{
Object obj = getCriterion(name).getValue();
if (obj instanceof String)
{
return new Long((String) obj).longValue();
}
return ((Long) obj).longValue();
}
/**
* Convenience method to return a long.
*
* @param table String name of table.
* @param column String name of column.
* @return A long with the value of object at key.
*/
public long getLong(String table, String column)
{
return getLong(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return a String.
*
* @param name A String with the name of the key.
* @return A String with the value of object at key.
*/
public String getString(String name)
{
return (String) getCriterion(name).getValue();
}
/**
* Convenience method to return a String.
*
* @param table String name of table.
* @param column String name of column.
* @return A String with the value of object at key.
*/
public String getString(String table, String column)
{
return getString(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Method to return a String table name.
*
* @param name A String with the name of the key.
* @return A String with the value of object at key.
*/
public String getTableName(String name)
{
return getCriterion(name).getTable();
}
/**
* Convenience method to return a List.
*
* @param name A String with the name of the key.
* @return A List with the value of object at key.
*/
public List getList(String name)
{
return (List) getCriterion(name).getValue();
}
/**
* Convenience method to return a List.
*
* @param table String name of table.
* @param column String name of column.
* @return A List with the value of object at key.
*/
public List getList(String table, String column)
{
return getList(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Method to return the value that was added to Criteria.
*
* @param name A String with the name of the key.
* @return An Object with the value of object at key.
*/
public Object getValue(String name)
{
return getCriterion(name).getValue();
}
/**
* Method to return the value that was added to Criteria.
*
* @param table String name of table.
* @param column String name of column.
* @return An Object with the value of object at key.
*/
public Object getValue(String table, String column)
{
return getValue(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Convenience method to return an ObjectKey.
*
* @param name A String with the name of the key.
* @return An ObjectKey with the value of object at key.
*/
public ObjectKey getObjectKey(String name)
{
return (ObjectKey) getCriterion(name).getValue();
}
/**
* Convenience method to return an ObjectKey.
*
* @param table String name of table.
* @param column String name of column.
* @return A String with the value of object at key.
*/
public ObjectKey getObjectKey(String table, String column)
{
return getObjectKey(
new StringBuffer(table.length() + column.length() + 1)
.append(table).append('.').append(column)
.toString());
}
/**
* Overrides Hashtable get, so that the value placed in the
* Criterion is returned instead of the Criterion.
*
* @param key An Object.
* @return An Object.
*/
public Object get(Object key)
{
return getValue((String) key);
}
/**
* Overrides Hashtable put, so that this object is returned
* instead of the value previously in the Criteria object.
* The reason is so that it more closely matches the behavior
* of the add() methods. If you want to get the previous value
* then you should first Criteria.get() it yourself. Note, if
* you attempt to pass in an Object that is not a String, it will
* throw a NPE. The reason for this is that none of the add()
* methods support adding anything other than a String as a key.
*
* @param key An Object. Must be instanceof String!
* @param value An Object.
* @throws NullPointerException if key != String or key/value is null.
* @return Instance of self.
*/
public Object put(Object key, Object value)
{
if (!(key instanceof String))
{
throw new NullPointerException(
"Criteria: Key must be a String object.");
}
return add((String) key, value);
}
/**
* Copies all of the mappings from the specified Map to this Criteria
* These mappings will replace any mappings that this Criteria had for any
* of the keys currently in the specified Map.
*
* if the map was another Criteria, its attributes are copied to this
* Criteria, overwriting previous settings.
*
* @param t Mappings to be stored in this map.
*/
public synchronized void putAll(Map t)
{
Iterator i = t.entrySet().iterator();
while (i.hasNext())
{
Map.Entry e = (Map.Entry) i.next();
Object val = e.getValue();
if (val instanceof Criteria.Criterion)
{
super.put(e.getKey(), val);
}
else
{
put(e.getKey(), val);
}
}
if (t instanceof Criteria)
{
Criteria c = (Criteria) t;
this.joinL = c.joinL;
this.joinR = c.joinR;
}
/* this would make a copy, not included
but might want to use some of it.
if (t instanceof Criteria)
{
Criteria c = (Criteria)t;
this.ignoreCase = c.ignoreCase;
this.singleRecord = c.singleRecord;
this.cascade = c.cascade;
this.selectModifiers = c.selectModifiers;
this.selectColumns = c.selectColumns;
this.orderByColumns = c.orderByColumns;
this.dbName = c.dbName;
this.limit = c.limit;
this.offset = c.offset;
this.aliases = c.aliases;
}
*/
}
/**
* This method adds a new criterion to the list of criterias. If a
* criterion for the requested column already exists, it is
* replaced. This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().add("column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the add(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
*
* @return A modified Criteria object.
*/
public Criteria add (String column, Object value)
{
add(column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* replaced. If is used as follow:
*
* <p>
* <code>
* Criteria crit = new Criteria().add("column",
* "value"
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the add(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison A String.
*
* @return A modified Criteria object.
*/
public Criteria add(String column, Object value, SqlEnum comparison)
{
super.put(column, new Criterion(column, value, comparison));
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* replaced. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().add("table",
* "column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* @param table Name of the table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
*
* @return A modified Criteria object.
*/
public Criteria add(String table, String column, Object value)
{
add(table, column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* replaced. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().add("table",
* "column",
* "value",
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* @param table Name of table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String table,
String column,
Object value,
SqlEnum comparison)
{
StringBuffer sb = new StringBuffer(table.length()
+ column.length() + 1);
sb.append(table);
sb.append('.');
sb.append(column);
super.put(sb.toString(),
new Criterion(table, column, value, comparison));
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Boolean(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
*
* @return A modified Criteria object.
*/
public Criteria add(String column, boolean value)
{
add(column, (value ? Boolean.TRUE : Boolean.FALSE));
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Boolean(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String column, boolean value, SqlEnum comparison)
{
add(column, new Boolean(value), comparison);
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Integer(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value An int.
* @return A modified Criteria object.
*/
public Criteria add(String column, int value)
{
add(column, new Integer(value));
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Integer(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value An int.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String column, int value, SqlEnum comparison)
{
add(column, new Integer(value), comparison);
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Long(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @return A modified Criteria object.
*/
public Criteria add(String column, long value)
{
add(column, new Long(value));
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Long(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String column, long value, SqlEnum comparison)
{
add(column, new Long(value), comparison);
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Float(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @return A modified Criteria object.
*/
public Criteria add(String column, float value)
{
add(column, new Float(value));
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Float(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String column, float value, SqlEnum comparison)
{
add(column, new Float(value), comparison);
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Double(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @return A modified Criteria object.
*/
public Criteria add(String column, double value)
{
add(column, new Double(value));
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new Double(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria add(String column, double value, SqlEnum comparison)
{
add(column, new Double(value), comparison);
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new GregorianCalendar(year, month,date), EQUAL);
* </code>
*
* @param column A String value to use as column.
* @param year An int with the year.
* @param month An int with the month. Month value is 0-based.
* e.g., 0 for January
* @param date An int with the date.
* @return A modified Criteria object.
*/
public Criteria addDate(String column, int year, int month, int date)
{
add(column, new GregorianCalendar(year, month, date).getTime());
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* add(column, new GregorianCalendar(year, month,date), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param year An int with the year.
* @param month An int with the month. Month value is 0-based.
* e.g., 0 for January
* @param date An int with the date.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria addDate(String column, int year, int month, int date,
SqlEnum comparison)
{
add(column, new GregorianCalendar(year, month, date).getTime(),
comparison);
return this;
}
/**
* This is the way that you should add a join of two tables. For
* example:
*
* <p>
* AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
* <p>
*
* left = PROJECT.PROJECT_ID
* right = FOO.PROJECT_ID
*
* @param left A String with the left side of the join.
* @param right A String with the right side of the join.
* @return A modified Criteria object.
*/
public Criteria addJoin(String left, String right)
{
if (joinL == null)
{
joinL = new ArrayList(3);
joinR = new ArrayList(3);
}
joinL.add(left);
joinR.add(right);
return this;
}
/**
* get one side of the set of possible joins. This method is meant to
* be called by BasePeer.
*/
public List getJoinL()
{
return joinL;
}
/**
* get one side of the set of possible joins. This method is meant to
* be called by BasePeer.
*/
public List getJoinR()
{
return joinR;
}
/**
* Adds an 'IN' clause with the criteria supplied as an Object
* array. For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values An Object[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria addIn(String column, Object[] values)
{
add(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as an int array.
* For example:
*
* <p>
* FOO.ID IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values An int[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria addIn(String column, int[] values)
{
add(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values A List with the allowed values.
* @return A modified Criteria object.
*/
public Criteria addIn(String column, List values)
{
add(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an Object
* array. For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values An Object[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria addNotIn(String column, Object[] values)
{
add(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an int
* array. For example:
*
* <p>
* FOO.ID NOT IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values An int[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria addNotIn(String column, int[] values)
{
add(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* replaced.
*
* @param column The column to run the comparison on
* @param values A List with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria addNotIn(String column, List values)
{
add(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds "ALL " to the SQL statement.
*/
public void setAll()
{
selectModifiers.add(ALL.toString());
}
/**
* Adds "DISTINCT " to the SQL statement.
*/
public void setDistinct()
{
selectModifiers.add(DISTINCT.toString());
}
/**
* Sets ignore case.
*
* @param b True if case should be ignored.
* @return A modified Criteria object.
*/
public Criteria setIgnoreCase(boolean b)
{
ignoreCase = b;
return this;
}
/**
* Is ignore case on or off?
*
* @return True if case is ignored.
*/
public boolean isIgnoreCase()
{
return ignoreCase;
}
/**
* Set single record? Set this to <code>true</code> if you expect the query
* to result in only a single result record (the default behaviour is to
* throw a TorqueException if multiple records are returned when the query
* is executed). This should be used in situations where returning multiple
* rows would indicate an error of some sort. If your query might return
* multiple records but you are only interested in the first one then you
* should be using setLimit(1).
*
* @param b set to <code>true</code> if you expect the query to select just
* one record.
* @return A modified Criteria object.
*/
public Criteria setSingleRecord(boolean b)
{
singleRecord = b;
return this;
}
/**
* Is single record?
*
* @return True if a single record is being returned.
*/
public boolean isSingleRecord()
{
return singleRecord;
}
/**
* Set cascade.
*
* @param b True if cascade is set.
* @return A modified Criteria object.
*/
public Criteria setCascade(boolean b)
{
cascade = b;
return this;
}
/**
* Is cascade set?
*
* @return True if cascade is set.
*/
public boolean isCascade()
{
return cascade;
}
/**
* Set limit.
*
* @param limit An int with the value for limit.
* @return A modified Criteria object.
*/
public Criteria setLimit(int limit)
{
this.limit = limit;
return this;
}
/**
* Get limit.
*
* @return An int with the value for limit.
*/
public int getLimit()
{
return limit;
}
/**
* Set offset.
*
* @param offset An int with the value for offset.
* @return A modified Criteria object.
*/
public Criteria setOffset(int offset)
{
this.offset = offset;
return this;
}
/**
* Get offset.
*
* @return An int with the value for offset.
*/
public int getOffset()
{
return offset;
}
/**
* Add select column.
*
* @param name A String with the name of the select column.
* @return A modified Criteria object.
*/
public Criteria addSelectColumn(String name)
{
selectColumns.add(name);
return this;
}
/**
* Get select columns.
*
* @return An StringStack with the name of the select
* columns.
*/
public UniqueList getSelectColumns()
{
return selectColumns;
}
/**
* Get select modifiers.
*
* @return An UniqueList with the select modifiers.
*/
public UniqueList getSelectModifiers()
{
return selectModifiers;
}
/**
* Add group by column name.
*
* @param groupBy The name of the column to group by.
* @return A modified Criteria object.
*/
public Criteria addGroupByColumn(String groupBy)
{
groupByColumns.add(groupBy);
return this;
}
/**
* Add order by column name, explicitly specifying ascending.
*
* @param name The name of the column to order by.
* @return A modified Criteria object.
*/
public Criteria addAscendingOrderByColumn(String name)
{
orderByColumns.add(name + ' ' + ASC);
return this;
}
/**
* Add order by column name, explicitly specifying descending.
*
* @param name The name of the column to order by.
* @return A modified Criteria object.
*/
public Criteria addDescendingOrderByColumn(String name)
{
orderByColumns.add(name + ' ' + DESC);
return this;
}
/**
* Get order by columns.
*
* @return An UniqueList with the name of the order columns.
*/
public UniqueList getOrderByColumns()
{
return orderByColumns;
}
/**
* Get group by columns.
*
* @return An UniqueList with the name of the groupBy clause.
*/
public UniqueList getGroupByColumns()
{
return groupByColumns;
}
/**
* Get Having Criterion.
*
* @return A Criterion that is the having clause.
*/
public Criterion getHaving()
{
return having;
}
/**
* Remove an object from the criteria.
*
* @param key A String with the key to be removed.
* @return The removed object.
*/
public Object remove(String key)
{
Object foo = super.remove(key);
if (foo instanceof Criterion)
{
return ((Criterion) foo).getValue();
}
return foo;
}
/**
* Build a string representation of the Criteria.
*
* @return A String with the representation of the Criteria.
*/
public String toString()
{
StringBuffer sb = new StringBuffer("Criteria:: ");
Iterator it = keySet().iterator();
while (it.hasNext())
{
String key = (String) it.next();
sb.append(key).append("<=>")
.append(super.get(key).toString()).append(": ");
}
try
{
sb.append("\nCurrent Query SQL (may not be complete or applicable): ")
.append(BasePeer.createQueryDisplayString(this));
}
catch (Exception exc)
{
}
return sb.toString();
}
/**
* This method checks another Criteria to see if they contain
* the same attributes and hashtable entries.
*/
public boolean equals(Object crit)
{
boolean isEquiv = false;
if (crit == null || !(crit instanceof Criteria))
{
isEquiv = false;
}
else if (this == crit)
{
isEquiv = true;
}
else if (this.size() == ((Criteria) crit).size())
{
Criteria criteria = (Criteria) crit;
if (this.offset == criteria.getOffset()
&& this.limit == criteria.getLimit()
&& ignoreCase == criteria.isIgnoreCase()
&& singleRecord == criteria.isSingleRecord()
&& cascade == criteria.isCascade()
&& dbName.equals(criteria.getDbName())
&& selectModifiers.equals(criteria.getSelectModifiers())
&& selectColumns.equals(criteria.getSelectColumns())
&& orderByColumns.equals(criteria.getOrderByColumns())
)
{
isEquiv = true;
for (Iterator it = criteria.keySet().iterator(); it.hasNext();)
{
String key = (String) it.next();
if (this.containsKey(key))
{
Criterion a = this.getCriterion(key);
Criterion b = criteria.getCriterion(key);
if (!a.equals(b))
{
isEquiv = false;
break;
}
}
else
{
isEquiv = false;
break;
}
}
}
}
return isEquiv;
}
/*
*------------------------------------------------------------------------
*
* Start of the "and" methods
*
*------------------------------------------------------------------------
*/
/**
* This method adds a prepared Criterion object to the Criteria as a having
* clause. You can get a new, empty Criterion object with the
* getNewCriterion() method.
*
* <p>
* <code>
* Criteria crit = new Criteria();
* Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
* Criteria.LESS_THAN);
* crit.addHaving(c);
* </code>
*
* @param having A Criterion object
* @return A modified Criteria object.
*/
public Criteria addHaving(Criterion having)
{
this.having = having;
return this;
}
/**
* This method adds a prepared Criterion object to the Criteria.
* You can get a new, empty Criterion object with the
* getNewCriterion() method. If a criterion for the requested column
* already exists, it is "AND"ed to the existing criterion.
* This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria();
* Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
* Criteria.LESS_THAN);
* crit.and(c);
* </code>
*
* @param c A Criterion object
* @return A modified Criteria object.
*/
public Criteria and(Criterion c)
{
Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
if (oc == null)
{
add(c);
}
else
{
oc.and(c);
}
return this;
}
/**
* This method adds a new criterion to the list of criterias. If a
* criterion for the requested column already exists, it is
* "AND"ed to the existing criterion. This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().and("column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the and(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
*
* @return A modified Criteria object.
*/
public Criteria and(String column, Object value)
{
and(column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion. If is used as follow:
*
* <p>
* <code>
* Criteria crit = new Criteria().and("column",
* "value"
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the and(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison A String.
*
* @return A modified Criteria object.
*/
public Criteria and(String column, Object value, SqlEnum comparison)
{
Criterion oc = getCriterion(column);
Criterion nc = new Criterion(column, value, comparison);
if (oc == null)
{
super.put(column, nc);
}
else
{
oc.and(nc);
}
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().and("table",
* "column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* @param table Name of the table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
* @return A modified Criteria object.
*/
public Criteria and(String table, String column, Object value)
{
and(table, column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().and("table",
* "column",
* "value",
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* @param table Name of table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria and(String table, String column, Object value,
SqlEnum comparison)
{
StringBuffer sb = new StringBuffer(table.length()
+ column.length() + 1);
sb.append(table);
sb.append('.');
sb.append(column);
Criterion oc = getCriterion(table, column);
Criterion nc = new Criterion(table, column, value, comparison);
if (oc == null)
{
super.put(sb.toString(), nc);
}
else
{
oc.and(nc);
}
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Boolean(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
* @return A modified Criteria object.
*/
public Criteria and(String column, boolean value)
{
and(column, new Boolean(value));
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Boolean(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria and(String column, boolean value, SqlEnum comparison)
{
and(column, new Boolean(value), comparison);
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Integer(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value An int.
* @return A modified Criteria object.
*/
public Criteria and(String column, int value)
{
and(column, new Integer(value));
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Integer(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value An int.
* @param comparison String describing how to compare the column with the value
* @return A modified Criteria object.
*/
public Criteria and(String column, int value, SqlEnum comparison)
{
and(column, new Integer(value), comparison);
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Long(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @return A modified Criteria object.
*/
public Criteria and(String column, long value)
{
and(column, new Long(value));
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Long(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria and(String column, long value, SqlEnum comparison)
{
and(column, new Long(value), comparison);
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Float(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @return A modified Criteria object.
*/
public Criteria and(String column, float value)
{
and(column, new Float(value));
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Float(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria and(String column, float value, SqlEnum comparison)
{
and(column, new Float(value), comparison);
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Double(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @return A modified Criteria object.
*/
public Criteria and(String column, double value)
{
and(column, new Double(value));
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new Double(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria and(String column, double value, SqlEnum comparison)
{
and(column, new Double(value), comparison);
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new GregorianCalendar(year, month,date), EQUAL);
* </code>
*
* @param column A String value to use as column.
* @param year An int with the year.
* @param month An int with the month.
* @param date An int with the date.
* @return A modified Criteria object.
*/
public Criteria andDate(String column, int year, int month, int date)
{
and(column, new GregorianCalendar(year, month, date));
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* and(column, new GregorianCalendar(year, month,date), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param year An int with the year.
* @param month An int with the month.
* @param date An int with the date.
* @param comparison String describing how to compare the column with
* the value
* @return A modified Criteria object.
*/
public Criteria andDate(String column, int year, int month, int date,
SqlEnum comparison)
{
and(column, new GregorianCalendar(year, month, date), comparison);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as an Object array.
* For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An Object[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria andIn(String column, Object[] values)
{
and(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as an int array.
* For example:
*
* <p>
* FOO.ID IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An int[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria andIn(String column, int[] values)
{
and(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values A List with the allowed values.
* @return A modified Criteria object.
*/
public Criteria andIn(String column, List values)
{
and(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an Object
* array. For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An Object[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria andNotIn(String column, Object[] values)
{
and(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an int
* array. For example:
*
* <p>
* FOO.ID NOT IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An int[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria andNotIn(String column, int[] values)
{
and(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "AND"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values A List with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria andNotIn(String column, List values)
{
and(column, (Object) values, Criteria.NOT_IN);
return this;
}
/*
*------------------------------------------------------------------------
*
* Start of the "or" methods
*
*------------------------------------------------------------------------
*/
/**
* This method adds a prepared Criterion object to the Criteria.
* You can get a new, empty Criterion object with the
* getNewCriterion() method. If a criterion for the requested column
* already exists, it is "OR"ed to the existing criterion.
* This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria();
* Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
* crit.or(c);
* </code>
*
* @param c A Criterion object
* @return A modified Criteria object.
*/
public Criteria or(Criterion c)
{
Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
if (oc == null)
{
add(c);
}
else
{
oc.or(c);
}
return this;
}
/**
* This method adds a new criterion to the list of criterias. If a
* criterion for the requested column already exists, it is
* "OR"ed to the existing criterion. This is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().or("column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the or(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
*
* @return A modified Criteria object.
*/
public Criteria or(String column, Object value)
{
or(column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion. If is used as follow:
*
* <p>
* <code>
* Criteria crit = new Criteria().or("column",
* "value"
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* The name of the table must be used implicitly in the column name,
* so the Column name must be something like 'TABLE.id'. If you
* don't like this, you can use the or(table, column, value) method.
*
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison A String.
* @return A modified Criteria object.
*/
public Criteria or(String column, Object value, SqlEnum comparison)
{
Criterion oc = getCriterion(column);
Criterion nc = new Criterion(column, value, comparison);
if (oc == null)
{
super.put(column, nc);
}
else
{
oc.or(nc);
}
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().or("table",
* "column",
* "value");
* </code>
*
* An EQUAL comparison is used for column and value.
*
* @param table Name of the table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
* @return A modified Criteria object.
*/
public Criteria or(String table, String column, Object value)
{
or(table, column, value, EQUAL);
return this;
}
/**
* This method adds a new criterion to the list of criterias.
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion. If is used as follows:
*
* <p>
* <code>
* Criteria crit = new Criteria().or("table",
* "column",
* "value",
* "Criterion.GREATER_THAN");
* </code>
*
* Any comparison can be used.
*
* @param table Name of table which contains the column
* @param column The column to run the comparison on
* @param value An Object.
* @param comparison String describing how to compare the column with the value
* @return A modified Criteria object.
*/
public Criteria or(String table, String column, Object value,
SqlEnum comparison)
{
StringBuffer sb = new StringBuffer(table.length() + column.length() + 1);
sb.append(table);
sb.append('.');
sb.append(column);
Criterion oc = getCriterion(table, column);
Criterion nc = new Criterion(table, column, value, comparison);
if (oc == null)
{
super.put(sb.toString(), nc);
}
else
{
oc.or(nc);
}
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Boolean(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
* @return A modified Criteria object.
*/
public Criteria or(String column, boolean value)
{
or(column, new Boolean(value));
return this;
}
/**
* Convenience method to add a boolean to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Boolean(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A Boolean.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria or(String column, boolean value, SqlEnum comparison)
{
or(column, new Boolean(value), comparison);
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Integer(value), EQUAL);
* </code>
*
*
* @param column The column to run the comparison on
* @param value An int.
* @return A modified Criteria object.
*/
public Criteria or(String column, int value)
{
or(column, new Integer(value));
return this;
}
/**
* Convenience method to add an int to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Integer(value), comparison);
* </code>
*
*
* @param column The column to run the comparison on
* @param value An int.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria or(String column, int value, SqlEnum comparison)
{
or(column, new Integer(value), comparison);
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Long(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @return A modified Criteria object.
*/
public Criteria or(String column, long value)
{
or(column, new Long(value));
return this;
}
/**
* Convenience method to add a long to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Long(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A long.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria or(String column, long value, SqlEnum comparison)
{
or(column, new Long(value), comparison);
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Float(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @return A modified Criteria object.
*/
public Criteria or(String column, float value)
{
or(column, new Float(value));
return this;
}
/**
* Convenience method to add a float to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Float(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A float.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria or(String column, float value, SqlEnum comparison)
{
or(column, new Float(value), comparison);
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Double(value), EQUAL);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @return A modified Criteria object.
*/
public Criteria or(String column, double value)
{
or(column, new Double(value));
return this;
}
/**
* Convenience method to add a double to Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new Double(value), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param value A double.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria or(String column, double value, SqlEnum comparison)
{
or(column, new Double(value), comparison);
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new GregorianCalendar(year, month,date), EQUAL);
* </code>
*
* @param column A String value to use as column.
* @param year An int with the year.
* @param month An int with the month.
* @param date An int with the date.
* @return A modified Criteria object.
*/
public Criteria orDate(String column, int year, int month, int date)
{
or(column, new GregorianCalendar(year, month, date));
return this;
}
/**
* Convenience method to add a Date object specified by
* year, month, and date into the Criteria.
* Equal to
*
* <p>
* <code>
* or(column, new GregorianCalendar(year, month,date), comparison);
* </code>
*
* @param column The column to run the comparison on
* @param year An int with the year.
* @param month An int with the month.
* @param date An int with the date.
* @param comparison String describing how to compare the column
* with the value
* @return A modified Criteria object.
*/
public Criteria orDate(String column, int year, int month, int date,
SqlEnum comparison)
{
or(column, new GregorianCalendar(year, month, date), comparison);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as an Object
* array. For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An Object[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria orIn(String column, Object[] values)
{
or(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as an int array.
* For example:
*
* <p>
* FOO.ID IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An int[] with the allowed values.
* @return A modified Criteria object.
*/
public Criteria orIn(String column, int[] values)
{
or(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds an 'IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values A List with the allowed values.
* @return A modified Criteria object.
*/
public Criteria orIn(String column, List values)
{
or(column, (Object) values, Criteria.IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an Object
* array. For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An Object[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria orNotIn(String column, Object[] values)
{
or(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as an int
* array. For example:
*
* <p>
* FOO.ID NOT IN ('2', '3', '7')
* <p>
*
* where 'values' contains those three integers.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values An int[] with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria orNotIn(String column, int[] values)
{
or(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Adds a 'NOT IN' clause with the criteria supplied as a List.
* For example:
*
* <p>
* FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
* <p>
*
* where 'values' contains three objects that evaluate to the
* respective strings above when .toString() is called.
*
* If a criterion for the requested column already exists, it is
* "OR"ed to the existing criterion.
*
* @param column The column to run the comparison on
* @param values A List with the disallowed values.
* @return A modified Criteria object.
*/
public Criteria orNotIn(String column, List values)
{
or(column, (Object) values, Criteria.NOT_IN);
return this;
}
/**
* Peers can set this flag to notify BasePeer that the table(s) involved
* in the Criteria contain Blobs, so that the operation can be placed
* in a transaction if the db requires it.
* This is primarily to support Postgresql.
*
* @deprecated this flag is not used any longer
*/
public void setBlobFlag(boolean b)
{
// do nothing as we don't use the flag any longer
}
/**
* This is an inner class that describes an object in the
* criteria.
*/
public final class Criterion implements Serializable
{
public static final String AND = " AND ";
public static final String OR = " OR ";
/** Value of the CO. */
private Object value;
/** Comparison value. */
private SqlEnum comparison;
/** Table name. */
private String table;
/** Column name. */
private String column;
/** flag to ignore case in comparision */
private boolean ignoreStringCase = false;
/**
* The DB adaptor which might be used to get db specific
* variations of sql.
*/
private DB db;
/**
* other connected criteria and their conjunctions.
*/
private List clauses = new ArrayList();
private List conjunctions = new ArrayList();
/**
* Creates a new instance, initializing a couple members.
*/
private Criterion(Object val, SqlEnum comp)
{
this.value = val;
this.comparison = comp;
}
/**
* Create a new instance.
*
* @param table A String with the name of the table.
* @param column A String with the name of the column.
* @param val An Object with the value for the Criteria.
* @param comp A String with the comparison value.
*/
Criterion(String table, String column, Object val, SqlEnum comp)
{
this(val, comp);
this.table = (table == null ? "" : table);
this.column = (column == null ? "" : column);
}
/**
* Create a new instance.
*
* @param tableColumn A String with the full name of the
* column.
* @param val An Object with the value for the Criteria.
* @param comp A String with the comparison value.
*/
Criterion(String tableColumn, Object val, SqlEnum comp)
{
this(val, comp);
int dot = tableColumn.indexOf('.');
if (dot == -1)
{
table = "";
column = tableColumn;
}
else
{
table = tableColumn.substring(0, dot);
column = tableColumn.substring(dot + 1);
}
}
/**
* Create a new instance.
*
* @param table A String with the name of the table.
* @param column A String with the name of the column.
* @param val An Object with the value for the Criteria.
*/
Criterion(String table, String column, Object val)
{
this(table, column, val, EQUAL);
}
/**
* Create a new instance.
*
* @param tableColumn A String with the full name of the
* column.
* @param val An Object with the value for the Criteria.
*/
Criterion(String tableColumn, Object val)
{
this(tableColumn, val, EQUAL);
}
/**
* Get the column name.
*
* @return A String with the column name.
*/
public String getColumn()
{
return this.column;
}
/**
* Set the table name.
*
* @param name A String with the table name.
*/
public void setTable(String name)
{
this.table = name;
}
/**
* Get the table name.
*
* @return A String with the table name.
*/
public String getTable()
{
return this.table;
}
/**
* Get the comparison.
*
* @return A String with the comparison.
*/
public SqlEnum getComparison()
{
return this.comparison;
}
/**
* Get the value.
*
* @return An Object with the value.
*/
public Object getValue()
{
return this.value;
}
/**
* Get the value of db.
* The DB adaptor which might be used to get db specific
* variations of sql.
* @return value of db.
*/
public DB getDb()
{
DB db = null;
if (this.db == null)
{
// db may not be set if generating preliminary sql for
// debugging.
try
{
db = Torque.getDB(getDbName());
}
catch (Exception e)
{
// we are only doing this to allow easier debugging, so
// no need to throw up the exception, just make note of it.
log.error(
"Could not get a DB adapter, so sql may be wrong");
}
}
else
{
db = this.db;
}
return db;
}
/**
* Set the value of db.
* The DB adaptor might be used to get db specific
* variations of sql.
* @param v Value to assign to db.
*/
public void setDB(DB v)
{
this.db = v;
for (int i = 0; i < this.clauses.size(); i++)
{
((Criterion) (clauses.get(i))).setDB(v);
}
}
/**
* Sets ignore case.
*
* @param b True if case should be ignored.
* @return A modified Criteria object.
*/
public Criterion setIgnoreCase(boolean b)
{
ignoreStringCase = b;
return this;
}
/**
* Is ignore case on or off?
*
* @return True if case is ignored.
*/
public boolean isIgnoreCase()
{
return ignoreStringCase;
}
/**
* get the list of clauses in this Criterion
*/
private List getClauses()
{
return clauses;
}
/**
* get the list of conjunctions in this Criterion
*/
private List getConjunctions()
{
return conjunctions;
}
/**
* Append an AND Criterion onto this Criterion's list.
*/
public Criterion and(Criterion criterion)
{
this.clauses.add(criterion);
this.conjunctions.add(AND);
return this;
}
/**
* Append an OR Criterion onto this Criterion's list.
*/
public Criterion or(Criterion criterion)
{
this.clauses.add(criterion);
this.conjunctions.add(OR);
return this;
}
/**
* Appends a representation of the Criterion onto the buffer.
*/
public void appendTo(StringBuffer sb)
{
//
// it is alright if value == null
//
if (column == null)
{
return;
}
Criterion clause = null;
for (int j = 0; j < this.clauses.size(); j++)
{
sb.append('(');
}
if (CUSTOM == comparison)
{
if (value != null && !"".equals(value))
{
sb.append((String) value);
}
}
else
{
String field = null;
if (table == null)
{
field = column;
}
else
{
field = new StringBuffer(
table.length() + 1 + column.length())
.append(table).append('.').append(column)
.toString();
}
SqlExpression.build(field, value, comparison,
ignoreStringCase, getDb(), sb);
}
for (int i = 0; i < this.clauses.size(); i++)
{
sb.append(this.conjunctions.get(i));
clause = (Criterion) (this.clauses.get(i));
clause.appendTo(sb);
sb.append(')');
}
}
/**
* Appends a Prepared Statement representation of the Criterion
* onto the buffer.
*
* @param sb The stringbuffer that will receive the Prepared Statement
* @param params A list to which Prepared Statement parameters
* will be appended
*/
public void appendPsTo(StringBuffer sb, List params)
{
if (column == null || value == null)
{
return;
}
DB db = getDb();
for (int j = 0; j < this.clauses.size(); j++)
{
sb.append('(');
}
if (CUSTOM == comparison)
{
if (!"".equals(value))
{
sb.append((String) value);
}
}
else
{
String field = null;
if (table == null)
{
field = column;
}
else
{
field = new StringBuffer(
table.length() + 1 + column.length())
.append(table).append('.').append(column)
.toString();
}
if (comparison.equals(Criteria.IN)
|| comparison.equals(Criteria.NOT_IN))
{
sb.append(field)
.append(comparison);
UniqueList inClause = new UniqueList();
if (value instanceof List)
{
value = ((List) value).toArray (new Object[0]);
}
for (int i = 0; i < Array.getLength(value); i++)
{
Object item = Array.get(value, i);
inClause.add(SqlExpression.processInValue(item,
ignoreCase,
db));
}
StringBuffer inString = new StringBuffer();
inString.append('(').append(StringUtils.join(
inClause.iterator(), (","))).append(')');
sb.append(inString.toString());
}
else
{
if (ignoreCase)
{
sb.append(db.ignoreCase(field))
.append(comparison)
.append(db.ignoreCase("?"));
}
else
{
sb.append(field)
.append(comparison)
.append(" ? ");
}
if (value instanceof java.util.Date)
{
params.add(new java.sql.Date(
((java.util.Date) value).getTime()));
}
else if (value instanceof DateKey)
{
params.add(new java.sql.Date(
((DateKey) value).getDate().getTime()));
}
else
{
params.add(value.toString());
}
}
}
for (int i = 0; i < this.clauses.size(); i++)
{
sb.append(this.conjunctions.get(i));
Criterion clause = (Criterion) (this.clauses.get(i));
clause.appendPsTo(sb, params);
sb.append(')');
}
}
/**
* Build a string representation of the Criterion.
*
* @return A String with the representation of the Criterion.
*/
public String toString()
{
//
// it is alright if value == null
//
if (column == null)
{
return "";
}
StringBuffer expr = new StringBuffer(25);
appendTo(expr);
return expr.toString();
}
/**
* This method checks another Criteria to see if they contain
* the same attributes and hashtable entries.
*/
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if ((obj == null) || !(obj instanceof Criterion))
{
return false;
}
Criterion crit = (Criterion) obj;
boolean isEquiv = ((table == null && crit.getTable() == null)
|| (table != null && table.equals(crit.getTable()))
)
&& column.equals(crit.getColumn())
&& comparison.equals(crit.getComparison());
// we need to check for value equality
if (isEquiv)
{
Object b = crit.getValue();
if (value instanceof Object[] && b instanceof Object[])
{
isEquiv &= Arrays.equals((Object[]) value, (Object[]) b);
}
else if (value instanceof int[] && b instanceof int[])
{
isEquiv &= Arrays.equals((int[]) value, (int[]) b);
}
else
{
isEquiv &= value.equals(b);
}
}
// check chained criterion
isEquiv &= this.clauses.size() == crit.getClauses().size();
for (int i = 0; i < this.clauses.size(); i++)
{
isEquiv &= ((String) (conjunctions.get(i)))
.equals((String) (crit.getConjunctions().get(i)));
isEquiv &= ((Criterion) (clauses.get(i)))
.equals((Criterion) (crit.getClauses().get(i)));
}
return isEquiv;
}
/**
* Returns a hash code value for the object.
*/
public int hashCode()
{
int h = value.hashCode() ^ comparison.hashCode();
if (table != null)
{
h ^= table.hashCode();
}
if (column != null)
{
h ^= column.hashCode();
}
for (int i = 0; i < this.clauses.size(); i++)
{
h ^= ((Criterion) (clauses.get(i))).hashCode();
}
return h;
}
/**
* get all tables from nested criterion objects
*
* @return the list of tables
*/
public List getAllTables()
{
UniqueList tables = new UniqueList();
addCriterionTable(this, tables);
return tables;
}
/**
* method supporting recursion through all criterions to give
* us a StringStack of tables from each criterion
*/
private void addCriterionTable(Criterion c, UniqueList s)
{
if (c != null)
{
s.add(c.getTable());
for (int i = 0; i < c.getClauses().size(); i++)
{
addCriterionTable((Criterion) (c.getClauses().get(i)), s);
}
}
}
/**
* get an array of all criterion attached to this
* recursing through all sub criterion
*/
public Criterion[] getAttachedCriterion()
{
ArrayList crits = new ArrayList();
traverseCriterion(this, crits);
Criterion[] crita = new Criterion[crits.size()];
for (int i = 0; i < crits.size(); i++)
{
crita[i] = (Criterion) crits.get(i);
}
return crita;
}
/**
* method supporting recursion through all criterions to give
* us an ArrayList of them
*/
private void traverseCriterion(Criterion c, ArrayList a)
{
if (c != null)
{
a.add(c);
for (int i = 0; i < c.getClauses().size(); i++)
{
traverseCriterion((Criterion) (c.getClauses().get(i)), a);
}
}
}
}
}