| /* |
| * 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; |
| |
| /** |
| * <b>Purpose:</b>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<Expression> lockedExpressions; |
| |
| public ForUpdateOfClause() { |
| } |
| |
| public void addLockedExpression(ObjectExpression expression) { |
| getLockedExpressions().add(expression); |
| } |
| |
| public void addLockedExpression(FieldExpression expression) { |
| getLockedExpressions().add(expression); |
| } |
| |
| public List<Expression> 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<Expression> 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<Expression> 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<expAliases.length; i++) { |
| aliases.add(expAliases[i]); |
| } |
| } |
| return aliases; |
| } |
| } |