blob: c7a50a3c3b77a6da64e881980cd0bbe0dd99cba2 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 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
package org.eclipse.persistence.history;
import java.io.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.expressions.*;
import org.eclipse.persistence.internal.helper.*;
/**
* <b>Purpose:</b>Wraps an immutable value for a past time.
* A session, query, or expression can be as of a past time.
* <p>
* For Oracle 9R2 Flasback corresponds to the sub clause which appears between
* the table and alias name in the FROM clause:
* <code>SELECT ... FROM EMPLOYEE AS OF TIMESTAMP (value) t0, ...</code>
* </p><p>For generic historical schema support, a special criteria can be added to
* the where clause for each table in a select:
* <code>((t0.ROW_START {@literal <=} value) AND ((t0.END IS NULL) OR (t1.END {@literal >} value)))</code>
* </p><p><b>Responsibilities:</b></p>
* <ul>
* <li>By default AsOfClause is a timestamp. To specify a system change number use AsOfSCNClause.
* <li>For Oracle 9R2 Flashback prints the correct AS OF clause before the alias name in the FROM clause.
* <li>Read-only: the wrapped value can not change.
* </ul>
* @since OracleAS TopLink 10<i>g</i> (10.0.3)
* @author Stephen McRitchie
* @see org.eclipse.persistence.expressions.Expression#asOf(AsOfClause)
* @see org.eclipse.persistence.queries.ObjectLevelReadQuery#setAsOfClause(AsOfClause)
* @see org.eclipse.persistence.sessions.Session#acquireHistoricalSession(AsOfClause)
* @see HistoryPolicy
*/
public class AsOfClause implements Serializable {
public static final AsOfClause NO_CLAUSE = new AsOfClause((Expression)null);
private Object value;
protected AsOfClause() {
}
public AsOfClause(java.util.Date date) {
this.value = date;
}
public AsOfClause(java.sql.Timestamp timestamp) {
this.value = timestamp;
}
public AsOfClause(java.util.Calendar calendar) {
this.value = calendar;
}
public AsOfClause(long time) {
this.value = time;
}
public AsOfClause(Long time) {
this.value = time;
}
protected AsOfClause(Number number) {
this.value = number;
}
public AsOfClause(Expression expression) {
this.value = expression;
}
protected AsOfClause(AsOfClause wrappedValue) {
this.value = wrappedValue;
}
/**
* INTERNAL:
* Return if the as of is equal to the other.
* Equality of asOf clauses is complex (with subclasses),
* so only use identity.
*/
@Override
public boolean equals(Object object) {
return this == object;
}
/**
* INTERNAL:
* Prints the as of clause for an expression inside of the FROM clause.
*/
public void printSQL(ExpressionSQLPrinter printer) {
printer.printString("AS OF TIMESTAMP (");
Object value = getValue();
if (value instanceof Expression) {
// Sort of an implementation of native sql.
// Print AS OF TIMESTAMP (SYSDATE - 1000*60*10) not AS OF ('SYSDATE - 1000*60*10').
if ((value instanceof ConstantExpression) && (((ConstantExpression)value).getValue() instanceof String)) {
printer.printString((String)((ConstantExpression)value).getValue());
} else {
printer.printExpression((Expression)value);
}
} else {
ConversionManager converter = ConversionManager.getDefaultManager();
value = converter.convertObject(value, ClassConstants.TIMESTAMP);
printer.printPrimitive(value);
}
printer.printString(")");
}
/**
* PUBLIC:
* The past time represented by the receiver. Either a timestamp, a system
* change number, or an Expression.
*/
public Object getValue() {
return value;
}
/**
* PUBLIC:
* Indicates that <code>value</code> is a system change number or an expression
* evaluating to one.
* <p>In Oracle the value will have to be printed using the syntax <code>AS OF SCN(value)</code>
* instead of <code>AS OF TIMESTAMP(value)</code>.
* @see AsOfSCNClause
*/
public boolean isAsOfSCNClause() {
return false;
}
/**
* PUBLIC:
* Answers if this is a UniversalAsOfClause, one to be applied
* to the entire selection criteria.
* <p>Used when a query is made as of a past time.
*/
public boolean isUniversal() {
return false;
}
@Override
public String toString() {
StringWriter writer = new StringWriter();
writer.write(Helper.getShortClassName(getClass()));
writer.write("(");
writer.write(String.valueOf(getValue()));
writer.write(")");
return writer.toString();
}
}