/******************************************************************************* | |
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
* 05/24/2011-2.3 Guy Pelletier | |
* - 345962: Join fetch query when using tenant discriminator column fails. | |
******************************************************************************/ | |
package org.eclipse.persistence.expressions; | |
import java.util.*; | |
import java.io.*; | |
import org.eclipse.persistence.mappings.DatabaseMapping; | |
import org.eclipse.persistence.queries.*; | |
import org.eclipse.persistence.descriptors.ClassDescriptor; | |
import org.eclipse.persistence.exceptions.*; | |
import org.eclipse.persistence.history.*; | |
import org.eclipse.persistence.internal.helper.*; | |
import org.eclipse.persistence.internal.expressions.*; | |
import org.eclipse.persistence.internal.localization.*; | |
import org.eclipse.persistence.internal.sessions.AbstractRecord; | |
import org.eclipse.persistence.internal.sessions.AbstractSession; | |
/** | |
* <p> | |
* <b>Purpose</b>: Define an object-level representation of a database query where clause.</p> | |
* <p> | |
* <b>Description</b>: An expression is a tree-like structure that defines the selection | |
* criteria for a query against objects in the database. The expression has the advantage | |
* over SQL by being at the object-level, i.e. the object model attributes and relationships | |
* can be used to be query on instead of the database field names. | |
* Because it is an object, not a string the expression has the advantage that is can be | |
* easily manipulated through code to easily build complex selection criterias.</p> | |
* <p> | |
* <b>Responsibilities</b>: | |
* <ul> | |
* <li> Store the selection criteria in a tree-like structure. | |
* <li> Support public manipulation protocols for all comparison and function operators. | |
* <li> Use operator overloading to support all primitive types as well as objects. | |
* </ul></p> | |
*/ | |
public abstract class Expression implements Serializable, Cloneable { | |
/** Required for serialization compatibility. */ | |
static final long serialVersionUID = -5979150600092006081L; | |
/** Temporary values for table aliasing */ | |
protected transient DatabaseTable lastTable; | |
protected transient DatabaseTable currentAlias; | |
protected boolean selectIfOrderedBy = true; | |
/** PERF: Cache the hashCode. */ | |
protected int hashCode = 0; | |
/** Use the upper() function for case insensitive expression operations (default). | |
Seting this flag to false will use the lower() function instead. */ | |
public static boolean shouldUseUpperCaseForIgnoreCase = true; | |
/** | |
* Base Expression Constructor. Not generally used by Developers | |
*/ | |
public Expression() { | |
super(); | |
} | |
/** | |
* PUBLIC: | |
* Function, return an expression that adds to a date based on | |
* the specified datePart. This is equivalent to the Sybase DATEADD function. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").addDate("year", 2) | |
* Java: NA | |
* SQL: DATEADD(date, 2, year) | |
* </blockquote></pre> | |
*/ | |
public Expression addDate(String datePart, int numberToAdd) { | |
return addDate(datePart, Integer.valueOf(numberToAdd)); | |
} | |
/** | |
* PUBLIC: | |
* Function, return an expression that adds to a date based on | |
* the specified datePart. This is equivalent to the Sybase DATEADD function. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").addDate("year", 2) | |
* Java: NA | |
* SQL: DATEADD(date, 2, year) | |
* </blockquote></pre> | |
*/ | |
public Expression addDate(String datePart, Object numberToAdd) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.AddDate); | |
List args = new ArrayList(2); | |
args.add(Expression.fromLiteral(datePart, this)); | |
args.add(numberToAdd); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, to add months to a date. | |
*/ | |
public Expression addMonths(int months) { | |
return addMonths(Integer.valueOf(months)); | |
} | |
/** | |
* PUBLIC: | |
* Function, to add months to a date. | |
*/ | |
public Expression addMonths(Object months) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.AddMonths); | |
return anOperator.expressionFor(this, months); | |
} | |
/** | |
* INTERNAL: | |
* Find the alias for a given table | |
*/ | |
public DatabaseTable aliasForTable(DatabaseTable table) { | |
return null; | |
} | |
/** | |
* PUBLIC: Returns an expression equivalent to all of <code>attributeName</code> | |
* holding true for <code>criteria</code>. | |
* <p> | |
* For every expression with an anyOf, its negation has either an allOf or a | |
* noneOf. The following two examples will illustrate as the second is the | |
* negation of the first: | |
* <p> | |
* AnyOf Example: Employees with a non '613' area code phone number. | |
* <blockquote><pre> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class); | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* Expression exp = employee.anyOf("phoneNumbers").get("areaCode").notEqual("613"); | |
* </blockquote></pre> | |
* <p> | |
* AllOf Example: Employees with all '613' area code phone numbers. | |
* <blockquote><pre> | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* ExpressionBuilder phones = new ExpressionBuilder(); | |
* Expression exp = employee.allOf("phoneNumbers", phones.get("areaCode").equal("613")); | |
* SQL: | |
* SELECT ... EMPLOYEE t0 WHERE NOT EXISTS (SELECT ... PHONE t1 WHERE | |
* (t0.EMP_ID = t1.EMP_ID) AND NOT (t1.AREACODE = '613')) | |
* </blockquote></pre> | |
* <p> | |
* allOf is the universal counterpart to the existential anyOf. To have the | |
* condition evaluated for each instance it must be put inside of a subquery, | |
* which can be expressed as not exists (any of attributeName some condition). | |
* (All x such that y = !Exist x such that !y). | |
* <p>Likewise the syntax employee.allOf("phoneNumbers").get("areaCode").equal("613") | |
* is not supported for the <pre>equal</pre> must go inside a subQuery. | |
* <p> | |
* This method saves you from writing the sub query yourself. The above is | |
* equivalent to the following expression: | |
* <blockquote><pre> | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* ExpressionBuilder phone = new ExpressionBuilder(); | |
* ReportQuery subQuery = new ReportQuery(Phone.class, phone); | |
* subQuery.retreivePrimaryKeys(); | |
* subQuery.setSelectionCriteria(phone.equal(employee.anyOf("phoneNumbers").and( | |
* phone.get("areaCode").notEqual("613"))); | |
* Expression exp = employee.notExists(subQuery); | |
* </blockquote></pre> | |
* <p> | |
* Note if employee has no phone numbers allOf ~ noneOf. | |
* @param criteria must have its own builder, as it will become the | |
* separate selection criteria of a subQuery. | |
* @return a notExists subQuery expression | |
*/ | |
public Expression allOf(String attributeName, Expression criteria) { | |
ReportQuery subQuery = new ReportQuery(); | |
subQuery.setShouldRetrieveFirstPrimaryKey(true); | |
Expression builder = criteria.getBuilder(); | |
criteria = builder.equal(anyOf(attributeName)).and(criteria.not()); | |
subQuery.setSelectionCriteria(criteria); | |
return notExists(subQuery); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that is the boolean logical combination of both expressions. | |
* This is equivalent to the SQL "AND" operator and the Java "&&" operator. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("firstName").equal("Bob").and(employee.get("lastName").equal("Smith")) | |
* Java: (employee.getFirstName().equals("Bob")) && (employee.getLastName().equals("Smith")) | |
* SQL: F_NAME = 'Bob' AND L_NAME = 'Smith' | |
* </blockquote></pre> | |
*/ | |
public Expression and(Expression theExpression) { | |
// Allow ands with null. | |
if (theExpression == null) { | |
return this; | |
} | |
ExpressionBuilder base = getBuilder(); | |
Expression expressionToUse = theExpression; | |
// Ensure the same builder, unless a parralel query is used. | |
// For flashback added an extra condition: if left side is a 'NullExpression' | |
// then rebuild on it regardless. | |
if ((theExpression.getBuilder() != base) && ((base == this) || (theExpression.getBuilder().getQueryClass() == null))) { | |
expressionToUse = theExpression.rebuildOn(base); | |
} | |
if (base == this) {// Allow and to be sent to the builder. | |
return expressionToUse; | |
} | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.And); | |
return anOperator.expressionFor(this, expressionToUse); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression representing traversal of a 1:many or many:many relationship. | |
* This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria. | |
* <p>Example: | |
* <p> | |
* <table border=0 summary="This table compares an example EclipseLink anyOf Expression to Java and SQL"> | |
* <tr> | |
* <th id="c1">Format</th> | |
* <th id="c2">Equivalent</th> | |
* </tr> | |
* <tr> | |
* <td headers="c1">EclipseLink</td> | |
* <td headers="c2"> | |
* <pre> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class);</br> | |
* ExpressionBuilder builder = new ExpressionBuilder();</br> | |
* Expression exp = builder.get("id").equal("14858");</br> | |
* exp = exp.or(builder.anyOf("managedEmployees").get("firstName").equal("Bob"));</br> | |
* </pre> | |
* </td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">Java</td> | |
* <td headers="c2">No direct equivalent</td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">SQL</td> | |
* <td headers="c2">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> | |
* </tr> | |
* </table> | |
*/ | |
public Expression anyOf(String attributeName) { | |
return anyOf(attributeName, true); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing traversal of a 1:many or many:many relationship. | |
* This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria. | |
* <p>Example: | |
* <p> | |
* <table border=0 summary="This table compares an example EclipseLink anyOf Expression to Java and SQL"> | |
* <tr> | |
* <th id="c1">Format</th> | |
* <th id="c2">Equivalent</th> | |
* </tr> | |
* <tr> | |
* <td headers="c1">EclipseLink</td> | |
* <td headers="c2"> | |
* <pre> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class);</br> | |
* ExpressionBuilder builder = new ExpressionBuilder();</br> | |
* Expression exp = builder.get("id").equal("14858");</br> | |
* exp = exp.or(builder.anyOf("managedEmployees").get("firstName").equal("Bob"));</br> | |
* </pre> | |
* </td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">Java</td> | |
* <td headers="c2">No direct equivalent</td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">SQL</td> | |
* <td headers="c2">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> | |
* </tr> | |
* </table> | |
* @parameter shouldJoinBeIndependent indicates whether a new expression should be created. | |
*/ | |
public Expression anyOf(String attributeName, boolean shouldJoinBeIndependent) { | |
throw new UnsupportedOperationException("anyOf"); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing traversal of a 1:many or many:many relationship. | |
* This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria. | |
* This version of the anyOf operation performs an outer join. | |
* Outer joins allow the join to performed even if the target of the relationship is empty. | |
* NOTE: outer joins are not supported on all database and have differing semantics. | |
* <p>Example: | |
* <p> | |
* <table border=0 summary="This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL"> | |
* <tr> | |
* <th id="c1">Format</th> | |
* <th id="c2">Equivalent</th> | |
* </tr> | |
* <tr> | |
* <td headers="c1">EclipseLink</td> | |
* <td headers="c2"> | |
* <pre> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class);</br> | |
* ExpressionBuilder builder = new ExpressionBuilder();</br> | |
* Expression exp = builder.get("id").equal("14858");</br> | |
* exp = exp.or(builder.anyOfAllowingNone("managedEmployees").get("firstName").equal("Bob"));</br> | |
* </pre> | |
* </td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">Java</td> | |
* <td headers="c2">No direct equivalent</td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">SQL</td> | |
* <td headers="c2">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> | |
* </tr> | |
* </table> | |
*/ | |
public Expression anyOfAllowingNone(String attributeName) { | |
return anyOfAllowingNone(attributeName, true); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing traversal of a 1:many or many:many relationship. | |
* This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria. | |
* This version of the anyOf operation performs an outer join. | |
* Outer joins allow the join to performed even if the target of the relationship is empty. | |
* NOTE: outer joins are not supported on all database and have differing semantics. | |
* <p>Example: | |
* <p> | |
* <table border=0 summary="This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL"> | |
* <tr> | |
* <th id="c1">Format</th> | |
* <th id="c2">Equivalent</th> | |
* </tr> | |
* <tr> | |
* <td headers="c1">EclipseLink</td> | |
* <td headers="c2"> | |
* <pre> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class);</br> | |
* ExpressionBuilder builder = new ExpressionBuilder();</br> | |
* Expression exp = builder.get("id").equal("14858");</br> | |
* exp = exp.or(builder.anyOfAllowingNone("managedEmployees").get("firstName").equal("Bob"));</br> | |
* </pre> | |
* </td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">Java</td> | |
* <td headers="c2">No direct equivalent</td> | |
* </tr> | |
* <tr> | |
* <td headers="c1">SQL</td> | |
* <td headers="c2">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> | |
* </tr> | |
* </table> | |
* @parameter shouldJoinBeIndependent indicates whether a new expression should be created. | |
*/ | |
public Expression anyOfAllowingNone(String attributeName, boolean shouldJoinBeIndependent) { | |
throw new UnsupportedOperationException("anyOfAllowingNone"); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression that allows you to treat its base as if it were a subclass of the class returned by the base. | |
* @deprecated replaced by {@link #treat(Class)} | |
*/ | |
@Deprecated | |
public Expression as(Class castClass) { | |
return treat(castClass); | |
} | |
/** | |
* ADVANCED: | |
* Assign an alias to the expression in the select clause. | |
*/ | |
public Expression as(String alias) { | |
ExpressionOperator operator = getOperator(ExpressionOperator.As); | |
return operator.expressionFor(this, literal(alias)); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression that allows you to treat its base as if it were a subclass of the class returned by the base | |
* This can only be called on an ExpressionBuilder, the result of expression.get(String), expression.getAllowingNull(String), | |
* the result of expression.anyOf("String") or the result of expression.anyOfAllowingNull("String") | |
* | |
* downcast uses Expression.type() internally to guarantee the results are of the specified class. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("project").treat(LargeProject.class).get("budget").equal(1000) | |
* Java: ((LargeProject)employee.getProjects().get(0)).getBudget() == 1000 | |
* SQL: LPROJ.PROJ_ID (+)= PROJ.PROJ_ID AND L_PROJ.BUDGET = 1000 AND PROJ.TYPE = "L" | |
* </blockquote></pre> | |
*/ | |
public Expression treat(Class castClass) { | |
return this; | |
} | |
/** | |
* PUBLIC: | |
* This can only be used within an ordering expression. | |
* It will order the result ascending. | |
* Example: | |
* <blockquote><pre> | |
* readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending()) | |
* </blockquote></pre> | |
*/ | |
public Expression ascending() { | |
return getFunction(ExpressionOperator.Ascending); | |
} | |
/** | |
* PUBLIC: | |
* This can only be used within an ordering expression. | |
* Null results will be ordered first. | |
* Example: | |
* <blockquote><pre> | |
* readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending().nullsFirst()) | |
* </blockquote></pre> | |
*/ | |
public Expression nullsFirst() { | |
return getFunction(ExpressionOperator.NullsFirst); | |
} | |
/** | |
* PUBLIC: | |
* This can only be used within an ordering expression. | |
* Null results will be ordered last. | |
* Example: | |
* <blockquote><pre> | |
* readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending().nullsLast()) | |
* </blockquote></pre> | |
*/ | |
public Expression nullsLast() { | |
return getFunction(ExpressionOperator.NullsLast); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the single character strings ascii value. | |
*/ | |
public Expression asciiValue() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Ascii); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* Sets all tables represented by this expression to be queried as of a past | |
* time. | |
* <p> | |
* Example: | |
* <p> | |
* <pre> | |
* EclipseLink: employee.asOf(new AsOfClause(pastTime)) | |
* Java: None | |
* SQL (Flashback): SELECT ... FROM EMPLOYEE AS OF TIMESTAMP (pastTime) t0 ... | |
* SQL (Generic): .. WHERE (t1.START <= pastTime) AND ((t1.END IS NULL) OR t1.END > pastTime) | |
* </pre> | |
* <p> | |
* Set an as of clause at the expression level to still query for current objects | |
* while expressing selection criteria like: | |
* <ul> | |
* <li>query objects as of one time that met some condition at another time. | |
* <li>query objects that changed a certain way over a certain interval (querying for change). | |
* </ul> | |
* <p> | |
* Simultaneously querying on two versions of the same object (one past | |
* one present) lets you express these advanced selection criteria. | |
* <p> | |
* Example: Querying on past attributes using parallel expressions. | |
* <p> | |
* <blockquote><pre> | |
* // Finds all employees who lived in Ottawa as of a past time. | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* ExpressionBuilder pastEmployee = new ExpressionBuilder(Employee.class); | |
* pastEmployee.asOf(pastTime); | |
* Expression pastAddress = pastEmployee.get("address"); // by default address will also be as of past time. | |
* Expression selectionCriteria = pastAddress.get("city").equal("Ottawa").and( | |
* employee.equal(pastEmployee)); | |
* </blockquote></pre> | |
* <p> | |
* The advantage of the parallel expression is that you can still read current | |
* objects, the as of clause will affect only the where clause / selection criteria. | |
* <p> | |
* You may be tempted to rewrite the above as employee.get("address").asOf(pastTime). | |
* That is allowed but see below for the finer points involved in this. | |
* <p> | |
* Example: Querying on object changes using parallel expressions. | |
* <p> | |
* <blockquote><pre> | |
* // Finds all employees who recently received a raise. Note that current | |
* // objects are returned, so can be cached normally. | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* Expression pastEmployee = new ExpressionBuilder(Employee.class); | |
* pastEmployee.asOf(yesterday); | |
* Expression parallelJoin = employee.equal(pastEmployee); | |
* Expression selectionCriteria = parallelJoin.and( | |
* employee.get("salary").greaterThan(pastEmployee.get("salary"))); | |
* </blockquote></pre> | |
* <p> | |
* Example: Querying on object changes using custom query keys | |
* <p><blockquote><pre> | |
* // First define the custom query key and add it to your descriptor. | |
* ExpressionBuilder builder = new ExpressionBuilder(Employee.class); | |
* Expression joinCriteria = builder.getField("EMPLOYEE.EMP_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID")); | |
* OneToOneQueryKey selfReferential = new OneToOneQueryKey(); | |
* selfReferential.setName("this"); | |
* selfReferential.setJoinCriteria(joinCriteria); | |
* selfReferential.setReferenceClass(Employee.class); | |
* getSession().getDescriptor(Employee.class).addQueryKey(selfReferential); | |
* | |
* // Now build query as before. | |
* Expression employee = new ExpessionBuilder(); | |
* Expression pastEmployee = employee.get("this").asOf(yesterday); | |
* Expression selectionCriteria = employee.get("salary").greaterThan(pastEmployee.get("salary")); | |
* </blockquote></pre> | |
* <p> | |
* Note in general that any parallel expression can be rewritten using a custom query key. | |
* EclipseLink will even automatically interpret x.get("this") for you so you do | |
* not need to define the above query key first. | |
* <p> | |
* <b>Full Reference:</b> | |
* <p> | |
* If an object is mapped to multiple tables, then each table will be as of | |
* the same time. Two objects mapped to the same table can not have different | |
* as of times. Conversely only expressions which have associated tables can have an as | |
* of clause. | |
* <p> | |
* If an as of clause is not explicitly set an expression will use the clause | |
* of its base expression, and so on recursively until one is found or an | |
* ExpressionBuilder is reached. Some usage scenarios follow: | |
* <ul> | |
* <li>employee.asOf(pastTime).anyOf("projects"): projects as of past time. | |
* <li>expressionBuilder.asOf(pastTime): entire expression as of past time. | |
* <li>employee.asOf(pastTime).anyOf("projects").asOf(null): projects as of current time. | |
* <li>employee.anyOf("projects").asOf(pastTime): projects only as of past time. | |
* </ul> | |
* <p> | |
* Watch out for x.asOf(oneTime).get("y").asOf(anotherTime). | |
* <ul> | |
* <li>emp.anyOf("phoneNumbers").asOf(yesterday) = emp.asOf(yesterday).anyOf("phoneNumbers") but: | |
* <li>emp.get("address").asOf(yesterday) != emp.asOf(yesterday).get("address"). | |
* </ul> | |
* Whether the join is also as of yesterday depends on which table the foreign | |
* key field resides on. In an anyOf the foreign key is always on the right, but | |
* in a get (1-1) it could be on either side. For this | |
* reason employee.get("address").asOf(yesterday) is undefined as it can mean | |
* either 'my address as of yesterday', or 'my address, as of yesterday.' | |
* @param pastTime A read only data object used to represent a past time. | |
* @return <code>this</code> | |
* @since OracleAS EclipseLink 10<i>g</i> (10.0.3) | |
* @see org.eclipse.persistence.history.AsOfClause | |
* @see #hasAsOfClause | |
* @see org.eclipse.persistence.sessions.Session#acquireHistoricalSession(org.eclipse.persistence.history.AsOfClause) | |
* @see org.eclipse.persistence.queries.ObjectLevelReadQuery#setAsOfClause(org.eclipse.persistence.history.AsOfClause)) | |
*/ | |
public Expression asOf(AsOfClause pastTime) { | |
throw new UnsupportedOperationException("anyOfAllowingNone"); | |
} | |
/** | |
* INTERNAL: | |
* Alias a particular table within this node | |
*/ | |
protected void assignAlias(String name, DatabaseTable tableOrExpression) { | |
// By default, do nothing. | |
} | |
/** | |
* INTERNAL: | |
* Assign aliases to any tables which I own. Start with t(initialValue), | |
* and return the new value of the counter , i.e. if initialValue is one | |
* and I have tables ADDRESS and EMPLOYEE I will assign them t1 and t2 respectively, and return 3. | |
*/ | |
public int assignTableAliasesStartingAt(int initialValue) { | |
if (hasBeenAliased()) { | |
return initialValue; | |
} | |
int counter = initialValue; | |
List<DatabaseTable> ownedTables = getOwnedTables(); | |
if (ownedTables != null) { | |
for (DatabaseTable table : ownedTables) { | |
assignAlias("t" + counter, table); | |
counter++; | |
} | |
} | |
return counter; | |
} | |
/** | |
* PUBLIC: | |
* Function, This represents the aggregate function Average. Can be used only within Report Queries. | |
*/ | |
public Expression average() { | |
return getFunction(ExpressionOperator.Average); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two bytes | |
*/ | |
public Expression between(byte leftValue, byte rightValue) { | |
return between(Byte.valueOf(leftValue), Byte.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two chars | |
*/ | |
public Expression between(char leftChar, char rightChar) { | |
return between(Character.valueOf(leftChar), Character.valueOf(rightChar)); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two doubles | |
*/ | |
public Expression between(double leftValue, double rightValue) { | |
return between(Double.valueOf(leftValue), Double.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two floats | |
*/ | |
public Expression between(float leftValue, float rightValue) { | |
return between(Float.valueOf(leftValue), Float.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two ints | |
*/ | |
public Expression between(int leftValue, int rightValue) { | |
return between(Integer.valueOf(leftValue), Integer.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two longs | |
*/ | |
public Expression between(long leftValue, long rightValue) { | |
return between(Long.valueOf(leftValue), Long.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receiver's value is between two other values. | |
* This means the receiver's value is greater than or equal to the leftValue argument and less than or equal to the | |
* rightValue argument. | |
* <p> | |
* This is equivalent to the SQL "BETWEEN AND" operator and Java ">=", "<=;" operators. | |
* <p>Example: | |
* <pre> | |
* EclipseLink: employee.get("age").between(19,50) | |
* Java: (employee.getAge() >= 19) && (employee.getAge() <= 50) | |
* SQL: AGE BETWEEN 19 AND 50 | |
* </pre> | |
*/ | |
public Expression between(Object leftValue, Object rightValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Between); | |
List args = new ArrayList(2); | |
args.add(leftValue); | |
args.add(rightValue); | |
return anOperator.expressionForArguments(this, args); | |
} | |
public Expression between(Expression leftExpression, Expression rightExpression) { | |
return between((Object)leftExpression, (Object)rightExpression); | |
} | |
/** | |
* PUBLIC: | |
* Function, between two shorts | |
*/ | |
public Expression between(short leftValue, short rightValue) { | |
return between(Short.valueOf(leftValue), Short.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Function Convert values returned by the query to values | |
* given in the caseItems Map. The equivalent of | |
* the Oracle CASE function | |
* <p>Example: | |
* <blockquote><pre> | |
* Map caseTable = new HashMap(); | |
* caseTable.put("Robert", "Bob"); | |
* caseTable.put("Susan", "Sue"); | |
* | |
* EclipseLink: employee.get("name").caseStatement(caseTable, "No-Nickname") | |
* Java: NA | |
* SQL: CASE name WHEN "Robert" THEN "Bob" | |
* WHEN "Susan" THEN "Sue" | |
* ELSE "No-Nickname" | |
* </blockquote></pre> | |
* @param caseItems java.util.Map | |
* A Map containing the items to be processed. | |
* Keys represent the items to match coming from the query. | |
* Values represent what a key will be changed to. | |
* @param defaultItem java.lang.String the default value that will be used if none of the keys in the | |
* hashtable match | |
*/ | |
public Expression caseStatement(Map caseItems, Object defaultItem) { | |
FunctionExpression expression = caseStatement(); | |
expression.addChild(this); | |
Iterator iterator = caseItems.keySet().iterator(); | |
while (iterator.hasNext()) { | |
Object key = iterator.next(); | |
expression.addChild(Expression.from(key, this)); | |
expression.addChild(Expression.from(caseItems.get(key), this)); | |
} | |
expression.addChild(Expression.from(defaultItem, this)); | |
return expression; | |
} | |
/** | |
* INTERNAL: | |
* Creates an ArgumentListFunctionExpression that is capable of creating a case statement of the form: | |
* <pre><blockquote> | |
* SQL: CASE name WHEN "Robert" THEN "Bob" | |
* WHEN "Susan" THEN "Sue" | |
* ELSE "No-Nickname" | |
* </blockquote></pre> | |
* | |
* This expression must be manipulated to successfully build a case statement by adding appropriate | |
* children to it. | |
* | |
* A child must be added for the "case expression" (name above), a pair of children must be added for | |
* each "when then" expression and a child must be added for the else. | |
* | |
* @see ArgumentListFunctionExpression | |
*/ | |
public ArgumentListFunctionExpression caseStatement() { | |
ListExpressionOperator caseOperator = (ListExpressionOperator)getOperator(ExpressionOperator.Case); | |
ListExpressionOperator clonedCaseOperator = new ListExpressionOperator(); | |
caseOperator.copyTo(clonedCaseOperator); | |
ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.setOperator(clonedCaseOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Function Convert values returned by the query to values | |
* given in the caseConditions Map. The equivalent of | |
* the SQL CASE function | |
* <p>Example: | |
* <blockquote><pre> | |
* Map caseTable = new HashMap(); | |
* caseTable.put(employee.get("name").equals("Robert"), "Bob"); | |
* caseTable.put(employee.get("name").equals("Susan"), "Sue"); | |
* | |
* EclipseLink: expressionBuilder.caseConditionStatement(caseTable, "No-Nickname") | |
* Java: NA | |
* SQL: CASE WHEN name = "Robert" THEN "Bob" | |
* WHEN name = "Susan" THEN "Sue" | |
* ELSE "No-Nickname" | |
* </blockquote></pre> | |
* @param caseItems java.util.Map | |
* A Map containing the items to be processed. | |
* Keys represent the items to match coming from the query. | |
* Values represent what a key will be changed to. | |
* @param defaultItem java.lang.Object the default value that will be used if none of the keys in the | |
* Map match | |
*/ | |
public Expression caseConditionStatement(Map<Expression, Object> caseConditions, Object defaultItem) { | |
FunctionExpression expression = caseConditionStatement(); | |
Iterator<Expression> iterator = caseConditions.keySet().iterator(); | |
if (iterator.hasNext()){ | |
Expression key = iterator.next(); | |
expression.addChild(key); | |
expression.setBaseExpression(key);//base needs to be the same as the first child for reportQuery items. | |
expression.addChild(Expression.from(caseConditions.get(key), this)); | |
while (iterator.hasNext()) { | |
key = iterator.next(); | |
expression.addChild(key); | |
expression.addChild(Expression.from(caseConditions.get(key), this)); | |
} | |
} | |
expression.addChild(Expression.from(defaultItem, this)); | |
return expression; | |
} | |
/** | |
* INTERNAL: | |
* Creates an ArgumentListFunctionExpression that is capable of creating a case statement of the form: | |
* <pre><blockquote> | |
* SQL: CASE WHEN name = "Robert" THEN "Bob" | |
* WHEN name = "Susan" THEN "Sue" | |
* ELSE "No-Nickname" | |
* </blockquote></pre> | |
* | |
* This expression must be manipulated to successfully build a case statement by adding appropriate | |
* children to it. | |
* | |
* A pair of children must be added for each "when then" expression and a child must be added for the else. | |
* | |
* @see ArgumentListFunctionExpression | |
*/ | |
public ArgumentListFunctionExpression caseConditionStatement() { | |
ListExpressionOperator caseOperator = (ListExpressionOperator)getOperator(ExpressionOperator.CaseCondition); | |
ListExpressionOperator clonedCaseOperator = new ListExpressionOperator(); | |
caseOperator.copyTo(clonedCaseOperator); | |
ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.setOperator(clonedCaseOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Function Test if arguments are equal, returning null if they are and the value of the | |
* first expression otherwise. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: builder.get("name").nullIf( "Bobby") | |
* Java: NA | |
* SQL: NULLIF(name, "Bobby") | |
* </blockquote></pre> | |
* @param defaultItem java.lang.Object the value/expression that will be compared to the base expression | |
*/ | |
public Expression nullIf(Object object) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NullIf); | |
List args = new ArrayList(1); | |
args.add(Expression.from(object, this)); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function Return null if all arguments are null and the first non-null argument otherwise | |
* The equivalent of the COALESCE SQL function | |
* <p>Example: | |
* <blockquote><pre> | |
* List list = new ArrayList(3); | |
* list.add(builder.get("firstName")); | |
* list.add(builder.get("lastName")); | |
* list.add(builder.get("nickname")); | |
* | |
* EclipseLink: expressionBuilder.coalesce(caseTable) | |
* Java: NA | |
* SQL: COALESCE(firstname, lastname, nickname) | |
* </blockquote></pre> | |
* @param caseItems java.util.Collection | |
* A Collection containing the items to check if null | |
*/ | |
public ArgumentListFunctionExpression coalesce(Collection expressions) { | |
ArgumentListFunctionExpression expression = coalesce(); | |
Iterator iterator = expressions.iterator(); | |
if (iterator.hasNext()){ | |
Expression base = Expression.from(iterator.next(), this); | |
expression.addChild(base); | |
expression.setBaseExpression(base);//base needs to be the same as the first child for reportQuery items. | |
while (iterator.hasNext()) { | |
expression.addChild(Expression.from(iterator.next(), this)); | |
} | |
} | |
return expression; | |
} | |
public ArgumentListFunctionExpression coalesce() { | |
ListExpressionOperator coalesceOperator = (ListExpressionOperator)getOperator(ExpressionOperator.Coalesce); | |
ListExpressionOperator clonedCoalesceOperator = new ListExpressionOperator(); | |
coalesceOperator.copyTo(clonedCoalesceOperator); | |
ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.setOperator(clonedCoalesceOperator); | |
return expression; | |
} | |
/** | |
* INTERNAL: | |
* Clone the expression maintaining clone identity in the inter-connected expression graph. | |
*/ | |
public Object clone() { | |
// 2612538 - the default size of Map (32) is appropriate | |
Map alreadyDone = new IdentityHashMap(); | |
return copiedVersionFrom(alreadyDone); | |
} | |
/** | |
* INTERNAL: | |
* This expression is built on a different base than the one we want. Rebuild it and | |
* return the root of the new tree. | |
* This method will rebuildOn the receiver even it is a parallel select or a | |
* sub select: it will not replace every base with newBase. | |
* Also it will rebuild using anyOf as appropriate not get. | |
* @see org.eclipse.persistence.mappings.ForeignReferenceMapping#batchedValueFromRow | |
* @see #rebuildOn(Expression) | |
* @bug 2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS | |
* @bug 2612567 CR4298- NULLPOINTEREXCEPTION WHEN USING SUBQUERY AND BATCH READING IN 4.6 | |
* @bug 2612140 CR2973- BATCHATTRIBUTE QUERIES WILL FAIL WHEN THE INITIAL QUERY HAS A SUBQUERY | |
* @bug 2720149 INVALID SQL WHEN USING BATCH READS AND MULTIPLE ANYOFS | |
*/ | |
public Expression cloneUsing(Expression newBase) { | |
// 2612538 - the default size of Map (32) is appropriate | |
Map alreadyDone = new IdentityHashMap(); | |
// cloneUsing is identical to cloning save that the primary builder | |
// will be replaced not with its clone but with newBase. | |
// ExpressionBuilder.registerIn() will check for this newBase with | |
// alreadyDone.get(alreadyDone); | |
// copiedVersionFrom() must be called on the primary builder before | |
// other builders. | |
alreadyDone.put(alreadyDone, newBase); | |
return copiedVersionFrom(alreadyDone); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the concatenation of the two string values. | |
*/ | |
public Expression concat(Object left) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Concat); | |
return anOperator.expressionFor(this, left); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that performs a key word search. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: project.get("description").containsAllKeyWords("EclipseLink rdbms java") | |
* </blockquote></pre> | |
*/ | |
public Expression containsAllKeyWords(String spaceSeparatedKeyWords) { | |
StringTokenizer tokenizer = new StringTokenizer(spaceSeparatedKeyWords); | |
Expression expression = null; | |
while (tokenizer.hasMoreTokens()) { | |
String token = tokenizer.nextToken(); | |
if (expression == null) { | |
expression = containsSubstringIgnoringCase(token); | |
} else { | |
expression = expression.and(containsSubstringIgnoringCase(token)); | |
} | |
} | |
if (expression == null) { | |
return like("%"); | |
} else { | |
return expression; | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that performs a key word search. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: project.get("description").containsAllKeyWords("EclipseLink rdbms java") | |
* </blockquote></pre> | |
*/ | |
public Expression containsAnyKeyWords(String spaceSeparatedKeyWords) { | |
StringTokenizer tokenizer = new StringTokenizer(spaceSeparatedKeyWords); | |
Expression expression = null; | |
while (tokenizer.hasMoreTokens()) { | |
String token = tokenizer.nextToken(); | |
if (expression == null) { | |
expression = containsSubstringIgnoringCase(token); | |
} else { | |
expression = expression.or(containsSubstringIgnoringCase(token)); | |
} | |
} | |
if (expression == null) { | |
return like("%"); | |
} else { | |
return expression; | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value contains the substring. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("firstName").containsSubstring("Bob") | |
* Java: employee.getFirstName().indexOf("Bob") != -1 | |
* SQL: F_NAME LIKE '%BOB%' | |
* </blockquote></pre> | |
*/ | |
public Expression containsSubstring(String theValue) { | |
return like("%" + theValue + "%"); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value contains the substring. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("firstName").containsSubstring("Bob") | |
* Java: employee.getFirstName().indexOf("Bob") != -1 | |
* SQL: F_NAME LIKE '%BOB%' | |
* </blockquote></pre> | |
*/ | |
public Expression containsSubstring(Expression expression) { | |
return like((value("%").concat(expression)).concat("%")); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value contains the substring, ignoring case. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("firstName").containsSubstringIgnoringCase("Bob") | |
* Java: employee.getFirstName().toUpperCase().indexOf("BOB") != -1 | |
* SQL: UPPER(F_NAME) LIKE '%BOB%' | |
* </blockquote></pre> | |
*/ | |
public Expression containsSubstringIgnoringCase(String theValue) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().containsSubstring(theValue.toUpperCase()); | |
} else { | |
return toLowerCase().containsSubstring(theValue.toLowerCase()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value contains the substring, ignoring case. | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("firstName").containsSubstringIgnoringCase("Bob") | |
* Java: employee.getFirstName().toUpperCase().indexOf("BOB") != -1 | |
* SQL: UPPER(F_NAME) LIKE '%BOB%' | |
* </blockquote></pre> | |
*/ | |
public Expression containsSubstringIgnoringCase(Expression expression) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().containsSubstring(expression.toUpperCase()); | |
} else { | |
return toLowerCase().containsSubstring(expression.toLowerCase()); | |
} | |
} | |
/* | |
* Modify this individual expression node to use outer joins wherever there are | |
* equality operations between two field nodes. | |
*/ | |
protected void convertNodeToUseOuterJoin() { | |
} | |
/** | |
* INTERNAL: | |
* Modify this expression to use outer joins wherever there are | |
* equality operations between two field nodes. | |
*/ | |
public Expression convertToUseOuterJoin() { | |
ExpressionIterator iterator = new ExpressionIterator() { | |
public void iterate(Expression each) { | |
each.convertNodeToUseOuterJoin(); | |
} | |
}; | |
iterator.iterateOn(this); | |
return this; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression copiedVersionFrom(Map alreadyDone) { | |
if (alreadyDone == null) { | |
// For sub-selects no cloning is done. | |
return this; | |
} | |
Expression existing = (Expression)alreadyDone.get(this); | |
if (existing == null) { | |
return registerIn(alreadyDone); | |
} else { | |
return existing; | |
} | |
} | |
/** | |
* PUBLIC: | |
* This represents the aggregate function Average. Can be used only within Report Queries. | |
*/ | |
public Expression count() { | |
return getFunction(ExpressionOperator.Count); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression create(Expression base, Object singleArgument, ExpressionOperator anOperator) { | |
// This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then | |
// mutate it using this method. | |
return this; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression createWithBaseLast(Expression base, Object singleArgument, ExpressionOperator anOperator) { | |
// This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then | |
// mutate it using this method. | |
return this; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression create(Expression base, List arguments, ExpressionOperator anOperator) { | |
// This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then | |
// mutate it using this method. | |
return this; | |
} | |
/** | |
* PUBLIC: | |
* This gives access to the current timestamp on the database through expression. | |
* Please note, this method is added for consistency and returns the same | |
* result as currentDate. | |
*/ | |
public Expression currentTimeStamp() { | |
return currentDate(); | |
} | |
/** | |
* PUBLIC: | |
* This gives access to the current date on the database through expression. | |
*/ | |
public Expression currentDate() { | |
return getFunction(ExpressionOperator.Today); | |
} | |
/** | |
* PUBLIC: | |
* This gives access to the current date only on the database through expression. | |
* Note the difference between currentDate() and this method. This method does | |
* not return the time portion of current date where as currentDate() does. | |
*/ | |
public Expression currentDateDate() { | |
return getFunction(ExpressionOperator.CurrentDate); | |
} | |
/** | |
* PUBLIC: | |
* This gives access to the current time only on the database through expression. | |
* Note the difference between currentDate() and this method. This method does | |
* not return the date portion where as currentDate() does. | |
*/ | |
public Expression currentTime() { | |
return getFunction(ExpressionOperator.CurrentTime); | |
} | |
/** | |
* PUBLIC: | |
* Function, Return the difference between the queried part of a date(i.e. years, days etc.) | |
* and same part of the given date. The equivalent of the Sybase function DateDiff | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").dateDifference("year", new Date(System.currentTimeMillis())) | |
* Java: NA | |
* SQL: DATEADD(date, 2, GETDATE) | |
* </blockquote></pre> * | |
*/ | |
public Expression dateDifference(String datePart, java.util.Date date) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.DateDifference); | |
FunctionExpression expression = new FunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.addChild(Expression.fromLiteral(datePart, this)); | |
expression.addChild(Expression.from(date, this)); | |
expression.addChild(this); | |
expression.setOperator(anOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Function, Return the difference between the queried part of a date(i.e. years, days etc.) | |
* and same part of the given date. The equivalent of the Sybase function DateDiff | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").dateDifference("year", new Date(System.currentTimeMillis())) | |
* Java: NA | |
* SQL: DATEADD(date, 2, GETDATE) | |
* </blockquote></pre> * | |
*/ | |
public Expression dateDifference(String datePart, Expression comparisonExpression) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.DateDifference); | |
FunctionExpression expression = new FunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.addChild(Expression.fromLiteral(datePart, this)); | |
expression.addChild(comparisonExpression); | |
expression.addChild(this); | |
expression.setOperator(anOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* return a string that represents the given part of a date. The equivalent | |
* of the Sybase DATENAME function | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").dateName("year") | |
* Java: new String(date.getYear()) | |
* SQL: DATENAME(date, year) | |
* </blockquote></pre> * | |
*/ | |
public Expression dateName(String datePart) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.DateName); | |
FunctionExpression expression = new FunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.addChild(Expression.fromLiteral(datePart, this)); | |
expression.addChild(this); | |
expression.setOperator(anOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Function return an integer which represents the requested | |
* part of the date. Equivalent of the Sybase function DATEPART | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("date").datePart("year") | |
* Java: date.getYear() | |
* SQL: DATEPART(date, year) | |
* </blockquote></pre> * */ | |
public Expression datePart(String datePart) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.DatePart); | |
FunctionExpression expression = new FunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.addChild(Expression.fromLiteral(datePart, this)); | |
expression.addChild(this); | |
expression.setOperator(anOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the date converted to the string value in the default database format. | |
*/ | |
public Expression dateToString() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.DateToString); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function Convert values returned by the query to values given in the decodeableItems Map. | |
* The equivalent of the Oracle DECODE function. | |
* Note: This will only work on databases that support Decode with the syntax below. | |
* <p>Example: | |
* <blockquote><pre> | |
* Map decodeTable = new HashMap(); | |
* decodeTable.put("Robert", "Bob"); | |
* decodeTable.put("Susan", "Sue"); | |
* | |
* EclipseLink: employee.get("name").Decode(decodeTable, "No-Nickname") | |
* Java: NA | |
* SQL: DECODE(name, "Robert", "Bob", "Susan", "Sue", "No-Nickname") | |
* </blockquote></pre> | |
* @param decodeableItems java.util.Map | |
* a Map containing the items to be decoded. Keys represent | |
* the items to match coming from the query. Values represent what | |
* a key will be changed to. | |
* @param defaultItem | |
* the default value that will be used if none of the keys in the | |
* Map match | |
**/ | |
public Expression decode(Map decodeableItems, String defaultItem) { | |
/** | |
* decode works differently than most of the functionality in the expression framework. | |
* It takes a variable number of arguments and as a result, the printed strings for | |
* a decode call have to be built when the number of arguments are known. | |
* As a result, we do not look up decode in the ExpressionOperator. Instead we build | |
* the whole operator here. The side effect of this is that decode will not thrown | |
* an invalid operator exception for any platform. (Even the ones that do not support | |
* decode) | |
*/ | |
ExpressionOperator anOperator = new ExpressionOperator(); | |
anOperator.setSelector(ExpressionOperator.Decode); | |
anOperator.setName("DECODE"); | |
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
anOperator.setType(ExpressionOperator.FunctionOperator); | |
anOperator.bePrefix(); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(decodeableItems.size() + 1); | |
v.add("DECODE("); | |
for (int i = 0; i < ((decodeableItems.size() * 2) + 1); i++) { | |
v.add(", "); | |
} | |
v.add(")"); | |
anOperator.printsAs(v); | |
FunctionExpression expression = new FunctionExpression(); | |
expression.setBaseExpression(this); | |
expression.addChild(this); | |
Iterator iterator = decodeableItems.keySet().iterator(); | |
while (iterator.hasNext()) { | |
Object key = iterator.next(); | |
expression.addChild(Expression.from(key, this)); | |
expression.addChild(Expression.from(decodeableItems.get(key), this)); | |
} | |
expression.addChild(Expression.from(defaultItem, this)); | |
expression.setOperator(anOperator); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* This can only be used within an ordering expression. | |
* It will order the result descending. | |
* <p>Example: | |
* <blockquote><pre> | |
* readAllQuery.addOrderBy(expBuilder.get("address").get("city").descending()) | |
* </blockquote></pre> | |
*/ | |
public Expression descending() { | |
return getFunction(ExpressionOperator.Descending); | |
} | |
/** | |
* INTERNAL: | |
* Used in debug printing of this node. | |
*/ | |
public String descriptionOfNodeType() { | |
return "Expression"; | |
} | |
/** | |
* PUBLIC: | |
* Function return a value which indicates how much difference there is | |
* between two expressions. Equivalent of the Sybase DIFFERENCE function | |
* <p>Example: | |
* <blockquote><pre> | |
* EclipseLink: employee.get("name").difference("Frank") | |
* SQL: DIFFERENCE(name, 'Frank') | |
* </blockquote></pre> * */ | |
public Expression difference(String expression) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Difference); | |
return anOperator.expressionFor(this, expression); | |
} | |
/** | |
* PUBLIC: | |
* Function, This represents the distinct option inside an aggregate function. Can be used only within Report Queries. | |
*/ | |
public Expression distinct() { | |
return getFunction(ExpressionOperator.Distinct); | |
} | |
/** | |
* INTERNAL: | |
* Check if the object conforms to the expression in memory. | |
* This is used for in-memory querying. | |
* By default throw an exception as all valid root expressions must override. | |
* If the expression in not able to determine if the object conform throw a not supported exception. | |
*/ | |
public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy) throws QueryException { | |
return doesConform(object, session, translationRow, valueHolderPolicy, false); | |
} | |
/** | |
* INTERNAL: | |
* New parameter added to doesConform for feature 2612601 | |
* @param objectIsUnregistered true if object possibly not a clone, but is being | |
* conformed against the unit of work cache; if object is not in the UOW cache | |
* but some of its attributes are, use the registered versions of | |
* object's attributes for the purposes of this method. | |
*/ | |
public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean objectIsUnregistered) throws QueryException { | |
throw QueryException.cannotConformExpression(); | |
} | |
/** | |
* INTERNAL: | |
* Return if the expression is equal to the other. | |
* This is used to allow dynamic expression's SQL to be cached. | |
* Two expressions should be considered equal if they have the same "parameterized" SQL. | |
* This must be over written by each subclass. | |
*/ | |
public boolean equals(Object expression) { | |
return (this == expression) || ((expression != null) && getClass().equals(expression.getClass()) && (hashCode() == expression.hashCode())); | |
} | |
/** | |
* INTERNAL: | |
* Return a consistent hash-code for the expression. | |
* This is used to allow dynamic expression's SQL to be cached. | |
* Two expressions should have the same hashCode if they have the same "parameterized" SQL. | |
* This should be over written by each subclass to provide a consistent value. | |
*/ | |
public int hashCode() { | |
if (this.hashCode == 0) { | |
this.hashCode = computeHashCode(); | |
} | |
return this.hashCode; | |
} | |
/** | |
* INTERNAL: | |
* Compute a consistent hash-code for the expression. | |
* This is used to allow dynamic expression's SQL to be cached. | |
* Two expressions should have the same hashCode if they have the same "parameterized" SQL. | |
* This should be over written by each subclass to provide a consistent value. | |
*/ | |
public int computeHashCode() { | |
return 32; | |
} | |
public Expression equal(byte theValue) { | |
return equal(Byte.valueOf(theValue)); | |
} | |
public Expression equal(char theChar) { | |
return equal(Character.valueOf(theChar)); | |
} | |
public Expression equal(double theValue) { | |
return equal(Double.valueOf(theValue)); | |
} | |
public Expression equal(float theValue) { | |
return equal(Float.valueOf(theValue)); | |
} | |
public Expression equal(int theValue) { | |
return equal(Integer.valueOf(theValue)); | |
} | |
public Expression equal(long theValue) { | |
return equal(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receiver's value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").equal("Bob") | |
* Java: employee.getFirstName().equals("Bob") | |
* SQL: F_NAME = 'Bob' | |
* </blockquote></pre> | |
*/ | |
public Expression equal(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Equal); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* Returns an expression that compares if the receiver's value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
* <p>Since OracleAS EclipseLink 10<i>g</i> (9.0.4) if <code>this</code> is an <code>ExpressionBuilder</code> and <code>theValue</code> | |
* is not used elsewhere, both will be translated to the same table. This can | |
* generate SQL with one less join for most exists subqueries. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("manager").equal(employee) | |
* Java: employee.getManager().equals(employee) | |
* SQL (optimized): EMP_ID = MANAGER_ID | |
* SQL (unoptimized): t0.MANAGER_ID = t1.EMP_ID AND t0.EMP_ID = t1.EMP_ID | |
* </blockquote></pre> | |
* @see #equal(Object) | |
*/ | |
public Expression equal(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Equal); | |
return anOperator.expressionFor(this, theValue); | |
} | |
public Expression equal(short theValue) { | |
return equal(Short.valueOf(theValue)); | |
} | |
public Expression equal(boolean theBoolean) { | |
return equal(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* INTERNAL: | |
* Return an expression representing an outer join comparison | |
*/ | |
// cr3546 | |
public Expression equalOuterJoin(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.EqualOuterJoin); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* INTERNAL: | |
* Return an expression representing an outer join comparison | |
*/ | |
public Expression equalOuterJoin(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.EqualOuterJoin); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receiver's value is equal to the other value, ignoring case. | |
* This is equivalent to the Java "equalsIgnoreCase" method. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob") | |
* Java: employee.getFirstName().equalsIgnoreCase("Bob") | |
* SQL: UPPER(F_NAME) = 'BOB' | |
* </blockquote></pre> | |
*/ | |
public Expression equalsIgnoreCase(String theValue) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().equal(theValue.toUpperCase()); | |
} else { | |
return toLowerCase().equal(theValue.toLowerCase()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receiver's value is equal to the other value, ignoring case. | |
* This is equivalent to the Java "equalsIgnoreCase" method. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob") | |
* Java: employee.getFirstName().equalsIgnoreCase("Bob") | |
* SQL: UPPER(F_NAME) = 'BOB' | |
* </blockquote></pre> | |
*/ | |
public Expression equalsIgnoreCase(Expression theValue) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().equal(theValue.toUpperCase()); | |
} else { | |
return toLowerCase().equal(theValue.toLowerCase()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return a sub query expression. | |
* A sub query using a report query to define a subselect within another queries expression or select's where clause. | |
* The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder. | |
* <p>Example: | |
* <pre><blockquote> | |
* ExpressionBuilder builder = new ExpressionBuilder(); | |
* ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder()); | |
* subQuery.setSelectionCriteria(subQuery.getExpressionBuilder().get("name").equal(builder.get("name"))); | |
* builder.exists(subQuery); | |
* </blockquote></pre> | |
*/ | |
public Expression exists(ReportQuery subQuery) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Exists); | |
return anOperator.expressionFor(subQuery(subQuery)); | |
} | |
/** | |
* INTERNAL: | |
* Extract the primary key from the expression into the row. | |
* Ensure that the query is querying the exact primary key. | |
* Return false if not on the primary key. | |
*/ | |
public boolean extractPrimaryKeyValues(boolean requireExactMatch, ClassDescriptor descriptor, AbstractRecord primaryKeyRow, AbstractRecord translationRow) { | |
return extractValues(true, requireExactMatch, descriptor, primaryKeyRow, translationRow); | |
} | |
/** | |
* INTERNAL: | |
* Extract the primary key from the expression into the row. | |
* Ensure that the query is querying the exact primary key. | |
* Return false if not on the primary key. | |
*/ | |
public boolean extractValues(boolean primaryKeyOnly, boolean requireExactMatch, ClassDescriptor descriptor, AbstractRecord primaryKeyRow, AbstractRecord translationRow) { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Return if the expression is not a valid primary key expression and add all primary key fields to the set. | |
*/ | |
public boolean extractFields(boolean requireExactMatch, boolean primaryKey, ClassDescriptor descriptor, List<DatabaseField> searchFields, Set<DatabaseField> foundFields) { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Create an expression node. | |
*/ | |
public static Expression from(Object value, Expression base) { | |
//CR#... null value used to return null, must build a null constant expression. | |
if (value instanceof Expression) { | |
Expression exp = (Expression)value; | |
if (exp.isValueExpression() || base.isExpressionBuilder()) { | |
exp.setLocalBase(base); | |
} else { | |
// We don't know which side of the relationship cares about the other one, so notify both | |
// However for 3107049 value.equal(value) would cause infinite loop if did that. | |
base.setLocalBase(exp); | |
} | |
return exp; | |
} | |
if (value instanceof ReportQuery) { | |
Expression exp = base.subQuery((ReportQuery)value); | |
exp.setLocalBase(base);// We don't know which side of the relationship cares about the other one, so notify both | |
base.setLocalBase(exp); | |
return exp; | |
} | |
return fromConstant(value, base); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression node. | |
*/ | |
public static Expression fromConstant(Object value, Expression base) { | |
return new ConstantExpression(value, base); | |
} | |
/** | |
* INTERNAL: | |
* Create an expression node. | |
*/ | |
public static Expression fromLiteral(String value, Expression base) { | |
return new LiteralExpression(value, base); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that wraps the attribute or query key name. | |
* This method is used to construct user-defined queries containing joins. | |
* <p>Example: | |
* <pre><blockquote> | |
* builder.get("address").get("city").equal("Ottawa"); | |
* </blockquote></pre> | |
*/ | |
public Expression get(String attributeName) { | |
throw new UnsupportedOperationException("get"); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression that wraps the attribute or query key name. | |
* This is only applicable to 1:1 relationships, and allows the target of | |
* the relationship to be null if there is no corresponding relationship in the database. | |
* Implemented via an outer join in the database. | |
* <p>Example: | |
* <pre><blockquote> | |
* builder.getAllowingNull("address").get("city").equal("Ottawa"); | |
* </blockquote></pre> | |
*/ | |
public Expression getAllowingNull(String attributeName) { | |
throw new UnsupportedOperationException("getAllowingNull"); | |
} | |
/** | |
* Answers the past time the expression is explicitly as of. | |
* @return An immutable object representation of the past time. | |
* <code>null</code> if no clause set, <code>AsOfClause.NO_CLAUSE</code> if | |
* clause explicitly set to <code>null</code>. | |
* @see #asOf(org.eclipse.persistence.history.AsOfClause) | |
* @see #hasAsOfClause() | |
*/ | |
public AsOfClause getAsOfClause() { | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* For Flashback: If this expression is not already as of some timestamp | |
* gets the clause from the base expression. Allows a clause to be set | |
* only on the builder and then propogated during normalize. | |
*/ | |
public AsOfClause getAsOfClauseRecursively() { | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* Return the expression builder which is the ultimate base of this expression, or | |
* null if there isn't one (shouldn't happen if we start from a root) | |
*/ | |
public abstract ExpressionBuilder getBuilder(); | |
/** | |
* INTERNAL: | |
* If there are any fields associated with this expression, return them | |
*/ | |
public DatabaseField getClonedField() { | |
return null; | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing a field in a data-level query. | |
* This is used internally in EclipseLink, or to construct queries involving | |
* fields and/or tables that are not mapped. | |
* <p> Example: | |
* <blockquote><pre> | |
* builder.getField("ADDR_ID").greaterThan(100); | |
* builder.getTable("PROJ_EMP").getField("TYPE").equal("S"); | |
* </blockquote></pre> | |
*/ | |
public Expression getField(String fieldName) { | |
throw QueryException.illegalUseOfGetField(fieldName); | |
} | |
/** | |
* ADVANCED: Return an expression representing a field in a data-level query. | |
* This is used internally in EclipseLink, or to construct queries involving | |
* fields and/or tables that are not mapped. | |
* <p> Example: | |
* <blockquote><pre> | |
* builder.getField(aField).greaterThan(100); | |
* </blockquote></pre> | |
*/ | |
public Expression getField(DatabaseField field) { | |
throw QueryException.illegalUseOfGetField(field); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Vector getFields() { | |
return org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public List<DatabaseField> getSelectionFields() { | |
return getSelectionFields(null); | |
} | |
public List<DatabaseField> getSelectionFields(ReadQuery query) { | |
return getFields(); | |
} | |
/** | |
* INTERNAL: | |
* Transform the object-level value into a database-level value | |
*/ | |
public Object getFieldValue(Object objectValue, AbstractSession session) { | |
// Enums default to their ordinal | |
if (objectValue instanceof Enum){ | |
return ((Enum)objectValue).ordinal(); | |
} | |
return objectValue; | |
} | |
/** | |
* ADVANCED: | |
* Defines a join between the two objects based on the specified ON clause. | |
* This can be used to define a join condition on two unrelated objects, | |
* or to qualify a relationship join with additional criteria. | |
* <p> Example: | |
* <pre><blockquote> | |
* Expression address = employee.getAllowingNull("address"); | |
* employee.join(address, address.get("city").equal("Ottawa")); | |
* query.addNonFetchJoin(address); | |
* </blockquote></pre> | |
*/ | |
public Expression join(Expression target, Expression onClause) { | |
throw new UnsupportedOperationException("join"); | |
} | |
/** | |
* ADVANCED: | |
* Defines an outer join between the two objects based on the specified ON clause. | |
* This can be used to define a join condition on two unrelated objects, | |
* or to qualify a relationship join with additional criteria. | |
* <p> Example: | |
* <pre><blockquote> | |
* Expression address = employee.getAllowingNull("address"); | |
* employee.leftJoin(address, address.get("city").equal("Ottawa")); | |
* query.addNonFetchJoin(address); | |
* </blockquote></pre> | |
*/ | |
public Expression leftJoin(Expression target, Expression onClause) { | |
throw new UnsupportedOperationException("leftJoin"); | |
} | |
/** | |
* ADVANCED: | |
* This can be used for accessing user defined functions. | |
* The operator must be defined in ExpressionOperator to be able to reference it. | |
* @see ExpressionOperator | |
* <p> Example: | |
* <pre><blockquote> | |
* builder.get("name").getFunction(MyFunctions.FOO_BAR).greaterThan(100); | |
* </blockquote></pre> | |
*/ | |
public Expression getFunction(int selector) { | |
ExpressionOperator anOperator = getOperator(selector); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* ADVANCED: | |
* This can be used for accessing user defined functions that have arguments. | |
* The operator must be defined in ExpressionOperator to be able to reference it. | |
* @see ExpressionOperator | |
* <p> Example: | |
* <pre><blockquote> | |
* List arguments = new ArrayList(); | |
* arguments.add("blee"); | |
* builder.get("name").getFunction(MyFunctions.FOO_BAR, arguments).greaterThan(100); | |
* </blockquote></pre> | |
*/ | |
public Expression getFunction(int selector, List arguments) { | |
ExpressionOperator anOperator = getOperator(selector); | |
return anOperator.expressionForArguments(this, arguments); | |
} | |
/** | |
* ADVANCED: | |
* This can be used for accessing user defined operators that have arguments. | |
* The operator must be defined in ExpressionOperator to be able to reference it. | |
* @see ExpressionOperator | |
* <p> Example: | |
* <pre><blockquote> | |
* List arguments = new ArrayList(); | |
* arguments.add("blee"); | |
* builder.get("name").operator("FOO_BAR", arguments).greaterThan(100); | |
* </blockquote></pre> | |
*/ | |
public Expression operator(String name, List arguments) { | |
Integer selector = ExpressionOperator.getPlatformOperatorSelectors().get(name); | |
if (selector == null) { | |
return getFunctionWithArguments(name, arguments); | |
} | |
return getFunction(selector, arguments); | |
} | |
/** | |
* ADVANCED: | |
* This can be used for accessing user defined functions that have arguments. | |
* The operator must be defined in ExpressionOperator to be able to reference it. | |
* @see ExpressionOperator | |
* <p> Example: | |
* <pre><blockquote> | |
* List arguments = new ArrayList(); | |
* arguments.add("blee"); | |
* builder.get("name").getFunction(MyFunctions.FOO_BAR, arguments).greaterThan(100); | |
* </blockquote></pre> | |
*/ | |
@Deprecated | |
public Expression getFunction(int selector, Vector arguments) { | |
return getFunction(selector, (List)arguments); | |
} | |
/** | |
* ADVANCED: | |
* Return a user defined function accepting the argument. | |
* The function is assumed to be a normal prefix function and will print like, UPPER(base). | |
* <p> Example: | |
* <pre><blockquote> | |
* builder.get("firstName").getFunction("UPPER"); | |
* </blockquote></pre> | |
*/ | |
public Expression getFunction(String functionName) { | |
ExpressionOperator anOperator = ExpressionOperator.simpleFunction(0, functionName); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* ADVANCED: | |
* Return a user defined function accepting the argument. | |
* The function is assumed to be a normal prefix function and will print like, CONCAT(base, argument). | |
*/ | |
public Expression getFunction(String functionName, Object argument) { | |
ExpressionOperator anOperator = ExpressionOperator.simpleTwoArgumentFunction(0, functionName); | |
return anOperator.expressionFor(this, argument); | |
} | |
/** | |
* ADVANCED: | |
* Return a user defined function accepting all of the arguments. | |
* The function is assumed to be a normal prefix function like, CONCAT(base, value1, value2, value3, ...). | |
*/ | |
@Deprecated | |
public Expression getFunctionWithArguments(String functionName, Vector arguments) { | |
return getFunctionWithArguments(functionName, (List)arguments); | |
} | |
/** | |
* ADVANCED: | |
* Return a user defined function accepting all of the arguments. | |
* The function is assumed to be a normal prefix function like, CONCAT(base, value1, value2, value3, ...). | |
*/ | |
public Expression getFunctionWithArguments(String functionName, List arguments) { | |
ExpressionOperator anOperator = new ExpressionOperator(); | |
anOperator.setType(ExpressionOperator.FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(arguments.size()); | |
v.add(functionName + "("); | |
for (int index = 0; index < arguments.size(); index++) { | |
v.add(", "); | |
} | |
v.add(")"); | |
anOperator.printsAs(v); | |
anOperator.bePrefix(); | |
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return anOperator.expressionForArguments(this, arguments); | |
} | |
/** | |
* ADVANCED: | |
* Parse the SQL for parameter and return a custom function expression | |
* using a custom operator that will print itself as the SQL. | |
* Arguments are passed using '?', and must match the number of arguments. | |
*/ | |
public Expression sql(String sql, List arguments) { | |
ExpressionOperator anOperator = new ExpressionOperator(); | |
anOperator.setType(ExpressionOperator.FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(arguments.size()); | |
int start = 0; | |
int index = sql.indexOf('?'); | |
while (index != -1) { | |
v.add(sql.substring(start, index)); | |
start = index + 1; | |
index = sql.indexOf('?', start); | |
} | |
if (start <= sql.length()) { | |
v.add(sql.substring(start, sql.length())); | |
} | |
anOperator.printsAs(v); | |
anOperator.bePrefix(); | |
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return anOperator.expressionForArguments(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that wraps the inheritance type field in an expression. | |
* <p>Example: | |
* <pre><blockquote> | |
* builder.getClassForInheritance().equal(SmallProject.class); | |
* builder.anyOf("projects").getClassForInheritance().equal(builder.getParameter("projectClass")); | |
* </blockquote></pre> | |
*/ | |
public Expression type() { | |
//Only valid on an ObjectExpression | |
return null; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public String getName() { | |
return ""; | |
} | |
/** | |
* INTERNAL: | |
* Most expression have operators, so this is just a convenience method. | |
*/ | |
public ExpressionOperator getOperator() { | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* Create a new expression tree with the named operator. Part of the implementation of user-level "get" | |
*/ | |
public ExpressionOperator getOperator(int selector) { | |
ExpressionOperator result = ExpressionOperator.getOperator(Integer.valueOf(selector)); | |
if (result != null) { | |
return result; | |
} | |
// Make a temporary operator which we expect the platform | |
// to supply later. | |
result = new ExpressionOperator(); | |
result.setSelector(selector); | |
result.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return result; | |
} | |
/** | |
* INTERNAL: | |
* Return the tables that this node owns for purposes of table aliasing. | |
*/ | |
public List<DatabaseTable> getOwnedTables() { | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* Return an expression representing a parameter with the given name and type | |
*/ | |
public Expression getParameter(String parameterName, Object type) { | |
return new ParameterExpression(parameterName, getBuilder(), type); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing a parameter with the given name. | |
*/ | |
public Expression getParameter(String parameterName) { | |
return new ParameterExpression(parameterName, getBuilder(), null); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing a parameter with the given name. | |
*/ | |
public Expression getParameter(DatabaseField field) { | |
return new ParameterExpression(field, getBuilder()); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression representing a property with the given name. | |
*/ | |
public Expression getProperty(DatabaseField field) { | |
ParameterExpression paramExpression = new ParameterExpression(field, this); | |
paramExpression.setIsProperty(true); | |
return paramExpression; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public AbstractSession getSession() { | |
return getBuilder().getSession(); | |
} | |
/** | |
* ADVANCED: Return an expression representing a table in a data-level query. | |
* This is used internally in EclipseLink, or to construct queries involving | |
* fields and/or tables that are not mapped. | |
* <p> Example: | |
* <pre><blockquote> | |
* builder.getTable("PROJ_EMP").getField("TYPE").equal("S"); | |
* </blockquote></pre> | |
*/ | |
public Expression getTable(String tableName) { | |
DatabaseTable table = new DatabaseTable(tableName); | |
return getTable(table); | |
} | |
/** | |
* ADVANCED: Return an expression representing a table in a data-level query. | |
* This is used internally in EclipseLink, or to construct queries involving | |
* fields and/or tables that are not mapped. | |
* <p> Example: | |
* <pre><blockquote> | |
* builder.getTable(linkTable).getField("TYPE").equal("S"); | |
* </blockquote></pre> | |
*/ | |
public Expression getTable(DatabaseTable table) { | |
throw QueryException.illegalUseOfGetTable(table); | |
} | |
/** | |
* ADVANCED: Return an expression representing a sub-select in the from clause. | |
* <p> Example: | |
* <pre><blockquote> | |
* builder.getAlias(builder.subQuery(reportQuery)).get("type").equal("S"); | |
* </blockquote></pre> | |
*/ | |
public Expression getAlias(Expression subSelect) { | |
throw QueryException.illegalUseOfGetTable(subSelect); | |
} | |
/** | |
* INTERNAL: | |
* Return the aliases used. By default, return null, since we don't have tables. | |
*/ | |
public TableAliasLookup getTableAliases() { | |
return null; | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(byte theValue) { | |
return greaterThan(Byte.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(char theChar) { | |
return greaterThan(Character.valueOf(theChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(double theValue) { | |
return greaterThan(Double.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(float theValue) { | |
return greaterThan(Float.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(int theValue) { | |
return greaterThan(Integer.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(long theValue) { | |
return greaterThan(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receiver's value is greater than the other value. | |
* This is equivalent to the SQL ">" operator. | |
*/ | |
public Expression greaterThan(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThan); | |
return anOperator.expressionFor(this, theValue); | |
} | |
public Expression greaterThan(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThan); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(short theValue) { | |
return greaterThan(Short.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is equal to the other value. | |
* This is equivalent to the SQL "=" operator and Java "equals" method. | |
*/ | |
public Expression greaterThan(boolean theBoolean) { | |
return greaterThan(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(byte theValue) { | |
return greaterThanEqual(Byte.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(char theChar) { | |
return greaterThanEqual(Character.valueOf(theChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(double theValue) { | |
return greaterThanEqual(Double.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(float theValue) { | |
return greaterThanEqual(Float.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(int theValue) { | |
return greaterThanEqual(Integer.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(long theValue) { | |
return greaterThanEqual(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThanEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThanEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(short theValue) { | |
return greaterThanEqual(Short.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is greater and equal to the other value. | |
* This is equivalent to the SQL ">=" operator . | |
*/ | |
public Expression greaterThanEqual(boolean theBoolean) { | |
return greaterThanEqual(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* ADVANCED: | |
* Answers true if <code>this</code> is to be queried as of a past time. | |
* @return false from <code>asOf(null); hasAsOfClause()</code>. | |
* @see #getAsOfClause | |
*/ | |
public boolean hasAsOfClause() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Answers if the database tables associated with this expression have been | |
* aliased. This insures the same tables are not aliased twice. | |
*/ | |
public boolean hasBeenAliased() { | |
return false; | |
} | |
/** | |
* PUBLIC: | |
* Function, returns binary array value for the hex string. | |
*/ | |
public Expression hexToRaw() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.HexToRaw); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function return a specific value if item returned from the | |
* query is null. Equivalent of the oracle NVL function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").ifNull("no-name") | |
* Java: NA | |
* SQL: NVL(name, 'no-name') | |
* </blockquote></pre> | |
*/ | |
public Expression ifNull(Object nullValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Nvl); | |
return anOperator.expressionFor(this, nullValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(byte[] theBytes) { | |
List values = new ArrayList(theBytes.length); | |
for (int index = 0; index < theBytes.length; index++) { | |
values.add(Byte.valueOf(theBytes[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(char[] theChars) { | |
List values = new ArrayList(theChars.length); | |
for (int index = 0; index < theChars.length; index++) { | |
values.add(Character.valueOf(theChars[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(double[] theDoubles) { | |
List values = new ArrayList(theDoubles.length); | |
for (int index = 0; index < theDoubles.length; index++) { | |
values.add(Double.valueOf(theDoubles[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(float[] theFloats) { | |
List values = new ArrayList(theFloats.length); | |
for (int index = 0; index < theFloats.length; index++) { | |
values.add(Float.valueOf(theFloats[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(int[] theInts) { | |
List values = new ArrayList(theInts.length); | |
for (int index = 0; index < theInts.length; index++) { | |
values.add(Integer.valueOf(theInts[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(long[] theLongs) { | |
List values = new ArrayList(theLongs.length); | |
for (int index = 0; index < theLongs.length; index++) { | |
values.add(Long.valueOf(theLongs[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(Object[] theObjects) { | |
List values = new ArrayList(theObjects.length); | |
for (int index = 0; index < theObjects.length; index++) { | |
values.add(theObjects[index]); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(short[] theShorts) { | |
List values = new ArrayList(theShorts.length); | |
for (int index = 0; index < theShorts.length; index++) { | |
values.add(Short.valueOf(theShorts[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression in(boolean[] theBooleans) { | |
List values = new ArrayList(theBooleans.length); | |
for (int index = 0; index < theBooleans.length; index++) { | |
values.add(Boolean.valueOf(theBooleans[index])); | |
} | |
return in(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
*/ | |
public Expression in(Collection theObjects) { | |
return in(new CollectionExpression(theObjects, this)); | |
} | |
public Expression in(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.In); | |
return anOperator.expressionFor(this, arguments); | |
} | |
public Expression in(ReportQuery subQuery) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.InSubQuery); | |
return anOperator.expressionFor(this, subQuery); | |
} | |
/* | |
* PUBLIC: | |
* Index method could be applied to QueryKeyExpression corresponding to CollectionMapping | |
* that has non-null listOrderField (the field holding the index values). | |
* <p>Example: | |
* <pre><blockquote> | |
* ReportQuery query = new ReportQuery(); | |
* query.setReferenceClass(Employee.class); | |
* ExpressionBuilder builder = query.getExpressionBuilder(); | |
* Expression firstNameJohn = builder.get("firstName").equal("John"); | |
* Expression anyOfProjects = builder.anyOf("projects"); | |
* Expression exp = firstNameJohn.and(anyOfProjects.index().between(2, 4)); | |
* query.setSelectionCriteria(exp); | |
* query.addAttribute("projects", anyOfProjects); | |
* | |
* SELECT DISTINCT t0.PROJ_ID, t0.PROJ_TYPE, t0.DESCRIP, t0.PROJ_NAME, t0.LEADER_ID, t0.VERSION, t1.PROJ_ID, t1.BUDGET, t1.MILESTONE | |
* FROM OL_PROJ_EMP t4, OL_SALARY t3, OL_EMPLOYEE t2, OL_LPROJECT t1, OL_PROJECT t0 | |
* WHERE ((((t2.F_NAME = 'John') AND (t4.PROJ_ORDER BETWEEN 2 AND 4)) AND (t3.OWNER_EMP_ID = t2.EMP_ID)) AND | |
* (((t4.EMP_ID = t2.EMP_ID) AND (t0.PROJ_ID = t4.PROJ_ID)) AND (t1.PROJ_ID (+) = t0.PROJ_ID))) | |
* </blockquote></pre> | |
*/ | |
public Expression index() { | |
throw QueryException.indexRequiresQueryKeyExpression(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the integer index of the substring within the source string. | |
*/ | |
public Expression indexOf(Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Instring); | |
return anOperator.expressionFor(this, substring); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isClassTypeExpression(){ | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isCompoundExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isConstantExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isDataExpression() { | |
return false; | |
} | |
/** | |
* PUBLIC: A logical expression for the collection <code>attributeName</code> | |
* being empty. | |
* Equivalent to <code>size(attributeName).equal(0)</code> | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.isEmpty("phoneNumbers") | |
* Java: employee.getPhoneNumbers().size() == 0 | |
* SQL: SELECT ... FROM EMP t0 WHERE ( | |
* (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) = 0) | |
* </blockquote></pre> | |
* This is a case where a fast operation in java does not translate to an | |
* equally fast operation in SQL, requiring a correlated subselect. | |
* @see #size(java.lang.String) | |
*/ | |
public Expression isEmpty(String attributeName) { | |
return size(attributeName).equal(0); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isExpressionBuilder() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isFieldExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isFunctionExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isLiteralExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isLogicalExpression() { | |
return false; | |
} | |
/** | |
* PUBLIC: | |
* Compare to null. | |
*/ | |
public Expression isNull() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.IsNull); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isObjectExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isParameterExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isQueryKeyExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isRelationExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isSubSelectExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isTableExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isTreatExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isMapEntryExpression(){ | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Subclasses implement (isParameterExpression() || isConstantExpression()) | |
*/ | |
public boolean isValueExpression() { | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* For iterating using an inner class | |
*/ | |
public void iterateOn(ExpressionIterator iterator) { | |
iterator.iterate(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the date with the last date in the months of this source date. | |
*/ | |
public Expression lastDay() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LastDay); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string padded with the substring to the size. | |
*/ | |
public Expression leftPad(int size, Object substring) { | |
return leftPad(Integer.valueOf(size), substring); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string padded with the substring to the size. | |
*/ | |
public Expression leftPad(Object size, Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftPad); | |
List args = new ArrayList(2); | |
args.add(size); | |
args.add(substring); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string left trimmed for white space. | |
*/ | |
public Expression leftTrim() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftTrim); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string with the substring trimed from the left. | |
*/ | |
public Expression leftTrim(Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftTrim2); | |
return anOperator.expressionFor(this, substring); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the size of the string. | |
*/ | |
public Expression length() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Length); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(byte theValue) { | |
return lessThan(Byte.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(char theChar) { | |
return lessThan(Character.valueOf(theChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(double theValue) { | |
return lessThan(Double.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(float theValue) { | |
return lessThan(Float.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(int theValue) { | |
return lessThan(Integer.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(long theValue) { | |
return lessThan(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThan); | |
return anOperator.expressionFor(this, theValue); | |
} | |
public Expression lessThan(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThan); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(short theValue) { | |
return lessThan(Short.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than the other value. | |
* This is equivalent to the SQL "<" operator. | |
*/ | |
public Expression lessThan(boolean theBoolean) { | |
return lessThan(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(byte theValue) { | |
return lessThanEqual(Byte.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(char theChar) { | |
return lessThanEqual(Character.valueOf(theChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(double theValue) { | |
return lessThanEqual(Double.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(float theValue) { | |
return lessThanEqual(Float.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(int theValue) { | |
return lessThanEqual(Integer.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(long theValue) { | |
return lessThanEqual(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThanEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThanEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(short theValue) { | |
return lessThanEqual(Short.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is less than and equal to the other value. | |
* This is equivalent to the SQL "<=" operator. | |
*/ | |
public Expression lessThanEqual(boolean theBoolean) { | |
return lessThanEqual(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like other value. | |
* This is equivalent to the SQL "LIKE" operator that except wildcards. | |
* The character "%" means any sequence of characters and the character "_" mean any character. | |
* i.e. "B%" == "Bob", "B_B" == "BOB" | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").like("B%") | |
* Java: NA | |
* SQL: F_NAME LIKE 'B%' | |
* </blockquote></pre> | |
*/ | |
public Expression like(String value) { | |
return like(new ConstantExpression(value, this)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like other value. | |
* This is equivalent to the SQL "LIKE ESCAPE" operator that except wildcards. | |
* The character "%" means any sequence of characters and the character "_" mean any character. | |
* i.e. "B%" == "Bob", "B_B" == "BOB" | |
* The escape sequence specifies a set of characters the may be used to indicate that | |
* an one of the wildcard characters should be interpreted literally. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").like("B\_SMITH", "\") | |
* Java: NA | |
* SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\'' | |
* </blockquote></pre> | |
*/ | |
public Expression like(String value, String escapeSequence) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LikeEscape); | |
List args = new ArrayList(2); | |
args.add(value); | |
args.add(escapeSequence); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like other value. | |
* This is equivalent to the SQL "LIKE" operator that except wildcards. | |
* The character "%" means any sequence of characters and the character "_" mean any character. | |
* i.e. "B%" == "Bob", "B_B" == "BOB" | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").like("B%") | |
* Java: NA | |
* SQL: F_NAME LIKE 'B%' | |
* </blockquote></pre> | |
*/ | |
public Expression like(Expression argument) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Like); | |
return anOperator.expressionFor(this, argument); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value matches the regular expression. | |
* This uses the databases support for regular expression. | |
* Regular expressions are similar to LIKE except support a much larger scope of comparisons. | |
* i.e. "^B.*" == "Bob", "^B.B$" == "BOB" | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").regexp("^B.*") | |
* Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches() | |
* SQL: F_NAME REGEXP '^B.*' | |
* </blockquote></pre> | |
*/ | |
public Expression regexp(String regexp) { | |
return regexp(new ConstantExpression(regexp, this)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value matches the regular expression. | |
* This uses the databases support for regular expression. | |
* Regular expressions are similar to LIKE except support a much larger scope of comparisons. | |
* i.e. "^B.*" == "Bob", "^B.B$" == "BOB" | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").regexp("^B.*") | |
* Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches() | |
* SQL: F_NAME REGEXP '^B.*' | |
* </blockquote></pre> | |
*/ | |
public Expression regexp(Expression regexp) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Regexp); | |
return anOperator.expressionFor(this, regexp); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like other value. | |
* This is equivalent to the SQL "LIKE ESCAPE" operator that except wildcards. | |
* The character "%" means any sequence of characters and the character "_" mean any character. | |
* i.e. "B%" == "Bob", "B_B" == "BOB" | |
* The escape sequence specifies a set of characters the may be used to indicate that | |
* an one of the wildcard characters should be interpreted literally. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").like("B\_SMITH", "\") | |
* Java: NA | |
* SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\'' | |
* </blockquote></pre> | |
*/ | |
public Expression like(Expression value, Expression escapeSequence) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.LikeEscape); | |
List args = new ArrayList(2); | |
args.add(value); | |
args.add(escapeSequence); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like the other value, ignoring case. | |
* This is a case in-sensitive like. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").likeIgnoreCase("%Bob%") | |
* Java: none | |
* SQL: UPPER(F_NAME) LIKE 'BOB' | |
* </blockquote></pre> | |
*/ | |
public Expression likeIgnoreCase(String theValue) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().like(theValue.toUpperCase()); | |
} else { | |
return toLowerCase().like(theValue.toLowerCase()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is like the other value, ignoring case. | |
* This is a case in-sensitive like. | |
*/ | |
public Expression likeIgnoreCase(Expression theValue) { | |
if (shouldUseUpperCaseForIgnoreCase) { | |
return toUpperCase().like(theValue.toUpperCase()); | |
} else { | |
return toLowerCase().like(theValue.toLowerCase()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the position of <code>str</code> in <code>this</code> | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").locate("ob") | |
* Java: employee.getFirstName().indexOf("ob") + 1 | |
* SQL: LOCATE('ob', t0.F_NAME) | |
* </blockquote></pre> | |
* <p> | |
* Note that while in String.locate(str) -1 is returned if not found, and the | |
* index starting at 0 if found, in SQL it is 0 if not found, and the index | |
* starting at 1 if found. | |
*/ | |
public Expression locate(Object str) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Locate); | |
List args = new ArrayList(1); | |
args.add(str); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the position of <code>str</code> in <code>this</code>, | |
* starting the search at <code>fromIndex</code>. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").locate("ob", 1) | |
* Java: employee.getFirstName().indexOf("ob", 1) + 1 | |
* SQL: LOCATE('ob', t0.F_NAME, 1) | |
* </blockquote></pre> | |
* <p> | |
* Note that while in String.locate(str) -1 is returned if not found, and the | |
* index starting at 0 if found, in SQL it is 0 if not found, and the index | |
* starting at 1 if found. | |
*/ | |
public Expression locate(String str, int fromIndex) { | |
return locate(str, Integer.valueOf(fromIndex)); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the position of <code>str</code> in <code>this</code>, | |
* starting the search at <code>fromIndex</code>. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").locate("ob", 1) | |
* Java: employee.getFirstName().indexOf("ob", 1) + 1 | |
* SQL: LOCATE('ob', t0.F_NAME, 1) | |
* </blockquote></pre> | |
* <p> | |
* Note that while in String.locate(str) -1 is returned if not found, and the | |
* index starting at 0 if found, in SQL it is 0 if not found, and the index | |
* starting at 1 if found. | |
*/ | |
public Expression locate(Object str, Object fromIndex) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Locate2); | |
List args = new ArrayList(2); | |
args.add(str); | |
args.add(fromIndex); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* This represents the aggregate function Maximum. Can be used only within Report Queries. | |
*/ | |
public Expression maximum() { | |
return getFunction(ExpressionOperator.Maximum); | |
} | |
/** | |
* PUBLIC: | |
* This represents the aggregate function Minimum. Can be used only within Report Queries. | |
*/ | |
public Expression minimum() { | |
return getFunction(ExpressionOperator.Minimum); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the decimal number of months between the two dates. | |
*/ | |
public Expression monthsBetween(Object otherDate) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.MonthsBetween); | |
return anOperator.expressionFor(this, otherDate); | |
} | |
/** | |
* PUBLIC: | |
* Return a Map.Entry containing the key and the value from a mapping that maps to a java.util.Map | |
* This expression can only be used as a return value in a ReportQuery and cannot be used as part of | |
* the WHERE clause in any query | |
* | |
* EclipseLink: eb.get("mapAttribute").mapEntry() | |
* @return | |
*/ | |
public Expression mapEntry(){ | |
MapEntryExpression expression = new MapEntryExpression(this); | |
expression.returnMapEntry(); | |
return expression; | |
} | |
/** | |
* PUBLIC: | |
* Return the key from a mapping that maps to a java.util.Map | |
* This expression can be used either in as a return value in a ReportQuery or in the WHERE clause in a query | |
* | |
* EclipseLink: eb.get("mapAttribute").mapKey() | |
* @return | |
*/ | |
public Expression mapKey(){ | |
return new MapEntryExpression(this); | |
} | |
/** | |
* PUBLIC: | |
* funcation return a date converted to a new timezone. Equivalent of the Oracle NEW_TIME function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("date").newTime("EST", "PST") | |
* Java: NA | |
* SQL: NEW_TIME(date, 'EST', 'PST') | |
* </blockquote></pre> * | |
*/ | |
public Expression newTime(String timeZoneFrom, String timeZoneTo) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NewTime); | |
List args = new ArrayList(2); | |
args.add(timeZoneFrom); | |
args.add(timeZoneTo); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the date with the next day from the source date as the day name given. | |
*/ | |
public Expression nextDay(Object dayName) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NextDay); | |
return anOperator.expressionFor(this, dayName); | |
} | |
/** | |
* PUBLIC: Returns an expression equivalent to none of <code>attributeName</code> | |
* holding true for <code>criteria</code>. | |
* <p> | |
* For every expression with an anyOf, its negation has either an allOf or a | |
* noneOf. The following two examples will illustrate as the second is the | |
* negation of the first: | |
* <p> | |
* AnyOf Example: Employees with a '613' area code phone number. | |
* <pre><blockquote> | |
* ReadAllQuery query = new ReadAllQuery(Employee.class); | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* Expression exp = employee.anyOf("phoneNumbers").get("areaCode").equal("613"); | |
* </blockquote></pre> | |
* <p> | |
* NoneOf Example: Employees with no '613' area code phone numbers. | |
* <blockquote><pre> | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* ExpressionBuilder phones = new ExpressionBuilder(); | |
* Expression exp = employee.noneOf("phoneNumbers", phones.get("areaCode").equal("613")); | |
* SQL: | |
* SELECT ... EMPLOYEE t0 WHERE NOT EXISTS (SELECT ... PHONE t1 WHERE | |
* (t0.EMP_ID = t1.EMP_ID) AND (t1.AREACODE = '613')) | |
* </blockquote></pre> | |
* <p> | |
* noneOf is the universal counterpart to the existential anyOf. To have the | |
* condition evaluated for each instance it must be put inside of a subquery, | |
* which can be expressed as not exists (any of attributeName some condition). | |
* (All x such that !y = !Exist x such that y). | |
* <p>Likewise the syntax employee.noneOf("phoneNumbers").get("areaCode").equal("613") | |
* is not supported for the <code>equal</code> must go inside a subQuery. | |
* <p> | |
* This method saves you from writing the sub query yourself. The above is | |
* equivalent to the following expression: | |
* <pre><blockquote> | |
* ExpressionBuilder employee = new ExpressionBuilder(); | |
* ExpressionBuilder phone = new ExpressionBuilder(); | |
* ReportQuery subQuery = new ReportQuery(Phone.class, phone); | |
* subQuery.retreivePrimaryKeys(); | |
* subQuery.setSelectionCriteria(phone.equal(employee.anyOf("phoneNumbers").and( | |
* phone.get("areaCode").equal("613"))); | |
* Expression exp = employee.notExists(subQuery); | |
* </blockquote></pre> | |
* @param criteria must have its own builder, as it will become the | |
* separate selection criteria of a subQuery. | |
* @return a notExists subQuery expression | |
*/ | |
public Expression noneOf(String attributeName, Expression criteria) { | |
ReportQuery subQuery = new ReportQuery(); | |
subQuery.setShouldRetrieveFirstPrimaryKey(true); | |
Expression builder = criteria.getBuilder(); | |
criteria = builder.equal(anyOf(attributeName)).and(criteria); | |
subQuery.setSelectionCriteria(criteria); | |
return notExists(subQuery); | |
} | |
/** | |
* INTERNAL: | |
* Normalize into a structure that is printable. | |
* Also compute printing information such as outer joins. | |
*/ | |
public Expression normalize(ExpressionNormalizer normalizer) { | |
//This class has no validation but we should still make the method call for consistency | |
//bug # 2956674 | |
//validation is moved into normalize to ensure that expressions are valid before we attempt to work with them | |
validateNode(); | |
return this; | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that is the boolean logical negation of the expression. | |
* This is equivalent to the SQL "NOT" operator and the Java "!" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").equal(24).not() | |
* Java: (! (employee.getAge() == 24)) | |
* SQL: NOT (AGE = 24) | |
* </blockquote></pre> | |
*/ | |
public Expression not() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Not); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(byte leftValue, byte rightValue) { | |
return notBetween(Byte.valueOf(leftValue), Byte.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(char leftChar, char rightChar) { | |
return notBetween(Character.valueOf(leftChar), Character.valueOf(rightChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(double leftValue, double rightValue) { | |
return notBetween(Double.valueOf(leftValue), Double.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(float leftValue, float rightValue) { | |
return notBetween(Float.valueOf(leftValue), Float.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(int leftValue, int rightValue) { | |
return notBetween(Integer.valueOf(leftValue), Integer.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(long leftValue, long rightValue) { | |
return notBetween(Long.valueOf(leftValue), Long.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(Object leftValue, Object rightValue) { | |
return between(leftValue, rightValue).not(); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(Expression leftExpression, Expression rightExpression) { | |
return between(leftExpression, rightExpression).not(); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not between two other values. | |
* Equivalent to between negated. | |
* @see #between(Object, Object) | |
*/ | |
public Expression notBetween(short leftValue, short rightValue) { | |
return notBetween(Short.valueOf(leftValue), Short.valueOf(rightValue)); | |
} | |
/** | |
* PUBLIC: A logical expression for the collection <code>attributeName</code> | |
* not being empty. | |
* Equivalent to <code>size(attributeName).greaterThan(0)</code> | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.notEmpty("phoneNumbers") | |
* Java: employee.getPhoneNumbers().size() > 0 | |
* SQL: SELECT ... FROM EMP t0 WHERE ( | |
* (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) > 0) | |
* </blockquote></pre> | |
* This is a case where a fast operation in java does not translate to an | |
* equally fast operation in SQL, requiring a correlated subselect. | |
* @see #size(java.lang.String) | |
*/ | |
public Expression notEmpty(String attributeName) { | |
return size(attributeName).greaterThan(0); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(byte theValue) { | |
return notEqual(Byte.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(char theChar) { | |
return notEqual(Character.valueOf(theChar)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(double theValue) { | |
return notEqual(Double.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(float theValue) { | |
return notEqual(Float.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(int theValue) { | |
return notEqual(Integer.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(long theValue) { | |
return notEqual(Long.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(Expression theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotEqual); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(short theValue) { | |
return notEqual(Short.valueOf(theValue)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not equal to the other value. | |
* This is equivalent to the SQL "<>" operator | |
* | |
* @see #equal(Object) | |
*/ | |
public Expression notEqual(boolean theBoolean) { | |
return notEqual(Boolean.valueOf(theBoolean)); | |
} | |
/** | |
* PUBLIC: | |
* Return a sub query expression. | |
* A sub query using a report query to define a subselect within another queries expression or select's where clause. | |
* The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder. | |
* <p>Example: | |
* <pre><blockquote> | |
* ExpressionBuilder builder = new ExpressionBuilder(); | |
* ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder()); | |
* subQuery.setSelectionCriteria(subQuery.getExpressionBuilder().get("name").equal(builder.get("name"))); | |
* builder.notExists(subQuery); | |
* </blockquote></pre> | |
*/ | |
public Expression notExists(ReportQuery subQuery) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotExists); | |
return anOperator.expressionFor(subQuery(subQuery)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(byte[] theBytes) { | |
List values = new ArrayList(theBytes.length); | |
for (int index = 0; index < theBytes.length; index++) { | |
values.add(Byte.valueOf(theBytes[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(char[] theChars) { | |
List values = new ArrayList(theChars.length); | |
for (int index = 0; index < theChars.length; index++) { | |
values.add(Character.valueOf(theChars[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(double[] theDoubles) { | |
List values = new ArrayList(theDoubles.length); | |
for (int index = 0; index < theDoubles.length; index++) { | |
values.add(Double.valueOf(theDoubles[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(float[] theFloats) { | |
List values = new ArrayList(theFloats.length); | |
for (int index = 0; index < theFloats.length; index++) { | |
values.add(Float.valueOf(theFloats[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(int[] theInts) { | |
List values = new ArrayList(theInts.length); | |
for (int index = 0; index < theInts.length; index++) { | |
values.add(Integer.valueOf(theInts[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(long[] theLongs) { | |
List values = new ArrayList(theLongs.length); | |
for (int index = 0; index < theLongs.length; index++) { | |
values.add(Long.valueOf(theLongs[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(Object[] theObjects) { | |
List values = new ArrayList(theObjects.length); | |
for (int index = 0; index < theObjects.length; index++) { | |
values.add(theObjects[index]); | |
} | |
return notIn(values); | |
} | |
public Expression notIn(ReportQuery subQuery) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotInSubQuery); | |
return anOperator.expressionFor(this, subQuery); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(short[] theShorts) { | |
List values = new ArrayList(theShorts.length); | |
for (int index = 0; index < theShorts.length; index++) { | |
values.add(Short.valueOf(theShorts[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression notIn(boolean[] theBooleans) { | |
List values = new ArrayList(theBooleans.length); | |
for (int index = 0; index < theBooleans.length; index++) { | |
values.add(Boolean.valueOf(theBooleans[index])); | |
} | |
return notIn(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* The collection can be a collection of constants or expressions. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
*/ | |
public Expression notIn(Collection theObjects) { | |
return notIn(new CollectionExpression(theObjects, this)); | |
} | |
public Expression notIn(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotIn); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not like the other value. | |
* Equivalent to like negated. | |
* @see #like(String) | |
*/ | |
public Expression notLike(String aString) { | |
return notLike(new ConstantExpression(aString, this)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not like the other value. | |
* Equivalent to like negated. | |
* @see #like(String) | |
*/ | |
public Expression notLike(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLike); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not like the other value. | |
* Equivalent to like negated. | |
* @param value string to compare | |
* @param escapeSequence the escape character to use | |
* @see #like(String) | |
*/ | |
public Expression notLike(String value, String escapeSequence) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLikeEscape); | |
List args = new ArrayList(2); | |
args.add(value); | |
args.add(escapeSequence); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that compares if the receivers value is not like the other value. | |
* Equivalent to like negated. | |
* @param value string to compare | |
* @param escapeSequence the escape character to use | |
* @see #like(String) | |
*/ | |
public Expression notLike(Expression value, Expression escapeSequence) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLikeEscape); | |
List args = new ArrayList(2); | |
args.add(value); | |
args.add(escapeSequence); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression representing a comparison to null | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").notNull() | |
* Java: employee.getAge() != null | |
* SQL: AGE IS NOT NULL | |
* </blockquote></pre> | |
*/ | |
public Expression notNull() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.NotNull); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that is the boolean logical combination of both expressions. | |
* This is equivalent to the SQL "OR" operator and the Java "||" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").equal("Bob").OR(employee.get("lastName").equal("Smith")) | |
* Java: (employee.getFirstName().equals("Bob")) || (employee.getLastName().equals("Smith")) | |
* SQL: F_NAME = 'Bob' OR L_NAME = 'Smith' | |
* </blockquote></pre> | |
*/ | |
public Expression or(Expression theExpression) { | |
// Allow ands with null. | |
if (theExpression == null) { | |
return this; | |
} | |
ExpressionBuilder base = getBuilder(); | |
Expression expressionToUse = theExpression; | |
// Ensure the same builder, unless a parralel query is used. | |
if ((theExpression.getBuilder() != base) && (theExpression.getBuilder().getQueryClass() == null)) { | |
expressionToUse = theExpression.rebuildOn(base); | |
} | |
if (base == this) {// Allow and to be sent to the builder. | |
return expressionToUse; | |
} | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Or); | |
return anOperator.expressionFor(this, expressionToUse); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression performOperator(ExpressionOperator anOperator, List args) { | |
return anOperator.expressionForArguments(this, args); | |
} | |
protected void postCopyIn(Map alreadyDone) { | |
} | |
/** | |
* ADVANCED: | |
* Inserts the SQL as is directly into the expression. | |
* The sql will be printed immediately after (postfixed to) the sql for | |
* <b>this</b>. | |
* Warning: Allowing an unverified SQL string to be passed into this | |
* method makes your application vulnerable to SQL injection attacks. | |
*/ | |
public Expression postfixSQL(String sqlString) { | |
ExpressionOperator anOperator = new ExpressionOperator(); | |
anOperator.setType(ExpressionOperator.FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
v.add(sqlString); | |
anOperator.printsAs(v); | |
anOperator.bePostfix(); | |
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* ADVANCED: | |
* Insert the SQL as is directly into the expression. | |
* The sql will be printed immediately before (prefixed to) the sql for | |
* <b>this</b>. | |
* Warning: Allowing an unverified SQL string to be passed into this | |
* method makes your application vulnerable to SQL injection attacks. | |
*/ | |
public Expression prefixSQL(String sqlString) { | |
ExpressionOperator anOperator = new ExpressionOperator(); | |
anOperator.setType(ExpressionOperator.FunctionOperator); | |
Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1); | |
v.add(sqlString); | |
anOperator.printsAs(v); | |
anOperator.bePrefix(); | |
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* INTERNAL: | |
* Print SQL | |
*/ | |
public abstract void printSQL(ExpressionSQLPrinter printer); | |
/** | |
* INTERNAL: | |
* Print java for project class generation | |
*/ | |
public void printJava(ExpressionJavaPrinter printer) { | |
//do nothing | |
} | |
/** | |
* INTERNAL: | |
* This expression is built on a different base than the one we want. Rebuild it and | |
* return the root of the new tree | |
* If receiver is a complex expression, use cloneUsing(newBase) instead. | |
* @see #cloneUsing(Expression newBase) | |
*/ | |
public abstract Expression rebuildOn(Expression newBase); | |
/** | |
* INTERNAL: | |
* Search the tree for any expressions (like SubSelectExpressions) that have been | |
* built using a builder that is not attached to the query. This happens in case of an Exists | |
* call using a new ExpressionBuilder(). This builder needs to be replaced with one from the query. | |
*/ | |
public abstract void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder); | |
/** | |
* ADVANCED: | |
* For Object-relational support. | |
*/ | |
public Expression ref() { | |
return getFunction(ExpressionOperator.Ref); | |
} | |
protected Expression registerIn(Map alreadyDone) { | |
Expression copy = shallowClone(); | |
alreadyDone.put(this, copy); | |
copy.postCopyIn(alreadyDone); | |
return copy; | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string with occurances of the first substring replaced with the second substring. | |
*/ | |
public Expression replace(Object stringToReplace, Object stringToReplaceWith) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Replace); | |
List args = new ArrayList(2); | |
args.add(stringToReplace); | |
args.add(stringToReplaceWith); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* return the result of this query repeated a given number of times. | |
* Equivalent of the Sybase REPLICATE function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").replicate(2) | |
* Java: NA | |
* SQL: REPLICATE(name, 2) | |
* </blockquote></pre> | |
*/ | |
public Expression replicate(int constant) { | |
return replicate(Integer.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* return the result of this query repeated a given number of times. | |
* Equivalent of the Sybase REPLICATE function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").replicate(2) | |
* Java: NA | |
* SQL: REPLICATE(name, 2) | |
* </blockquote></pre> | |
*/ | |
public Expression replicate(Object theValue) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Replicate); | |
return anOperator.expressionFor(this, theValue); | |
} | |
/** | |
* Reset cached information here so that we can be sure we're accurate. | |
*/ | |
protected void resetCache() { | |
} | |
/** | |
* PUBLIC: | |
* Function return the reverse of the query result. Equivalent of the | |
* Sybase REVERSE function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").reverse() | |
* Java: NA | |
* SQL: REVERSE(name) | |
* </blockquote></pre> | |
*/ | |
public Expression reverse() { | |
return getFunction(ExpressionOperator.Reverse); | |
} | |
/** | |
* PUBLIC: | |
* Function return a given number of characters starting at the | |
* right of a string. Equivalent to the Sybase RIGHT function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").right(2) | |
* Java: NA | |
* SQL: RIGHT(name, 2) | |
* </blockquote></pre> | |
*/ | |
public Expression right(int characters) { | |
return right(Integer.valueOf(characters)); | |
} | |
/** | |
* PUBLIC: | |
* Function return a given number of characters starting at the | |
* right of a string. Equivalent to the Sybase RIGHT function | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("name").right(2) | |
* Java: NA | |
* SQL: RIGHT(name, 2) | |
* </blockquote></pre> | |
*/ | |
public Expression right(Object characters) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Right); | |
return anOperator.expressionFor(this, characters); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string padded with the substring to the size. | |
*/ | |
public Expression rightPad(int size, Object substring) { | |
return rightPad(Integer.valueOf(size), substring); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string padded with the substring to the size. | |
*/ | |
public Expression rightPad(Object size, Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.RightPad); | |
List args = new ArrayList(2); | |
args.add(size); | |
args.add(substring); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string right trimmed for white space. | |
*/ | |
public Expression rightTrim() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.RightTrim); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string with the substring trimed from the right. | |
*/ | |
public Expression rightTrim(Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.RightTrim2); | |
return anOperator.expressionFor(this, substring); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the date rounded to the year, month or day. | |
*/ | |
public Expression roundDate(Object yearOrMonthOrDayRoundToken) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.RoundDate); | |
return anOperator.expressionFor(this, yearOrMonthOrDayRoundToken); | |
} | |
/** | |
* PUBLIC: | |
* Return whether this expression should be included in the SELECT clause if it is used | |
* in an ORDER BY clause | |
*/ | |
public boolean selectIfOrderedBy() { | |
return selectIfOrderedBy; | |
} | |
/** | |
* INTERNAL: | |
* Set the local base expression, ie the one on the other side of the operator | |
* Most types will ignore this, since they don't need it. | |
*/ | |
public void setLocalBase(Expression exp) { | |
} | |
/** | |
* PUBLIC: | |
* Set whether this expression should be included in the SELECT clause of a query | |
* that uses it in the ORDER BY clause. | |
* | |
* @param selectIfOrderedBy | |
*/ | |
public void setSelectIfOrderedBy(boolean selectIfOrderedBy) { | |
this.selectIfOrderedBy = selectIfOrderedBy; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public Expression shallowClone() { | |
Expression result = null; | |
try { | |
result = (Expression)super.clone(); | |
} catch (CloneNotSupportedException exception) { | |
throw new InternalError(exception.toString()); | |
} | |
return result; | |
} | |
/** | |
* PUBLIC: A logical expression for the size of collection <code>attributeName</code>. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.size("phoneNumbers") | |
* Java: employee.getPhoneNumbers().size() | |
* SQL: SELECT ... FROM EMP t0 WHERE ... | |
* (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) | |
* </blockquote></pre> | |
* This is a case where a fast operation in java does not translate to an | |
* equally fast operation in SQL, requiring a correlated subselect. | |
*/ | |
public Expression size(String attributeName) { | |
return SubSelectExpression.createSubSelectExpressionForCount(this, this, attributeName, null); | |
} | |
/** | |
* PUBLIC: A logical expression for the size of collection expression. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.size(Class returnType) | |
* Java: employee.getPhoneNumbers().size() | |
* SQL: SELECT ... FROM EMP t0 WHERE ... | |
* (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) | |
* </blockquote></pre> | |
* This is a case where a fast operation in java does not translate to an | |
* equally fast operation in SQL, requiring a correlated subselect. | |
*/ | |
public Expression size(Class returnType) { | |
if (((BaseExpression)this).getBaseExpression() == null){ | |
return SubSelectExpression.createSubSelectExpressionForCount(this, this, null, returnType); | |
} | |
return SubSelectExpression.createSubSelectExpressionForCount(((BaseExpression)this).getBaseExpression(), this, null, returnType); | |
} | |
/** | |
* PUBLIC: | |
* This represents the aggregate function StandardDeviation. Can be used only within Report Queries. | |
*/ | |
public Expression standardDeviation() { | |
return getFunction(ExpressionOperator.StandardDeviation); | |
} | |
/** | |
* PUBLIC: | |
* Return a sub query expression. | |
* A sub query using a report query to define a subselect within another queries expression or select's where clause. | |
* The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder. | |
* <p>Example: | |
* <pre><blockquote> | |
* ExpressionBuilder builder = new ExpressionBuilder(); | |
* ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder()); | |
* subQuery.addMaximum("salary"); | |
* builder.get("salary").equal(builder.subQuery(subQuery)); | |
* </blockquote></pre> | |
*/ | |
public Expression subQuery(ReportQuery subQuery) { | |
return new SubSelectExpression(subQuery, this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the substring from the source string. | |
* EclipseLink: employee.get("firstName").substring(1, 2) | |
* Java: NA | |
* SQL: SUBSTR(FIRST_NAME, 1, 2) | |
*/ | |
public Expression substring(int startPosition, int size) { | |
return substring(Integer.valueOf(startPosition), Integer.valueOf(size)); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the substring from the source string. | |
* EclipseLink: employee.get("firstName").substring(1, 2) | |
* Java: NA | |
* SQL: SUBSTR(FIRST_NAME, 1, 2) | |
*/ | |
public Expression substring(Object startPosition, Object size) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Substring); | |
List args = new ArrayList(2); | |
args.add(startPosition); | |
args.add(size); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the substring from the source string. | |
* EclipseLink: employee.get("firstName").substring(1) | |
* Java: NA | |
* SQL: SUBSTR(FIRST_NAME, 1) | |
*/ | |
public Expression substring(int startPosition) { | |
return substring(Integer.valueOf(startPosition)); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the substring from the source string. | |
* EclipseLink: employee.get("firstName").substring(1) | |
* Java: NA | |
* SQL: SUBSTR(FIRST_NAME, 1) | |
*/ | |
public Expression substring(Object startPosition) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.SubstringSingleArg); | |
List args = new ArrayList(1); | |
args.add(startPosition); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* This represents the aggregate function Sum. Can be used only within Report Queries. | |
*/ | |
public Expression sum() { | |
return getFunction(ExpressionOperator.Sum); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the single character string with the ascii or character set value. | |
*/ | |
public Expression toCharacter() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Chr); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns date from the string using the default format. | |
*/ | |
public Expression toDate() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToDate); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that represents the receiver value converted to a character string. | |
* This is equivalent to the SQL "TO_CHAR" operator and Java "toString" method. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("salary").toChar().equal("100000") | |
* Java: employee.getSalary().toString().equals("100000") | |
* SQL: TO_CHAR(SALARY) = '100000' | |
* </blockquote></pre> | |
*/ | |
public Expression toChar() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToChar); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that represents the receiver value converted to a character string, | |
* with the database formating options (i.e. 'year', 'yyyy', 'day', etc.). | |
* This is equivalent to the SQL "TO_CHAR" operator and Java Date API. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("startDate").toChar("day").equal("monday") | |
* Java: employee.getStartDate().getDay().equals("monday") | |
* SQL: TO_CHAR(START_DATE, 'day') = 'monday' | |
* </blockquote></pre> | |
*/ | |
public Expression toChar(String format) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToCharWithFormat); | |
return anOperator.expressionFor(this, format); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that represents the receiver value converted to lower case. | |
* This is equivalent to the SQL "LOWER" operator and Java "toLowerCase" method. | |
* This is only allowed for String attribute values. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").toLowerCase().equal("bob") | |
* Java: employee.getFirstName().toLowerCase().equals("bob") | |
* SQL: LOWER(F_NAME) = 'bob' | |
* </blockquote></pre> | |
*/ | |
public Expression toLowerCase() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToLowerCase); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the number converted from the string. | |
*/ | |
public Expression toNumber() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToNumber); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Print a debug form of the expression tree. | |
*/ | |
public String toString() { | |
try { | |
StringWriter innerWriter = new StringWriter(); | |
BufferedWriter outerWriter = new BufferedWriter(innerWriter); | |
toString(outerWriter, 0); | |
outerWriter.flush(); | |
return innerWriter.toString(); | |
} catch (IOException e) { | |
return ToStringLocalization.buildMessage("error_printing_expression", (Object[])null); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Print a debug form of the expression tree. | |
*/ | |
public void toString(BufferedWriter writer, int indent) throws IOException { | |
writer.newLine(); | |
for (int i = 0; i < indent; i++) { | |
writer.write(" "); | |
} | |
writer.write(descriptionOfNodeType()); | |
writer.write(" "); | |
writeDescriptionOn(writer); | |
writeSubexpressionsTo(writer, indent + 1); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that represents the receiver value converted to upper case. | |
* This is equivalent to the SQL "UPPER" operator and Java "toUpperCase" method. | |
* This is only allowed for String attribute values. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("firstName").toUpperCase().equal("BOB") | |
* Java: employee.getFirstName().toUpperCase().equals("BOB") | |
* SQL: UPPER(F_NAME) = 'BOB' | |
* </blockquote></pre> | |
*/ | |
public Expression toUpperCase() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ToUpperCase); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string with the first letter of each word capitalized. | |
*/ | |
public Expression toUppercaseCasedWords() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Initcap); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string with each char from the from string converted to the char in the to string. | |
*/ | |
public Expression translate(Object fromString, Object toString) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Translate); | |
List args = new ArrayList(2); | |
args.add(fromString); | |
args.add(toString); | |
return anOperator.expressionForArguments(this, args); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string trimmed for white space. | |
*/ | |
public Expression trim() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Trim); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Function, returns the string right and left trimmed for the substring. | |
*/ | |
public Expression trim(Object substring) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Trim2); | |
return anOperator.expressionForWithBaseLast(this, substring); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function, extracts a secton of XML from a larget XML document | |
* @param xpath XPath expression representing the node to be returned | |
*/ | |
public Expression extractXml(String xpath) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ExtractXml); | |
return anOperator.expressionFor(this, xpath); | |
} | |
/** | |
* PUBLIC: | |
* Extract the date part from the date/time value. | |
* EXTRACT is part of the SQL standard, so should be supported by most databases. | |
* @param part is the date part to extract, "YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND", "TIMEZONE_HOUR", "TIMEZONE_MINUTE". | |
*/ | |
public Expression extract(String part) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Extract); | |
return anOperator.expressionFor(this, literal(part)); | |
} | |
/** | |
* PUBLIC: | |
* Cast the value to the database type. | |
* CAST is part of the SQL standard, so should be supported by most databases. | |
* @param type is the database type name, this is database specific but should include, "CHAR", "VARCHAR", "NUMERIC", "INTEGER", "DATE", "TIME", "TIMESTAMP", | |
* the type may include a size and scale. | |
*/ | |
public Expression cast(String type) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Cast); | |
return anOperator.expressionFor(this, literal(type)); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function, extracts a value from an XMLType field | |
* @param xpath XPath expression | |
*/ | |
public Expression extractValue(String xpath) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ExtractValue); | |
return anOperator.expressionFor(this, xpath); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function, gets the number of nodes returned by the given xpath expression | |
* returns 0 if there are none | |
* @param xpath Xpath expression | |
*/ | |
public Expression existsNode(String xpath) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ExistsNode); | |
return anOperator.expressionFor(this, xpath); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function - evaluates to 0 if the xml is a well formed document and 1 if the document | |
* is a fragment | |
*/ | |
public Expression isFragment() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.IsFragment); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function - gets a string value from an XMLType | |
*/ | |
public Expression getStringVal() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GetStringVal); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* XMLType Function - gets a number value from an XMLType | |
*/ | |
public Expression getNumberVal() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.GetNumberVal); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* return the date truncated to the indicated datePart. Equivalent | |
* to the Sybase TRUNC function for dates | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("date").truncDate(year) | |
* Java: NA | |
* SQL: TRUNC(date, year) | |
* </blockquote></pre> */ | |
public Expression truncateDate(String datePart) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.TruncateDate); | |
return anOperator.expressionFor(this, datePart); | |
} | |
/** | |
* INTERNAL: | |
* We are given an expression that comes from a different context than the one in which this was built, | |
* e.g. it is the selection criteria of a mapping, or the criteria on which multiple tables are joined in a descriptor. | |
* We need to transform it so it refers to the objects we are dealing with, and AND it into the rest of our expression. | |
* | |
* We want to replace the original base expression with (newBase), and any parameters will be given values based | |
* on the context which (this) provides. | |
* | |
* For example, suppose that the main expression is | |
* emp.address.streetName = 'something' | |
* and we are trying to twist the selection criteria for the mapping 'address' in Employee. Because that mapping | |
* selects addresses, we will use the 'address' node as the base. Values for any parameters will come from the 'emp' node, | |
* which was the base of the original expression. Note that the values need not be constants, they can be fields. | |
* | |
* We do this by taking the tree we're trying to merge and traverse it more or less re-executing it | |
* it with the appropriate initial receiver and context. | |
* Return the root of the new expression tree. This will probably need to be AND'ed with the root of the old tree. | |
*/ | |
public Expression twist(Expression expression, Expression newBase) { | |
if (expression == null) { | |
return null; | |
} | |
return expression.twistedForBaseAndContext(newBase, this, null); | |
} | |
/** | |
* INTERNAL: | |
* Rebuild myself against the base, with the values of parameters supplied by the context | |
* expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping) | |
* into part of some larger expression. You normally would not call this directly, instead calling twist | |
* See the comment there for more details" | |
*/ | |
public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) { | |
// Will be overridden by subclasses | |
return this; | |
} | |
/** | |
* INTERNAL: | |
* Do any required validation for this node. Throw an exception for any incorrect constructs. | |
*/ | |
public void validateNode() { | |
} | |
/** | |
* PUBLIC: | |
* Function, this represents the value function, used in nestedtable | |
*/ | |
public Expression value() { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Value); | |
return anOperator.expressionFor(this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(byte constant) { | |
return value(Byte.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(char constant) { | |
return value(Character.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(double constant) { | |
return value(Double.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(float constant) { | |
return value(Float.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(int constant) { | |
return value(Integer.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(long constant) { | |
return value(Long.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(Object constant) { | |
return new ConstantExpression(constant, this); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(short constant) { | |
return value(Short.valueOf(constant)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression on the constant. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("a constant", builder.value("a constant")); | |
* </blockquote></pre> | |
*/ | |
public Expression value(boolean constant) { | |
return value(Boolean.valueOf(constant)); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression on the literal. | |
* A literal is a specific SQL syntax string that will be printed as is without quotes in the SQL. | |
* It can be useful for printing database key words or global variables. | |
* <p>Example: | |
* <pre><blockquote> | |
* reportQuery.addItem("currentTime", builder.literal("SYSDATE")); | |
* </blockquote></pre> | |
*/ | |
public Expression literal(String literal) { | |
return new LiteralExpression(literal, this); | |
} | |
/** | |
* ADVANCED: | |
* Return an expression for the alias. | |
* This allows an alias used in the select clause to be used in other clauses. | |
*/ | |
public Expression alias(String alias) { | |
return literal(alias); | |
} | |
/** | |
* INTERNAL: | |
* Return the value for in memory comparison. | |
* This is only valid for valueable expressions. | |
* New parameter added for feature 2612601 | |
* @param isObjectUnregistered true if object possibly not a clone, but is being | |
* conformed against the unit of work cache. | |
*/ | |
public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) { | |
throw QueryException.cannotConformExpression(); | |
} | |
/** | |
* INTERNAL: | |
* Return the value for in memory comparison. | |
* This is only valid for valueable expressions. | |
*/ | |
public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy) { | |
return valueFromObject(object, session, translationRow, valueHolderPolicy, false); | |
} | |
/** | |
* PUBLIC: | |
* Function, this represents the aggregate function Variance. Can be used only within Report Queries. | |
*/ | |
public Expression variance() { | |
return getFunction(ExpressionOperator.Variance); | |
} | |
/** | |
* INTERNAL: | |
* Used to print a debug form of the expression tree. | |
*/ | |
public void writeDescriptionOn(BufferedWriter writer) throws IOException { | |
writer.write("some expression"); | |
} | |
/** | |
* INTERNAL: | |
* Append the field name to the writer. Should be overridden for special operators such as functions. | |
*/ | |
protected void writeField(ExpressionSQLPrinter printer, DatabaseField field, SQLSelectStatement statement) { | |
//print ", " before each selected field except the first one | |
if (printer.isFirstElementPrinted()) { | |
printer.printString(", "); | |
} else { | |
printer.setIsFirstElementPrinted(true); | |
} | |
if (statement.requiresAliases()) { | |
if (field.getTable() != lastTable) { | |
lastTable = field.getTable(); | |
currentAlias = aliasForTable(lastTable); | |
} | |
printer.printString(currentAlias.getQualifiedNameDelimited(printer.getPlatform())); | |
printer.printString("."); | |
} | |
printer.printString(field.getNameDelimited(printer.getPlatform())); | |
//bug6070214: unique field aliases need to be generated when required. | |
if (statement.getUseUniqueFieldAliases()){ | |
printer.printString(" AS " + statement.generatedAlias(field.getNameDelimited(printer.getPlatform()))); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Append the field's alias to the writer. | |
* This is used for pessimistic locking. | |
*/ | |
protected void writeAlias(ExpressionSQLPrinter printer, DatabaseField field, SQLSelectStatement statement) { | |
//print ", " before each selected field except the first one | |
if (printer.isFirstElementPrinted()) { | |
printer.printString(", "); | |
} else { | |
printer.setIsFirstElementPrinted(true); | |
} | |
if (statement.requiresAliases()) { | |
if (field.getTable() != this.lastTable) { | |
this.lastTable = field.getTable(); | |
this.currentAlias = aliasForTable(this.lastTable); | |
} | |
printer.printString(this.currentAlias.getQualifiedNameDelimited(printer.getPlatform())); | |
} else { | |
printer.printString(field.getTable().getQualifiedNameDelimited(printer.getPlatform())); | |
} | |
} | |
/** | |
* INTERNAL: | |
* called from SQLSelectStatement.writeFieldsFromExpression(...) | |
*/ | |
public void writeFields(ExpressionSQLPrinter printer, Vector newFields, SQLSelectStatement statement) { | |
for (DatabaseField field : getSelectionFields(statement.getQuery())) { | |
newFields.add(field); | |
writeField(printer, field, statement); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Used in SQL printing. | |
*/ | |
public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException { | |
// In general, there are no sub-expressions | |
} | |
/** | |
* | |
* PUBLIC: | |
* Return an expression that is used with a comparison expression. | |
* The ANY keyword denotes that the search condition is TRUE if the comparison is TRUE | |
* for at least one of the values that is returned. If the subquery returns no value, | |
* the search condition is FALSE | |
*/ | |
public Expression any(byte[] theBytes) { | |
List values = new ArrayList(theBytes.length); | |
for (int index = 0; index < theBytes.length; index++) { | |
values.add(Byte.valueOf(theBytes[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(char[] theChars) { | |
List values = new ArrayList(theChars.length); | |
for (int index = 0; index < theChars.length; index++) { | |
values.add(Character.valueOf(theChars[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(double[] theDoubles) { | |
List values = new ArrayList(theDoubles.length); | |
for (int index = 0; index < theDoubles.length; index++) { | |
values.add(Double.valueOf(theDoubles[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(float[] theFloats) { | |
List values = new ArrayList(theFloats.length); | |
for (int index = 0; index < theFloats.length; index++) { | |
values.add(Float.valueOf(theFloats[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(int[] theInts) { | |
List values = new ArrayList(theInts.length); | |
for (int index = 0; index < theInts.length; index++) { | |
values.add(Integer.valueOf(theInts[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(long[] theLongs) { | |
List values = new ArrayList(theLongs.length); | |
for (int index = 0; index < theLongs.length; index++) { | |
values.add(Long.valueOf(theLongs[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(Object[] theObjects) { | |
List values = new ArrayList(theObjects.length); | |
for (int index = 0; index < theObjects.length; index++) { | |
values.add(theObjects[index]); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(short[] theShorts) { | |
List values = new ArrayList(theShorts.length); | |
for (int index = 0; index < theShorts.length; index++) { | |
values.add(Short.valueOf(theShorts[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression any(boolean[] theBooleans) { | |
List values = new ArrayList(theBooleans.length); | |
for (int index = 0; index < theBooleans.length; index++) { | |
values.add(Boolean.valueOf(theBooleans[index])); | |
} | |
return any(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
* @deprecated since 2.4 replaced by any(List) | |
* @see #any(List) | |
*/ | |
@Deprecated | |
public Expression any(Vector theObjects) { | |
return any((List)theObjects); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
*/ | |
public Expression any(List theObjects) { | |
return any(new ConstantExpression(theObjects, this)); | |
} | |
public Expression any(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Any); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a union expression with the subquery. | |
*/ | |
public Expression union(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Union); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a intersect expression with the subquery. | |
*/ | |
public Expression intersect(ReportQuery query) { | |
return intersect(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a intersect all expression with the subquery. | |
*/ | |
public Expression intersectAll(ReportQuery query) { | |
return intersectAll(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a intersect expression with the subquery. | |
*/ | |
public Expression intersect(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Intersect); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a except expression with the subquery. | |
*/ | |
public Expression except(ReportQuery query) { | |
return except(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a except all expression with the subquery. | |
*/ | |
public Expression exceptAll(ReportQuery query) { | |
return exceptAll(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a except expression with the subquery. | |
*/ | |
public Expression except(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Except); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a union expression with the subquery. | |
*/ | |
public Expression union(ReportQuery query) { | |
return union(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a union all expression with the subquery. | |
*/ | |
public Expression unionAll(ReportQuery query) { | |
return unionAll(subQuery(query)); | |
} | |
/** | |
* PUBLIC: | |
* Return a union all expression with the subquery. | |
*/ | |
public Expression unionAll(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.UnionAll); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a intersect all expression with the subquery. | |
*/ | |
public Expression intersectAll(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.IntersectAll); | |
return anOperator.expressionFor(this, arguments); | |
} | |
/** | |
* PUBLIC: | |
* Return a except all expression with the subquery. | |
*/ | |
public Expression exceptAll(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.ExceptAll); | |
return anOperator.expressionFor(this, arguments); | |
} | |
public Expression any(ReportQuery subQuery) { | |
return any(subQuery(subQuery)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that is used with a comparison expression. | |
* The SOME keyword denotes that the search condition is TRUE if the comparison is TRUE | |
* for at least one of the values that is returned. If the subquery returns no value, | |
* the search condition is FALSE | |
*/ | |
public Expression some(byte[] theBytes) { | |
List values = new ArrayList(theBytes.length); | |
for (int index = 0; index < theBytes.length; index++) { | |
values.add(Byte.valueOf(theBytes[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(char[] theChars) { | |
List values = new ArrayList(theChars.length); | |
for (int index = 0; index < theChars.length; index++) { | |
values.add(Character.valueOf(theChars[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(double[] theDoubles) { | |
List values = new ArrayList(theDoubles.length); | |
for (int index = 0; index < theDoubles.length; index++) { | |
values.add(Double.valueOf(theDoubles[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(float[] theFloats) { | |
List values = new ArrayList(theFloats.length); | |
for (int index = 0; index < theFloats.length; index++) { | |
values.add(Float.valueOf(theFloats[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(int[] theInts) { | |
List values = new ArrayList(theInts.length); | |
for (int index = 0; index < theInts.length; index++) { | |
values.add(Integer.valueOf(theInts[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(long[] theLongs) { | |
List values = new ArrayList(theLongs.length); | |
for (int index = 0; index < theLongs.length; index++) { | |
values.add(Long.valueOf(theLongs[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(Object[] theObjects) { | |
List values = new ArrayList(theObjects.length); | |
for (int index = 0; index < theObjects.length; index++) { | |
values.add(theObjects[index]); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(short[] theShorts) { | |
List values = new ArrayList(theShorts.length); | |
for (int index = 0; index < theShorts.length; index++) { | |
values.add(Short.valueOf(theShorts[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression some(boolean[] theBooleans) { | |
List values = new ArrayList(theBooleans.length); | |
for (int index = 0; index < theBooleans.length; index++) { | |
values.add(Boolean.valueOf(theBooleans[index])); | |
} | |
return some(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
* @deprecated since 2.4 replaced by some(List) | |
* @see #some(List) | |
*/ | |
@Deprecated | |
public Expression some(Vector theObjects) { | |
return some(new ConstantExpression(theObjects, this)); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
*/ | |
public Expression some(List theObjects) { | |
return some(new ConstantExpression(theObjects, this)); | |
} | |
public Expression some(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.Some); | |
return anOperator.expressionFor(this, arguments); | |
} | |
public Expression some(ReportQuery subQuery) { | |
return some(subQuery(subQuery)); | |
} | |
/** | |
* | |
* PUBLIC: | |
* Return an expression that is used with a comparison expression. | |
* The SOME keyword denotes that the search condition is TRUE if the comparison is TRUE | |
* for at least one of the values that is returned. If the subquery returns no value, | |
* the search condition is FALSE | |
*/ | |
public Expression all(byte[] theBytes) { | |
List values = new ArrayList(theBytes.length); | |
for (int index = 0; index < theBytes.length; index++) { | |
values.add(Byte.valueOf(theBytes[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(char[] theChars) { | |
List values = new ArrayList(theChars.length); | |
for (int index = 0; index < theChars.length; index++) { | |
values.add(Character.valueOf(theChars[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(double[] theDoubles) { | |
List values = new ArrayList(theDoubles.length); | |
for (int index = 0; index < theDoubles.length; index++) { | |
values.add(Double.valueOf(theDoubles[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(float[] theFloats) { | |
List values = new ArrayList(theFloats.length); | |
for (int index = 0; index < theFloats.length; index++) { | |
values.add(Float.valueOf(theFloats[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(int[] theInts) { | |
List values = new ArrayList(theInts.length); | |
for (int index = 0; index < theInts.length; index++) { | |
values.add(Integer.valueOf(theInts[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(long[] theLongs) { | |
List values = new ArrayList(theLongs.length); | |
for (int index = 0; index < theLongs.length; index++) { | |
values.add(Long.valueOf(theLongs[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(Object[] theObjects) { | |
List values = new ArrayList(theObjects.length); | |
for (int index = 0; index < theObjects.length; index++) { | |
values.add(theObjects[index]); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(short[] theShorts) { | |
List values = new ArrayList(theShorts.length); | |
for (int index = 0; index < theShorts.length; index++) { | |
values.add(Short.valueOf(theShorts[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
*/ | |
public Expression all(boolean[] theBooleans) { | |
List values = new ArrayList(theBooleans.length); | |
for (int index = 0; index < theBooleans.length; index++) { | |
values.add(Boolean.valueOf(theBooleans[index])); | |
} | |
return all(values); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
* @deprecated since 2.4 replaced by all(List) | |
* @see #all(List) | |
*/ | |
@Deprecated | |
public Expression all(Vector theObjects) { | |
return all((List)theObjects); | |
} | |
/** | |
* PUBLIC: | |
* Return an expression that checks if the receivers value is contained in the collection. | |
* This is equivalent to the SQL "IN" operator and Java "contains" operator. | |
* <p>Example: | |
* <pre><blockquote> | |
* EclipseLink: employee.get("age").in(ages) | |
* Java: ages.contains(employee.getAge()) | |
* SQL: AGE IN (55, 18, 30) | |
* </blockquote></pre> | |
*/ | |
public Expression all(List theObjects) { | |
return all(new ConstantExpression(theObjects, this)); | |
} | |
public Expression all(Expression arguments) { | |
ExpressionOperator anOperator = getOperator(ExpressionOperator.All); | |
return anOperator.expressionFor(this, arguments); | |
} | |
public Expression all(ReportQuery subQuery) { | |
return all(subQuery(subQuery)); | |
} | |
/** | |
* INTERNAL: | |
* Lookup the descriptor for this item by traversing its expression recursively. | |
*/ | |
public ClassDescriptor getLeafDescriptor(DatabaseQuery query, ClassDescriptor rootDescriptor, AbstractSession session) { | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* Lookup the mapping for this item by traversing its expression recursively. | |
* If an aggregate of foreign mapping is found it is traversed. | |
*/ | |
public DatabaseMapping getLeafMapping(DatabaseQuery query, ClassDescriptor rootDescriptor, AbstractSession session) { | |
return null; | |
} | |
} |