1 /*
2  * Copyright (C) 2013 Brett Wooldridge
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package com.zaxxer.hikari.pool;
18
19 import java.sql.Connection;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.sql.Statement;
23
24 /**
25  * This is the proxy class for java.sql.Statement.
26  *
27  * @author Brett Wooldridge
28  */

29 public abstract class ProxyStatement implements Statement
30 {
31    protected final ProxyConnection connection;
32    final Statement delegate;
33
34    private boolean isClosed;
35    private ResultSet proxyResultSet;
36
37    ProxyStatement(ProxyConnection connection, Statement statement)
38    {
39       this.connection = connection;
40       this.delegate = statement;
41    }
42
43    @SuppressWarnings("unused")
44    final SQLException checkException(SQLException e)
45    {
46       return connection.checkException(e);
47    }
48
49    /** {@inheritDoc} */
50    @Override
51    public final String toString()
52    {
53       final String delegateToString = delegate.toString();
54       return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegateToString;
55    }
56
57    // **********************************************************************
58    //                 Overridden java.sql.Statement Methods
59    // **********************************************************************
60
61    /** {@inheritDoc} */
62    @Override
63    public final void close() throws SQLException
64    {
65       synchronized (this) {
66          if (isClosed) {
67             return;
68          }
69
70          isClosed = true;
71       }
72
73       connection.untrackStatement(delegate);
74
75       try {
76          delegate.close();
77       }
78       catch (SQLException e) {
79          throw connection.checkException(e);
80       }
81    }
82
83    /** {@inheritDoc} */
84    @Override
85    public Connection getConnection() throws SQLException
86    {
87       return connection;
88    }
89
90    /** {@inheritDoc} */
91    @Override
92    public boolean execute(String sql) throws SQLException
93    {
94       connection.markCommitStateDirty();
95       return delegate.execute(sql);
96    }
97
98    /** {@inheritDoc} */
99    @Override
100    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
101    {
102       connection.markCommitStateDirty();
103       return delegate.execute(sql, autoGeneratedKeys);
104    }
105
106    /** {@inheritDoc} */
107    @Override
108    public ResultSet executeQuery(String sql) throws SQLException
109    {
110       connection.markCommitStateDirty();
111       ResultSet resultSet = delegate.executeQuery(sql);
112       return ProxyFactory.getProxyResultSet(connection, this, resultSet);
113    }
114
115    /** {@inheritDoc} */
116    @Override
117    public int executeUpdate(String sql) throws SQLException
118    {
119       connection.markCommitStateDirty();
120       return delegate.executeUpdate(sql);
121    }
122
123    /** {@inheritDoc} */
124    @Override
125    public int[] executeBatch() throws SQLException
126    {
127       connection.markCommitStateDirty();
128       return delegate.executeBatch();
129    }
130
131    /** {@inheritDoc} */
132    @Override
133    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
134    {
135       connection.markCommitStateDirty();
136       return delegate.executeUpdate(sql, autoGeneratedKeys);
137    }
138
139    /** {@inheritDoc} */
140    @Override
141    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException
142    {
143       connection.markCommitStateDirty();
144       return delegate.executeUpdate(sql, columnIndexes);
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public int executeUpdate(String sql, String[] columnNames) throws SQLException
150    {
151       connection.markCommitStateDirty();
152       return delegate.executeUpdate(sql, columnNames);
153    }
154
155    /** {@inheritDoc} */
156    @Override
157    public boolean execute(String sql, int[] columnIndexes) throws SQLException
158    {
159       connection.markCommitStateDirty();
160       return delegate.execute(sql, columnIndexes);
161    }
162
163    /** {@inheritDoc} */
164    @Override
165    public boolean execute(String sql, String[] columnNames) throws SQLException
166    {
167       connection.markCommitStateDirty();
168       return delegate.execute(sql, columnNames);
169    }
170
171    /** {@inheritDoc} */
172    @Override
173    public long[] executeLargeBatch() throws SQLException
174    {
175       connection.markCommitStateDirty();
176       return delegate.executeLargeBatch();
177    }
178
179    /** {@inheritDoc} */
180    @Override
181    public long executeLargeUpdate(String sql) throws SQLException
182    {
183       connection.markCommitStateDirty();
184       return delegate.executeLargeUpdate(sql);
185    }
186
187    /** {@inheritDoc} */
188    @Override
189    public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException
190    {
191       connection.markCommitStateDirty();
192       return delegate.executeLargeUpdate(sql, autoGeneratedKeys);
193    }
194
195    /** {@inheritDoc} */
196    @Override
197    public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException
198    {
199       connection.markCommitStateDirty();
200       return delegate.executeLargeUpdate(sql, columnIndexes);
201    }
202
203    /** {@inheritDoc} */
204    @Override
205    public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException
206    {
207       connection.markCommitStateDirty();
208       return delegate.executeLargeUpdate(sql, columnNames);
209    }
210
211    /** {@inheritDoc} */
212    @Override
213    public ResultSet getResultSet() throws SQLException {
214       final ResultSet resultSet = delegate.getResultSet();
215       if (resultSet != null) {
216          if (proxyResultSet == null || ((ProxyResultSet) proxyResultSet).delegate != resultSet) {
217             proxyResultSet = ProxyFactory.getProxyResultSet(connection, this, resultSet);
218          }
219       }
220       else {
221          proxyResultSet = null;
222       }
223       return proxyResultSet;
224    }
225
226    /** {@inheritDoc} */
227    @Override
228    public ResultSet getGeneratedKeys() throws SQLException
229    {
230       ResultSet resultSet = delegate.getGeneratedKeys();
231       if (proxyResultSet == null || ((ProxyResultSet) proxyResultSet).delegate != resultSet) {
232          proxyResultSet = ProxyFactory.getProxyResultSet(connection, this, resultSet);
233       }
234       return proxyResultSet;
235    }
236
237    /** {@inheritDoc} */
238    @Override
239    @SuppressWarnings("unchecked")
240    public final <T> T unwrap(Class<T> iface) throws SQLException
241    {
242       if (iface.isInstance(delegate)) {
243          return (T) delegate;
244       }
245       else if (delegate != null) {
246           return delegate.unwrap(iface);
247       }
248
249       throw new SQLException("Wrapped statement is not an instance of " + iface);
250    }
251 }
252