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    *      https://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.Time;
36  import java.sql.Timestamp;
37  import java.util.ArrayList;
38  import java.util.Calendar;
39  import java.util.List;
40  import java.util.Objects;
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     /**
171      * Prepares internal states before calling {@link #passivate()}.
172      *
173      * @throws SQLException Thrown closing a traced resource or calling {@link #passivate()}.
174      */
175     protected void prepareToReturn() throws SQLException {
176         setClosedInternal(true);
177         removeThisTrace(getConnectionInternal());
178         // The JDBC spec requires that a statement close any open
179         // ResultSet's when it is closed.
180         // FIXME The PreparedStatement we're wrapping should handle this for us.
181         // See DBCP-10 for what could happen when ResultSets are closed twice.
182         final List<AbandonedTrace> traceList = getTrace();
183         if (traceList != null) {
184             final List<Exception> thrownList = new ArrayList<>();
185             traceList.forEach(trace -> trace.close(thrownList::add));
186             clearTrace();
187             if (!thrownList.isEmpty()) {
188                 throw new SQLExceptionList(thrownList);
189             }
190         }
191         super.passivate();
192     }
193 
194     @Override
195     public void setArray(final int i, final Array x) throws SQLException {
196         checkOpen();
197         try {
198             getDelegatePreparedStatement().setArray(i, x);
199         } catch (final SQLException e) {
200             handleException(e);
201         }
202     }
203 
204     @Override
205     public void setAsciiStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
206         checkOpen();
207         try {
208             getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream);
209         } catch (final SQLException e) {
210             handleException(e);
211         }
212     }
213 
214     @Override
215     public void setAsciiStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
216         checkOpen();
217         try {
218             getDelegatePreparedStatement().setAsciiStream(parameterIndex, x, length);
219         } catch (final SQLException e) {
220             handleException(e);
221         }
222     }
223 
224     @Override
225     public void setAsciiStream(final int parameterIndex, final InputStream inputStream, final long length)
226             throws SQLException {
227         checkOpen();
228         try {
229             getDelegatePreparedStatement().setAsciiStream(parameterIndex, inputStream, length);
230         } catch (final SQLException e) {
231             handleException(e);
232         }
233     }
234 
235     @Override
236     public void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException {
237         checkOpen();
238         try {
239             getDelegatePreparedStatement().setBigDecimal(parameterIndex, x);
240         } catch (final SQLException e) {
241             handleException(e);
242         }
243     }
244 
245     @Override
246     public void setBinaryStream(final int parameterIndex, final InputStream inputStream) throws SQLException {
247         checkOpen();
248         try {
249             getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream);
250         } catch (final SQLException e) {
251             handleException(e);
252         }
253     }
254 
255     @Override
256     public void setBinaryStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
257         checkOpen();
258         try {
259             getDelegatePreparedStatement().setBinaryStream(parameterIndex, x, length);
260         } catch (final SQLException e) {
261             handleException(e);
262         }
263     }
264 
265     @Override
266     public void setBinaryStream(final int parameterIndex, final InputStream inputStream, final long length)
267             throws SQLException {
268         checkOpen();
269         try {
270             getDelegatePreparedStatement().setBinaryStream(parameterIndex, inputStream, length);
271         } catch (final SQLException e) {
272             handleException(e);
273         }
274     }
275 
276     @Override
277     public void setBlob(final int i, final Blob x) throws SQLException {
278         checkOpen();
279         try {
280             getDelegatePreparedStatement().setBlob(i, x);
281         } catch (final SQLException e) {
282             handleException(e);
283         }
284     }
285 
286     @Override
287     public void setBlob(final int parameterIndex, final InputStream inputStream) throws SQLException {
288         checkOpen();
289         try {
290             getDelegatePreparedStatement().setBlob(parameterIndex, inputStream);
291         } catch (final SQLException e) {
292             handleException(e);
293         }
294     }
295 
296     @Override
297     public void setBlob(final int parameterIndex, final InputStream inputStream, final long length)
298             throws SQLException {
299         checkOpen();
300         try {
301             getDelegatePreparedStatement().setBlob(parameterIndex, inputStream, length);
302         } catch (final SQLException e) {
303             handleException(e);
304         }
305     }
306 
307     @Override
308     public void setBoolean(final int parameterIndex, final boolean x) throws SQLException {
309         checkOpen();
310         try {
311             getDelegatePreparedStatement().setBoolean(parameterIndex, x);
312         } catch (final SQLException e) {
313             handleException(e);
314         }
315     }
316 
317     @Override
318     public void setByte(final int parameterIndex, final byte x) throws SQLException {
319         checkOpen();
320         try {
321             getDelegatePreparedStatement().setByte(parameterIndex, x);
322         } catch (final SQLException e) {
323             handleException(e);
324         }
325     }
326 
327     @Override
328     public void setBytes(final int parameterIndex, final byte[] x) throws SQLException {
329         checkOpen();
330         try {
331             getDelegatePreparedStatement().setBytes(parameterIndex, x);
332         } catch (final SQLException e) {
333             handleException(e);
334         }
335     }
336 
337     @Override
338     public void setCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
339         checkOpen();
340         try {
341             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader);
342         } catch (final SQLException e) {
343             handleException(e);
344         }
345     }
346 
347     @Override
348     public void setCharacterStream(final int parameterIndex, final Reader reader, final int length)
349             throws SQLException {
350         checkOpen();
351         try {
352             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
353         } catch (final SQLException e) {
354             handleException(e);
355         }
356     }
357 
358     @Override
359     public void setCharacterStream(final int parameterIndex, final Reader reader, final long length)
360             throws SQLException {
361         checkOpen();
362         try {
363             getDelegatePreparedStatement().setCharacterStream(parameterIndex, reader, length);
364         } catch (final SQLException e) {
365             handleException(e);
366         }
367     }
368 
369     @Override
370     public void setClob(final int i, final Clob x) throws SQLException {
371         checkOpen();
372         try {
373             getDelegatePreparedStatement().setClob(i, x);
374         } catch (final SQLException e) {
375             handleException(e);
376         }
377     }
378 
379     @Override
380     public void setClob(final int parameterIndex, final Reader reader) throws SQLException {
381         checkOpen();
382         try {
383             getDelegatePreparedStatement().setClob(parameterIndex, reader);
384         } catch (final SQLException e) {
385             handleException(e);
386         }
387     }
388 
389     @Override
390     public void setClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
391         checkOpen();
392         try {
393             getDelegatePreparedStatement().setClob(parameterIndex, reader, length);
394         } catch (final SQLException e) {
395             handleException(e);
396         }
397     }
398 
399     @Override
400     public void setDate(final int parameterIndex, final Date x) throws SQLException {
401         checkOpen();
402         try {
403             getDelegatePreparedStatement().setDate(parameterIndex, x);
404         } catch (final SQLException e) {
405             handleException(e);
406         }
407     }
408 
409     @Override
410     public void setDate(final int parameterIndex, final Date x, final Calendar cal) throws SQLException {
411         checkOpen();
412         try {
413             getDelegatePreparedStatement().setDate(parameterIndex, x, cal);
414         } catch (final SQLException e) {
415             handleException(e);
416         }
417     }
418 
419     @Override
420     public void setDouble(final int parameterIndex, final double x) throws SQLException {
421         checkOpen();
422         try {
423             getDelegatePreparedStatement().setDouble(parameterIndex, x);
424         } catch (final SQLException e) {
425             handleException(e);
426         }
427     }
428 
429     @Override
430     public void setFloat(final int parameterIndex, final float x) throws SQLException {
431         checkOpen();
432         try {
433             getDelegatePreparedStatement().setFloat(parameterIndex, x);
434         } catch (final SQLException e) {
435             handleException(e);
436         }
437     }
438 
439     @Override
440     public void setInt(final int parameterIndex, final int x) throws SQLException {
441         checkOpen();
442         try {
443             getDelegatePreparedStatement().setInt(parameterIndex, x);
444         } catch (final SQLException e) {
445             handleException(e);
446         }
447     }
448 
449     @Override
450     public void setLong(final int parameterIndex, final long x) throws SQLException {
451         checkOpen();
452         try {
453             getDelegatePreparedStatement().setLong(parameterIndex, x);
454         } catch (final SQLException e) {
455             handleException(e);
456         }
457     }
458 
459     @Override
460     public void setNCharacterStream(final int parameterIndex, final Reader reader) throws SQLException {
461         checkOpen();
462         try {
463             getDelegatePreparedStatement().setNCharacterStream(parameterIndex, reader);
464         } catch (final SQLException e) {
465             handleException(e);
466         }
467     }
468 
469     @Override
470     public void setNCharacterStream(final int parameterIndex, final Reader value, final long length)
471             throws SQLException {
472         checkOpen();
473         try {
474             getDelegatePreparedStatement().setNCharacterStream(parameterIndex, value, length);
475         } catch (final SQLException e) {
476             handleException(e);
477         }
478     }
479 
480     @Override
481     public void setNClob(final int parameterIndex, final NClob value) throws SQLException {
482         checkOpen();
483         try {
484             getDelegatePreparedStatement().setNClob(parameterIndex, value);
485         } catch (final SQLException e) {
486             handleException(e);
487         }
488     }
489 
490     @Override
491     public void setNClob(final int parameterIndex, final Reader reader) throws SQLException {
492         checkOpen();
493         try {
494             getDelegatePreparedStatement().setNClob(parameterIndex, reader);
495         } catch (final SQLException e) {
496             handleException(e);
497         }
498     }
499 
500     @Override
501     public void setNClob(final int parameterIndex, final Reader reader, final long length) throws SQLException {
502         checkOpen();
503         try {
504             getDelegatePreparedStatement().setNClob(parameterIndex, reader, length);
505         } catch (final SQLException e) {
506             handleException(e);
507         }
508     }
509 
510     @Override
511     public void setNString(final int parameterIndex, final String value) throws SQLException {
512         checkOpen();
513         try {
514             getDelegatePreparedStatement().setNString(parameterIndex, value);
515         } catch (final SQLException e) {
516             handleException(e);
517         }
518     }
519 
520     @Override
521     public void setNull(final int parameterIndex, final int sqlType) throws SQLException {
522         checkOpen();
523         try {
524             getDelegatePreparedStatement().setNull(parameterIndex, sqlType);
525         } catch (final SQLException e) {
526             handleException(e);
527         }
528     }
529 
530     @Override
531     public void setNull(final int paramIndex, final int sqlType, final String typeName) throws SQLException {
532         checkOpen();
533         try {
534             getDelegatePreparedStatement().setNull(paramIndex, sqlType, typeName);
535         } catch (final SQLException e) {
536             handleException(e);
537         }
538     }
539 
540     @Override
541     public void setObject(final int parameterIndex, final Object x) throws SQLException {
542         checkOpen();
543         try {
544             getDelegatePreparedStatement().setObject(parameterIndex, x);
545         } catch (final SQLException e) {
546             handleException(e);
547         }
548     }
549 
550     @Override
551     public void setObject(final int parameterIndex, final Object x, final int targetSqlType) throws SQLException {
552         checkOpen();
553         try {
554             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType);
555         } catch (final SQLException e) {
556             handleException(e);
557         }
558     }
559 
560     @Override
561     public void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scale)
562             throws SQLException {
563         checkOpen();
564         try {
565             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType, scale);
566         } catch (final SQLException e) {
567             handleException(e);
568         }
569     }
570 
571     /**
572      * @since 2.5.0
573      */
574     @Override
575     public void setObject(final int parameterIndex, final Object x, final SQLType targetSqlType) throws SQLException {
576         checkOpen();
577         try {
578             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType);
579         } catch (final SQLException e) {
580             handleException(e);
581         }
582     }
583 
584     /**
585      * @since 2.5.0
586      */
587     @Override
588     public void setObject(final int parameterIndex, final Object x, final SQLType targetSqlType, final int scaleOrLength) throws SQLException {
589         checkOpen();
590         try {
591             getDelegatePreparedStatement().setObject(parameterIndex, x, targetSqlType, scaleOrLength);
592         } catch (final SQLException e) {
593             handleException(e);
594         }
595     }
596 
597     @Override
598     public void setRef(final int i, final Ref x) throws SQLException {
599         checkOpen();
600         try {
601             getDelegatePreparedStatement().setRef(i, x);
602         } catch (final SQLException e) {
603             handleException(e);
604         }
605     }
606 
607     @Override
608     public void setRowId(final int parameterIndex, final RowId value) throws SQLException {
609         checkOpen();
610         try {
611             getDelegatePreparedStatement().setRowId(parameterIndex, value);
612         } catch (final SQLException e) {
613             handleException(e);
614         }
615     }
616 
617     @Override
618     public void setShort(final int parameterIndex, final short x) throws SQLException {
619         checkOpen();
620         try {
621             getDelegatePreparedStatement().setShort(parameterIndex, x);
622         } catch (final SQLException e) {
623             handleException(e);
624         }
625     }
626 
627     @Override
628     public void setSQLXML(final int parameterIndex, final SQLXML value) throws SQLException {
629         checkOpen();
630         try {
631             getDelegatePreparedStatement().setSQLXML(parameterIndex, value);
632         } catch (final SQLException e) {
633             handleException(e);
634         }
635     }
636 
637     @Override
638     public void setString(final int parameterIndex, final String x) throws SQLException {
639         checkOpen();
640         try {
641             getDelegatePreparedStatement().setString(parameterIndex, x);
642         } catch (final SQLException e) {
643             handleException(e);
644         }
645     }
646 
647     @Override
648     public void setTime(final int parameterIndex, final Time x) throws SQLException {
649         checkOpen();
650         try {
651             getDelegatePreparedStatement().setTime(parameterIndex, x);
652         } catch (final SQLException e) {
653             handleException(e);
654         }
655     }
656 
657     @Override
658     public void setTime(final int parameterIndex, final Time x, final Calendar cal) throws SQLException {
659         checkOpen();
660         try {
661             getDelegatePreparedStatement().setTime(parameterIndex, x, cal);
662         } catch (final SQLException e) {
663             handleException(e);
664         }
665     }
666 
667     @Override
668     public void setTimestamp(final int parameterIndex, final Timestamp x) throws SQLException {
669         checkOpen();
670         try {
671             getDelegatePreparedStatement().setTimestamp(parameterIndex, x);
672         } catch (final SQLException e) {
673             handleException(e);
674         }
675     }
676 
677     @Override
678     public void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) throws SQLException {
679         checkOpen();
680         try {
681             getDelegatePreparedStatement().setTimestamp(parameterIndex, x, cal);
682         } catch (final SQLException e) {
683             handleException(e);
684         }
685     }
686 
687     /** @deprecated Use setAsciiStream(), setCharacterStream() or setNCharacterStream() */
688     @Deprecated
689     @Override
690     public void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
691         checkOpen();
692         try {
693             getDelegatePreparedStatement().setUnicodeStream(parameterIndex, x, length);
694         } catch (final SQLException e) {
695             handleException(e);
696         }
697     }
698 
699     @Override
700     public void setURL(final int parameterIndex, final java.net.URL x) throws SQLException {
701         checkOpen();
702         try {
703             getDelegatePreparedStatement().setURL(parameterIndex, x);
704         } catch (final SQLException e) {
705             handleException(e);
706         }
707     }
708 
709     /**
710      * Returns a String representation of this object.
711      *
712      * @return String
713      */
714     @SuppressWarnings("resource")
715     @Override
716     public synchronized String toString() {
717         return Objects.toString(getDelegate(), "NULL");
718     }
719 }