--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.jdbc.EmbedCallableStatement\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.jdbc;\r
+\r
+import org.apache.derby.iapi.sql.ParameterValueSet;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import java.net.URL;\r
+import java.sql.Blob;\r
+import java.sql.CallableStatement;\r
+import java.sql.Clob;\r
+import java.sql.SQLException;\r
+import java.sql.Date;\r
+import java.sql.Time;\r
+import java.sql.Timestamp;\r
+import java.util.Calendar;\r
+\r
+/**\r
+ * Local implementation.\r
+ *\r
+ */\r
+public abstract class EmbedCallableStatement extends EmbedPreparedStatement\r
+ implements CallableStatement\r
+{\r
+ /*\r
+ ** True if we are of the form ? = CALL() -- i.e. true\r
+ ** if we have a return output parameter.\r
+ */\r
+ private boolean hasReturnOutputParameter;\r
+\r
+ protected boolean wasNull;\r
+\r
+ /**\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public EmbedCallableStatement (EmbedConnection conn, String sql,\r
+ int resultSetType,\r
+ int resultSetConcurrency,\r
+ int resultSetHoldability)\r
+ throws SQLException\r
+ {\r
+ super(conn, sql, false, \r
+ resultSetType,\r
+ resultSetConcurrency,\r
+ resultSetHoldability,\r
+ JDBC30Translation.NO_GENERATED_KEYS,\r
+ null,\r
+ null);\r
+\r
+ // mark our parameters as for a callable statement \r
+ ParameterValueSet pvs = getParms();\r
+\r
+ // do we have a return parameter?\r
+ hasReturnOutputParameter = pvs.hasReturnOutputParameter();\r
+ }\r
+\r
+ protected void checkRequiresCallableStatement(Activation activation) {\r
+ }\r
+\r
+ protected final boolean executeStatement(Activation a,\r
+ boolean executeQuery, boolean executeUpdate)\r
+ throws SQLException\r
+ {\r
+ // need this additional check (it's also in the super.executeStatement\r
+ // to ensure we have an activation for the getParams\r
+ checkExecStatus();\r
+ synchronized (getConnectionSynchronization())\r
+ {\r
+ wasNull = false;\r
+ //Don't fetch the getParms into a local varibale\r
+ //at this point because it is possible that the activation\r
+ //associated with this callable statement may have become\r
+ //stale. If the current activation is invalid, a new activation \r
+ //will be created for it in executeStatement call below. \r
+ //We should be using the ParameterValueSet associated with\r
+ //the activation associated to the CallableStatement after\r
+ //the executeStatement below. That ParameterValueSet is the\r
+ //right object to hold the return value from the CallableStatement.\r
+ try\r
+ {\r
+ getParms().validate();\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ /* KLUDGE - ? = CALL ... returns a ResultSet(). We\r
+ * need executeUpdate to be false in that case.\r
+ */\r
+ boolean execResult = super.executeStatement(a, executeQuery,\r
+ (executeUpdate && (! hasReturnOutputParameter)));\r
+\r
+ //Fetch the getParms into a local variable now because the\r
+ //activation associated with a CallableStatement at this \r
+ //point(after the executStatement) is the current activation. \r
+ //We can now safely stuff the return value of the \r
+ //CallableStatement into the following ParameterValueSet object.\r
+ ParameterValueSet pvs = getParms();\r
+\r
+ /*\r
+ ** If we have a return parameter, then we\r
+ ** consume it from the returned ResultSet\r
+ ** reset the ResultSet set to null.\r
+ */\r
+ if (hasReturnOutputParameter)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(results!=null, "null results even though we are supposed to have a return parameter");\r
+ }\r
+ boolean gotRow = results.next();\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(gotRow, "the return resultSet didn't have any rows");\r
+ }\r
+\r
+ try\r
+ {\r
+ DataValueDescriptor returnValue = pvs.getReturnValueForSet();\r
+ returnValue.setValueFromResultSet(results, 1, true);\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ finally {\r
+ results.close();\r
+ results = null;\r
+ }\r
+\r
+ // This is a form of ? = CALL which current is not a procedure call.\r
+ // Thus there cannot be any user result sets, so return false. execResult\r
+ // is set to true since a result set was returned, for the return parameter.\r
+ execResult = false;\r
+ }\r
+ return execResult;\r
+ }\r
+ }\r
+\r
+ /*\r
+ * CallableStatement interface\r
+ * (the PreparedStatement part implemented by EmbedPreparedStatement)\r
+ */\r
+\r
+ /**\r
+ * @see CallableStatement#registerOutParameter\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public final void registerOutParameter(int parameterIndex, int sqlType)\r
+ throws SQLException \r
+ {\r
+ checkStatus();\r
+\r
+ try {\r
+ getParms().registerOutParameter(parameterIndex-1, sqlType, -1);\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#registerOutParameter\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public final void registerOutParameter(int parameterIndex, int sqlType, int scale)\r
+ throws SQLException \r
+ {\r
+ checkStatus();\r
+\r
+ if (scale < 0)\r
+ throw newSQLException(SQLState.BAD_SCALE_VALUE, new Integer(scale));\r
+ try {\r
+ getParms().registerOutParameter(parameterIndex-1, sqlType, scale);\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ * JDBC 2.0\r
+ *\r
+ * Registers the designated output parameter\r
+ *\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public void registerOutParameter(int parameterIndex, int sqlType, \r
+ String typeName) \r
+ throws SQLException\r
+ {\r
+ throw Util.notImplemented("registerOutParameter");\r
+ }\r
+ \r
+ \r
+\r
+ /**\r
+ * @see CallableStatement#wasNull\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public boolean wasNull() throws SQLException \r
+ {\r
+ checkStatus();\r
+ return wasNull;\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getString\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public String getString(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ String v = getParms().getParameterForGet(parameterIndex-1).getString();\r
+ wasNull = (v == null);\r
+ return v;\r
+\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getBoolean\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public boolean getBoolean(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ boolean v = param.getBoolean();\r
+ wasNull = (!v) && param.isNull();\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getByte\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public byte getByte(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ byte b = param.getByte();\r
+ wasNull = (b == 0) && param.isNull();\r
+ return b;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getShort\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public short getShort(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ short s = param.getShort();\r
+ wasNull = (s == 0) && param.isNull();\r
+ return s;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getInt\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public int getInt(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ int v = param.getInt();\r
+ wasNull = (v == 0) && param.isNull();\r
+ return v;\r
+\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getLong\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public long getLong(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ long v = param.getLong();\r
+ wasNull = (v == 0L) && param.isNull();\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getFloat\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public float getFloat(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ float v = param.getFloat();\r
+ wasNull = (v == 0.0) && param.isNull();\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getDouble\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public double getDouble(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ DataValueDescriptor param = getParms().getParameterForGet(parameterIndex-1);\r
+ double v = param.getDouble();\r
+ wasNull = (v == 0.0) && param.isNull();\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getBytes\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public byte[] getBytes(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ byte[] v = getParms().getParameterForGet(parameterIndex-1).getBytes();\r
+ wasNull = (v == null);\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getDate\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public Date getDate(int parameterIndex) throws SQLException\r
+ {\r
+ checkStatus();\r
+ try {\r
+ Date v = getParms().getParameterForGet(parameterIndex-1).getDate(getCal());\r
+ wasNull = (v == null);\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getTime\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public Time getTime(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ Time v = getParms().getParameterForGet(parameterIndex-1).getTime(getCal());\r
+ wasNull = (v == null);\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getTimestamp\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public Timestamp getTimestamp(int parameterIndex)\r
+ throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ Timestamp v = getParms().getParameterForGet(parameterIndex-1).getTimestamp(getCal());\r
+ wasNull = (v == null);\r
+ return v;\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+ /**\r
+ * Get the value of a SQL DATE parameter as a java.sql.Date object\r
+ *\r
+ * @param parameterIndex the first parameter is 1, the second is 2, ...\r
+ * @return the parameter value; if the value is SQL NULL, the result is \r
+ * null\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public java.sql.Date getDate(int parameterIndex, Calendar cal) \r
+ throws SQLException \r
+ {\r
+ return getDate(parameterIndex);\r
+ }\r
+\r
+ /**\r
+ * Get the value of a SQL TIME parameter as a java.sql.Time object.\r
+ *\r
+ * @param parameterIndex the first parameter is 1, the second is 2, ...\r
+ * @return the parameter value; if the value is SQL NULL, the result is \r
+ * null\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public java.sql.Time getTime(int parameterIndex, Calendar cal) \r
+ throws SQLException \r
+ {\r
+ return getTime(parameterIndex);\r
+ }\r
+\r
+ /**\r
+ * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp \r
+ * object.\r
+ *\r
+ * @param parameterIndex the first parameter is 1, the second is 2, ...\r
+ * @return the parameter value; if the value is SQL NULL, the result is \r
+ * null\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal) \r
+ throws SQLException \r
+ {\r
+ return getTimestamp(parameterIndex);\r
+ }\r
+\r
+ /**\r
+ * @see CallableStatement#getObject\r
+ * @exception SQLException NoOutputParameters thrown.\r
+ */\r
+ public final Object getObject(int parameterIndex) throws SQLException \r
+ {\r
+ checkStatus();\r
+ try {\r
+ Object v = getParms().getParameterForGet(parameterIndex-1).getObject();\r
+ wasNull = (v == null);\r
+ return v;\r
+\r
+ } catch (StandardException e)\r
+ {\r
+ throw EmbedResultSet.noStateChangeException(e);\r
+ }\r
+ }\r
+ /**\r
+ * JDBC 3.0\r
+ *\r
+ * Retrieve the value of the designated JDBC DATALINK parameter as a java.net.URL object\r
+ *\r
+ * @param parameterIndex - the first parameter is 1, the second is 2\r
+ * @return a java.net.URL object that represents the JDBC DATALINK value used as\r
+ * the designated parameter\r
+ * @exception SQLException Feature not implemented for now.\r
+ */\r
+ public URL getURL(int parameterIndex)\r
+ throws SQLException\r
+ {\r
+ throw Util.notImplemented();\r
+ }\r
+\r
+ /**\r
+ * JDBC 3.0\r
+ *\r
+ * Sets the designated parameter to the given java.net.URL object. The driver\r
+ * converts this to an SQL DATALINK value when it sends it to the database.\r
+ *\r
+ * @param parameterName - the name of the parameter\r
+ * @param val - the parameter value\r
+ * @exception SQLException Feature not implemented for now.\r
+ */\r
+ public void setURL(String parameterName, URL val)\r
+ throws SQLException\r
+ {\r
+ throw Util.notImplemented();\r
+ }\r
+\r
+ /**\r
+ * JDBC 3.0\r
+ *\r
+ * Retrieves the value of a JDBC DATALINK parameter as a java.net.URL object\r
+ *\r
+ * @param parameterName - the name of the parameter\r
+ * @return the parameter value. If the value is SQL NULL, the result is null.\r
+ * @exception SQLException Feature not implemented for now.\r
+ */\r
+ public URL getURL(String parameterName)\r
+ throws SQLException\r
+ {\r
+ throw Util.notImplemented();\r
+ }\r
+\r
+ /**\r
+ * JDBC 2.0\r
+ *\r
+ * Get a BLOB OUT parameter.\r
+ *\r
+ * @param i the first parameter is 1, the second is 2, ...\r
+ * @return an object representing a BLOB\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public Blob getBlob (int i) throws SQLException {\r
+ throw Util.notImplemented();\r
+ }\r
+\r
+ /**\r
+ * JDBC 2.0\r
+ *\r
+ * Get a CLOB OUT parameter.\r
+ *\r
+ * @param i the first parameter is 1, the second is 2, ...\r
+ * @return an object representing a CLOB\r
+ * @exception SQLException if a database-access error occurs.\r
+ */\r
+ public Clob getClob (int i) throws SQLException {\r
+ throw Util.notImplemented();\r
+ }\r
+ public void addBatch() throws SQLException {\r
+\r
+ checkStatus();\r
+ ParameterValueSet pvs = getParms();\r
+\r
+ int numberOfParameters = pvs.getParameterCount();\r
+\r
+ for (int j=1; j<=numberOfParameters; j++) {\r
+\r
+ switch (pvs.getParameterMode(j)) {\r
+ case JDBC30Translation.PARAMETER_MODE_IN:\r
+ case JDBC30Translation.PARAMETER_MODE_UNKNOWN:\r
+ break;\r
+ case JDBC30Translation.PARAMETER_MODE_OUT:\r
+ case JDBC30Translation.PARAMETER_MODE_IN_OUT:\r
+ throw newSQLException(SQLState.OUTPUT_PARAMS_NOT_ALLOWED);\r
+ }\r
+ }\r
+\r
+ super.addBatch();\r
+ }\r
+}\r
+\r