| /* |
| * 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.io.*; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Vector; |
| import java.util.Collection; |
| |
| import org.eclipse.persistence.exceptions.*; |
| import org.eclipse.persistence.queries.*; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.internal.databaseaccess.DatabaseCall; |
| import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform; |
| import org.eclipse.persistence.internal.helper.DatabaseField; |
| import org.eclipse.persistence.internal.helper.DatabaseTable; |
| import java.util.Map; |
| |
| /** |
| * @author Andrei Ilitchev |
| * @since TOPLink/Java 1.0 |
| */ |
| public class SQLUpdateAllStatementForOracleAnonymousBlock extends SQLModifyStatement { |
| protected HashMap tables_databaseFieldsToValues; |
| protected HashMap tablesToPrimaryKeyFields; |
| protected SQLCall selectCall; |
| |
| protected static final String varSuffix = "_VAR"; |
| protected static final String typeSuffix = "_TYPE"; |
| protected static final String tab = " "; |
| protected static final String dbltab = tab + tab; |
| protected static final String trpltab = dbltab + tab; |
| |
| public void setSelectCall(SQLCall selectCall) { |
| this.selectCall = selectCall; |
| } |
| public SQLCall getSelectCall() { |
| return selectCall; |
| } |
| public void setTablesToPrimaryKeyFields(HashMap tablesToPrimaryKeyFields) { |
| this.tablesToPrimaryKeyFields = tablesToPrimaryKeyFields; |
| } |
| public HashMap getTablesToPrimaryKeyFields() { |
| return tablesToPrimaryKeyFields; |
| } |
| public void setTables_databaseFieldsToValues(HashMap tables_databaseFieldsToValues) { |
| this.tables_databaseFieldsToValues = tables_databaseFieldsToValues; |
| } |
| public HashMap getTables_databaseFieldsToValues() { |
| return tables_databaseFieldsToValues; |
| } |
| |
| /** |
| * Append the string containing the SQL insert string for the given table. |
| */ |
| @Override |
| public DatabaseCall buildCall(AbstractSession session) { |
| SQLCall call = new SQLCall(); |
| call.returnNothing(); |
| |
| Writer writer = new CharArrayWriter(100); |
| |
| Vector mainPrimaryKeys = new Vector(); |
| mainPrimaryKeys.addAll((Collection)tablesToPrimaryKeyFields.get(table)); |
| |
| Vector allFields = (Vector)mainPrimaryKeys.clone(); |
| Iterator itDatabaseFieldsToValues = tables_databaseFieldsToValues.values().iterator(); |
| while(itDatabaseFieldsToValues.hasNext()) { |
| Iterator itDatabaseFields = ((HashMap)itDatabaseFieldsToValues.next()).keySet().iterator(); |
| while(itDatabaseFields.hasNext()) { |
| allFields.addElement(itDatabaseFields.next()); |
| } |
| } |
| |
| try { |
| //DECLARE |
| writer.write("DECLARE\n"); |
| |
| for(int i=0; i < allFields.size(); i++) { |
| writeDeclareTypeAndVar(writer, (DatabaseField)allFields.elementAt(i), session.getPlatform()); |
| } |
| |
| //BEGIN |
| writer.write("BEGIN\n"); |
| |
| // select t0.emp_id, concat('Even', t0.f_name), t1.salary + 1000 BULK COLLECT into EMPLOYEEE_EMP_ID_VAR, EMPLOYEEE_F_NAME_VAR, SALARY_SALARY_VAR from employee t0, salary t1 where t0.l_name like 'updateEmployeeTestUsingTempTable' and t0.f_name in ('0', '2') and t1.salary = 0 and t0.emp_id = t1.emp_id; |
| String selectStr = selectCall.getSQLString(); |
| int index = selectStr.toUpperCase().indexOf(" FROM "); |
| String firstPart = selectStr.substring(0, index); |
| String secondPart = selectStr.substring(index, selectStr.length()); |
| |
| writer.write(tab); |
| writer.write(firstPart); |
| writer.write(" BULK COLLECT INTO "); |
| |
| for(int i=0; i < allFields.size(); i++) { |
| writeVar(writer, (DatabaseField)allFields.elementAt(i), session.getPlatform()); |
| if(i < allFields.size() - 1) { |
| writer.write(", "); |
| } |
| } |
| writer.write(secondPart); |
| writer.write(";\n"); |
| |
| call.getParameters().addAll(selectCall.getParameters()); |
| call.getParameterTypes().addAll(selectCall.getParameterTypes()); |
| |
| DatabaseField firstMainPrimaryKey = (DatabaseField)mainPrimaryKeys.firstElement(); |
| writer.write(tab); |
| writer.write("IF "); |
| writeVar(writer, firstMainPrimaryKey, session.getPlatform()); |
| writer.write(".COUNT > 0 THEN\n"); |
| |
| Iterator itEntries = tables_databaseFieldsToValues.entrySet().iterator(); |
| while(itEntries.hasNext()) { |
| writeForAll(writer, firstMainPrimaryKey, session.getPlatform()); |
| writer.write(trpltab); |
| writer.write("UPDATE "); |
| Map.Entry entry = (Map.Entry)itEntries.next(); |
| DatabaseTable t = (DatabaseTable)entry.getKey(); |
| writer.write(t.getQualifiedNameDelimited(session.getPlatform())); |
| writer.write(" SET "); |
| HashMap databaseFieldsToValues = (HashMap)entry.getValue(); |
| int counter = 0; |
| Iterator itDatabaseFields = databaseFieldsToValues.keySet().iterator(); |
| while(itDatabaseFields.hasNext()) { |
| counter++; |
| DatabaseField field = (DatabaseField)itDatabaseFields.next(); |
| writer.write(field.getNameDelimited(session.getPlatform())); |
| writer.write(" = "); |
| writeVar(writer, field, session.getPlatform()); |
| writer.write("(i)"); |
| if(counter < databaseFieldsToValues.size()) { |
| writer.write(", "); |
| } |
| } |
| |
| writer.write(" WHERE "); |
| |
| Vector tablePrimaryKeys = new Vector(); |
| tablePrimaryKeys.addAll((Collection)tablesToPrimaryKeyFields.get(t)); |
| for(int i=0; i < mainPrimaryKeys.size(); i++) { |
| DatabaseField tableField = (DatabaseField)tablePrimaryKeys.elementAt(i); |
| writer.write(tableField.getNameDelimited(session.getPlatform())); |
| writer.write(" = "); |
| DatabaseField mainField = (DatabaseField )mainPrimaryKeys.elementAt(i); |
| writeVar(writer, mainField, session.getPlatform()); |
| writer.write("(i)"); |
| if(i < mainPrimaryKeys.size()-1) { |
| writer.write(" AND "); |
| } else { |
| writer.write(";\n"); |
| } |
| } |
| } |
| |
| writer.write(tab); |
| writer.write("END IF;\n"); |
| |
| writer.write(tab); |
| DatabaseField outField = new DatabaseField("ROW_COUNT"); |
| outField.setType(Integer.class); |
| call.appendOut(writer, outField); |
| writer.write(" := "); |
| writeVar(writer, firstMainPrimaryKey, session.getPlatform()); |
| writer.write(".COUNT;\n"); |
| |
| writer.write("END;"); |
| |
| call.setSQLString(writer.toString()); |
| |
| } catch (IOException exception) { |
| throw ValidationException.fileError(exception); |
| } |
| |
| return call; |
| } |
| |
| protected static void writeUniqueFieldName(Writer writer, DatabaseField field, DatasourcePlatform platform) throws IOException { |
| // EMPLOYEE_EMP_ID |
| writer.write(field.getTable().getNameDelimited(platform)); |
| writer.write("_"); |
| writer.write(field.getNameDelimited(platform)); |
| } |
| |
| protected static void writeType(Writer writer, DatabaseField field, DatasourcePlatform platform) throws IOException { |
| // EMPLOYEE_EMP_ID_TYPE |
| writeUniqueFieldName(writer, field, platform); |
| writer.write(typeSuffix); |
| } |
| |
| protected static void writeVar(Writer writer, DatabaseField field, DatasourcePlatform platform) throws IOException { |
| // EMPLOYEE_EMP_ID_VAR |
| writeUniqueFieldName(writer, field, platform); |
| writer.write(varSuffix); |
| } |
| |
| protected static void writeDeclareTypeAndVar(Writer writer, DatabaseField field, DatasourcePlatform platform) throws IOException { |
| // TYPE EMPLOYEE_EMP_ID_TYPE IS TABLE OF EMPLOYEE.EMP_ID%TYPE; |
| writer.write(tab); |
| writer.write("TYPE "); |
| writeType(writer, field, platform); |
| writer.write(" IS TABLE OF "); |
| writer.write(field.getQualifiedName()); |
| writer.write("%TYPE;\n"); |
| |
| // EMPLOYEE_EMP_ID_VAR EMP_ID_TYPE; |
| writer.write(tab); |
| writeVar(writer, field, platform); |
| writer.write(" "); |
| writeType(writer, field, platform); |
| writer.write(";\n"); |
| } |
| |
| protected static void writeForAll(Writer writer, DatabaseField field, DatasourcePlatform platform) throws IOException { |
| //FORALL i IN EMPLOYEE_EMP_ID_VAR.FIRST..EMPLOYEE_EMP_ID_VAR.LAST |
| writer.write(dbltab); |
| writer.write("FORALL i IN "); |
| writeVar(writer, field, platform); |
| writer.write(".FIRST.."); |
| writeVar(writer, field, platform); |
| writer.write(".LAST\n"); |
| } |
| } |