blob: 02576018eeec03b5627247294e92bb2108449e85 [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.testing.tests.returning.model;
import java.math.*;
import java.util.*;
import java.io.StringWriter;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.ReturningPolicy;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.queries.SQLCall;
// This adapter requires project of type ReturningProject");
public class AdapterForReturningProject extends AdapterWithReturnObjectControl {
static class InsertInfo {
InsertInfo(boolean isReadOnly, boolean isSequence, boolean overrideNullOnly, Object value) {
this.isReadOnly = isReadOnly;
this.isSequence = isSequence;
this.overrideNullOnly = overrideNullOnly;
this.value = value;
}
boolean isReadOnly;
boolean isSequence;
boolean overrideNullOnly;
Object value;
}
static class UpdateInfo {
UpdateInfo(boolean overrideNullOnly, Object value) {
this.overrideNullOnly = overrideNullOnly;
this.value = value;
}
boolean overrideNullOnly;
Object value;
}
Hashtable insertInfos = new Hashtable();
Hashtable updateInfos = new Hashtable();
public void addInsert(String qualifiedName, Object value) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
insertInfos.put(field, new InsertInfo(false, false, false, value));
}
public void addInsert(String qualifiedName, Object value, boolean overrideNullOnly) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
insertInfos.put(field, new InsertInfo(false, false, overrideNullOnly, value));
}
public void addInsertReadOnly(String qualifiedName, Object value) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
insertInfos.put(field, new InsertInfo(false, false, false, value));
}
public void addInsertSequence(String qualifiedName) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
insertInfos.put(field, new InsertInfo(false, true, false, new BigDecimal(0)));
}
public void addInsertSequenceReadOnly(String qualifiedName) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
insertInfos.put(field, new InsertInfo(true, true, false, new BigDecimal(0)));
}
public void addUpdate(String qualifiedName, Object value) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
updateInfos.put(field, new UpdateInfo(false, value));
}
public void addUpdate(String qualifiedName, Object value, boolean overrideNullOnly) {
DatabaseField field = new DatabaseField(qualifiedName);
field.setType(java.math.BigDecimal.class);
updateInfos.put(field, new UpdateInfo(overrideNullOnly, value));
}
@Override
public void updateProject(Project project, Session session) {
ClassDescriptor desc = project.getClassDescriptor(Class1.class);
if (!desc.hasReturningPolicy()) {
desc.setReturningPolicy(new ReturningPolicy());
}
Enumeration insertFields = insertInfos.keys();
while (insertFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)insertFields.nextElement();
InsertInfo info = (InsertInfo)insertInfos.get(field);
if (info.isReadOnly) {
desc.getReturningPolicy().addFieldForInsertReturnOnly(field);
} else {
desc.getReturningPolicy().addFieldForInsert(field);
}
}
Enumeration updateFields = updateInfos.keys();
while (updateFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)updateFields.nextElement();
UpdateInfo info = (UpdateInfo)updateInfos.get(field);
desc.getReturningPolicy().addFieldForUpdate(field);
}
}
@Override
public void updateDatabase(Session session) {
createSequence(session);
createInsertTrigger(session);
createUpdateTriggers(session);
}
protected void createSequence(Session session) {
Enumeration insertFields = insertInfos.keys();
while (insertFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)insertFields.nextElement();
InsertInfo info = (InsertInfo)insertInfos.get(field);
if (info.isSequence) {
String seqName = field.getTableName() + "_" + field.getName() + "_SEQ";
try {
session.executeNonSelectingCall(new SQLCall("DROP SEQUENCE " + seqName));
} catch (Exception e) {
}
session.executeNonSelectingCall(new SQLCall("CREATE SEQUENCE " + seqName));
}
}
}
protected void createInsertTrigger(Session session) {
StringWriter writer = new StringWriter();
writer.write("CREATE OR REPLACE TRIGGER RETURNING_TRIGGER_INS BEFORE INSERT ON RETURNING FOR EACH ROW ");
writer.write("BEGIN\n");
Enumeration insertFields = insertInfos.keys();
while (insertFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)insertFields.nextElement();
InsertInfo info = (InsertInfo)insertInfos.get(field);
if (info.overrideNullOnly) {
writer.write(" IF :new." + field.getName() + " IS NULL THEN\n ");
}
if (info.isSequence) {
String seqName = field.getTableName() + "_" + field.getName() + "_SEQ";
writer.write(" SELECT " + seqName + ".NEXTVAL INTO :new." + field.getName() + " FROM DUAL;\n");
} else {
if (info.value == null) {
writer.write(" :new." + field.getName() + " := null;\n");
} else {
writer.write(" :new." + field.getName() + " := " + info.value + ";\n");
}
}
if (info.overrideNullOnly) {
writer.write(" END IF;\n");
}
}
writer.write("END;");
String str = writer.toString();
DataModifyQuery query = new DataModifyQuery(new SQLCall(str));
query.setShouldBindAllParameters(false);
session.executeQuery(query);
}
protected void createUpdateTriggers(Session session) {
Enumeration updateFields = updateInfos.keys();
while (updateFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)updateFields.nextElement();
UpdateInfo info = (UpdateInfo)updateInfos.get(field);
createUpdateTrigger(session, field, info);
}
}
protected void createUpdateTrigger(Session session, DatabaseField field, UpdateInfo info) {
StringWriter writer = new StringWriter();
writer.write("CREATE OR REPLACE TRIGGER RETURNING_TRIGGER_UPD_" + field.getName() + " BEFORE UPDATE OF " + field.getName() + " ON RETURNING FOR EACH ROW ");
writer.write("BEGIN\n");
if (info.overrideNullOnly) {
writer.write(" IF :new." + field.getName() + " IS NULL THEN\n ");
}
if (info.value == null) {
writer.write(" :new." + field.getName() + " := null;\n");
} else {
writer.write(" :new." + field.getName() + " := " + info.value + ";\n");
}
if (info.overrideNullOnly) {
writer.write(" END IF;\n");
}
writer.write("END;");
String str = writer.toString();
DataModifyQuery query = new DataModifyQuery(new SQLCall(str));
query.setShouldBindAllParameters(false);
session.executeQuery(query);
}
@Override
protected DataRecord getRowForInsert(DataRecord rowToInsert) {
DataRecord row = new DatabaseRecord();
Enumeration insertFields = insertInfos.keys();
while (insertFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)insertFields.nextElement();
InsertInfo info = (InsertInfo)insertInfos.get(field);
Object valueIn = rowToInsert.get(field);
if (!info.overrideNullOnly || valueIn == null) {
row.put(field, info.value);
}
}
return row;
}
@Override
protected DataRecord getRowForUpdate(DataRecord rowChange) {
DataRecord row = new DatabaseRecord();
Enumeration updateFields = updateInfos.keys();
while (updateFields.hasMoreElements()) {
DatabaseField field = (DatabaseField)updateFields.nextElement();
UpdateInfo info = (UpdateInfo)updateInfos.get(field);
if (rowChange.containsKey(field)) {
Object valueIn = rowChange.get(field);
if (!info.overrideNullOnly || valueIn == null) {
row.put(field, info.value);
}
}
}
return row;
}
}