001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.dbcp2;
019
020import java.io.InputStream;
021import java.io.Reader;
022import java.math.BigDecimal;
023import java.sql.Array;
024import java.sql.Blob;
025import java.sql.Clob;
026import java.sql.Date;
027import java.sql.NClob;
028import java.sql.PreparedStatement;
029import java.sql.Ref;
030import java.sql.ResultSet;
031import java.sql.ResultSetMetaData;
032import java.sql.RowId;
033import java.sql.SQLException;
034import java.sql.SQLXML;
035import java.sql.Statement;
036import java.sql.Time;
037import java.sql.Timestamp;
038import java.util.Calendar;
039
040/**
041 * A base delegating implementation of {@link PreparedStatement}.
042 * <p>
043 * All of the methods from the {@link PreparedStatement} interface simply check to see that the
044 * {@link PreparedStatement} is active, and call the corresponding method on the "delegate" provided in my constructor.
045 * <p>
046 * Extends AbandonedTrace to implement Statement tracking and logging of code which created the Statement. Tracking the
047 * Statement ensures that the Connection which created it can close any open Statement's on Connection close.
048 *
049 * @since 2.0
050 */
051public class DelegatingPreparedStatement extends DelegatingStatement implements PreparedStatement {
052
053    /**
054     * Create a wrapper for the Statement which traces this Statement to the Connection which created it and the code
055     * which created it.
056     *
057     * @param statement
058     *            the {@link PreparedStatement} to delegate all calls to.
059     * @param connection
060     *            the {@link DelegatingConnection} that created this statement.
061     */
062    public DelegatingPreparedStatement(final DelegatingConnection<?> connection, final PreparedStatement statement) {
063        super(connection, statement);
064    }
065
066    @Override
067    public ResultSet executeQuery() throws SQLException {
068        checkOpen();
069        if (getConnectionInternal() != null) {
070            getConnectionInternal().setLastUsed();
071        }
072        try {
073            return DelegatingResultSet.wrapResultSet(this, getDelegatePreparedStatement().executeQuery());
074        } catch (final SQLException e) {
075            handleException(e);
076            throw new AssertionError();
077        }
078    }
079
080    @Override
081    public int executeUpdate() throws SQLException {
082        checkOpen();
083        if (getConnectionInternal() != null) {
084            getConnectionInternal().setLastUsed();
085        }
086        try {
087            return getDelegatePreparedStatement().executeUpdate();
088        } catch (final SQLException e) {
089            handleException(e);
090            return 0;
091        }
092    }
093
094    private PreparedStatement getDelegatePreparedStatement() {
095        return (PreparedStatement) getDelegate();
096    }
097
098    @Override
099    public void setNull(final int parameterIndex, final int sqlType) throws SQLException {
100        checkOpen();
101        try {
102            getDelegatePreparedStatement().setNull(parameterIndex, sqlType);
103        } catch (final SQLException e) {
104            handleException(e);
105        }
106    }
107
108    @Override
109    public void setBoolean(final int parameterIndex, final boolean x) throws SQLException {
110        checkOpen();
111        try {
112            getDelegatePreparedStatement().setBoolean(parameterIndex, x);
113        } catch (final SQLException e) {
114            handleException(e);
115        }
116    }
117
118    @Override
119    public void setByte(final int parameterIndex, final byte x) throws SQLException {
120        checkOpen();
121        try {
122            getDelegatePreparedStatement().setByte(parameterIndex, x);
123        } catch (final SQLException e) {
124            handleException(e);
125        }
126    }
127
128    @Override
129    public void setShort(final int parameterIndex, final short x) throws SQLException {
130        checkOpen();
131        try {
132            getDelegatePreparedStatement().setShort(parameterIndex, x);
133        } catch (final SQLException e) {
134            handleException(e);
135        }
136    }
137
138    @Override
139    public void setInt(final int parameterIndex, final int x) throws SQLException {
140        checkOpen();
141        try {
142            getDelegatePreparedStatement().setInt(parameterIndex, x);
143        } catch (final SQLException e) {
144            handleException(e);
145        }
146    }
147
148    @Override
149    public void setLong(final int parameterIndex, final long x) throws SQLException {
150        checkOpen();
151        try {
152            getDelegatePreparedStatement().setLong(parameterIndex, x);
153        } catch (final SQLException e) {
154            handleException(e);
155        }
156    }
157
158    @Override
159    public void setFloat(final int parameterIndex, final float x) throws SQLException {
160        checkOpen();
161        try {
162            getDelegatePreparedStatement().setFloat(parameterIndex, x);
163        } catch (final SQLException e) {
164            handleException(e);
165        }
166    }
167
168    @Override
169    public void setDouble(final int parameterIndex, final double x) throws SQLException {
170        checkOpen();
171        try {
172            getDelegatePreparedStatement().setDouble(parameterIndex, x);
173        } catch (final SQLException e) {
174            handleException(e);
175        }
176    }
177
178    @Override
179    public void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException {
180        checkOpen();
181        try {
182            getDelegatePreparedStatement().setBigDecimal(parameterIndex, x);
183        } catch (final SQLException e) {
184            handleException(e);
185        }
186    }
187
188    @Override
189    public void setString(final int parameterIndex, final String x) throws SQLException {
190        checkOpen();
191        try {
192            getDelegatePreparedStatement().setString(parameterIndex, x);
193        } catch (final SQLException e) {
194            handleException(e);
195        }
196    }
197
198    @Override
199    public void setBytes(final int parameterIndex, final byte[] x) throws SQLException {
200        checkOpen();
201        try {
202            getDelegatePreparedStatement().setBytes(parameterIndex, x);
203        } catch (final SQLException e) {
204            handleException(e);
205        }
206    }
207
208    @Override
209    public void setDate(final int parameterIndex, final Date x) throws SQLException {
210        checkOpen();
211        try {
212            getDelegatePreparedStatement().setDate(parameterIndex, x);
213        } catch (final SQLException e) {
214            handleException(e);
215        }
216    }
217
218    @Override
219    public void setTime(final int parameterIndex, final Time x) throws SQLException {
220        checkOpen();
221        try {
222            getDelegatePreparedStatement().setTime(parameterIndex, x);
223        } catch (final SQLException e) {
224            handleException(e);
225        }
226    }
227
228    @Override
229    public void setTimestamp(final int parameterIndex, final Timestamp x) throws SQLException {
230        checkOpen();
231        try {
232            getDelegatePreparedStatement().setTimestamp(parameterIndex, x);
233        } catch (final SQLException e) {
234            handleException(e);
235        }
236    }
237
238    @Override
239    public void setAsciiStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
240        checkOpen();
241        try {
242            getDelegatePreparedStatement().setAsciiStream(parameterIndex, x, length);
243        } catch (final SQLException e) {
244            handleException(e);
245        }
246    }
247
248    /** @deprecated Use setAsciiStream(), setCharacterStream() or setNCharacterStream() */
249    @Deprecated
250    @Override
251    public void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
252        checkOpen();
253        try {
254            getDelegatePreparedStatement().setUnicodeStream(parameterIndex, x, length);
255        } catch (final SQLException e) {
256            handleException(e);
257        }
258    }
259
260    @Override
261    public void setBinaryStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
262        checkOpen();
263        try {
264            getDelegatePreparedStatement().setBinaryStream(parameterIndex, x, length);
265        } catch (final SQLException e) {
266            handleException(e);
267        }
268    }
269
270    @Override
271    public void clearParameters() throws SQLException {
272        checkOpen();
273        try {
274            getDelegatePreparedStatement().clearParameters();
275        } catch (final SQLException e) {
276            handleException(e);
277        }
278    }
279
280    @Override
281    public void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scale)
282            throws SQLException {
283        checkOpen();
284        try {
285            getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType, scale);
286        } catch (final SQLException e) {
287            handleException(e);
288        }
289    }
290
291    @Override
292    public void setObject(final int parameterIndex, final Object x, final int targetSqlType) throws SQLException {
293        checkOpen();
294        try {
295            getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType);
296        } catch (final SQLException e) {
297            handleException(e);
298        }
299    }
300
301    @Override
302    public void setObject(final int parameterIndex, final Object x) throws SQLException {
303        checkOpen();
304        try {
305            getDelegatePreparedStatement().setObject(parameterIndex, x);
306        } catch (final SQLException e) {
307            handleException(e);
308        }
309    }
310
311    @Override
312    public boolean execute() throws SQLException {
313        checkOpen();
314        if (getConnectionInternal() != null) {
315            getConnectionInternal().setLastUsed();
316        }
317        try {
318            return getDelegatePreparedStatement().execute();
319        } catch (final SQLException e) {
320            handleException(e);
321            return false;
322        }
323    }
324
325    @Override
326    public void addBatch() throws SQLException {
327        checkOpen();
328        try {
329            getDelegatePreparedStatement().addBatch();
330        } catch (final SQLException e) {
331            handleException(e);
332        }
333    }
334
335    @Override
336    public void setCharacterStream(final int parameterIndex, final Reader reader, final int length)
337            throws SQLException {
338        checkOpen();
339        try {
340            getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
341        } catch (final SQLException e) {
342            handleException(e);
343        }
344    }
345
346    @Override
347    public void setRef(final int i, final Ref x) throws SQLException {
348        checkOpen();
349        try {
350            getDelegatePreparedStatement().setRef(i, x);
351        } catch (final SQLException e) {
352            handleException(e);
353        }
354    }
355
356    @Override
357    public void setBlob(final int i, final Blob x) throws SQLException {
358        checkOpen();
359        try {
360            getDelegatePreparedStatement().setBlob(i, x);
361        } catch (final SQLException e) {
362            handleException(e);
363        }
364    }
365
366    @Override
367    public void setClob(final int i, final Clob x) throws SQLException {
368        checkOpen();
369        try {
370            getDelegatePreparedStatement().setClob(i, x);
371        } catch (final SQLException e) {
372            handleException(e);
373        }
374    }
375
376    @Override
377    public void setArray(final int i, final Array x) throws SQLException {
378        checkOpen();
379        try {
380            getDelegatePreparedStatement().setArray(i, x);
381        } catch (final SQLException e) {
382            handleException(e);
383        }
384    }
385
386    @Override
387    public ResultSetMetaData getMetaData() throws SQLException {
388        checkOpen();
389        try {
390            return getDelegatePreparedStatement().getMetaData();
391        } catch (final SQLException e) {
392            handleException(e);
393            throw new AssertionError();
394        }
395    }
396
397    @Override
398    public void setDate(final int parameterIndex, final Date x, final Calendar cal) throws SQLException {
399        checkOpen();
400        try {
401            getDelegatePreparedStatement().setDate(parameterIndex, x, cal);
402        } catch (final SQLException e) {
403            handleException(e);
404        }
405    }
406
407    @Override
408    public void setTime(final int parameterIndex, final Time x, final Calendar cal) throws SQLException {
409        checkOpen();
410        try {
411            getDelegatePreparedStatement().setTime(parameterIndex, x, cal);
412        } catch (final SQLException e) {
413            handleException(e);
414        }
415    }
416
417    @Override
418    public void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) throws SQLException {
419        checkOpen();
420        try {
421            getDelegatePreparedStatement().setTimestamp(parameterIndex, x, cal);
422        } catch (final SQLException e) {
423            handleException(e);
424        }
425    }
426
427    @Override
428    public void setNull(final int paramIndex, final int sqlType, final String typeName) throws SQLException {
429        checkOpen();
430        try {
431            getDelegatePreparedStatement().setNull(paramIndex, sqlType, typeName);
432        } catch (final SQLException e) {
433            handleException(e);
434        }
435    }
436
437    /**
438     * Returns a String representation of this object.
439     *
440     * @return String
441     */
442    @SuppressWarnings("resource")
443    @Override
444    public String toString() {
445        final Statement statement = getDelegate();
446        return statement == null ? "NULL" : statement.toString();
447    }
448
449    @Override
450    public void setURL(final int parameterIndex, final java.net.URL x) throws SQLException {
451        checkOpen();
452        try {
453            getDelegatePreparedStatement().setURL(parameterIndex, x);
454        } catch (final SQLException e) {
455            handleException(e);
456        }
457    }
458
459    @Override
460    public java.sql.ParameterMetaData getParameterMetaData() throws SQLException {
461        checkOpen();
462        try {
463            return getDelegatePreparedStatement().getParameterMetaData();
464        } catch (final SQLException e) {
465            handleException(e);
466            throw new AssertionError();
467        }
468    }
469
470    @Override
471    public void setRowId(final int parameterIndex, final RowId value) throws SQLException {
472        checkOpen();
473        try {
474            getDelegatePreparedStatement().setRowId(parameterIndex, value);
475        } catch (final SQLException e) {
476            handleException(e);
477        }
478    }
479
480    @Override
481    public void setNString(final int parameterIndex, final String value) throws SQLException {
482        checkOpen();
483        try {
484            getDelegatePreparedStatement().setNString(parameterIndex, value);
485        } catch (final SQLException e) {
486            handleException(e);
487        }
488    }
489
490    @Override
491    public void setNCharacterStream(final int parameterIndex, final Reader value, final long length)
492            throws SQLException {
493        checkOpen();
494        try {
495            getDelegatePreparedStatement().setNCharacterStream(parameterIndex, value, length);
496        } catch (final SQLException e) {
497            handleException(e);
498        }
499    }
500
501    @Override
502    public void setNClob(final int parameterIndex, final NClob value) throws SQLException {
503        checkOpen();
504        try {
505            getDelegatePreparedStatement().setNClob(parameterIndex, value);
506        } catch (final SQLException e) {
507            handleException(e);
508        }
509    }
510
511    @Override
512    public void setClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
513        checkOpen();
514        try {
515            getDelegatePreparedStatement().setClob(parameterIndex, reader, length);
516        } catch (final SQLException e) {
517            handleException(e);
518        }
519    }
520
521    @Override
522    public void setBlob(final int parameterIndex, final InputStream inputStream, final long length)
523            throws SQLException {
524        checkOpen();
525        try {
526            getDelegatePreparedStatement().setBlob(parameterIndex, inputStream, length);
527        } catch (final SQLException e) {
528            handleException(e);
529        }
530    }
531
532    @Override
533    public void setNClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
534        checkOpen();
535        try {
536            getDelegatePreparedStatement().setNClob(parameterIndex, reader, length);
537        } catch (final SQLException e) {
538            handleException(e);
539        }
540    }
541
542    @Override
543    public void setSQLXML(final int parameterIndex, final SQLXML value) throws SQLException {
544        checkOpen();
545        try {
546            getDelegatePreparedStatement().setSQLXML(parameterIndex, value);
547        } catch (final SQLException e) {
548            handleException(e);
549        }
550    }
551
552    @Override
553    public void setAsciiStream(final int parameterIndex, final InputStream inputStream, final long length)
554            throws SQLException {
555        checkOpen();
556        try {
557            getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream, length);
558        } catch (final SQLException e) {
559            handleException(e);
560        }
561    }
562
563    @Override
564    public void setBinaryStream(final int parameterIndex, final InputStream inputStream, final long length)
565            throws SQLException {
566        checkOpen();
567        try {
568            getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream, length);
569        } catch (final SQLException e) {
570            handleException(e);
571        }
572    }
573
574    @Override
575    public void setCharacterStream(final int parameterIndex, final Reader reader, final long length)
576            throws SQLException {
577        checkOpen();
578        try {
579            getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
580        } catch (final SQLException e) {
581            handleException(e);
582        }
583    }
584
585    @Override
586    public void setAsciiStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
587        checkOpen();
588        try {
589            getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream);
590        } catch (final SQLException e) {
591            handleException(e);
592        }
593    }
594
595    @Override
596    public void setBinaryStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
597        checkOpen();
598        try {
599            getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream);
600        } catch (final SQLException e) {
601            handleException(e);
602        }
603    }
604
605    @Override
606    public void setCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
607        checkOpen();
608        try {
609            getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader);
610        } catch (final SQLException e) {
611            handleException(e);
612        }
613    }
614
615    @Override
616    public void setNCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
617        checkOpen();
618        try {
619            getDelegatePreparedStatement().setNCharacterStream(parameterIndex, reader);
620        } catch (final SQLException e) {
621            handleException(e);
622        }
623    }
624
625    @Override
626    public void setClob(final int parameterIndex, final Reader reader) throws SQLException {
627        checkOpen();
628        try {
629            getDelegatePreparedStatement().setClob(parameterIndex, reader);
630        } catch (final SQLException e) {
631            handleException(e);
632        }
633    }
634
635    @Override
636    public void setBlob(final int parameterIndex, final InputStream inputStream) throws SQLException {
637        checkOpen();
638        try {
639            getDelegatePreparedStatement().setBlob(parameterIndex, inputStream);
640        } catch (final SQLException e) {
641            handleException(e);
642        }
643    }
644
645    @Override
646    public void setNClob(final int parameterIndex, final Reader reader) throws SQLException {
647        checkOpen();
648        try {
649            getDelegatePreparedStatement().setNClob(parameterIndex, reader);
650        } catch (final SQLException e) {
651            handleException(e);
652        }
653    }
654}