1 pjaol 1.1 /**
2 * Title: <p>
3 * Description: <p>
4 * Copyright: Copyright (c) Troy Thompson Bob Byron<p>
5 * Company: JavaUnderground<p>
6 * @author Troy Thompson Bob Byron
7 * @version 1.1
8 */
9 package com.javaunderground.jdbc;
10
11 import java.io.InputStream;
12 import java.io.Reader;
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
15 import java.math.BigDecimal;
16 import java.net.URL;
17 import java.sql.Blob;
18 import java.sql.Clob;
19 import java.sql.Connection;
20 import java.sql.ParameterMetaData;
21 import java.sql.PreparedStatement;
22 pjaol 1.1 import java.sql.Ref;
23 import java.sql.ResultSet;
24 import java.sql.ResultSetMetaData;
25 import java.sql.SQLException;
26 import java.sql.SQLWarning;
27 import java.sql.Time;
28 import java.sql.Timestamp;
29 import java.util.Calendar;
30 import java.util.StringTokenizer;
31
32 /**
33 * PreparedStatements have no way to retrieve the statement that was executed on
34 * the database. This is due to the nature of prepared statements, which are
35 * database driver specific. This class proxies for a PreparedStatement and
36 * creates the SQL string that is created from the sets done on the
37 * PreparedStatement.
38 * <p>
39 * Some of the objects such as blob, clob, and Ref are only represented as
40 * Strings and are not the actual objects populating the database. Array is
41 * represented by the object type within the array.
42 *
43 pjaol 1.1 * Example code: int payPeriod = 1; String name = "Troy Thompson"; ArrayList
44 * employeePay = new ArrayList(); ResultSet rs = null; PreparedStatement ps =
45 * null; Connection con = null; try{
46 * Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url =
47 * "jdbc:odbc:Employee"; con = DriverManager.getConnection(url); String sql =
48 * "SELECT e.name,e.employee_number,e.pay_rate,e.type,"+ "
49 * e.hire_date,h.pay_period,h.hours,h.commissions"+ " FROM Employee_tbl
50 * e,hours_tbl h "+ " WHERE h.pay_period = ?"+ " AND e.name = ?"+ " AND
51 * h.employee_number = e.employee_number"; ps =
52 * StatementFactory.getStatement(con,sql); // <-- insert this to debug //ps =
53 * con.prepareStatement(sql); ps.setInt(1,payPeriod); ps.setString(2,name);
54 * System.out.println(); System.out.println(" debuggable statement= " +
55 * ps.toString()); rs = ps.executeQuery(); }catch(SQLException e){
56 * e.printStackTrace(); }catch(ClassNotFoundException ce){ ce.printStackTrace(); }
57 * finally{ try{ if(rs != null){rs.close();} if(ps != null){ps.close();}
58 * if(!con.isClosed()) con.close(); }catch(SQLException e){ e.printStackTrace(); } }
59 * </p>
60 * *****notes***** One of the main differences between databases is how they
61 * handle dates/times. Since we use Oracle, the debug string for Dates, Times,
62 * Timestamps are using an Oracle specific SqlFormatter called
63 * OracleSqlFormatter.
64 pjaol 1.1 *
65 * The following is in our debug class: static{
66 * StatementFactory.setDefaultDebug(DebugLevel.ON);
67 * StatementFactory.setDefaultFormatter(new OracleSqlFormatter()); }
68 *
69 */
70 public class DebuggableStatement implements PreparedStatement {
71
72 private PreparedStatement ps; // preparedStatement being proxied for.
73
74 private String sql; // original statement going to database.
75
76 private String filteredSql; // statement filtered for rogue '?' that are not
77 // bind variables.
78
79 private DebugObject[] variables; // array of bind variables
80
81 private SqlFormatter formatter; // format for dates
82
83 private long startTime; // time that statement began execution
84
85 pjaol 1.1 private long executeTime; // time elapsed while executing statement
86
87 private DebugLevel debugLevel; // level of debug
88
89 /**
90 * Construct new DebugableStatement. Uses the SqlFormatter to format date,
91 * time, timestamp outputs
92 *
93 * @param con
94 * Connection to be used to construct PreparedStatement
95 * @param sqlStatement
96 * sql statement to be sent to database.
97 * @param debugLevel
98 * DebugLevel can be ON, OFF, VERBOSE.
99 *
100 */
101 protected DebuggableStatement(Connection con, String sqlStatement,
102 SqlFormatter formatter, DebugLevel debugLevel) throws SQLException {
103 // set values for member variables
104 if (con == null)
105 throw new SQLException("Connection object is null");
106 pjaol 1.1 this.ps = con.prepareStatement(sqlStatement);
107 this.sql = sqlStatement;
108 this.debugLevel = debugLevel;
109 this.formatter = formatter;
110
111 // see if there are any '?' in the statement that are not bind variables
112 // and filter them out.
113 boolean isString = false;
114 char[] sqlString = sqlStatement.toCharArray();
115 for (int i = 0; i < sqlString.length; i++) {
116 if (sqlString[i] == '\'')
117 isString = !isString;
118 // substitute the ? with an unprintable character if the ? is in a
119 // string.
120 if (sqlString[i] == '?' && isString)
121 sqlString[i] = '\u0007';
122 }
123 filteredSql = new String(sqlString);
124
125 // find out how many variables are present in statement.
126 int count = 0;
127 pjaol 1.1 int index = -1;
128 while ((index = filteredSql.indexOf("?", index + 1)) != -1) {
129 count++;
130 }
131
132 // show how many bind variables found
133 if (debugLevel == DebugLevel.VERBOSE)
134 System.out.println("count= " + count);
135
136 // create array for bind variables
137 variables = new DebugObject[count];
138
139 }
140
141 /**
142 * Facade for PreparedStatement
143 */
144 public void addBatch() throws SQLException {
145 ps.addBatch();
146 }
147
148 pjaol 1.1 /**
149 * Facade for PreparedStatement
150 */
151 public void addBatch(String sql) throws SQLException {
152 ps.addBatch();
153 }
154
155 /**
156 * Facade for PreparedStatement
157 */
158 public void cancel() throws SQLException {
159 ps.cancel();
160 }
161
162 /**
163 * Facade for PreparedStatement
164 */
165 public void clearBatch() throws SQLException {
166 ps.clearBatch();
167 }
168
169 pjaol 1.1 /**
170 * Facade for PreparedStatement
171 */
172 public void clearParameters() throws SQLException {
173 ps.clearParameters();
174 }
175
176 /**
177 * Facade for PreparedStatement
178 */
179 public void clearWarnings() throws SQLException {
180 ps.clearWarnings();
181 }
182
183 /**
184 * Facade for PreparedStatement
185 */
186 public void close() throws SQLException {
187 ps.close();
188 }
189
190 pjaol 1.1 /**
191 * Executes query and Calculates query execution time if DebugLevel =
192 * VERBOSE
193 *
194 * @return results of query
195 */
196 public boolean execute() throws SQLException {
197 // execute query
198 Boolean results = null;
199 try {
200 results = (Boolean) executeVerboseQuery("execute", null);
201 } catch (Exception e) {
202 throw new SQLException(
203 "Could not execute sql command - Original message: "
204 + e.getMessage());
205 }
206 return results.booleanValue();
207 }
208
209 /**
210 * This method is only here for convenience. If a different sql string is
211 pjaol 1.1 * executed than was passed into Debuggable, unknown results will occur.
212 * Executes query and Calculates query execution time if DebugLevel =
213 * VERBOSE
214 *
215 * @param sql
216 * should be same string that was passed into Debuggable
217 * @return results of query
218 */
219 public boolean execute(String sql) throws SQLException {
220 // execute query
221 Boolean results = null;
222 try {
223 results = (Boolean) executeVerboseQuery("execute",
224 new Class[] { sql.getClass() });
225 } catch (Exception e) {
226 throw new SQLException(
227 "Could not execute sql command - Original message: "
228 + e.getMessage());
229 }
230 return results.booleanValue();
231 }
232 pjaol 1.1
233 /**
234 * Executes query and Calculates query execution time if DebugLevel =
235 * VERBOSE
236 *
237 * @return results of query
238 */
239 public int[] executeBatch() throws SQLException {
240 // execute query
241 int[] results = null;
242 try {
243 results = (int[]) executeVerboseQuery("executeBatch", null);
244 } catch (Exception e) {
245 throw new SQLException(
246 "Could not execute sql command - Original message: "
247 + e.getMessage());
248 }
249 return results;
250 }
251
252 /**
253 pjaol 1.1 * Executes query and Calculates query execution time if DebugLevel =
254 * VERBOSE
255 *
256 * @return results of query
257 */
258 public ResultSet executeQuery() throws SQLException {
259 // execute query
260 ResultSet results = null;
261 try {
262 results = (ResultSet) executeVerboseQuery("executeQuery", null);
263 } catch (Exception e) {
264 throw new SQLException(
265 "Could not execute sql command - Original message: "
266 + e.getMessage());
267 }
268 return results;
269 }
270
271 /**
272 * This method is only here for convenience. If a different sql string is
273 * executed than was passed into Debuggable, unknown results will occur.
274 pjaol 1.1 * Executes query and Calculates query execution time if DebugLevel =
275 * VERBOSE
276 *
277 * @param sql
278 * should be same string that was passed into Debuggable
279 * @return results of query
280 */
281 public ResultSet executeQuery(String sql) throws SQLException {
282 // execute query
283 ResultSet results = null;
284 try {
285 results = (ResultSet) executeVerboseQuery("executeQuery",
286 new Class[] { sql.getClass() });
287 } catch (Exception e) {
288 throw new SQLException(
289 "Could not execute sql command - Original message: "
290 + e.getMessage());
291 }
292 return results;
293 }
294
295 pjaol 1.1 /**
296 * Executes query and Calculates query execution time if DebugLevel =
297 * VERBOSE
298 *
299 * @return results of query
300 */
301 public int executeUpdate() throws SQLException {
302 // execute query
303 Integer results = null;
304 try {
305 results = (Integer) executeVerboseQuery("executeUpdate", null);
306 } catch (Exception e) {
307 throw new SQLException(
308 "Could not execute sql command - Original message: "
309 + e.getMessage());
310 }
311 return results.intValue();
312 }
313
314 /**
315 * This method is only here for convenience. If a different sql string is
316 pjaol 1.1 * executed than was passed into Debuggable, unknown results will occur.
317 * Executes query and Calculates query execution time if DebugLevel =
318 * VERBOSE
319 *
320 * @param sql
321 * should be same string that was passed into Debuggable
322 * @return results of query
323 */
324 public int executeUpdate(String sql) throws SQLException {
325 // execute query
326 Integer results = null;
327 try {
328 results = (Integer) executeVerboseQuery("executeUpdate",
329 new Class[] { sql.getClass() });
330 } catch (Exception e) {
331 throw new SQLException(
332 "Could not execute sql command - Original message: "
333 + e.getMessage());
334 }
335 return results.intValue();
336 }
337 pjaol 1.1
338 /**
339 * Facade for PreparedStatement
340 */
341 public Connection getConnection() throws SQLException {
342 return ps.getConnection();
343 }
344
345 /**
346 * Facade for PreparedStatement
347 */
348 public int getFetchDirection() throws SQLException {
349 return ps.getFetchDirection();
350 }
351
352 /**
353 * Facade for PreparedStatement
354 */
355 public int getFetchSize() throws SQLException {
356 return ps.getFetchSize();
357 }
358 pjaol 1.1
359 /**
360 * Facade for PreparedStatement
361 */
362 public int getMaxFieldSize() throws SQLException {
363 return ps.getMaxFieldSize();
364 }
365
366 /**
367 * Facade for PreparedStatement
368 */
369 public int getMaxRows() throws SQLException {
370 return ps.getMaxRows();
371 }
372
373 /**
374 * Facade for PreparedStatement
375 */
376 public ResultSetMetaData getMetaData() throws SQLException {
377 return ps.getMetaData();
378 }
379 pjaol 1.1
380 /**
381 * Facade for PreparedStatement
382 */
383 public boolean getMoreResults() throws SQLException {
384 return ps.getMoreResults();
385 }
386
387 /**
388 * Facade for PreparedStatement
389 */
390 public int getQueryTimeout() throws SQLException {
391 return ps.getQueryTimeout();
392 }
393
394 /**
395 * Facade for PreparedStatement
396 */
397 public ResultSet getResultSet() throws SQLException {
398 return ps.getResultSet();
399 }
400 pjaol 1.1
401 /**
402 * Facade for PreparedStatement
403 */
404 public int getResultSetConcurrency() throws SQLException {
405 return ps.getResultSetConcurrency();
406 }
407
408 /**
409 * Facade for PreparedStatement
410 */
411 public int getResultSetType() throws SQLException {
412 return ps.getResultSetType();
413 }
414
415 /**
416 * Facade for PreparedStatement
417 */
418 public String getStatement() {
419 return sql;
420 }
421 pjaol 1.1
422 /**
423 * Facade for PreparedStatement
424 */
425 public int getUpdateCount() throws SQLException {
426 return ps.getUpdateCount();
427 }
428
429 /**
430 * Facade for PreparedStatement
431 */
432 public SQLWarning getWarnings() throws SQLException {
433 return ps.getWarnings();
434 }
435
436 /**
437 * Tests Object o for parameterIndex (which parameter is being set) and
438 * places object in array of variables.
439 *
440 * @param parameterIndex
441 * which PreparedStatement parameter is being set. Sequence
442 pjaol 1.1 * begins at 1.
443 * @param o
444 * Object being stored as parameter
445 * @exception Thrown
446 * if index exceeds number of variables.
447 */
448 private void saveObject(int parameterIndex, Object o)
449 throws ParameterIndexOutOfBoundsException {
450 if (parameterIndex > variables.length)
451 throw new ParameterIndexOutOfBoundsException("Parameter index of "
452 + parameterIndex + " exceeds actual parameter count of "
453 + variables.length);
454
455 variables[parameterIndex - 1] = new DebugObject(o);
456 }
457
458 /**
459 * Adds name of the Array's internal class type(by using
460 * x.getBaseTypeName()) to the debug String. If x is null, NULL is added to
461 * debug String.
462 *
463 pjaol 1.1 * @param i
464 * index of parameter
465 * @param x
466 * parameter Object
467 */
468 public void setArray(int i, java.sql.Array x) throws SQLException {
469 saveObject(i, x);
470 ps.setArray(i, x);
471 }
472
473 /**
474 * Debug string prints NULL if InputStream is null, or adds "stream length = " +
475 * length
476 */
477 public void setAsciiStream(int parameterIndex, InputStream x, int length)
478 throws SQLException {
479 saveObject(parameterIndex, (x == null ? "NULL" : "<stream length= "
480 + length + ">"));
481 ps.setAsciiStream(parameterIndex, x, length);
482 }
483
484 pjaol 1.1 /**
485 * Adds BigDecimal to debug string in parameterIndex position.
486 *
487 * @param parameterIndex
488 * index of parameter
489 * @param x
490 * parameter Object
491 */
492 public void setBigDecimal(int parameterIndex, BigDecimal x)
493 throws SQLException {
494 saveObject(parameterIndex, x);
495 ps.setBigDecimal(parameterIndex, x);
496 }
497
498 /**
499 * Debug string prints NULL if InputStream is null, or adds "stream length= " +
500 * length.
501 *
502 * @param parameterIndex
503 * index of parameter
504 * @param x
505 pjaol 1.1 * parameter Object
506 * @param length
507 * length of InputStream
508 */
509 public void setBinaryStream(int parameterIndex, InputStream x, int length)
510 throws SQLException {
511 saveObject(parameterIndex, (x == null ? "NULL" : "<stream length= "
512 + length + ">"));
513 ps.setBinaryStream(parameterIndex, x, length);
514 }
515
516 /**
517 * Adds name of the object's class type(Blob) to the debug String. If object
518 * is null, NULL is added to debug String.
519 *
520 * @param parameterIndex
521 * index of parameter
522 * @param x
523 * parameter Object
524 */
525 public void setBlob(int parameterIndex, Blob x) throws SQLException {
526 pjaol 1.1 saveObject(parameterIndex, x);
527 ps.setBlob(parameterIndex, x);
528 }
529
530 /**
531 * Adds boolean to debug string in parameterIndex position.
532 *
533 * @param parameterIndex
534 * index of parameter
535 * @param x
536 * parameter Object
537 */
538 public void setBoolean(int parameterIndex, boolean x) throws SQLException {
539 saveObject(parameterIndex, new Boolean(x));
540 ps.setBoolean(parameterIndex, x);
541 }
542
543 /**
544 * Adds byte to debug string in parameterIndex position.
545 *
546 * @param parameterIndex
547 pjaol 1.1 * index of parameter
548 * @param x
549 * parameter Object
550 */
551 public void setByte(int parameterIndex, byte x) throws SQLException {
552 saveObject(parameterIndex, new Byte(x));
553 ps.setByte(parameterIndex, x);
554 }
555
556 /**
557 * Adds byte[] to debug string in parameterIndex position.
558 *
559 * @param parameterIndex
560 * index of parameter
561 * @param x
562 * parameter Object
563 */
564 public void setBytes(int parameterIndex, byte[] x) throws SQLException {
565 saveObject(parameterIndex, (x == null ? "NULL" : "byte[] length="
566 + x.length));
567 ps.setBytes(parameterIndex, x);
568 pjaol 1.1 }
569
570 /**
571 * Debug string prints NULL if reader is null, or adds "stream length= " +
572 * length.
573 *
574 * @param parameterIndex
575 * index of parameter
576 * @param x
577 * parameter Object
578 * @param length
579 * length of InputStream
580 */
581 public void setCharacterStream(int parameterIndex, Reader reader, int length)
582 throws SQLException {
583 saveObject(parameterIndex, (reader == null ? "NULL"
584 : "<stream length= " + length + ">"));
585 ps.setCharacterStream(parameterIndex, reader, length);
586 }
587
588 /**
589 pjaol 1.1 * Adds name of the object's class type(Clob) to the debug String. If object
590 * is null, NULL is added to debug String.
591 *
592 * @param parameterIndex
593 * index of parameter
594 * @param x
595 * parameter Object
596 */
597 public void setClob(int i, Clob x) throws SQLException {
598 saveObject(i, x);
599 ps.setClob(i, x);
600 }
601
602 public void setCursorName(String name) throws SQLException {
603 ps.setCursorName(name);
604 }
605
606 /**
607 * Debug string displays date in YYYY-MM-DD HH24:MI:SS.# format.
608 *
609 * @param parameterIndex
610 pjaol 1.1 * index of parameter
611 * @param x
612 * parameter Object
613 */
614 public void setDate(int parameterIndex, java.sql.Date x)
615 throws SQLException {
616 saveObject(parameterIndex, x);
617 ps.setDate(parameterIndex, x);
618 }
619
620 /**
621 * this implementation assumes that the Date has the date, and the calendar
622 * has the local info. For the debug string, the cal date is set to the date
623 * of x. Debug string displays date in YYYY-MM-DD HH24:MI:SS.# format.
624 *
625 * @param parameterIndex
626 * index of parameter
627 * @param x
628 * parameter Object
629 * @param cal
630 * uses x to set time
631 pjaol 1.1 */
632 public void setDate(int parameterIndex, java.sql.Date x, Calendar cal)
633 throws SQLException {
634 cal.setTime(new java.util.Date(x.getTime()));
635 saveObject(parameterIndex, cal);
636 ps.setDate(parameterIndex, x, cal);
637 }
638
639 /**
640 * Adds double to debug string in parameterIndex position.
641 *
642 * @param parameterIndex
643 * index of parameter
644 * @param x
645 * parameter Object
646 */
647 public void setDouble(int parameterIndex, double x) throws SQLException {
648 saveObject(parameterIndex, new Double(x));
649 ps.setDouble(parameterIndex, x);
650 }
651
652 pjaol 1.1 /**
653 * Facade for PreparedStatement
654 */
655 public void setEscapeProcessing(boolean enable) throws SQLException {
656 ps.setEscapeProcessing(enable);
657 }
658
659 /**
660 * Facade for PreparedStatement
661 */
662 public void setFormatter(SqlFormatter formatter) {
663 this.formatter = formatter;
664 }
665
666 /**
667 * Facade for PreparedStatement
668 */
669 public void setFetchDirection(int direction) throws SQLException {
670 ps.setFetchDirection(direction);
671 }
672
673 pjaol 1.1 /**
674 * Facade for PreparedStatement
675 */
676 public void setFetchSize(int rows) throws SQLException {
677 ps.setFetchSize(rows);
678 }
679
680 /**
681 * Adds float to debug string in parameterIndex position.
682 *
683 * @param parameterIndex
684 * index of parameter
685 * @param x
686 * parameter Object
687 */
688 public void setFloat(int parameterIndex, float x) throws SQLException {
689 saveObject(parameterIndex, new Float(x));
690 ps.setFloat(parameterIndex, x);
691 }
692
693 /**
694 pjaol 1.1 * Adds int to debug string in parameterIndex position.
695 *
696 * @param parameterIndex
697 * index of parameter
698 * @param x
699 * parameter Object
700 */
701 public void setInt(int parameterIndex, int x) throws SQLException {
702 saveObject(parameterIndex, new Integer(x));
703 ps.setInt(parameterIndex, x);
704 }
705
706 /**
707 * Adds long to debug string in parameterIndex position.
708 *
709 * @param parameterIndex
710 * index of parameter
711 * @param x
712 * parameter Object
713 */
714 public void setLong(int parameterIndex, long x) throws SQLException {
715 pjaol 1.1 saveObject(parameterIndex, new Long(x));
716 ps.setLong(parameterIndex, x);
717 }
718
719 /**
720 * Facade for PreparedStatement
721 */
722 public void setMaxFieldSize(int max) throws SQLException {
723 ps.setMaxFieldSize(max);
724 }
725
726 /**
727 * Facade for PreparedStatement
728 */
729 public void setMaxRows(int max) throws SQLException {
730 ps.setMaxRows(max);
731 }
732
733 /**
734 * Adds a NULL to the debug String.
735 *
736 pjaol 1.1 * @param parameterIndex
737 * index of parameter
738 * @param x
739 * parameter Object
740 */
741 public void setNull(int parameterIndex, int sqlType) throws SQLException {
742 saveObject(parameterIndex, "NULL");
743 ps.setNull(parameterIndex, sqlType);
744 }
745
746 /**
747 * Adds a NULL to the debug String.
748 *
749 * @param parameterIndex
750 * index of parameter
751 * @param x
752 * parameter Object
753 * @param typeName
754 * type of Object
755 */
756 public void setNull(int parameterIndex, int sqlType, String typeName)
757 pjaol 1.1 throws SQLException {
758 saveObject(parameterIndex, "NULL");
759 ps.setNull(parameterIndex, sqlType, typeName);
760 }
761
762 /**
763 * Adds name of the object's class type to the debug String. If object is
764 * null, NULL is added to debug String.
765 *
766 * @param parameterIndex
767 * index of parameter
768 * @param x
769 * parameter Object
770 */
771 public void setObject(int parameterIndex, Object x) throws SQLException {
772 saveObject(parameterIndex,
773 (x == null ? "NULL" : x.getClass().getName()));
774 ps.setObject(parameterIndex, x);
775 }
776
777 /**
778 pjaol 1.1 * Adds name of the object's class type to the debug String. If object is
779 * null, NULL is added to debug String.
780 *
781 * @param parameterIndex
782 * index of parameter
783 * @param x
784 * parameter Object
785 * @param targetSqlType
786 * database type
787 */
788 public void setObject(int parameterIndex, Object x, int targetSqlType)
789 throws SQLException {
790 saveObject(parameterIndex,
791 (x == null ? "NULL" : x.getClass().getName()));
792 ps.setObject(parameterIndex, x, targetSqlType);
793 }
794
795 /**
796 * Adds name of the object's class type to the debug String. If object is
797 * null, NULL is added to debug String.
798 *
799 pjaol 1.1 * @param parameterIndex
800 * index of parameter
801 * @param x
802 * parameter Object
803 * @param targetSqlType
804 * database type
805 * @param scale
806 * see PreparedStatement
807 */
808 public void setObject(int parameterIndex, Object x, int targetSqlType,
809 int scale) throws SQLException {
810 saveObject(parameterIndex,
811 (x == null ? "NULL" : x.getClass().getName()));
812 ps.setObject(parameterIndex, x, targetSqlType, scale);
813 }
814
815 /**
816 * Facade for PreparedStatement
817 */
818 public void setQueryTimeout(int seconds) throws SQLException {
819 ps.setQueryTimeout(seconds);
820 pjaol 1.1 }
821
822 /**
823 * From the javadocs: A reference to an SQL structured type value in the
824 * database. A Ref can be saved to persistent storage. The output from this
825 * method call in DebuggableStatement is a string representation of the Ref
826 * object by calling the Ref object's getBaseTypeName() method. Again, this
827 * will only be a String representation of the actual object being stored in
828 * the database.
829 *
830 * @param i
831 * index of parameter
832 * @param x
833 * parameter Object
834 */
835
836 public void setRef(int i, Ref x) throws SQLException {
837 saveObject(i, x);
838 ps.setRef(i, x);
839 }
840
841 pjaol 1.1 /**
842 * Adds short to debug string in parameterIndex position.
843 *
844 * @param parameterIndex
845 * index of parameter
846 * @param x
847 * parameter Object
848 */
849 public void setShort(int parameterIndex, short x) throws SQLException {
850 saveObject(parameterIndex, new Short(x));
851 ps.setShort(parameterIndex, x);
852 }
853
854 /**
855 * Adds String to debug string in parameterIndex position. If String is null
856 * "NULL" is inserted in debug string. ***note**** In situations where a
857 * single ' is in the string being inserted in the database. The debug
858 * string will need to be modified to reflect this when running the debug
859 * statement in the database.
860 *
861 * @param parameterIndex
862 pjaol 1.1 * index of parameter
863 * @param x
864 * parameter Object
865 */
866 public void setString(int parameterIndex, String x) throws SQLException {
867 saveObject(parameterIndex, x);
868 ps.setString(parameterIndex, x);
869 }
870
871 /**
872 * Debug string displays Time in HH24:MI:SS.# format.
873 *
874 * @param parameterIndex
875 * index of parameter
876 * @param x
877 * parameter Object
878 */
879 public void setTime(int parameterIndex, Time x) throws SQLException {
880 saveObject(parameterIndex, x);
881 ps.setTime(parameterIndex, x);
882 }
883 pjaol 1.1
884 /**
885 * This implementation assumes that the Time object has the time and
886 * Calendar has the locale info. For the debug string, the cal time is set
887 * to the value of x. Debug string displays time in HH24:MI:SS.# format.
888 *
889 * @param parameterIndex
890 * index of parameter
891 * @param x
892 * parameter Object
893 * @param cal
894 * sets time based on x
895 */
896 public void setTime(int parameterIndex, Time x, Calendar cal)
897 throws SQLException {
898 cal.setTime(new java.util.Date(x.getTime()));
899 saveObject(parameterIndex, cal);
900 ps.setTime(parameterIndex, x, cal);
901 }
902
903 /**
904 pjaol 1.1 * Debug string displays timestamp in YYYY-MM-DD HH24:MI:SS.# format.
905 *
906 * @param parameterIndex
907 * index of parameter
908 * @param x
909 * parameter Object
910 */
911 public void setTimestamp(int parameterIndex, Timestamp x)
912 throws SQLException {
913 saveObject(parameterIndex, x);
914 ps.setTimestamp(parameterIndex, x);
915 }
916
917 /**
918 * This implementation assumes that the Timestamp has the date/time and
919 * Calendar has the locale info. For the debug string, the cal date/time is
920 * set to the default value of Timestamp which is YYYY-MM-DD HH24:MI:SS.#.
921 * Debug string displays timestamp in DateFormat.LONG format.
922 *
923 * @param parameterIndex
924 * index of parameter
925 pjaol 1.1 * @param x
926 * parameter Object
927 * @param cal
928 * sets time based on x
929 */
930 public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
931 throws SQLException {
932 cal.setTime(new java.util.Date(x.getTime()));
933 saveObject(parameterIndex, cal);
934 ps.setTimestamp(parameterIndex, x, cal);
935 }
936
937 /**
938 * Method has been deprecated in PreparedStatement interface. This method is
939 * present only to satisfy interface and does not do anything. Do not use...
940 *
941 * @deprecated
942 */
943 public void setUnicodeStream(int parameterIndex, InputStream x, int length)
944 throws SQLException {
945 // ps.setUnicodeStream(parameterIndex, x, length);
946 pjaol 1.1 }
947
948 /**
949 * this toString is overidden to return a String representation of the sql
950 * statement being sent to the database. If a bind variable is missing then
951 * the String contains a ? + (missing variable #)
952 *
953 * @return the above string representation
954 */
955 public String toString() {
956 StringTokenizer st = new StringTokenizer(filteredSql, "?");
957 int count = 1;
958 StringBuffer statement = new StringBuffer();
959 while (st.hasMoreTokens()) {
960 statement.append(st.nextToken());
961 if (count <= variables.length) {
962 if (variables[count - 1] != null
963 && variables[count - 1].isValueAssigned()) {
964 try {
965 statement.append(formatter.format(variables[count - 1]
966 .getDebugObject()));
967 pjaol 1.1 } catch (SQLException e) {
968 statement.append("SQLException");
969 }
970 } else {
971 statement.append("? " + "(missing variable # " + count
972 + " ) ");
973 }
974 }
975 count++;
976 }
977 // unfilter the string in case there where rogue '?' in query string.
978 char[] unfilterSql = statement.toString().toCharArray();
979 for (int i = 0; i < unfilterSql.length; i++) {
980 if (unfilterSql[i] == '\u0007')
981 unfilterSql[i] = '?';
982 }
983
984 // return execute time
985 if (debugLevel == DebugLevel.ON)
986 return new String(unfilterSql);
987 else
988 pjaol 1.1 return new String(unfilterSql)
989 + System.getProperty("line.separator")
990 + System.getProperty("line.separator")
991 + "query executed in " + executeTime + " milliseconds"
992 + System.getProperty("line.separator");
993
994 }
995
996 private Object executeVerboseQuery(String methodName, Class[] parameters)
997 throws SQLException, NoSuchMethodException,
998 InvocationTargetException, IllegalAccessException {
999 // determine which method we have
1000 Method m = ps.getClass().getDeclaredMethod(methodName, parameters);
1001
1002 // debug is set to on, so no times are calculated
1003 if (debugLevel == DebugLevel.ON)
1004 return m.invoke(ps, parameters);
1005
1006 // calculate execution time for verbose debugging
1007 start();
1008 Object returnObject = m.invoke(ps, parameters);
1009 pjaol 1.1 end();
1010
1011 // return the executions return type
1012 return returnObject;
1013 }
1014
1015 private void start() {
1016 startTime = System.currentTimeMillis();
1017 }
1018
1019 private void end() {
1020 executeTime = System.currentTimeMillis() - startTime;
1021 }
1022
1023 private class DebugObject {
1024 private Object debugObject;
1025
1026 private boolean valueAssigned;
1027
1028 public DebugObject(Object debugObject) {
1029 this.debugObject = debugObject;
1030 pjaol 1.1 valueAssigned = true;
1031 }
1032
1033 public Object getDebugObject() {
1034 return debugObject;
1035 }
1036
1037 public boolean isValueAssigned() {
1038 return valueAssigned;
1039 }
1040 }
1041
1042 public void setURL(int arg0, URL arg1) throws SQLException {
1043 // TODO Auto-generated method stub
1044
1045 }
1046
1047 public ParameterMetaData getParameterMetaData() throws SQLException {
1048 // TODO Auto-generated method stub
1049 return null;
1050 }
1051 pjaol 1.1
1052 public boolean getMoreResults(int arg0) throws SQLException {
1053 // TODO Auto-generated method stub
1054 return false;
1055 }
1056
1057 public ResultSet getGeneratedKeys() throws SQLException {
1058 // TODO Auto-generated method stub
1059 return null;
1060 }
1061
1062 public int executeUpdate(String arg0, int arg1) throws SQLException {
1063 // TODO Auto-generated method stub
1064 return 0;
1065 }
1066
1067 public int executeUpdate(String arg0, int[] arg1) throws SQLException {
1068 // TODO Auto-generated method stub
1069 return 0;
1070 }
1071
1072 pjaol 1.1 public int executeUpdate(String arg0, String[] arg1) throws SQLException {
1073 // TODO Auto-generated method stub
1074 return 0;
1075 }
1076
1077 public boolean execute(String arg0, int arg1) throws SQLException {
1078 // TODO Auto-generated method stub
1079 return false;
1080 }
1081
1082 public boolean execute(String arg0, int[] arg1) throws SQLException {
1083 // TODO Auto-generated method stub
1084 return false;
1085 }
1086
1087 public boolean execute(String arg0, String[] arg1) throws SQLException {
1088 // TODO Auto-generated method stub
1089 return false;
1090 }
1091
1092 public int getResultSetHoldability() throws SQLException {
1093 pjaol 1.1 // TODO Auto-generated method stub
1094 return 0;
1095 }
1096 }
|