blob: 9558f11feae142d2f85846666f222a5ec30c6aa8 [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:
// Mike Norman - from Proof-of-concept, become production code
package dbws.testing.shadowddlgeneration.oldjpub;
//javase imports
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
//EclipseLink imports
import dbws.testing.shadowddlgeneration.oldjpub.PublisherException;
import dbws.testing.shadowddlgeneration.oldjpub.Util;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.IS_TYPE_OR_PACKAGE;
/**
* DML or Query Method
*/
public abstract class SqlStmtMethod extends ProcedureMethod {
protected String[] m_sqlStmtParamNames;
protected TypeClass[] m_sqlStmtParamTypes;
protected int[] m_sqlStmtParamModes;
protected String m_sqlStmt; // ? represents host variables
protected String m_sqlStmtTmp;
protected String m_sqlStmtQuoted;
protected SqlReflector m_reflector;
public SqlStmtMethod(String name, int modifiers, String sqlStmt, SqlReflector reflector)
throws SQLException, PublisherException {
super(name, null, /* overloadNumber */
modifiers, null, /* returnType */
null, /* sqlStmtParamTypes */
null, /* sqlStmtParamNames */
null, /* sqlStmtParamModes */
null, /* sqlStmtParamDefaults */
-1);
m_sqlStmt = sqlStmt;
m_reflector = reflector;
m_keepMethodName = true;
/* get method information, populate m_methods */
// System.out.println("[SqlStmtType] Method: "+methodName); //D+
/* get host variable/parameter type information */
// sqlj/semantics/sql/SimpleCheckerImpl.m4
// oracle.j2ee.ws.db.sqlrefl.Map#writePredefinedName(sqlTypecode):
// names[getJavaTypecode(sqlTypecode)]
// SqlType#m_allTypes: CLOB_TYPE "CLOB", OracleTypes.CLOB
// This loop accomplishes two tasks:
// (1) Rewrite sqlStatment in the SQLJ format, e.g.,
// Pre: sqlStmt = "select * from emp where eno=:{x NUMBER}"
// Post: sqlStmt = "select * from emp where eno=:x"
// (2) Reflect on the parameter names and types (sqlStmtParamNames, sqlStmtParamTypes)
// The refection is done by running the sqlStmt against database.
// The query used for reflection is sqlStmtTmp, e.g.,
// select * from emp where eno=?,
// derived by replacing bind variables. :{Y Z} => ?
m_sqlStmtTmp = m_sqlStmt;
ArrayList<String> sqlStmtParamNamesV = new ArrayList<String>();
ArrayList<TypeClass> sqlStmtParamTypesV = new ArrayList<TypeClass>();
ArrayList<Integer> sqlStmtParamModesV = new ArrayList<Integer>();
ArrayList<String> uniqueParamNamesV = new ArrayList<String>();
ArrayList<TypeClass> uniqueParamTypesV = new ArrayList<TypeClass>();
ArrayList<Integer> uniqueParamModesV = new ArrayList<Integer>();
Map<String, String> uniqueHash = new HashMap<String, String>();
int idx0 = m_sqlStmtTmp.lastIndexOf(":{");
int idx1 = -1;
int jdbcParamIdx = 0;
if (idx0 >= 0) {
idx1 = m_sqlStmtTmp.indexOf('}', idx0);
}
while (idx0 >= 0 && idx1 >= 0) {
jdbcParamIdx++;
String sqlStmtTmpTerm = m_sqlStmtTmp.substring(idx0 + ":{".length(), idx1);
StringTokenizer stnz = new StringTokenizer(sqlStmtTmpTerm);
boolean unique = true; // 3299079
if (stnz.countTokens() > 1) {
String paramName = SqlName.sqlIdToJavaId(stnz.nextToken(), false);
if (paramName != null) {
unique = (uniqueHash.get(paramName) == null);
}
uniqueHash.put(paramName, paramName);
sqlStmtParamNamesV.add(paramName);
if (unique) {
uniqueParamNamesV.add(paramName);
}
try {
// String schema=null;
String typeName = stnz.nextToken();
// for types like "double precision"
while (stnz.hasMoreTokens()) {
typeName += " " + stnz.nextToken();
}
String schema = null;
typeName = typeName.toUpperCase();
if (typeName.indexOf('.') > -1
&& typeName.indexOf('.') < (typeName.length() - 1)) {
schema = typeName.substring(0, typeName.indexOf('.'));
typeName = typeName.substring(typeName.indexOf('.') + 1);
}
TypeClass tmpType = m_reflector.addSqlUserType(schema, typeName,
IS_TYPE_OR_PACKAGE, false, 0, 0, null);
sqlStmtParamTypesV.add(tmpType);
if (unique) {
uniqueParamTypesV.add(tmpType);
}
}
catch (PublisherException e) {
// e.printStackTrace(); //D+
throw new SQLException(e.getMessage());
}
sqlStmtParamModesV.add(ProcedureMethod.IN);
if (unique) {
uniqueParamModesV.add(ProcedureMethod.IN);
}
m_sqlStmtTmp = m_sqlStmtTmp.substring(0, idx0) + "?"
+ m_sqlStmtTmp.substring(idx1 + 1);
m_sqlStmt = m_sqlStmt.substring(0, idx0) + ":" + jdbcParamIdx
+ m_sqlStmt.substring(idx1 + 1);
}
else {
System.err.println("needParamNameAndType " + sqlStmtTmpTerm);
}
idx0 = m_sqlStmtTmp.lastIndexOf(":{");
if (idx0 >= 0) {
idx1 = m_sqlStmtTmp.indexOf('}', idx0);
}
}
m_sqlStmtParamNames = new String[sqlStmtParamNamesV.size()];
m_sqlStmtParamTypes = new TypeClass[sqlStmtParamNamesV.size()];
m_sqlStmtParamModes = new int[sqlStmtParamNamesV.size()];
for (int j = 0; j < sqlStmtParamNamesV.size(); j++) {
int jj = sqlStmtParamNamesV.size() - j - 1;
m_sqlStmtParamNames[jj] = sqlStmtParamNamesV.get(j);
m_sqlStmtParamTypes[jj] = sqlStmtParamTypesV.get(j);
m_sqlStmtParamModes[jj] = sqlStmtParamModesV.get(j);
}
m_paramNames = new String[uniqueParamNamesV.size()];
m_paramTypes = new TypeClass[uniqueParamNamesV.size()];
m_paramModes = new int[uniqueParamNamesV.size()];
for (int j = 0; j < uniqueParamNamesV.size(); j++) {
int jj = uniqueParamNamesV.size() - j - 1;
m_paramNames[jj] = uniqueParamNamesV.get(j);
m_paramTypes[jj] = uniqueParamTypesV.get(j);
m_paramModes[jj] = uniqueParamModesV.get(j);
}
}
public String getSqlStmt() {
return m_sqlStmt;
}
public String getSqlStmtQuoted() {
if (m_sqlStmtQuoted == null) {
m_sqlStmtQuoted = Util.quote(m_sqlStmt);
}
return m_sqlStmtQuoted;
}
public String[] getSqlStmtParamNames() {
return m_sqlStmtParamNames;
}
public TypeClass[] getSqlStmtParamTypes() {
return m_sqlStmtParamTypes;
}
}