001package org.javasimon.jdbc4;
002
003import java.io.InputStream;
004import java.io.Reader;
005import java.math.BigDecimal;
006import java.net.URL;
007import java.sql.Array;
008import java.sql.Blob;
009import java.sql.Clob;
010import java.sql.Connection;
011import java.sql.Date;
012import java.sql.NClob;
013import java.sql.ParameterMetaData;
014import java.sql.PreparedStatement;
015import java.sql.Ref;
016import java.sql.ResultSet;
017import java.sql.ResultSetMetaData;
018import java.sql.RowId;
019import java.sql.SQLException;
020import java.sql.SQLXML;
021import java.sql.Time;
022import java.sql.Timestamp;
023import java.util.Calendar;
024
025import org.javasimon.Split;
026
027/**
028 * Simon JDBC proxy prepared statement implementation class.
029 *
030 * @author Radovan Sninsky
031 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a>
032 * @see java.sql.PreparedStatement
033 * @since 2.4
034 */
035@SuppressWarnings("deprecation")
036public class SimonPreparedStatement extends SimonStatement implements PreparedStatement {
037        /**
038         * SQL string.
039         */
040        protected String sql;
041
042        private PreparedStatement stmt;
043
044        private final SqlNormalizerFactory sqlNormalizerFactory;
045
046        /**
047         * Class constructor, initializes Simons (lifespan, active) related to statement.
048         *  @param conn database connection (simon impl.)
049         * @param stmt real prepared statement
050         * @param sql sql command
051         * @param prefix hierarchy prefix for statement Simons
052         * @param sqlNormalizerFactory factory to map queries to Simon keys
053         */
054        SimonPreparedStatement(Connection conn, PreparedStatement stmt, String sql, String prefix, SqlNormalizerFactory sqlNormalizerFactory) {
055                super(conn, stmt, prefix, sqlNormalizerFactory);
056
057                this.stmt = stmt;
058                this.sql = sql;
059                this.sqlNormalizerFactory = sqlNormalizerFactory;
060        }
061
062        /**
063         * Called before each prepared SQL command execution. Prepares (obtains and starts)
064         * {@link org.javasimon.Stopwatch Stopwatch Simon} for measure SQL operation.
065         *
066         * @return Simon stopwatch object or null if sql is null or empty
067         */
068        private Split prepare() {
069                if (sql != null && !sql.equals("")) {
070                        sqlNormalizer = sqlNormalizerFactory.getNormalizer(sql);
071                        sqlCmdLabel = prefix + ".sql." + sqlNormalizer.getType();
072                        return startSplit();
073                } else {
074                        return null;
075                }
076        }
077
078        /**
079         * Measure and execute prepared SQL operation.
080         *
081         * @return database rows and columns
082         * @throws java.sql.SQLException if real calls fails
083         */
084        @Override
085        public final ResultSet executeQuery() throws SQLException {
086                Split split = prepare();
087                try {
088                        return new SimonResultSet(stmt.executeQuery(), this, prefix, split.getStopwatch().getName());
089                } finally {
090                        finish(split);
091                }
092        }
093
094        /**
095         * Measure and execute prepared SQL operation.
096         *
097         * @return count of updated rows
098         * @throws java.sql.SQLException if real calls fails
099         */
100        @Override
101        public final int executeUpdate() throws SQLException {
102                Split split = prepare();
103                try {
104                        return stmt.executeUpdate();
105                } finally {
106                        finish(split);
107                }
108        }
109
110        /**
111         * Measure and execute prepared SQL operation.
112         *
113         * @return <code>true</code> if the first result is a <code>ResultSet</code> object;
114         *         <code>false</code> if it is an update count or there are no results
115         * @throws java.sql.SQLException if real calls fails
116         */
117        @Override
118        public final boolean execute() throws SQLException {
119                Split split = prepare();
120                try {
121                        return stmt.execute();
122                } finally {
123                        finish(split);
124                }
125        }
126
127        /**
128         * Adds prepared SQL command into batch list of sql and also into real batch.
129         *
130         * @throws java.sql.SQLException if real calls fails
131         */
132        @Override
133        public final void addBatch() throws SQLException {
134                batchSql.add(sql);
135
136                stmt.addBatch();
137        }
138
139        //// NOT MONITORED
140
141        @Override
142        public final void setNull(int i, int i1) throws SQLException {
143                stmt.setNull(i, i1);
144        }
145
146        @Override
147        public final void setBoolean(int i, boolean b) throws SQLException {
148                stmt.setBoolean(i, b);
149        }
150
151        @Override
152        public final void setByte(int i, byte b) throws SQLException {
153                stmt.setByte(i, b);
154        }
155
156        @Override
157        public final void setShort(int i, short i1) throws SQLException {
158                stmt.setShort(i, i1);
159        }
160
161        @Override
162        public final void setInt(int i, int i1) throws SQLException {
163                stmt.setInt(i, i1);
164        }
165
166        @Override
167        public final void setLong(int i, long l) throws SQLException {
168                stmt.setLong(i, l);
169        }
170
171        @Override
172        public final void setFloat(int i, float v) throws SQLException {
173                stmt.setFloat(i, v);
174        }
175
176        @Override
177        public final void setDouble(int i, double v) throws SQLException {
178                stmt.setDouble(i, v);
179        }
180
181        @Override
182        public final void setBigDecimal(int i, BigDecimal bigDecimal) throws SQLException {
183                stmt.setBigDecimal(i, bigDecimal);
184        }
185
186        @Override
187        public final void setString(int i, String s) throws SQLException {
188                stmt.setString(i, s);
189        }
190
191        @Override
192        public final void setBytes(int i, byte[] bytes) throws SQLException {
193                stmt.setBytes(i, bytes);
194        }
195
196        @Override
197        public final void setDate(int i, Date date) throws SQLException {
198                stmt.setDate(i, date);
199        }
200
201        @Override
202        public final void setTime(int i, Time time) throws SQLException {
203                stmt.setTime(i, time);
204        }
205
206        @Override
207        public final void setTimestamp(int i, Timestamp timestamp) throws SQLException {
208                stmt.setTimestamp(i, timestamp);
209        }
210
211        @Override
212        public final void setAsciiStream(int i, InputStream inputStream, int i1) throws SQLException {
213                stmt.setAsciiStream(i, inputStream, i1);
214        }
215
216        @Deprecated
217        @Override
218        public final void setUnicodeStream(int i, InputStream inputStream, int i1) throws SQLException {
219                stmt.setUnicodeStream(i, inputStream, i1);
220        }
221
222        @Override
223        public final void setBinaryStream(int i, InputStream inputStream, int i1) throws SQLException {
224                stmt.setBinaryStream(i, inputStream, i1);
225        }
226
227        @Override
228        public final void clearParameters() throws SQLException {
229                stmt.clearParameters();
230        }
231
232        @Override
233        public final void setObject(int i, Object o, int i1) throws SQLException {
234                stmt.setObject(i, o, i1);
235        }
236
237        @Override
238        public final void setObject(int i, Object o) throws SQLException {
239                stmt.setObject(i, o);
240        }
241
242        @Override
243        public final void setObject(int i, Object o, int i1, int i2) throws SQLException {
244                stmt.setObject(i, o, i1, i2);
245        }
246
247        @Override
248        public final void setCharacterStream(int i, Reader reader, int i1) throws SQLException {
249                stmt.setCharacterStream(i, reader, i1);
250        }
251
252        @Override
253        public final void setRef(int i, Ref ref) throws SQLException {
254                stmt.setRef(i, ref);
255        }
256
257        @Override
258        public final void setBlob(int i, Blob blob) throws SQLException {
259                stmt.setBlob(i, blob);
260        }
261
262        @Override
263        public final void setClob(int i, Clob clob) throws SQLException {
264                stmt.setClob(i, clob);
265        }
266
267        @Override
268        public final void setArray(int i, Array array) throws SQLException {
269                stmt.setArray(i, array);
270        }
271
272        @Override
273        public final ResultSetMetaData getMetaData() throws SQLException {
274                return stmt.getMetaData();
275        }
276
277        public final void setDate(int i, Date date, Calendar calendar) throws SQLException {
278                stmt.setDate(i, date, calendar);
279        }
280
281        @Override
282        public final void setTime(int i, Time time, Calendar calendar) throws SQLException {
283                stmt.setTime(i, time, calendar);
284        }
285
286        @Override
287        public final void setTimestamp(int i, Timestamp timestamp, Calendar calendar) throws SQLException {
288                stmt.setTimestamp(i, timestamp, calendar);
289        }
290
291        @Override
292        public final void setNull(int i, int i1, String s) throws SQLException {
293                stmt.setNull(i, i1, s);
294        }
295
296        @Override
297        public final void setURL(int i, URL url) throws SQLException {
298                stmt.setURL(i, url);
299        }
300
301        @Override
302        public final ParameterMetaData getParameterMetaData() throws SQLException {
303                return stmt.getParameterMetaData();
304        }
305
306        @Override
307        public final void setRowId(int i, RowId rowId) throws SQLException {
308                stmt.setRowId(i, rowId);
309        }
310
311        @Override
312        public final void setNString(int i, String s) throws SQLException {
313                stmt.setNString(i, s);
314        }
315
316        @Override
317        public final void setNCharacterStream(int i, Reader reader, long l) throws SQLException {
318                stmt.setNCharacterStream(i, reader, l);
319        }
320
321        @Override
322        public final void setNClob(int i, NClob nClob) throws SQLException {
323                stmt.setNClob(i, nClob);
324        }
325
326        @Override
327        public final void setClob(int i, Reader reader, long l) throws SQLException {
328                stmt.setClob(i, reader, l);
329        }
330
331        @Override
332        public final void setBlob(int i, InputStream inputStream, long l) throws SQLException {
333                stmt.setBlob(i, inputStream, l);
334        }
335
336        @Override
337        public final void setNClob(int i, Reader reader, long l) throws SQLException {
338                stmt.setNClob(i, reader, l);
339        }
340
341        @Override
342        public final void setSQLXML(int i, SQLXML sqlxml) throws SQLException {
343                stmt.setSQLXML(i, sqlxml);
344        }
345
346        @Override
347        public final void setAsciiStream(int i, InputStream inputStream, long l) throws SQLException {
348                stmt.setAsciiStream(i, inputStream, l);
349        }
350
351        @Override
352        public final void setBinaryStream(int i, InputStream inputStream, long l) throws SQLException {
353                stmt.setBinaryStream(i, inputStream);
354        }
355
356        @Override
357        public final void setCharacterStream(int i, Reader reader, long l) throws SQLException {
358                stmt.setCharacterStream(i, reader, l);
359        }
360
361        @Override
362        public final void setAsciiStream(int i, InputStream inputStream) throws SQLException {
363                stmt.setAsciiStream(i, inputStream);
364        }
365
366        @Override
367        public final void setBinaryStream(int i, InputStream inputStream) throws SQLException {
368                stmt.setBinaryStream(i, inputStream);
369        }
370
371        @Override
372        public final void setCharacterStream(int i, Reader reader) throws SQLException {
373                stmt.setCharacterStream(i, reader);
374        }
375
376        @Override
377        public final void setNCharacterStream(int i, Reader reader) throws SQLException {
378                stmt.setNCharacterStream(i, reader);
379        }
380
381        @Override
382        public final void setClob(int i, Reader reader) throws SQLException {
383                stmt.setClob(i, reader);
384        }
385
386        @Override
387        public final void setBlob(int i, InputStream inputStream) throws SQLException {
388                stmt.setBlob(i, inputStream);
389        }
390
391        @Override
392        public final void setNClob(int i, Reader reader) throws SQLException {
393                stmt.setNClob(i, reader);
394        }
395
396}