| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 2021 IBM Corporation. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // 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.io.BufferedWriter; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.io.StringWriter; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.IdentityHashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.exceptions.QueryException; |
| import org.eclipse.persistence.history.AsOfClause; |
| import org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression; |
| import org.eclipse.persistence.internal.expressions.BaseExpression; |
| import org.eclipse.persistence.internal.expressions.CollectionExpression; |
| import org.eclipse.persistence.internal.expressions.ConstantExpression; |
| import org.eclipse.persistence.internal.expressions.ExpressionIterator; |
| import org.eclipse.persistence.internal.expressions.ExpressionJavaPrinter; |
| import org.eclipse.persistence.internal.expressions.ExpressionNormalizer; |
| import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter; |
| import org.eclipse.persistence.internal.expressions.FunctionExpression; |
| import org.eclipse.persistence.internal.expressions.LiteralExpression; |
| import org.eclipse.persistence.internal.expressions.MapEntryExpression; |
| import org.eclipse.persistence.internal.expressions.ParameterExpression; |
| import org.eclipse.persistence.internal.expressions.SQLSelectStatement; |
| import org.eclipse.persistence.internal.expressions.SubSelectExpression; |
| import org.eclipse.persistence.internal.expressions.TableAliasLookup; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.internal.helper.DatabaseField; |
| import org.eclipse.persistence.internal.helper.DatabaseTable; |
| import org.eclipse.persistence.internal.localization.ToStringLocalization; |
| import org.eclipse.persistence.internal.sessions.AbstractRecord; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| import org.eclipse.persistence.queries.DatabaseQuery; |
| import org.eclipse.persistence.queries.ReadQuery; |
| import org.eclipse.persistence.queries.ReportQuery; |
| |
| /** |
| * <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> |
| */ |
| 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 |
| */ |
| protected 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) |
| * </pre></blockquote> |
| */ |
| 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) |
| * </pre></blockquote> |
| */ |
| 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"); |
| * </pre></blockquote> |
| * <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')) |
| * </pre></blockquote> |
| * <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); |
| * </pre></blockquote> |
| * <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 {@literal "&&"} operator. |
| * <p>Example: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").equal("Bob").and(employee.get("lastName").equal("Smith")) |
| * Java: (employee.getFirstName().equals("Bob")) {@literal &&} (employee.getLastName().equals("Smith")) |
| * SQL: F_NAME = 'Bob' AND L_NAME = 'Smith' |
| * </pre></blockquote> |
| */ |
| 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> |
| * <caption>This table compares an example EclipseLink anyOf Expression to Java and SQL</caption> |
| * <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> |
| * <caption>This table compares an example EclipseLink anyOf Expression to Java and SQL</caption> |
| * <tr> |
| * <th id="c3">Format</th> |
| * <th id="c4">Equivalent</th> |
| * </tr> |
| * <tr> |
| * <td headers="c3">EclipseLink</td> |
| * <td headers="c4"> |
| * <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="c3">Java</td> |
| * <td headers="c4">No direct equivalent</td> |
| * </tr> |
| * <tr> |
| * <td headers="c3">SQL</td> |
| * <td headers="c4">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> |
| * </tr> |
| * </table> |
| * @param 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> |
| * <caption>This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL</caption> |
| * <tr> |
| * <th id="c5">Format</th> |
| * <th id="c6">Equivalent</th> |
| * </tr> |
| * <tr> |
| * <td headers="c5">EclipseLink</td> |
| * <td headers="c6"> |
| * <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="c5">Java</td> |
| * <td headers="c6">No direct equivalent</td> |
| * </tr> |
| * <tr> |
| * <td headers="c5">SQL</td> |
| * <td headers="c6">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> |
| * <caption>This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL</caption> |
| * <tr> |
| * <th id="c7">Format</th> |
| * <th id="c8">Equivalent</th> |
| * </tr> |
| * <tr> |
| * <td headers="c7">EclipseLink</td> |
| * <td headers="c8"> |
| * <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="c7">Java</td> |
| * <td headers="c8">No direct equivalent</td> |
| * </tr> |
| * <tr> |
| * <td headers="c7">SQL</td> |
| * <td headers="c8">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td> |
| * </tr> |
| * </table> |
| * @param shouldJoinBeIndependent indicates whether a new expression should be created. |
| */ |
| public Expression anyOfAllowingNone(String attributeName, boolean shouldJoinBeIndependent) { |
| throw new UnsupportedOperationException("anyOfAllowingNone"); |
| } |
| |
| /** |
| * 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: |
| * <blockquote><pre> |
| * 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" |
| * </pre></blockquote> |
| */ |
| 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()) |
| * </pre></blockquote> |
| */ |
| 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()) |
| * </pre></blockquote> |
| */ |
| 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()) |
| * </pre></blockquote> |
| */ |
| 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 {@literal <=} pastTime) AND ((t1.END IS NULL) OR t1.END {@literal >} 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)); |
| * </pre></blockquote> |
| * <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"))); |
| * </pre></blockquote> |
| * <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")); |
| * </pre></blockquote> |
| * <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 {@literal ">=", "<=;"} operators. |
| * <p>Example: |
| * <pre> |
| * EclipseLink: employee.get("age").between(19,50) |
| * Java: (employee.getAge() {@literal >=} 19) {@literal &&} (employee.getAge() {@literal <=} 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(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" |
| * </pre></blockquote> |
| * @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: |
| * <blockquote><pre> |
| * SQL: CASE name WHEN "Robert" THEN "Bob" |
| * WHEN "Susan" THEN "Sue" |
| * ELSE "No-Nickname" |
| * </pre></blockquote> |
| * |
| * 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" |
| * </pre></blockquote> |
| * @param caseConditions 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: |
| * <blockquote><pre> |
| * SQL: CASE WHEN name = "Robert" THEN "Bob" |
| * WHEN name = "Susan" THEN "Sue" |
| * ELSE "No-Nickname" |
| * </pre></blockquote> |
| * |
| * 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") |
| * </pre></blockquote> |
| * @param object 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) |
| * </pre></blockquote> |
| * @param expressions 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. |
| */ |
| @Override |
| 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) |
| */ |
| public Expression cloneUsing(Expression newBase) { |
| // 2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS |
| // 2612567 CR4298- NULLPOINTEREXCEPTION WHEN USING SUBQUERY AND BATCH READING IN 4.6 |
| // 2612140 CR2973- BATCHATTRIBUTE QUERIES WILL FAIL WHEN THE INITIAL QUERY HAS A SUBQUERY |
| // 2720149 INVALID SQL WHEN USING BATCH READS AND MULTIPLE ANYOFS |
| // 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") |
| * </pre></blockquote> |
| */ |
| 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") |
| * </pre></blockquote> |
| */ |
| 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%' |
| * </pre></blockquote> |
| */ |
| 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%' |
| * </pre></blockquote> |
| */ |
| 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%' |
| * </pre></blockquote> |
| */ |
| 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%' |
| * </pre></blockquote> |
| */ |
| 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() { |
| @Override |
| 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) |
| * </pre></blockquote> |
| */ |
| 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) |
| * </pre></blockquote> |
| */ |
| 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) |
| * </pre></blockquote> |
| */ |
| 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) |
| * </pre></blockquote> |
| */ |
| 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") |
| * </pre></blockquote> |
| * @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(); |
| |
| List<String> v = new ArrayList<>(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()) |
| * </pre></blockquote> |
| */ |
| 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') |
| * </pre></blockquote> |
| */ |
| 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. |
| */ |
| @Override |
| 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. |
| */ |
| @Override |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").equal("Bob") |
| * Java: employee.getFirstName().equals("Bob") |
| * SQL: F_NAME = 'Bob' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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 |
| * </pre></blockquote> |
| * @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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob") |
| * Java: employee.getFirstName().equalsIgnoreCase("Bob") |
| * SQL: UPPER(F_NAME) = 'BOB' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob") |
| * Java: employee.getFirstName().equalsIgnoreCase("Bob") |
| * SQL: UPPER(F_NAME) = 'BOB' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * builder.get("address").get("city").equal("Ottawa"); |
| * </pre></blockquote> |
| */ |
| public Expression get(String attributeName) { |
| return get(attributeName, true); |
| } |
| |
| /** |
| * 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: |
| * <blockquote><pre> |
| * builder.get("address", false).get("city").equal("Ottawa"); |
| * </pre></blockquote> |
| * @param forceInnerJoin - allows the get to not force an inner-join (if getAllowingNull was used elsewhere). |
| */ |
| public Expression get(String attributeName, boolean forceInnerJoin) { |
| 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: |
| * <blockquote><pre> |
| * builder.getAllowingNull("address").get("city").equal("Ottawa"); |
| * </pre></blockquote> |
| */ |
| 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"); |
| * </pre></blockquote> |
| */ |
| 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); |
| * </pre></blockquote> |
| */ |
| public Expression getField(DatabaseField field) { |
| throw QueryException.illegalUseOfGetField(field); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public List<DatabaseField> getFields() { |
| return new ArrayList<>(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: |
| * <blockquote><pre> |
| * Expression address = employee.getAllowingNull("address"); |
| * employee.join(address, address.get("city").equal("Ottawa")); |
| * query.addNonFetchJoin(address); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * Expression address = employee.getAllowingNull("address"); |
| * employee.leftJoin(address, address.get("city").equal("Ottawa")); |
| * query.addNonFetchJoin(address); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * builder.get("name").getFunction(MyFunctions.FOO_BAR).greaterThan(100); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * List arguments = new ArrayList(); |
| * arguments.add("blee"); |
| * builder.get("name").getFunction(MyFunctions.FOO_BAR, arguments).greaterThan(100); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * List arguments = new ArrayList(); |
| * arguments.add("blee"); |
| * builder.get("name").operator("FOO_BAR", arguments).greaterThan(100); |
| * </pre></blockquote> |
| */ |
| 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: |
| * 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: |
| * <blockquote><pre> |
| * builder.get("firstName").getFunction("UPPER"); |
| * </pre></blockquote> |
| */ |
| 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, ...). |
| */ |
| public Expression getFunctionWithArguments(String functionName, List arguments) { |
| ExpressionOperator anOperator = new ExpressionOperator(); |
| anOperator.setType(ExpressionOperator.FunctionOperator); |
| List<String> v = new ArrayList<>(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); |
| List<String> v = new ArrayList<>(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: |
| * <blockquote><pre> |
| * builder.getClassForInheritance().equal(SmallProject.class); |
| * builder.anyOf("projects").getClassForInheritance().equal(builder.getParameter("projectClass")); |
| * </pre></blockquote> |
| */ |
| 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(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: |
| * <blockquote><pre> |
| * builder.getTable("PROJ_EMP").getField("TYPE").equal("S"); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * builder.getTable(linkTable).getField("TYPE").equal("S"); |
| * </pre></blockquote> |
| */ |
| public Expression getTable(DatabaseTable table) { |
| throw QueryException.illegalUseOfGetTable(table); |
| } |
| |
| /** |
| * ADVANCED: Return an expression representing a sub-select in the from clause. |
| * <p> Example: |
| * <blockquote><pre> |
| * builder.getAlias(builder.subQuery(reportQuery)).get("type").equal("S"); |
| * </pre></blockquote> |
| */ |
| 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 {@literal ">"} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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 {@literal ">="} 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").ifNull("no-name") |
| * Java: NA |
| * SQL: NVL(name, 'no-name') |
| * </pre></blockquote> |
| */ |
| 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(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(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(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(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(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(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(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(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").in(ages) |
| * Java: ages.contains(employee.getAge()) |
| * SQL: AGE IN (55, 18, 30) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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))) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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) |
| * </pre></blockquote> |
| * 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<"} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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 {@literal "<="} 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").like("B%") |
| * Java: NA |
| * SQL: F_NAME LIKE 'B%' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").like("B\_SMITH", "\") |
| * Java: NA |
| * SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\'' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").like("B%") |
| * Java: NA |
| * SQL: F_NAME LIKE 'B%' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").regexp("^B.*") |
| * Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches() |
| * SQL: F_NAME REGEXP '^B.*' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").regexp("^B.*") |
| * Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches() |
| * SQL: F_NAME REGEXP '^B.*' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").like("B\_SMITH", "\") |
| * Java: NA |
| * SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\'' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").likeIgnoreCase("%Bob%") |
| * Java: none |
| * SQL: UPPER(F_NAME) LIKE 'BOB' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").locate("ob") |
| * Java: employee.getFirstName().indexOf("ob") + 1 |
| * SQL: LOCATE('ob', t0.F_NAME) |
| * </pre></blockquote> |
| * <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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").locate("ob", 1) |
| * Java: employee.getFirstName().indexOf("ob", 1) + 1 |
| * SQL: LOCATE('ob', t0.F_NAME, 1) |
| * </pre></blockquote> |
| * <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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").locate("ob", 1) |
| * Java: employee.getFirstName().indexOf("ob", 1) + 1 |
| * SQL: LOCATE('ob', t0.F_NAME, 1) |
| * </pre></blockquote> |
| * <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() |
| */ |
| 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() |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("date").newTime("EST", "PST") |
| * Java: NA |
| * SQL: NEW_TIME(date, 'EST', 'PST') |
| * </pre></blockquote> |
| */ |
| 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. |
| * <blockquote><pre> |
| * ReadAllQuery query = new ReadAllQuery(Employee.class); |
| * ExpressionBuilder employee = new ExpressionBuilder(); |
| * Expression exp = employee.anyOf("phoneNumbers").get("areaCode").equal("613"); |
| * </pre></blockquote> |
| * <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')) |
| * </pre></blockquote> |
| * <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: |
| * <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").equal("613"))); |
| * Expression exp = employee.notExists(subQuery); |
| * </pre></blockquote> |
| * @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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").equal(24).not() |
| * Java: (! (employee.getAge() == 24)) |
| * SQL: NOT (AGE = 24) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.notEmpty("phoneNumbers") |
| * Java: employee.getPhoneNumbers().size() {@literal >} 0 |
| * SQL: SELECT ... FROM EMP t0 WHERE ( |
| * (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) {@literal >} 0) |
| * </pre></blockquote> |
| * 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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 {@literal "<>"} 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: |
| * <blockquote><pre> |
| * 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); |
| * </pre></blockquote> |
| */ |
| 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(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(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(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(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(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(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(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(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").in(ages) |
| * Java: ages.contains(employee.getAge()) |
| * SQL: AGE IN (55, 18, 30) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").notNull() |
| * Java: employee.getAge() != null |
| * SQL: AGE IS NOT NULL |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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' |
| * </pre></blockquote> |
| */ |
| 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); |
| List<String> v = new ArrayList<>(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); |
| List<String> v = new ArrayList<>(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").replicate(2) |
| * Java: NA |
| * SQL: REPLICATE(name, 2) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").replicate(2) |
| * Java: NA |
| * SQL: REPLICATE(name, 2) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").reverse() |
| * Java: NA |
| * SQL: REVERSE(name) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").right(2) |
| * Java: NA |
| * SQL: RIGHT(name, 2) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("name").right(2) |
| * Java: NA |
| * SQL: RIGHT(name, 2) |
| * </pre></blockquote> |
| */ |
| 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. |
| * |
| */ |
| 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: |
| * <blockquote><pre> |
| * 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)) |
| * </pre></blockquote> |
| * 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: |
| * <blockquote><pre> |
| * 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)) |
| * </pre></blockquote> |
| * 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: |
| * <blockquote><pre> |
| * ExpressionBuilder builder = new ExpressionBuilder(); |
| * ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder()); |
| * subQuery.addMaximum("salary"); |
| * builder.get("salary").equal(builder.subQuery(subQuery)); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("salary").toChar().equal("100000") |
| * Java: employee.getSalary().toString().equals("100000") |
| * SQL: TO_CHAR(SALARY) = '100000' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("startDate").toChar("day").equal("monday") |
| * Java: employee.getStartDate().getDay().equals("monday") |
| * SQL: TO_CHAR(START_DATE, 'day') = 'monday' |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").toLowerCase().equal("bob") |
| * Java: employee.getFirstName().toLowerCase().equals("bob") |
| * SQL: LOWER(F_NAME) = 'bob' |
| * </pre></blockquote> |
| */ |
| 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. |
| */ |
| @Override |
| 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", 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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("firstName").toUpperCase().equal("BOB") |
| * Java: employee.getFirstName().toUpperCase().equals("BOB") |
| * SQL: UPPER(F_NAME) = 'BOB' |
| * </pre></blockquote> |
| */ |
| 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.expressionFor(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("date").truncDate(year) |
| * Java: NA |
| * SQL: TRUNC(date, year) |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(byte constant) { |
| return value(Byte.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(char constant) { |
| return value(Character.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(double constant) { |
| return value(Double.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(float constant) { |
| return value(Float.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(int constant) { |
| return value(Integer.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(long constant) { |
| return value(Long.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(Object constant) { |
| return new ConstantExpression(constant, this); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| public Expression value(short constant) { |
| return value(Short.valueOf(constant)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return an expression on the constant. |
| * <p>Example: |
| * <blockquote><pre> |
| * reportQuery.addItem("a constant", builder.value("a constant")); |
| * </pre></blockquote> |
| */ |
| 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: |
| * <blockquote><pre> |
| * reportQuery.addItem("currentTime", builder.literal("SYSDATE")); |
| * </pre></blockquote> |
| */ |
| 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, List<DatabaseField> 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(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(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(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(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(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(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(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(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").in(ages) |
| * Java: ages.contains(employee.getAge()) |
| * SQL: AGE IN (55, 18, 30) |
| * </pre></blockquote> |
| */ |
| 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(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(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(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(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(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(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(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(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").in(ages) |
| * Java: ages.contains(employee.getAge()) |
| * SQL: AGE IN (55, 18, 30) |
| * </pre></blockquote> |
| */ |
| 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(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(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(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(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(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(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(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(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: |
| * <blockquote><pre> |
| * EclipseLink: employee.get("age").in(ages) |
| * Java: ages.contains(employee.getAge()) |
| * SQL: AGE IN (55, 18, 30) |
| * </pre></blockquote> |
| */ |
| 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; |
| } |
| |
| } |