0001: /*
0002: * This file is part of the WfMOpen project.
0003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
0004: * All rights reserved.
0005: *
0006: * This program is free software; you can redistribute it and/or modify
0007: * it under the terms of the GNU General Public License as published by
0008: * the Free Software Foundation; either version 2 of the License, or
0009: * (at your option) any later version.
0010: *
0011: * This program is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0014: * GNU General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * along with this program; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: *
0020: * $Id: UniversalPrepStmt.java,v 1.7 2007/03/27 21:59:43 mlipp Exp $
0021: *
0022: * $Log: UniversalPrepStmt.java,v $
0023: * Revision 1.7 2007/03/27 21:59:43 mlipp
0024: * Fixed lots of checkstyle warnings.
0025: *
0026: * Revision 1.6 2006/09/29 12:32:08 drmlipp
0027: * Consistently using WfMOpen as projct name now.
0028: *
0029: * Revision 1.5 2005/09/10 21:44:18 mlipp
0030: * Fixed JDK 5.0 warnings.
0031: *
0032: * Revision 1.4 2005/04/22 15:10:48 drmlipp
0033: * Merged changes from 1.3 branch up to 1.3p15.
0034: *
0035: * Revision 1.2.2.6 2005/04/21 13:10:23 drmlipp
0036: * Improved setBinary for Oracle.
0037: *
0038: * Revision 1.2.2.5 2005/04/14 11:45:07 drmlipp
0039: * More (minor) optimizations.
0040: *
0041: * Revision 1.2.2.4 2005/04/13 16:14:06 drmlipp
0042: * Optimized db access.
0043: *
0044: * Revision 1.2.2.3 2005/04/11 14:11:34 drmlipp
0045: * Added workaround for PointBase bug.
0046: *
0047: * Revision 1.3 2005/04/08 11:28:02 drmlipp
0048: * Merged changes from 1.3 branch up to 1.3p6.
0049: *
0050: * Revision 1.2.2.2 2005/04/04 12:39:15 drmlipp
0051: * Revoked assumption that Oracle 10g driver is fixed and minor
0052: * optimizations.
0053: *
0054: * Revision 1.2.2.1 2005/04/04 09:54:22 drmlipp
0055: * Optimized support for Oracle 10g driver.
0056: *
0057: * Revision 1.2 2004/12/31 13:06:08 mlipp
0058: * Improved setObject.
0059: *
0060: * Revision 1.1.1.2 2003/12/19 13:01:37 drmlipp
0061: * Updated to 1.1rc1
0062: *
0063: * Revision 1.34 2003/12/16 17:24:49 lipp
0064: * Made sanity check a requirement.
0065: *
0066: * Revision 1.33 2003/12/16 17:18:39 lipp
0067: * Added sanity check.
0068: *
0069: * Revision 1.32 2003/12/15 16:28:42 lipp
0070: * Fixed various problems.
0071: *
0072: * Revision 1.31 2003/12/03 15:37:48 lipp
0073: * Added WLS Oracle wrapper support.
0074: *
0075: * Revision 1.30 2003/06/27 08:51:47 lipp
0076: * Fixed copyright/license information.
0077: *
0078: * Revision 1.29 2003/05/13 14:36:22 lipp
0079: * Implemented WfRequester methods in AbstractActivity.
0080: *
0081: * Revision 1.28 2003/04/25 14:50:59 lipp
0082: * Fixed javadoc errors and warnings.
0083: *
0084: * Revision 1.27 2003/04/16 16:23:48 lipp
0085: * Adapted to jdk 1.4.1
0086: *
0087: * Revision 1.26 2003/04/10 08:20:50 huaiyang
0088: * Cache Column of Update statement fixed.
0089: *
0090: * Revision 1.25 2003/03/31 16:50:27 huaiyang
0091: * Logging using common-logging.
0092: *
0093: * Revision 1.24 2003/03/11 09:19:23 schlue
0094: * Comment for defer updated.
0095: *
0096: * Revision 1.23 2003/03/10 13:42:19 schlue
0097: * Added some comments.
0098: *
0099: * Revision 1.22 2003/03/07 15:09:09 lipp
0100: * Minor fixes.
0101: *
0102: * Revision 1.21 2003/03/07 11:19:34 huaiyang
0103: * initialisation of updateClobsMap/updateBlobsMap rationalized.
0104: *
0105: * Revision 1.20 2003/03/07 09:26:16 lipp
0106: * Fixed character conversion problem.
0107: *
0108: * Revision 1.19 2003/03/06 13:50:36 lipp
0109: * Some cleanup.
0110: *
0111: * Revision 1.18 2003/03/06 11:03:02 huaiyang
0112: * use innerClass of SaveColumn to replace the list for caching.
0113: *
0114: * Revision 1.17 2003/03/06 09:23:27 lipp
0115: * Added some debugging info.
0116: *
0117: * Revision 1.16 2003/03/06 08:07:11 lipp
0118: * Work around JBoss bug.
0119: *
0120: * Revision 1.15 2003/03/05 11:43:42 huaiyang
0121: * set updateClobsMap and updateBlobsMap to null after executeUpdate.
0122: *
0123: * Revision 1.14 2003/03/05 10:39:36 huaiyang
0124: * remove unnecessary logs.
0125: *
0126: * Revision 1.13 2003/03/05 10:38:11 huaiyang
0127: * primary key column error fixed.
0128: *
0129: * Revision 1.12 2003/03/05 09:42:01 lipp
0130: * Added some debug info.
0131: *
0132: * Revision 1.11 2003/03/05 08:43:07 huaiyang
0133: * clean up the code.
0134: *
0135: * Revision 1.10 2003/03/05 08:19:53 huaiyang
0136: * setAutoCommit staff added.
0137: *
0138: * Revision 1.9 2003/03/04 14:00:27 huaiyang
0139: * review worked.
0140: *
0141: * Revision 1.8 2003/03/04 12:23:06 huaiyang
0142: * error with setting deferDelegee fixed.
0143: *
0144: * Revision 1.7 2003/03/04 10:17:33 huaiyang
0145: * add the see link of javadoc.
0146: *
0147: * Revision 1.6 2003/03/04 09:55:10 huaiyang
0148: * javadoc for the public set methods added.
0149: *
0150: * Revision 1.5 2003/03/04 08:18:57 huaiyang
0151: * added the additional comments.
0152: *
0153: * Revision 1.4 2003/03/03 15:47:38 huaiyang
0154: * close the selectForUpdateStmt after used.
0155: *
0156: * Revision 1.3 2003/03/03 12:35:18 lipp
0157: * Removed inappropriate use of printStacktrace.
0158: *
0159: * Revision 1.2 2003/02/28 15:32:02 huaiyang
0160: * use deferDelegee to wrap the oracle prepStmt.
0161: *
0162: * Revision 1.1 2003/02/21 16:38:51 lipp
0163: * Introduced UniversalPrepStmt.
0164: *
0165: */
0166: package de.danet.an.util;
0167:
0168: import java.io.ByteArrayInputStream;
0169: import java.io.ByteArrayOutputStream;
0170: import java.io.IOException;
0171: import java.io.InputStream;
0172: import java.io.ObjectOutputStream;
0173: import java.io.OutputStream;
0174: import java.io.Reader;
0175: import java.io.StringReader;
0176: import java.io.Writer;
0177:
0178: import java.util.ArrayList;
0179: import java.util.Calendar;
0180: import java.util.Iterator;
0181: import java.util.List;
0182: import java.util.Map;
0183: import java.util.SortedMap;
0184: import java.util.StringTokenizer;
0185: import java.util.TreeMap;
0186:
0187: import java.lang.reflect.InvocationTargetException;
0188: import java.lang.reflect.Method;
0189: import java.math.BigDecimal;
0190: import java.net.URL;
0191: import java.sql.Array;
0192: import java.sql.Blob;
0193: import java.sql.Clob;
0194: import java.sql.Connection;
0195: import java.sql.Date;
0196: import java.sql.ParameterMetaData;
0197: import java.sql.PreparedStatement;
0198: import java.sql.Ref;
0199: import java.sql.ResultSet;
0200: import java.sql.ResultSetMetaData;
0201: import java.sql.SQLException;
0202: import java.sql.SQLWarning;
0203: import java.sql.Time;
0204: import java.sql.Timestamp;
0205: import java.sql.Types;
0206:
0207: import javax.sql.DataSource;
0208:
0209: /**
0210: * This class provides a wrapper that can handle special database
0211: * requirements. Although suitable for all jdbc-driven database
0212: * connections, special features of the following databases
0213: * are supported: Oracle, SAPDB and Hypersonic. In addition, all
0214: * set/get methods for non-primitives handle <code>null</code> values
0215: * correctly.<P>
0216: *
0217: * Additional methods {@link #setBinary <code>setBinary</code>} and
0218: * {@link #setInt(int,Integer) <code>setInt(int, Integer)</code>}
0219: * {@link #setLargeString <code>setLargeString</code>} are
0220: * provided for convenience.
0221: *
0222: * @author <a href="mailto:lipp@danet.de"></a>
0223: * @version $Revision: 1.7 $
0224: */
0225:
0226: public class UniversalPrepStmt implements PreparedStatement {
0227:
0228: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0229: .getLog(UniversalPrepStmt.class);
0230:
0231: // constant to identify which method of deferDelegee must be called for
0232: // the cached values.
0233: private static final int SET_INT = 1;
0234: private static final int SET_SHORT = 2;
0235: private static final int SET_LONG = 3;
0236: private static final int SET_FLOAT = 4;
0237: private static final int SET_DOUBLE = 5;
0238: private static final int SET_BIGDECIMAL = 6;
0239: private static final int SET_BOOLEAN = 7;
0240: private static final int SET_BYTE = 8;
0241: private static final int SET_STRING = 9;
0242: private static final int SET_DATE = 10;
0243: private static final int SET_DATE_CALENDAR = 11;
0244: private static final int SET_TIME = 12;
0245: private static final int SET_TIME_CALENDAR = 13;
0246: private static final int SET_TIMESTAMP = 14;
0247: private static final int SET_TIMESTAMP_CALENDAR = 15;
0248: private static final int SET_NULL = 16;
0249: private static final int SET_NULL_STRING = 17;
0250: private static final int SET_CLOB = 18;
0251: private static final int SET_BLOB = 19;
0252:
0253: private static Class thinBlobClass = null;
0254: private static Class thinClobClass = null;
0255: private static Method thinBlobGetBinaryOS = null;
0256: private static Method thinBlobGetBufferSize = null;
0257: private static Method thinClobGetCharacterOS = null;
0258: static {
0259: try {
0260: thinBlobClass = Thread
0261: .currentThread()
0262: .getContextClassLoader()
0263: .loadClass(
0264: "weblogic.jdbc.vendor.oracle.OracleThinBlob");
0265: if (thinBlobClass != null) {
0266: thinBlobGetBinaryOS = thinBlobClass.getMethod(
0267: "getBinaryOutputStream", (Class[]) null);
0268: thinBlobGetBufferSize = thinBlobClass.getMethod(
0269: "getBufferSize", (Class[]) null);
0270: }
0271: thinClobClass = Thread
0272: .currentThread()
0273: .getContextClassLoader()
0274: .loadClass(
0275: "weblogic.jdbc.vendor.oracle.OracleThinClob");
0276: if (thinClobClass != null) {
0277: thinClobGetCharacterOS = thinClobClass.getMethod(
0278: "getCharacterOutputStream", (Class[]) null);
0279: }
0280: } catch (ClassNotFoundException e) {
0281: // OK, no WLS environment.
0282: } catch (NoSuchMethodException e) {
0283: logger.error("Class does not have expected method: "
0284: + e.getMessage());
0285: } catch (SecurityException e) {
0286: logger.error("Cannot access method: " + e.getMessage());
0287: }
0288: }
0289:
0290: /** The database connection. */
0291: private Connection con;
0292:
0293: /** The statement. */
0294: private String stmt;
0295:
0296: /** The db properties for the current connection. */
0297: private JDBCUtil.DBProperties dbProps = null;
0298:
0299: /** Flag to pass through (this statement) */
0300: private boolean passThrough = true;
0301:
0302: /** flag to defer delegee. if the given stmt is INSERT or UPDATE
0303: using the database of ORACLE, this flag is set to true. The
0304: statement has to be deferred since - for some databases -
0305: large objects (CLOB or BLOB) have to be stored by use of more than
0306: one statement. */
0307: private boolean deferDelegee = false;
0308:
0309: /** Set if deferDelegee is true and the statement is an "INSERT"
0310: statement. */
0311: private boolean deferredInsert = false;
0312:
0313: /** The delegee prepared statement if calls may simply be passed. */
0314: private PreparedStatement delegee = null;
0315:
0316: /** The comma separated list of primary key columns */
0317: private String[] primaryKeyColumns = null;
0318:
0319: /** table name of the prepare statement */
0320: private String tableName = null;
0321:
0322: /** the list of column names to be updated (without WHERE columns) */
0323: private List dataCols = null;
0324:
0325: /** the list of all the column name include where columns */
0326: private List allCols = null;
0327:
0328: /** the map of all the clobs and its index */
0329: private SortedMap updateClobsMap = null;
0330:
0331: /** the map of all the blobs and its index */
0332: private SortedMap updateBlobsMap = null;
0333:
0334: /** the map of the columns of primary keys or of where clause */
0335: private List keyValues = new ArrayList();
0336:
0337: /** the cached where clause of the update statement */
0338: private String updateWhereClause = null;
0339:
0340: /**
0341: * This class is used to cache the column value so that the deferDelegee
0342: * can call the respective method to set the column value again.
0343: */
0344: private class SaveColumn {
0345: /** to identify which method must be used to set the given values */
0346: public int methodType;
0347: /** given values to set in the deferDelegee */
0348: public Object value1;
0349: public Object value2;
0350:
0351: public SaveColumn(int methodType, Object value1) {
0352: this (methodType, value1, null);
0353: }
0354:
0355: public SaveColumn(int methodType, Object value1, Object value2) {
0356: this .methodType = methodType;
0357: this .value1 = value1;
0358: this .value2 = value2;
0359: }
0360: }
0361:
0362: /**
0363: * Creates an instance of <code>UniversalPrepStmt</code> with no
0364: * given primary key columns, thus assuming the 1st column of the
0365: * insert statement being primary key column. NOTE: In this case,
0366: * only insert statements without column name listings (format:
0367: * INSERT INTO <table> <values>) are supported. An internal
0368: * delegee prepared statement is generated using the given
0369: * connection for the supported databases.
0370: * @param connection the connection to be used to generate the delegee
0371: * PrepareStatement.
0372: * @param statement the statement to be executed.
0373: * @throws IllegalArgumentException if the statement cannot be parsed.
0374: * @throws SQLException if an error occurs.
0375: */
0376: public UniversalPrepStmt(Connection connection, String statement)
0377: throws IllegalArgumentException, SQLException {
0378: this (null, connection, statement, (String[]) null);
0379: }
0380:
0381: /**
0382: * Creates an instance of <code>UniversalPrepStmt</code> with no
0383: * given primary key columns, thus assuming the 1st column of the
0384: * insert statement being primary key column. NOTE: In this case,
0385: * only insert statements without column name listings (format:
0386: * INSERT INTO <table> <values>) are supported. An internal
0387: * delegee prepared statement is generated using the given
0388: * connection for the supported databases.
0389: * @param dataSource used for caching properties of the database
0390: * @param connection the connection to be used to generate the delegee
0391: * PrepareStatement.
0392: * @param statement the statement to be executed.
0393: * @throws IllegalArgumentException if the statement cannot be parsed.
0394: * @throws SQLException if an error occurs.
0395: */
0396: public UniversalPrepStmt(DataSource dataSource,
0397: Connection connection, String statement)
0398: throws IllegalArgumentException, SQLException {
0399: this (dataSource, connection, statement, (String[]) null);
0400: }
0401:
0402: /**
0403: * Creates an instance of <code>UniversalPrepStmt</code>. An internal
0404: * delegee prepared statement is generated using the given connection for
0405: * the supported databases.
0406: * @param connection the connection to be used.
0407: * @param statement the statement to be executed.
0408: * @param primaryKeyColumns the comma separated primary key
0409: * list. The column names must be in the same sequence as they
0410: * appear in the field list of the insert statement.
0411: * @throws IllegalArgumentException if the statement cannot be parsed.
0412: * @throws SQLException if an error occurs.
0413: */
0414: public UniversalPrepStmt(Connection connection, String statement,
0415: String primaryKeyColumns) throws IllegalArgumentException,
0416: SQLException {
0417: this (null, connection, statement, primaryKeyColumns);
0418: }
0419:
0420: /**
0421: * Creates an instance of <code>UniversalPrepStmt</code>. An internal
0422: * delegee prepared statement is generated using the given connection for
0423: * the supported databases.
0424: * @param connection the connection to be used.
0425: * @param statement the statement to be executed.
0426: * @param primaryKeyColumns the primary key column name list. The
0427: * column names must be in the same sequence as they appear in the
0428: * field list of the insert statement.
0429: * @throws IllegalArgumentException if the statement cannot be parsed.
0430: * @throws SQLException if an error occurs.
0431: */
0432: public UniversalPrepStmt(Connection connection, String statement,
0433: String[] primaryKeyColumns)
0434: throws IllegalArgumentException, SQLException {
0435: this (null, connection, statement, primaryKeyColumns);
0436: }
0437:
0438: /**
0439: * Creates an instance of <code>UniversalPrepStmt</code>. An internal
0440: * delegee prepared statement is generated using the given connection for
0441: * the supported databases.
0442: * @param dataSource used for caching properties of the database
0443: * @param connection the connection to be used.
0444: * @param statement the statement to be executed.
0445: * @param primaryKeyColumns the comma separated primary key
0446: * list. The column names must be in the same sequence as they
0447: * appear in the field list of the insert statement.
0448: * @throws IllegalArgumentException if the statement cannot be parsed.
0449: * @throws SQLException if an error occurs.
0450: */
0451: public UniversalPrepStmt(DataSource dataSource,
0452: Connection connection, String statement,
0453: String primaryKeyColumns) throws IllegalArgumentException,
0454: SQLException {
0455: this (dataSource, connection, statement,
0456: parseColumns(primaryKeyColumns));
0457: }
0458:
0459: private static String[] parseColumns(String primaryKeyColumns) {
0460: if (primaryKeyColumns == null) {
0461: return null;
0462: }
0463: List pkcs = new ArrayList();
0464: StringTokenizer st = new StringTokenizer(primaryKeyColumns, ",");
0465: while (st.hasMoreTokens()) {
0466: pkcs.add(st.nextToken().trim());
0467: }
0468: return (String[]) pkcs.toArray(new String[pkcs.size()]);
0469: }
0470:
0471: /**
0472: * Creates an instance of <code>UniversalPrepStmt</code>. An internal
0473: * delegee prepared statement is generated using the given connection for
0474: * the supported databases.
0475: * @param dataSource used for caching properties of the database
0476: * @param connection the connection to be used.
0477: * @param statement the statement to be executed.
0478: * @param primaryKeyColumns the primary key column name list. The
0479: * column names must be in the same sequence as they appear in the
0480: * field list of the insert statement.
0481: * @throws IllegalArgumentException if the statement cannot be parsed.
0482: * @throws SQLException if an error occurs.
0483: */
0484: public UniversalPrepStmt(DataSource dataSource,
0485: Connection connection, String statement,
0486: String[] primaryKeyColumns)
0487: throws IllegalArgumentException, SQLException {
0488: this .primaryKeyColumns = primaryKeyColumns;
0489: con = connection;
0490: stmt = statement;
0491: dbProps = JDBCUtil.dbProperties(dataSource, connection);
0492: passThrough = dbProps.mayPassThrough();
0493: if (passThrough) {
0494: delegee = con.prepareStatement(stmt);
0495: } else {
0496: // do specific preparation before getting delegee.
0497: // if the database is oracle, do it; if not, throws Exception.
0498: if (dbProps.isOracle()) {
0499: // if the given stmt is INSERT or UPDATE, the flag of
0500: // deferDelegee is set to true; for all the other stmts
0501: // set passthrough as true.
0502: delegee = getOraclePrepareStatement(con, stmt);
0503: } else {
0504: throw new SQLException("unsupported database!");
0505: }
0506: }
0507: }
0508:
0509: /**
0510: * Calls the <code>close</code> method on the delegee prepared statement.
0511: * Throws a UnsupportedOperationException if no delegee is available.
0512: * @throws SQLException if an error occurs
0513: * @see java.sql.PreparedStatement#close
0514: */
0515: public void close() throws SQLException {
0516: if (delegee != null) {
0517: delegee.close();
0518: return;
0519: }
0520: throw new UnsupportedOperationException();
0521: }
0522:
0523: /**
0524: * Calls the <code>execute</code> method on the delegee prepared statement.
0525: * Throws a UnsupportedOperationException if no delegee is available.
0526: *
0527: * @param string a <code>String</code> value.
0528: * @return a <code>boolean</code> value.
0529: * @throws SQLException if an error occurs.
0530: * @see java.sql.PreparedStatement#execute
0531: */
0532: public boolean execute(String string) throws SQLException {
0533: if (delegee != null) {
0534: return delegee.execute(string);
0535: }
0536: throw new UnsupportedOperationException();
0537: }
0538:
0539: /**
0540: * Calls the <code>execute</code> method on the delegee prepared statement.
0541: * Throws a UnsupportedOperationException if no delegee is available.
0542: *
0543: * @param string a <code>String</code> value.
0544: * @param autoGeneratedKeys see {@link
0545: * java.sql.Statement#execute(String,int)
0546: * <code>Statement</code>}
0547: * @return a <code>boolean</code> value.
0548: * @throws SQLException if an error occurs.
0549: * @see java.sql.Statement#execute(String,int)
0550: */
0551: public boolean execute(String string, int autoGeneratedKeys)
0552: throws SQLException {
0553: if (delegee != null) {
0554: return delegee.execute(string, autoGeneratedKeys);
0555: }
0556: throw new UnsupportedOperationException();
0557: }
0558:
0559: /**
0560: * Calls the <code>execute</code> method on the delegee prepared statement.
0561: * Throws a UnsupportedOperationException if no delegee is available.
0562: *
0563: * @param string a <code>String</code> value.
0564: * @param columnIndexes see {@link
0565: * java.sql.Statement#execute(String,int[])
0566: * <code>Statement</code>}
0567: * @return a <code>boolean</code> value.
0568: * @throws SQLException if an error occurs.
0569: * @see java.sql.Statement#execute(String,int[])
0570: */
0571: public boolean execute(String string, int[] columnIndexes)
0572: throws SQLException {
0573: if (delegee != null) {
0574: return delegee.execute(string, columnIndexes);
0575: }
0576: throw new UnsupportedOperationException();
0577: }
0578:
0579: /**
0580: * Calls the <code>execute</code> method on the delegee prepared statement.
0581: * Throws a UnsupportedOperationException if no delegee is available.
0582: *
0583: * @param string a <code>String</code> value.
0584: * @param columnNames see {@link
0585: * java.sql.Statement#execute(String,String[])
0586: * <code>Statement</code>}
0587: * @return a <code>boolean</code> value.
0588: * @throws SQLException if an error occurs.
0589: * @see java.sql.Statement#execute(String,String[])
0590: */
0591: public boolean execute(String string, String[] columnNames)
0592: throws SQLException {
0593: if (delegee != null) {
0594: return delegee.execute(string, columnNames);
0595: }
0596: throw new UnsupportedOperationException();
0597: }
0598:
0599: /**
0600: * Return the database connection.
0601: *
0602: * @return the database connection.
0603: * @throws SQLException if an error occurs.
0604: */
0605: public Connection getConnection() throws SQLException {
0606: return con;
0607: }
0608:
0609: /**
0610: * Calls the <code>executeQuery</code> method on the delegee prepared
0611: * statement. Throws a UnsupportedOperationException if no delegee
0612: * is available.
0613: *
0614: * @param string a <code>String</code> value.
0615: * @return a <code>ResultSet</code> value.
0616: * @throws SQLException if an error occurs.
0617: * @see java.sql.PreparedStatement#executeQuery
0618: */
0619: public ResultSet executeQuery(String string) throws SQLException {
0620: if (delegee != null) {
0621: return delegee.executeQuery(string);
0622: }
0623: throw new UnsupportedOperationException();
0624: }
0625:
0626: /**
0627: * Calls the <code>getWarnings</code> method on the delegee prepared
0628: * statement. Throws a UnsupportedOperationException if no delegee
0629: * is available.
0630: *
0631: * @return a <code>SQLWarning</code> value.
0632: * @throws SQLException if an error occurs.
0633: * @see java.sql.PreparedStatement#getWarnings
0634: */
0635: public SQLWarning getWarnings() throws SQLException {
0636: if (delegee != null) {
0637: return delegee.getWarnings();
0638: }
0639: throw new UnsupportedOperationException();
0640: }
0641:
0642: /**
0643: * Calls the <code>clearWarnings</code> method on the delegee prepared
0644: * statement. Throws a UnsupportedOperationException if no delegee
0645: * is available.
0646: *
0647: * @throws SQLException if an error occurs.
0648: * @see java.sql.PreparedStatement#clearWarnings
0649: */
0650: public void clearWarnings() throws SQLException {
0651: if (delegee != null) {
0652: delegee.clearWarnings();
0653: return;
0654: }
0655: throw new UnsupportedOperationException();
0656: }
0657:
0658: /**
0659: * Calls the <code>executeUpdate</code> method on the delegee prepared
0660: * statement.
0661: * Throws a UnsupportedOperationException if no delegee is available.
0662: *
0663: * @param string a <code>String</code> value.
0664: * @return an <code>int</code> value.
0665: * @throws SQLException if an error occurs.
0666: * @see java.sql.PreparedStatement#executeUpdate
0667: */
0668: public int executeUpdate(String string) throws SQLException {
0669: if (delegee != null) {
0670: return delegee.executeUpdate(string);
0671: }
0672: throw new UnsupportedOperationException();
0673: }
0674:
0675: /**
0676: * Calls the <code>executeUpdate</code> method on the delegee prepared
0677: * statement.
0678: * Throws a UnsupportedOperationException if no delegee is available.
0679: *
0680: * @param string a <code>String</code> value.
0681: * @param autoGeneratedKeys see {@link
0682: * java.sql.Statement#executeUpdate(String,int)
0683: * <code>Statement</code>}
0684: * @return an <code>int</code> value.
0685: * @throws SQLException if an error occurs.
0686: * @see java.sql.Statement#executeUpdate(String,int)
0687: */
0688: public int executeUpdate(String string, int autoGeneratedKeys)
0689: throws SQLException {
0690: if (delegee != null) {
0691: return delegee.executeUpdate(string, autoGeneratedKeys);
0692: }
0693: throw new UnsupportedOperationException();
0694: }
0695:
0696: /**
0697: * Calls the <code>executeUpdate</code> method on the delegee prepared
0698: * statement.
0699: * Throws a UnsupportedOperationException if no delegee is available.
0700: *
0701: * @param string a <code>String</code> value.
0702: * @param columnIndexes see {@link
0703: * java.sql.Statement#executeUpdate(String,int[])
0704: * <code>Statement</code>}
0705: * @return an <code>int</code> value.
0706: * @throws SQLException if an error occurs.
0707: * @see java.sql.Statement#executeUpdate(String,int[])
0708: */
0709: public int executeUpdate(String string, int[] columnIndexes)
0710: throws SQLException {
0711: if (delegee != null) {
0712: return delegee.executeUpdate(string, columnIndexes);
0713: }
0714: throw new UnsupportedOperationException();
0715: }
0716:
0717: /**
0718: * Calls the <code>executeUpdate</code> method on the delegee prepared
0719: * statement.
0720: * Throws a UnsupportedOperationException if no delegee is available.
0721: *
0722: * @param string a <code>String</code> value.
0723: * @param columnNames see {@link
0724: * java.sql.Statement#executeUpdate(String,String[])
0725: * <code>Statement</code>}
0726: * @return an <code>int</code> value.
0727: * @throws SQLException if an error occurs.
0728: * @see java.sql.Statement#executeUpdate(String,String[])
0729: */
0730: public int executeUpdate(String string, String[] columnNames)
0731: throws SQLException {
0732: if (delegee != null) {
0733: return delegee.executeUpdate(string, columnNames);
0734: }
0735: throw new UnsupportedOperationException();
0736: }
0737:
0738: /**
0739: * Calls the <code>addBatch</code> method on the delegee prepared
0740: * statement. Throws a UnsupportedOperationException if no delegee
0741: * is available.
0742: *
0743: * @param string a <code>String</code> value.
0744: * @throws SQLException if an error occurs.
0745: * @see java.sql.PreparedStatement#addBatch
0746: */
0747: public void addBatch(String string) throws SQLException {
0748: if (delegee != null) {
0749: delegee.addBatch(string);
0750: return;
0751: }
0752: throw new UnsupportedOperationException();
0753: }
0754:
0755: /**
0756: * Calls the <code>getMaxFieldSize</code> method on the delegee prepared
0757: * statement. Throws a UnsupportedOperationException if no delegee
0758: * is available.
0759: *
0760: * @return an <code>int</code> value.
0761: * @throws SQLException if an error occurs.
0762: * @see java.sql.PreparedStatement#getMaxFieldSize
0763: */
0764: public int getMaxFieldSize() throws SQLException {
0765: if (delegee != null) {
0766: return delegee.getMaxFieldSize();
0767: }
0768: throw new UnsupportedOperationException();
0769: }
0770:
0771: /**
0772: * Calls the <code>setMaxFieldSize</code> method on the delegee prepared
0773: * statement. Throws a UnsupportedOperationException if no delegee
0774: * is available.
0775: *
0776: * @param n an <code>int</code> value.
0777: * @throws SQLException if an error occurs.
0778: * @see java.sql.PreparedStatement#setMaxFieldSize
0779: */
0780: public void setMaxFieldSize(int n) throws SQLException {
0781: if (delegee != null) {
0782: delegee.setMaxFieldSize(n);
0783: return;
0784: }
0785: throw new UnsupportedOperationException();
0786: }
0787:
0788: /**
0789: * Calls the <code>getMaxRows</code> method on the delegee prepared
0790: * statement. Throws a UnsupportedOperationException if no delegee
0791: * is available.
0792: *
0793: * @return an <code>int</code> value.
0794: * @throws SQLException if an error occurs.
0795: * @see java.sql.PreparedStatement#getMaxRows
0796: */
0797: public int getMaxRows() throws SQLException {
0798: if (delegee != null) {
0799: return delegee.getMaxRows();
0800: }
0801: throw new UnsupportedOperationException();
0802: }
0803:
0804: /**
0805: * Calls the <code>setMaxRows</code> method on the delegee prepared
0806: * statement. Throws a UnsupportedOperationException if no delegee
0807: * is available.
0808: *
0809: * @param n an <code>int</code> value.
0810: * @throws SQLException if an error occurs.
0811: * @see java.sql.PreparedStatement#setMaxRows
0812: */
0813: public void setMaxRows(int n) throws SQLException {
0814: if (delegee != null) {
0815: delegee.setMaxRows(n);
0816: return;
0817: }
0818: throw new UnsupportedOperationException();
0819: }
0820:
0821: /**
0822: * Calls the <code>setEscapeProcessing</code> method on the delegee
0823: * prepared statement. Throws a UnsupportedOperationException if no
0824: * delegee is available.
0825: *
0826: * @param flag a <code>boolean</code> value.
0827: * @throws SQLException if an error occurs.
0828: * @see java.sql.PreparedStatement#setEscapeProcessing
0829: */
0830: public void setEscapeProcessing(boolean flag) throws SQLException {
0831: if (delegee != null) {
0832: delegee.setEscapeProcessing(flag);
0833: return;
0834: }
0835: throw new UnsupportedOperationException();
0836: }
0837:
0838: /**
0839: * Calls the <code>getQueryTimeout</code> method on the delegee
0840: * prepared statement. Throws a UnsupportedOperationException if no
0841: * delegee is available.
0842: *
0843: * @return an <code>int</code> value.
0844: * @throws SQLException if an error occurs.
0845: * @see java.sql.PreparedStatement#getQueryTimeout
0846: */
0847: public int getQueryTimeout() throws SQLException {
0848: if (delegee != null) {
0849: return delegee.getQueryTimeout();
0850: }
0851: throw new UnsupportedOperationException();
0852: }
0853:
0854: /**
0855: * Calls the <code>setQueryTimeout</code> method on the delegee
0856: * prepared statement. Throws a UnsupportedOperationException if no
0857: * delegee is available.
0858: *
0859: * @param n an <code>int</code> value.
0860: * @throws SQLException if an error occurs.
0861: * @see java.sql.PreparedStatement#setQueryTimeout
0862: */
0863: public void setQueryTimeout(int n) throws SQLException {
0864: if (delegee != null) {
0865: delegee.setQueryTimeout(n);
0866: return;
0867: }
0868: throw new UnsupportedOperationException();
0869: }
0870:
0871: /**
0872: * Calls the <code>cancel</code> method on the delegee prepared statement.
0873: * Throws a UnsupportedOperationException if no delegee is available.
0874: *
0875: * @throws SQLException if an error occurs.
0876: * @see java.sql.PreparedStatement#cancel
0877: */
0878: public void cancel() throws SQLException {
0879: if (delegee != null) {
0880: delegee.cancel();
0881: return;
0882: }
0883: throw new UnsupportedOperationException();
0884: }
0885:
0886: /**
0887: * Calls the <code>setCursorName</code> method on the delegee prepared
0888: * statement. Throws a UnsupportedOperationException if no delegee is
0889: * available.
0890: *
0891: * @param string a <code>String</code> value.
0892: * @throws SQLException if an error occurs.
0893: * @see java.sql.PreparedStatement#setCursorName
0894: */
0895: public void setCursorName(String string) throws SQLException {
0896: if (delegee != null) {
0897: delegee.setCursorName(string);
0898: return;
0899: }
0900: throw new UnsupportedOperationException();
0901: }
0902:
0903: /**
0904: * Calls the <code>getResultSet</code> method on the delegee prepared
0905: * statement. Throws a UnsupportedOperationException if no delegee is
0906: * available.
0907: *
0908: * @return a <code>ResultSet</code> value.
0909: * @throws SQLException if an error occurs.
0910: * @see java.sql.PreparedStatement#getResultSet
0911: */
0912: public ResultSet getResultSet() throws SQLException {
0913: if (delegee != null) {
0914: return delegee.getResultSet();
0915: }
0916: throw new UnsupportedOperationException();
0917: }
0918:
0919: /**
0920: * Calls the <code>getResultSetHoldability</code> method on the
0921: * delegee prepared statement. Throws a
0922: * UnsupportedOperationException if no delegee is available.
0923: *
0924: * @return a <code>int</code> value.
0925: * @throws SQLException if an error occurs.
0926: * @see java.sql.PreparedStatement#getResultSetHoldability
0927: */
0928: public int getResultSetHoldability() throws SQLException {
0929: if (delegee != null) {
0930: return delegee.getResultSetHoldability();
0931: }
0932: throw new UnsupportedOperationException();
0933: }
0934:
0935: /**
0936: * Calls the <code>getUpdateCount</code> method on the delegee prepared
0937: * statement. Throws a UnsupportedOperationException if no delegee is
0938: * available.
0939: *
0940: * @return an <code>int</code> value.
0941: * @throws SQLException if an error occurs.
0942: * @see java.sql.PreparedStatement#getUpdateCount
0943: */
0944: public int getUpdateCount() throws SQLException {
0945: if (delegee != null) {
0946: return delegee.getUpdateCount();
0947: }
0948: throw new UnsupportedOperationException();
0949: }
0950:
0951: /**
0952: * Calls the <code>getMoreResults</code> method on the delegee prepared
0953: * statement. Throws a UnsupportedOperationException if no delegee is
0954: * available.
0955: *
0956: * @return a <code>boolean</code> value.
0957: * @throws SQLException if an error occurs.
0958: * @see java.sql.PreparedStatement#getMoreResults
0959: */
0960: public boolean getMoreResults() throws SQLException {
0961: if (delegee != null) {
0962: return delegee.getMoreResults();
0963: }
0964: throw new UnsupportedOperationException();
0965: }
0966:
0967: /**
0968: * Calls the <code>getMoreResults</code> method on the delegee prepared
0969: * statement. Throws a UnsupportedOperationException if no delegee is
0970: * available.
0971: *
0972: * @param current see {@link
0973: * java.sql.Statement#getMoreResults(int)
0974: * <code>Statement</code>}
0975: * @return a <code>boolean</code> value.
0976: * @throws SQLException if an error occurs.
0977: * @see java.sql.Statement#getMoreResults(int)
0978: */
0979: public boolean getMoreResults(int current) throws SQLException {
0980: if (delegee != null) {
0981: return delegee.getMoreResults(current);
0982: }
0983: throw new UnsupportedOperationException();
0984: }
0985:
0986: /**
0987: * Calls the <code>getGeneratedKeys</code> method on the delegee prepared
0988: * statement. Throws a UnsupportedOperationException if no delegee is
0989: * available.
0990: *
0991: * @return a <code>ResultSet</code> value.
0992: * @throws SQLException if an error occurs.
0993: * @see java.sql.PreparedStatement#getMoreResults
0994: */
0995: public ResultSet getGeneratedKeys() throws SQLException {
0996: if (delegee != null) {
0997: return delegee.getGeneratedKeys();
0998: }
0999: throw new UnsupportedOperationException();
1000: }
1001:
1002: /**
1003: * Calls the <code>setFetchDirection</code> method on the delegee prepared
1004: * statement. Throws a UnsupportedOperationException if no delegee is
1005: * available.
1006: *
1007: * @param n an <code>int</code> value.
1008: * @throws SQLException if an error occurs.
1009: * @see java.sql.PreparedStatement#setFetchDirection
1010: */
1011: public void setFetchDirection(int n) throws SQLException {
1012: if (delegee != null) {
1013: delegee.setFetchDirection(n);
1014: return;
1015: }
1016: throw new UnsupportedOperationException();
1017: }
1018:
1019: /**
1020: * Calls the <code>getFetchDirection</code> method on the delegee prepared
1021: * statement. Throws a UnsupportedOperationException if no delegee is
1022: * available.
1023: *
1024: * @return an <code>int</code> value.
1025: * @throws SQLException if an error occurs.
1026: * @see java.sql.PreparedStatement#getFetchDirection
1027: */
1028: public int getFetchDirection() throws SQLException {
1029: if (delegee != null) {
1030: return delegee.getFetchDirection();
1031: }
1032: throw new UnsupportedOperationException();
1033: }
1034:
1035: /**
1036: * Calls the <code>setFetchSize</code> method on the delegee prepared
1037: * statement. Throws a UnsupportedOperationException if no delegee is
1038: * available.
1039: *
1040: * @param n an <code>int</code> value.
1041: * @throws SQLException if an error occurs.
1042: * @see java.sql.PreparedStatement#setFetchSize
1043: */
1044: public void setFetchSize(int n) throws SQLException {
1045: if (delegee != null) {
1046: delegee.setFetchDirection(n);
1047: return;
1048: }
1049: throw new UnsupportedOperationException();
1050: }
1051:
1052: /**
1053: * Calls the <code>getFetchSize</code> method on the delegee prepared
1054: * statement. Throws a UnsupportedOperationException if no delegee is
1055: * available.
1056: *
1057: * @return an <code>int</code> value.
1058: * @throws SQLException if an error occurs.
1059: * @see java.sql.PreparedStatement#getFetchSize
1060: */
1061: public int getFetchSize() throws SQLException {
1062: if (delegee != null) {
1063: return delegee.getFetchSize();
1064: }
1065: throw new UnsupportedOperationException();
1066: }
1067:
1068: /**
1069: * Calls the <code>getResultSetConcurrency</code> method on the delegee
1070: * prepared statement. Throws a UnsupportedOperationException if no delegee
1071: * is available.
1072: *
1073: * @return an <code>int</code> value.
1074: * @throws SQLException if an error occurs.
1075: * @see java.sql.PreparedStatement#getResultSetConcurrency
1076: */
1077: public int getResultSetConcurrency() throws SQLException {
1078: if (delegee != null) {
1079: return delegee.getResultSetConcurrency();
1080: }
1081: throw new UnsupportedOperationException();
1082: }
1083:
1084: /**
1085: * Calls the <code>getResultSetType</code> method on the delegee prepared
1086: * statement. Throws a UnsupportedOperationException if no delegee is
1087: * available.
1088: *
1089: * @return an <code>int</code> value.
1090: * @throws SQLException if an error occurs.
1091: * @see java.sql.PreparedStatement#getResultSetType
1092: */
1093: public int getResultSetType() throws SQLException {
1094: if (delegee != null) {
1095: return delegee.getResultSetType();
1096: }
1097: throw new UnsupportedOperationException();
1098: }
1099:
1100: /**
1101: * Calls the <code>clearBatch</code> method on the delegee prepared
1102: * statement. Throws a UnsupportedOperationException if no delegee is
1103: * available.
1104: *
1105: * @throws SQLException if an error occurs.
1106: * @see java.sql.PreparedStatement#clearBatch
1107: */
1108: public void clearBatch() throws SQLException {
1109: if (delegee != null) {
1110: delegee.clearBatch();
1111: return;
1112: }
1113: throw new UnsupportedOperationException();
1114: }
1115:
1116: /**
1117: * Calls the <code>executeBatch</code> method on the delegee prepared
1118: * statement. Throws a UnsupportedOperationException if no delegee is
1119: * available.
1120: *
1121: * @return an <code>int[]</code> value.
1122: * @throws SQLException if an error occurs.
1123: * @see java.sql.PreparedStatement#executeBatch
1124: */
1125: public int[] executeBatch() throws SQLException {
1126: if (delegee != null) {
1127: return delegee.executeBatch();
1128: }
1129: throw new UnsupportedOperationException();
1130: }
1131:
1132: /**
1133: * Calls the <code>setTime</code> method on the delegee prepared
1134: * statement. Throws a UnsupportedOperationException if no delegee is
1135: * available.
1136: *
1137: * @param n an <code>int</code> value.
1138: * @param time a <code>Time</code> value.
1139: * @param calendar a <code>Calendar</code> value.
1140: * @throws SQLException if an error occurs.
1141: * @see java.sql.PreparedStatement#setTime
1142: */
1143: public void setTime(int n, Time time, Calendar calendar)
1144: throws SQLException {
1145: if (delegee != null) {
1146: delegee.setTime(n, time, calendar);
1147: if (deferDelegee) {
1148: maybeSave(n, SET_TIME_CALENDAR, time, calendar);
1149: }
1150: return;
1151: }
1152: throw new UnsupportedOperationException();
1153: }
1154:
1155: /**
1156: * Calls the <code>setTime</code> method on the delegee prepared
1157: * statement. Throws a UnsupportedOperationException if no delegee is
1158: * available.
1159: *
1160: * @param n an <code>int</code> value.
1161: * @param time a <code>Time</code> value.
1162: * @throws SQLException if an error occurs.
1163: * @see java.sql.PreparedStatement#setTime
1164: */
1165: public void setTime(int n, Time time) throws SQLException {
1166: if (delegee != null) {
1167: delegee.setTime(n, time);
1168: if (deferDelegee) {
1169: maybeSave(n, SET_TIME, time);
1170: }
1171: return;
1172: }
1173: throw new UnsupportedOperationException();
1174: }
1175:
1176: /**
1177: * Calls the <code>execute</code> method on the delegee prepared
1178: * statement. Throws a UnsupportedOperationException if no delegee is
1179: * available.
1180: *
1181: * @return a <code>boolean</code> value.
1182: * @throws SQLException if an error occurs.
1183: * @see java.sql.PreparedStatement#execute
1184: */
1185: public boolean execute() throws SQLException {
1186: if (delegee != null) {
1187: return delegee.execute();
1188: }
1189: throw new UnsupportedOperationException();
1190: }
1191:
1192: /**
1193: * Calls the <code>setBoolean</code> method on the delegee prepared
1194: * statement. Throws a UnsupportedOperationException if no delegee is
1195: * available.
1196: *
1197: * @param n an <code>int</code> value.
1198: * @param flag a <code>boolean</code> value.
1199: * @throws SQLException if an error occurs.
1200: * @see java.sql.PreparedStatement#setBoolean
1201: */
1202: public void setBoolean(int n, boolean flag) throws SQLException {
1203: if (delegee != null) {
1204: delegee.setBoolean(n, flag);
1205: if (deferDelegee) {
1206: maybeSave(n, SET_BOOLEAN, new Boolean(flag));
1207: }
1208: return;
1209: }
1210: throw new UnsupportedOperationException();
1211: }
1212:
1213: /**
1214: * Calls the <code>setByte</code> method on the delegee prepared
1215: * statement. Throws a UnsupportedOperationException if no delegee is
1216: * available.
1217: *
1218: * @param n an <code>int</code> value.
1219: * @param b a <code>byte</code> value.
1220: * @throws SQLException if an error occurs.
1221: * @see java.sql.PreparedStatement#setByte
1222: */
1223: public void setByte(int n, byte b) throws SQLException {
1224: if (delegee != null) {
1225: delegee.setByte(n, b);
1226: if (deferDelegee) {
1227: maybeSave(n, SET_BYTE, new Byte(b));
1228: }
1229: return;
1230: }
1231: throw new UnsupportedOperationException();
1232: }
1233:
1234: /**
1235: * Calls the <code>setShort</code> method on the delegee prepared
1236: * statement. Throws a UnsupportedOperationException if no delegee is
1237: * available.
1238: *
1239: * @param n an <code>int</code> value.
1240: * @param s a <code>short</code> value.
1241: * @throws SQLException if an error occurs.
1242: * @see java.sql.PreparedStatement#setShort
1243: */
1244: public void setShort(int n, short s) throws SQLException {
1245: if (delegee != null) {
1246: delegee.setShort(n, s);
1247: if (deferDelegee) {
1248: maybeSave(n, SET_SHORT, new Short(s));
1249: }
1250: return;
1251: }
1252: throw new UnsupportedOperationException();
1253: }
1254:
1255: /**
1256: * Calls the <code>setInt</code> method on the delegee prepared
1257: * statement. Throws a UnsupportedOperationException if no delegee is
1258: * available.
1259: *
1260: * @param n an <code>int</code> value.
1261: * @param index an <code>int</code> value.
1262: * @throws SQLException if an error occurs.
1263: * @see java.sql.PreparedStatement#setInt
1264: */
1265: public void setInt(int n, int index) throws SQLException {
1266: if (delegee != null) {
1267: delegee.setInt(n, index);
1268: if (deferDelegee) {
1269: maybeSave(n, SET_INT, new Integer(index));
1270: }
1271: return;
1272: }
1273: throw new UnsupportedOperationException();
1274: }
1275:
1276: /**
1277: * Calls either <code>setInt</code> or <code>setNull</code> on
1278: * the prepared statement, depending on the value of the object
1279: * to be stored. Throws a UnsupportedOperationException if no delegee is
1280: * available.
1281: * @param offset position of paramter in prepared statement.
1282: * @param value the value to be stored.
1283: * @throws SQLException if a database error occurs.
1284: * @see java.sql.PreparedStatement#setInt
1285: */
1286: public void setInt(int offset, Integer value) throws SQLException {
1287: if (value == null) {
1288: setNull(offset, Types.INTEGER);
1289: return;
1290: }
1291: setInt(offset, value.intValue());
1292: }
1293:
1294: /**
1295: * Calls the <code>setLong</code> method on the delegee prepared
1296: * statement. Throws a UnsupportedOperationException if no delegee is
1297: * available.
1298: *
1299: * @param n an <code>int</code> value.
1300: * @param l a <code>long</code> value.
1301: * @throws SQLException if an error occurs.
1302: * @see java.sql.PreparedStatement#setLong
1303: */
1304: public void setLong(int n, long l) throws SQLException {
1305: if (delegee != null) {
1306: delegee.setLong(n, l);
1307: if (deferDelegee) {
1308: maybeSave(n, SET_LONG, new Long(l));
1309: }
1310: return;
1311: }
1312: throw new UnsupportedOperationException();
1313: }
1314:
1315: /**
1316: * Calls either <code>setLong</code> or <code>setNull</code> on
1317: * the prepared statement, depending on the value of the object
1318: * to be stored. Throws a UnsupportedOperationException if no delegee is
1319: * available.
1320: * @param offset position of paramter in prepared statement.
1321: * @param value the value to be stored.
1322: * @throws SQLException if a database error occurs.
1323: * @see java.sql.PreparedStatement#setInt
1324: */
1325: public void setLong(int offset, Long value) throws SQLException {
1326: if (value == null) {
1327: setNull(offset, Types.INTEGER);
1328: return;
1329: }
1330: setLong(offset, value.intValue());
1331: }
1332:
1333: /**
1334: * Calls the <code>setFloat</code> method on the delegee prepared
1335: * statement. Throws a UnsupportedOperationException if no delegee is
1336: * available.
1337: *
1338: * @param n an <code>int</code> value.
1339: * @param f a <code>float</code> value.
1340: * @throws SQLException if an error occurs.
1341: * @see java.sql.PreparedStatement#setFloat
1342: */
1343: public void setFloat(int n, float f) throws SQLException {
1344: if (delegee != null) {
1345: delegee.setFloat(n, f);
1346: if (deferDelegee) {
1347: maybeSave(n, SET_FLOAT, new Float(f));
1348: }
1349: return;
1350: }
1351: throw new UnsupportedOperationException();
1352: }
1353:
1354: /**
1355: * Calls the <code>setDouble</code> method on the delegee prepared
1356: * statement. Throws a UnsupportedOperationException if no delegee is
1357: * available.
1358: *
1359: * @param n an <code>int</code> value.
1360: * @param d a <code>double</code> value.
1361: * @throws SQLException if an error occurs.
1362: * @see java.sql.PreparedStatement#setDouble
1363: */
1364: public void setDouble(int n, double d) throws SQLException {
1365: if (delegee != null) {
1366: delegee.setDouble(n, d);
1367: if (deferDelegee) {
1368: maybeSave(n, SET_DOUBLE, new Double(d));
1369: }
1370: return;
1371: }
1372: throw new UnsupportedOperationException();
1373: }
1374:
1375: /**
1376: * Calls the <code>setString</code> method on the delegee prepared
1377: * statement. Throws a UnsupportedOperationException if no delegee is
1378: * available.
1379: *
1380: * @param n an <code>int</code> value.
1381: * @param string a <code>String</code> value.
1382: * @throws SQLException if an error occurs.
1383: * @see java.sql.PreparedStatement#setString
1384: */
1385: public void setString(int n, String string) throws SQLException {
1386: if (delegee != null) {
1387: if (dbProps.fixPointBaseSetString()) {
1388: delegee.setCharacterStream(n, new StringReader(string),
1389: string.length());
1390: } else {
1391: delegee.setString(n, string);
1392: }
1393: if (deferDelegee) {
1394: maybeSave(n, SET_STRING, string);
1395: }
1396: return;
1397: }
1398: throw new UnsupportedOperationException();
1399: }
1400:
1401: /**
1402: * Calls {@link #setString <code>setString</code>} or
1403: * {@link #setClob <code>setClob</code>} depending on the driver for the
1404: * delegee prepared statement. Throws a UnsupportedOperationException if no
1405: * delegee is available.
1406: *
1407: * @param n an <code>int</code> value.
1408: * @param string a <code>String</code> value.
1409: * @throws SQLException if an error occurs.
1410: * @see java.sql.PreparedStatement#setString
1411: * @see java.sql.PreparedStatement#setClob
1412: */
1413: public void setLargeString(int n, String string)
1414: throws SQLException {
1415: if (passThrough) {
1416: setString(n, string);
1417: return;
1418: } else if (deferDelegee) {
1419: // if inputStream is null, set the column as null; if not,
1420: // set this column as empty clob.
1421: if (string == null) {
1422: setNull(n, Types.CLOB);
1423: } else {
1424: Integer index = new Integer(n);
1425: updateClobsMap.put(index, string);
1426: delegee.setClob(n, oracle.sql.CLOB.empty_lob());
1427: }
1428: return;
1429: }
1430: throw new UnsupportedOperationException();
1431: }
1432:
1433: /**
1434: * Calls the <code>setNull</code> method on the delegee prepared
1435: * statement. Throws a UnsupportedOperationException if no delegee is
1436: * available.
1437: *
1438: * @param n an <code>int</code> value.
1439: * @param index an <code>int</code> value.
1440: * @throws SQLException if an error occurs.
1441: * @see java.sql.PreparedStatement#setNull
1442: */
1443: public void setNull(int n, int index) throws SQLException {
1444: if (delegee != null) {
1445: delegee.setNull(n, index);
1446: if (deferDelegee) {
1447: maybeSave(n, SET_NULL, new Integer(index));
1448: }
1449: return;
1450: }
1451: throw new UnsupportedOperationException();
1452: }
1453:
1454: /**
1455: * Calls the <code>setNull</code> method on the delegee prepared
1456: * statement. Throws a UnsupportedOperationException if no delegee is
1457: * available.
1458: *
1459: * @param n an <code>int</code> value.
1460: * @param n1 an <code>int</code> value.
1461: * @param string a <code>String</code> value.
1462: * @throws SQLException if an error occurs.
1463: * @see java.sql.PreparedStatement#setNull
1464: */
1465: public void setNull(int n, int n1, String string)
1466: throws SQLException {
1467: if (delegee != null) {
1468: delegee.setNull(n, n1, string);
1469: if (deferDelegee) {
1470: maybeSave(n, SET_NULL_STRING, new Integer(n1), string);
1471: }
1472: return;
1473: }
1474: throw new UnsupportedOperationException();
1475: }
1476:
1477: /**
1478: * Calls the <code>setDate</code> method on the delegee prepared
1479: * statement. Throws a UnsupportedOperationException if no delegee is
1480: * available.
1481: *
1482: * @param n an <code>int</code> value.
1483: * @param date a <code>Date</code> value.
1484: * @param calendar a <code>Calendar</code> value.
1485: * @throws SQLException if an error occurs.
1486: * @see java.sql.PreparedStatement#setDate
1487: */
1488: public void setDate(int n, Date date, Calendar calendar)
1489: throws SQLException {
1490: if (delegee != null) {
1491: delegee.setDate(n, date, calendar);
1492: if (deferDelegee) {
1493: maybeSave(n, SET_DATE_CALENDAR, date, calendar);
1494: }
1495: return;
1496: }
1497: throw new UnsupportedOperationException();
1498: }
1499:
1500: /**
1501: * Calls the <code>setDate</code> method on the delegee prepared
1502: * statement. Throws a UnsupportedOperationException if no delegee is
1503: * available.
1504: *
1505: * @param n an <code>int</code> value.
1506: * @param date a <code>Date</code> value.
1507: * @throws SQLException if an error occurs.
1508: * @see java.sql.PreparedStatement#setDate
1509: */
1510: public void setDate(int n, Date date) throws SQLException {
1511: if (delegee != null) {
1512: if (date != null) {
1513: delegee.setDate(n, date);
1514: if (deferDelegee) {
1515: maybeSave(n, SET_DATE, date);
1516: }
1517: } else {
1518: setNull(n, Types.DATE);
1519: }
1520: return;
1521: }
1522: throw new UnsupportedOperationException();
1523: }
1524:
1525: /**
1526: * Calls the <code>setTimestamp</code> method on the delegee prepared
1527: * statement. Throws a UnsupportedOperationException if no delegee is
1528: * available.
1529: *
1530: * @param n an <code>int</code> value.
1531: * @param timestamp a <code>Timestamp</code> value.
1532: * @throws SQLException if an error occurs.
1533: * @see java.sql.PreparedStatement#setTimestamp
1534: */
1535: public void setTimestamp(int n, Timestamp timestamp)
1536: throws SQLException {
1537: if (delegee != null) {
1538: if (timestamp != null) {
1539: delegee.setTimestamp(n, timestamp);
1540: if (deferDelegee) {
1541: maybeSave(n, SET_TIMESTAMP, timestamp);
1542: }
1543: return;
1544: } else {
1545: setNull(n, Types.DATE);
1546: }
1547: return;
1548: }
1549: throw new UnsupportedOperationException();
1550: }
1551:
1552: /**
1553: * Calls the <code>setTimestamp</code> method on the delegee prepared
1554: * statement. Throws a UnsupportedOperationException if no delegee is
1555: * available.
1556: *
1557: * @param n an <code>int</code> value.
1558: * @param timestamp a <code>Timestamp</code> value.
1559: * @param calendar a <code>Calendar</code> value.
1560: * @throws SQLException if an error occurs.
1561: * @see java.sql.PreparedStatement#setTimestamp
1562: */
1563: public void setTimestamp(int n, Timestamp timestamp,
1564: Calendar calendar) throws SQLException {
1565: if (delegee != null) {
1566: delegee.setTimestamp(n, timestamp, calendar);
1567: if (deferDelegee) {
1568: maybeSave(n, SET_TIMESTAMP_CALENDAR, timestamp,
1569: calendar);
1570: }
1571: return;
1572: }
1573: throw new UnsupportedOperationException();
1574: }
1575:
1576: /**
1577: * Calls {@link #setBinaryStream <code>setBinaryStream</code>} or
1578: * {@link #setBlob <code>setBlob</code>} depends on the driver for the
1579: * delegee prepared statement. Throws a UnsupportedOperationException if no
1580: * delegee is available.
1581: *
1582: * @param n an <code>int</code> value.
1583: * @param inputStream an <code>InputStream</code> value.
1584: * @param n1 an <code>int</code> value.
1585: * @throws SQLException if an error occurs.
1586: * @see java.sql.PreparedStatement#setBinaryStream
1587: * @see java.sql.PreparedStatement#setBlob
1588: */
1589: public void setBinaryStream(int n, InputStream inputStream, int n1)
1590: throws SQLException {
1591: if (delegee != null) {
1592: if (passThrough) {
1593: delegee.setBinaryStream(n, inputStream, n1);
1594: return;
1595: } else if (deferDelegee) {
1596: // if inputStream is null, set the column as null; if not,
1597: // set this column as empty blob.
1598: if (inputStream == null) {
1599: setNull(n, Types.BLOB);
1600: } else {
1601: Integer index = new Integer(n);
1602: updateBlobsMap.put(index, inputStream);
1603: delegee.setBlob(n, oracle.sql.BLOB.empty_lob());
1604: }
1605: return;
1606: }
1607: }
1608: throw new UnsupportedOperationException();
1609: }
1610:
1611: /**
1612: * Store the object. Uses {@link #setBytes <code>setBytes</code>}
1613: * or {@link #setBinaryStream <code>setBinaryStream</code>}
1614: * as appropriate for the driver. Throws a UnsupportedOperationException if
1615: * no delegee is available.
1616: *
1617: * @param offset an int offset for the PreparedStatement
1618: * @param data an Object
1619: * @throws IOException any of the usual Input/Output related exceptions.
1620: * @throws SQLException if a sql error occurs.
1621: */
1622: public void setBinary(int offset, Object data) throws IOException,
1623: SQLException {
1624: if (delegee != null) {
1625: if (data == null) {
1626: if (passThrough) {
1627: setNull(offset, Types.BINARY);
1628: return;
1629: }
1630: if (deferDelegee) {
1631: setNull(offset, Types.BLOB);
1632: return;
1633: }
1634: throw new UnsupportedOperationException();
1635: }
1636: if (dbProps.isOracle()) {
1637: // defer delegee
1638: Integer index = new Integer(offset);
1639: updateBlobsMap.put(index, data);
1640: delegee.setBlob(offset, oracle.sql.BLOB.empty_lob());
1641: return;
1642: }
1643: ByteArrayOutputStream baos = new ByteArrayOutputStream();
1644: ObjectOutputStream oos = new ObjectOutputStream(baos);
1645: oos.writeObject(data);
1646: oos.flush();
1647: oos.close();
1648: // serialize the data object into a byte array
1649: byte[] dataAsBytes = baos.toByteArray();
1650: if (dbProps.isHsqldb()) {
1651: delegee.setBytes(offset, dataAsBytes);
1652: } else {
1653: // pass through
1654: ByteArrayInputStream bais = new ByteArrayInputStream(
1655: dataAsBytes);
1656: // bind our byte array to the emp column
1657: delegee.setBinaryStream(offset, bais,
1658: dataAsBytes.length);
1659: }
1660: return;
1661: }
1662: throw new UnsupportedOperationException();
1663: }
1664:
1665: /**
1666: * Calls the <code>executeQuery</code> method on the delegee prepared
1667: * statement. Throws a UnsupportedOperationException if no delegee is
1668: * available.
1669: *
1670: * @return a <code>ResultSet</code> value.
1671: * @throws SQLException if an error occurs.
1672: * @see java.sql.PreparedStatement#executeQuery
1673: */
1674: public ResultSet executeQuery() throws SQLException {
1675: if (delegee != null) {
1676: return delegee.executeQuery();
1677: }
1678: throw new UnsupportedOperationException();
1679: }
1680:
1681: /**
1682: * Calls the <code>getMetaData</code> method on the delegee prepared
1683: * statement. Throws a UnsupportedOperationException if no delegee is
1684: * available.
1685: *
1686: * @return a <code>ResultSetMetaData</code> value.
1687: * @throws SQLException if an error occurs
1688: * @see java.sql.PreparedStatement#getMetaData
1689: */
1690: public ResultSetMetaData getMetaData() throws SQLException {
1691: if (delegee != null) {
1692: return delegee.getMetaData();
1693: }
1694: throw new UnsupportedOperationException();
1695: }
1696:
1697: /**
1698: * Calls the <code>executeUpdate</code> method on the delegee prepared
1699: * statement and then execute the builded selectForUpdate statement to
1700: * lob datas. Throws a UnsupportedOperationException if no delegee is
1701: * available.
1702: *
1703: * @return an <code>int</code> value
1704: * @throws SQLException if an error occurs
1705: */
1706: public int executeUpdate() throws SQLException {
1707: // not supported database
1708: if (delegee == null) {
1709: throw new UnsupportedOperationException();
1710: }
1711: if (passThrough) {
1712: return delegee.executeUpdate();
1713: }
1714: try {
1715: if (deferDelegee
1716: && ((updateClobsMap == null) || (updateClobsMap
1717: .isEmpty()))
1718: && ((updateBlobsMap == null) || (updateBlobsMap
1719: .isEmpty()))) {
1720: return delegee.executeUpdate();
1721: }
1722:
1723: boolean autocommit = false;
1724: PreparedStatement prepStmt = null;
1725: ResultSet rs = null;
1726: try {
1727: // Work around a bug in jboss-3.0.6: autocommit should
1728: // be false on connections used in ejbStore, but it is
1729: // not
1730: if (con.getAutoCommit()
1731: && !(con.getClass().getName()
1732: .startsWith("org.jboss.resource.adapter.jdbc"))) {
1733: autocommit = true;
1734: if (logger.isDebugEnabled()) {
1735: logger
1736: .debug("Resetting connection autocommit for "
1737: + con);
1738: }
1739: con.setAutoCommit(false);
1740: }
1741: if (logger.isDebugEnabled()) {
1742: logger.debug("Executing default query: " + stmt);
1743: }
1744: // first execute insert/update statement for non-lobs
1745: // and empty lobs.
1746: int returncode = delegee.executeUpdate();
1747: // Safety check ...
1748: if (returncode == 0 && deferredInsert) {
1749: throw new SQLException("Statement \"" + stmt
1750: + "\" did not result in row being inserted");
1751: }
1752: // if update didn't update any rows, probably nothing
1753: // matched WHERE clause.
1754: if (returncode == 0) {
1755: if (logger.isDebugEnabled()) {
1756: logger
1757: .debug("Not updating clob or blob data because"
1758: + " update of regular columns returned 0.");
1759: }
1760: return returncode;
1761: }
1762: // do select for updating clob and blob data.
1763: prepStmt = buildSelectForUpdateStmt();
1764: // get the lob locator into a result set.
1765: rs = executeSelectForUpdateStmt(prepStmt);
1766: if (!rs.next()) {
1767: throw new SQLException(
1768: "updating clob and blob data failed");
1769: }
1770: writeLobs(rs);
1771: if (rs.next()) {
1772: throw new IllegalStateException(
1773: "Ambiguous selection of LOBs for update. "
1774: + "Verify key field specification.");
1775: }
1776: return returncode;
1777: } catch (IOException e) {
1778: logger.error(e.getMessage(), e);
1779: throw new SQLException(e.getMessage());
1780: } finally {
1781: // restore the autocommit of the connection.
1782: if (autocommit) {
1783: con.commit();
1784: con.setAutoCommit(autocommit);
1785: }
1786: if (rs != null) {
1787: rs.close();
1788: }
1789: if (prepStmt != null) {
1790: prepStmt.close();
1791: }
1792: }
1793: } finally {
1794: updateClobsMap.clear();
1795: updateBlobsMap.clear();
1796: keyValues.clear();
1797: }
1798: }
1799:
1800: private void writeLobs(ResultSet rs) throws IOException,
1801: SQLException {
1802: try {
1803: // Get the blob data - cast to OracleResult set to
1804: // retrieve the data in oracle.sql format.
1805: int index = 1;
1806: if (updateClobsMap != null) {
1807: Iterator clobit = updateClobsMap.values().iterator();
1808: while (clobit.hasNext()) {
1809: Clob clob = rs.getClob(index);
1810: Writer out = null;
1811: if (clob instanceof oracle.sql.CLOB) {
1812: out = ((oracle.sql.CLOB) clob)
1813: .getCharacterOutputStream();
1814: } else if (thinClobClass != null
1815: && (thinClobClass.isAssignableFrom(clob
1816: .getClass()))) {
1817: out = (Writer) thinClobGetCharacterOS.invoke(
1818: clob, new Object[0]);
1819: } else {
1820: throw new UnsupportedOperationException(
1821: "Unsupported Clob implementation: "
1822: + clob.getClass().getName());
1823: }
1824: out.write(((String) clobit.next()).toCharArray());
1825: out.flush();
1826: out.close();
1827: index++;
1828: }
1829: }
1830: if (updateBlobsMap != null) {
1831: Iterator blobit = updateBlobsMap.values().iterator();
1832: while (blobit.hasNext()) {
1833: Blob blob = rs.getBlob(index);
1834: OutputStream out = null;
1835: int bufferSize = 4096;
1836: if (blob instanceof oracle.sql.BLOB) {
1837: out = ((oracle.sql.BLOB) blob)
1838: .getBinaryOutputStream();
1839: bufferSize = ((oracle.sql.BLOB) blob)
1840: .getBufferSize();
1841: } else if (thinBlobClass != null
1842: && (thinBlobClass.isAssignableFrom(blob
1843: .getClass()))) {
1844: out = (OutputStream) thinBlobGetBinaryOS
1845: .invoke(blob, new Object[0]);
1846: bufferSize = ((Integer) thinBlobGetBufferSize
1847: .invoke(blob, new Object[0]))
1848: .intValue();
1849: } else {
1850: throw new UnsupportedOperationException(
1851: "Unsupported Blob implementation: "
1852: + blob.getClass().getName());
1853: }
1854: Object data = blobit.next();
1855: if (data instanceof InputStream) {
1856: InputStream dataStream = (InputStream) data;
1857: byte[] buffer = new byte[bufferSize];
1858: int length;
1859: while ((length = dataStream.read(buffer)) != -1) {
1860: out.write(buffer, 0, length);
1861: }
1862: dataStream.close();
1863: } else {
1864: // write data direct in outputstream.
1865: out = new ObjectOutputStream(out);
1866: ((ObjectOutputStream) out).writeObject(data);
1867: }
1868: out.flush();
1869: out.close();
1870: index++;
1871: }
1872: }
1873: } catch (SecurityException e) {
1874: // from method invocation, shouldn't happen
1875: logger.error("Cannot access method: " + e.getMessage());
1876: throw new UnsupportedOperationException(e.getMessage());
1877: } catch (IllegalAccessException e) {
1878: // from method invocation, shouldn't happen
1879: logger.error("Cannot access method: " + e.getMessage());
1880: throw new UnsupportedOperationException(e.getMessage());
1881: } catch (InvocationTargetException e) {
1882: // from method invocation, shouldn't happen
1883: logger.error("Cannot access method: " + e.getMessage());
1884: throw new UnsupportedOperationException(e.getMessage());
1885: }
1886: }
1887:
1888: /**
1889: * Calls the <code>setBigDecimal</code> method on the delegee prepared
1890: * statement. Throws a UnsupportedOperationException if no delegee is
1891: * available.
1892: *
1893: * @param n an <code>int</code> value.
1894: * @param bigDecimal a <code>BigDecimal</code> value.
1895: * @throws SQLException if an error occurs.
1896: * @see java.sql.PreparedStatement#setBigDecimal
1897: */
1898: public void setBigDecimal(int n, BigDecimal bigDecimal)
1899: throws SQLException {
1900: if (delegee != null) {
1901: delegee.setBigDecimal(n, bigDecimal);
1902: if (deferDelegee) {
1903: maybeSave(n, SET_BIGDECIMAL, bigDecimal);
1904: }
1905: return;
1906: }
1907: throw new UnsupportedOperationException();
1908: }
1909:
1910: /**
1911: * Store the object. Uses {@link #setBytes <code>setBytes</code>}
1912: * or {@link #setBlob <code>setBlob</code>} depending on the driver for
1913: * the delegee prepared statement. Throws a UnsupportedOperationException
1914: * if no delegee is available.
1915: *
1916: * @param n an <code>int</code> value.
1917: * @param byteArray a <code>byte[]</code> value.
1918: * @throws SQLException if an error occurs.
1919: * @see java.sql.PreparedStatement#setBytes
1920: */
1921: public void setBytes(int n, byte[] byteArray) throws SQLException {
1922: if (delegee != null) {
1923: if (passThrough || byteArray == null
1924: || byteArray.length == 0) {
1925: delegee.setBytes(n, byteArray);
1926: return;
1927: } else if (deferDelegee) {
1928: Integer index = new Integer(n);
1929: updateBlobsMap.put(index, byteArray);
1930: delegee.setBlob(n, oracle.sql.BLOB.empty_lob());
1931: return;
1932: }
1933: }
1934: throw new UnsupportedOperationException();
1935: }
1936:
1937: /**
1938: * Calls the <code>setAsciiStream</code> method on the delegee prepared
1939: * statement. Throws a UnsupportedOperationException if no delegee is
1940: * available.
1941: *
1942: * @param n an <code>int</code> value
1943: * @param inputStream an <code>InputStream</code> value.
1944: * @param n1 an <code>int</code> value.
1945: * @throws SQLException if an error occurs.
1946: * @see java.sql.PreparedStatement#setAsciiStream
1947: */
1948: public void setAsciiStream(int n, InputStream inputStream, int n1)
1949: throws SQLException {
1950: if (delegee != null) {
1951: delegee.setAsciiStream(n, inputStream, n1);
1952: return;
1953: }
1954: throw new UnsupportedOperationException();
1955: }
1956:
1957: /**
1958: * Calls the <code>setUnicodeStream</code> method on the delegee prepared
1959: * statement. Throws a UnsupportedOperationException if no delegee is
1960: * available.
1961: *
1962: * @param n an <code>int</code> value.
1963: * @param inputStream an <code>InputStream</code> value.
1964: * @param n1 an <code>int</code> value.
1965: * @throws SQLException if an error occurs.
1966: * @see java.sql.PreparedStatement#setUnicodeStream
1967: */
1968: public void setUnicodeStream(int n, InputStream inputStream, int n1)
1969: throws SQLException {
1970: if (delegee != null) {
1971: delegee.setUnicodeStream(n, inputStream, n1);
1972: return;
1973: }
1974: throw new UnsupportedOperationException();
1975: }
1976:
1977: /**
1978: * Calls the <code>clearParameters</code> method on the delegee prepared
1979: * statement. Throws a UnsupportedOperationException if no delegee is
1980: * available.
1981: *
1982: * @throws SQLException if an error occurs.
1983: * @see java.sql.PreparedStatement#clearParameters
1984: */
1985: public void clearParameters() throws SQLException {
1986: if (delegee != null) {
1987: delegee.clearParameters();
1988: return;
1989: }
1990: throw new UnsupportedOperationException();
1991: }
1992:
1993: /**
1994: * Calls the <code>setObject</code> method on the delegee prepared
1995: * statement. Throws a UnsupportedOperationException if no delegee is
1996: * available.
1997: *
1998: * @param n an <code>int</code> value.
1999: * @param object an <code>Object</code> value.
2000: * @param n1 an <code>int</code> value.
2001: * @param n2 an <code>int</code> value.
2002: * @throws SQLException if an error occurs.
2003: * @see java.sql.PreparedStatement#setObject
2004: */
2005: public void setObject(int n, Object object, int n1, int n2)
2006: throws SQLException {
2007: if (delegee != null) {
2008: delegee.setObject(n, object, n1, n2);
2009: return;
2010: }
2011: throw new UnsupportedOperationException();
2012: }
2013:
2014: /**
2015: * Calls the <code>setObject</code> method on the delegee prepared
2016: * statement. Throws a UnsupportedOperationException if no delegee is
2017: * available.
2018: *
2019: * @param n an <code>int</code> value.
2020: * @param object an <code>Object</code> value.
2021: * @param n1 an <code>int</code> value.
2022: * @throws SQLException if an error occurs.
2023: * @see java.sql.PreparedStatement#setObject
2024: */
2025: public void setObject(int n, Object object, int n1)
2026: throws SQLException {
2027: if (delegee != null) {
2028: delegee.setObject(n, object, n1);
2029: return;
2030: }
2031: throw new UnsupportedOperationException();
2032: }
2033:
2034: /**
2035: * Delegates to <code>setLargeString</code> if <code>object</code>
2036: * is of type <code>String</code> and the driver requires special
2037: * handling of large strings. Else calls the
2038: * <code>setObject</code> method on the delegee prepared
2039: * statement. Throws a UnsupportedOperationException if no delegee
2040: * is available.
2041: *
2042: * @param n an <code>int</code> value.
2043: * @param object an <code>Object</code> value.
2044: * @throws SQLException if an error occurs.
2045: * @see java.sql.PreparedStatement#setObject
2046: */
2047: public void setObject(int n, Object object) throws SQLException {
2048: if (!passThrough && (object instanceof String)) {
2049: setLargeString(n, (String) object);
2050: }
2051: if (delegee != null) {
2052: delegee.setObject(n, object);
2053: return;
2054: }
2055: throw new UnsupportedOperationException();
2056: }
2057:
2058: /**
2059: * Calls the <code>addBatch</code> method on the delegee prepared
2060: * statement. Throws a UnsupportedOperationException if no delegee is
2061: * available.
2062: *
2063: * @throws SQLException if an error occurs.
2064: * @see java.sql.PreparedStatement#addBatch
2065: */
2066: public void addBatch() throws SQLException {
2067: if (delegee != null) {
2068: delegee.addBatch();
2069: return;
2070: }
2071: throw new UnsupportedOperationException();
2072: }
2073:
2074: /**
2075: * Calls the <code>setCharacterStream</code> method on the delegee prepared
2076: * statement. Throws a UnsupportedOperationException if no delegee is
2077: * available.
2078: *
2079: * @param n an <code>int</code> value.
2080: * @param reader a <code>Reader</code> value.
2081: * @param n1 an <code>int</code> value.
2082: * @throws SQLException if an error occurs.
2083: * @see java.sql.PreparedStatement#setCharacterStream
2084: */
2085: public void setCharacterStream(int n, Reader reader, int n1)
2086: throws SQLException {
2087: if (delegee != null) {
2088: delegee.setCharacterStream(n, reader, n1);
2089: return;
2090: }
2091: throw new UnsupportedOperationException();
2092: }
2093:
2094: /**
2095: * Calls the <code>setRef</code> method on the delegee prepared
2096: * statement. Throws a UnsupportedOperationException if no delegee is
2097: * available.
2098: *
2099: * @param n an <code>int</code> value.
2100: * @param ref a <code>Ref</code> value.
2101: * @throws SQLException if an error occurs.
2102: * @see java.sql.PreparedStatement#setRef
2103: */
2104: public void setRef(int n, Ref ref) throws SQLException {
2105: if (delegee != null) {
2106: delegee.setRef(n, ref);
2107: return;
2108: }
2109: throw new UnsupportedOperationException();
2110: }
2111:
2112: /**
2113: * Calls the <code>setBlob</code> method on the delegee prepared
2114: * statement. Throws a UnsupportedOperationException if no delegee is
2115: * available.
2116: *
2117: * @param n an <code>int</code> value.
2118: * @param blob a <code>Blob</code> value.
2119: * @throws SQLException if an error occurs.
2120: * @see java.sql.PreparedStatement#setBlob
2121: */
2122: public void setBlob(int n, Blob blob) throws SQLException {
2123: if (delegee != null) {
2124: delegee.setBlob(n, blob);
2125: return;
2126: }
2127: throw new UnsupportedOperationException();
2128: }
2129:
2130: /**
2131: * Calls the <code>setClob</code> method on the delegee prepared
2132: * statement. Throws a UnsupportedOperationException if no delegee is
2133: * available.
2134: *
2135: * @param n an <code>int</code> value.
2136: * @param clob a <code>Clob</code> value.
2137: * @throws SQLException if an error occurs.
2138: * @see java.sql.PreparedStatement#setClob
2139: */
2140: public void setClob(int n, Clob clob) throws SQLException {
2141: if (delegee != null) {
2142: delegee.setClob(n, clob);
2143: return;
2144: }
2145: throw new UnsupportedOperationException();
2146: }
2147:
2148: /**
2149: * Calls the <code>setArray</code> method on the delegee prepared
2150: * statement. Throws a UnsupportedOperationException if no delegee is
2151: * available.
2152: *
2153: * @param n an <code>int</code> value.
2154: * @param array an <code>Array</code> value.
2155: * @throws SQLException if an error occurs.
2156: * @see java.sql.PreparedStatement#setArray
2157: */
2158: public void setArray(int n, Array array) throws SQLException {
2159: if (delegee != null) {
2160: delegee.setArray(n, array);
2161: return;
2162: }
2163: throw new UnsupportedOperationException();
2164: }
2165:
2166: /**
2167: * Calls the <code>setURL</code> method on the delegee prepared
2168: * statement. Throws a UnsupportedOperationException if no delegee is
2169: * available.
2170: *
2171: * @param parameterIndex an <code>int</code> value
2172: * @param x an <code>URL</code> value
2173: * @exception SQLException if an error occurs.
2174: * @see java.sql.PreparedStatement#setURL
2175: */
2176: public void setURL(int parameterIndex, URL x) throws SQLException {
2177: if (delegee != null) {
2178: delegee.setURL(parameterIndex, x);
2179: return;
2180: }
2181: throw new UnsupportedOperationException();
2182: }
2183:
2184: /**
2185: * Calls the <code>getParameterMetaData</code> method on the
2186: * delegee prepared statement. Throws a
2187: * UnsupportedOperationException if no delegee is available.
2188: *
2189: * @return the result.
2190: * @throws SQLException if an error occurs.
2191: * @see java.sql.PreparedStatement#getParameterMetaData
2192: */
2193: public ParameterMetaData getParameterMetaData() throws SQLException {
2194: if (delegee != null) {
2195: return delegee.getParameterMetaData();
2196: }
2197: throw new UnsupportedOperationException();
2198: }
2199:
2200: /**
2201: * Do specific preparation for oracle before getting delegee.
2202: * @param con the connection to be used.
2203: * @param stmt the statement to be executed.
2204: * @throws IllegalArgumentException if the statement cannot be parsed.
2205: */
2206: private PreparedStatement getOraclePrepareStatement(Connection con,
2207: String statement) throws IllegalArgumentException,
2208: SQLException {
2209: if (statement == null || statement.equals("")) {
2210: throw new IllegalArgumentException();
2211: }
2212: // analyse the statement and set up the mapping of column number
2213: // and column name.
2214: String stmt = statement.trim().toUpperCase();
2215: if (!stmt.startsWith("INSERT") && !stmt.startsWith("UPDATE")) {
2216: passThrough = true;
2217: return con.prepareStatement(stmt);
2218: }
2219:
2220: deferDelegee = true;
2221: if (stmt.startsWith("INSERT")) {
2222: deferredInsert = true;
2223: parseInsertStatement(stmt);
2224: } else {
2225: deferredInsert = false;
2226: parseUpdateStatement(stmt);
2227: }
2228: updateClobsMap = new TreeMap();
2229: updateBlobsMap = new TreeMap();
2230: return con.prepareStatement(stmt);
2231: }
2232:
2233: // analyse the insert statement and set up the mapping of column number
2234: // and column name.
2235: private void parseInsertStatement(String stmt)
2236: throws IllegalArgumentException {
2237: // collect all the columns in the statement as
2238: // "INSERT INTO <tablename> (<1.column>, <2.column>, ...)"
2239: dataCols = new ArrayList();
2240: String colnames = substring(stmt, "(", ")");
2241: StringTokenizer st = new StringTokenizer(colnames, ",");
2242: while (st.hasMoreTokens()) {
2243: String colname = st.nextToken().trim();
2244: if (primaryKeyColumns == null) {
2245: // use 1. column as the default primary key column
2246: primaryKeyColumns = new String[] { colname };
2247: }
2248: dataCols.add(colname);
2249: }
2250: tableName = substring(stmt, "INTO ", "(").trim();
2251: }
2252:
2253: // analyse the update statement and set up the mapping of column number
2254: // and column name.
2255: private void parseUpdateStatement(String stmt) {
2256: // reset the primary key column names.
2257: primaryKeyColumns = null;
2258: // collect all the columns in the statement as
2259: // "UPDATE <tablename> SET <1.column> = ?, <2.column> = ?, ... WHERE"
2260: // get the columns between SET and WHERE of the statement
2261: String columnNames = substring(stmt, " SET ", " WHERE ");
2262: columnNames = columnNames.replace('?', '\b');
2263: columnNames = columnNames.replace(',', '\b');
2264: dataCols = new ArrayList();
2265: allCols = new ArrayList();
2266: StringTokenizer st = new StringTokenizer(columnNames.trim(),
2267: "=");
2268: while (st.hasMoreTokens()) {
2269: String colname = st.nextToken().trim();
2270: dataCols.add(colname);
2271: allCols.add(colname);
2272: }
2273: // find out the table name
2274: tableName = substring(stmt, "UPDATE ", " SET ").trim();
2275: // cache the where clause of update statement
2276: int posOfWhere = stmt.indexOf(" WHERE ");
2277: updateWhereClause = stmt.substring(posOfWhere).trim();
2278: // get the columns in the where clause
2279: String whereColNames = stmt.substring(posOfWhere
2280: + " WHERE ".length());
2281: whereColNames = whereColNames.replace('?', '\b').trim();
2282: st = new StringTokenizer(whereColNames.trim(), " =");
2283: while (st.hasMoreTokens()) {
2284: String acolname = st.nextToken().trim();
2285: if (acolname.equals("") || acolname.equals("AND")
2286: || acolname.equals("OR") || acolname.equals("IS")
2287: || acolname.equals("NULL")) {
2288: continue;
2289: }
2290: allCols.add(acolname);
2291: }
2292: }
2293:
2294: private void maybeSave(int index, int methodType, Object value1) {
2295: maybeSave(index, methodType, value1, null);
2296: }
2297:
2298: private void maybeSave(int index, int methodType, Object value1,
2299: Object value2) {
2300: if (primaryKeyColumns == null) {
2301: // Update Statement
2302: if (index <= dataCols.size()) {
2303: // value of set columns of update statement, do not need
2304: // to cache
2305: return;
2306: }
2307: // columns in the where clause, needs to be cached
2308: keyValues.add(new SaveColumn(methodType, value1, value2));
2309: } else {
2310: // insert Statement
2311: String acolumnName = (String) dataCols.get(index - 1);
2312: // Check the column name if it is primary key.
2313: for (int i = 0; i < primaryKeyColumns.length; i++) {
2314: if (primaryKeyColumns[i].equalsIgnoreCase(acolumnName)) {
2315: keyValues.add(new SaveColumn(methodType, value1,
2316: value2));
2317: break;
2318: }
2319: }
2320: }
2321: return;
2322: }
2323:
2324: /**
2325: * after the insert/update statement with empty lobs executed, needs to
2326: * build and execute selectForUpdate statement so that the locators of
2327: * lobs can be got into a result set. After the locators be selected,
2328: * the lob data can be retrieved.
2329: */
2330: private PreparedStatement buildSelectForUpdateStmt()
2331: throws SQLException {
2332: StringBuffer selectForUpdateStmt = new StringBuffer("SELECT "
2333: + selectedLOBColumns(updateClobsMap)
2334: + selectedLOBColumns(updateBlobsMap));
2335: // remove trailing ", "
2336: selectForUpdateStmt.setLength(selectForUpdateStmt.length() - 2);
2337: selectForUpdateStmt.append(" FROM " + tableName + " ");
2338: if (primaryKeyColumns == null) {
2339: // if in the first update statement executed, use its where clause
2340: // in the statement of select for update.
2341: selectForUpdateStmt.append(updateWhereClause);
2342: } else {
2343: // if in the first insert statement executed, use primary key in
2344: // the statement of select for update.
2345: selectForUpdateStmt.append(" WHERE ");
2346: int index = 0;
2347: for (int i = 0; i < primaryKeyColumns.length; i++) {
2348: String primaryKey = primaryKeyColumns[i];
2349: if (index > 0) {
2350: selectForUpdateStmt.append("AND ");
2351: }
2352: selectForUpdateStmt
2353: .append(((SaveColumn) keyValues.get(index)).methodType == SET_NULL ? (primaryKey + " IS NULL ")
2354: : (primaryKey + " = ? "));
2355: index += 1;
2356: }
2357: }
2358: selectForUpdateStmt.append(" FOR UPDATE");
2359: if (logger.isDebugEnabled()) {
2360: logger.debug("LOB access query: " + selectForUpdateStmt);
2361: }
2362: PreparedStatement prepStmt = con
2363: .prepareStatement(selectForUpdateStmt.toString());
2364: return prepStmt;
2365: }
2366:
2367: /**
2368: * execute the selectForUpdate statement. All the parameters in the where
2369: * clause must be setted using the cached values.
2370: */
2371: private ResultSet executeSelectForUpdateStmt(
2372: PreparedStatement prepStmt) throws SQLException {
2373: Iterator it = keyValues.iterator();
2374: int index = 1;
2375: while (it.hasNext()) {
2376: SaveColumn saveColumn = (SaveColumn) it.next();
2377: // determine to use which method to set the cached value.
2378: switch (saveColumn.methodType) {
2379: case SET_INT:
2380: prepStmt.setInt(index++, ((Integer) saveColumn.value1)
2381: .intValue());
2382: break;
2383: case SET_SHORT:
2384: prepStmt.setShort(index++, ((Short) saveColumn.value1)
2385: .shortValue());
2386: break;
2387: case SET_LONG:
2388: prepStmt.setLong(index++, ((Long) saveColumn.value1)
2389: .longValue());
2390: break;
2391: case SET_FLOAT:
2392: prepStmt.setFloat(index++, ((Float) saveColumn.value1)
2393: .floatValue());
2394: break;
2395: case SET_DOUBLE:
2396: prepStmt.setDouble(index++,
2397: ((Double) saveColumn.value1).doubleValue());
2398: break;
2399: case SET_BIGDECIMAL:
2400: prepStmt.setBigDecimal(index++,
2401: (BigDecimal) saveColumn.value1);
2402: break;
2403: case SET_BOOLEAN:
2404: prepStmt.setBoolean(index++,
2405: ((Boolean) saveColumn.value1).booleanValue());
2406: break;
2407: case SET_BYTE:
2408: prepStmt.setByte(index++, ((Byte) saveColumn.value1)
2409: .byteValue());
2410: break;
2411: case SET_STRING:
2412: String stringValue = (String) saveColumn.value1;
2413: if (logger.isDebugEnabled()) {
2414: logger.debug("LOB access query: setString(" + index
2415: + ", " + stringValue + ")");
2416: }
2417: prepStmt.setString(index++, stringValue);
2418: break;
2419: case SET_DATE:
2420: prepStmt.setDate(index++, (Date) saveColumn.value1);
2421: break;
2422: case SET_DATE_CALENDAR:
2423: prepStmt.setDate(index++, (Date) saveColumn.value1,
2424: (Calendar) saveColumn.value2);
2425: break;
2426: case SET_TIME:
2427: prepStmt.setTime(index++, (Time) saveColumn.value1);
2428: break;
2429: case SET_TIME_CALENDAR:
2430: prepStmt.setTime(index++, (Time) saveColumn.value1,
2431: (Calendar) saveColumn.value2);
2432: break;
2433: case SET_TIMESTAMP:
2434: prepStmt.setTimestamp(index++,
2435: (Timestamp) saveColumn.value1);
2436: break;
2437: case SET_TIMESTAMP_CALENDAR:
2438: prepStmt.setTimestamp(index++,
2439: (Timestamp) saveColumn.value1,
2440: (Calendar) saveColumn.value2);
2441: break;
2442: case SET_NULL:
2443: if (primaryKeyColumns == null) {
2444: prepStmt.setNull(index++,
2445: ((Integer) saveColumn.value1).intValue());
2446: }
2447: break;
2448: case SET_NULL_STRING:
2449: prepStmt.setNull(index++, ((Integer) saveColumn.value1)
2450: .intValue(), (String) saveColumn.value2);
2451: break;
2452: default:
2453: throw new UnsupportedOperationException();
2454: }
2455: }
2456: ResultSet rs = prepStmt.executeQuery();
2457: return rs;
2458: }
2459:
2460: // build the comma separated string of lob names.
2461: private String selectedLOBColumns(Map aMap) {
2462: String lobCloumns = "";
2463: if ((aMap == null) || (aMap.isEmpty())) {
2464: // return empty string
2465: return lobCloumns;
2466: }
2467: Iterator it = aMap.keySet().iterator();
2468: while (it.hasNext()) {
2469: Integer index = (Integer) it.next();
2470: if (aMap.get(index) == null) {
2471: // if the value of this map is null
2472: break;
2473: }
2474: String columnName = (String) dataCols
2475: .get(index.intValue() - 1);
2476: lobCloumns += columnName + ", ";
2477: }
2478: return lobCloumns;
2479: }
2480:
2481: // get the substring between the begin string and the end string in
2482: // the sql statement. The end string is the last occurrence in the
2483: // statement.
2484: private String substring(String str, String beginStr, String endStr) {
2485: int posOfBeginStr = str.indexOf(beginStr);
2486: int posOfEndStr = str.indexOf(endStr);
2487: return str.substring(posOfBeginStr + beginStr.length(),
2488: posOfEndStr);
2489: }
2490:
2491: }
|