001: /*
002:
003: Derby - Class org.apache.derby.impl.jdbc.EmbedCallableStatement
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.jdbc;
023:
024: import org.apache.derby.iapi.sql.ParameterValueSet;
025: import org.apache.derby.iapi.sql.Activation;
026: import org.apache.derby.iapi.error.StandardException;
027: import org.apache.derby.iapi.types.DataValueDescriptor;
028:
029: import org.apache.derby.iapi.services.sanity.SanityManager;
030:
031: import org.apache.derby.iapi.reference.JDBC30Translation;
032: import org.apache.derby.iapi.reference.SQLState;
033:
034: import java.net.URL;
035: import java.sql.Blob;
036: import java.sql.CallableStatement;
037: import java.sql.Clob;
038: import java.sql.SQLException;
039: import java.sql.Date;
040: import java.sql.Time;
041: import java.sql.Timestamp;
042: import java.util.Calendar;
043:
044: /**
045: * Local implementation.
046: *
047: * @author ames
048: */
049: public abstract class EmbedCallableStatement extends
050: EmbedPreparedStatement implements CallableStatement {
051: /*
052: ** True if we are of the form ? = CALL() -- i.e. true
053: ** if we have a return output parameter.
054: */
055: private boolean hasReturnOutputParameter;
056:
057: protected boolean wasNull;
058:
059: /**
060: * @exception SQLException thrown on failure
061: */
062: public EmbedCallableStatement(EmbedConnection conn, String sql,
063: int resultSetType, int resultSetConcurrency,
064: int resultSetHoldability) throws SQLException {
065: super (conn, sql, false, resultSetType, resultSetConcurrency,
066: resultSetHoldability,
067: JDBC30Translation.NO_GENERATED_KEYS, null, null);
068:
069: // mark our parameters as for a callable statement
070: ParameterValueSet pvs = getParms();
071:
072: // do we have a return parameter?
073: hasReturnOutputParameter = pvs.hasReturnOutputParameter();
074: }
075:
076: protected void checkRequiresCallableStatement(Activation activation) {
077: }
078:
079: protected final boolean executeStatement(Activation a,
080: boolean executeQuery, boolean executeUpdate)
081: throws SQLException {
082: // need this additional check (it's also in the super.executeStatement
083: // to ensure we have an activation for the getParams
084: checkExecStatus();
085: synchronized (getConnectionSynchronization()) {
086: wasNull = false;
087: ParameterValueSet pvs = getParms();
088: try {
089: pvs.validate();
090:
091: } catch (StandardException e) {
092: throw EmbedResultSet.noStateChangeException(e);
093: }
094:
095: /* KLUDGE - ? = CALL ... returns a ResultSet(). We
096: * need executeUpdate to be false in that case.
097: */
098: boolean execResult = super .executeStatement(a,
099: executeQuery,
100: (executeUpdate && (!hasReturnOutputParameter)));
101:
102: /*
103: ** If we have a return parameter, then we
104: ** consume it from the returned ResultSet
105: ** reset the ResultSet set to null.
106: */
107: if (hasReturnOutputParameter) {
108: if (SanityManager.DEBUG) {
109: SanityManager
110: .ASSERT(results != null,
111: "null results even though we are supposed to have a return parameter");
112: }
113: boolean gotRow = results.next();
114: if (SanityManager.DEBUG) {
115: SanityManager
116: .ASSERT(gotRow,
117: "the return resultSet didn't have any rows");
118: }
119:
120: try {
121: DataValueDescriptor returnValue = pvs
122: .getReturnValueForSet();
123: returnValue.setValueFromResultSet(results, 1, true);
124: } catch (StandardException e) {
125: throw EmbedResultSet.noStateChangeException(e);
126: } finally {
127: results = null;
128: }
129:
130: // This is a form of ? = CALL which current is not a procedure call.
131: // Thus there cannot be any user result sets, so return false. execResult
132: // is set to true since a result set was returned, for the return parameter.
133: execResult = false;
134: }
135: return execResult;
136: }
137: }
138:
139: /*
140: * CallableStatement interface
141: * (the PreparedStatement part implemented by EmbedPreparedStatement)
142: */
143:
144: /**
145: * @see CallableStatement#registerOutParameter
146: * @exception SQLException NoOutputParameters thrown.
147: */
148: public final void registerOutParameter(int parameterIndex,
149: int sqlType) throws SQLException {
150: checkStatus();
151:
152: try {
153: getParms().registerOutParameter(parameterIndex - 1,
154: sqlType, -1);
155: } catch (StandardException e) {
156: throw EmbedResultSet.noStateChangeException(e);
157: }
158: }
159:
160: /**
161: * @see CallableStatement#registerOutParameter
162: * @exception SQLException NoOutputParameters thrown.
163: */
164: public final void registerOutParameter(int parameterIndex,
165: int sqlType, int scale) throws SQLException {
166: checkStatus();
167:
168: if (scale < 0)
169: throw newSQLException(SQLState.BAD_SCALE_VALUE,
170: new Integer(scale));
171: try {
172: getParms().registerOutParameter(parameterIndex - 1,
173: sqlType, scale);
174: } catch (StandardException e) {
175: throw EmbedResultSet.noStateChangeException(e);
176: }
177:
178: }
179:
180: /**
181: * JDBC 2.0
182: *
183: * Registers the designated output parameter
184: *
185: * @exception SQLException if a database-access error occurs.
186: */
187: public void registerOutParameter(int parameterIndex, int sqlType,
188: String typeName) throws SQLException {
189: throw Util.notImplemented("registerOutParameter");
190: }
191:
192: /**
193: * @see CallableStatement#wasNull
194: * @exception SQLException NoOutputParameters thrown.
195: */
196: public boolean wasNull() throws SQLException {
197: checkStatus();
198: return wasNull;
199: }
200:
201: /**
202: * @see CallableStatement#getString
203: * @exception SQLException NoOutputParameters thrown.
204: */
205: public String getString(int parameterIndex) throws SQLException {
206: checkStatus();
207: try {
208: String v = getParms()
209: .getParameterForGet(parameterIndex - 1).getString();
210: wasNull = (v == null);
211: return v;
212:
213: } catch (StandardException e) {
214: throw EmbedResultSet.noStateChangeException(e);
215: }
216: }
217:
218: /**
219: * @see CallableStatement#getBoolean
220: * @exception SQLException NoOutputParameters thrown.
221: */
222: public boolean getBoolean(int parameterIndex) throws SQLException {
223: checkStatus();
224: try {
225: DataValueDescriptor param = getParms().getParameterForGet(
226: parameterIndex - 1);
227: boolean v = param.getBoolean();
228: wasNull = (!v) && param.isNull();
229: return v;
230: } catch (StandardException e) {
231: throw EmbedResultSet.noStateChangeException(e);
232: }
233:
234: }
235:
236: /**
237: * @see CallableStatement#getByte
238: * @exception SQLException NoOutputParameters thrown.
239: */
240: public byte getByte(int parameterIndex) throws SQLException {
241: checkStatus();
242: try {
243: DataValueDescriptor param = getParms().getParameterForGet(
244: parameterIndex - 1);
245: byte b = param.getByte();
246: wasNull = (b == 0) && param.isNull();
247: return b;
248: } catch (StandardException e) {
249: throw EmbedResultSet.noStateChangeException(e);
250: }
251:
252: }
253:
254: /**
255: * @see CallableStatement#getShort
256: * @exception SQLException NoOutputParameters thrown.
257: */
258: public short getShort(int parameterIndex) throws SQLException {
259: checkStatus();
260: try {
261: DataValueDescriptor param = getParms().getParameterForGet(
262: parameterIndex - 1);
263: short s = param.getShort();
264: wasNull = (s == 0) && param.isNull();
265: return s;
266: } catch (StandardException e) {
267: throw EmbedResultSet.noStateChangeException(e);
268: }
269:
270: }
271:
272: /**
273: * @see CallableStatement#getInt
274: * @exception SQLException NoOutputParameters thrown.
275: */
276: public int getInt(int parameterIndex) throws SQLException {
277: checkStatus();
278:
279: try {
280: DataValueDescriptor param = getParms().getParameterForGet(
281: parameterIndex - 1);
282: int v = param.getInt();
283: wasNull = (v == 0) && param.isNull();
284: return v;
285:
286: } catch (StandardException e) {
287: throw EmbedResultSet.noStateChangeException(e);
288: }
289: }
290:
291: /**
292: * @see CallableStatement#getLong
293: * @exception SQLException NoOutputParameters thrown.
294: */
295: public long getLong(int parameterIndex) throws SQLException {
296: checkStatus();
297: try {
298: DataValueDescriptor param = getParms().getParameterForGet(
299: parameterIndex - 1);
300: long v = param.getLong();
301: wasNull = (v == 0L) && param.isNull();
302: return v;
303: } catch (StandardException e) {
304: throw EmbedResultSet.noStateChangeException(e);
305: }
306:
307: }
308:
309: /**
310: * @see CallableStatement#getFloat
311: * @exception SQLException NoOutputParameters thrown.
312: */
313: public float getFloat(int parameterIndex) throws SQLException {
314: checkStatus();
315: try {
316: DataValueDescriptor param = getParms().getParameterForGet(
317: parameterIndex - 1);
318: float v = param.getFloat();
319: wasNull = (v == 0.0) && param.isNull();
320: return v;
321: } catch (StandardException e) {
322: throw EmbedResultSet.noStateChangeException(e);
323: }
324: }
325:
326: /**
327: * @see CallableStatement#getDouble
328: * @exception SQLException NoOutputParameters thrown.
329: */
330: public double getDouble(int parameterIndex) throws SQLException {
331: checkStatus();
332: try {
333: DataValueDescriptor param = getParms().getParameterForGet(
334: parameterIndex - 1);
335: double v = param.getDouble();
336: wasNull = (v == 0.0) && param.isNull();
337: return v;
338: } catch (StandardException e) {
339: throw EmbedResultSet.noStateChangeException(e);
340: }
341:
342: }
343:
344: /**
345: * @see CallableStatement#getBytes
346: * @exception SQLException NoOutputParameters thrown.
347: */
348: public byte[] getBytes(int parameterIndex) throws SQLException {
349: checkStatus();
350: try {
351: byte[] v = getParms()
352: .getParameterForGet(parameterIndex - 1).getBytes();
353: wasNull = (v == null);
354: return v;
355: } catch (StandardException e) {
356: throw EmbedResultSet.noStateChangeException(e);
357: }
358:
359: }
360:
361: /**
362: * @see CallableStatement#getDate
363: * @exception SQLException NoOutputParameters thrown.
364: */
365: public Date getDate(int parameterIndex) throws SQLException {
366: checkStatus();
367: try {
368: Date v = getParms().getParameterForGet(parameterIndex - 1)
369: .getDate(getCal());
370: wasNull = (v == null);
371: return v;
372: } catch (StandardException e) {
373: throw EmbedResultSet.noStateChangeException(e);
374: }
375:
376: }
377:
378: /**
379: * @see CallableStatement#getTime
380: * @exception SQLException NoOutputParameters thrown.
381: */
382: public Time getTime(int parameterIndex) throws SQLException {
383: checkStatus();
384: try {
385: Time v = getParms().getParameterForGet(parameterIndex - 1)
386: .getTime(getCal());
387: wasNull = (v == null);
388: return v;
389: } catch (StandardException e) {
390: throw EmbedResultSet.noStateChangeException(e);
391: }
392:
393: }
394:
395: /**
396: * @see CallableStatement#getTimestamp
397: * @exception SQLException NoOutputParameters thrown.
398: */
399: public Timestamp getTimestamp(int parameterIndex)
400: throws SQLException {
401: checkStatus();
402: try {
403: Timestamp v = getParms().getParameterForGet(
404: parameterIndex - 1).getTimestamp(getCal());
405: wasNull = (v == null);
406: return v;
407: } catch (StandardException e) {
408: throw EmbedResultSet.noStateChangeException(e);
409: }
410: }
411:
412: /**
413: * Get the value of a SQL DATE parameter as a java.sql.Date object
414: *
415: * @param parameterIndex the first parameter is 1, the second is 2, ...
416: * @return the parameter value; if the value is SQL NULL, the result is
417: * null
418: * @exception SQLException if a database-access error occurs.
419: */
420: public java.sql.Date getDate(int parameterIndex, Calendar cal)
421: throws SQLException {
422: return getDate(parameterIndex);
423: }
424:
425: /**
426: * Get the value of a SQL TIME parameter as a java.sql.Time object.
427: *
428: * @param parameterIndex the first parameter is 1, the second is 2, ...
429: * @return the parameter value; if the value is SQL NULL, the result is
430: * null
431: * @exception SQLException if a database-access error occurs.
432: */
433: public java.sql.Time getTime(int parameterIndex, Calendar cal)
434: throws SQLException {
435: return getTime(parameterIndex);
436: }
437:
438: /**
439: * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp
440: * object.
441: *
442: * @param parameterIndex the first parameter is 1, the second is 2, ...
443: * @return the parameter value; if the value is SQL NULL, the result is
444: * null
445: * @exception SQLException if a database-access error occurs.
446: */
447: public java.sql.Timestamp getTimestamp(int parameterIndex,
448: Calendar cal) throws SQLException {
449: return getTimestamp(parameterIndex);
450: }
451:
452: /**
453: * @see CallableStatement#getObject
454: * @exception SQLException NoOutputParameters thrown.
455: */
456: public final Object getObject(int parameterIndex)
457: throws SQLException {
458: checkStatus();
459: try {
460: Object v = getParms()
461: .getParameterForGet(parameterIndex - 1).getObject();
462: wasNull = (v == null);
463: return v;
464:
465: } catch (StandardException e) {
466: throw EmbedResultSet.noStateChangeException(e);
467: }
468: }
469:
470: /**
471: * JDBC 3.0
472: *
473: * Retrieve the value of the designated JDBC DATALINK parameter as a java.net.URL object
474: *
475: * @param parameterIndex - the first parameter is 1, the second is 2
476: * @return a java.net.URL object that represents the JDBC DATALINK value used as
477: * the designated parameter
478: * @exception SQLException Feature not implemented for now.
479: */
480: public URL getURL(int parameterIndex) throws SQLException {
481: throw Util.notImplemented();
482: }
483:
484: /**
485: * JDBC 3.0
486: *
487: * Sets the designated parameter to the given java.net.URL object. The driver
488: * converts this to an SQL DATALINK value when it sends it to the database.
489: *
490: * @param parameterName - the name of the parameter
491: * @param val - the parameter value
492: * @exception SQLException Feature not implemented for now.
493: */
494: public void setURL(String parameterName, URL val)
495: throws SQLException {
496: throw Util.notImplemented();
497: }
498:
499: /**
500: * JDBC 3.0
501: *
502: * Retrieves the value of a JDBC DATALINK parameter as a java.net.URL object
503: *
504: * @param parameterName - the name of the parameter
505: * @return the parameter value. If the value is SQL NULL, the result is null.
506: * @exception SQLException Feature not implemented for now.
507: */
508: public URL getURL(String parameterName) throws SQLException {
509: throw Util.notImplemented();
510: }
511:
512: /**
513: * JDBC 2.0
514: *
515: * Get a BLOB OUT parameter.
516: *
517: * @param i the first parameter is 1, the second is 2, ...
518: * @return an object representing a BLOB
519: * @exception SQLException if a database-access error occurs.
520: */
521: public Blob getBlob(int i) throws SQLException {
522: throw Util.notImplemented();
523: }
524:
525: /**
526: * JDBC 2.0
527: *
528: * Get a CLOB OUT parameter.
529: *
530: * @param i the first parameter is 1, the second is 2, ...
531: * @return an object representing a CLOB
532: * @exception SQLException if a database-access error occurs.
533: */
534: public Clob getClob(int i) throws SQLException {
535: throw Util.notImplemented();
536: }
537:
538: public void addBatch() throws SQLException {
539:
540: checkStatus();
541: ParameterValueSet pvs = getParms();
542:
543: int numberOfParameters = pvs.getParameterCount();
544:
545: for (int j = 1; j <= numberOfParameters; j++) {
546:
547: switch (pvs.getParameterMode(j)) {
548: case JDBC30Translation.PARAMETER_MODE_IN:
549: case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
550: break;
551: case JDBC30Translation.PARAMETER_MODE_OUT:
552: case JDBC30Translation.PARAMETER_MODE_IN_OUT:
553: throw newSQLException(SQLState.OUTPUT_PARAMS_NOT_ALLOWED);
554: }
555: }
556:
557: super.addBatch();
558: }
559: }
|