blob: 64a30d235c3c21133de4b8485c49cdfde0f6aed4 [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.platform.database.oracle.plsql;
import java.util.List;
import java.util.ListIterator;
import static java.sql.Types.OTHER;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseType;
import org.eclipse.persistence.internal.helper.SimpleDatabaseType;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sessions.DatabaseRecord;
import static org.eclipse.persistence.internal.helper.DatabaseType.DatabaseTypeHelper.databaseTypeHelper;
import static org.eclipse.persistence.internal.helper.Helper.NL;
import static org.eclipse.persistence.platform.database.jdbc.JDBCTypes.INTEGER_TYPE;
import static org.eclipse.persistence.platform.database.jdbc.JDBCTypes.NUMERIC_TYPE;
/**
* <b>PUBLIC</b>: Oracle PL/SQL types
* @author Mike Norman - michael.norman@oracle.com
* @since Oracle TopLink 11.x.x
*/
public enum OraclePLSQLTypes implements SimpleDatabaseType, OraclePLSQLType {
BinaryInteger("BINARY_INTEGER"),
Dec("DEC") ,
Int("INT"),
Natural("NATURAL"),
NaturalN("NATURALN") {
/**
* Requires an initial value.
*/
@Override
public void buildOutDeclare(StringBuilder sb, PLSQLargument outArg) {
databaseTypeHelper.declareTarget(sb, outArg, this);
sb.append(" := 1;");
// can't use Helper.cr 'cause Oracle PL/SQL parser only likes Unix-style newlines '\n'
sb.append(NL);
}
},
PLSQLBoolean("BOOLEAN") {
@Override
public int getConversionCode() {
// substitute Integer
return INTEGER_TYPE.getConversionCode();
}
@Override
public void buildInDeclare(StringBuilder sb, PLSQLargument inArg) {
databaseTypeHelper.declareTarget(sb, inArg, this);
sb.append(" := ");
sb.append(PLSQLBoolean_IN_CONV);
sb.append("(:");
sb.append(inArg.inIndex);
sb.append(");");
sb.append(NL);
}
@Override
public void buildOutAssignment(StringBuilder sb, PLSQLargument outArg, PLSQLStoredProcedureCall call) {
sb.append(" :");
sb.append(outArg.outIndex);
sb.append(" := ");
sb.append(PLSQLBoolean_OUT_CONV);
sb.append("(");
sb.append(databaseTypeHelper.buildTarget(outArg));
sb.append(");");
sb.append(NL);
}
},
PLSQLInteger("PLS_INTEGER"),
Positive("POSITIVE"),
PositiveN("POSITIVEN") {
/**
* Requires an initial value.
*/
@Override
public void buildOutDeclare(StringBuilder sb, PLSQLargument outArg) {
databaseTypeHelper.declareTarget(sb, outArg, this);
sb.append(" := 1;");
sb.append(NL);
}
},
SignType("SIGNTYPE"),
XMLType("XMLTYPE") {
@Override
public void buildInDeclare(StringBuilder sb, PLSQLargument inArg) {
buildInitialDeclare(sb, inArg);
sb.append(" := :");
sb.append(inArg.inIndex);
sb.append(";");
sb.append(NL);
}
@Override
public void buildOutDeclare(StringBuilder sb, PLSQLargument outArg) {
buildInitialDeclare(sb, outArg);
sb.append(";");
sb.append(NL);
}
protected void buildInitialDeclare(StringBuilder sb, PLSQLargument arg) {
sb.append(" ");
sb.append(arg.name);
sb.append(TARGET_SUFFIX);
sb.append(" ");
sb.append(getTypeName());
}
@Override
public int getSqlCode() {
return 2007;
}
@Override
public int getConversionCode() {
return getSqlCode();
}
},
;
private final String typeName;
OraclePLSQLTypes(String typeName) {
this.typeName = typeName;
}
@Override
public boolean isComplexDatabaseType() {
return false;
}
@Override
public int getSqlCode() {
return OTHER;
}
@Override
public int getConversionCode() {
// widest compatible type java.sql.Types.NUMERIC <-> BigDecimal
return NUMERIC_TYPE.getConversionCode();
}
@Override
public String getTypeName() {
return typeName;
}
@Override
public boolean isJDBCType() {
return false;
}
/**
* INTERNAL:
* Return the parameter index for the IN parameter.
*/
@Override
public int computeInIndex(PLSQLargument inArg, int newIndex,
ListIterator<PLSQLargument> i) {
return databaseTypeHelper.computeInIndex(inArg, newIndex);
}
/**
* INTERNAL:
* Return the parameter index for the OUT parameter.
*/
@Override
public int computeOutIndex(PLSQLargument outArg, int newIndex,
ListIterator<PLSQLargument> i) {
return databaseTypeHelper.computeOutIndex(outArg, newIndex);
}
/**
* INTERNAL:
* Append the variable declaration for the type.
*/
@Override
public void buildInDeclare(StringBuilder sb, PLSQLargument inArg) {
databaseTypeHelper.declareTarget(sb, inArg, this);
sb.append(" := :");
sb.append(inArg.inIndex);
sb.append(";");
sb.append(NL);
}
/**
* INTERNAL:
* Append the variable declaration for the type.
*/
@Override
public void buildOutDeclare(StringBuilder sb, PLSQLargument outArg) {
databaseTypeHelper.declareTarget(sb, outArg, this);
sb.append(";");
sb.append(NL);
}
/**
* INTERNAL:
* Append any code or translation required for the type.
*/
@Override
public void buildBeginBlock(StringBuilder sb, PLSQLargument arg, PLSQLStoredProcedureCall call) {
// nothing to do for simple types
}
/**
* INTERNAL:
* Append any code or translation for assigning the output value.
*/
@Override
public void buildOutAssignment(StringBuilder sb, PLSQLargument arg, PLSQLStoredProcedureCall call) {
databaseTypeHelper.buildOutAssignment(sb, arg, call);
}
/**
* INTERNAL:
* Translate the argument value from the query translation row to call translation row.
*/
@Override
public void translate(PLSQLargument arg, AbstractRecord translationRow,
AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
List<DatabaseField> translationRowFields, List translationRowValues, StoredProcedureCall call) {
databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
copyOfTranslationFields, translationRowFields, translationRowValues, call);
}
/**
* INTERNAL:
* Build the query output row from the call output row.
*/
@Override
public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
databaseTypeHelper.buildOutputRow(outArg, outputRow,
newOutputRow, outputRowFields, outputRowValues);
}
/**
* INTERNAL:
* Append the parameter for logging purposes.
*/
@Override
public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
AbstractRecord translationRow, DatabasePlatform platform) {
databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
}
public static DatabaseType getDatabaseTypeForCode(String typeName) {
DatabaseType databaseType = null;
if (BinaryInteger.typeName.equalsIgnoreCase(typeName)) {
databaseType = BinaryInteger;
}
else if (Dec.typeName.equalsIgnoreCase(typeName)) {
databaseType = Dec;
}
else if (Int.typeName.equalsIgnoreCase(typeName)) {
databaseType = Int;
}
else if (Natural.typeName.equalsIgnoreCase(typeName)) {
databaseType = Natural;
}
else if (NaturalN.typeName.equalsIgnoreCase(typeName)) {
databaseType = NaturalN;
}
else if (PLSQLBoolean.typeName.equalsIgnoreCase(typeName) ||
"BOOLEAN".equalsIgnoreCase(typeName)) {
databaseType = PLSQLBoolean;
}
else if (PLSQLInteger.typeName.equalsIgnoreCase(typeName)) {
databaseType = PLSQLInteger;
}
else if (Positive.typeName.equalsIgnoreCase(typeName)) {
databaseType = Positive;
}
else if (PositiveN.typeName.equalsIgnoreCase(typeName)) {
databaseType = PositiveN;
}
else if (SignType.typeName.equalsIgnoreCase(typeName)) {
databaseType = SignType;
} else if (XMLType.typeName.equalsIgnoreCase(typeName)) {
databaseType = XMLType;
}
return databaseType;
}
}