0001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
0002: package jodd.db;
0003:
0004: import java.sql.Connection;
0005: import java.sql.PreparedStatement;
0006: import java.sql.SQLException;
0007: import java.sql.ParameterMetaData;
0008: import java.sql.ResultSet;
0009: import java.util.ArrayList;
0010: import java.util.Date;
0011: import java.util.StringTokenizer;
0012: import java.net.URL;
0013: import java.io.InputStream;
0014:
0015: /**
0016: * A <code>LoggablePreparedStatement</code> is a {@link PreparedStatement} with added logging capability.
0017: * <p>
0018: * In addition to the methods declared in <code>PreparedStatement</code>,
0019: * <code>LoggablePreparedStatement</code> provides a method {@link #getQueryString} which can be used to get
0020: * the query string in a format suitable for logging.
0021: */
0022: public class LoggablePreparedStatement implements PreparedStatement {
0023:
0024: /**
0025: * Used for storing parameter values needed for producing log.
0026: */
0027: private ArrayList<String> parameterValues;
0028:
0029: /**
0030: * The query string with question marks as parameter placeholders.
0031: */
0032: private String sqlTemplate;
0033:
0034: /**
0035: * A statement created from a real database connection.
0036: */
0037: private PreparedStatement wrappedStatement;
0038:
0039: /**
0040: * Constructs a LoggablePreparedStatement.
0041: *
0042: * Creates {@link java.sql.PreparedStatement PreparedStatement} with the query string <code>sql</code> using
0043: * the specified <code>conn</code> by calling {@link java.sql.Connection#prepareStatement(String)}.
0044: * <p>
0045: * Whenever a call is made to this <code>LoggablePreparedStatement</code> it is forwarded to the prepared statment created from
0046: * <code>conn</code> after first saving relevant parameters for use in logging output.
0047: *
0048: * @param connection java.sql.Connection a JDBC-conn to be used for obtaining a "real statement"
0049: * @param sql java.lang.String thw sql to exectute
0050: * @exception SQLException if a <code>PreparedStatement</code> cannot be created using the supplied <code>conn</code> and <code>sql</code>
0051: */
0052: public LoggablePreparedStatement(Connection connection, String sql)
0053: throws SQLException {
0054: wrappedStatement = connection.prepareStatement(sql);
0055: sqlTemplate = sql;
0056: parameterValues = new ArrayList<String>();
0057: }
0058:
0059: public LoggablePreparedStatement(Connection connection, String sql,
0060: int resultType, int resultSetConcurrency)
0061: throws SQLException {
0062: wrappedStatement = connection.prepareStatement(sql, resultType,
0063: resultSetConcurrency);
0064: sqlTemplate = sql;
0065: parameterValues = new ArrayList<String>();
0066: }
0067:
0068: /**
0069: * JDBC 2.0
0070: *
0071: * Adds a set of parameters to the batch.
0072: *
0073: * @exception SQLException if a database access error occurs
0074: * @see java.sql.Statement#addBatch
0075: */
0076: public void addBatch() throws SQLException {
0077: wrappedStatement.addBatch();
0078: }
0079:
0080: /**
0081: * JDBC 2.0
0082: *
0083: * Adds a SQL command to the current batch of commmands for the statement.
0084: * This method is optional.
0085: *
0086: * @param sql typically this is a static SQL INSERT or UPDATE statement
0087: * @exception SQLException if a database access error occurs, or the
0088: * driver does not support batch statements
0089: */
0090: public void addBatch(String sql) throws SQLException {
0091: wrappedStatement.addBatch(sql);
0092: }
0093:
0094: /**
0095: * Cancels this <code>Statement</code> object if both the DBMS and
0096: * driver support aborting an SQL statement.
0097: * This method can be used by one thread to cancel a statement that
0098: * is being executed by another thread.
0099: *
0100: * @exception SQLException if a database access error occurs
0101: */
0102: public void cancel() throws SQLException {
0103: wrappedStatement.cancel();
0104: }
0105:
0106: /**
0107: * JDBC 2.0
0108: *
0109: * Makes the set of commands in the current batch empty.
0110: * This method is optional.
0111: *
0112: * @exception SQLException if a database access error occurs or the
0113: * driver does not support batch statements
0114: */
0115: public void clearBatch() throws SQLException {
0116: wrappedStatement.clearBatch();
0117: }
0118:
0119: /**
0120: * Clears the current parameter values immediately.
0121: * <P>In general, parameter values remain in force for repeated use of a
0122: * Statement. Setting a parameter value automatically clears its
0123: * previous value. However, in some cases it is useful to immediately
0124: * release the resources used by the current parameter values; this can
0125: * be done by calling clearParameters.
0126: *
0127: * @exception SQLException if a database access error occurs
0128: */
0129: public void clearParameters() throws SQLException {
0130: wrappedStatement.clearParameters();
0131: }
0132:
0133: /**
0134: * Clears all the warnings reported on this <code>Statement</code>
0135: * object. After a call to this method,
0136: * the method <code>getWarnings</code> will return
0137: * null until a new warning is reported for this Statement.
0138: *
0139: * @exception SQLException if a database access error occurs
0140: */
0141: public void clearWarnings() throws SQLException {
0142: wrappedStatement.clearWarnings();
0143: }
0144:
0145: /**
0146: * Releases this <code>Statement</code> object's database
0147: * and JDBC resources immediately instead of waiting for
0148: * this to happen when it is automatically closed.
0149: * It is generally good practice to release resources as soon as
0150: * you are finished with them to avoid tying up database
0151: * resources.
0152: * <P><B>Note:</B> A Statement is automatically closed when it is
0153: * garbage collected. When a Statement is closed, its current
0154: * ResultSet, if one exists, is also closed.
0155: *
0156: * @exception SQLException if a database access error occurs
0157: */
0158: public void close() throws SQLException {
0159: wrappedStatement.close();
0160: }
0161:
0162: /**
0163: * Executes any kind of SQL statement.
0164: * Some prepared statements return multiple results; the execute
0165: * method handles these complex statements as well as the simpler
0166: * form of statements handled by executeQuery and executeUpdate.
0167: *
0168: * @exception SQLException if a database access error occurs
0169: * @see java.sql.Statement#execute
0170: */
0171: public boolean execute() throws SQLException {
0172: return wrappedStatement.execute();
0173: }
0174:
0175: /**
0176: * Executes a SQL statement that may return multiple results.
0177: * Under some (uncommon) situations a single SQL statement may return
0178: * multiple result sets and/or update counts. Normally you can ignore
0179: * this unless you are (1) executing a stored procedure that you know may
0180: * return multiple results or (2) you are dynamically executing an
0181: * unknown SQL string. The methods <code>execute</code>,
0182: * <code>getMoreResults</code>, <code>getResultSet</code>,
0183: * and <code>getUpdateCount</code> let you navigate through multiple results.
0184: *
0185: * The <code>execute</code> method executes a SQL statement and indicates the
0186: * form of the first result. You can then use getResultSet or
0187: * getUpdateCount to retrieve the result, and getMoreResults to
0188: * move to any subsequent result(s).
0189: *
0190: * @param sql any SQL statement
0191: * @return true if the next result is a ResultSet; false if it is
0192: * an update count or there are no more results
0193: * @exception SQLException if a database access error occurs
0194: * @see #getResultSet
0195: * @see #getUpdateCount
0196: * @see #getMoreResults
0197: */
0198: public boolean execute(String sql) throws SQLException {
0199: return wrappedStatement.execute(sql);
0200: }
0201:
0202: /**
0203: * JDBC 2.0
0204: *
0205: * Submits a batch of commands to the database for execution.
0206: * This method is optional.
0207: *
0208: * @return an array of update counts containing one element for each
0209: * command in the batch. The array is ordered according
0210: * to the order in which commands were inserted into the batch.
0211: * @exception SQLException if a database access error occurs or the
0212: * driver does not support batch statements
0213: */
0214: public int[] executeBatch() throws SQLException {
0215: return wrappedStatement.executeBatch();
0216: }
0217:
0218: /**
0219: * Executes the SQL query in this <code>PreparedStatement</code> object
0220: * and returns the result set generated by the query.
0221: *
0222: * @return a ResultSet that contains the data produced by the
0223: * query; never null
0224: * @exception SQLException if a database access error occurs
0225: */
0226: public ResultSet executeQuery() throws SQLException {
0227: return wrappedStatement.executeQuery();
0228: }
0229:
0230: /**
0231: * Executes a SQL statement that returns a single ResultSet.
0232: *
0233: * @param sql typically this is a static SQL SELECT statement
0234: * @return a ResultSet that contains the data produced by the
0235: * query; never null
0236: * @exception SQLException if a database access error occurs
0237: */
0238: public ResultSet executeQuery(String sql) throws SQLException {
0239: return wrappedStatement.executeQuery(sql);
0240: }
0241:
0242: /**
0243: * Executes the SQL INSERT, UPDATE or DELETE statement
0244: * in this <code>PreparedStatement</code> object.
0245: * In addition,
0246: * SQL statements that return nothing, such as SQL DDL statements,
0247: * can be executed.
0248: *
0249: * @return either the row count for INSERT, UPDATE or DELETE statements;
0250: * or 0 for SQL statements that return nothing
0251: * @exception SQLException if a database access error occurs
0252: */
0253: public int executeUpdate() throws SQLException {
0254: return wrappedStatement.executeUpdate();
0255: }
0256:
0257: /**
0258: * Executes an SQL INSERT, UPDATE or DELETE statement. In addition,
0259: * SQL statements that return nothing, such as SQL DDL statements,
0260: * can be executed.
0261: *
0262: * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
0263: * statement that returns nothing
0264: * @return either the row count for INSERT, UPDATE or DELETE or 0
0265: * for SQL statements that return nothing
0266: * @exception SQLException if a database access error occurs
0267: */
0268: public int executeUpdate(String sql) throws SQLException {
0269: return wrappedStatement.executeUpdate(sql);
0270: }
0271:
0272: /**
0273: * JDBC 2.0
0274: *
0275: * Returns the <code>Connection</code> object
0276: * that produced this <code>Statement</code> object.
0277: * @return the conn that produced this statement
0278: * @exception SQLException if a database access error occurs
0279: */
0280: public java.sql.Connection getConnection() throws SQLException {
0281: return wrappedStatement.getConnection();
0282: }
0283:
0284: /**
0285: * JDBC 2.0
0286: *
0287: * Retrieves the direction for fetching rows from
0288: * database tables that is the default for result sets
0289: * generated from this <code>Statement</code> object.
0290: * If this <code>Statement</code> object has not set
0291: * a fetch direction by calling the method <code>setFetchDirection</code>,
0292: * the return value is implementation-specific.
0293: *
0294: * @return the default fetch direction for result sets generated
0295: * from this <code>Statement</code> object
0296: * @exception SQLException if a database access error occurs
0297: */
0298: public int getFetchDirection() throws SQLException {
0299: return wrappedStatement.getFetchDirection();
0300: }
0301:
0302: /**
0303: * JDBC 2.0
0304: *
0305: * Retrieves the number of result set rows that is the default
0306: * fetch size for result sets
0307: * generated from this <code>Statement</code> object.
0308: * If this <code>Statement</code> object has not set
0309: * a fetch size by calling the method <code>setFetchSize</code>,
0310: * the return value is implementation-specific.
0311: * @return the default fetch size for result sets generated
0312: * from this <code>Statement</code> object
0313: * @exception SQLException if a database access error occurs
0314: */
0315: public int getFetchSize() throws SQLException {
0316: return wrappedStatement.getFetchSize();
0317: }
0318:
0319: /**
0320: * Returns the maximum number of bytes allowed
0321: * for any column value.
0322: * This limit is the maximum number of bytes that can be
0323: * returned for any column value.
0324: * The limit applies only to BINARY,
0325: * VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR
0326: * columns. If the limit is exceeded, the excess data is silently
0327: * discarded.
0328: *
0329: * @return the current max column size limit; zero means unlimited
0330: * @exception SQLException if a database access error occurs
0331: */
0332: public int getMaxFieldSize() throws SQLException {
0333: return wrappedStatement.getMaxFieldSize();
0334: }
0335:
0336: /**
0337: * Retrieves the maximum number of rows that a
0338: * ResultSet can contain. If the limit is exceeded, the excess
0339: * rows are silently dropped.
0340: *
0341: * @return the current max row limit; zero means unlimited
0342: * @exception SQLException if a database access error occurs
0343: */
0344: public int getMaxRows() throws SQLException {
0345: return wrappedStatement.getMaxRows();
0346: }
0347:
0348: /**
0349: * JDBC 2.0
0350: *
0351: * Gets the number, types and properties of a ResultSet's columns.
0352: *
0353: * @return the description of a ResultSet's columns
0354: * @exception SQLException if a database access error occurs
0355: */
0356: public java.sql.ResultSetMetaData getMetaData() throws SQLException {
0357: return wrappedStatement.getMetaData();
0358: }
0359:
0360: /**
0361: * Moves to a Statement's next result. It returns true if
0362: * this result is a ResultSet. This method also implicitly
0363: * closes any current ResultSet obtained with getResultSet.
0364: *
0365: * There are no more results when (!getMoreResults() &&
0366: * (getUpdateCount() == -1)
0367: *
0368: * @return true if the next result is a ResultSet; false if it is
0369: * an update count or there are no more results
0370: * @exception SQLException if a database access error occurs
0371: * @see #execute
0372: */
0373: public boolean getMoreResults() throws SQLException {
0374: return wrappedStatement.getMoreResults();
0375: }
0376:
0377: /**
0378: * Retrieves the number of seconds the driver will
0379: * wait for a Statement to execute. If the limit is exceeded, a
0380: * SQLException is thrown.
0381: *
0382: * @return the current query timeout limit in seconds; zero means unlimited
0383: * @exception SQLException if a database access error occurs
0384: */
0385: public int getQueryTimeout() throws SQLException {
0386: return wrappedStatement.getQueryTimeout();
0387: }
0388:
0389: /**
0390: * Returns the current result as a <code>ResultSet</code> object.
0391: * This method should be called only once per result.
0392: *
0393: * @return the current result as a ResultSet; null if the result
0394: * is an update count or there are no more results
0395: * @exception SQLException if a database access error occurs
0396: * @see #execute
0397: */
0398: public ResultSet getResultSet() throws SQLException {
0399: return wrappedStatement.getResultSet();
0400: }
0401:
0402: /**
0403: * JDBC 2.0
0404: *
0405: * Retrieves the result set concurrency.
0406: */
0407: public int getResultSetConcurrency() throws SQLException {
0408: return wrappedStatement.getResultSetConcurrency();
0409: }
0410:
0411: /**
0412: * JDBC 2.0
0413: *
0414: * Determine the result set type.
0415: */
0416: public int getResultSetType() throws SQLException {
0417: return wrappedStatement.getResultSetType();
0418: }
0419:
0420: /**
0421: * Returns the current result as an update count;
0422: * if the result is a ResultSet or there are no more results, -1
0423: * is returned.
0424: * This method should be called only once per result.
0425: *
0426: * @return the current result as an update count; -1 if it is a
0427: * ResultSet or there are no more results
0428: * @exception SQLException if a database access error occurs
0429: * @see #execute
0430: */
0431: public int getUpdateCount() throws SQLException {
0432: return wrappedStatement.getUpdateCount();
0433: }
0434:
0435: /**
0436: * Retrieves the first warning reported by calls on this Statement.
0437: * Subsequent Statement warnings will be chained to this
0438: * SQLWarning.
0439: *
0440: * <p>The warning chain is automatically cleared each time
0441: * a statement is (re)executed.
0442: *
0443: * <P><B>Note:</B> If you are processing a ResultSet, any
0444: * warnings associated with ResultSet reads will be chained on the
0445: * ResultSet object.
0446: *
0447: * @return the first SQLWarning or null
0448: * @exception SQLException if a database access error occurs
0449: */
0450: public java.sql.SQLWarning getWarnings() throws SQLException {
0451: return wrappedStatement.getWarnings();
0452: }
0453:
0454: /**
0455: * JDBC 2.0
0456: *
0457: * Sets an Array parameter.
0458: *
0459: * @param i the first parameter is 1, the second is 2, ...
0460: * @param x an object representing an SQL array
0461: * @exception SQLException if a database access error occurs
0462: */
0463: public void setArray(int i, java.sql.Array x) throws SQLException {
0464: wrappedStatement.setArray(i, x);
0465: saveQueryParamValue(i, x);
0466:
0467: }
0468:
0469: /**
0470: * Sets the designated parameter to the given input stream, which will have
0471: * the specified number of bytes.
0472: * When a very large ASCII value is input to a LONGVARCHAR
0473: * parameter, it may be more practical to send it via a
0474: * InputStream. JDBC will read the data from the stream
0475: * as needed, until it reaches end-of-file. The JDBC driver will
0476: * do any necessary conversion from ASCII to the database char format.
0477: *
0478: * <P><B>Note:</B> This stream object can either be a standard
0479: * Java stream object or your own subclass that implements the
0480: * standard interface.
0481: *
0482: * @param parameterIndex the first parameter is 1, the second is 2, ...
0483: * @param x the Java input stream that contains the ASCII parameter value
0484: * @param length the number of bytes in the stream
0485: * @exception SQLException if a database access error occurs
0486: */
0487: public void setAsciiStream(int parameterIndex, InputStream x,
0488: int length) throws SQLException {
0489: wrappedStatement.setAsciiStream(parameterIndex, x, length);
0490: saveQueryParamValue(parameterIndex, x);
0491: }
0492:
0493: /**
0494: * Sets the designated parameter to a java.lang.BigDecimal value.
0495: * The driver converts this to an SQL NUMERIC value when
0496: * it sends it to the database.
0497: *
0498: * @param parameterIndex the first parameter is 1, the second is 2, ...
0499: * @param x the parameter value
0500: * @exception SQLException if a database access error occurs
0501: */
0502: public void setBigDecimal(int parameterIndex, java.math.BigDecimal x)
0503: throws SQLException {
0504: wrappedStatement.setBigDecimal(parameterIndex, x);
0505: saveQueryParamValue(parameterIndex, x);
0506:
0507: }
0508:
0509: /**
0510: * Sets the designated parameter to the given input stream, which will have
0511: * the specified number of bytes.
0512: * When a very large binary value is input to a LONGVARBINARY
0513: * parameter, it may be more practical to send it via a
0514: * InputStream. JDBC will read the data from the stream
0515: * as needed, until it reaches end-of-file.
0516: *
0517: * <P><B>Note:</B> This stream object can either be a standard
0518: * Java stream object or your own subclass that implements the
0519: * standard interface.
0520: *
0521: * @param parameterIndex the first parameter is 1, the second is 2, ...
0522: * @param x the java input stream which contains the binary parameter value
0523: * @param length the number of bytes in the stream
0524: * @exception SQLException if a database access error occurs
0525: */
0526: public void setBinaryStream(int parameterIndex, InputStream x,
0527: int length) throws SQLException {
0528: wrappedStatement.setBinaryStream(parameterIndex, x, length);
0529: saveQueryParamValue(parameterIndex, x);
0530:
0531: }
0532:
0533: /**
0534: * JDBC 2.0
0535: *
0536: * Sets a BLOB parameter.
0537: *
0538: * @param i the first parameter is 1, the second is 2, ...
0539: * @param x an object representing a BLOB
0540: * @exception SQLException if a database access error occurs
0541: */
0542: public void setBlob(int i, java.sql.Blob x) throws SQLException {
0543: wrappedStatement.setBlob(i, x);
0544: saveQueryParamValue(i, x);
0545: }
0546:
0547: /**
0548: * Sets the designated parameter to a Java boolean value. The driver converts this
0549: * to an SQL BIT value when it sends it to the database.
0550: *
0551: * @param parameterIndex the first parameter is 1, the second is 2, ...
0552: * @param x the parameter value
0553: * @exception SQLException if a database access error occurs
0554: */
0555: public void setBoolean(int parameterIndex, boolean x)
0556: throws SQLException {
0557: wrappedStatement.setBoolean(parameterIndex, x);
0558: saveQueryParamValue(parameterIndex, Boolean.valueOf(x));
0559:
0560: }
0561:
0562: /**
0563: * Sets the designated parameter to a Java byte value. The driver converts this
0564: * to an SQL TINYINT value when it sends it to the database.
0565: *
0566: * @param parameterIndex the first parameter is 1, the second is 2, ...
0567: * @param x the parameter value
0568: * @exception SQLException if a database access error occurs
0569: */
0570: public void setByte(int parameterIndex, byte x) throws SQLException {
0571: wrappedStatement.setByte(parameterIndex, x);
0572: saveQueryParamValue(parameterIndex, new Integer(x));
0573: }
0574:
0575: /**
0576: * Sets the designated parameter to a Java array of bytes. The driver converts
0577: * this to an SQL VARBINARY or LONGVARBINARY (depending on the
0578: * argument's size relative to the driver's limits on VARBINARYs)
0579: * when it sends it to the database.
0580: *
0581: * @param parameterIndex the first parameter is 1, the second is 2, ...
0582: * @param x the parameter value
0583: * @exception SQLException if a database access error occurs
0584: */
0585: public void setBytes(int parameterIndex, byte[] x)
0586: throws SQLException {
0587: wrappedStatement.setBytes(parameterIndex, x);
0588: saveQueryParamValue(parameterIndex, x);
0589: }
0590:
0591: /**
0592: * JDBC 2.0
0593: *
0594: * Sets the designated parameter to the given <code>Reader</code>
0595: * object, which is the given number of characters long.
0596: * When a very large UNICODE value is input to a LONGVARCHAR
0597: * parameter, it may be more practical to send it via a
0598: * java.io.Reader. JDBC will read the data from the stream
0599: * as needed, until it reaches end-of-file. The JDBC driver will
0600: * do any necessary conversion from UNICODE to the database char format.
0601: *
0602: * <P><B>Note:</B> This stream object can either be a standard
0603: * Java stream object or your own subclass that implements the
0604: * standard interface.
0605: *
0606: * @param parameterIndex the first parameter is 1, the second is 2, ...
0607: * @param reader the java reader which contains the UNICODE data
0608: * @param length the number of characters in the stream
0609: * @exception SQLException if a database access error occurs
0610: */
0611: public void setCharacterStream(int parameterIndex,
0612: java.io.Reader reader, int length) throws SQLException {
0613: wrappedStatement.setCharacterStream(parameterIndex, reader,
0614: length);
0615: saveQueryParamValue(parameterIndex, reader);
0616:
0617: }
0618:
0619: /**
0620: * JDBC 2.0
0621: *
0622: * Sets a CLOB parameter.
0623: *
0624: * @param i the first parameter is 1, the second is 2, ...
0625: * @param x an object representing a CLOB
0626: * @exception SQLException if a database access error occurs
0627: */
0628: public void setClob(int i, java.sql.Clob x) throws SQLException {
0629: wrappedStatement.setClob(i, x);
0630: saveQueryParamValue(i, x);
0631:
0632: }
0633:
0634: /**
0635: * Defines the SQL cursor name that will be used by
0636: * subsequent Statement <code>execute</code> methods. This name can then be
0637: * used in SQL positioned update/delete statements to identify the
0638: * current row in the ResultSet generated by this statement. If
0639: * the database doesn't support positioned update/delete, this
0640: * method is a noop. To insure that a cursor has the proper isolation
0641: * level to support updates, the cursor's SELECT statement should be
0642: * of the form 'select for update ...'. If the 'for update' phrase is
0643: * omitted, positioned updates may fail.
0644: *
0645: * <P><B>Note:</B> By definition, positioned update/delete
0646: * execution must be done by a different Statement than the one
0647: * which generated the ResultSet being used for positioning. Also,
0648: * cursor names must be unique within a conn.
0649: *
0650: * @param name the new cursor name, which must be unique within
0651: * a conn
0652: * @exception SQLException if a database access error occurs
0653: */
0654: public void setCursorName(String name) throws SQLException {
0655: wrappedStatement.setCursorName(name);
0656:
0657: }
0658:
0659: /**
0660: * Sets the designated parameter to a java.sql.Date value. The driver converts this
0661: * to an SQL DATE value when it sends it to the database.
0662: *
0663: * @param parameterIndex the first parameter is 1, the second is 2, ...
0664: * @param x the parameter value
0665: * @exception SQLException if a database access error occurs
0666: */
0667: public void setDate(int parameterIndex, java.sql.Date x)
0668: throws SQLException {
0669: wrappedStatement.setDate(parameterIndex, x);
0670: saveQueryParamValue(parameterIndex, x);
0671: }
0672:
0673: /**
0674: * JDBC 2.0
0675: *
0676: * Sets the designated parameter to a java.sql.Date value,
0677: * using the given <code>Calendar</code> object. The driver uses
0678: * the <code>Calendar</code> object to construct an SQL DATE,
0679: * which the driver then sends to the database. With a
0680: * a <code>Calendar</code> object, the driver can calculate the date
0681: * taking into account a custom timezone and locale. If no
0682: * <code>Calendar</code> object is specified, the driver uses the default
0683: * timezone and locale.
0684: *
0685: * @param parameterIndex the first parameter is 1, the second is 2, ...
0686: * @param x the parameter value
0687: * @param cal the <code>Calendar</code> object the driver will use
0688: * to construct the date
0689: * @exception SQLException if a database access error occurs
0690: */
0691: public void setDate(int parameterIndex, java.sql.Date x,
0692: java.util.Calendar cal) throws SQLException {
0693: wrappedStatement.setDate(parameterIndex, x, cal);
0694: saveQueryParamValue(parameterIndex, x);
0695: }
0696:
0697: /**
0698: * Sets the designated parameter to a Java double value. The driver converts this
0699: * to an SQL DOUBLE value when it sends it to the database.
0700: *
0701: * @param parameterIndex the first parameter is 1, the second is 2, ...
0702: * @param x the parameter value
0703: * @exception SQLException if a database access error occurs
0704: */
0705: public void setDouble(int parameterIndex, double x)
0706: throws SQLException {
0707: wrappedStatement.setDouble(parameterIndex, x);
0708: saveQueryParamValue(parameterIndex, new Double(x));
0709: }
0710:
0711: /**
0712: * Sets escape processing on or off.
0713: * If escape scanning is on (the default), the driver will do
0714: * escape substitution before sending the SQL to the database.
0715: *
0716: * Note: Since prepared statements have usually been parsed prior
0717: * to making this call, disabling escape processing for prepared
0718: * statements will have no effect.
0719: *
0720: * @param enable true to enable; false to disable
0721: * @exception SQLException if a database access error occurs
0722: */
0723: public void setEscapeProcessing(boolean enable) throws SQLException {
0724: wrappedStatement.setEscapeProcessing(enable);
0725:
0726: }
0727:
0728: /**
0729: * JDBC 2.0
0730: *
0731: * Gives the driver a hint as to the direction in which
0732: * the rows in a result set
0733: * will be processed. The hint applies only to result sets created
0734: * using this Statement object. The default value is
0735: * ResultSet.FETCH_FORWARD.
0736: * <p>Note that this method sets the default fetch direction for
0737: * result sets generated by this <code>Statement</code> object.
0738: * Each result set has its own methods for getting and setting
0739: * its own fetch direction.
0740: * @param direction the initial direction for processing rows
0741: * @exception SQLException if a database access error occurs
0742: * or the given direction
0743: * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
0744: * ResultSet.FETCH_UNKNOWN
0745: */
0746: public void setFetchDirection(int direction) throws SQLException {
0747: wrappedStatement.setFetchDirection(direction);
0748: }
0749:
0750: /**
0751: * JDBC 2.0
0752: *
0753: * Gives the JDBC driver a hint as to the number of rows that should
0754: * be fetched from the database when more rows are needed. The number
0755: * of rows specified affects only result sets created using this
0756: * statement. If the value specified is zero, then the hint is ignored.
0757: * The default value is zero.
0758: *
0759: * @param rows the number of rows to fetch
0760: * @exception SQLException if a database access error occurs, or the
0761: * condition 0 <= rows <= this.getMaxRows() is not satisfied.
0762: */
0763: public void setFetchSize(int rows) throws SQLException {
0764: wrappedStatement.setFetchSize(rows);
0765: }
0766:
0767: /**
0768: * Sets the designated parameter to a Java float value. The driver converts this
0769: * to an SQL FLOAT value when it sends it to the database.
0770: *
0771: * @param parameterIndex the first parameter is 1, the second is 2, ...
0772: * @param x the parameter value
0773: * @exception SQLException if a database access error occurs
0774: */
0775: public void setFloat(int parameterIndex, float x)
0776: throws SQLException {
0777: wrappedStatement.setFloat(parameterIndex, x);
0778: saveQueryParamValue(parameterIndex, new Float(x));
0779:
0780: }
0781:
0782: /**
0783: * Sets the designated parameter to a Java int value. The driver converts this
0784: * to an SQL INTEGER value when it sends it to the database.
0785: *
0786: * @param parameterIndex the first parameter is 1, the second is 2, ...
0787: * @param x the parameter value
0788: * @exception SQLException if a database access error occurs
0789: */
0790: public void setInt(int parameterIndex, int x) throws SQLException {
0791: wrappedStatement.setInt(parameterIndex, x);
0792: saveQueryParamValue(parameterIndex, new Integer(x));
0793: }
0794:
0795: /**
0796: * Sets the designated parameter to a Java long value. The driver converts this
0797: * to an SQL BIGINT value when it sends it to the database.
0798: *
0799: * @param parameterIndex the first parameter is 1, the second is 2, ...
0800: * @param x the parameter value
0801: * @exception SQLException if a database access error occurs
0802: */
0803: public void setLong(int parameterIndex, long x) throws SQLException {
0804: wrappedStatement.setLong(parameterIndex, x);
0805: saveQueryParamValue(parameterIndex, new Long(x));
0806:
0807: }
0808:
0809: /**
0810: * Sets the limit for the maximum number of bytes in a column to
0811: * the given number of bytes. This is the maximum number of bytes
0812: * that can be returned for any column value. This limit applies
0813: * only to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and
0814: * LONGVARCHAR fields. If the limit is exceeded, the excess data
0815: * is silently discarded. For maximum portability, use values
0816: * greater than 256.
0817: *
0818: * @param max the new max column size limit; zero means unlimited
0819: * @exception SQLException if a database access error occurs
0820: */
0821: public void setMaxFieldSize(int max) throws SQLException {
0822: wrappedStatement.setMaxFieldSize(max);
0823:
0824: }
0825:
0826: /**
0827: * Sets the limit for the maximum number of rows that any
0828: * ResultSet can contain to the given number.
0829: * If the limit is exceeded, the excess
0830: * rows are silently dropped.
0831: *
0832: * @param max the new max rows limit; zero means unlimited
0833: * @exception SQLException if a database access error occurs
0834: */
0835: public void setMaxRows(int max) throws SQLException {
0836: wrappedStatement.setMaxRows(max);
0837: }
0838:
0839: /**
0840: * Sets the designated parameter to SQL NULL.
0841: *
0842: * <P><B>Note:</B> You must specify the parameter's SQL type.
0843: *
0844: * @param parameterIndex the first parameter is 1, the second is 2, ...
0845: * @param sqlType the SQL type code defined in java.sql.Types
0846: * @exception SQLException if a database access error occurs
0847: */
0848: public void setNull(int parameterIndex, int sqlType)
0849: throws SQLException {
0850: wrappedStatement.setNull(parameterIndex, sqlType);
0851: saveQueryParamValue(parameterIndex, null);
0852: }
0853:
0854: /**
0855: * JDBC 2.0
0856: *
0857: * Sets the designated parameter to SQL NULL. This version of setNull should
0858: * be used for user-named types and REF type parameters. Examples
0859: * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
0860: * named array types.
0861: *
0862: * <P><B>Note:</B> To be portable, applications must give the
0863: * SQL type code and the fully-qualified SQL type name when specifying
0864: * a NULL user-defined or REF parameter. In the case of a user-named type
0865: * the name is the type name of the parameter itself. For a REF
0866: * parameter the name is the type name of the referenced type. If
0867: * a JDBC driver does not need the type code or type name information,
0868: * it may ignore it.
0869: *
0870: * Although it is intended for user-named and Ref parameters,
0871: * this method may be used to set a null parameter of any JDBC type.
0872: * If the parameter does not have a user-named or REF type, the given
0873: * typeName is ignored.
0874: *
0875: *
0876: * @param parameterIndex the first parameter is 1, the second is 2, ...
0877: * @param sqlType a value from java.sql.Types
0878: * @param typeName the fully-qualified name of an SQL user-named type,
0879: * ignored if the parameter is not a user-named type or REF
0880: * @exception SQLException if a database access error occurs
0881: */
0882: public void setNull(int parameterIndex, int sqlType, String typeName)
0883: throws SQLException {
0884: wrappedStatement.setNull(parameterIndex, sqlType, typeName);
0885: saveQueryParamValue(parameterIndex, null);
0886:
0887: }
0888:
0889: /**
0890: * <p>Sets the value of a parameter using an object; use the
0891: * java.lang equivalent objects for integral values.
0892: *
0893: * <p>The JDBC specification specifies a standard mapping from
0894: * Java Object types to SQL types. The given argument java object
0895: * will be converted to the corresponding SQL type before being
0896: * sent to the database.
0897: *
0898: * <p>Note that this method may be used to pass datatabase-
0899: * specific abstract data types, by using a Driver-specific Java
0900: * type.
0901: *
0902: * If the object is of a class implementing SQLData,
0903: * the JDBC driver should call its method <code>writeSQL</code> to write it
0904: * to the SQL data stream.
0905: * If, on the other hand, the object is of a class implementing
0906: * Ref, Blob, Clob, Struct,
0907: * or Array, then the driver should pass it to the database as a value of the
0908: * corresponding SQL type.
0909: *
0910: * This method throws an exception if there is an ambiguity, for example, if the
0911: * object is of a class implementing more than one of those interfaces.
0912: *
0913: * @param parameterIndex the first parameter is 1, the second is 2, ...
0914: * @param x the object containing the input parameter value
0915: * @exception SQLException if a database access error occurs
0916: */
0917: public void setObject(int parameterIndex, Object x)
0918: throws SQLException {
0919: wrappedStatement.setObject(parameterIndex, x);
0920: saveQueryParamValue(parameterIndex, x);
0921: }
0922:
0923: /**
0924: * Sets the value of the designated parameter with the given object.
0925: * This method is like setObject above, except that it assumes a scale of zero.
0926: *
0927: * @param parameterIndex the first parameter is 1, the second is 2, ...
0928: * @param x the object containing the input parameter value
0929: * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
0930: * sent to the database
0931: * @exception SQLException if a database access error occurs
0932: */
0933: public void setObject(int parameterIndex, Object x,
0934: int targetSqlType) throws SQLException {
0935: wrappedStatement.setObject(parameterIndex, x, targetSqlType);
0936: saveQueryParamValue(parameterIndex, x);
0937: }
0938:
0939: /**
0940: * <p>Sets the value of a parameter using an object. The second
0941: * argument must be an object type; for integral values, the
0942: * java.lang equivalent objects should be used.
0943: *
0944: * <p>The given Java object will be converted to the targetSqlType
0945: * before being sent to the database.
0946: *
0947: * If the object has a custom mapping (is of a class implementing SQLData),
0948: * the JDBC driver should call its method <code>writeSQL</code> to write it
0949: * to the SQL data stream.
0950: * If, on the other hand, the object is of a class implementing
0951: * Ref, Blob, Clob, Struct,
0952: * or Array, the driver should pass it to the database as a value of the
0953: * corresponding SQL type.
0954: *
0955: * <p>Note that this method may be used to pass datatabase-
0956: * specific abstract data types.
0957: *
0958: * @param parameterIndex the first parameter is 1, the second is 2, ...
0959: * @param x the object containing the input parameter value
0960: * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
0961: * sent to the database. The scale argument may further qualify this type.
0962: * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
0963: * this is the number of digits after the decimal point. For all other
0964: * types, this value will be ignored.
0965: * @exception SQLException if a database access error occurs
0966: * @see java.sql.Types
0967: */
0968: public void setObject(int parameterIndex, Object x,
0969: int targetSqlType, int scale) throws SQLException {
0970: wrappedStatement.setObject(parameterIndex, x, targetSqlType,
0971: scale);
0972: saveQueryParamValue(parameterIndex, x);
0973: }
0974:
0975: /**
0976: * Sets the number of seconds the driver will
0977: * wait for a Statement to execute to the given number of seconds.
0978: * If the limit is exceeded, a SQLException is thrown.
0979: *
0980: * @param seconds the new query timeout limit in seconds; zero means
0981: * unlimited
0982: * @exception SQLException if a database access error occurs
0983: */
0984: public void setQueryTimeout(int seconds) throws SQLException {
0985: wrappedStatement.setQueryTimeout(seconds);
0986: }
0987:
0988: /**
0989: * JDBC 2.0
0990: *
0991: * Sets a REF(<structured-type>) parameter.
0992: *
0993: * @param i the first parameter is 1, the second is 2, ...
0994: * @param x an object representing data of an SQL REF Type
0995: * @exception SQLException if a database access error occurs
0996: */
0997: public void setRef(int i, java.sql.Ref x) throws SQLException {
0998: wrappedStatement.setRef(i, x);
0999: saveQueryParamValue(i, x);
1000:
1001: }
1002:
1003: /**
1004: * Sets the designated parameter to a Java short value. The driver converts this
1005: * to an SQL SMALLINT value when it sends it to the database.
1006: *
1007: * @param parameterIndex the first parameter is 1, the second is 2, ...
1008: * @param x the parameter value
1009: * @exception SQLException if a database access error occurs
1010: */
1011: public void setShort(int parameterIndex, short x)
1012: throws SQLException {
1013: wrappedStatement.setShort(parameterIndex, x);
1014: saveQueryParamValue(parameterIndex, new Integer(x));
1015: }
1016:
1017: /**
1018: * Sets the designated parameter to a Java String value. The driver converts this
1019: * to an SQL VARCHAR or LONGVARCHAR value (depending on the argument's
1020: * size relative to the driver's limits on VARCHARs) when it sends
1021: * it to the database.
1022: *
1023: * @param parameterIndex the first parameter is 1, the second is 2, ...
1024: * @param x the parameter value
1025: * @exception SQLException if a database access error occurs
1026: */
1027: public void setString(int parameterIndex, String x)
1028: throws SQLException {
1029:
1030: wrappedStatement.setString(parameterIndex, x);
1031: saveQueryParamValue(parameterIndex, x);
1032: }
1033:
1034: /**
1035: * Sets the designated parameter to a java.sql.Time value. The driver converts this
1036: * to an SQL TIME value when it sends it to the database.
1037: *
1038: * @param parameterIndex the first parameter is 1, the second is 2, ...
1039: * @param x the parameter value
1040: * @exception SQLException if a database access error occurs
1041: */
1042: public void setTime(int parameterIndex, java.sql.Time x)
1043: throws SQLException {
1044: wrappedStatement.setTime(parameterIndex, x);
1045: saveQueryParamValue(parameterIndex, x);
1046: }
1047:
1048: /**
1049: * JDBC 2.0
1050: *
1051: * Sets the designated parameter to a java.sql.Time value,
1052: * using the given <code>Calendar</code> object. The driver uses
1053: * the <code>Calendar</code> object to construct an SQL TIME,
1054: * which the driver then sends to the database. With a
1055: * a <code>Calendar</code> object, the driver can calculate the time
1056: * taking into account a custom timezone and locale. If no
1057: * <code>Calendar</code> object is specified, the driver uses the default
1058: * timezone and locale.
1059: *
1060: * @param parameterIndex the first parameter is 1, the second is 2, ...
1061: * @param x the parameter value
1062: * @param cal the <code>Calendar</code> object the driver will use
1063: * to construct the time
1064: * @exception SQLException if a database access error occurs
1065: */
1066: public void setTime(int parameterIndex, java.sql.Time x,
1067: java.util.Calendar cal) throws SQLException {
1068: wrappedStatement.setTime(parameterIndex, x, cal);
1069: saveQueryParamValue(parameterIndex, x);
1070:
1071: }
1072:
1073: /**
1074: * Sets the designated parameter to a java.sql.Timestamp value. The driver
1075: * converts this to an SQL TIMESTAMP value when it sends it to the
1076: * database.
1077: *
1078: * @param parameterIndex the first parameter is 1, the second is 2, ...
1079: * @param x the parameter value
1080: * @exception SQLException if a database access error occurs
1081: */
1082: public void setTimestamp(int parameterIndex, java.sql.Timestamp x)
1083: throws SQLException {
1084: wrappedStatement.setTimestamp(parameterIndex, x);
1085: saveQueryParamValue(parameterIndex, x);
1086: }
1087:
1088: /**
1089: * JDBC 2.0
1090: *
1091: * Sets the designated parameter to a java.sql.Timestamp value,
1092: * using the given <code>Calendar</code> object. The driver uses
1093: * the <code>Calendar</code> object to construct an SQL TIMESTAMP,
1094: * which the driver then sends to the database. With a
1095: * a <code>Calendar</code> object, the driver can calculate the timestamp
1096: * taking into account a custom timezone and locale. If no
1097: * <code>Calendar</code> object is specified, the driver uses the default
1098: * timezone and locale.
1099: *
1100: * @param parameterIndex the first parameter is 1, the second is 2, ...
1101: * @param x the parameter value
1102: * @param cal the <code>Calendar</code> object the driver will use
1103: * to construct the timestamp
1104: * @exception SQLException if a database access error occurs
1105: */
1106: public void setTimestamp(int parameterIndex, java.sql.Timestamp x,
1107: java.util.Calendar cal) throws SQLException {
1108: wrappedStatement.setTimestamp(parameterIndex, x, cal);
1109: saveQueryParamValue(parameterIndex, x);
1110: }
1111:
1112: /**
1113: * Sets the designated parameter to the given input stream, which will have
1114: * the specified number of bytes.
1115: * When a very large UNICODE value is input to a LONGVARCHAR
1116: * parameter, it may be more practical to send it via a
1117: * InputStream. JDBC will read the data from the stream
1118: * as needed, until it reaches end-of-file. The JDBC driver will
1119: * do any necessary conversion from UNICODE to the database char format.
1120: * The byte format of the Unicode stream must be Java UTF-8, as
1121: * defined in the Java Virtual Machine Specification.
1122: *
1123: * <P><B>Note:</B> This stream object can either be a standard
1124: * Java stream object or your own subclass that implements the
1125: * standard interface.
1126: *
1127: * @param parameterIndex the first parameter is 1, the second is 2, ...
1128: * @param x the java input stream which contains the
1129: * UNICODE parameter value
1130: * @param length the number of bytes in the stream
1131: * @exception SQLException if a database access error occurs
1132: * @deprecated
1133: */
1134: public void setUnicodeStream(int parameterIndex, InputStream x,
1135: int length) throws SQLException {
1136: //noinspection deprecation
1137: wrappedStatement.setUnicodeStream(parameterIndex, x, length);
1138: saveQueryParamValue(parameterIndex, x);
1139: }
1140:
1141: // ---------------------------------------------------------------- JDBC new
1142:
1143: /**
1144: * Sets the designated parameter to the given <code>java.net.URL</code> value.
1145: * The driver converts this to an SQL <code>DATALINK</code> value
1146: * when it sends it to the database.
1147: *
1148: * @param parameterIndex the first parameter is 1, the second is 2, ...
1149: * @param x the <code>java.net.URL</code> object to be set
1150: * @throws java.sql.SQLException if a database access error occurs
1151: * @since 1.4
1152: */
1153: public void setURL(int parameterIndex, URL x) throws SQLException {
1154: wrappedStatement.setURL(parameterIndex, x);
1155: saveQueryParamValue(parameterIndex, x);
1156: }
1157:
1158: /**
1159: * Retrieves the number, types and properties of this
1160: * <code>PreparedStatement</code> object's parameters.
1161: *
1162: * @return a <code>ParameterMetaData</code> object that contains information
1163: * about the number, types and properties of this
1164: * <code>PreparedStatement</code> object's parameters
1165: * @throws java.sql.SQLException if a database access error occurs
1166: * @see java.sql.ParameterMetaData
1167: * @since 1.4
1168: */
1169: public ParameterMetaData getParameterMetaData() throws SQLException {
1170: return wrappedStatement.getParameterMetaData();
1171: }
1172:
1173: /**
1174: * Retrieves the result set holdability for <code>ResultSet</code> objects
1175: * generated by this <code>Statement</code> object.
1176: *
1177: * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
1178: * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1179: * @throws java.sql.SQLException if a database access error occurs
1180: * @since 1.4
1181: */
1182: public int getResultSetHoldability() throws SQLException {
1183: return wrappedStatement.getResultSetHoldability();
1184: }
1185:
1186: /**
1187: * Moves to this <code>Statement</code> object's next result, deals with
1188: * any current <code>ResultSet</code> object(s) according to the instructions
1189: * specified by the given flag, and returns
1190: * <code>true</code> if the next result is a <code>ResultSet</code> object.
1191: * <p>
1192: * There are no more results when the following is true:
1193: * <PRE>
1194: * // stmt is a Statement object
1195: * ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
1196: * </PRE>
1197: *
1198: * @param current one of the following <code>Statement</code>
1199: * constants indicating what should happen to current
1200: * <code>ResultSet</code> objects obtained using the method
1201: * <code>getResultSet</code>:
1202: * <code>Statement.CLOSE_CURRENT_RESULT</code>,
1203: * <code>Statement.KEEP_CURRENT_RESULT</code>, or
1204: * <code>Statement.CLOSE_ALL_RESULTS</code>
1205: * @return <code>true</code> if the next result is a <code>ResultSet</code>
1206: * object; <code>false</code> if it is an update count or there are no
1207: * more results
1208: * @throws java.sql.SQLException if a database access error occurs or the argument
1209: * supplied is not one of the following:
1210: * <code>Statement.CLOSE_CURRENT_RESULT</code>,
1211: * <code>Statement.KEEP_CURRENT_RESULT</code>, or
1212: * <code>Statement.CLOSE_ALL_RESULTS</code>
1213: * @see #execute
1214: * @since 1.4
1215: */
1216: public boolean getMoreResults(int current) throws SQLException {
1217: return wrappedStatement.getMoreResults(current);
1218: }
1219:
1220: /**
1221: * Retrieves any auto-generated keys created as a result of executing this
1222: * <code>Statement</code> object. If this <code>Statement</code> object did
1223: * not generate any keys, an empty <code>ResultSet</code>
1224: * object is returned.
1225: *
1226: * @return a <code>ResultSet</code> object containing the auto-generated key(s)
1227: * generated by the execution of this <code>Statement</code> object
1228: * @throws java.sql.SQLException if a database access error occurs
1229: * @since 1.4
1230: */
1231: public ResultSet getGeneratedKeys() throws SQLException {
1232: return wrappedStatement.getGeneratedKeys();
1233: }
1234:
1235: /**
1236: * Executes the given SQL statement and signals the driver with the
1237: * given flag about whether the
1238: * auto-generated keys produced by this <code>Statement</code> object
1239: * should be made available for retrieval.
1240: *
1241: * @param sql must be an SQL <code>INSERT</code>, <code>UPDATE</code> or
1242: * <code>DELETE</code> statement or an SQL statement that
1243: * returns nothing
1244: * @param autoGeneratedKeys a flag indicating whether auto-generated keys
1245: * should be made available for retrieval;
1246: * one of the following constants:
1247: * <code>Statement.RETURN_GENERATED_KEYS</code>
1248: * <code>Statement.NO_GENERATED_KEYS</code>
1249: * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
1250: * or <code>DELETE</code> statements, or <code>0</code> for SQL
1251: * statements that return nothing
1252: * @throws java.sql.SQLException if a database access error occurs, the given
1253: * SQL statement returns a <code>ResultSet</code> object, or
1254: * the given constant is not one of those allowed
1255: * @since 1.4
1256: */
1257: public int executeUpdate(String sql, int autoGeneratedKeys)
1258: throws SQLException {
1259: return wrappedStatement.executeUpdate(sql, autoGeneratedKeys);
1260: }
1261:
1262: /**
1263: * Executes the given SQL statement, which may return multiple results,
1264: * and signals the driver that any
1265: * auto-generated keys should be made available
1266: * for retrieval. The driver will ignore this signal if the SQL statement
1267: * is not an <code>INSERT</code> statement.
1268: * <p>
1269: * In some (uncommon) situations, a single SQL statement may return
1270: * multiple result sets and/or update counts. Normally you can ignore
1271: * this unless you are (1) executing a stored procedure that you know may
1272: * return multiple results or (2) you are dynamically executing an
1273: * unknown SQL string.
1274: * <p>
1275: * The <code>execute</code> method executes an SQL statement and indicates the
1276: * form of the first result. You must then use the methods
1277: * <code>getResultSet</code> or <code>getUpdateCount</code>
1278: * to retrieve the result, and <code>getMoreResults</code> to
1279: * move to any subsequent result(s).
1280: *
1281: * @param sql any SQL statement
1282: * @param autoGeneratedKeys a constant indicating whether auto-generated
1283: * keys should be made available for retrieval using the method
1284: * <code>getGeneratedKeys</code>; one of the following constants:
1285: * <code>Statement.RETURN_GENERATED_KEYS</code> or
1286: * <code>Statement.NO_GENERATED_KEYS</code>
1287: * @return <code>true</code> if the first result is a <code>ResultSet</code>
1288: * object; <code>false</code> if it is an update count or there are
1289: * no results
1290: * @throws java.sql.SQLException if a database access error occurs or the second
1291: * parameter supplied to this method is not
1292: * <code>Statement.RETURN_GENERATED_KEYS</code> or
1293: * <code>Statement.NO_GENERATED_KEYS</code>.
1294: * @see #getResultSet
1295: * @see #getUpdateCount
1296: * @see #getMoreResults
1297: * @see #getGeneratedKeys
1298: * @since 1.4
1299: */
1300: public boolean execute(String sql, int autoGeneratedKeys)
1301: throws SQLException {
1302: return wrappedStatement.execute(sql, autoGeneratedKeys);
1303: }
1304:
1305: /**
1306: * Executes the given SQL statement and signals the driver that the
1307: * auto-generated keys indicated in the given array should be made available
1308: * for retrieval. The driver will ignore the array if the SQL statement
1309: * is not an <code>INSERT</code> statement.
1310: *
1311: * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
1312: * <code>DELETE</code> statement or an SQL statement that returns nothing,
1313: * such as an SQL DDL statement
1314: * @param columnIndexes an array of column indexes indicating the columns
1315: * that should be returned from the inserted row
1316: * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
1317: * or <code>DELETE</code> statements, or 0 for SQL statements
1318: * that return nothing
1319: * @throws java.sql.SQLException if a database access error occurs, the SQL
1320: * statement returns a <code>ResultSet</code> object, or the
1321: * second argument supplied to this method is not an <code>int</code> array
1322: * whose elements are valid column indexes
1323: * @since 1.4
1324: */
1325: public int executeUpdate(String sql, int columnIndexes[])
1326: throws SQLException {
1327: return wrappedStatement.executeUpdate(sql, columnIndexes);
1328: }
1329:
1330: /**
1331: * Executes the given SQL statement, which may return multiple results,
1332: * and signals the driver that the
1333: * auto-generated keys indicated in the given array should be made available
1334: * for retrieval. This array contains the indexes of the columns in the
1335: * target table that contain the auto-generated keys that should be made
1336: * available. The driver will ignore the array if the given SQL statement
1337: * is not an <code>INSERT</code> statement.
1338: * <p>
1339: * Under some (uncommon) situations, a single SQL statement may return
1340: * multiple result sets and/or update counts. Normally you can ignore
1341: * this unless you are (1) executing a stored procedure that you know may
1342: * return multiple results or (2) you are dynamically executing an
1343: * unknown SQL string.
1344: * <p>
1345: * The <code>execute</code> method executes an SQL statement and indicates the
1346: * form of the first result. You must then use the methods
1347: * <code>getResultSet</code> or <code>getUpdateCount</code>
1348: * to retrieve the result, and <code>getMoreResults</code> to
1349: * move to any subsequent result(s).
1350: *
1351: * @param sql any SQL statement
1352: * @param columnIndexes an array of the indexes of the columns in the
1353: * inserted row that should be made available for retrieval by a
1354: * call to the method <code>getGeneratedKeys</code>
1355: * @return <code>true</code> if the first result is a <code>ResultSet</code>
1356: * object; <code>false</code> if it is an update count or there
1357: * are no results
1358: * @throws java.sql.SQLException if a database access error occurs or the
1359: * elements in the <code>int</code> array passed to this method
1360: * are not valid column indexes
1361: * @see #getResultSet
1362: * @see #getUpdateCount
1363: * @see #getMoreResults
1364: * @since 1.4
1365: */
1366: public boolean execute(String sql, int columnIndexes[])
1367: throws SQLException {
1368: return wrappedStatement.execute(sql, columnIndexes);
1369: }
1370:
1371: /**
1372: * Executes the given SQL statement and signals the driver that the
1373: * auto-generated keys indicated in the given array should be made available
1374: * for retrieval. The driver will ignore the array if the SQL statement
1375: * is not an <code>INSERT</code> statement.
1376: *
1377: * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
1378: * <code>DELETE</code> statement or an SQL statement that returns nothing
1379: * @param columnNames an array of the names of the columns that should be
1380: * returned from the inserted row
1381: * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
1382: * or <code>DELETE</code> statements, or 0 for SQL statements
1383: * that return nothing
1384: * @throws java.sql.SQLException if a database access error occurs, the SQL
1385: * statement returns a <code>ResultSet</code> object, or the
1386: * second argument supplied to this method is not a <code>String</code> array
1387: * whose elements are valid column names
1388: * @since 1.4
1389: */
1390: public int executeUpdate(String sql, String columnNames[])
1391: throws SQLException {
1392: return wrappedStatement.executeUpdate(sql, columnNames);
1393: }
1394:
1395: /**
1396: * Executes the given SQL statement, which may return multiple results,
1397: * and signals the driver that the
1398: * auto-generated keys indicated in the given array should be made available
1399: * for retrieval. This array contains the names of the columns in the
1400: * target table that contain the auto-generated keys that should be made
1401: * available. The driver will ignore the array if the given SQL statement
1402: * is not an <code>INSERT</code> statement.
1403: * <p>
1404: * In some (uncommon) situations, a single SQL statement may return
1405: * multiple result sets and/or update counts. Normally you can ignore
1406: * this unless you are (1) executing a stored procedure that you know may
1407: * return multiple results or (2) you are dynamically executing an
1408: * unknown SQL string.
1409: * <p>
1410: * The <code>execute</code> method executes an SQL statement and indicates the
1411: * form of the first result. You must then use the methods
1412: * <code>getResultSet</code> or <code>getUpdateCount</code>
1413: * to retrieve the result, and <code>getMoreResults</code> to
1414: * move to any subsequent result(s).
1415: *
1416: * @param sql any SQL statement
1417: * @param columnNames an array of the names of the columns in the inserted
1418: * row that should be made available for retrieval by a call to the
1419: * method <code>getGeneratedKeys</code>
1420: * @return <code>true</code> if the next result is a <code>ResultSet</code>
1421: * object; <code>false</code> if it is an update count or there
1422: * are no more results
1423: * @throws java.sql.SQLException if a database access error occurs or the
1424: * elements of the <code>String</code> array passed to this
1425: * method are not valid column names
1426: * @see #getResultSet
1427: * @see #getUpdateCount
1428: * @see #getMoreResults
1429: * @see #getGeneratedKeys
1430: * @since 1.4
1431: */
1432: public boolean execute(String sql, String columnNames[])
1433: throws SQLException {
1434: return wrappedStatement.execute(sql, columnNames);
1435: }
1436:
1437: // ---------------------------------------------------------------- output
1438:
1439: /**
1440: * Returns the sql statement string (question marks replaced with set parameter values)
1441: * that will be (or has been) executed by the {@link java.sql.PreparedStatement PreparedStatement} that this
1442: * <code>LoggablePreparedStatement</code> is a wrapper for.
1443:
1444: * @return the statemant represented by this <code>LoggablePreparedStatement</code>
1445: */
1446: public String getQueryString() {
1447: StringBuilder buf = new StringBuilder();
1448: int qMarkCount = 0;
1449: StringTokenizer tok = new StringTokenizer(sqlTemplate + ' ',
1450: "?");
1451: while (tok.hasMoreTokens()) {
1452: String oneChunk = tok.nextToken();
1453: buf.append(oneChunk);
1454: try {
1455: Object value;
1456: if (parameterValues.size() > 1 + qMarkCount) {
1457: value = parameterValues.get(1 + qMarkCount);
1458: qMarkCount++;
1459: } else {
1460: if (tok.hasMoreTokens()) {
1461: value = null;
1462: } else {
1463: value = "";
1464: }
1465: }
1466: buf.append(value);
1467: } catch (Throwable th) {
1468: buf
1469: .append(
1470: "--- Exception occurs while creating query string for log: ")
1471: .append(th.toString());
1472: }
1473: }
1474: return buf.toString().trim();
1475: }
1476:
1477: /**
1478: * Saves the parameter value <code>obj</code> for the specified <code>position</code> for use in logging output
1479: *
1480: * @param position position (starting at 1) of the parameter to save
1481: * @param obj java.lang.Object the parameter value to save
1482: */
1483: private void saveQueryParamValue(int position, Object obj) {
1484: String strValue;
1485: if (obj instanceof String || obj instanceof Date) {
1486: strValue = "'" + obj + '\''; // if we have a String or Date , include '' in the saved value
1487: } else {
1488:
1489: if (obj == null) {
1490: strValue = "<null>"; // convert null to the string null
1491: } else {
1492: strValue = obj.toString(); // unknown object (includes all Numbers), just call toString
1493: }
1494: }
1495:
1496: // if we are setting a position larger than current size of parameterValues, first make it larger
1497: while (position >= parameterValues.size()) {
1498: parameterValues.add(null);
1499: }
1500: parameterValues.set(position, strValue);
1501: }
1502: }
|