blob: 6f00c10b78377a85b183d9f6b9e570c016617e2e [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 IBM Corporation. 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
// Markus KARG - Added methods allowing to support stored procedure creation on SQLAnywherePlatform.
package org.eclipse.persistence.tools.schemaframework;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Vector;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.sessions.AbstractSession;
/**
* <b>Purpose</b>: Allow a semi-generic way of creating stored procedures.
*/
public class StoredProcedureDefinition extends DatabaseObjectDefinition {
protected List<FieldDefinition> variables;
protected List<String> statements;
protected List<FieldDefinition> arguments;
protected List<Integer> argumentTypes;
protected static final Integer IN = 1;
protected static final Integer OUT = 2;
protected static final Integer INOUT = 3;
public StoredProcedureDefinition() {
this.statements = new Vector<>();
this.variables = new Vector<>();
this.arguments = new Vector<>();
this.argumentTypes = new Vector<>();
}
/**
* The arguments are the names of the parameters to the procedure.
*/
public void addArgument(String argumentName, Class type) {
addArgument(new FieldDefinition(argumentName, type));
}
/**
* The arguments are the names of the parameters to the procedure.
*/
public void addArgument(String argumentName, Class type, int size) {
addArgument(new FieldDefinition(argumentName, type, size));
}
/**
* The arguments are the names of the parameters to the procedure.
*/
public void addArgument(String argumentName, String typeName) {
addArgument(new FieldDefinition(argumentName, typeName));
}
/**
* The arguments are the names of the parameters to the procedure.
*/
public void addArgument(FieldDefinition argument) {
getArguments().add(argument);
getArgumentTypes().add(IN);
}
/**
* The output arguments are used to get values back from the proc.
*/
public void addInOutputArgument(String argumentName, Class type) {
addInOutputArgument(new FieldDefinition(argumentName, type));
}
/**
* The output arguments are used to get values back from the proc, such as cursors.
*/
public void addInOutputArgument(FieldDefinition argument) {
getArguments().add(argument);
getArgumentTypes().add(INOUT);
}
/**
* The output arguments are used to get values back from the proc.
*/
public void addOutputArgument(String argumentName, Class type) {
addOutputArgument(new FieldDefinition(argumentName, type));
}
/**
* The output arguments are used to get values back from the proc.
*/
public void addOutputArgument(String argumentName, Class type, int size) {
addOutputArgument(new FieldDefinition(argumentName, type, size));
}
/**
* The output arguments are used to get values back from the proc, such as cursors.
*/
public void addOutputArgument(String argumentName, String typeName) {
addOutputArgument(new FieldDefinition(argumentName, typeName));
}
/**
* The output arguments are used to get values back from the proc, such as cursors.
*/
public void addOutputArgument(FieldDefinition argument) {
getArguments().add(argument);
getArgumentTypes().add(OUT);
}
/**
* The statements are the SQL lines of code in procedure.
*/
public void addStatement(String statement) {
getStatements().add(statement);
}
/**
* The variables are the names of the declared variables used in the procedure.
*/
public void addVariable(String variableName, String typeName) {
this.addVariable(new FieldDefinition(variableName, typeName));
}
/**
* The variables are the names of the declared variables used in the procedure.
*/
public void addVariable(FieldDefinition variable) {
getVariables().add(variable);
}
/**
* INTERNAL: Return the create table statement.
*/
@Override
public Writer buildCreationWriter(AbstractSession session, Writer writer) throws ValidationException {
try {
DatabasePlatform platform = session.getPlatform();
writer.write(getCreationHeader() + getFullName());
if (getArguments().size() > getFirstArgumentIndex() || platform.requiresProcedureBrackets()) {
writer.write(" (");
}
writer.write("\n");
for (int i = getFirstArgumentIndex(); i < getArguments().size(); i++) {
writer.write("\t");
FieldDefinition argument = getArguments().get(i);
Integer argumentType = getArgumentTypes().get(i);
if (argumentType == IN) {
printArgument(argument, writer, session);
} else if (argumentType == OUT) {
printOutputArgument(argument, writer, session);
} else if (argumentType == INOUT) {
printInOutputArgument(argument, writer, session);
}
if (i < (getArguments().size() - 1)) {
writer.write(",\n");
}
}
if (getArguments().size() > getFirstArgumentIndex() || platform.requiresProcedureBrackets()) {
writer.write(")");
}
printReturn(writer, session);
writer.write(platform.getProcedureAsString());
writer.write("\n");
writer.write(platform.getProcedureOptionList());
writer.write("\n");
if (platform.shouldPrintStoredProcedureVariablesAfterBeginString()) {
writer.write(platform.getProcedureBeginString());
writer.write("\n");
}
if (!getVariables().isEmpty()) {
writer.write("DECLARE\n");
}
for (FieldDefinition field: getVariables()) {
writer.write("\t");
writer.write(field.getName());
writer.write(" ");
writer.write(field.getTypeName());
writer.write(platform.getBatchDelimiterString());
writer.write("\n");
}
if (!platform.shouldPrintStoredProcedureVariablesAfterBeginString()) {
writer.write(platform.getProcedureBeginString());
writer.write("\n");
}
for (String statement: getStatements()) {
writer.write(statement);
writer.write(platform.getBatchDelimiterString());
writer.write("\n");
}
writer.write(platform.getProcedureEndString());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL: Return the drop table statement.
*/
@Override
public Writer buildDeletionWriter(AbstractSession session, Writer writer) throws ValidationException {
try {
writer.write(getDeletionHeader() + getFullName());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* The arguments are the names of the parameters to the procedure.
*/
public List<FieldDefinition> getArguments() {
return arguments;
}
/**
*
*/
public String getCreationHeader() {
return "CREATE PROCEDURE ";
}
/**
*
*/
public String getDeletionHeader() {
return "DROP PROCEDURE ";
}
/**
*
*/
public int getFirstArgumentIndex() {
return 0;
}
/**
*
*/
public List<Integer> getArgumentTypes() {
return argumentTypes;
}
/**
* The statements are the SQL lines of code in procedure.
*/
public List<String> getStatements() {
return statements;
}
/**
* The variables are the names of the declared variables used in the procedure.
*/
public List<FieldDefinition> getVariables() {
return variables;
}
/**
* Print the argument and its type.
* @param argument Stored procedure argument.
* @param writer Target writer where to write argument string.
* @param session Current session context.
* @throws IOException When any IO problem occurs.
*/
protected void printArgument(final FieldDefinition argument, final Writer writer,
final AbstractSession session) throws IOException {
final DatabasePlatform platform = session.getPlatform();
final FieldTypeDefinition fieldType
= getFieldTypeDefinition(session, argument.type, argument.typeName);
writer.write(platform.getProcedureArgumentString());
if (platform.shouldPrintInputTokenAtStart()) {
writer.write(" ");
writer.write(platform.getInputProcedureToken());
writer.write(" ");
}
writer.write(argument.name);
writer.write(" ");
writer.write(fieldType.getName());
if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
&& ((argument.size != 0) || (fieldType.isSizeRequired()))) {
writer.write("(");
if (argument.size == 0) {
writer.write(Integer.toString(fieldType.getDefaultSize()));
} else {
writer.write(Integer.toString(argument.size));
}
if (argument.subSize != 0) {
writer.write(",");
writer.write(Integer.toString(argument.subSize));
} else if (fieldType.getDefaultSubSize() != 0) {
writer.write(",");
writer.write(Integer.toString(fieldType.getDefaultSubSize()));
}
writer.write(")");
}
}
/**
* Print the argument and its type.
* @param argument Stored procedure argument.
* @param writer Target writer where to write argument string.
* @param session Current session context.
* @throws ValidationException When invalid or inconsistent data were found.
*/
protected void printInOutputArgument(final FieldDefinition argument, final Writer writer,
final AbstractSession session) throws ValidationException {
try {
final DatabasePlatform platform = session.getPlatform();
final FieldTypeDefinition fieldType
= getFieldTypeDefinition(session, argument.type, argument.typeName);
writer.write(platform.getProcedureArgumentString());
if (platform.shouldPrintOutputTokenAtStart()) {
writer.write(" ");
writer.write(platform.getCreationInOutputProcedureToken());
writer.write(" ");
}
writer.write(argument.name);
if ((!platform.shouldPrintOutputTokenAtStart()) && platform.shouldPrintOutputTokenBeforeType()) {
writer.write(" ");
writer.write(platform.getCreationInOutputProcedureToken());
}
writer.write(" ");
writer.write(fieldType.getName());
if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
&& ((argument.size != 0) || (fieldType.isSizeRequired()))) {
writer.write("(");
if (argument.size == 0) {
writer.write(Integer.toString(fieldType.getDefaultSize()));
} else {
writer.write(Integer.toString(argument.size));
}
if (argument.subSize != 0) {
writer.write(",");
writer.write(Integer.toString(argument.subSize));
} else if (fieldType.getDefaultSubSize() != 0) {
writer.write(",");
writer.write(Integer.toString(fieldType.getDefaultSubSize()));
}
writer.write(")");
}
if ((!platform.shouldPrintOutputTokenAtStart()) && (!platform.shouldPrintOutputTokenBeforeType())) {
writer.write(" ");
writer.write(platform.getCreationInOutputProcedureToken());
}
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
}
/**
* Print the argument and its type.
* @param argument Stored procedure argument.
* @param writer Target writer where to write argument string.
* @param session Current session context.
* @throws ValidationException When invalid or inconsistent data were found.
*/
protected void printOutputArgument(final FieldDefinition argument, final Writer writer,
final AbstractSession session) throws ValidationException {
try {
final DatabasePlatform platform = session.getPlatform();
final FieldTypeDefinition fieldType
= getFieldTypeDefinition(session, argument.type, argument.typeName);
writer.write(platform.getProcedureArgumentString());
if (platform.shouldPrintOutputTokenAtStart()) {
writer.write(" ");
writer.write(platform.getCreationOutputProcedureToken());
writer.write(" ");
}
writer.write(argument.name);
if ((!platform.shouldPrintOutputTokenAtStart()) && platform.shouldPrintOutputTokenBeforeType()) {
writer.write(" ");
writer.write(platform.getCreationOutputProcedureToken());
}
writer.write(" ");
writer.write(fieldType.getName());
if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
&& ((argument.size != 0) || (fieldType.isSizeRequired()))) {
writer.write("(");
if (argument.size == 0) {
writer.write(Integer.toString(fieldType.getDefaultSize()));
} else {
writer.write(Integer.toString(argument.size));
}
if (argument.subSize != 0) {
writer.write(",");
writer.write(Integer.toString(argument.subSize));
} else if (fieldType.getDefaultSubSize() != 0) {
writer.write(",");
writer.write(Integer.toString(fieldType.getDefaultSubSize()));
}
writer.write(")");
}
if ((!platform.shouldPrintOutputTokenAtStart()) && !platform.shouldPrintOutputTokenBeforeType()) {
writer.write(" ");
writer.write(platform.getCreationOutputProcedureToken());
}
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
}
/**
* Prints return for stored function, nothing to do for stored procedure
*/
protected void printReturn(Writer writer, AbstractSession session) throws ValidationException {
}
/**
* The arguments are the field defs of the parameters names and types to the procedure.
*/
public void setArguments(List<FieldDefinition> arguments) {
this.arguments = arguments;
}
/**
* The statements are the SQL lines of code in procedure.
*/
public void setStatements(List<String> statements) {
this.statements = statements;
}
/**
* The variables are the field defs of the declared variables used in the procedure.
*/
public void setVariables(List<FieldDefinition> variables) {
this.variables = variables;
}
}