View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.dbcp2;
18  
19  import java.io.InputStream;
20  import java.io.Reader;
21  import java.math.BigDecimal;
22  import java.sql.Array;
23  import java.sql.Blob;
24  import java.sql.Clob;
25  import java.sql.Date;
26  import java.sql.NClob;
27  import java.sql.PreparedStatement;
28  import java.sql.Ref;
29  import java.sql.ResultSet;
30  import java.sql.ResultSetMetaData;
31  import java.sql.RowId;
32  import java.sql.SQLException;
33  import java.sql.SQLType;
34  import java.sql.SQLXML;
35  import java.sql.Statement;
36  import java.sql.Time;
37  import java.sql.Timestamp;
38  import java.util.ArrayList;
39  import java.util.Calendar;
40  import java.util.List;
41  
42  /**
43   * A base delegating implementation of {@link PreparedStatement}.
44   * <p>
45   * All of the methods from the {@link PreparedStatement} interface simply check to see that the
46   * {@link PreparedStatement} is active, and call the corresponding method on the "delegate" provided in my constructor.
47   * <p>
48   * Extends AbandonedTrace to implement Statement tracking and logging of code which created the Statement. Tracking the
49   * Statement ensures that the Connection which created it can close any open Statement's on Connection close.
50   *
51   * @since 2.0
52   */
53  public class DelegatingPreparedStatement extends DelegatingStatement implements PreparedStatement {
54  
55      /**
56       * Create a wrapper for the Statement which traces this Statement to the Connection which created it and the code
57       * which created it.
58       *
59       * @param statement
60       *            the {@link PreparedStatement} to delegate all calls to.
61       * @param connection
62       *            the {@link DelegatingConnection} that created this statement.
63       */
64      public DelegatingPreparedStatement(final DelegatingConnection<?> connection, final PreparedStatement statement) {
65          super(connection, statement);
66      }
67  
68      @Override
69      public void addBatch() throws SQLException {
70          checkOpen();
71          try {
72              getDelegatePreparedStatement().addBatch();
73          } catch (final SQLException e) {
74              handleException(e);
75          }
76      }
77  
78      @Override
79      public void clearParameters() throws SQLException {
80          checkOpen();
81          try {
82              getDelegatePreparedStatement().clearParameters();
83          } catch (final SQLException e) {
84              handleException(e);
85          }
86      }
87  
88      @Override
89      public boolean execute() throws SQLException {
90          checkOpen();
91          if (getConnectionInternal() != null) {
92              getConnectionInternal().setLastUsed();
93          }
94          try {
95              return getDelegatePreparedStatement().execute();
96          } catch (final SQLException e) {
97              handleException(e);
98              return false;
99          }
100     }
101 
102     /**
103      * @since 2.5.0
104      */
105     @Override
106     public long executeLargeUpdate() throws SQLException {
107         checkOpen();
108         try {
109             return getDelegatePreparedStatement().executeLargeUpdate();
110         } catch (final SQLException e) {
111             handleException(e);
112             return 0;
113         }
114     }
115 
116     @Override
117     public ResultSet executeQuery() throws SQLException {
118         checkOpen();
119         if (getConnectionInternal() != null) {
120             getConnectionInternal().setLastUsed();
121         }
122         try {
123             return DelegatingResultSet.wrapResultSet(this, getDelegatePreparedStatement().executeQuery());
124         } catch (final SQLException e) {
125             handleException(e);
126             throw new AssertionError();
127         }
128     }
129 
130     @Override
131     public int executeUpdate() throws SQLException {
132         checkOpen();
133         if (getConnectionInternal() != null) {
134             getConnectionInternal().setLastUsed();
135         }
136         try {
137             return getDelegatePreparedStatement().executeUpdate();
138         } catch (final SQLException e) {
139             handleException(e);
140             return 0;
141         }
142     }
143 
144     private PreparedStatement getDelegatePreparedStatement() {
145         return (PreparedStatement) getDelegate();
146     }
147 
148     @Override
149     public ResultSetMetaData getMetaData() throws SQLException {
150         checkOpen();
151         try {
152             return getDelegatePreparedStatement().getMetaData();
153         } catch (final SQLException e) {
154             handleException(e);
155             throw new AssertionError();
156         }
157     }
158 
159     @Override
160     public java.sql.ParameterMetaData getParameterMetaData() throws SQLException {
161         checkOpen();
162         try {
163             return getDelegatePreparedStatement().getParameterMetaData();
164         } catch (final SQLException e) {
165             handleException(e);
166             throw new AssertionError();
167         }
168     }
169 
170     protected void prepareToReturn() throws SQLException {
171         setClosedInternal(true);
172         removeThisTrace(getConnectionInternal());
173 
174         // The JDBC spec requires that a statement close any open
175         // ResultSet's when it is closed.
176         // FIXME The PreparedStatement we're wrapping should handle this for us.
177         // See DBCP-10 for what could happen when ResultSets are closed twice.
178         final List<AbandonedTrace> traceList = getTrace();
179         if (traceList != null) {
180             final List<Exception> thrownList = new ArrayList<>();
181             traceList.forEach(trace -> trace.close(thrownList::add));
182             clearTrace();
183             if (!thrownList.isEmpty()) {
184                 throw new SQLExceptionList(thrownList);
185             }
186         }
187 
188         super.passivate();
189     }
190 
191     @Override
192     public void setArray(final int i, final Array x) throws SQLException {
193         checkOpen();
194         try {
195             getDelegatePreparedStatement().setArray(i, x);
196         } catch (final SQLException e) {
197             handleException(e);
198         }
199     }
200 
201     @Override
202     public void setAsciiStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
203         checkOpen();
204         try {
205             getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream);
206         } catch (final SQLException e) {
207             handleException(e);
208         }
209     }
210 
211     @Override
212     public void setAsciiStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
213         checkOpen();
214         try {
215             getDelegatePreparedStatement().setAsciiStream(parameterIndex, x, length);
216         } catch (final SQLException e) {
217             handleException(e);
218         }
219     }
220 
221     @Override
222     public void setAsciiStream(final int parameterIndex, final InputStream inputStream, final long length)
223             throws SQLException {
224         checkOpen();
225         try {
226             getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream, length);
227         } catch (final SQLException e) {
228             handleException(e);
229         }
230     }
231 
232     @Override
233     public void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException {
234         checkOpen();
235         try {
236             getDelegatePreparedStatement().setBigDecimal(parameterIndex, x);
237         } catch (final SQLException e) {
238             handleException(e);
239         }
240     }
241 
242     @Override
243     public void setBinaryStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
244         checkOpen();
245         try {
246             getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream);
247         } catch (final SQLException e) {
248             handleException(e);
249         }
250     }
251 
252     @Override
253     public void setBinaryStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
254         checkOpen();
255         try {
256             getDelegatePreparedStatement().setBinaryStream(parameterIndex, x, length);
257         } catch (final SQLException e) {
258             handleException(e);
259         }
260     }
261 
262     @Override
263     public void setBinaryStream(final int parameterIndex, final InputStream inputStream, final long length)
264             throws SQLException {
265         checkOpen();
266         try {
267             getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream, length);
268         } catch (final SQLException e) {
269             handleException(e);
270         }
271     }
272 
273     @Override
274     public void setBlob(final int i, final Blob x) throws SQLException {
275         checkOpen();
276         try {
277             getDelegatePreparedStatement().setBlob(i, x);
278         } catch (final SQLException e) {
279             handleException(e);
280         }
281     }
282 
283     @Override
284     public void setBlob(final int parameterIndex, final InputStream inputStream) throws SQLException {
285         checkOpen();
286         try {
287             getDelegatePreparedStatement().setBlob(parameterIndex, inputStream);
288         } catch (final SQLException e) {
289             handleException(e);
290         }
291     }
292 
293     @Override
294     public void setBlob(final int parameterIndex, final InputStream inputStream, final long length)
295             throws SQLException {
296         checkOpen();
297         try {
298             getDelegatePreparedStatement().setBlob(parameterIndex, inputStream, length);
299         } catch (final SQLException e) {
300             handleException(e);
301         }
302     }
303 
304     @Override
305     public void setBoolean(final int parameterIndex, final boolean x) throws SQLException {
306         checkOpen();
307         try {
308             getDelegatePreparedStatement().setBoolean(parameterIndex, x);
309         } catch (final SQLException e) {
310             handleException(e);
311         }
312     }
313 
314     @Override
315     public void setByte(final int parameterIndex, final byte x) throws SQLException {
316         checkOpen();
317         try {
318             getDelegatePreparedStatement().setByte(parameterIndex, x);
319         } catch (final SQLException e) {
320             handleException(e);
321         }
322     }
323 
324     @Override
325     public void setBytes(final int parameterIndex, final byte[] x) throws SQLException {
326         checkOpen();
327         try {
328             getDelegatePreparedStatement().setBytes(parameterIndex, x);
329         } catch (final SQLException e) {
330             handleException(e);
331         }
332     }
333 
334     @Override
335     public void setCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
336         checkOpen();
337         try {
338             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader);
339         } catch (final SQLException e) {
340             handleException(e);
341         }
342     }
343 
344     @Override
345     public void setCharacterStream(final int parameterIndex, final Reader reader, final int length)
346             throws SQLException {
347         checkOpen();
348         try {
349             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
350         } catch (final SQLException e) {
351             handleException(e);
352         }
353     }
354 
355     @Override
356     public void setCharacterStream(final int parameterIndex, final Reader reader, final long length)
357             throws SQLException {
358         checkOpen();
359         try {
360             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
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 setClob(final int parameterIndex, final Reader reader) throws SQLException {
378         checkOpen();
379         try {
380             getDelegatePreparedStatement().setClob(parameterIndex, reader);
381         } catch (final SQLException e) {
382             handleException(e);
383         }
384     }
385 
386     @Override
387     public void setClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
388         checkOpen();
389         try {
390             getDelegatePreparedStatement().setClob(parameterIndex, reader, length);
391         } catch (final SQLException e) {
392             handleException(e);
393         }
394     }
395 
396     @Override
397     public void setDate(final int parameterIndex, final Date x) throws SQLException {
398         checkOpen();
399         try {
400             getDelegatePreparedStatement().setDate(parameterIndex, x);
401         } catch (final SQLException e) {
402             handleException(e);
403         }
404     }
405 
406     @Override
407     public void setDate(final int parameterIndex, final Date x, final Calendar cal) throws SQLException {
408         checkOpen();
409         try {
410             getDelegatePreparedStatement().setDate(parameterIndex, x, cal);
411         } catch (final SQLException e) {
412             handleException(e);
413         }
414     }
415 
416     @Override
417     public void setDouble(final int parameterIndex, final double x) throws SQLException {
418         checkOpen();
419         try {
420             getDelegatePreparedStatement().setDouble(parameterIndex, x);
421         } catch (final SQLException e) {
422             handleException(e);
423         }
424     }
425 
426     @Override
427     public void setFloat(final int parameterIndex, final float x) throws SQLException {
428         checkOpen();
429         try {
430             getDelegatePreparedStatement().setFloat(parameterIndex, x);
431         } catch (final SQLException e) {
432             handleException(e);
433         }
434     }
435 
436     @Override
437     public void setInt(final int parameterIndex, final int x) throws SQLException {
438         checkOpen();
439         try {
440             getDelegatePreparedStatement().setInt(parameterIndex, x);
441         } catch (final SQLException e) {
442             handleException(e);
443         }
444     }
445 
446     @Override
447     public void setLong(final int parameterIndex, final long x) throws SQLException {
448         checkOpen();
449         try {
450             getDelegatePreparedStatement().setLong(parameterIndex, x);
451         } catch (final SQLException e) {
452             handleException(e);
453         }
454     }
455 
456     @Override
457     public void setNCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
458         checkOpen();
459         try {
460             getDelegatePreparedStatement().setNCharacterStream(parameterIndex, reader);
461         } catch (final SQLException e) {
462             handleException(e);
463         }
464     }
465 
466     @Override
467     public void setNCharacterStream(final int parameterIndex, final Reader value, final long length)
468             throws SQLException {
469         checkOpen();
470         try {
471             getDelegatePreparedStatement().setNCharacterStream(parameterIndex, value, length);
472         } catch (final SQLException e) {
473             handleException(e);
474         }
475     }
476 
477     @Override
478     public void setNClob(final int parameterIndex, final NClob value) throws SQLException {
479         checkOpen();
480         try {
481             getDelegatePreparedStatement().setNClob(parameterIndex, value);
482         } catch (final SQLException e) {
483             handleException(e);
484         }
485     }
486 
487     @Override
488     public void setNClob(final int parameterIndex, final Reader reader) throws SQLException {
489         checkOpen();
490         try {
491             getDelegatePreparedStatement().setNClob(parameterIndex, reader);
492         } catch (final SQLException e) {
493             handleException(e);
494         }
495     }
496 
497     @Override
498     public void setNClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
499         checkOpen();
500         try {
501             getDelegatePreparedStatement().setNClob(parameterIndex, reader, length);
502         } catch (final SQLException e) {
503             handleException(e);
504         }
505     }
506 
507     @Override
508     public void setNString(final int parameterIndex, final String value) throws SQLException {
509         checkOpen();
510         try {
511             getDelegatePreparedStatement().setNString(parameterIndex, value);
512         } catch (final SQLException e) {
513             handleException(e);
514         }
515     }
516 
517     @Override
518     public void setNull(final int parameterIndex, final int sqlType) throws SQLException {
519         checkOpen();
520         try {
521             getDelegatePreparedStatement().setNull(parameterIndex, sqlType);
522         } catch (final SQLException e) {
523             handleException(e);
524         }
525     }
526 
527     @Override
528     public void setNull(final int paramIndex, final int sqlType, final String typeName) throws SQLException {
529         checkOpen();
530         try {
531             getDelegatePreparedStatement().setNull(paramIndex, sqlType, typeName);
532         } catch (final SQLException e) {
533             handleException(e);
534         }
535     }
536 
537     @Override
538     public void setObject(final int parameterIndex, final Object x) throws SQLException {
539         checkOpen();
540         try {
541             getDelegatePreparedStatement().setObject(parameterIndex, x);
542         } catch (final SQLException e) {
543             handleException(e);
544         }
545     }
546 
547     @Override
548     public void setObject(final int parameterIndex, final Object x, final int targetSqlType) throws SQLException {
549         checkOpen();
550         try {
551             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType);
552         } catch (final SQLException e) {
553             handleException(e);
554         }
555     }
556 
557     @Override
558     public void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scale)
559             throws SQLException {
560         checkOpen();
561         try {
562             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType, scale);
563         } catch (final SQLException e) {
564             handleException(e);
565         }
566     }
567 
568     /**
569      * @since 2.5.0
570      */
571     @Override
572     public void setObject(final int parameterIndex, final Object x, final SQLType targetSqlType) throws SQLException {
573         checkOpen();
574         try {
575             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType);
576         } catch (final SQLException e) {
577             handleException(e);
578         }
579     }
580 
581     /**
582      * @since 2.5.0
583      */
584     @Override
585     public void setObject(final int parameterIndex, final Object x, final SQLType targetSqlType, final int scaleOrLength) throws SQLException {
586         checkOpen();
587         try {
588             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType, scaleOrLength);
589         } catch (final SQLException e) {
590             handleException(e);
591         }
592     }
593 
594     @Override
595     public void setRef(final int i, final Ref x) throws SQLException {
596         checkOpen();
597         try {
598             getDelegatePreparedStatement().setRef(i, x);
599         } catch (final SQLException e) {
600             handleException(e);
601         }
602     }
603 
604     @Override
605     public void setRowId(final int parameterIndex, final RowId value) throws SQLException {
606         checkOpen();
607         try {
608             getDelegatePreparedStatement().setRowId(parameterIndex, value);
609         } catch (final SQLException e) {
610             handleException(e);
611         }
612     }
613 
614     @Override
615     public void setShort(final int parameterIndex, final short x) throws SQLException {
616         checkOpen();
617         try {
618             getDelegatePreparedStatement().setShort(parameterIndex, x);
619         } catch (final SQLException e) {
620             handleException(e);
621         }
622     }
623 
624     @Override
625     public void setSQLXML(final int parameterIndex, final SQLXML value) throws SQLException {
626         checkOpen();
627         try {
628             getDelegatePreparedStatement().setSQLXML(parameterIndex, value);
629         } catch (final SQLException e) {
630             handleException(e);
631         }
632     }
633 
634     @Override
635     public void setString(final int parameterIndex, final String x) throws SQLException {
636         checkOpen();
637         try {
638             getDelegatePreparedStatement().setString(parameterIndex, x);
639         } catch (final SQLException e) {
640             handleException(e);
641         }
642     }
643 
644     @Override
645     public void setTime(final int parameterIndex, final Time x) throws SQLException {
646         checkOpen();
647         try {
648             getDelegatePreparedStatement().setTime(parameterIndex, x);
649         } catch (final SQLException e) {
650             handleException(e);
651         }
652     }
653 
654     @Override
655     public void setTime(final int parameterIndex, final Time x, final Calendar cal) throws SQLException {
656         checkOpen();
657         try {
658             getDelegatePreparedStatement().setTime(parameterIndex, x, cal);
659         } catch (final SQLException e) {
660             handleException(e);
661         }
662     }
663 
664     @Override
665     public void setTimestamp(final int parameterIndex, final Timestamp x) throws SQLException {
666         checkOpen();
667         try {
668             getDelegatePreparedStatement().setTimestamp(parameterIndex, x);
669         } catch (final SQLException e) {
670             handleException(e);
671         }
672     }
673 
674     @Override
675     public void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) throws SQLException {
676         checkOpen();
677         try {
678             getDelegatePreparedStatement().setTimestamp(parameterIndex, x, cal);
679         } catch (final SQLException e) {
680             handleException(e);
681         }
682     }
683 
684     /** @deprecated Use setAsciiStream(), setCharacterStream() or setNCharacterStream() */
685     @Deprecated
686     @Override
687     public void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
688         checkOpen();
689         try {
690             getDelegatePreparedStatement().setUnicodeStream(parameterIndex, x, length);
691         } catch (final SQLException e) {
692             handleException(e);
693         }
694     }
695 
696     @Override
697     public void setURL(final int parameterIndex, final java.net.URL x) throws SQLException {
698         checkOpen();
699         try {
700             getDelegatePreparedStatement().setURL(parameterIndex, x);
701         } catch (final SQLException e) {
702             handleException(e);
703         }
704     }
705 
706     /**
707      * Returns a String representation of this object.
708      *
709      * @return String
710      */
711     @SuppressWarnings("resource")
712     @Override
713     public synchronized String toString() {
714         final Statement statement = getDelegate();
715         return statement == null ? "NULL" : statement.toString();
716     }
717 }