org.eclipse.persistence.internal.expressions.ForUpdateOfClause Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2020 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.internal.expressions;
import java.util.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
/**
* Purpose:Represents The FOR UPDATE OF fine-grained pessimistically
* locking clause.
* @author Stephen McRitchie
* @since Oracle Toplink 10g AS
*/
public class ForUpdateOfClause extends ForUpdateClause {
protected List lockedExpressions;
public ForUpdateOfClause() {
}
public void addLockedExpression(ObjectExpression expression) {
getLockedExpressions().add(expression);
}
public void addLockedExpression(FieldExpression expression) {
getLockedExpressions().add(expression);
}
public List getLockedExpressions() {
if (lockedExpressions == null) {
lockedExpressions = new ArrayList();
}
return lockedExpressions;
}
@Override
public boolean isForUpdateOfClause() {
return true;
}
@Override
public boolean isReferenceClassLocked() {
if (this.lockedExpressions == null) {
return false;
}
// Normally the expressionBuilder is stored first but not necessarily
// when a child ForUpdateOfClause is built for a nested query, or if a
//user made this clause.
int size = this.lockedExpressions.size();
for (int i = 0; i < size; i++) {
if (this.lockedExpressions.get(i).isExpressionBuilder()) {
return true;
}
}
return false;
}
public void setLockedExpressions(List lockedExpressions) {
this.lockedExpressions = lockedExpressions;
}
public void setLockMode(short lockMode) {
this.lockMode = lockMode;
}
/**
* INTERNAL:
* Prints the as of clause for an expression inside of the FROM clause.
*/
@Override
public void printSQL(ExpressionSQLPrinter printer, SQLSelectStatement statement) {
// assert(lockedExpressions != null && lockedExpressions.size() > 0);
// assert( getLockMode() == ObjectBuildingQuery.LOCK ||
// getLockMode() == ObjectBuildingQuery.LOCK_NOWAIT);
if(printer.getSession().getPlatform().shouldPrintLockingClauseAfterWhereClause()) {
ExpressionBuilder clonedBuilder = statement.getBuilder();
printer.printString(printer.getSession().getPlatform().getSelectForUpdateOfString());
printer.setIsFirstElementPrinted(false);
for (Expression next : getLockedExpressions()) {
// Necessary as this was determined in query framework.
next = next.rebuildOn(clonedBuilder);
if(next.isObjectExpression()) {
ObjectExpression objectExp = (ObjectExpression)next;
objectExp.writeForUpdateOfFields(printer, statement);
} else {
// must be FieldExpression
FieldExpression fieldExp = (FieldExpression)next;
fieldExp.writeForUpdateOf(printer, statement);
}
}
if (lockMode == ObjectBuildingQuery.LOCK_NOWAIT) {
printer.printString(printer.getSession().getPlatform().getNoWaitString());
}
} else {
super.printSQL(printer, statement);
}
}
/**
* INTERNAL:
* Returns collection of aliases of the tables to be locked.
* Only used by platforms that lock tables individually in FROM clause
* (platform.shouldPrintLockingClauseAfterWhereClause()==false)
* like SQLServer
*/
@Override
public Collection getAliasesOfTablesToBeLocked(SQLSelectStatement statement) {
int expected = statement.getTableAliases().size();
HashSet aliases = new HashSet(expected);
ExpressionBuilder clonedBuilder = statement.getBuilder();
Iterator iterator = getLockedExpressions().iterator();
while (iterator.hasNext() && aliases.size() < expected) {
Expression next = iterator.next();
// Necessary as this was determined in query framework.
next = next.rebuildOn(clonedBuilder);
// next is either ObjectExpression or FieldExpression
if(next.isFieldExpression()) {
next = ((FieldExpression)next).getBaseExpression();
}
DatabaseTable[] expAliases = next.getTableAliases().keys();
for (int i=0; i