KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > craftsman > spy > SpyPreparedStatement


1 /*
2  * Craftsman Spy.
3  * Copyright (C) 2005 Sébastien LECACHEUR
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */

19 package craftsman.spy;
20
21 import java.io.InputStream JavaDoc;
22 import java.io.Reader JavaDoc;
23 import java.math.BigDecimal JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.sql.Array JavaDoc;
26 import java.sql.Blob JavaDoc;
27 import java.sql.Clob JavaDoc;
28 import java.sql.Connection JavaDoc;
29 import java.sql.Date JavaDoc;
30 import java.sql.ParameterMetaData JavaDoc;
31 import java.sql.PreparedStatement JavaDoc;
32 import java.sql.Ref JavaDoc;
33 import java.sql.ResultSet JavaDoc;
34 import java.sql.ResultSetMetaData JavaDoc;
35 import java.sql.SQLException JavaDoc;
36 import java.sql.Time JavaDoc;
37 import java.sql.Timestamp JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.Calendar JavaDoc;
40
41 /**
42  * The classe used to represent a precompiled SQL statement.
43  *
44  * @author Sébastien LECACHEUR
45  */

46 public class SpyPreparedStatement extends SpyStatement implements PreparedStatement JavaDoc {
47     /**
48      * The real prepared statement instance.
49      */

50     private PreparedStatement JavaDoc real = null;
51
52
53     /**
54      * The current prepared SQL.
55      */

56     protected String JavaDoc preparedSql = null;
57
58
59     /**
60      * The list of all the parameters.
61      */

62     private ArrayList JavaDoc parameters = null;
63
64
65     /**
66      * Constructs a new Spy JDBC prepared statement.
67      *
68      * @param c Connection The used connection.
69      * @param pstm PreparedStatement The real JDBC prepared statement.
70      * @param sql String The prepared SQL.
71      */

72     protected SpyPreparedStatement ( Connection JavaDoc c, PreparedStatement JavaDoc pstm, String JavaDoc sql) {
73         super ( c, pstm);
74         real = pstm;
75         preparedSql = sql;
76
77         // Initializes capacity with the number of '?' in sql string
78
parameters = new ArrayList JavaDoc(1);
79         addParametersList();
80     }
81
82
83     /**
84      * Retrieves the estimation of the number of parameters for
85      * the prepared SQL.
86      *
87      * @return int The number of parameters.
88      */

89     protected int getEstimatedParametersCount() {
90         int count = 0, index = 0;
91         while ( (index = preparedSql.indexOf('?', index+1)) != -1) count++;
92
93         return count;
94     }
95
96
97     /**
98      * Adds a new parameters list for the next SQL or batch.
99      */

100     private void addParametersList() {
101         // Adds a new parameters list for the next batch
102
parameters.add(new ArrayList JavaDoc(getEstimatedParametersCount()+1));
103
104         // Initializes the new parameters list
105
ArrayList JavaDoc nextParameters = (ArrayList JavaDoc)parameters.get(parameters.size()-1);
106         if ( nextParameters!=null) {
107             for (int i = 0; i < getEstimatedParametersCount()+1; i++) nextParameters.add(i,null);
108         } else {
109             if ( log.isFatalEnabled()) log.fatal("the next parameters list is null (current size is "+parameters.size()+")");
110         }
111     }
112
113
114     /**
115      * Registers the given input parameter.
116      *
117      * @param paramIndex int The index position of the parameter.
118      * @param parameter Object The value of the parameter.
119      */

120     private void registerInputParameter (int paramIndex, Object JavaDoc parameter) {
121         // Check if the current parameters list is initialized
122
if (parameters.size()==0 || parameters.get(parameters.size()-1)==null) {
123             addParametersList();
124         }
125
126         ArrayList JavaDoc currentParameters = (ArrayList JavaDoc)parameters.get(parameters.size()-1);
127         if ( currentParameters!=null) {
128             if ( currentParameters.size()<=paramIndex) {
129                 currentParameters.ensureCapacity(paramIndex+1);
130                 for ( int i = currentParameters.size(); i < paramIndex; i++) currentParameters.add(i,null);
131                     currentParameters.add(paramIndex,parameter);
132             } else {
133                 currentParameters.set(paramIndex,parameter);
134             }
135         } else {
136             if ( log.isFatalEnabled()) log.fatal("the current parameters list is null (current size is "+parameters.size()+")");
137         }
138     }
139
140
141     /**
142      * Retrieves the string representation with parameters of
143      * a prepared SQL.
144      *
145      * @param index int The index of the prepared SQL.
146      * @return String The string representation with parameters
147      * of the prepared SQL.
148      */

149     private String JavaDoc getDisplayableSql(int index) {
150         StringBuffer JavaDoc displayableSql = new StringBuffer JavaDoc(preparedSql.length());
151
152
153         if ( parameters!=null) {
154             int i = 1, limit = 0, base = 0;
155             while ((limit = preparedSql.indexOf('?',limit)) != -1) {
156                 displayableSql.append(preparedSql.substring(base,limit));
157                 if ( ((ArrayList JavaDoc)parameters.get(index)).get(i) instanceof String JavaDoc ) {
158                     displayableSql.append("'");
159                     displayableSql.append(((ArrayList JavaDoc)parameters.get(index)).get(i));
160                     displayableSql.append("'");
161                 } else if ( ((ArrayList JavaDoc)parameters.get(index)).get(i)==null ) {
162                     displayableSql.append("NULL");
163                 } else {
164                     displayableSql.append(((ArrayList JavaDoc)parameters.get(index)).get(i));
165                 }
166                 i++;
167                 limit++;
168                 base = limit;
169             }
170
171             if (base < preparedSql.length()) {
172                 displayableSql.append(preparedSql.substring(base));
173             }
174         }
175         
176         return displayableSql.toString();
177     }
178
179
180     /**
181      * Logs the success of a SQL execution.
182      *
183      * @param result String The string representation of the SQL result.
184      * @param time long The execution time.
185      */

186     private void logSql(String JavaDoc result, long time) {
187         if ( log.isInfoEnabled()) {
188             for (int i = 0; i < parameters.size(); i++) {
189                 log.info(getId()+":"+getDisplayableSql(i)+" => "+result+" ("+(time)+" ms)");
190             }
191         }
192     }
193
194
195     /**
196      * Logs the failure of a SQL execution.
197      *
198      * @param e SQLException The throwed SQL exception by the execution.
199      * @param time long The execution time.
200      */

201     private void logSql(SQLException JavaDoc e, long time) {
202         if ( log.isErrorEnabled()) {
203             for (int i = 0; i < parameters.size(); i++) {
204                 log.error(getId()+":"+getDisplayableSql(i)+" => state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(time)+" ms)",e);
205             }
206         }
207     }
208
209
210     /**
211      * @see PreparedStatement#executeUpdate()
212      */

213     public int executeUpdate() throws SQLException JavaDoc {
214         long end, start = System.currentTimeMillis();
215         int result = 0;
216
217
218         try {
219             result = real.executeUpdate();
220             end = System.currentTimeMillis();
221             logSql(String.valueOf(result),end-start);
222         } catch ( SQLException JavaDoc e) {
223             end = System.currentTimeMillis();
224             logSql(e,end-start);
225             throw e;
226         }
227
228         return result;
229     }
230
231
232     /**
233      * @see PreparedStatement#addBatch()
234      */

235     public void addBatch() throws SQLException JavaDoc {
236         addParametersList();
237         real.addBatch();
238     }
239
240
241     /**
242      * @see PreparedStatement#clearParameters()
243      */

244     public void clearParameters() throws SQLException JavaDoc {
245         for ( int i = 0; i < parameters.size(); i++) parameters.remove(i);
246         real.clearParameters();
247     }
248
249
250     /**
251      * @see PreparedStatement#execute()
252      */

253     public boolean execute() throws SQLException JavaDoc {
254         long end, start = System.currentTimeMillis();
255         boolean result = false;
256
257
258         try {
259             result = real.execute();
260             end = System.currentTimeMillis();
261             logSql(String.valueOf(result),end-start);
262         } catch ( SQLException JavaDoc e) {
263             end = System.currentTimeMillis();
264             logSql(e,end-start);
265             throw e;
266         }
267
268         return result;
269     }
270
271
272     /**
273      * @see PreparedStatement#setByte(int, byte)
274      */

275     public void setByte(int parameterIndex, byte x) throws SQLException JavaDoc {
276         registerInputParameter(parameterIndex,new Byte JavaDoc(x).toString());
277         real.setByte(parameterIndex,x);
278     }
279
280
281     /**
282      * @see PreparedStatement#setDouble(int, double)
283      */

284     public void setDouble(int parameterIndex, double x) throws SQLException JavaDoc {
285         registerInputParameter(parameterIndex,new Double JavaDoc(x));
286         real.setDouble(parameterIndex,x);
287     }
288
289
290     /**
291      * @see PreparedStatement#setFloat(int, float)
292      */

293     public void setFloat(int parameterIndex, float x) throws SQLException JavaDoc {
294         registerInputParameter(parameterIndex,new Float JavaDoc(x));
295         real.setFloat(parameterIndex,x);
296     }
297
298
299     /**
300      * @see PreparedStatement#setInt(int, int)
301      */

302     public void setInt(int parameterIndex, int x) throws SQLException JavaDoc {
303         registerInputParameter(parameterIndex,new Integer JavaDoc(x));
304         real.setInt(parameterIndex,x);
305     }
306
307
308     /**
309      * @see PreparedStatement#setNull(int, int)
310      */

311     public void setNull(int parameterIndex, int sqlType) throws SQLException JavaDoc {
312         registerInputParameter(parameterIndex,null);
313         real.setNull(parameterIndex,sqlType);
314     }
315
316
317     /**
318      * @see PreparedStatement#setLong(int, long)
319      */

320     public void setLong(int parameterIndex, long x) throws SQLException JavaDoc {
321         registerInputParameter(parameterIndex,new Long JavaDoc(x));
322         real.setLong(parameterIndex,x);
323     }
324
325
326     /**
327      * @see PreparedStatement#setShort(int, short)
328      */

329     public void setShort(int parameterIndex, short x) throws SQLException JavaDoc {
330         registerInputParameter(parameterIndex,new Short JavaDoc(x));
331         real.setShort(parameterIndex,x);
332     }
333
334
335     /**
336      * @see PreparedStatement#setBoolean(int, boolean)
337      */

338     public void setBoolean(int parameterIndex, boolean x) throws SQLException JavaDoc {
339         registerInputParameter(parameterIndex,Boolean.valueOf(x).toString());
340         real.setBoolean(parameterIndex,x);
341     }
342
343
344     /**
345      * @see PreparedStatement#setBytes(int, byte[])
346      */

347     public void setBytes(int parameterIndex, byte[] x) throws SQLException JavaDoc {
348         registerInputParameter(parameterIndex,x.toString());
349         real.setBytes(parameterIndex,x);
350     }
351
352
353     /**
354      * @see PreparedStatement#setAsciiStream(int, java.io.InputStream, int)
355      */

356     public void setAsciiStream(int parameterIndex, InputStream JavaDoc x, int length) throws SQLException JavaDoc {
357         registerInputParameter(parameterIndex,x.toString());
358         real.setAsciiStream(parameterIndex,x,length);
359     }
360
361
362     /**
363      * @see PreparedStatement#setBinaryStream(int, java.io.InputStream, int)
364      */

365     public void setBinaryStream(int parameterIndex, InputStream JavaDoc x, int length) throws SQLException JavaDoc {
366         registerInputParameter(parameterIndex,x.toString());
367         real.setBinaryStream(parameterIndex,x,length);
368     }
369
370
371     /**
372      * @see PreparedStatement#setUnicodeStream(int, java.io.InputStream, int)
373      */

374     public void setUnicodeStream(int parameterIndex, InputStream JavaDoc x, int length) throws SQLException JavaDoc {
375         registerInputParameter(parameterIndex,x.toString());
376         real.setUnicodeStream(parameterIndex,x,length);
377     }
378
379
380     /**
381      * @see PreparedStatement#setCharacterStream(int, java.io.Reader, int)
382      */

383     public void setCharacterStream(int parameterIndex, Reader JavaDoc reader, int length) throws SQLException JavaDoc {
384         registerInputParameter(parameterIndex,reader.toString());
385         real.setCharacterStream(parameterIndex,reader,length);
386     }
387
388
389     /**
390      * @see PreparedStatement#setObject(int, Object)
391      */

392     public void setObject(int parameterIndex, Object JavaDoc x) throws SQLException JavaDoc {
393         registerInputParameter(parameterIndex,x.toString());
394         real.setObject(parameterIndex,x);
395     }
396
397
398     /**
399      * @see PreparedStatement#setObject(int, Object, int)
400      */

401     public void setObject(int parameterIndex, Object JavaDoc x, int targetSqlType) throws SQLException JavaDoc {
402         registerInputParameter(parameterIndex,x.toString());
403         real.setObject(parameterIndex,x,targetSqlType);
404     }
405
406
407     /**
408      * @see PreparedStatement#setObject(int, Object, int, int)
409      */

410     public void setObject(int parameterIndex, Object JavaDoc x, int targetSqlType, int scale) throws SQLException JavaDoc {
411         registerInputParameter(parameterIndex,x.toString());
412         real.setObject(parameterIndex,x,targetSqlType,scale);
413     }
414
415
416     /**
417      * @see PreparedStatement#setNull(int, int, String)
418      */

419     public void setNull(int paramIndex, int sqlType, String JavaDoc typeName) throws SQLException JavaDoc {
420         registerInputParameter(paramIndex,null);
421         real.setNull(paramIndex,sqlType,typeName);
422     }
423
424
425     /**
426      * @see PreparedStatement#setString(int, String)
427      */

428     public void setString(int parameterIndex, String JavaDoc x) throws SQLException JavaDoc {
429         registerInputParameter(parameterIndex,x);
430         real.setString(parameterIndex,x);
431     }
432
433
434     /**
435      * @see PreparedStatement#setBigDecimal(int, java.math.BigDecimal)
436      */

437     public void setBigDecimal(int parameterIndex, BigDecimal JavaDoc x) throws SQLException JavaDoc {
438         registerInputParameter(parameterIndex,x.toString());
439         real.setBigDecimal(parameterIndex,x);
440     }
441
442
443     /**
444      * @see PreparedStatement#setURL(int, java.net.URL)
445      */

446     public void setURL(int parameterIndex, URL JavaDoc x) throws SQLException JavaDoc {
447         registerInputParameter(parameterIndex,x.toString());
448         real.setURL(parameterIndex,x);
449     }
450
451
452     /**
453      * @see PreparedStatement#setArray(int, Array)
454      */

455     public void setArray(int i, Array JavaDoc x) throws SQLException JavaDoc {
456         registerInputParameter(i,x.toString());
457         real.setArray(i,x);
458     }
459
460
461     /**
462      * @see PreparedStatement#setBlob(int, Blob)
463      */

464     public void setBlob(int i, Blob JavaDoc x) throws SQLException JavaDoc {
465         registerInputParameter(i,x.toString());
466         real.setBlob(i,x);
467     }
468
469
470     /**
471      * @see PreparedStatement#setClob(int, Clob)
472      */

473     public void setClob(int i, Clob JavaDoc x) throws SQLException JavaDoc {
474         registerInputParameter(i,x.toString());
475         real.setClob(i,x);
476     }
477
478
479     /**
480      * @see PreparedStatement#setDate(int, Date)
481      */

482     public void setDate(int parameterIndex, Date JavaDoc x) throws SQLException JavaDoc {
483         registerInputParameter(parameterIndex,x.toString());
484         real.setDate(parameterIndex,x);
485     }
486
487
488     /**
489      * @see PreparedStatement#getParameterMetaData()
490      */

491     public ParameterMetaData JavaDoc getParameterMetaData() throws SQLException JavaDoc {
492         return real.getParameterMetaData();
493     }
494
495
496     /**
497      * @see PreparedStatement#setRef(int, Ref)
498      */

499     public void setRef(int i, Ref JavaDoc x) throws SQLException JavaDoc {
500         registerInputParameter(i,x.toString());
501         real.setRef(i,x);
502     }
503
504
505     /**
506      * @see PreparedStatement#executeQuery()
507      */

508     public ResultSet JavaDoc executeQuery() throws SQLException JavaDoc {
509         long end, start = System.currentTimeMillis();
510         ResultSet JavaDoc result = null;
511
512
513         try {
514             result = new SpyResultSet ( getConnection(), this, real.executeQuery());
515             end = System.currentTimeMillis();
516             logSql("...",end-start);
517         } catch ( SQLException JavaDoc e) {
518             end = System.currentTimeMillis();
519             logSql(e,end-start);
520             throw e;
521         }
522
523         return result;
524     }
525
526
527     /**
528      * @see PreparedStatement#getMetaData()
529      */

530     public ResultSetMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
531         return real.getMetaData();
532     }
533
534
535     /**
536      * @see PreparedStatement#setTime(int, Time)
537      */

538     public void setTime(int parameterIndex, Time JavaDoc x) throws SQLException JavaDoc {
539         registerInputParameter(parameterIndex,x.toString());
540         real.setTime(parameterIndex,x);
541     }
542
543
544     /**
545      * @see PreparedStatement#setTimestamp(int, Timestamp)
546      */

547     public void setTimestamp(int parameterIndex, Timestamp JavaDoc x) throws SQLException JavaDoc {
548         registerInputParameter(parameterIndex,x.toString());
549         real.setTimestamp(parameterIndex,x);
550     }
551
552
553     /**
554      * @see PreparedStatement#setDate(int, Date, Calendar)
555      */

556     public void setDate(int parameterIndex, Date JavaDoc x, Calendar JavaDoc cal) throws SQLException JavaDoc {
557         registerInputParameter(parameterIndex,x.toString());
558         real.setDate(parameterIndex,x,cal);
559     }
560
561
562     /**
563      * @see PreparedStatement#setTime(int, Time, Calendar)
564      */

565     public void setTime(int parameterIndex, Time JavaDoc x, Calendar JavaDoc cal) throws SQLException JavaDoc {
566         registerInputParameter(parameterIndex,x.toString());
567         real.setTime(parameterIndex,x,cal);
568     }
569
570
571     /**
572      * @see PreparedStatement#setTimestamp(int, Timestamp, Calendar)
573      */

574     public void setTimestamp(int parameterIndex, Timestamp JavaDoc x, Calendar JavaDoc cal) throws SQLException JavaDoc {
575         registerInputParameter(parameterIndex,x.toString());
576         real.setTimestamp(parameterIndex,x,cal);
577     }
578
579
580     /**
581      * @see java.sql.Statement#executeBatch()
582      */

583     public int[] executeBatch() throws SQLException JavaDoc {
584         // Adds all the prepared statements in the logged batches
585
for (int i = 0; i < parameters.size() - 1; i++) {
586             batch.add(getDisplayableSql(i));
587         }
588
589         // Executes (and logs) all the batches
590
return super.executeBatch();
591     }
592 }
593
Popular Tags