Github user mashengchen commented on a diff in the pull request:
https://github.com/apache/trafodion/pull/1535#discussion_r185398568
--- Diff:
core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java
---
@@ -0,0 +1,393 @@
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// @@@ END COPYRIGHT @@@
+
+package org.trafodion.jdbc.t4;
+
+import java.math.BigDecimal;
+import java.sql.BatchUpdateException;
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.logging.Level;
+
+public class TrafT4MultiQueriesPreparedStatement extends
TrafT4PreparedStatement {
+
+ private String[] sqlArr = null;
+ private TrafT4PreparedStatement[] pstmtArr = null;
+ private int[][] paramDescs = null;
+
+ private int currentSqlIndex;
+
+ TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection,
String sql) throws SQLException {
+ this(connection, sql, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
+ TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
+ if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection.props_,
connection, sql);
+ connection.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
+ }
+ }
+
+ TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection,
String sql, String stmtLabel) throws SQLException {
+ this(connection, sql, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
+ TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
+ if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection.props_,
connection, sql, stmtLabel);
+ connection.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
+ }
+ }
+
+ TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection,
String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException {
+ this(connection, sql, resultSetType, resultSetConcurrency,
connection.holdability_, null);
+ if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection.props_,
connection, sql, resultSetType,
+ resultSetConcurrency);
+ connection.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
+ }
+ }
+
+ TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection,
String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability) throws
SQLException {
+ this(connection, sql, resultSetType, resultSetConcurrency,
resultSetHoldability, null);
+ if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection.props_,
connection, sql, resultSetType,
+ resultSetConcurrency, resultSetHoldability);
+ connection.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
+ }
+
+ }
+
+ TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection,
String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability, String
stmtLabel) throws SQLException {
+ super(connection, sql, resultSetType, resultSetConcurrency,
resultSetHoldability, stmtLabel);
+ if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection.props_,
connection, sql, resultSetType,
+ resultSetConcurrency, resultSetHoldability, stmtLabel);
+ connection.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
+ }
+
+ if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType
!= ResultSet.TYPE_SCROLL_INSENSITIVE
+ && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
+ throw TrafT4Messages.createSQLException(connection_.props_,
connection_.getLocale(),
+ "invalid_resultset_type", null);
+ }
+ if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
+ throw TrafT4Messages.createSQLException(connection_.props_,
connection_.getLocale(),
+ "invalid_resultset_concurrency", null);
+ }
+ if ((resultSetHoldability != 0) && (resultSetHoldability !=
ResultSet.CLOSE_CURSORS_AT_COMMIT)
+ && (resultSetHoldability !=
ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
+ throw TrafT4Messages.createSQLException(connection_.props_,
connection_.getLocale(), "invalid_holdability",
+ null);
+ }
+
+ sqlArr = sql.split(";");
+ pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
+ paramDescs = new int[sqlArr.length][3];
+ int total = 0;
+ int currentParamsLen = 0;
+ for (int i = 0; i < sqlArr.length; i++) {
+ pstmtArr[i] = new TrafT4PreparedStatement(connection,
sqlArr[i], resultSetType, resultSetConcurrency,
+ resultSetHoldability, stmtLabel);
+ pstmtArr[i].prepare(sqlArr[i], queryTimeout_,
resultSetHoldability_);
+
+ // this is to setup the paramDescs, each paramDesc has 3
column,
+ // 1: index of preparedStatement
+ // 2: num of params for current pstmt
+ // 3: accumulated params for current index
+ // this varible is used when there invoking setXXX api
+ if (pstmtArr[i].inputDesc_ != null) {
+ currentParamsLen = pstmtArr[i].inputDesc_.length;
+ total += currentParamsLen;
+ }
+ int[] paramDesc = { i, currentParamsLen, total };
+ paramDescs[i] = paramDesc;
+
+ }
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
sql);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "execute", "", p);
+ }
+ sqlArr = sql.split(";");
+ pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
+
+ boolean result = false;
+
+ return result;
+ }
+
+ // this method will return a 2 column array.
+ // first column means the index of preparedStatement
+ // second column means the real parameter index of the column one
preparedStatement
+ // eg:
+ // insert into tbl values (?,?);insert into tbl values (?,?,?);insert
into tbl values (?,?)
+ // the paramDescs is {0,2,2},{1,3,5},{2,2,7} , when use setXXX(6, x);
+ // there will return {2,1} , means set param for the 1st param of the
3rd sql.
+ private int[] getCurrentParamIndex(int paramIndex) {
+ if (paramIndex < 1 || paramIndex > paramDescs[paramDescs.length -
1][2]) {
+ return new int[] { 0, paramIndex };
+ }
+ for (int i = 0; i < paramDescs.length; i++) {
+ if (paramIndex > paramDescs[i][2]) {
+ continue;
+ } else {
+ int index = paramIndex - (paramDescs[i][2] -
paramDescs[i][1]);
+ return new int[] { i, index };
+ }
+ }
+
+ return new int[] { 0, paramIndex };
+
+ }
+
+ public void setObject(int parameterIndex, Object x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setObject", "", p);
+ }
+ int[] paramIndex = getCurrentParamIndex(parameterIndex);
+ pstmtArr[paramIndex[0]].setObject(paramIndex[1], x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ @Override
+ public void setDouble(int parameterIndex, double x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ @Override
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ @Override
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws
SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setString", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte[] x) throws SQLException
{
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_,
parameterIndex, x);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
+ }
+ setObject(parameterIndex, x);
+ }
+
+ public void addBatch() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "addBatch", "", p);
+ }
+ for (int i = 0; i < pstmtArr.length; i++) {
+ pstmtArr[i].addBatch();
+ }
+ }
+
+ public int[] executeBatch() throws SQLException, BatchUpdateException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "executeBatch", "", p);
+ }
+ currentSqlIndex = 0;
+
+ int[] results = null;
+ for (int i = 0; i < pstmtArr.length; i++) {
+ int[] result = pstmtArr[i].executeBatch();
+ if (results == null) {
+ results = result;
+ } else {
+ int[] tmp = new int[results.length + result.length];
+ System.arraycopy(results, 0, tmp, 0, results.length);
+ System.arraycopy(result, 0, tmp, results.length,
result.length);
+ results = tmp;
+ }
+ }
+
+ return results;
+ }
+
+ // TODO here may add some logic in TrafT4ResultSet
+ public ResultSet executeQuery() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "executeQuery", "", p);
+ }
+ ResultSet[] results = new ResultSet[pstmtArr.length];
+ currentSqlIndex = 0;
+
+ for (int i = 0; i < pstmtArr.length; i++) {
+ results[i] = pstmtArr[i].executeQuery();
+ }
+ return results[currentSqlIndex++];
+ }
+
+ public boolean execute() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "execute", "", p);
+ }
+ boolean result = false;
+ currentSqlIndex = 0;
+
+ for (int i = 0; i < pstmtArr.length; i++) {
+ result |= pstmtArr[i].execute();
+ }
+ return result;
+ }
+
+ public int getUpdateCount() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "getUpdateCount", "",
+ p);
+ }
+ long result = 0;
+ currentSqlIndex = 0;
+
+ for (int i = 0; i < pstmtArr.length; i++) {
+ result += pstmtArr[i].getUpdateCount();
+ }
+ return (int) result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_
+ .logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "executeUpdate", "", p);
+ }
+ long result = 0;
+ currentSqlIndex = 0;
+
+ for (int i = 0; i < pstmtArr.length; i++) {
+ result += pstmtArr[i].executeUpdate();
+ }
+ return (int) result;
+ }
+
+ public void close() throws SQLException {
+ if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
+ Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
+ connection_.props_.t4Logger_.logp(Level.FINE,
"TrafT4MultiQueriesPreparedStatement", "close", "", p);
+ }
+ for (int i = 0; i < pstmtArr.length; i++) {
+ pstmtArr[i].close();
--- End diff --
very good suggestions, thanks
---