--- /dev/null
+ 47119 djd /*\r
+ 47119 djd \r
+ 57533 djd Derby - Class org.apache.derby.impl.drda.DRDAStatement\r
+ 47119 djd \r
+429803 fuzzylogic Licensed to the Apache Software Foundation (ASF) under one or more\r
+429803 fuzzylogic contributor license agreements. See the NOTICE file distributed with\r
+429803 fuzzylogic this work for additional information regarding copyright ownership.\r
+429803 fuzzylogic The ASF licenses this file to You under the Apache License, Version 2.0\r
+429803 fuzzylogic (the "License"); you may not use this file except in compliance with\r
+429803 fuzzylogic the License. You may obtain a copy of the License at\r
+ 57533 djd \r
+ 57533 djd http://www.apache.org/licenses/LICENSE-2.0\r
+ 57533 djd \r
+ 57533 djd Unless required by applicable law or agreed to in writing, software\r
+ 57533 djd distributed under the License is distributed on an "AS IS" BASIS,\r
+ 57533 djd WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ 57533 djd See the License for the specific language governing permissions and\r
+ 57533 djd limitations under the License.\r
+ 57533 djd \r
+ 47119 djd */\r
+ 47119 djd \r
+ 47119 djd package org.apache.derby.impl.drda;\r
+ 47119 djd \r
+581031 kmarsden import java.io.IOException;\r
+189752 kmarsden import java.io.UnsupportedEncodingException;\r
+189752 kmarsden import java.lang.reflect.InvocationTargetException;\r
+189752 kmarsden import java.lang.reflect.Method;\r
+189752 kmarsden import java.math.BigInteger;\r
+189752 kmarsden import java.sql.CallableStatement;\r
+ 47119 djd import java.sql.Connection;\r
+495543 kahatlen import java.sql.ParameterMetaData;\r
+ 47119 djd import java.sql.PreparedStatement;\r
+ 47119 djd import java.sql.ResultSet;\r
+ 47119 djd import java.sql.SQLException;\r
+189752 kmarsden import java.sql.Statement;\r
+ 47119 djd import java.util.ArrayList;\r
+189752 kmarsden import java.util.Hashtable;\r
+ 47119 djd import java.util.StringTokenizer;\r
+ 47119 djd import java.util.Vector;\r
+467612 kahatlen import java.lang.reflect.Array;\r
+ 47119 djd \r
+189752 kmarsden import org.apache.derby.iapi.jdbc.BrokeredConnection;\r
+189752 kmarsden import org.apache.derby.iapi.jdbc.BrokeredPreparedStatement;\r
+380278 djd import org.apache.derby.iapi.jdbc.EngineConnection;\r
+421435 davidvc import org.apache.derby.iapi.jdbc.EnginePreparedStatement;\r
+ 47119 djd import org.apache.derby.iapi.reference.JDBC30Translation;\r
+ 47119 djd import org.apache.derby.iapi.sql.execute.ExecutionContext;\r
+ 47119 djd import org.apache.derby.iapi.util.StringUtil;\r
+189752 kmarsden import org.apache.derby.impl.jdbc.Util;\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd DRDAStatement stores information about the statement being executed\r
+ 47119 djd */\r
+ 47119 djd class DRDAStatement\r
+ 47119 djd {\r
+ 47119 djd \r
+381937 kmarsden //NOTE!\r
+381937 kmarsden //\r
+381937 kmarsden // Since DRDAStatements are reused, ALL variables (except those noted in \r
+381937 kmarsden // the comments for reset method) should be set to their default values \r
+381937 kmarsden // in reset().\r
+381937 kmarsden \r
+ 47119 djd \r
+ 47119 djd protected String typDefNam; //TYPDEFNAM for this statement\r
+ 47119 djd protected int byteOrder; //deduced from typDefNam, save String comparisons\r
+ 47119 djd protected int ccsidSBC; //CCSID for single byte characters\r
+ 47119 djd protected int ccsidDBC; //CCSID for double byte characters\r
+ 47119 djd protected int ccsidMBC; //CCSID for mixed byte characters\r
+ 47119 djd protected String ccsidSBCEncoding; //Java encoding for CCSIDSBC\r
+ 47119 djd protected String ccsidDBCEncoding; //Java encoding for CCSIDDBC\r
+ 47119 djd protected String ccsidMBCEncoding; //Java encoding for CCSIDMBC\r
+ 47119 djd \r
+ 47119 djd protected Database database; // Database this statement is created for\r
+368333 bernt private Pkgnamcsn pkgnamcsn; // Package name/section # and consistency token\r
+368333 bernt protected ConsistencyToken pkgcnstkn; // Consistency token for the first result set\r
+ 47119 djd protected String pkgid; // package id\r
+368333 bernt protected int pkgsn; // section number\r
+380278 djd int withHoldCursor = -1; // hold cursor after commit attribute.\r
+ 47119 djd protected int isolationLevel; //JCC isolation level for Statement\r
+ 47119 djd protected String cursorName;\r
+123827 kmarsden protected int scrollType = ResultSet.TYPE_FORWARD_ONLY; // Sensitive or Insensitive scroll attribute\r
+123827 kmarsden protected int concurType = ResultSet.CONCUR_READ_ONLY;; // Concurency type\r
+ 47119 djd protected long rowCount; // Number of rows we have processed\r
+ 47119 djd protected byte [] rslsetflg; // Result Set Flags\r
+ 47119 djd protected int maxrslcnt; // Maximum Result set count\r
+ 47119 djd protected PreparedStatement ps; // Prepared statement\r
+495543 kahatlen protected ParameterMetaData stmtPmeta; // param metadata\r
+ 47119 djd protected boolean isCall;\r
+ 47119 djd protected String procName; // callable statement's method name\r
+ 47119 djd private int[] outputTypes; // jdbc type for output parameter or NOT_OUTPUT_PARAM\r
+ 47119 djd // if not an output parameter.\r
+534985 kmarsden private int[] outputPrecision;\r
+534985 kmarsden private int[] outputScale;\r
+534985 kmarsden \r
+ 47119 djd protected static int NOT_OUTPUT_PARAM = -100000;\r
+ 47119 djd protected boolean outputExpected; // expect output from a callable statement\r
+ 47119 djd private Statement stmt; // SQL statement\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd private DRDAResultSet currentDrdaRs; // Current ResultSet\r
+ 47119 djd private Hashtable resultSetTable; // Hashtable with resultsets \r
+ 47119 djd private ArrayList resultSetKeyList; // ordered list of hash keys\r
+ 47119 djd private int numResultSets = 0; \r
+ 47119 djd \r
+467612 kahatlen /** This class is used to keep track of the statement's parameters\r
+467612 kahatlen * as they are received from the client. It uses arrays to track\r
+467612 kahatlen * the DRDA type, the length in bytes and the externalness of each\r
+467612 kahatlen * parameter. Arrays of int/byte are used rather than ArrayLists\r
+467612 kahatlen * of Integer/Byte in order to re-use the same storage each time\r
+467612 kahatlen * the statement is executed. */\r
+467612 kahatlen private static class DrdaParamState {\r
+581031 kmarsden // The last parameter may be streamed. \r
+581031 kmarsden // We need to keep a record of it so we can drain it if it is not \r
+581031 kmarsden // used.\r
+581031 kmarsden // Only the last parameter with an EXTDTA will be streamed. \r
+581031 kmarsden //(See DRDAConnThread.readAndSetAllExtParams()). \r
+581031 kmarsden private EXTDTAReaderInputStream streamedParameter = null;\r
+467612 kahatlen private int typeLstEnd_ = 0;\r
+467612 kahatlen private byte[] typeLst_ = new byte[10];\r
+467612 kahatlen private int[] lenLst_ = new int[10];\r
+467612 kahatlen private int extLstEnd_ = 0;\r
+467612 kahatlen private int[] extLst_ = new int[10];\r
+ 47119 djd \r
+467612 kahatlen private static Object growArray(Object array) {\r
+467612 kahatlen final int oldLen = Array.getLength(array);\r
+467612 kahatlen Object tmp =\r
+467612 kahatlen Array.newInstance(array.getClass().getComponentType(),\r
+467612 kahatlen Math.max(oldLen,1)*2);\r
+467612 kahatlen System.arraycopy(array, 0, tmp, 0, oldLen);\r
+467612 kahatlen return tmp;\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>clear</code> resets the arrays so that new parameters\r
+467612 kahatlen * will be added at the beginning. No initialization or\r
+467612 kahatlen * releasing of storage takes place unless the trim argument\r
+467612 kahatlen * is true.\r
+467612 kahatlen *\r
+467612 kahatlen * @param trim - if true; release excess storage\r
+467612 kahatlen */\r
+467612 kahatlen protected void clear(boolean trim) {\r
+581031 kmarsden streamedParameter = null;\r
+467612 kahatlen typeLstEnd_ = 0;\r
+467612 kahatlen extLstEnd_ = 0;\r
+467612 kahatlen if (trim && typeLst_.length > 10) {\r
+467612 kahatlen typeLst_ = new byte[10];\r
+467612 kahatlen lenLst_ = new int[10];\r
+467612 kahatlen extLst_ = new int[10];\r
+467612 kahatlen }\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>addDrdaParam</code> adds a new parameter with its\r
+467612 kahatlen * DRDA type and byte length. The arrays are automatically\r
+467612 kahatlen * grown if needed.\r
+467612 kahatlen *\r
+467612 kahatlen * @param t a <code>byte</code> value, the DRDA type of the\r
+467612 kahatlen * parameter being added\r
+467612 kahatlen * @param s an <code>int</code> value, the length in bytes of\r
+467612 kahatlen * the parameter being added\r
+467612 kahatlen */\r
+467612 kahatlen protected void addDrdaParam(byte t, int s) {\r
+467612 kahatlen if (typeLstEnd_ >= typeLst_.length) {\r
+467612 kahatlen typeLst_ = (byte[])growArray(typeLst_);\r
+467612 kahatlen lenLst_ = (int[])growArray(lenLst_);\r
+467612 kahatlen }\r
+467612 kahatlen typeLst_[typeLstEnd_] = t;\r
+467612 kahatlen lenLst_[typeLstEnd_] = s;\r
+467612 kahatlen ++typeLstEnd_;\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>getDrdaParamCount</code> return the number of\r
+467612 kahatlen * parameters added so far (since last clear).\r
+467612 kahatlen *\r
+467612 kahatlen * @return an <code>int</code> value, the number of parameters\r
+467612 kahatlen */\r
+467612 kahatlen protected int getDrdaParamCount() { return typeLstEnd_; }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>getDrdaType</code> returns a byte that represents the\r
+467612 kahatlen * DRDA type of the ith parameter.\r
+467612 kahatlen *\r
+467612 kahatlen * @param i an <code>int</code> value, a parameter position\r
+467612 kahatlen * (zero-based)\r
+467612 kahatlen * @return a <code>byte</code> value, the DRDA type\r
+467612 kahatlen */\r
+467612 kahatlen protected byte getDrdaType(int i) { return typeLst_[i]; }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>getDrdaLen</code> returns the length in bytes of the\r
+467612 kahatlen * ith parameter.\r
+467612 kahatlen *\r
+467612 kahatlen * @param i an <code>int</code> value, a parameter position\r
+467612 kahatlen * (zero-based)\r
+467612 kahatlen * @return an <code>int</code> value\r
+467612 kahatlen */\r
+467612 kahatlen protected int getDrdaLen(int i) { return lenLst_[i]; }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>addExtPos</code> marks parameter i as external. The\r
+467612 kahatlen * array is grown as needed.\r
+467612 kahatlen *\r
+467612 kahatlen * @param p an <code>int</code> value, a parameter position\r
+467612 kahatlen * (zero-based)\r
+467612 kahatlen */\r
+467612 kahatlen protected void addExtPos(int p) {\r
+467612 kahatlen if (extLstEnd_ >= extLst_.length) {\r
+467612 kahatlen extLst_ = (int[])growArray(extLst_);\r
+467612 kahatlen }\r
+467612 kahatlen extLst_[extLstEnd_] = p;\r
+467612 kahatlen ++extLstEnd_;\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>getExtPosCount</code> returns the number of\r
+467612 kahatlen * parameters marked as external so far (since last clear).\r
+467612 kahatlen *\r
+467612 kahatlen * @return an <code>int</code> value, the number of external\r
+467612 kahatlen * parameters.\r
+467612 kahatlen */\r
+467612 kahatlen protected int getExtPosCount() { return extLstEnd_; }\r
+467612 kahatlen \r
+467612 kahatlen /**\r
+467612 kahatlen * <code>getExtPos</code> returns the actual parameter position\r
+467612 kahatlen * of the ith external parameter.\r
+467612 kahatlen *\r
+467612 kahatlen * @param i an <code>int</code> value, index into the list of\r
+467612 kahatlen * external parameters, zero-based\r
+467612 kahatlen * @return an <code>int</code> value, the parameter position\r
+467612 kahatlen * of the ith external parameter (zero-based)\r
+467612 kahatlen */\r
+467612 kahatlen protected int getExtPos(int i) { return extLst_[i]; }\r
+581031 kmarsden \r
+581031 kmarsden /**\r
+581031 kmarsden * Read the rest of the streamed parameter if not consumed\r
+581031 kmarsden * by the executing statement. DERBY-3085\r
+581031 kmarsden * @throws IOException\r
+581031 kmarsden */\r
+581031 kmarsden protected void drainStreamedParameter() throws IOException\r
+581031 kmarsden {\r
+581031 kmarsden if (streamedParameter != null)\r
+581031 kmarsden { \r
+581031 kmarsden // we drain the buffer 1000 bytes at a time.\r
+581031 kmarsden // 1000 is just a random selection that doesn't take\r
+581031 kmarsden // too much memory. Perhaps something else would be \r
+581031 kmarsden // more efficient?\r
+581031 kmarsden byte[] buffer = new byte[1000];\r
+581031 kmarsden int i;\r
+581031 kmarsden do {\r
+581031 kmarsden i= streamedParameter.read(buffer,0,1000);\r
+581031 kmarsden } while (i != -1);\r
+581031 kmarsden }\r
+581031 kmarsden }\r
+581031 kmarsden \r
+581031 kmarsden \r
+581031 kmarsden public void setStreamedParameter(EXTDTAReaderInputStream eis) {\r
+581031 kmarsden streamedParameter = eis; \r
+581031 kmarsden }\r
+581031 kmarsden \r
+467612 kahatlen }\r
+467612 kahatlen private DrdaParamState drdaParamState_ = new DrdaParamState();\r
+467612 kahatlen \r
+ 47119 djd // Query options sent on EXCSQLSTT\r
+ 47119 djd // These the default for ResultSets created for this statement.\r
+ 47119 djd // These can be overriden by OPNQRY or CNTQRY,\r
+ 47119 djd protected int nbrrow; // number of fetch or insert rows\r
+ 47119 djd protected int qryrowset; // Query row set\r
+ 47119 djd protected int blksize; // Query block size\r
+ 47119 djd protected int maxblkext; // Maximum number of extra blocks\r
+ 47119 djd protected int outovropt; // Output Override option\r
+ 47119 djd protected boolean qryrfrtbl; // Query refresh answer set table\r
+ 47119 djd private int qryprctyp = CodePoint.QRYBLKCTL_DEFAULT; // Protocol type\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd boolean needsToSendParamData = false;\r
+ 47119 djd boolean explicitlyPrepared = false; //Prepared with PRPSQLSTT (reusable) \r
+ 47119 djd \r
+ 47119 djd // constructor\r
+ 47119 djd /**\r
+ 47119 djd * DRDAStatement constructor\r
+ 47119 djd *\r
+ 47119 djd * @param database\r
+ 47119 djd * \r
+ 47119 djd */\r
+379174 djd DRDAStatement (Database database) \r
+ 47119 djd {\r
+ 47119 djd this.database = database;\r
+ 47119 djd setTypDefValues();\r
+ 47119 djd this.currentDrdaRs = new DRDAResultSet();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * set TypDef values\r
+ 47119 djd *\r
+ 47119 djd */\r
+ 47119 djd protected void setTypDefValues()\r
+ 47119 djd {\r
+ 47119 djd // initialize statement values to current database values\r
+ 47119 djd this.typDefNam = database.typDefNam;\r
+ 47119 djd this.byteOrder = database.byteOrder;\r
+ 47119 djd this.ccsidSBC = database.ccsidSBC;\r
+ 47119 djd this.ccsidDBC = database.ccsidDBC;\r
+ 47119 djd this.ccsidMBC = database.ccsidMBC;\r
+ 47119 djd this.ccsidSBCEncoding = database.ccsidSBCEncoding;\r
+ 47119 djd this.ccsidDBCEncoding = database.ccsidDBCEncoding;\r
+ 47119 djd this.ccsidMBCEncoding = database.ccsidMBCEncoding;\r
+ 47119 djd }\r
+ 47119 djd /**\r
+ 47119 djd * Set database\r
+ 47119 djd *\r
+ 47119 djd * @param database\r
+ 47119 djd */\r
+ 47119 djd protected void setDatabase(Database database)\r
+ 47119 djd {\r
+ 47119 djd this.database = database;\r
+ 47119 djd setTypDefValues();\r
+ 47119 djd }\r
+ 47119 djd /**\r
+ 47119 djd * Set statement\r
+ 47119 djd *\r
+ 47119 djd * @param conn Connection\r
+ 47119 djd * @exception SQLException\r
+ 47119 djd */\r
+ 47119 djd protected void setStatement(Connection conn)\r
+ 47119 djd throws SQLException\r
+ 47119 djd {\r
+ 47119 djd stmt = conn.createStatement();\r
+ 47119 djd //beetle 3849 - see prepareStatement for details\r
+ 47119 djd if (cursorName != null)\r
+ 47119 djd stmt.setCursorName(cursorName);\r
+ 47119 djd }\r
+ 47119 djd /**\r
+ 47119 djd * Get the statement\r
+ 47119 djd *\r
+ 47119 djd * @return statement\r
+ 47119 djd * @exception SQLException\r
+ 47119 djd */\r
+ 47119 djd protected Statement getStatement() \r
+ 47119 djd throws SQLException\r
+ 47119 djd {\r
+ 47119 djd return stmt;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**Set resultSet defaults to match \r
+ 47119 djd * the statement defaults sent on EXCSQLSTT\r
+ 47119 djd * This might be overridden on OPNQRY or CNTQRY\r
+ 47119 djd **/\r
+ 47119 djd \r
+ 47119 djd protected void setRsDefaultOptions(DRDAResultSet drs)\r
+ 47119 djd {\r
+ 47119 djd drs.nbrrow = nbrrow;\r
+ 47119 djd drs.qryrowset = qryrowset;\r
+ 47119 djd drs.blksize = blksize;\r
+ 47119 djd drs.maxblkext = maxblkext;\r
+ 47119 djd drs.outovropt = outovropt;\r
+ 47119 djd drs.rslsetflg = rslsetflg;\r
+ 47119 djd drs.scrollType = scrollType;\r
+ 47119 djd drs.concurType = concurType;\r
+ 47119 djd drs.setQryprctyp(qryprctyp);\r
+ 47119 djd drs.qryrowset = qryrowset;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Get the extData Objects\r
+ 47119 djd *\r
+ 47119 djd * @return ArrayList with extdta\r
+ 47119 djd */\r
+ 47119 djd protected ArrayList getExtDtaObjects()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getExtDtaObjects();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set the extData Objects\r
+ 47119 djd */\r
+ 47119 djd protected void setExtDtaObjects(ArrayList a)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setExtDtaObjects(a);\r
+ 47119 djd }\r
+355689 kmarsden \r
+355689 kmarsden public void setSplitQRYDTA(byte []data)\r
+355689 kmarsden {\r
+355689 kmarsden currentDrdaRs.setSplitQRYDTA(data);\r
+355689 kmarsden }\r
+355689 kmarsden public byte[]getSplitQRYDTA()\r
+355689 kmarsden {\r
+355689 kmarsden return currentDrdaRs.getSplitQRYDTA();\r
+355689 kmarsden }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Add extDtaObject\r
+ 47119 djd * @param o - object to add\r
+ 47119 djd * @param jdbcIndex - jdbc index for parameter\r
+ 47119 djd */\r
+ 47119 djd protected void addExtDtaObject (Object o, int jdbcIndex )\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.addExtDtaObject(o,jdbcIndex);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Clear externalized lob objects in current result set\r
+ 47119 djd */\r
+ 47119 djd protected void clearExtDtaObjects ()\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.clearExtDtaObjects();\r
+ 47119 djd }\r
+ 47119 djd \r
+123827 kmarsden /**\r
+123827 kmarsden *\r
+391691 djd * get resultSetHoldability.\r
+123827 kmarsden * \r
+123827 kmarsden * @return the resultSet holdability for the prepared statement\r
+123827 kmarsden *\r
+123827 kmarsden */\r
+123827 kmarsden protected int getResultSetHoldability() throws SQLException\r
+123827 kmarsden {\r
+495543 kahatlen return getResultSetHoldability(getResultSet());\r
+123827 kmarsden }\r
+326718 kmarsden \r
+326718 kmarsden /**\r
+326718 kmarsden *\r
+391691 djd * get resultSetHoldability.\r
+326718 kmarsden * \r
+326718 kmarsden * @param rs ResultSet \r
+326718 kmarsden * @return the resultSet holdability for the prepared statement\r
+326718 kmarsden *\r
+326718 kmarsden */\r
+391691 djd int getResultSetHoldability(ResultSet rs) throws SQLException\r
+326718 kmarsden {\r
+391691 djd Statement rsstmt;\r
+123827 kmarsden \r
+326718 kmarsden if (rs != null)\r
+326718 kmarsden rsstmt = rs.getStatement();\r
+326718 kmarsden else\r
+326718 kmarsden rsstmt = getPreparedStatement();\r
+391691 djd \r
+495543 kahatlen return rsstmt.getResultSetHoldability();\r
+326718 kmarsden } \r
+326718 kmarsden \r
+ 47119 djd /*\r
+ 47119 djd * Is lob object nullable\r
+ 47119 djd * @param index - offset starting with 0\r
+ 47119 djd * @return true if object is nullable\r
+ 47119 djd */\r
+ 47119 djd protected boolean isExtDtaValueNullable(int index)\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.isExtDtaValueNullable(index);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+394859 kahatlen * Set query options sent on OPNQRY and pass options down to the\r
+394859 kahatlen * current <code>DRDAResultSet</code> object.\r
+394859 kahatlen *\r
+394859 kahatlen * @param blksize QRYBLKSZ (Query Block Size)\r
+394859 kahatlen * @param qryblkctl QRYPRCTYP (Query Protocol Type)\r
+394859 kahatlen * @param maxblkext MAXBLKEXT (Maximum Number of Extra Blocks)\r
+394859 kahatlen * @param outovropt OUTOVROPT (Output Override Option)\r
+394859 kahatlen * @param qryrowset QRYROWSET (Query Rowset Size)\r
+394859 kahatlen * @param qryclsimpl QRYCLSIMP (Query Close Implicit)\r
+189752 kmarsden * @see DRDAResultSet#setOPNQRYOptions(int, int, int, int, int, int)\r
+ 47119 djd */\r
+ 47119 djd protected void setOPNQRYOptions(int blksize, int qryblkctl,\r
+ 47119 djd int maxblkext, int outovropt,int qryrowset,int qryclsimpl)\r
+ 47119 djd {\r
+394859 kahatlen this.blksize = blksize;\r
+394859 kahatlen this.qryprctyp = qryblkctl;\r
+394859 kahatlen this.maxblkext = maxblkext;\r
+394859 kahatlen this.outovropt = outovropt;\r
+394859 kahatlen this.qryrowset = qryrowset;\r
+189752 kmarsden currentDrdaRs.setOPNQRYOptions( blksize, qryblkctl, maxblkext, \r
+189752 kmarsden outovropt, qryrowset, qryclsimpl);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /*\r
+ 47119 djd * Set query options sent on CNTQRY\r
+ 47119 djd */\r
+ 47119 djd protected void setQueryOptions(int blksize, boolean qryrelscr, \r
+ 47119 djd long qryrownbr,\r
+ 47119 djd boolean qryfrtbl,int nbrrow,int maxblkext,\r
+ 47119 djd int qryscrorn, boolean qryrowsns,\r
+ 47119 djd boolean qryblkrst,\r
+ 47119 djd boolean qryrtndta,int qryrowset,\r
+ 47119 djd int rtnextdta)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.blksize = blksize;\r
+ 47119 djd currentDrdaRs.qryrelscr = qryrelscr;\r
+ 47119 djd currentDrdaRs.qryrownbr = qryrownbr;\r
+ 47119 djd currentDrdaRs.qryrfrtbl = qryrfrtbl;\r
+ 47119 djd currentDrdaRs.nbrrow = nbrrow;\r
+ 47119 djd currentDrdaRs.maxblkext = maxblkext;\r
+ 47119 djd currentDrdaRs.qryscrorn = qryscrorn;\r
+ 47119 djd currentDrdaRs.qryrowsns = qryrowsns;\r
+ 47119 djd currentDrdaRs.qryblkrst = qryblkrst;\r
+ 47119 djd currentDrdaRs.qryrtndta = qryrtndta;\r
+ 47119 djd currentDrdaRs.qryrowset = qryrowset;\r
+ 47119 djd currentDrdaRs.rtnextdta = rtnextdta;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected void setQryprctyp(int qryprctyp)\r
+ 47119 djd {\r
+ 47119 djd this.qryprctyp = qryprctyp;\r
+ 47119 djd currentDrdaRs.setQryprctyp(qryprctyp);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected int getQryprctyp()\r
+ 47119 djd throws SQLException\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getQryprctyp();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected void setQryrownbr(long qryrownbr)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.qryrownbr = qryrownbr;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected long getQryrownbr()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.qryrownbr;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected int getQryrowset()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.qryrowset;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected int getBlksize()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.blksize;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected void setQryrtndta(boolean qryrtndta)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.qryrtndta = qryrtndta;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected boolean getQryrtndta()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.qryrtndta;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected void setQryscrorn(int qryscrorn)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.qryscrorn = qryscrorn;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected int getQryscrorn()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.qryscrorn;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected void setScrollType(int scrollType)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.scrollType = scrollType;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected int getScrollType()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.scrollType;\r
+ 47119 djd }\r
+ 47119 djd \r
+123827 kmarsden /** \r
+123827 kmarsden * is this a scrollable cursor?\r
+123827 kmarsden * return true if this is not a forward only cursor\r
+123827 kmarsden */\r
+123827 kmarsden protected boolean isScrollable()\r
+123827 kmarsden {\r
+123827 kmarsden return (getScrollType() != ResultSet.TYPE_FORWARD_ONLY);\r
+123827 kmarsden }\r
+ 47119 djd \r
+ 47119 djd protected void setConcurType(int scrollType)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.concurType = scrollType;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected int getConcurType()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.concurType;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected void setOutovr_drdaType(int[] outovr_drdaType) \r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.outovr_drdaType = outovr_drdaType;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected int[] getOutovr_drdaType() \r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.outovr_drdaType;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected boolean hasdata()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.hasdata;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected void setHasdata(boolean hasdata)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.hasdata = hasdata;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+381937 kmarsden * This method is used to initialize the default statement of the database\r
+381937 kmarsden * for re-use. It is different from reset() method since default statements\r
+381937 kmarsden * get initiliazed differently. e.g: stmt variable used in default statement\r
+381937 kmarsden * is created only once in Database.makeConnection. \r
+381937 kmarsden * TODO: Need to see what exactly it means to initialize the default \r
+381937 kmarsden * statement. (DERBY-1002)\r
+381937 kmarsden * \r
+ 47119 djd */\r
+ 47119 djd protected void initialize() \r
+ 47119 djd {\r
+ 47119 djd setTypDefValues();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected PreparedStatement explicitPrepare(String sqlStmt) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd explicitlyPrepared = true;\r
+ 47119 djd return prepare(sqlStmt);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected boolean wasExplicitlyPrepared()\r
+ 47119 djd {\r
+ 47119 djd return explicitlyPrepared;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Create a prepared statement\r
+ 47119 djd *\r
+ 47119 djd * @param sqlStmt - SQL statement\r
+ 47119 djd *\r
+ 47119 djd * @exception SQLException\r
+ 47119 djd */\r
+ 47119 djd protected PreparedStatement prepare(String sqlStmt) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd // save current prepare iso level\r
+ 47119 djd int saveIsolationLevel = -1;\r
+ 47119 djd boolean isolationSet = false;\r
+159041 kmarsden if (pkgnamcsn !=null && \r
+159041 kmarsden isolationLevel != Connection.TRANSACTION_NONE)\r
+ 47119 djd {\r
+ 47119 djd saveIsolationLevel = database.getPrepareIsolation();\r
+ 47119 djd database.setPrepareIsolation(isolationLevel);\r
+ 47119 djd isolationSet = true;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd if (isCallableSQL(sqlStmt))\r
+ 47119 djd {\r
+ 47119 djd isCall = true;\r
+ 47119 djd ps = database.getConnection().prepareCall(sqlStmt);\r
+ 47119 djd setupCallableStatementParams((CallableStatement)ps);\r
+ 47119 djd if (isolationSet)\r
+ 47119 djd database.setPrepareIsolation(saveIsolationLevel);\r
+ 47119 djd return ps;\r
+ 47119 djd }\r
+ 47119 djd parsePkgidToFindHoldability();\r
+380278 djd ps = prepareStatementJDBC3(sqlStmt, scrollType, concurType, \r
+156229 kmarsden withHoldCursor);\r
+ 47119 djd // beetle 3849 - Need to change the cursor name to what\r
+ 47119 djd // JCC thinks it will be, since there is no way in the \r
+ 47119 djd // protocol to communicate the actual cursor name. JCC keeps \r
+ 47119 djd // a mapping from the client cursor names to the DB2 style cursor names\r
+ 47119 djd if (cursorName != null)//cursorName not null means we are dealing with dynamic pacakges\r
+ 47119 djd ps.setCursorName(cursorName);\r
+ 47119 djd if (isolationSet)\r
+ 47119 djd database.setPrepareIsolation(saveIsolationLevel);\r
+ 47119 djd return ps;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Get prepared statement\r
+ 47119 djd *\r
+ 47119 djd * @return prepared statement\r
+ 47119 djd */\r
+126392 kmarsden protected PreparedStatement getPreparedStatement() throws SQLException\r
+ 47119 djd {\r
+421435 davidvc return ps;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Executes the prepared statement and populates the resultSetTable.\r
+ 47119 djd * Access to the various resultSets is then possible by using\r
+ 47119 djd * setCurrentDrdaResultSet(String pkgnamcsn) to set the current\r
+ 47119 djd * resultSet and then calling getResultSet() or the other access \r
+ 47119 djd * methods to get resultset data.\r
+ 47119 djd *\r
+126257 fuzzylogic * @return true if the execution has resultSets\r
+ 47119 djd */\r
+ 47119 djd protected boolean execute() throws SQLException\r
+ 47119 djd {\r
+ 47119 djd boolean hasResultSet = ps.execute();\r
+581031 kmarsden // DERBY-3085 - We need to make sure we drain the streamed parameter\r
+581031 kmarsden // if not used by the server, for example if an update statement does not \r
+581031 kmarsden // update any rows, the parameter won't be used. Network Server will\r
+581031 kmarsden // stream only the last parameter with an EXTDTA. This is stored when the\r
+581031 kmarsden // parameter is set and drained now after statement execution if needed.\r
+581031 kmarsden try {\r
+581031 kmarsden drdaParamState_.drainStreamedParameter();\r
+581031 kmarsden } catch (IOException e) { \r
+581031 kmarsden Util.javaException(e);\r
+581031 kmarsden }\r
+ 47119 djd // java.sql.Statement says any result sets that are opened\r
+ 47119 djd // when the statement is re-executed must be closed; this\r
+ 47119 djd // is handled by the call to "ps.execute()" above--but we\r
+ 47119 djd // also have to reset our 'numResultSets' counter, since\r
+ 47119 djd // all previously opened result sets are now invalid.\r
+ 47119 djd numResultSets = 0;\r
+ 47119 djd \r
+ 47119 djd ResultSet rs = null;\r
+ 47119 djd boolean isCallable = (ps instanceof java.sql.CallableStatement);\r
+ 47119 djd if (isCallable)\r
+ 47119 djd needsToSendParamData = true;\r
+ 47119 djd \r
+ 47119 djd do {\r
+ 47119 djd rs = ps.getResultSet();\r
+ 47119 djd if (rs !=null)\r
+ 47119 djd {\r
+326718 kmarsden //For callable statement, get holdability of statement generating the result set\r
+326718 kmarsden if(isCallable)\r
+326718 kmarsden addResultSet(rs,getResultSetHoldability(rs));\r
+326718 kmarsden else\r
+326718 kmarsden addResultSet(rs,withHoldCursor);\r
+ 47119 djd hasResultSet = true;\r
+ 47119 djd }\r
+ 47119 djd // For normal selects we are done, but procedures might\r
+ 47119 djd // have more resultSets\r
+123827 kmarsden }while (isCallable && getMoreResults(JDBC30Translation.KEEP_CURRENT_RESULT));\r
+ 47119 djd \r
+ 47119 djd return hasResultSet;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * clear out type data for parameters.\r
+ 47119 djd * Unfortunately we currently overload the resultSet type info\r
+ 47119 djd * rsDRDATypes et al with parameter info.\r
+ 47119 djd * RESOLVE: Need to separate this\r
+ 47119 djd */\r
+ 47119 djd protected void finishParams()\r
+ 47119 djd {\r
+ 47119 djd needsToSendParamData = false;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set the pkgid sec num for this statement and the \r
+ 47119 djd * consistency token that will be used for the first resultSet.\r
+ 47119 djd * For dyamic packages The package name is encoded as follows\r
+ 47119 djd * SYS(S/L)(H/N)xyy \r
+ 47119 djd * where 'S' represents Small package and 'L' large \r
+515793 fuzzylogic * (ignored by Derby) \r
+ 47119 djd * Where 'H' represents WITH HOLD, and 'N' represents NO WITH HOLD. \r
+ 47119 djd * (May be overridden by SQLATTR for WITH\r
+ 47119 djd * HOLD")\r
+ 47119 djd *\r
+515793 fuzzylogic * Where 'www' is the package iteration (ignored by Derby)\r
+ 47119 djd * Where 'x' is the isolation level: 0=NC, 1=UR, 2=CS, 3=RS, 4=RR \r
+ 47119 djd * Where 'yy' is the package iteration 00 through FF \r
+ 47119 djd * Where 'zz' is unique for each platform\r
+515793 fuzzylogic * Happilly, these values correspond precisely to the internal Derby\r
+ 47119 djd * isolation levels in ExecutionContext.java\r
+ 47119 djd * x Isolation Level \r
+ 47119 djd * -- ---------------------\r
+ 47119 djd * 0 NC (java.sql.Connection.TRANSACTION_NONE)\r
+ 47119 djd * 1 UR (java.sql.Connection.TRANACTION_READ_UNCOMMITTED)\r
+ 47119 djd * 2 CS (java.sql.Connection.TRANSACTION_READ_COMMITTED)\r
+ 47119 djd * 3 RS (java.sql.Connection.TRANSACTION_REPEATABLE_READ)\r
+ 47119 djd * 4 RR (java.sql.Connection.TRANSACTION_SERIALIZABLE)\r
+ 47119 djd * \r
+ 47119 djd * static packages have preset isolation levels \r
+ 47119 djd * (see getStaticPackageIsolation)\r
+ 47119 djd * @param pkgnamcsn package id section number and token from the client\r
+ 47119 djd */\r
+368333 bernt protected void setPkgnamcsn(Pkgnamcsn pkgnamcsn)\r
+ 47119 djd {\r
+ 47119 djd this.pkgnamcsn = pkgnamcsn;\r
+ 47119 djd // Store the consistency string for the first ResultSet.\r
+ 47119 djd // this will be used to calculate consistency strings for the \r
+ 47119 djd // other result sets.\r
+368333 bernt pkgid = pkgnamcsn.getPkgid();\r
+ 47119 djd \r
+ 47119 djd if (isDynamicPkgid(pkgid))\r
+ 47119 djd {\r
+ 47119 djd isolationLevel = Integer.parseInt(pkgid.substring(5,6));\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /*\r
+ 47119 djd * generate DB2-style cursorname\r
+ 47119 djd * example value : SQL_CURSN200C1\r
+ 47119 djd * where \r
+ 47119 djd * SQL_CUR is db2 cursor name prefix;\r
+ 47119 djd * S - Small package , L -Large package\r
+ 47119 djd * N - normal cursor, H - hold cursor \r
+ 47119 djd * 200 - package id as sent by jcc \r
+ 47119 djd * C - tack-on code for cursors\r
+ 47119 djd * 1 - section number sent by jcc \r
+ 47119 djd */\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd // cursor name\r
+ 47119 djd // trim the SYS off the pkgid so it wont' be in the cursor name\r
+ 47119 djd String shortPkgid = pkgid.substring(pkgid.length() -5 , pkgid.length());\r
+368333 bernt pkgsn = pkgnamcsn.getPkgsn();\r
+368333 bernt this.cursorName = "SQL_CUR" + shortPkgid + "C" + pkgsn ;\r
+ 47119 djd }\r
+ 47119 djd else // static package\r
+ 47119 djd {\r
+ 47119 djd isolationLevel = getStaticPackageIsolation(pkgid);\r
+ 47119 djd }\r
+ 47119 djd \r
+368333 bernt this.pkgcnstkn = pkgnamcsn.getPkgcnstkn();\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get the isolation level for a static package.\r
+ 47119 djd * @param pkgid - Package identifier string (e.g. SYSSTAT)\r
+ 47119 djd * @return isolation\r
+ 47119 djd */\r
+ 47119 djd private int getStaticPackageIsolation(String pkgid)\r
+ 47119 djd {\r
+ 47119 djd // SYSSTAT is used for metadata. and is the only static package used\r
+ 47119 djd // for JCC. Other static packages will need to be supported for \r
+ 47119 djd // CCC. Maybe a static hash table would then be in order.\r
+ 47119 djd if (pkgid.equals("SYSSTAT"))\r
+ 47119 djd return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL;\r
+ 47119 djd else\r
+ 47119 djd return ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Get pkgnamcsn\r
+ 47119 djd *\r
+ 47119 djd * @return pkgnamcsn\r
+ 47119 djd */\r
+368333 bernt protected Pkgnamcsn getPkgnamcsn() \r
+ 47119 djd {\r
+ 47119 djd return pkgnamcsn;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd /**\r
+ 47119 djd * Get result set\r
+ 47119 djd *\r
+ 47119 djd * @return result set\r
+ 47119 djd */\r
+ 47119 djd protected ResultSet getResultSet() \r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getResultSet();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /** \r
+ 47119 djd * Just get the resultset. Don't set it to current\r
+ 47119 djd * Assumes resultSet rsnum exists.\r
+ 47119 djd *\r
+126257 fuzzylogic * @param rsNum resultSetNumber starting with 0\r
+ 47119 djd * @return The result set in the order it was retrieved\r
+ 47119 djd * \r
+ 47119 djd * with getMoreResults()\r
+ 47119 djd **/\r
+ 47119 djd private ResultSet getResultSet(int rsNum) \r
+ 47119 djd {\r
+ 47119 djd if (rsNum == 0)\r
+ 47119 djd return currentDrdaRs.getResultSet();\r
+ 47119 djd else\r
+ 47119 djd {\r
+368333 bernt ConsistencyToken key = (ConsistencyToken) resultSetKeyList.get(rsNum);\r
+ 47119 djd return ((DRDAResultSet) (resultSetTable.get( key))).getResultSet();\r
+ 47119 djd }\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set result set\r
+ 47119 djd *\r
+ 47119 djd * @param value\r
+ 47119 djd */\r
+ 47119 djd protected void setResultSet(ResultSet value) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (currentDrdaRs.getResultSet() == null)\r
+ 47119 djd numResultSets = 1;\r
+ 47119 djd currentDrdaRs.setResultSet(value);\r
+ 47119 djd setRsDefaultOptions(currentDrdaRs);\r
+ 47119 djd }\r
+326718 kmarsden \r
+326718 kmarsden /**\r
+326718 kmarsden * Gets the current DRDA ResultSet\r
+326718 kmarsden * \r
+326718 kmarsden * @return DRDAResultSet\r
+326718 kmarsden */\r
+326718 kmarsden protected DRDAResultSet getCurrentDrdaResultSet()\r
+326718 kmarsden {\r
+326718 kmarsden return currentDrdaRs ;\r
+326718 kmarsden }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set currentDrdaResultSet \r
+ 47119 djd *\r
+ 47119 djd * @param rsNum The result set number starting with 0\r
+ 47119 djd * \r
+ 47119 djd */\r
+ 47119 djd protected void setCurrentDrdaResultSet(int rsNum)\r
+ 47119 djd {\r
+368333 bernt ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum);\r
+368333 bernt if (currentDrdaRs.pkgcnstkn == consistToken)\r
+ 47119 djd return;\r
+ 47119 djd currentDrdaRs = getDrdaResultSet(consistToken);\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set currentDrdaResultSet \r
+ 47119 djd *\r
+126257 fuzzylogic * @param pkgnamcsn The pkgid section number and unique resultset\r
+ 47119 djd * consistency token\r
+ 47119 djd * \r
+ 47119 djd */\r
+368333 bernt protected void setCurrentDrdaResultSet(Pkgnamcsn pkgnamcsn)\r
+ 47119 djd {\r
+368333 bernt pkgid = pkgnamcsn.getPkgid();\r
+368333 bernt pkgsn = pkgnamcsn.getPkgsn();\r
+368333 bernt ConsistencyToken consistToken = pkgnamcsn.getPkgcnstkn();\r
+ 47119 djd DRDAResultSet newDrdaRs = getDrdaResultSet(consistToken);\r
+ 47119 djd if (newDrdaRs != null)\r
+ 47119 djd currentDrdaRs = newDrdaRs;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /*\r
+ 47119 djd * get DRDAResultSet by consistency token\r
+ 47119 djd *\r
+ 47119 djd */\r
+368333 bernt private DRDAResultSet getDrdaResultSet(ConsistencyToken consistToken)\r
+ 47119 djd {\r
+ 47119 djd if ( resultSetTable == null || \r
+ 47119 djd (currentDrdaRs != null &&\r
+368333 bernt currentDrdaRs.pkgcnstkn == consistToken ))\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs;\r
+ 47119 djd }\r
+ 47119 djd else\r
+ 47119 djd {\r
+ 47119 djd return (DRDAResultSet) (resultSetTable.get(consistToken));\r
+ 47119 djd }\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /*\r
+ 47119 djd * get DRDAResultSet by result set number\r
+ 47119 djd *\r
+ 47119 djd */\r
+ 47119 djd private DRDAResultSet getDrdaResultSet(int rsNum)\r
+ 47119 djd {\r
+368333 bernt ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum);\r
+ 47119 djd return getDrdaResultSet(consistToken);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /** Add a new resultSet to this statement.\r
+ 47119 djd * Set as the current result set if there is not an \r
+ 47119 djd * existing current resultset.\r
+ 47119 djd * @param value - ResultSet to add\r
+326718 kmarsden * @param holdValue - Holdability of the ResultSet \r
+ 47119 djd * @return Consistency token for this resultSet\r
+ 47119 djd * For a single resultSet that is the same as the statement's \r
+ 47119 djd * For multiple resultSets just the consistency token is changed \r
+ 47119 djd */\r
+368333 bernt protected ConsistencyToken addResultSet(ResultSet value, int holdValue) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd \r
+ 47119 djd DRDAResultSet newDrdaRs = null;\r
+ 47119 djd \r
+ 47119 djd int rsNum = numResultSets;\r
+368333 bernt ConsistencyToken newRsPkgcnstkn = calculateResultSetPkgcnstkn(rsNum);\r
+ 47119 djd \r
+ 47119 djd if (rsNum == 0)\r
+ 47119 djd newDrdaRs = currentDrdaRs;\r
+ 47119 djd \r
+ 47119 djd else\r
+ 47119 djd {\r
+ 47119 djd newDrdaRs = new DRDAResultSet();\r
+ 47119 djd \r
+ 47119 djd // Multiple resultSets we neeed to setup the hash table\r
+ 47119 djd if (resultSetTable == null)\r
+ 47119 djd {\r
+ 47119 djd // If hashtable doesn't exist, create it and store resultSet 0\r
+ 47119 djd // before we store our new resultSet.\r
+ 47119 djd // For just a single resultSet we don't ever create the Hashtable.\r
+ 47119 djd resultSetTable = new Hashtable();\r
+368333 bernt resultSetTable.put(pkgcnstkn, currentDrdaRs);\r
+ 47119 djd resultSetKeyList = new ArrayList();\r
+368333 bernt resultSetKeyList.add(0, pkgcnstkn);\r
+ 47119 djd }\r
+ 47119 djd \r
+368333 bernt resultSetTable.put(newRsPkgcnstkn, newDrdaRs);\r
+368333 bernt resultSetKeyList.add(rsNum, newRsPkgcnstkn);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd newDrdaRs.setResultSet(value);\r
+368333 bernt newDrdaRs.setPkgcnstkn(newRsPkgcnstkn);\r
+326718 kmarsden newDrdaRs.withHoldCursor = holdValue;\r
+ 47119 djd setRsDefaultOptions(newDrdaRs);\r
+ 47119 djd newDrdaRs.suspend();\r
+ 47119 djd numResultSets++;\r
+368333 bernt return newRsPkgcnstkn;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd *\r
+ 47119 djd * @return number of result sets\r
+ 47119 djd */\r
+ 47119 djd protected int getNumResultSets()\r
+ 47119 djd {\r
+ 47119 djd return numResultSets;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * @param rsNum result set starting with 0\r
+ 47119 djd * @return consistency token (key) for the result set \r
+ 47119 djd */\r
+368333 bernt protected ConsistencyToken getResultSetPkgcnstkn(int rsNum)\r
+ 47119 djd {\r
+ 47119 djd if (rsNum == 0)\r
+368333 bernt return pkgcnstkn;\r
+ 47119 djd else \r
+368333 bernt return (ConsistencyToken) resultSetKeyList.get(rsNum); \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /** \r
+ 47119 djd * Set ResultSet DRDA DataTypes\r
+126257 fuzzylogic * @param value drdaTypes for columns.\r
+ 47119 djd **/\r
+ 47119 djd protected void setRsDRDATypes(int [] value)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setRsDRDATypes(value);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd *@return ResultSet DRDA DataTypes\r
+ 47119 djd **/\r
+ 47119 djd \r
+ 47119 djd protected int[] getRsDRDATypes()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getRsDRDATypes();\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /** \r
+ 47119 djd * Set ResultSet DRDA DataTypes Lengths\r
+126257 fuzzylogic * @param value drdaTypes for columns.\r
+ 47119 djd **/\r
+ 47119 djd protected void setRsLens(int [] value)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.rsLens = value;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd *@return ResultSet DRDA DataTypes Lengths\r
+ 47119 djd **/\r
+ 47119 djd \r
+ 47119 djd protected int[] getRsLens()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.rsLens;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Close the current resultSet\r
+ 47119 djd */\r
+ 47119 djd protected void rsClose() throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (currentDrdaRs.getResultSet() == null) \r
+ 47119 djd return;\r
+ 47119 djd \r
+ 47119 djd currentDrdaRs.close();\r
+ 47119 djd needsToSendParamData = false; \r
+ 47119 djd numResultSets--;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Explicitly close the result set by CLSQRY\r
+ 47119 djd * needed to check for double close.\r
+ 47119 djd */\r
+ 47119 djd protected void CLSQRY()\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.CLSQRY();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /* \r
+ 47119 djd * @return whether CLSQRY has been called on the\r
+ 47119 djd * current result set.\r
+ 47119 djd */\r
+ 47119 djd protected boolean wasExplicitlyClosed()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.wasExplicitlyClosed();\r
+ 47119 djd }\r
+ 47119 djd \r
+381937 kmarsden /**\r
+381937 kmarsden * This method closes the JDBC objects and frees up all references held by\r
+381937 kmarsden * this object.\r
+ 47119 djd * \r
+381937 kmarsden * @throws SQLException\r
+ 47119 djd */\r
+ 47119 djd protected void close() throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (ps != null)\r
+ 47119 djd ps.close();\r
+ 47119 djd if (stmt != null)\r
+ 47119 djd stmt.close();\r
+381937 kmarsden currentDrdaRs.close();\r
+ 47119 djd resultSetTable = null;\r
+ 47119 djd resultSetKeyList = null;\r
+ 47119 djd ps = null;\r
+123827 kmarsden stmtPmeta = null;\r
+ 47119 djd stmt = null;\r
+381937 kmarsden rslsetflg = null;\r
+381937 kmarsden procName = null;\r
+381937 kmarsden outputTypes = null;\r
+534985 kmarsden outputPrecision = null;\r
+534985 kmarsden outputScale = null;\r
+467612 kahatlen // Clear parameters and release excess storage\r
+467612 kahatlen drdaParamState_.clear(true);\r
+381937 kmarsden }\r
+381937 kmarsden \r
+381937 kmarsden /**\r
+381937 kmarsden * This method resets the state of this DRDAStatement object so that it can\r
+381937 kmarsden * be re-used. This method should reset all variables of this class except \r
+381937 kmarsden * the following:\r
+381937 kmarsden * 1. database - This variable gets initialized in the constructor and by\r
+381937 kmarsden * call to setDatabase.\r
+381937 kmarsden * 2. members which get initialized in setPkgnamcsn (pkgnamcsn, pkgcnstkn, \r
+381937 kmarsden * pkgid, pkgsn, isolationLevel, cursorName). pkgnamcsn is the key used to \r
+381937 kmarsden * find if the DRDAStatement can be re-used. Hence its value will not change \r
+381937 kmarsden * when the object is re-used.\r
+381937 kmarsden * \r
+381937 kmarsden */\r
+381937 kmarsden protected void reset() \r
+381937 kmarsden {\r
+381937 kmarsden setTypDefValues();\r
+381937 kmarsden \r
+381937 kmarsden withHoldCursor = -1;\r
+123827 kmarsden scrollType = ResultSet.TYPE_FORWARD_ONLY; \r
+123827 kmarsden concurType = ResultSet.CONCUR_READ_ONLY;;\r
+ 47119 djd rowCount = 0;\r
+ 47119 djd rslsetflg = null;\r
+ 47119 djd maxrslcnt = 0;\r
+381937 kmarsden ps = null;\r
+381937 kmarsden stmtPmeta = null;\r
+381937 kmarsden isCall = false;\r
+ 47119 djd procName = null;\r
+ 47119 djd outputTypes = null;\r
+ 47119 djd outputExpected = false;\r
+381937 kmarsden stmt = null;\r
+381937 kmarsden \r
+381937 kmarsden currentDrdaRs.reset();\r
+381937 kmarsden resultSetTable = null;\r
+381937 kmarsden resultSetKeyList = null;\r
+381937 kmarsden numResultSets = 0;\r
+381937 kmarsden \r
+467612 kahatlen // Clear parameters without releasing storage\r
+467612 kahatlen drdaParamState_.clear(false);\r
+381937 kmarsden \r
+381937 kmarsden nbrrow = 0;\r
+381937 kmarsden qryrowset = 0; \r
+381937 kmarsden blksize = 0; \r
+381937 kmarsden maxblkext = 0; \r
+381937 kmarsden outovropt = 0; \r
+381937 kmarsden qryrfrtbl = false;\r
+381937 kmarsden qryprctyp = CodePoint.QRYBLKCTL_DEFAULT;\r
+374029 bernt \r
+381937 kmarsden needsToSendParamData = false;\r
+381937 kmarsden explicitlyPrepared = false;\r
+381937 kmarsden }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * is Statement closed\r
+ 47119 djd * @return whether the statement is closed\r
+ 47119 djd */\r
+ 47119 djd protected boolean rsIsClosed()\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.isClosed();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * Set state to SUSPENDED (result set is opened)\r
+ 47119 djd */\r
+ 47119 djd protected void rsSuspend()\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.suspend();\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * set resultset/out parameter precision\r
+ 47119 djd *\r
+ 47119 djd * @param index - starting with 1\r
+ 47119 djd * @param precision\r
+ 47119 djd */\r
+ 47119 djd protected void setRsPrecision(int index, int precision)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setRsPrecision(index,precision);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get resultset /out paramter precision\r
+ 47119 djd * @param index -starting with 1\r
+ 47119 djd * @return precision of column\r
+ 47119 djd */\r
+ 47119 djd protected int getRsPrecision(int index)\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getRsPrecision(index);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * set resultset/out parameter scale\r
+ 47119 djd *\r
+ 47119 djd * @param index - starting with 1\r
+ 47119 djd * @param scale\r
+ 47119 djd */\r
+ 47119 djd protected void setRsScale(int index, int scale)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setRsScale(index, scale);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get resultset /out paramter scale\r
+ 47119 djd * @param index -starting with 1\r
+ 47119 djd * @return scale of column\r
+ 47119 djd */\r
+ 47119 djd protected int getRsScale(int index)\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getRsScale(index);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * set result DRDAType\r
+ 47119 djd *\r
+ 47119 djd * @param index - starting with 1\r
+ 47119 djd * @param type\r
+ 47119 djd */\r
+ 47119 djd protected void setRsDRDAType(int index, int type)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setRsDRDAType(index,type);\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+467612 kahatlen /** Clears the parameter state (type, length and ext information)\r
+467612 kahatlen * stored in this statement, but does not release any\r
+467612 kahatlen * storage. This reduces the cost of re-executing the statement\r
+467612 kahatlen * since no new storage needs to be allocated. */\r
+467612 kahatlen protected void clearDrdaParams() {\r
+467612 kahatlen drdaParamState_.clear(false);\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /** Get the number of external parameters in this\r
+467612 kahatlen * statement. External means parameters that are transmitted in a\r
+467612 kahatlen * separate DSS in the DRDA protocol.\r
+467612 kahatlen * @return the number of external parameters\r
+ 47119 djd */\r
+467612 kahatlen protected int getExtPositionCount() {\r
+467612 kahatlen return drdaParamState_.getExtPosCount();\r
+ 47119 djd }\r
+ 47119 djd \r
+467612 kahatlen /** Get the parameter position of the i'th external parameter\r
+467612 kahatlen * @param i - zero-based index into list of external parameters\r
+467612 kahatlen * @return the parameter position of the i'th external parameter\r
+467612 kahatlen */\r
+467612 kahatlen protected int getExtPosition(int i) {\r
+467612 kahatlen return drdaParamState_.getExtPos(i);\r
+467612 kahatlen }\r
+ 47119 djd \r
+467612 kahatlen /** Mark the pos'th parameter as external\r
+467612 kahatlen * @param pos - zero-based index into list of external parameters\r
+467612 kahatlen */\r
+467612 kahatlen protected void addExtPosition(int pos) {\r
+467612 kahatlen drdaParamState_.addExtPos(pos);\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /** Get the number of parameters, internal and external, that has\r
+467612 kahatlen * been added to this statement.\r
+467612 kahatlen * @return the number of parameters\r
+467612 kahatlen */\r
+467612 kahatlen protected int getDrdaParamCount() {\r
+467612 kahatlen return drdaParamState_.getDrdaParamCount();\r
+467612 kahatlen }\r
+467612 kahatlen \r
+467612 kahatlen /** Add another parameter to this statement.\r
+467612 kahatlen * @param t - type of the parameter\r
+467612 kahatlen * @param l - length in bytes of the parameter\r
+467612 kahatlen */\r
+467612 kahatlen protected void addDrdaParam(byte t, int l) {\r
+467612 kahatlen drdaParamState_.addDrdaParam(t, l);\r
+467612 kahatlen }\r
+467612 kahatlen \r
+581031 kmarsden protected void setStreamedParameter(EXTDTAReaderInputStream eis)\r
+581031 kmarsden {\r
+581031 kmarsden drdaParamState_.setStreamedParameter(eis);\r
+581031 kmarsden }\r
+581031 kmarsden \r
+ 47119 djd /**\r
+467612 kahatlen * get parameter DRDAType\r
+ 47119 djd *\r
+ 47119 djd * @param index - starting with 1\r
+467612 kahatlen * @return DRDA Type of column\r
+ 47119 djd */\r
+467612 kahatlen protected int getParamDRDAType(int index) {\r
+467612 kahatlen return drdaParamState_.getDrdaType(index-1);\r
+467612 kahatlen }\r
+467612 kahatlen \r
+ 47119 djd /**\r
+ 47119 djd * returns drda length of parameter as sent by client.\r
+467612 kahatlen * @param index - starting with 1\r
+ 47119 djd * @return data length\r
+ 47119 djd \r
+ 47119 djd */\r
+ 47119 djd protected int getParamLen(int index)\r
+ 47119 djd {\r
+467612 kahatlen return drdaParamState_.getDrdaLen(index-1);\r
+ 47119 djd }\r
+467612 kahatlen \r
+467612 kahatlen \r
+ 47119 djd /**\r
+ 47119 djd * get parameter precision or DB2 max (31)\r
+ 47119 djd *\r
+ 47119 djd * @param index parameter index starting with 1\r
+ 47119 djd *\r
+ 47119 djd * @return precision\r
+ 47119 djd */\r
+ 47119 djd protected int getParamPrecision(int index) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (ps != null && ps instanceof CallableStatement)\r
+ 47119 djd {\r
+495543 kahatlen ParameterMetaData pmeta = getParameterMetaData();\r
+123827 kmarsden \r
+ 47119 djd return Math.min(pmeta.getPrecision(index),\r
+ 47119 djd FdocaConstants.NUMERIC_MAX_PRECISION);\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd else \r
+ 47119 djd return -1;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get parameter scale or DB2 max (31)\r
+ 47119 djd *\r
+ 47119 djd * @param index parameter index starting with 1\r
+ 47119 djd *\r
+ 47119 djd * @return scale\r
+ 47119 djd */\r
+ 47119 djd protected int getParamScale(int index) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (ps != null && ps instanceof CallableStatement)\r
+ 47119 djd {\r
+495543 kahatlen ParameterMetaData pmeta = getParameterMetaData();\r
+ 47119 djd return Math.min(pmeta.getScale(index),FdocaConstants.NUMERIC_MAX_PRECISION);\r
+ 47119 djd }\r
+ 47119 djd else \r
+ 47119 djd return -1;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /** \r
+ 47119 djd * get the number of result set columns for the current resultSet\r
+ 47119 djd * \r
+ 47119 djd * @return number of columns\r
+ 47119 djd */\r
+ 47119 djd \r
+ 47119 djd protected int getNumRsCols()\r
+ 47119 djd {\r
+348577 kmarsden int[] rsDrdaTypes = getRsDRDATypes();\r
+ 47119 djd if (rsDrdaTypes != null)\r
+ 47119 djd return rsDrdaTypes.length;\r
+ 47119 djd else \r
+ 47119 djd return 0;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get resultset/out parameter DRDAType\r
+ 47119 djd *\r
+ 47119 djd * @param index - starting with 1\r
+ 47119 djd * @return DRDA Type of column\r
+ 47119 djd */\r
+ 47119 djd protected int getRsDRDAType(int index)\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getRsDRDAType(index);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * get resultset/out parameter DRDALen\r
+ 47119 djd * @param index starting with 1\r
+ 47119 djd * \r
+ 47119 djd * @return length of drda data\r
+ 47119 djd */\r
+ 47119 djd \r
+ 47119 djd protected int getRsLen(int index)\r
+ 47119 djd {\r
+ 47119 djd return currentDrdaRs.getRsLen(index);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * set resultset column data length\r
+ 47119 djd * @param index starting with 1\r
+126257 fuzzylogic * @param value length\r
+ 47119 djd */\r
+ 47119 djd protected void setRsLen(int index, int value)\r
+ 47119 djd {\r
+ 47119 djd currentDrdaRs.setRsLen(index,value);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * @param rsNum - result set # starting with 0 \r
+ 47119 djd */\r
+ 47119 djd public String getResultSetCursorName(int rsNum) throws SQLException\r
+ 47119 djd {\r
+348577 kmarsden DRDAResultSet drdaRs = getDrdaResultSet(rsNum);\r
+348577 kmarsden return drdaRs.getResultSetCursorName(); \r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd protected String toDebugString(String indent)\r
+ 47119 djd {\r
+ 47119 djd ResultSet rs = currentDrdaRs.getResultSet();\r
+ 47119 djd \r
+ 47119 djd String s ="";\r
+ 47119 djd if (ps == null) \r
+ 47119 djd s += indent + ps;\r
+ 47119 djd else\r
+ 47119 djd {\r
+368333 bernt s += indent + pkgid + pkgsn ;\r
+123827 kmarsden s += "\t" + getSQLText();\r
+ 47119 djd }\r
+ 47119 djd return s;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /** For a single result set, just echo the consistency token that the client sent us.\r
+ 47119 djd * For subsequent resultSets, just subtract the resultset number from\r
+ 47119 djd * the consistency token and that will differentiate the result sets.\r
+ 47119 djd * This seems to be what DB2 does\r
+ 47119 djd * @param rsNum - result set # starting with 0\r
+ 47119 djd * \r
+ 47119 djd * @return Consistency token for result set\r
+ 47119 djd */\r
+ 47119 djd \r
+368333 bernt protected ConsistencyToken calculateResultSetPkgcnstkn(int rsNum)\r
+ 47119 djd { \r
+368333 bernt ConsistencyToken consistToken = pkgcnstkn;\r
+ 47119 djd \r
+368333 bernt if (rsNum == 0 || pkgcnstkn == null)\r
+ 47119 djd return consistToken;\r
+ 47119 djd else\r
+ 47119 djd {\r
+368333 bernt BigInteger consistTokenBi =\r
+368333 bernt new BigInteger(consistToken.getBytes());\r
+368333 bernt BigInteger rsNumBi = BigInteger.valueOf(rsNum);\r
+368333 bernt consistTokenBi = consistTokenBi.subtract(rsNumBi);\r
+368333 bernt consistToken = new ConsistencyToken(consistTokenBi.toByteArray());\r
+ 47119 djd }\r
+ 47119 djd return consistToken;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected boolean isCallableStatement()\r
+ 47119 djd {\r
+ 47119 djd return isCall;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd private boolean isCallableSQL(String sql)\r
+ 47119 djd {\r
+ 47119 djd java.util.StringTokenizer tokenizer = new java.util.StringTokenizer\r
+ 47119 djd (sql, "\t\n\r\f=? (");\r
+ 47119 djd String firstToken = tokenizer.nextToken();\r
+ 47119 djd if (StringUtil.SQLEqualsIgnoreCase(firstToken, \r
+ 47119 djd "call")) // captures CALL...and ?=CALL...\r
+ 47119 djd return true;\r
+ 47119 djd return false;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd private void setupCallableStatementParams(CallableStatement cs) throws SQLException\r
+ 47119 djd {\r
+495543 kahatlen ParameterMetaData pmeta = getParameterMetaData();\r
+ 47119 djd int numElems = pmeta.getParameterCount();\r
+ 47119 djd \r
+ 47119 djd for ( int i = 0; i < numElems; i ++)\r
+ 47119 djd {\r
+ 47119 djd boolean outputFlag = false;\r
+ 47119 djd \r
+ 47119 djd int parameterMode = pmeta.getParameterMode(i + 1);\r
+ 47119 djd int parameterType = pmeta.getParameterType(i + 1);\r
+534985 kmarsden int parameterPrecision = pmeta.getPrecision(i + 1);\r
+534985 kmarsden int parameterScale = pmeta.getScale(i + 1);\r
+ 47119 djd \r
+ 47119 djd switch (parameterMode) {\r
+ 47119 djd case JDBC30Translation.PARAMETER_MODE_IN:\r
+ 47119 djd break;\r
+ 47119 djd case JDBC30Translation.PARAMETER_MODE_OUT:\r
+ 47119 djd case JDBC30Translation.PARAMETER_MODE_IN_OUT:\r
+ 47119 djd outputFlag = true;\r
+ 47119 djd break;\r
+ 47119 djd case JDBC30Translation.PARAMETER_MODE_UNKNOWN:\r
+ 47119 djd // It's only unknown if array\r
+ 47119 djd String objectType = pmeta.getParameterClassName(i+1);\r
+ 47119 djd parameterType =\r
+ 47119 djd getOutputParameterTypeFromClassName(objectType);\r
+ 47119 djd if (parameterType != NOT_OUTPUT_PARAM)\r
+ 47119 djd outputFlag = true;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd if (outputFlag)\r
+ 47119 djd {\r
+ 47119 djd if (outputTypes == null) //not initialized yet, since previously none output\r
+ 47119 djd {\r
+ 47119 djd outputTypes = new int[numElems];\r
+534985 kmarsden outputPrecision = new int [numElems];\r
+534985 kmarsden outputScale = new int [numElems];\r
+534985 kmarsden for (int j = 0; j < numElems; j++) {\r
+ 47119 djd outputTypes[j] = NOT_OUTPUT_PARAM; //default init value\r
+534985 kmarsden outputPrecision[j] = NOT_OUTPUT_PARAM;\r
+534985 kmarsden outputScale[j] = NOT_OUTPUT_PARAM;\r
+534985 kmarsden }\r
+ 47119 djd }\r
+ 47119 djd // save the output type so we can register when we parse\r
+ 47119 djd // the SQLDTA\r
+ 47119 djd outputTypes[i] = parameterType;\r
+534985 kmarsden outputPrecision[i] = parameterPrecision;\r
+534985 kmarsden outputScale[i] = parameterScale; \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd /** \r
+ 47119 djd Given an object class name get the paramameter type if the \r
+ 47119 djd parameter mode is unknown.\r
+ 47119 djd \r
+ 47119 djd Arrays except for byte arrrays are assumed to be output parameters\r
+ 47119 djd TINYINT output parameters are going to be broken because there\r
+ 47119 djd is no way to differentiate them from binary input parameters.\r
+ 47119 djd @param objectName Class name of object being evaluated.\r
+ 47119 djd indicating if this an output parameter\r
+ 47119 djd @return type from java.sql.Types\r
+ 47119 djd **/\r
+ 47119 djd \r
+ 47119 djd protected static int getOutputParameterTypeFromClassName(String\r
+ 47119 djd objectName)\r
+ 47119 djd {\r
+ 47119 djd \r
+ 47119 djd if (objectName.endsWith("[]"))\r
+ 47119 djd {\r
+ 47119 djd // For byte[] we are going to assume it is input.\r
+ 47119 djd // For TINYINT output params you gotta use \r
+ 47119 djd // object Integer[] or use a procedure \r
+ 47119 djd if (objectName.equals("byte[]"))\r
+ 47119 djd {\r
+ 47119 djd return NOT_OUTPUT_PARAM;\r
+ 47119 djd \r
+ 47119 djd //isOutParam[offset] = false;\r
+ 47119 djd //return java.sql.Types.VARBINARY;\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd // Known arrays are output parameters\r
+ 47119 djd // otherwise we pass it's a JAVA_OBJECT\r
+ 47119 djd if (objectName.equals("java.lang.Byte[]"))\r
+ 47119 djd return java.sql.Types.TINYINT;\r
+ 47119 djd \r
+ 47119 djd if (objectName.equals("byte[][]"))\r
+ 47119 djd return java.sql.Types.VARBINARY;\r
+ 47119 djd if (objectName.equals("java.lang.String[]"))\r
+ 47119 djd return java.sql.Types.VARCHAR; \r
+ 47119 djd if (objectName.equals("int[]") || \r
+ 47119 djd objectName.equals("java.lang.Integer[]"))\r
+ 47119 djd return java.sql.Types.INTEGER;\r
+ 47119 djd else if (objectName.equals("long[]")\r
+ 47119 djd || objectName.equals("java.lang.Long[]"))\r
+ 47119 djd return java.sql.Types.BIGINT;\r
+ 47119 djd else if (objectName.equals("java.math.BigDecimal[]"))\r
+ 47119 djd return java.sql.Types.NUMERIC;\r
+ 47119 djd else if (objectName.equals("boolean[]") || \r
+ 47119 djd objectName.equals("java.lang.Boolean[]"))\r
+ 47119 djd return java.sql.Types.BIT;\r
+ 47119 djd else if (objectName.equals("short[]"))\r
+ 47119 djd return java.sql.Types.SMALLINT;\r
+ 47119 djd else if (objectName.equals("float[]") ||\r
+ 47119 djd objectName.equals("java.lang.Float[]"))\r
+ 47119 djd return java.sql.Types.REAL;\r
+ 47119 djd else if (objectName.equals("double[]") ||\r
+ 47119 djd objectName.equals("java.lang.Double[]"))\r
+ 47119 djd return java.sql.Types.DOUBLE;\r
+ 47119 djd else if (objectName.equals("java.sql.Date[]"))\r
+ 47119 djd return java.sql.Types.DATE;\r
+ 47119 djd else if (objectName.equals("java.sql.Time[]"))\r
+ 47119 djd return java.sql.Types.TIME;\r
+ 47119 djd else if (objectName.equals("java.sql.Timestamp[]"))\r
+ 47119 djd return java.sql.Types.TIMESTAMP;\r
+ 47119 djd }\r
+ 47119 djd // Not one of the ones we know. This must be a JAVA_OBJECT\r
+ 47119 djd return NOT_OUTPUT_PARAM;\r
+ 47119 djd //isOutParam[offset] = false; \r
+ 47119 djd //return java.sql.Types.JAVA_OBJECT;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd public void registerAllOutParams() throws SQLException\r
+ 47119 djd {\r
+ 47119 djd if (isCall && (outputTypes != null))\r
+ 47119 djd for (int i = 1; i <= outputTypes.length; i ++)\r
+ 47119 djd registerOutParam(i);\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd public void registerOutParam(int paramNum) throws SQLException\r
+ 47119 djd {\r
+ 47119 djd CallableStatement cs;\r
+ 47119 djd if (isOutputParam(paramNum))\r
+ 47119 djd {\r
+ 47119 djd cs = (CallableStatement) ps;\r
+ 47119 djd cs.registerOutParameter(paramNum, getOutputParamType(paramNum));\r
+ 47119 djd }\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd protected boolean hasOutputParams()\r
+ 47119 djd {\r
+ 47119 djd return (outputTypes != null);\r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd /**\r
+ 47119 djd * is parameter an ouput parameter\r
+ 47119 djd * @param paramNum parameter number starting with 1.\r
+ 47119 djd * return true if this is an output parameter.\r
+ 47119 djd */\r
+ 47119 djd boolean isOutputParam(int paramNum)\r
+ 47119 djd {\r
+ 47119 djd if (outputTypes != null)\r
+ 47119 djd return (outputTypes[paramNum - 1] != NOT_OUTPUT_PARAM);\r
+ 47119 djd return false;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd /** \r
+ 47119 djd * get type for output parameter. \r
+ 47119 djd *\r
+ 47119 djd * @param paramNum - parameter number starting with 1\r
+ 47119 djd * @return jdbcType or NOT_OUTPUT_PARAM if this is not an output parameter\r
+ 47119 djd */\r
+ 47119 djd int getOutputParamType(int paramNum)\r
+ 47119 djd {\r
+ 47119 djd if (outputTypes != null)\r
+ 47119 djd return (outputTypes[ paramNum - 1 ]);\r
+ 47119 djd return NOT_OUTPUT_PARAM;\r
+ 47119 djd }\r
+ 47119 djd \r
+534985 kmarsden /** \r
+534985 kmarsden * get scale for output parameter. \r
+534985 kmarsden *\r
+534985 kmarsden * @param paramNum - parameter number starting with 1\r
+534985 kmarsden * @return scale or NOT_OUTPUT_PARAM if this is not an output parameter\r
+534985 kmarsden */\r
+534985 kmarsden int getOutputParamScale(int paramNum){\r
+534985 kmarsden if (outputScale != null)\r
+534985 kmarsden return (outputScale[paramNum -1]);\r
+534985 kmarsden return NOT_OUTPUT_PARAM;\r
+534985 kmarsden }\r
+534985 kmarsden \r
+534985 kmarsden /** \r
+534985 kmarsden * get precision for output parameter. \r
+534985 kmarsden *\r
+534985 kmarsden * @param paramNum - parameter number starting with 1\r
+534985 kmarsden * @return precision or NOT_OUTPUT_PARAM if this is not an output parameter\r
+534985 kmarsden */\r
+534985 kmarsden int getOutputParamPrecision(int paramNum){\r
+534985 kmarsden if (outputPrecision != null)\r
+534985 kmarsden return (outputPrecision[paramNum -1]);\r
+534985 kmarsden return NOT_OUTPUT_PARAM;\r
+534985 kmarsden }\r
+534985 kmarsden \r
+ 47119 djd private boolean isDynamicPkgid(String pkgid)\r
+ 47119 djd {\r
+ 47119 djd char size = pkgid.charAt(3);\r
+ 47119 djd \r
+ 47119 djd // separate attribute used for holdability in 5.1.60\r
+ 47119 djd // this is just for checking that it is a dynamic package\r
+ 47119 djd char holdability = pkgid.charAt(4); \r
+ 47119 djd return (pkgid.substring(0,3).equals("SYS") && (size == 'S' ||\r
+ 47119 djd size == 'L')\r
+ 47119 djd && (holdability == 'H' || holdability == 'N'));\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd \r
+ 47119 djd \r
+ 47119 djd private void parsePkgidToFindHoldability()\r
+ 47119 djd {\r
+ 47119 djd if (withHoldCursor != -1)\r
+ 47119 djd return;\r
+380278 djd \r
+ 47119 djd //First, check if holdability was passed as a SQL attribute "WITH HOLD" for this prepare. If yes, then withHoldCursor\r
+ 47119 djd //should not get overwritten by holdability from package name and that is why the check for -1\r
+ 47119 djd if (isDynamicPkgid(pkgid))\r
+380278 djd { \r
+ 47119 djd if(pkgid.charAt(4) == 'N')\r
+ 47119 djd withHoldCursor = JDBC30Translation.CLOSE_CURSORS_AT_COMMIT;\r
+ 47119 djd else \r
+ 47119 djd withHoldCursor = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;\r
+ 47119 djd }\r
+ 47119 djd else \r
+380278 djd { \r
+ 47119 djd withHoldCursor = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;\r
+ 47119 djd \r
+ 47119 djd }\r
+ 47119 djd }\r
+123827 kmarsden \r
+123827 kmarsden \r
+123827 kmarsden /**\r
+380278 djd * prepare a statement using EngineConnection.prepareStatement\r
+380278 djd * so that server can run on jdk131 and still pass holdability. \r
+123827 kmarsden * @param sqlStmt - SQL statement text\r
+123827 kmarsden * @param scrollType - scroll type\r
+126257 fuzzylogic * @param concurType - concurrency type\r
+123827 kmarsden * @param withHoldCursor - holdability\r
+123827 kmarsden * \r
+123827 kmarsden * @throws SQLException\r
+123827 kmarsden * @return Prepared Statement\r
+123827 kmarsden * @see java.sql.Connection#prepareStatement\r
+123827 kmarsden */\r
+123827 kmarsden private PreparedStatement prepareStatementJDBC3(String sqlStmt, int\r
+123827 kmarsden scrollType, int concurType,\r
+123827 kmarsden int withHoldCursor) throws SQLException\r
+123827 kmarsden {\r
+380278 djd EngineConnection conn = database.getConnection();\r
+380278 djd if (withHoldCursor == -1) {\r
+380278 djd // Holdability not explictly set, let the\r
+380278 djd // connection provide the default.\r
+380278 djd return conn.prepareStatement(sqlStmt,\r
+380278 djd scrollType, concurType);\r
+380278 djd }\r
+380278 djd \r
+380278 djd // Holdability explictly set. \r
+380278 djd return conn.prepareStatement(sqlStmt,\r
+380278 djd scrollType, concurType, withHoldCursor);\r
+123827 kmarsden }\r
+123827 kmarsden \r
+123827 kmarsden \r
+123827 kmarsden /** \r
+421435 davidvc * Retrieve the ParameterMetaData for the prepared statement. \r
+495543 kahatlen * @return ParameterMetaData for the prepared statement. \r
+123827 kmarsden * Note: there is no separate BrokeredParameterSetMetaData.\r
+123827 kmarsden */\r
+495543 kahatlen protected ParameterMetaData getParameterMetaData() throws SQLException\r
+123827 kmarsden {\r
+123827 kmarsden if (stmtPmeta != null)\r
+123827 kmarsden return stmtPmeta;\r
+123827 kmarsden \r
+495543 kahatlen stmtPmeta = ps.getParameterMetaData();\r
+421435 davidvc \r
+421435 davidvc return stmtPmeta;\r
+123827 kmarsden }\r
+123827 kmarsden \r
+123827 kmarsden /**\r
+123827 kmarsden * get more results using reflection.\r
+123827 kmarsden * @param current - flag to pass to Statement.getMoreResults(current)\r
+123827 kmarsden * @return true if there are more results.\r
+123827 kmarsden * @throws SQLException\r
+126257 fuzzylogic * @see java.sql.Statement#getMoreResults\r
+123827 kmarsden *\r
+123827 kmarsden */\r
+391691 djd private boolean getMoreResults(int current) throws SQLException\r
+391691 djd { \r
+495543 kahatlen return getPreparedStatement().getMoreResults(current);\r
+123827 kmarsden }\r
+123827 kmarsden \r
+123827 kmarsden /**\r
+123827 kmarsden * Use reflection to retrieve SQL Text for EmbedPreparedStatement \r
+123827 kmarsden * or BrokeredPreparedStatement.\r
+123827 kmarsden * @return SQL text\r
+123827 kmarsden */\r
+123827 kmarsden private String getSQLText() \r
+123827 kmarsden {\r
+123827 kmarsden String retVal = null;\r
+123827 kmarsden Class[] emptyPARAM = {};\r
+123827 kmarsden Object[] args = null;\r
+123827 kmarsden try {\r
+123827 kmarsden Method sh = getPreparedStatement().getClass().getMethod("getSQLText",emptyPARAM);\r
+123827 kmarsden retVal = (String) sh.invoke(getPreparedStatement(),args);\r
+123827 kmarsden }\r
+123827 kmarsden catch (Exception e)\r
+123827 kmarsden {\r
+123827 kmarsden // do nothing we will just return a null string\r
+123827 kmarsden }\r
+123827 kmarsden return retVal;\r
+123827 kmarsden \r
+123827 kmarsden }\r
+123827 kmarsden \r
+123827 kmarsden /** helper method to handle exceptions generated by methods invoked \r
+123827 kmarsden * through reflection.\r
+123827 kmarsden * @param e - exception thrown\r
+123827 kmarsden * @throws SQLException - actual exception that occurred\r
+123827 kmarsden */\r
+123827 kmarsden private void handleReflectionException(Exception e) throws SQLException\r
+123827 kmarsden {\r
+123827 kmarsden if (e instanceof InvocationTargetException) \r
+123827 kmarsden {\r
+123827 kmarsden Throwable t = ((InvocationTargetException) e).getTargetException();\r
+123827 kmarsden \r
+123827 kmarsden if (t instanceof SQLException)\r
+123827 kmarsden {\r
+123827 kmarsden throw (SQLException) t;\r
+123827 kmarsden }\r
+123827 kmarsden else\r
+124273 kmarsden {\r
+156229 kmarsden t.printStackTrace();\r
+123827 kmarsden throw Util.javaException(t);\r
+124273 kmarsden }\r
+123827 kmarsden }\r
+123827 kmarsden else\r
+123827 kmarsden // invoke can throw IllegalAccessException or \r
+123827 kmarsden // IllegalArgumentException, but these should not \r
+123827 kmarsden // occur from this code. Just in case we will throw it\r
+123827 kmarsden throw Util.javaException(e);\r
+123827 kmarsden \r
+123827 kmarsden }\r
+189752 kmarsden \r
+189752 kmarsden /**\r
+377367 bernt * Method to decide whether the ResultSet should be closed\r
+377367 bernt * implicitly based on the QRYCLSIMP value sent from the\r
+377367 bernt * client. Only forward-only result sets should be implicitly\r
+377367 bernt * closed. Some clients do not expect result sets to be closed\r
+377367 bernt * implicitly if the protocol is LMTBLKPRC.\r
+377367 bernt *\r
+377367 bernt * @param lmtblkprcOK <code>true</code> if the client expects\r
+377367 bernt * QRYCLSIMP to be respected for the LMTBLKPRC protocol\r
+189752 kmarsden * @return implicit close boolean\r
+377367 bernt * @exception SQLException\r
+189752 kmarsden */\r
+377367 bernt boolean isRSCloseImplicit(boolean lmtblkprcOK) throws SQLException {\r
+377367 bernt return\r
+377367 bernt (currentDrdaRs.qryclsimp == CodePoint.QRYCLSIMP_YES) &&\r
+377367 bernt !isScrollable() &&\r
+377367 bernt (lmtblkprcOK ||\r
+377367 bernt (currentDrdaRs.getQryprctyp() != CodePoint.LMTBLKPRC));\r
+189752 kmarsden }\r
+ 47119 djd }\r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r
+374029 bernt \r