KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfox > jdbc > LoggablePreparedStatement


1 /* JFox, the OpenSource J2EE Application Server
2  *
3  * Distributable under GNU LGPL license by gun.org
4  * more details please visit http://www.huihoo.org/jfox
5  */

6
7 package org.jfox.jdbc;
8
9 import java.net.URL JavaDoc;
10 import java.sql.ParameterMetaData JavaDoc;
11 import java.sql.PreparedStatement JavaDoc;
12 import java.sql.ResultSet JavaDoc;
13 import java.sql.SQLException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Date JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17
18 /**
19  * 增加 PreparedStatement 的 Log 功能
20  * 在设置好参数之后,可以用 getSQLString() 得到当前的完整 SQL 语句
21  * 通过 ClientConnection.preparedStatement 得到的均为 LoggablePreparedStatement
22  * ClientConnection 通过 TxDataSource.getConnection 得到
23  *
24  * @author <a HREF="mailto:young_yy@hotmail.com">Young Yang</a>
25  */

26
27 public class LoggablePreparedStatement implements PreparedStatement JavaDoc {
28
29     /**
30      * used for storing parameter values needed for producing log
31      */

32     private ArrayList JavaDoc parameterValues;
33
34     /**
35      * the query string with question marks as parameter placeholders
36      */

37     private String JavaDoc sqlTemplate;
38
39     /**
40      * a statement created from a real database connection
41      */

42     private PreparedStatement JavaDoc pstm;
43
44     /**
45      * Constructs a LoggableStatement.
46      * <p/>
47      * Creates {@link java.sql.PreparedStatement PreparedStatement} with the query string <code>sql</code> using
48      * the specified <code>connection</code> by calling {@link java.sql.Connection#prepareStatement(String)}.
49      * <p/>
50      * Whenever a call is made to this <code>LoggableStatement</code> it is forwarded to the prepared statment created from
51      * <code>connection</code> after first saving relevant parameters for use in logging output.
52      *
53      * @param pst
54      * @param sql java.lang.String thw sql to exectute
55      * using the supplied <code>connection</code> and <code>sql</code>
56      */

57
58     public LoggablePreparedStatement(PreparedStatement JavaDoc pst, String JavaDoc sql) {
59         pstm = pst;
60         sqlTemplate = sql;
61         parameterValues = new ArrayList JavaDoc();
62     }
63
64     /**
65      * JDBC 2.0
66      * <p/>
67      * Adds a set of parameters to the batch.
68      *
69      * @throws java.sql.SQLException if a database access error occurs
70      * @see java.sql.Statement#addBatch
71      */

72     public void addBatch() throws java.sql.SQLException JavaDoc {
73         pstm.addBatch();
74     }
75
76     /**
77      * JDBC 2.0
78      * <p/>
79      * Adds a SQL command to the current batch of commmands for the statement.
80      * This method is optional.
81      *
82      * @param sql typically this is a static SQL INSERT or UPDATE statement
83      * @throws java.sql.SQLException if a database access error occurs, or the
84      * driver does not support batch statements
85      */

86     public void addBatch(String JavaDoc sql) throws java.sql.SQLException JavaDoc {
87         pstm.addBatch(sql);
88     }
89
90     /**
91      * Cancels this <code>Statement</code> object if both the DBMS and
92      * driver support aborting an SQL statement.
93      * This method can be used by one thread to cancel a statement that
94      * is being executed by another thread.
95      *
96      * @throws java.sql.SQLException if a database access error occurs
97      */

98     public void cancel() throws SQLException JavaDoc {
99         pstm.cancel();
100     }
101
102     /**
103      * JDBC 2.0
104      * <p/>
105      * Makes the set of commands in the current batch empty.
106      * This method is optional.
107      *
108      * @throws SQLException if a database access error occurs or the
109      * driver does not support batch statements
110      */

111     public void clearBatch() throws java.sql.SQLException JavaDoc {
112         pstm.clearBatch();
113     }
114
115     /**
116      * Clears the current parameter values immediately.
117      * <P>In general, parameter values remain in force for repeated use of a
118      * Statement. Setting a parameter value automatically clears its
119      * previous value. However, in some cases it is useful to immediately
120      * release the resources used by the current parameter values; this can
121      * be done by calling clearParameters.
122      *
123      * @throws SQLException if a database access error occurs
124      */

125     public void clearParameters() throws java.sql.SQLException JavaDoc {
126         pstm.clearParameters();
127     }
128
129     /**
130      * Clears all the warnings reported on this <code>Statement</code>
131      * object. After a call to this method,
132      * the method <code>getWarnings</code> will return
133      * null until a new warning is reported for this Statement.
134      *
135      * @throws SQLException if a database access error occurs
136      */

137     public void clearWarnings() throws java.sql.SQLException JavaDoc {
138         pstm.clearWarnings();
139     }
140
141     /**
142      * Releases this <code>Statement</code> object's database
143      * and JDBC resources immediately instead of waiting for
144      * this to happen when it is automatically closed.
145      * It is generally good practice to release resources as soon as
146      * you are finished with them to avoid tying up database
147      * resources.
148      * <P><B>Note:</B> A Statement is automatically closed when it is
149      * garbage collected. When a Statement is closed, its current
150      * ResultSet, if one exists, is also closed.
151      *
152      * @throws SQLException if a database access error occurs
153      */

154     public void close() throws java.sql.SQLException JavaDoc {
155         pstm.close();
156     }
157
158     /**
159      * Executes any kind of SQL statement.
160      * Some prepared statements return multiple results; the execute
161      * method handles these complex statements as well as the simpler
162      * form of statements handled by executeQuery and executeUpdate.
163      *
164      * @throws SQLException if a database access error occurs
165      * @see java.sql.Statement#execute
166      */

167     public boolean execute() throws java.sql.SQLException JavaDoc {
168         return pstm.execute();
169     }
170
171     /**
172      * Executes a SQL statement that may return multiple results.
173      * Under some (uncommon) situations a single SQL statement may return
174      * multiple result sets and/or update counts. Normally you can ignore
175      * this unless you are (1) executing a stored procedure that you know may
176      * return multiple results or (2) you are dynamically executing an
177      * unknown SQL string. The methods <code>execute</code>,
178      * <code>getMoreResults</code>, <code>getResultSet</code>,
179      * and <code>getUpdateCount</code> let you navigate through multiple results.
180      * <p/>
181      * The <code>execute</code> method executes a SQL statement and indicates the
182      * form of the first result. You can then use getResultSet or
183      * getUpdateCount to retrieve the result, and getMoreResults to
184      * move to any subsequent result(s).
185      *
186      * @param sql any SQL statement
187      * @return true if the next result is a ResultSet; false if it is
188      * an update count or there are no more results
189      * @throws SQLException if a database access error occurs
190      * @see #getResultSet
191      * @see #getUpdateCount
192      * @see #getMoreResults
193      */

194     public boolean execute(String JavaDoc sql) throws java.sql.SQLException JavaDoc {
195         return pstm.execute(sql);
196     }
197
198     /**
199      * JDBC 2.0
200      * <p/>
201      * Submits a batch of commands to the database for execution.
202      * This method is optional.
203      *
204      * @return an array of update counts containing one element for each
205      * command in the batch. The array is ordered according
206      * to the order in which commands were inserted into the batch.
207      * @throws SQLException if a database access error occurs or the
208      * driver does not support batch statements
209      */

210     public int[] executeBatch() throws java.sql.SQLException JavaDoc {
211         return pstm.executeBatch();
212     }
213
214     /**
215      * Executes the SQL query in this <code>PreparedStatement</code> object
216      * and returns the result set generated by the query.
217      *
218      * @return a ResultSet that contains the data produced by the
219      * query; never null
220      * @throws SQLException if a database access error occurs
221      */

222     public java.sql.ResultSet JavaDoc executeQuery() throws java.sql.SQLException JavaDoc {
223         return pstm.executeQuery();
224     }
225
226     /**
227      * Executes a SQL statement that returns a single ResultSet.
228      *
229      * @param sql typically this is a static SQL SELECT statement
230      * @return a ResultSet that contains the data produced by the
231      * query; never null
232      * @throws SQLException if a database access error occurs
233      */

234     public java.sql.ResultSet JavaDoc executeQuery(String JavaDoc sql)
235             throws java.sql.SQLException JavaDoc {
236         return pstm.executeQuery(sql);
237     }
238
239     /**
240      * Executes the SQL INSERT, UPDATE or DELETE statement
241      * in this <code>PreparedStatement</code> object.
242      * In addition,
243      * SQL statements that return nothing, such as SQL DDL statements,
244      * can be executed.
245      *
246      * @return either the row count for INSERT, UPDATE or DELETE statements;
247      * or 0 for SQL statements that return nothing
248      * @throws SQLException if a database access error occurs
249      */

250     public int executeUpdate() throws java.sql.SQLException JavaDoc {
251         return pstm.executeUpdate();
252     }
253
254     /**
255      * Executes an SQL INSERT, UPDATE or DELETE statement. In addition,
256      * SQL statements that return nothing, such as SQL DDL statements,
257      * can be executed.
258      *
259      * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
260      * statement that returns nothing
261      * @return either the row count for INSERT, UPDATE or DELETE or 0
262      * for SQL statements that return nothing
263      * @throws SQLException if a database access error occurs
264      */

265     public int executeUpdate(String JavaDoc sql) throws java.sql.SQLException JavaDoc {
266         return pstm.executeUpdate(sql);
267     }
268
269     /**
270      * JDBC 2.0
271      * <p/>
272      * Returns the <code>Connection</code> object
273      * that produced this <code>Statement</code> object.
274      *
275      * @return the connection that produced this statement
276      * @throws SQLException if a database access error occurs
277      */

278     public java.sql.Connection JavaDoc getConnection() throws java.sql.SQLException JavaDoc {
279         return pstm.getConnection();
280     }
281
282     /**
283      * JDBC 2.0
284      * <p/>
285      * Retrieves the direction for fetching rows from
286      * database tables that is the default for result sets
287      * generated from this <code>Statement</code> object.
288      * If this <code>Statement</code> object has not set
289      * a fetch direction by calling the method <code>setFetchDirection</code>,
290      * the return value is implementation-specific.
291      *
292      * @return the default fetch direction for result sets generated
293      * from this <code>Statement</code> object
294      * @throws SQLException if a database access error occurs
295      */

296     public int getFetchDirection() throws java.sql.SQLException JavaDoc {
297         return pstm.getFetchDirection();
298     }
299
300     /**
301      * JDBC 2.0
302      * <p/>
303      * Retrieves the number of result set rows that is the default
304      * fetch size for result sets
305      * generated from this <code>Statement</code> object.
306      * If this <code>Statement</code> object has not set
307      * a fetch size by calling the method <code>setFetchSize</code>,
308      * the return value is implementation-specific.
309      *
310      * @return the default fetch size for result sets generated
311      * from this <code>Statement</code> object
312      * @throws SQLException if a database access error occurs
313      */

314     public int getFetchSize() throws java.sql.SQLException JavaDoc {
315         return pstm.getFetchSize();
316     }
317
318     /**
319      * Returns the maximum number of bytes allowed
320      * for any column value.
321      * This limit is the maximum number of bytes that can be
322      * returned for any column value.
323      * The limit applies only to BINARY,
324      * VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR
325      * columns. If the limit is exceeded, the excess data is silently
326      * discarded.
327      *
328      * @return the current max column size limit; zero means unlimited
329      * @throws SQLException if a database access error occurs
330      */

331     public int getMaxFieldSize() throws java.sql.SQLException JavaDoc {
332         return pstm.getMaxFieldSize();
333     }
334
335     /**
336      * Retrieves the maximum number of rows that a
337      * ResultSet can contain. If the limit is exceeded, the excess
338      * rows are silently dropped.
339      *
340      * @return the current max row limit; zero means unlimited
341      * @throws SQLException if a database access error occurs
342      */

343     public int getMaxRows() throws java.sql.SQLException JavaDoc {
344         return pstm.getMaxRows();
345     }
346
347     /**
348      * JDBC 2.0
349      * <p/>
350      * Gets the number, types and properties of a ResultSet's columns.
351      *
352      * @return the description of a ResultSet's columns
353      * @throws SQLException if a database access error occurs
354      */

355     public java.sql.ResultSetMetaData JavaDoc getMetaData()
356             throws java.sql.SQLException JavaDoc {
357         return pstm.getMetaData();
358     }
359
360     /**
361      * Moves to a Statement's next result. It returns true if
362      * this result is a ResultSet. This method also implicitly
363      * closes any current ResultSet obtained with getResultSet.
364      * <p/>
365      * There are no more results when (!getMoreResults() &&
366      * (getUpdateCount() == -1)
367      *
368      * @return true if the next result is a ResultSet; false if it is
369      * an update count or there are no more results
370      * @throws SQLException if a database access error occurs
371      * @see #execute
372      */

373     public boolean getMoreResults() throws java.sql.SQLException JavaDoc {
374         return pstm.getMoreResults();
375     }
376
377     /**
378      * Retrieves the number of seconds the driver will
379      * wait for a Statement to execute. If the limit is exceeded, a
380      * SQLException is thrown.
381      *
382      * @return the current query timeout limit in seconds; zero means unlimited
383      * @throws SQLException if a database access error occurs
384      */

385     public int getQueryTimeout() throws java.sql.SQLException JavaDoc {
386         return pstm.getQueryTimeout();
387     }
388
389     /**
390      * Returns the current result as a <code>ResultSet</code> object.
391      * This method should be called only once per result.
392      *
393      * @return the current result as a ResultSet; null if the result
394      * is an update count or there are no more results
395      * @throws SQLException if a database access error occurs
396      * @see #execute
397      */

398     public java.sql.ResultSet JavaDoc getResultSet() throws java.sql.SQLException JavaDoc {
399         return pstm.getResultSet();
400     }
401
402     /**
403      * JDBC 2.0
404      * <p/>
405      * Retrieves the result set concurrency.
406      */

407     public int getResultSetConcurrency() throws java.sql.SQLException JavaDoc {
408         return pstm.getResultSetConcurrency();
409     }
410
411     /**
412      * JDBC 2.0
413      * <p/>
414      * Determine the result set type.
415      */

416     public int getResultSetType() throws java.sql.SQLException JavaDoc {
417         return pstm.getResultSetType();
418     }
419
420     /**
421      * Returns the current result as an update count;
422      * if the result is a ResultSet or there are no more results, -1
423      * is returned.
424      * This method should be called only once per result.
425      *
426      * @return the current result as an update count; -1 if it is a
427      * ResultSet or there are no more results
428      * @throws SQLException if a database access error occurs
429      * @see #execute
430      */

431     public int getUpdateCount() throws java.sql.SQLException JavaDoc {
432         return pstm.getUpdateCount();
433     }
434
435     /**
436      * Retrieves the first warning reported by calls on this Statement.
437      * Subsequent Statement warnings will be chained to this
438      * SQLWarning.
439      * <p/>
440      * <p>The warning chain is automatically cleared each time
441      * a statement is (re)executed.
442      * <p/>
443      * <P><B>Note:</B> If you are processing a ResultSet, any
444      * warnings associated with ResultSet reads will be chained on the
445      * ResultSet object.
446      *
447      * @return the first SQLWarning or null
448      * @throws SQLException if a database access error occurs
449      */

450     public java.sql.SQLWarning JavaDoc getWarnings() throws java.sql.SQLException JavaDoc {
451         return pstm.getWarnings();
452     }
453
454     /**
455      * JDBC 2.0
456      * <p/>
457      * Sets an Array parameter.
458      *
459      * @param i the first parameter is 1, the second is 2, ...
460      * @param x an object representing an SQL array
461      * @throws SQLException if a database access error occurs
462      */

463     public void setArray(int i, java.sql.Array JavaDoc x)
464             throws java.sql.SQLException JavaDoc {
465
466         pstm.setArray(i, x);
467         saveQueryParamValue(i, x);
468
469     }
470
471     /**
472      * Sets the designated parameter to the given input stream, which will have
473      * the specified number of bytes.
474      * When a very large ASCII value is input to a LONGVARCHAR
475      * parameter, it may be more practical to send it via a
476      * java.io.InputStream. JDBC will read the data from the stream
477      * as needed, until it reaches end-of-file. The JDBC driver will
478      * do any necessary conversion from ASCII to the database char format.
479      * <p/>
480      * <P><B>Note:</B> This stream object can either be a standard
481      * Java stream object or your own subclass that implements the
482      * standard interface.
483      *
484      * @param parameterIndex the first parameter is 1, the second is 2, ...
485      * @param x the Java input stream that contains the ASCII parameter value
486      * @param length the number of bytes in the stream
487      * @throws SQLException if a database access error occurs
488      */

489     public void setAsciiStream(int parameterIndex,
490                                java.io.InputStream JavaDoc x,
491                                int length)
492             throws java.sql.SQLException JavaDoc {
493
494         pstm.setAsciiStream(parameterIndex, x, length);
495         saveQueryParamValue(parameterIndex, x);
496     }
497
498     /**
499      * Sets the designated parameter to a java.lang.BigDecimal value.
500      * The driver converts this to an SQL NUMERIC value when
501      * it sends it to the database.
502      *
503      * @param parameterIndex the first parameter is 1, the second is 2, ...
504      * @param x the parameter value
505      * @throws SQLException if a database access error occurs
506      */

507     public void setBigDecimal(int parameterIndex, java.math.BigDecimal JavaDoc x)
508             throws java.sql.SQLException JavaDoc {
509         pstm.setBigDecimal(parameterIndex, x);
510         saveQueryParamValue(parameterIndex, x);
511
512     }
513
514     /**
515      * Sets the designated parameter to the given input stream, which will have
516      * the specified number of bytes.
517      * When a very large binary value is input to a LONGVARBINARY
518      * parameter, it may be more practical to send it via a
519      * java.io.InputStream. JDBC will read the data from the stream
520      * as needed, until it reaches end-of-file.
521      * <p/>
522      * <P><B>Note:</B> This stream object can either be a standard
523      * Java stream object or your own subclass that implements the
524      * standard interface.
525      *
526      * @param parameterIndex the first parameter is 1, the second is 2, ...
527      * @param x the java input stream which contains the binary parameter value
528      * @param length the number of bytes in the stream
529      * @throws SQLException if a database access error occurs
530      */

531     public void setBinaryStream(int parameterIndex,
532                                 java.io.InputStream JavaDoc x,
533                                 int length)
534             throws java.sql.SQLException JavaDoc {
535         pstm.setBinaryStream(parameterIndex, x, length);
536         saveQueryParamValue(parameterIndex, x);
537
538     }
539
540     /**
541      * JDBC 2.0
542      * <p/>
543      * Sets a BLOB parameter.
544      *
545      * @param i the first parameter is 1, the second is 2, ...
546      * @param x an object representing a BLOB
547      * @throws SQLException if a database access error occurs
548      */

549     public void setBlob(int i, java.sql.Blob JavaDoc x) throws java.sql.SQLException JavaDoc {
550         pstm.setBlob(i, x);
551         saveQueryParamValue(i, x);
552     }
553
554     /**
555      * Sets the designated parameter to a Java boolean value. The driver converts this
556      * to an SQL BIT value when it sends it to the database.
557      *
558      * @param parameterIndex the first parameter is 1, the second is 2, ...
559      * @param x the parameter value
560      * @throws SQLException if a database access error occurs
561      */

562     public void setBoolean(int parameterIndex, boolean x)
563             throws java.sql.SQLException JavaDoc {
564         pstm.setBoolean(parameterIndex, x);
565         saveQueryParamValue(parameterIndex, new Boolean JavaDoc(x));
566
567     }
568
569     /**
570      * Sets the designated parameter to a Java byte value. The driver converts this
571      * to an SQL TINYINT value when it sends it to the database.
572      *
573      * @param parameterIndex the first parameter is 1, the second is 2, ...
574      * @param x the parameter value
575      * @throws SQLException if a database access error occurs
576      */

577     public void setByte(int parameterIndex, byte x)
578             throws java.sql.SQLException JavaDoc {
579         pstm.setByte(parameterIndex, x);
580         saveQueryParamValue(parameterIndex, new Integer JavaDoc(x));
581     }
582
583     /**
584      * Sets the designated parameter to a Java array of bytes. The driver converts
585      * this to an SQL VARBINARY or LONGVARBINARY (depending on the
586      * argument's size relative to the driver's limits on VARBINARYs)
587      * when it sends it to the database.
588      *
589      * @param parameterIndex the first parameter is 1, the second is 2, ...
590      * @param x the parameter value
591      * @throws SQLException if a database access error occurs
592      */

593     public void setBytes(int parameterIndex, byte[] x)
594             throws java.sql.SQLException JavaDoc {
595         pstm.setBytes(parameterIndex, x);
596         saveQueryParamValue(parameterIndex, x);
597     }
598
599     /**
600      * JDBC 2.0
601      * <p/>
602      * Sets the designated parameter to the given <code>Reader</code>
603      * object, which is the given number of characters long.
604      * When a very large UNICODE value is input to a LONGVARCHAR
605      * parameter, it may be more practical to send it via a
606      * java.io.Reader. JDBC will read the data from the stream
607      * as needed, until it reaches end-of-file. The JDBC driver will
608      * do any necessary conversion from UNICODE to the database char format.
609      * <p/>
610      * <P><B>Note:</B> This stream object can either be a standard
611      * Java stream object or your own subclass that implements the
612      * standard interface.
613      *
614      * @param parameterIndex the first parameter is 1, the second is 2, ...
615      * @param reader the java reader which contains the UNICODE data
616      * @param length the number of characters in the stream
617      * @throws SQLException if a database access error occurs
618      */

619     public void setCharacterStream(int parameterIndex,
620                                    java.io.Reader JavaDoc reader,
621                                    int length)
622             throws java.sql.SQLException JavaDoc {
623         pstm.setCharacterStream(parameterIndex, reader, length);
624         saveQueryParamValue(parameterIndex, reader);
625
626     }
627
628     /**
629      * JDBC 2.0
630      * <p/>
631      * Sets a CLOB parameter.
632      *
633      * @param i the first parameter is 1, the second is 2, ...
634      * @param x an object representing a CLOB
635      * @throws SQLException if a database access error occurs
636      */

637     public void setClob(int i, java.sql.Clob JavaDoc x) throws java.sql.SQLException JavaDoc {
638         pstm.setClob(i, x);
639         saveQueryParamValue(i, x);
640
641     }
642
643     /**
644      * Defines the SQL cursor name that will be used by
645      * subsequent Statement <code>execute</code> methods. This name can then be
646      * used in SQL positioned update/delete statements to identify the
647      * current row in the ResultSet generated by this statement. If
648      * the database doesn't support positioned update/delete, this
649      * method is a noop. To insure that a cursor has the proper isolation
650      * level to support updates, the cursor's SELECT statement should be
651      * of the form 'select for update ...'. If the 'for update' phrase is
652      * omitted, positioned updates may fail.
653      * <p/>
654      * <P><B>Note:</B> By definition, positioned update/delete
655      * execution must be done by a different Statement than the one
656      * which generated the ResultSet being used for positioning. Also,
657      * cursor names must be unique within a connection.
658      *
659      * @param name the new cursor name, which must be unique within
660      * a connection
661      * @throws SQLException if a database access error occurs
662      */

663     public void setCursorName(String JavaDoc name) throws java.sql.SQLException JavaDoc {
664         pstm.setCursorName(name);
665
666     }
667
668     /**
669      * Sets the designated parameter to a java.sql.Date value. The driver converts this
670      * to an SQL DATE value when it sends it to the database.
671      *
672      * @param parameterIndex the first parameter is 1, the second is 2, ...
673      * @param x the parameter value
674      * @throws SQLException if a database access error occurs
675      */

676     public void setDate(int parameterIndex, java.sql.Date JavaDoc x)
677             throws java.sql.SQLException JavaDoc {
678
679         pstm.setDate(parameterIndex, x);
680         saveQueryParamValue(parameterIndex, x);
681     }
682
683     /**
684      * JDBC 2.0
685      * <p/>
686      * Sets the designated parameter to a java.sql.Date value,
687      * using the given <code>Calendar</code> object. The driver uses
688      * the <code>Calendar</code> object to construct an SQL DATE,
689      * which the driver then sends to the database. With a
690      * a <code>Calendar</code> object, the driver can calculate the date
691      * taking into account a custom timezone and locale. If no
692      * <code>Calendar</code> object is specified, the driver uses the default
693      * timezone and locale.
694      *
695      * @param parameterIndex the first parameter is 1, the second is 2, ...
696      * @param x the parameter value
697      * @param cal the <code>Calendar</code> object the driver will use
698      * to construct the date
699      * @throws SQLException if a database access error occurs
700      */

701     public void setDate(int parameterIndex,
702                         java.sql.Date JavaDoc x,
703                         java.util.Calendar JavaDoc cal)
704             throws java.sql.SQLException JavaDoc {
705         pstm.setDate(parameterIndex, x, cal);
706         saveQueryParamValue(parameterIndex, x);
707     }
708
709     /**
710      * Sets the designated parameter to a Java double value. The driver converts this
711      * to an SQL DOUBLE value when it sends it to the database.
712      *
713      * @param parameterIndex the first parameter is 1, the second is 2, ...
714      * @param x the parameter value
715      * @throws SQLException if a database access error occurs
716      */

717     public void setDouble(int parameterIndex, double x)
718             throws java.sql.SQLException JavaDoc {
719         pstm.setDouble(parameterIndex, x);
720         saveQueryParamValue(parameterIndex, new Double JavaDoc(x));
721     }
722
723     /**
724      * Sets escape processing on or off.
725      * If escape scanning is on (the default), the driver will do
726      * escape substitution before sending the SQL to the database.
727      * <p/>
728      * Note: Since prepared statements have usually been parsed prior
729      * to making this call, disabling escape processing for prepared
730      * statements will have no effect.
731      *
732      * @param enable true to enable; false to disable
733      * @throws SQLException if a database access error occurs
734      */

735     public void setEscapeProcessing(boolean enable)
736             throws java.sql.SQLException JavaDoc {
737         pstm.setEscapeProcessing(enable);
738
739     }
740
741     /**
742      * JDBC 2.0
743      * <p/>
744      * Gives the driver a hint as to the direction in which
745      * the rows in a result set
746      * will be processed. The hint applies only to result sets created
747      * using this Statement object. The default value is
748      * ResultSet.FETCH_FORWARD.
749      * <p>Note that this method sets the default fetch direction for
750      * result sets generated by this <code>Statement</code> object.
751      * Each result set has its own methods for getting and setting
752      * its own fetch direction.
753      *
754      * @param direction the initial direction for processing rows
755      * @throws SQLException if a database access error occurs
756      * or the given direction
757      * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
758      * ResultSet.FETCH_UNKNOWN
759      */

760     public void setFetchDirection(int direction) throws java.sql.SQLException JavaDoc {
761         pstm.setFetchDirection(direction);
762     }
763
764     /**
765      * JDBC 2.0
766      * <p/>
767      * Gives the JDBC driver a hint as to the number of rows that should
768      * be fetched from the database when more rows are needed. The number
769      * of rows specified affects only result sets created using this
770      * statement. If the value specified is zero, then the hint is ignored.
771      * The default value is zero.
772      *
773      * @param rows the number of rows to fetch
774      * @throws SQLException if a database access error occurs, or the
775      * condition 0 <= rows <= this.getMaxRows() is not satisfied.
776      */

777     public void setFetchSize(int rows) throws java.sql.SQLException JavaDoc {
778         pstm.setFetchSize(rows);
779     }
780
781     /**
782      * Sets the designated parameter to a Java float value. The driver converts this
783      * to an SQL FLOAT value when it sends it to the database.
784      *
785      * @param parameterIndex the first parameter is 1, the second is 2, ...
786      * @param x the parameter value
787      * @throws SQLException if a database access error occurs
788      */

789     public void setFloat(int parameterIndex, float x)
790             throws java.sql.SQLException JavaDoc {
791         pstm.setFloat(parameterIndex, x);
792         saveQueryParamValue(parameterIndex, new Float JavaDoc(x));
793
794     }
795
796     /**
797      * Sets the designated parameter to a Java int value. The driver converts this
798      * to an SQL INTEGER value when it sends it to the database.
799      *
800      * @param parameterIndex the first parameter is 1, the second is 2, ...
801      * @param x the parameter value
802      * @throws SQLException if a database access error occurs
803      */

804     public void setInt(int parameterIndex, int x)
805             throws java.sql.SQLException JavaDoc {
806         pstm.setInt(parameterIndex, x);
807         saveQueryParamValue(parameterIndex, new Integer JavaDoc(x));
808     }
809
810     /**
811      * Sets the designated parameter to a Java long value. The driver converts this
812      * to an SQL BIGINT value when it sends it to the database.
813      *
814      * @param parameterIndex the first parameter is 1, the second is 2, ...
815      * @param x the parameter value
816      * @throws SQLException if a database access error occurs
817      */

818     public void setLong(int parameterIndex, long x)
819             throws java.sql.SQLException JavaDoc {
820         pstm.setLong(parameterIndex, x);
821         saveQueryParamValue(parameterIndex, new Long JavaDoc(x));
822
823     }
824
825     /**
826      * Sets the limit for the maximum number of bytes in a column to
827      * the given number of bytes. This is the maximum number of bytes
828      * that can be returned for any column value. This limit applies
829      * only to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and
830      * LONGVARCHAR fields. If the limit is exceeded, the excess data
831      * is silently discarded. For maximum portability, use values
832      * greater than 256.
833      *
834      * @param max the new max column size limit; zero means unlimited
835      * @throws SQLException if a database access error occurs
836      */

837     public void setMaxFieldSize(int max) throws java.sql.SQLException JavaDoc {
838         pstm.setMaxFieldSize(max);
839
840     }
841
842     /**
843      * Sets the limit for the maximum number of rows that any
844      * ResultSet can contain to the given number.
845      * If the limit is exceeded, the excess
846      * rows are silently dropped.
847      *
848      * @param max the new max rows limit; zero means unlimited
849      * @throws SQLException if a database access error occurs
850      */

851     public void setMaxRows(int max) throws java.sql.SQLException JavaDoc {
852         pstm.setMaxRows(max);
853     }
854
855     /**
856      * Sets the designated parameter to SQL NULL.
857      * <p/>
858      * <P><B>Note:</B> You must specify the parameter's SQL type.
859      *
860      * @param parameterIndex the first parameter is 1, the second is 2, ...
861      * @param sqlType the SQL type code defined in java.sql.Types
862      * @throws SQLException if a database access error occurs
863      */

864     public void setNull(int parameterIndex, int sqlType)
865             throws java.sql.SQLException JavaDoc {
866         pstm.setNull(parameterIndex, sqlType);
867         saveQueryParamValue(parameterIndex, null);
868     }
869
870     /**
871      * JDBC 2.0
872      * <p/>
873      * Sets the designated parameter to SQL NULL. This version of setNull should
874      * be used for user-named types and REF type parameters. Examples
875      * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
876      * named array types.
877      * <p/>
878      * <P><B>Note:</B> To be portable, applications must give the
879      * SQL type code and the fully-qualified SQL type name when specifying
880      * a NULL user-defined or REF parameter. In the case of a user-named type
881      * the name is the type name of the parameter itself. For a REF
882      * parameter the name is the type name of the referenced type. If
883      * a JDBC driver does not need the type code or type name information,
884      * it may ignore it.
885      * <p/>
886      * Although it is intended for user-named and Ref parameters,
887      * this method may be used to set a null parameter of any JDBC type.
888      * If the parameter does not have a user-named or REF type, the given
889      * typeName is ignored.
890      *
891      * @param paramIndex the first parameter is 1, the second is 2, ...
892      * @param sqlType a value from java.sql.Types
893      * @param typeName the fully-qualified name of an SQL user-named type,
894      * ignored if the parameter is not a user-named type or REF
895      * @throws SQLException if a database access error occurs
896      */

897     public void setNull(int paramIndex, int sqlType, String JavaDoc typeName)
898             throws java.sql.SQLException JavaDoc {
899         pstm.setNull(paramIndex, sqlType, typeName);
900         saveQueryParamValue(paramIndex, null);
901
902     }
903
904     /**
905      * <p>Sets the value of a parameter using an object; use the
906      * java.lang equivalent objects for integral values.
907      * <p/>
908      * <p>The JDBC specification specifies a standard mapping from
909      * Java Object types to SQL types. The given argument java object
910      * will be converted to the corresponding SQL type before being
911      * sent to the database.
912      * <p/>
913      * <p>Note that this method may be used to pass datatabase-
914      * specific abstract data types, by using a Driver-specific Java
915      * type.
916      * <p/>
917      * If the object is of a class implementing SQLData,
918      * the JDBC driver should call its method <code>writeSQL</code> to write it
919      * to the SQL data stream.
920      * If, on the other hand, the object is of a class implementing
921      * Ref, Blob, Clob, Struct,
922      * or Array, then the driver should pass it to the database as a value of the
923      * corresponding SQL type.
924      * <p/>
925      * This method throws an exception if there is an ambiguity, for example, if the
926      * object is of a class implementing more than one of those interfaces.
927      *
928      * @param parameterIndex the first parameter is 1, the second is 2, ...
929      * @param x the object containing the input parameter value
930      * @throws SQLException if a database access error occurs
931      */

932     public void setObject(int parameterIndex, Object JavaDoc x)
933             throws java.sql.SQLException JavaDoc {
934         pstm.setObject(parameterIndex, x);
935         saveQueryParamValue(parameterIndex, x);
936     }
937
938     /**
939      * Sets the value of the designated parameter with the given object.
940      * This method is like setObject above, except that it assumes a getScale of zero.
941      *
942      * @param parameterIndex the first parameter is 1, the second is 2, ...
943      * @param x the object containing the input parameter value
944      * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
945      * sent to the database
946      * @throws SQLException if a database access error occurs
947      */

948     public void setObject(int parameterIndex, Object JavaDoc x, int targetSqlType)
949             throws java.sql.SQLException JavaDoc {
950         pstm.setObject(parameterIndex, x, targetSqlType);
951         saveQueryParamValue(parameterIndex, x);
952     }
953
954     /**
955      * <p>Sets the value of a parameter using an object. The second
956      * argument must be an object type; for integral values, the
957      * java.lang equivalent objects should be used.
958      * <p/>
959      * <p>The given Java object will be converted to the targetSqlType
960      * before being sent to the database.
961      * <p/>
962      * If the object has a custom mapping (is of a class implementing SQLData),
963      * the JDBC driver should call its method <code>writeSQL</code> to write it
964      * to the SQL data stream.
965      * If, on the other hand, the object is of a class implementing
966      * Ref, Blob, Clob, Struct,
967      * or Array, the driver should pass it to the database as a value of the
968      * corresponding SQL type.
969      * <p/>
970      * <p>Note that this method may be used to pass datatabase-
971      * specific abstract data types.
972      *
973      * @param parameterIndex the first parameter is 1, the second is 2, ...
974      * @param x the object containing the input parameter value
975      * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
976      * sent to the database. The getScale argument may further qualify this type.
977      * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
978      * this is the number of digits after the decimal point. For all other
979      * types, this value will be ignored.
980      * @throws SQLException if a database access error occurs
981      * @see java.sql.Types
982      */

983     public void setObject(int parameterIndex,
984                           Object JavaDoc x,
985                           int targetSqlType,
986                           int scale)
987             throws java.sql.SQLException JavaDoc {
988
989         pstm.setObject(parameterIndex, x, targetSqlType, scale);
990         saveQueryParamValue(parameterIndex, x);
991     }
992
993     /**
994      * Sets the number of seconds the driver will
995      * wait for a Statement to execute to the given number of seconds.
996      * If the limit is exceeded, a SQLException is thrown.
997      *
998      * @param seconds the new query timeout limit in seconds; zero means
999      * unlimited
1000     * @throws SQLException if a database access error occurs
1001     */

1002    public void setQueryTimeout(int seconds) throws java.sql.SQLException JavaDoc {
1003        pstm.setQueryTimeout(seconds);
1004    }
1005
1006    /**
1007     * JDBC 2.0
1008     * <p/>
1009     * Sets a REF(&lt;structured-type&gt;) parameter.
1010     *
1011     * @param i the first parameter is 1, the second is 2, ...
1012     * @param x an object representing data of an SQL REF Type
1013     * @throws SQLException if a database access error occurs
1014     */

1015    public void setRef(int i, java.sql.Ref JavaDoc x) throws java.sql.SQLException JavaDoc {
1016        pstm.setRef(i, x);
1017        saveQueryParamValue(i, x);
1018
1019    }
1020
1021    /**
1022     * Sets the designated parameter to a Java short value. The driver converts this
1023     * to an SQL SMALLINT value when it sends it to the database.
1024     *
1025     * @param parameterIndex the first parameter is 1, the second is 2, ...
1026     * @param x the parameter value
1027     * @throws SQLException if a database access error occurs
1028     */

1029    public void setShort(int parameterIndex, short x)
1030            throws java.sql.SQLException JavaDoc {
1031        pstm.setShort(parameterIndex, x);
1032        saveQueryParamValue(parameterIndex, new Integer JavaDoc(x));
1033    }
1034
1035    /**
1036     * Sets the designated parameter to a Java String value. The driver converts this
1037     * to an SQL VARCHAR or LONGVARCHAR value (depending on the argument's
1038     * size relative to the driver's limits on VARCHARs) when it sends
1039     * it to the database.
1040     *
1041     * @param parameterIndex the first parameter is 1, the second is 2, ...
1042     * @param x the parameter value
1043     * @throws SQLException if a database access error occurs
1044     */

1045    public void setString(int parameterIndex, String JavaDoc x)
1046            throws java.sql.SQLException JavaDoc {
1047
1048        pstm.setString(parameterIndex, x);
1049        saveQueryParamValue(parameterIndex, x);
1050    }
1051
1052    /**
1053     * Sets the designated parameter to a java.sql.Time value. The driver converts this
1054     * to an SQL TIME value when it sends it to the database.
1055     *
1056     * @param parameterIndex the first parameter is 1, the second is 2, ...
1057     * @param x the parameter value
1058     * @throws SQLException if a database access error occurs
1059     */

1060    public void setTime(int parameterIndex, java.sql.Time JavaDoc x)
1061            throws java.sql.SQLException JavaDoc {
1062        pstm.setTime(parameterIndex, x);
1063        saveQueryParamValue(parameterIndex, x);
1064    }
1065
1066    /**
1067     * JDBC 2.0
1068     * <p/>
1069     * Sets the designated parameter to a java.sql.Time value,
1070     * using the given <code>Calendar</code> object. The driver uses
1071     * the <code>Calendar</code> object to construct an SQL TIME,
1072     * which the driver then sends to the database. With a
1073     * a <code>Calendar</code> object, the driver can calculate the time
1074     * taking into account a custom timezone and locale. If no
1075     * <code>Calendar</code> object is specified, the driver uses the default
1076     * timezone and locale.
1077     *
1078     * @param parameterIndex the first parameter is 1, the second is 2, ...
1079     * @param x the parameter value
1080     * @param cal the <code>Calendar</code> object the driver will use
1081     * to construct the time
1082     * @throws SQLException if a database access error occurs
1083     */

1084    public void setTime(int parameterIndex,
1085                        java.sql.Time JavaDoc x,
1086                        java.util.Calendar JavaDoc cal)
1087            throws java.sql.SQLException JavaDoc {
1088        pstm.setTime(parameterIndex, x, cal);
1089        saveQueryParamValue(parameterIndex, x);
1090
1091    }
1092
1093    /**
1094     * Sets the designated parameter to a java.sql.Timestamp value. The driver
1095     * converts this to an SQL TIMESTAMP value when it sends it to the
1096     * database.
1097     *
1098     * @param parameterIndex the first parameter is 1, the second is 2, ...
1099     * @param x the parameter value
1100     * @throws SQLException if a database access error occurs
1101     */

1102    public void setTimestamp(int parameterIndex, java.sql.Timestamp JavaDoc x)
1103            throws java.sql.SQLException JavaDoc {
1104        pstm.setTimestamp(parameterIndex, x);
1105        saveQueryParamValue(parameterIndex, x);
1106    }
1107
1108    /**
1109     * JDBC 2.0
1110     * <p/>
1111     * Sets the designated parameter to a java.sql.Timestamp value,
1112     * using the given <code>Calendar</code> object. The driver uses
1113     * the <code>Calendar</code> object to construct an SQL TIMESTAMP,
1114     * which the driver then sends to the database. With a
1115     * a <code>Calendar</code> object, the driver can calculate the timestamp
1116     * taking into account a custom timezone and locale. If no
1117     * <code>Calendar</code> object is specified, the driver uses the default
1118     * timezone and locale.
1119     *
1120     * @param parameterIndex the first parameter is 1, the second is 2, ...
1121     * @param x the parameter value
1122     * @param cal the <code>Calendar</code> object the driver will use
1123     * to construct the timestamp
1124     * @throws SQLException if a database access error occurs
1125     */

1126    public void setTimestamp(int parameterIndex,
1127                             java.sql.Timestamp JavaDoc x,
1128                             java.util.Calendar JavaDoc cal)
1129            throws java.sql.SQLException JavaDoc {
1130        pstm.setTimestamp(parameterIndex, x, cal);
1131        saveQueryParamValue(parameterIndex, x);
1132    }
1133
1134    /**
1135     * Sets the designated parameter to the given input stream, which will have
1136     * the specified number of bytes.
1137     * When a very large UNICODE value is input to a LONGVARCHAR
1138     * parameter, it may be more practical to send it via a
1139     * java.io.InputStream. JDBC will read the data from the stream
1140     * as needed, until it reaches end-of-file. The JDBC driver will
1141     * do any necessary conversion from UNICODE to the database char format.
1142     * The byte format of the Unicode stream must be Java UTF-8, as
1143     * defined in the Java Virtual Machine Specification.
1144     * <p/>
1145     * <P><B>Note:</B> This stream object can either be a standard
1146     * Java stream object or your own subclass that implements the
1147     * standard interface.
1148     *
1149     * @param parameterIndex the first parameter is 1, the second is 2, ...
1150     * @param x the java input stream which contains the
1151     * UNICODE parameter value
1152     * @param length the number of bytes in the stream
1153     * @throws SQLException if a database access error occurs
1154     * @deprecated
1155     */

1156    public void setUnicodeStream(int parameterIndex,
1157                                 java.io.InputStream JavaDoc x,
1158                                 int length)
1159            throws java.sql.SQLException JavaDoc {
1160        pstm.setUnicodeStream(parameterIndex, x, length);
1161        saveQueryParamValue(parameterIndex, x);
1162    }
1163
1164    public ResultSet JavaDoc getGeneratedKeys() throws SQLException JavaDoc {
1165        return pstm.getGeneratedKeys();
1166    }
1167
1168    public boolean execute(String JavaDoc sql, int columnIndexes[]) throws SQLException JavaDoc {
1169        return pstm.execute(sql, columnIndexes);
1170    }
1171
1172    public boolean execute(String JavaDoc sql, String JavaDoc columnNames[]) throws SQLException JavaDoc {
1173        return pstm.execute(sql, columnNames);
1174    }
1175
1176    public int executeUpdate(String JavaDoc sql, String JavaDoc columnNames[]) throws SQLException JavaDoc {
1177        return pstm.executeUpdate(sql, columnNames);
1178    }
1179
1180    public ParameterMetaData JavaDoc getParameterMetaData() throws SQLException JavaDoc {
1181        return pstm.getParameterMetaData();
1182    }
1183
1184    public void setURL(int parameterIndex, URL JavaDoc x) throws SQLException JavaDoc {
1185        pstm.setURL(parameterIndex, x);
1186        saveQueryParamValue(parameterIndex, x);
1187    }
1188
1189    public int executeUpdate(String JavaDoc sql, int autoGeneratedKeys) throws SQLException JavaDoc {
1190        return pstm.executeUpdate(sql, autoGeneratedKeys);
1191    }
1192
1193    public boolean getMoreResults(int current) throws SQLException JavaDoc {
1194        return pstm.getMoreResults(current);
1195    }
1196
1197    public int getResultSetHoldability() throws SQLException JavaDoc {
1198        return pstm.getResultSetHoldability();
1199    }
1200
1201    public boolean execute(String JavaDoc sql, int autoGeneratedKeys) throws SQLException JavaDoc {
1202        return pstm.execute(sql, autoGeneratedKeys);
1203    }
1204
1205    public int executeUpdate(String JavaDoc sql, int columnIndexes[]) throws SQLException JavaDoc {
1206        return pstm.executeUpdate(sql, columnIndexes);
1207    }
1208
1209    /**
1210     * Returns the sql statement string (question marks replaced with set parameter values)
1211     * that will be (or has been) executed by the {@link java.sql.PreparedStatement PreparedStatement} that this
1212     * <code>LoggableStatement</code> is a wrapper for.
1213     * <p/>
1214     *
1215     * @return java.lang.String the statemant represented by this <code>LoggableStatement</code>
1216     */

1217    public String JavaDoc getSQLString() {
1218        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1219        int qMarkCount = 0;
1220// ArrayList chunks = new ArrayList();
1221
StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(sqlTemplate + " ", "?");
1222        while(tok.hasMoreTokens()) {
1223            String JavaDoc oneChunk = tok.nextToken();
1224            buf.append(oneChunk);
1225
1226            try {
1227                Object JavaDoc value;
1228                if(parameterValues.size() > 1 + qMarkCount) {
1229                    value = parameterValues.get(1 + qMarkCount++);
1230                }
1231                else {
1232                    if(tok.hasMoreTokens()) {
1233                        value = null;
1234                    }
1235                    else {
1236                        value = "";
1237                    }
1238                }
1239                buf.append("" + value);
1240            }
1241            catch(Throwable JavaDoc e) {
1242                buf.append("ERROR WHEN PRODUCING QUERY STRING FOR LOG."
1243                        + e.toString());
1244                // catch this without whining, if this fails the only thing wrong is probably this class
1245
}
1246        }
1247        return buf.toString().trim();
1248    }
1249
1250    /**
1251     * Saves the parameter value <code>obj</code> for the specified <code>position</code> for use in logging output
1252     *
1253     * @param position position (starting at 1) of the parameter to save
1254     * @param obj java.lang.Object the parameter value to save
1255     */

1256    private void saveQueryParamValue(int position, Object JavaDoc obj) {
1257        String JavaDoc strValue;
1258        if(obj instanceof String JavaDoc || obj instanceof Date JavaDoc) {
1259            // if we have a String or Date , include '' in the saved value
1260
strValue = "'" + obj + "'";
1261        }
1262        else {
1263
1264            if(obj == null) {
1265                // convert null to the string null
1266
strValue = "null";
1267            }
1268            else {
1269                // unknown object (includes all Numbers), just call toString
1270
strValue = obj.toString();
1271            }
1272        }
1273
1274        // if we are setting a position larger than current size of parameterValues, first make it larger
1275
while(position >= parameterValues.size()) {
1276            parameterValues.add(null);
1277        }
1278        // save the parameter
1279
parameterValues.set(position, strValue);
1280    }
1281
1282}
1283
1284
Popular Tags