Source Code Cross Referenced for PreparedStatement.java in  » Database-JDBC-Connection-Pool » sequoia-2.10.9 » org » continuent » sequoia » driver » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » sequoia 2.10.9 » org.continuent.sequoia.driver 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * Sequoia: Database clustering technology.
0003:         * Copyright (C) 2002-2004 French National Institute For Research In Computer
0004:         * Science And Control (INRIA).
0005:         * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
0006:         * Contact: sequoia@continuent.org
0007:         * 
0008:         * Licensed under the Apache License, Version 2.0 (the "License");
0009:         * you may not use this file except in compliance with the License.
0010:         * You may obtain a copy of the License at
0011:         * 
0012:         * http://www.apache.org/licenses/LICENSE-2.0
0013:         * 
0014:         * Unless required by applicable law or agreed to in writing, software
0015:         * distributed under the License is distributed on an "AS IS" BASIS,
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:         * See the License for the specific language governing permissions and
0018:         * limitations under the License. 
0019:         *
0020:         * Initial developer(s): Emmanuel Cecchet.
0021:         * Contributor(s): Nicolas Modrzyk, Jaco Swart.
0022:         */package org.continuent.sequoia.driver;
0023:
0024:        import java.io.ByteArrayOutputStream;
0025:        import java.io.IOException;
0026:        import java.io.InputStream;
0027:        import java.io.ObjectOutputStream;
0028:        import java.io.Serializable;
0029:        import java.math.BigDecimal;
0030:        import java.sql.Array;
0031:        import java.sql.BatchUpdateException;
0032:        import java.sql.Blob;
0033:        import java.sql.Date;
0034:        import java.sql.ParameterMetaData;
0035:        import java.sql.Ref;
0036:        import java.sql.SQLException;
0037:        import java.sql.Time;
0038:        import java.sql.Timestamp;
0039:        import java.sql.Types;
0040:        import java.util.LinkedList;
0041:        import java.util.Vector;
0042:
0043:        import org.continuent.sequoia.common.exceptions.NotImplementedException;
0044:        import org.continuent.sequoia.common.protocol.PreparedStatementSerialization;
0045:        import org.continuent.sequoia.common.sql.filters.AbstractBlobFilter;
0046:        import org.continuent.sequoia.common.util.Strings;
0047:
0048:        /**
0049:         * A SQL Statement is pre-compiled and stored in a
0050:         * <code>PreparedStatement</code> object. This object can then be used to
0051:         * efficiently execute this statement multiple times.
0052:         * <p>
0053:         * <b>Note: </b> The setXXX methods for setting IN parameter values must specify
0054:         * types that are compatible with the defined SQL type of the input parameter.
0055:         * For instance, if the IN parameter has SQL type Integer, then setInt should be
0056:         * used.
0057:         * <p>
0058:         * If arbitrary parameter type conversions are required, then the setObject
0059:         * method should be used with a target SQL type.
0060:         * <p>
0061:         * In the old days, this was just a dirty copy/paste from the PostgreSQL driver.
0062:         * Some irrelevant comments are left-over here and there.
0063:         * <p>
0064:         * This class could maybe be splitted into DriverProcessedPreparedStatement and
0065:         * ProxyModeProcessedStatement
0066:         * 
0067:         * @see DriverResultSet
0068:         * @see java.sql.PreparedStatement
0069:         * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
0070:         * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
0071:         * @author <a href="mailto:marc.wick@monte-bre.ch">Marc Wick </a>
0072:         * @author <a href="mailto:jaco.swart@iblocks.co.uk">Jaco Swart </a>
0073:         * @version 1.0
0074:         */
0075:        public class PreparedStatement extends Statement implements 
0076:                java.sql.PreparedStatement {
0077:            /** Original, untouched request (only trimmed) */
0078:            protected String sql;
0079:            /** IN parameters, ready to be inlined in the request */
0080:            private String[] inStrings;
0081:
0082:            // Some performance caches
0083:            protected StringBuffer sbuf = new StringBuffer();
0084:
0085:            /**
0086:             * Constructor. Counts the number of question mark placeholders to size the
0087:             * parameters array.
0088:             * 
0089:             * @param connection the instantiating connection
0090:             * @param sqlStatement the SQL statement with ? for IN markers
0091:             * @param driver the Driver used to create connections
0092:             */
0093:            PreparedStatement(Connection connection, String sqlStatement,
0094:                    Driver driver) {
0095:                super (connection, driver);
0096:
0097:                // The following two boolean switches are used to make sure we're not
0098:                // counting "?" in either strings or metadata strings. For instance the
0099:                // following query:
0100:                // select '?' "A ? value" from dual
0101:                // doesn't have any parameters.
0102:
0103:                boolean inString = false;
0104:                boolean inMetaString = false;
0105:                int nbParam = 0;
0106:
0107:                this .sql = sqlStatement.trim();
0108:                this .connection = connection;
0109:
0110:                // Count how many parameters have to be set
0111:                for (int i = 0; i < sql.length(); ++i) {
0112:                    if (sql.charAt(i) == '\'')
0113:                        if (i > 0 && sql.charAt(i - 1) != '\\')
0114:                            inString = !inString;
0115:                    if (sql.charAt(i) == '"')
0116:                        if (i > 0 && sql.charAt(i - 1) != '\\')
0117:                            inMetaString = !inMetaString;
0118:                    if ((sql.charAt(i) == '?') && (!(inString || inMetaString)))
0119:                        nbParam++;
0120:                }
0121:
0122:                inStrings = new String[nbParam];
0123:
0124:                if (connection.isAlwaysGettingGeneratedKeys())
0125:                    generatedKeysFlag = RETURN_GENERATED_KEYS;
0126:            }
0127:
0128:            /**
0129:             * @see PreparedStatement#PreparedStatement(Connection, String, Driver)
0130:             */
0131:            PreparedStatement(Connection connection, String sqlStatement,
0132:                    Driver driver, int autoGeneratedKeysArg) {
0133:                this (connection, sqlStatement, driver);
0134:                if (!connection.isAlwaysGettingGeneratedKeys())
0135:                    generatedKeysFlag = autoGeneratedKeysArg;
0136:            }
0137:
0138:            /**
0139:             * Release objects for garbage collection and call Statement.close().
0140:             * 
0141:             * @throws SQLException if an error occurs
0142:             */
0143:            public void close() throws SQLException {
0144:                sql = null;
0145:                inStrings = null;
0146:
0147:                super .close();
0148:            }
0149:
0150:            /**
0151:             * A Prepared SQL query is executed and its <code>ResultSet</code> is
0152:             * returned.
0153:             * 
0154:             * @return a <code>ResultSet</code> that contains the data produced by the *
0155:             *         query - never <code>null</code>.
0156:             * @exception SQLException if a database access error occurs
0157:             */
0158:            public java.sql.ResultSet executeQuery() throws SQLException {
0159:                // in Statement class
0160:                return super .executeQuery(sql, compileParameters(false));
0161:            }
0162:
0163:            /**
0164:             * Execute a SQL INSERT, UPDATE or DELETE statement. In addition, SQL
0165:             * statements that return nothing such as SQL DDL statements can be executed.
0166:             * 
0167:             * @return either the row count for <code>INSERT</code>,
0168:             *         <code>UPDATE</code> or <code>DELETE</code>; or 0 for SQL
0169:             *         statements that return nothing.
0170:             * @exception SQLException if a database access error occurs
0171:             */
0172:            public int executeUpdate() throws SQLException {
0173:                // in Statement class
0174:                return super .executeUpdateWithSkeleton(sql,
0175:                        compileParameters(false));
0176:            }
0177:
0178:            /**
0179:             * Sets the length of the temporary buffer to zero and returns a trimmed
0180:             * version of the buffer's content. This ensures that we are not leaking
0181:             * memory and that we manipulate Strings which have the minimal possible
0182:             * memory footprint. Useful when handling BLOBs. Please refer to bug #4546734
0183:             * is Sun's bug database.
0184:             * 
0185:             * @return a String object containing a trimmed version of the StringBuffer's
0186:             *         content
0187:             */
0188:            protected String trimStringBuffer() {
0189:                String trimmedBuf = new String(sbuf.toString());
0190:                sbuf.setLength(0);
0191:                return trimmedBuf;
0192:            }
0193:
0194:            /**
0195:             * Helper - this compiles the SQL query, inlining the parameters in the
0196:             * request String. This is identical to <code>this.toString()</code> except
0197:             * it throws an exception if a parameter was not set.
0198:             * 
0199:             * @param fillEmptyParametersWithCSParamTag true if called from a
0200:             *          CallableStatement
0201:             * @return the compiled query
0202:             * @throws SQLException if an error occurs
0203:             */
0204:            protected synchronized String compileParameters(
0205:                    boolean fillEmptyParametersWithCSParamTag)
0206:                    throws SQLException {
0207:                if (inStrings.length == 0) {
0208:                    return "";
0209:                }
0210:
0211:                sbuf.setLength(0);
0212:                for (int i = 0; i < inStrings.length; ++i) {
0213:                    if (inStrings[i] == null) {
0214:                        if (!fillEmptyParametersWithCSParamTag)
0215:                            throw new SQLException("Parameter " + (i + 1)
0216:                                    + " is not set");
0217:                        setParameterWithTag(i + 1,
0218:                                PreparedStatementSerialization.CS_PARAM_TAG, "");
0219:                    }
0220:                    sbuf.append(inStrings[i]);
0221:                }
0222:                return trimStringBuffer();
0223:            }
0224:
0225:            /**
0226:             * Escape the input string. <br>
0227:             * <char>' </char> is replaced by <char>\' </char> <br>
0228:             * <char>\ </char> is replaced by <char>\\ </char> <br>
0229:             * if connection.escapeProcessing is set to true, surround the new string with
0230:             * <char>\' </char>
0231:             * 
0232:             * @param x the string to process
0233:             * @return escaped string
0234:             */
0235:            protected String doEscapeProcessing(String x) {
0236:                // use the shared buffer object. Should never clash but this
0237:                // makes us thread safe!
0238:                synchronized (sbuf) {
0239:                    sbuf.setLength(0);
0240:                    int i;
0241:                    sbuf.append(connection.getEscapeChar());
0242:                    for (i = 0; i < x.length(); ++i) {
0243:                        char c = x.charAt(i);
0244:                        if ((c == '\'' && connection.isEscapeSingleQuote())
0245:                                || (c == '\\' && connection.isEscapeBackslash()))
0246:                            sbuf.append(c);
0247:                        sbuf.append(c);
0248:                    }
0249:                    sbuf.append(connection.getEscapeChar());
0250:                }
0251:                return trimStringBuffer();
0252:            }
0253:
0254:            /**
0255:             * Sets a parameter to SQL NULL.
0256:             * 
0257:             * @param parameterIndex the first parameter is 1, etc...
0258:             * @param sqlType the SQL type code defined in java.sql.Types
0259:             * @exception SQLException if a database access error occurs
0260:             */
0261:            public void setNull(int parameterIndex, int sqlType)
0262:                    throws SQLException {
0263:                // NULL_VALUE is (confusingly) also used as the "NULL_TAG" to proxy
0264:                // the setNull() call
0265:                setParameterWithTag(parameterIndex,
0266:                        PreparedStatementSerialization.NULL_VALUE, String
0267:                                .valueOf(sqlType));
0268:            }
0269:
0270:            /**
0271:             * Sets a parameter to a Java boolean value. The driver converts this to a SQL
0272:             * BIT value when it sends it to the database.
0273:             * 
0274:             * @param parameterIndex the first parameter is 1...
0275:             * @param x the parameter value
0276:             * @exception SQLException if a database access error occurs
0277:             */
0278:            public void setBoolean(int parameterIndex, boolean x)
0279:                    throws SQLException {
0280:                setParameterWithTag(parameterIndex,
0281:                        PreparedStatementSerialization.BOOLEAN_TAG, String
0282:                                .valueOf(x));
0283:            }
0284:
0285:            /**
0286:             * Sets a parameter to a Java byte value.
0287:             * 
0288:             * @param parameterIndex the first parameter is 1...
0289:             * @param x the parameter value
0290:             * @exception SQLException if a database access error occurs
0291:             */
0292:            public void setByte(int parameterIndex, byte x) throws SQLException {
0293:                setParameterWithTag(parameterIndex,
0294:                        PreparedStatementSerialization.BYTE_TAG, Integer
0295:                                .toString(x));
0296:            }
0297:
0298:            /**
0299:             * Sets a parameter to a Java short value. The driver converts this to a SQL
0300:             * SMALLINT value when it sends it to the database.
0301:             * 
0302:             * @param parameterIndex the first parameter is 1...
0303:             * @param x the parameter value
0304:             * @exception SQLException if a database access error occurs
0305:             */
0306:            public void setShort(int parameterIndex, short x)
0307:                    throws SQLException {
0308:                setParameterWithTag(parameterIndex,
0309:                        PreparedStatementSerialization.SHORT_TAG, Integer
0310:                                .toString(x));
0311:            }
0312:
0313:            /**
0314:             * Sets a parameter to a Java int value. The driver converts this to a SQL
0315:             * INTEGER value when it sends it to the database.
0316:             * 
0317:             * @param parameterIndex the first parameter is 1...
0318:             * @param x the parameter value
0319:             * @exception SQLException if a database access error occurs
0320:             */
0321:            public void setInt(int parameterIndex, int x) throws SQLException {
0322:                setParameterWithTag(parameterIndex,
0323:                        PreparedStatementSerialization.INTEGER_TAG, Integer
0324:                                .toString(x));
0325:            }
0326:
0327:            /**
0328:             * Sets a parameter to a Java long value. The driver converts this to a SQL
0329:             * BIGINT value when it sends it to the database.
0330:             * 
0331:             * @param parameterIndex the first parameter is 1...
0332:             * @param x the parameter value
0333:             * @exception SQLException if a database access error occurs
0334:             */
0335:            public void setLong(int parameterIndex, long x) throws SQLException {
0336:                setParameterWithTag(parameterIndex,
0337:                        PreparedStatementSerialization.LONG_TAG, Long
0338:                                .toString(x));
0339:            }
0340:
0341:            /**
0342:             * Sets a parameter to a Java float value. The driver converts this to a SQL
0343:             * FLOAT value when it sends it to the database.
0344:             * 
0345:             * @param parameterIndex the first parameter is 1...
0346:             * @param x the parameter value
0347:             * @exception SQLException if a database access error occurs
0348:             */
0349:            public void setFloat(int parameterIndex, float x)
0350:                    throws SQLException {
0351:                setParameterWithTag(parameterIndex,
0352:                        PreparedStatementSerialization.FLOAT_TAG, Float
0353:                                .toString(x));
0354:            }
0355:
0356:            /**
0357:             * Sets a parameter to a Java double value. The driver converts this to a SQL
0358:             * DOUBLE value when it sends it to the database.
0359:             * 
0360:             * @param parameterIndex the first parameter is 1...
0361:             * @param x the parameter value
0362:             * @exception SQLException if a database access error occurs
0363:             */
0364:            public void setDouble(int parameterIndex, double x)
0365:                    throws SQLException {
0366:                setParameterWithTag(parameterIndex,
0367:                        PreparedStatementSerialization.DOUBLE_TAG, Double
0368:                                .toString(x));
0369:            }
0370:
0371:            /**
0372:             * Sets a parameter to a java.lang.BigDecimal value. The driver converts this
0373:             * to a SQL NUMERIC value when it sends it to the database.
0374:             * 
0375:             * @param parameterIndex the first parameter is 1...
0376:             * @param x the parameter value
0377:             * @exception SQLException if a database access error occurs
0378:             */
0379:            public void setBigDecimal(int parameterIndex, BigDecimal x)
0380:                    throws SQLException {
0381:                String serializedParam = (x == null ? null : x.toString());
0382:
0383:                setParameterWithTag(parameterIndex,
0384:                        PreparedStatementSerialization.BIG_DECIMAL_TAG,
0385:                        serializedParam);
0386:            }
0387:
0388:            /**
0389:             * Sets a parameter to a Java String value. The driver converts this to a SQL
0390:             * VARCHAR or LONGVARCHAR value (depending on the arguments size relative to
0391:             * the driver's limits on VARCHARs) when it sends it to the database.
0392:             * 
0393:             * @param parameterIndex the first parameter is 1...
0394:             * @param x the parameter value
0395:             * @exception SQLException if a database access error occurs
0396:             */
0397:            public void setString(int parameterIndex, String x)
0398:                    throws SQLException {
0399:                if (PreparedStatementSerialization.NULL_VALUE.equals(x))
0400:                    // Someone is trying to set a String that matches our NULL tag, a real
0401:                    // bad luck, use our special type NULL_STRING_TAG!
0402:                    setParameterWithTag(parameterIndex,
0403:                            PreparedStatementSerialization.NULL_STRING_TAG, x);
0404:                else
0405:                    setParameterWithTag(parameterIndex,
0406:                            PreparedStatementSerialization.STRING_TAG, x);
0407:            }
0408:
0409:            /**
0410:             * Sets a parameter to a Java array of bytes.
0411:             * <p>
0412:             * 
0413:             * @param parameterIndex the first parameter is 1...
0414:             * @param x the parameter value
0415:             * @exception SQLException if a database access error occurs
0416:             */
0417:            public void setBytes(int parameterIndex, byte[] x)
0418:                    throws SQLException {
0419:                try {
0420:                    /**
0421:                     * Encoded only for request inlining. Decoded right away by the controller
0422:                     * at static
0423:                     * {@link #setPreparedStatement(String, java.sql.PreparedStatement)}
0424:                     */
0425:                    String encodedString = AbstractBlobFilter
0426:                            .getDefaultBlobFilter().encode(x);
0427:                    setParameterWithTag(parameterIndex,
0428:                            PreparedStatementSerialization.BYTES_TAG,
0429:                            encodedString);
0430:                } catch (OutOfMemoryError oome) {
0431:                    System.gc();
0432:                    throw new SQLException("Out of memory while encoding bytes");
0433:                }
0434:            }
0435:
0436:            /**
0437:             * Sets a parameter to a java.sql.Date value. The driver converts this to a
0438:             * SQL DATE value when it sends it to the database.
0439:             * 
0440:             * @param parameterIndex the first parameter is 1...
0441:             * @param x the parameter value
0442:             * @exception SQLException if a database access error occurs
0443:             */
0444:            public void setDate(int parameterIndex, java.sql.Date x)
0445:                    throws SQLException {
0446:                String serializedParam = (x == null ? null : new java.sql.Date(
0447:                        x.getTime()).toString());
0448:
0449:                setParameterWithTag(parameterIndex,
0450:                        PreparedStatementSerialization.DATE_TAG,
0451:                        serializedParam);
0452:            }
0453:
0454:            /**
0455:             * Sets a parameter to a <code>java.sql.Time</code> value. The driver
0456:             * converts this to a SQL TIME value when it sends it to the database.
0457:             * 
0458:             * @param parameterIndex the first parameter is 1...));
0459:             * @param x the parameter value
0460:             * @exception SQLException if a database access error occurs
0461:             */
0462:            public void setTime(int parameterIndex, Time x) throws SQLException {
0463:                String serializedParam = (x == null ? null : x.toString());
0464:
0465:                setParameterWithTag(parameterIndex,
0466:                        PreparedStatementSerialization.TIME_TAG,
0467:                        serializedParam);
0468:            }
0469:
0470:            /**
0471:             * Sets a parameter to a <code>java.sql.Timestamp</code> value. The driver
0472:             * converts this to a SQL TIMESTAMP value when it sends it to the database.
0473:             * 
0474:             * @param parameterIndex the first parameter is 1...
0475:             * @param x the parameter value
0476:             * @exception SQLException if a database access error occurs
0477:             */
0478:            public void setTimestamp(int parameterIndex, Timestamp x)
0479:                    throws SQLException {
0480:                if (x == null)
0481:                    setParameterWithTag(parameterIndex,
0482:                            PreparedStatementSerialization.TIMESTAMP_TAG, null);
0483:                else {
0484:                    if (x.getClass().equals(Timestamp.class))
0485:                        setParameterWithTag(parameterIndex,
0486:                                PreparedStatementSerialization.TIMESTAMP_TAG, x
0487:                                        .toString());
0488:                    else
0489:                        setParameterWithTag(parameterIndex,
0490:                                PreparedStatementSerialization.TIMESTAMP_TAG,
0491:                                new Timestamp(x.getTime()).toString());
0492:                }
0493:            }
0494:
0495:            /**
0496:             * When a very large ASCII value is input to a LONGVARCHAR parameter, it may
0497:             * be more practical to send it via a java.io.InputStream. JDBC will read the
0498:             * data from the stream as needed, until it reaches end-of-file. The JDBC
0499:             * driver will do any necessary conversion from ASCII to the database char
0500:             * format.
0501:             * <p>
0502:             * <b>Note: </b> this stream object can either be a standard Java stream
0503:             * object or your own subclass that implements the standard interface.
0504:             * 
0505:             * @param parameterIndex the first parameter is 1...
0506:             * @param x the parameter value
0507:             * @param length the number of bytes in the stream
0508:             * @exception SQLException if a database access error occurs
0509:             */
0510:            public void setAsciiStream(int parameterIndex, InputStream x,
0511:                    int length) throws SQLException {
0512:                setBinaryStream(parameterIndex, x, length);
0513:            }
0514:
0515:            /**
0516:             * When a very large Unicode value is input to a LONGVARCHAR parameter, it may
0517:             * be more practical to send it via a java.io.InputStream. JDBC will read the
0518:             * data from the stream as needed, until it reaches end-of-file. The JDBC
0519:             * driver will do any necessary conversion from UNICODE to the database char
0520:             * format.
0521:             * <p>** DEPRECIATED IN JDBC 2 **
0522:             * <p>
0523:             * <b>Note: </b> this stream object can either be a standard Java stream
0524:             * object or your own subclass that implements the standard interface.
0525:             * 
0526:             * @param parameterIndex the first parameter is 1...
0527:             * @param x the parameter value
0528:             * @param length the parameter length
0529:             * @exception SQLException if a database access error occurs
0530:             * @deprecated
0531:             */
0532:            public void setUnicodeStream(int parameterIndex, InputStream x,
0533:                    int length) throws SQLException {
0534:                setBinaryStream(parameterIndex, x, length);
0535:            }
0536:
0537:            /**
0538:             * Stores a binary stream into parameters array, using an intermediate byte[].
0539:             * When a very large binary value is input to a LONGVARBINARY parameter, it
0540:             * may be more practical to send it via a java.io.InputStream. JDBC will read
0541:             * the data from the stream as needed, until it reaches end-of-file. This
0542:             * should be more or less equivalent to setBytes(blob.getBytes()).
0543:             * <p>
0544:             * <b>Note: </b> This stream object can either be a standard Java stream
0545:             * object or your own subclass that implements the standard interface.
0546:             * 
0547:             * @param parameterIndex the first parameter is 1...
0548:             * @param inStreamArg the parameter value
0549:             * @param length the parameter length
0550:             * @exception SQLException if a database access error occurs
0551:             * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream,
0552:             *      int)
0553:             */
0554:            public void setBinaryStream(int parameterIndex,
0555:                    InputStream inStreamArg, int length) throws SQLException {
0556:                byte[] data = new byte[length];
0557:                try {
0558:                    inStreamArg.read(data, 0, length);
0559:                } catch (Exception ioe) {
0560:                    throw new SQLException("Problem with streaming of data");
0561:                }
0562:                // TODO: optimize me and avoid the copy thanks to a new setBytesFromStream()
0563:                // setBytes does the blob filter encoding.
0564:                setBytes(parameterIndex, data);
0565:            }
0566:
0567:            /**
0568:             * In general, parameter values remain in force for repeated used of a
0569:             * <code>Statement</code>. Setting a parameter value automatically clears
0570:             * its previous value. However, in coms cases, it is useful to immediately
0571:             * release the resources used by the current parameter values; this can be
0572:             * done by calling <code>clearParameters()</code>.
0573:             * 
0574:             * @exception SQLException if a database access error occurs
0575:             */
0576:            public void clearParameters() throws SQLException {
0577:                int i;
0578:
0579:                for (i = 0; i < inStrings.length; i++)
0580:                    inStrings[i] = null;
0581:            }
0582:
0583:            /**
0584:             * Sets the value of a parameter using an object; use the
0585:             * <code>java.lang</code> equivalent objects for integral values.
0586:             * <p>
0587:             * The given Java object will be converted to the targetSqlType before being
0588:             * sent to the database.
0589:             * <p>
0590:             * Note that this method may be used to pass database-specific abstract data
0591:             * types. This is done by using a Driver-specific Java type and using a
0592:             * <code>targetSqlType</code> of <code>java.sql.Types.OTHER</code>.
0593:             * 
0594:             * @param parameterIndex the first parameter is 1...
0595:             * @param x the object containing the input parameter value
0596:             * @param targetSqlType The SQL type to be send to the database
0597:             * @param scale for <code>java.sql.Types.DECIMAL</code> or
0598:             *          <code>java.sql.Types.NUMERIC</code> types this is the number of
0599:             *          digits after the decimal. For all other types this value will be
0600:             *          ignored.
0601:             * @exception SQLException if a database access error or an incompatible type
0602:             *              match occurs
0603:             * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int, int)
0604:             */
0605:            public void setObject(int parameterIndex, Object x,
0606:                    int targetSqlType, int scale) throws SQLException {
0607:                if (x == null) {
0608:                    setNull(parameterIndex, targetSqlType);
0609:                    return;
0610:                }
0611:
0612:                try {
0613:                    boolean failed = false;
0614:                    switch (targetSqlType) {
0615:                    /**
0616:                     * Reference is table "Conversions Performed by setObject()..." in JDBC
0617:                     * Reference Book (table 47.9.5 in 2nd edition, 50.5 in 3rd edition).
0618:                     * Also available online in Sun's "JDBC Technology Guide: Getting
0619:                     * Started", section "Mapping SQL and Java Types".
0620:                     */
0621:
0622:                    // Some drivers (at least postgresql > 8.1) don't accept setInt for tiny
0623:                    // and small ints. We can safely use setShort instead. See bug
0624:                    // SEQUOIA-543
0625:                    // setShort().
0626:                    case Types.TINYINT:
0627:                    case Types.SMALLINT:
0628:                        if (x instanceof  Number)
0629:                            setShort(parameterIndex, ((Number) x).shortValue());
0630:                        else if (x instanceof  Boolean)
0631:                            setShort(parameterIndex, ((Boolean) x)
0632:                                    .booleanValue() ? (short) 1 : (short) 0);
0633:                        else if (x instanceof  String)
0634:                            setShort(parameterIndex, Short
0635:                                    .parseShort((String) x));
0636:                        else
0637:                            failed = true;
0638:                        break;
0639:                    // setInt()
0640:                    case Types.INTEGER:
0641:                        if (x instanceof  Number)
0642:                            setInt(parameterIndex, ((Number) x).intValue());
0643:                        else if (x instanceof  Boolean)
0644:                            setInt(parameterIndex,
0645:                                    ((Boolean) x).booleanValue() ? 1 : 0);
0646:                        else if (x instanceof  String)
0647:                            setInt(parameterIndex, Integer.parseInt((String) x));
0648:                        else
0649:                            failed = true;
0650:                        break;
0651:                    // setLong()
0652:                    case Types.BIGINT:
0653:                        if (x instanceof  Number)
0654:                            setLong(parameterIndex, ((Number) x).longValue());
0655:                        else if (x instanceof  String)
0656:                            setLong(parameterIndex, Long.parseLong((String) x));
0657:                        else if (x instanceof  Boolean)
0658:                            setLong(parameterIndex, ((Boolean) x)
0659:                                    .booleanValue() ? 1 : 0);
0660:                        else
0661:                            failed = true;
0662:                        break;
0663:                    // setDouble()
0664:                    case Types.REAL:
0665:                    case Types.FLOAT:
0666:                    case Types.DOUBLE:
0667:                        if (x instanceof  Number)
0668:                            setDouble(parameterIndex, ((Number) x)
0669:                                    .doubleValue());
0670:                        else if (x instanceof  String)
0671:                            setDouble(parameterIndex, Double
0672:                                    .parseDouble((String) x));
0673:                        else if (x instanceof  Boolean)
0674:                            setDouble(parameterIndex, ((Boolean) x)
0675:                                    .booleanValue() ? 1 : 0);
0676:                        else
0677:                            failed = true;
0678:                        break;
0679:                    // setBigDecimal()
0680:                    case Types.DECIMAL:
0681:                    case Types.NUMERIC:
0682:                        BigDecimal bd;
0683:                        if (x instanceof  Boolean)
0684:                            bd = new BigDecimal(
0685:                                    ((Boolean) x).booleanValue() ? 1d : 0d);
0686:                        else if (x instanceof  Number)
0687:                            bd = new BigDecimal(((Number) x).toString());
0688:                        else if (x instanceof  String)
0689:                            bd = new BigDecimal((String) x);
0690:                        else {
0691:                            failed = true;
0692:                            break;
0693:                        }
0694:                        bd = bd.setScale(scale, BigDecimal.ROUND_HALF_UP);
0695:                        setBigDecimal(parameterIndex, bd);
0696:                        break;
0697:                    // setBoolean()
0698:                    case Types.BIT:
0699:                    case Types.BOOLEAN:
0700:                        if (x instanceof  Number)
0701:                            setBoolean(parameterIndex, 0 != ((Number) x)
0702:                                    .longValue());
0703:                        else if (x instanceof  Boolean)
0704:                            setBoolean(parameterIndex, ((Boolean) x)
0705:                                    .booleanValue());
0706:                        else if (x instanceof  String)
0707:                            setBoolean(parameterIndex, Boolean.valueOf(
0708:                                    (String) x).booleanValue());
0709:                        else
0710:                            failed = true;
0711:                        break;
0712:                    // setString()
0713:                    case Types.CHAR:
0714:                    case Types.VARCHAR:
0715:                    case Types.LONGVARCHAR:
0716:                        setString(parameterIndex, x.toString());
0717:                        break;
0718:                    // setBytes(), setBlob(),...
0719:                    case Types.BINARY:
0720:                    case Types.VARBINARY:
0721:                    case Types.LONGVARBINARY:
0722:                        if (x instanceof  byte[])
0723:                            setBytes(parameterIndex, (byte[]) x);
0724:                        else if (x instanceof  Blob)
0725:                            setBlob(parameterIndex, (Blob) x);
0726:                        else if (x instanceof  Serializable)
0727:                            // Try it as an Object (serialized in bytes in setObject below)
0728:                            setObject(parameterIndex, x);
0729:                        else
0730:                            failed = true;
0731:                        break;
0732:                    // setDate()
0733:                    case Types.DATE:
0734:                        if (x instanceof  String)
0735:                            setDate(parameterIndex, java.sql.Date
0736:                                    .valueOf((String) x));
0737:                        else if (x instanceof  java.sql.Date)
0738:                            setDate(parameterIndex, (java.sql.Date) x);
0739:                        else if (x instanceof  Timestamp)
0740:                            setDate(parameterIndex, new java.sql.Date(
0741:                                    ((Timestamp) x).getTime()));
0742:                        else
0743:                            failed = true;
0744:                        break;
0745:                    // setTime()
0746:                    case Types.TIME:
0747:                        if (x instanceof  String)
0748:                            setTime(parameterIndex, Time.valueOf((String) x));
0749:                        else if (x instanceof  Time)
0750:                            setTime(parameterIndex, (Time) x);
0751:                        else if (x instanceof  Timestamp)
0752:                            setTime(parameterIndex, new Time(((Timestamp) x)
0753:                                    .getTime()));
0754:                        else
0755:                            failed = true;
0756:                        break;
0757:                    // setTimeStamp()
0758:                    case Types.TIMESTAMP:
0759:                        if (x instanceof  String)
0760:                            setTimestamp(parameterIndex, Timestamp
0761:                                    .valueOf((String) x));
0762:                        else if (x instanceof  Date)
0763:                            setTimestamp(parameterIndex, new Timestamp(
0764:                                    ((Date) x).getTime()));
0765:                        else if (x instanceof  Timestamp)
0766:                            setTimestamp(parameterIndex, (Timestamp) x);
0767:                        else
0768:                            failed = true;
0769:                        break;
0770:                    // setBlob()
0771:                    case Types.BLOB:
0772:                        if (x instanceof  Blob)
0773:                            setBlob(parameterIndex, (Blob) x);
0774:                        else
0775:                            failed = true;
0776:                        break;
0777:                    // setURL()
0778:                    case Types.DATALINK:
0779:                        if (x instanceof  java.net.URL)
0780:                            setURL(parameterIndex, (java.net.URL) x);
0781:                        else
0782:                            setURL(parameterIndex, new java.net.URL(x
0783:                                    .toString()));
0784:                        break;
0785:                    case Types.JAVA_OBJECT:
0786:                    case Types.OTHER:
0787:                        // let's ignore the unknown target type given.
0788:                        setObject(parameterIndex, x);
0789:                        break;
0790:                    default:
0791:                        throw new SQLException("Unsupported type value");
0792:                    }
0793:                    if (true == failed)
0794:                        throw new IllegalArgumentException(
0795:                                "Attempt to perform an illegal conversion");
0796:                } catch (Exception e) {
0797:                    SQLException outE = new SQLException(
0798:                            "Exception while converting type " + x.getClass()
0799:                                    + " to SQL type " + targetSqlType);
0800:                    outE.initCause(e);
0801:                    throw outE;
0802:                }
0803:            }
0804:
0805:            /**
0806:             * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int)
0807:             */
0808:            public void setObject(int parameterIndex, Object x,
0809:                    int targetSqlType) throws SQLException {
0810:                setObject(parameterIndex, x, targetSqlType, 0);
0811:            }
0812:
0813:            /**
0814:             * This stores an Object parameter into the parameters array.
0815:             * 
0816:             * @param parameterIndex the first parameter is 1...
0817:             * @param x the object to set
0818:             * @exception SQLException if a database access error occurs
0819:             */
0820:            public void setObject(int parameterIndex, Object x)
0821:                    throws SQLException {
0822:                if (x == null) {
0823:                    setParameterWithTag(parameterIndex,
0824:                            PreparedStatementSerialization.OBJECT_TAG, null);
0825:                } else { // This is an optimization, faster than going through
0826:                    // the generic setObject() method and calling instanceof again.
0827:                    // This has to be in the end equivalent to
0828:                    // setObject(index, object, DEFAULT_targetSqlType, 0)
0829:                    // where DEFAULT_targetSqlType is defined in table:
0830:                    // "Java Object Type Mapped to JDBC Types".
0831:                    // It's currently not exactly the same, since generic setObject()
0832:                    // is not strict enough in its conversions. For instance
0833:                    // setObject(target=Float) actually calls "setDouble()" -- MH.
0834:
0835:                    if (x instanceof  String)
0836:                        setString(parameterIndex, (String) x);
0837:                    else if (x instanceof  BigDecimal)
0838:                        setBigDecimal(parameterIndex, (BigDecimal) x);
0839:                    else if (x instanceof  Boolean)
0840:                        setBoolean(parameterIndex, ((Boolean) x).booleanValue());
0841:                    else if (x instanceof  Short)
0842:                        setShort(parameterIndex, ((Short) x).shortValue());
0843:                    else if (x instanceof  Integer)
0844:                        setInt(parameterIndex, ((Integer) x).intValue());
0845:                    else if (x instanceof  Long)
0846:                        setLong(parameterIndex, ((Long) x).longValue());
0847:                    else if (x instanceof  Float)
0848:                        setFloat(parameterIndex, ((Float) x).floatValue());
0849:                    else if (x instanceof  Double)
0850:                        setDouble(parameterIndex, ((Double) x).doubleValue());
0851:                    else if (x instanceof  byte[])
0852:                        setBytes(parameterIndex, (byte[]) x);
0853:                    else if (x instanceof  java.sql.Date)
0854:                        setDate(parameterIndex, (java.sql.Date) x);
0855:                    else if (x instanceof  Time)
0856:                        setTime(parameterIndex, (Time) x);
0857:                    else if (x instanceof  Timestamp)
0858:                        setTimestamp(parameterIndex, (Timestamp) x);
0859:                    else if (x instanceof  Blob)
0860:                        setBlob(parameterIndex, (Blob) x);
0861:                    else if (x instanceof  java.net.URL)
0862:                        setURL(parameterIndex, (java.net.URL) x);
0863:                    else if (x instanceof  Serializable) {
0864:                        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
0865:                        try {
0866:                            // Serialize object to byte array
0867:                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(
0868:                                    byteOutputStream);
0869:                            objectOutputStream.writeObject(x);
0870:                            objectOutputStream.close();
0871:                            synchronized (this .sbuf) {
0872:                                this .sbuf.setLength(0);
0873:                                /**
0874:                                 * Encoded only for request inlining. Decoded right away by the
0875:                                 * controller
0876:                                 */
0877:                                this .sbuf
0878:                                        .append(AbstractBlobFilter
0879:                                                .getDefaultBlobFilter().encode(
0880:                                                        byteOutputStream
0881:                                                                .toByteArray()));
0882:                                setParameterWithTag(
0883:                                        parameterIndex,
0884:                                        PreparedStatementSerialization.OBJECT_TAG,
0885:                                        trimStringBuffer());
0886:                            }
0887:                        } catch (IOException e) {
0888:                            throw new SQLException(
0889:                                    "Failed to serialize object: " + e);
0890:                        }
0891:                    } else
0892:                        throw new SQLException("Objects of type "
0893:                                + x.getClass() + " are not supported.");
0894:                }
0895:            }
0896:
0897:            /**
0898:             * Some prepared statements return multiple results; the execute method
0899:             * handles these complex statements as well as the simpler form of statements
0900:             * handled by <code>executeQuery()</code> and <code>executeUpdate()</code>.
0901:             * 
0902:             * @return <code>true</code> if the next result is a
0903:             *         <code>ResultSet<code>; <code>false<code> if it is an update count
0904:             * or there are no more results
0905:             * @exception SQLException if a database access error occurs
0906:             */
0907:            public boolean execute() throws SQLException {
0908:                if (this .generatedKeysFlag == RETURN_GENERATED_KEYS) {
0909:                    if (connection.isAlwaysGettingGeneratedKeys()
0910:                            && !sql.toLowerCase().trim().startsWith("insert")) {
0911:                        return super .execute(sql, compileParameters(false));
0912:                    }
0913:                    int result = executeUpdate();
0914:                    resultList = new LinkedList();
0915:                    resultList.add(new Integer(result));
0916:                    resultListIterator = resultList.iterator();
0917:                    return getMoreResults();
0918:                }
0919:                return super .execute(sql, compileParameters(false));
0920:            }
0921:
0922:            /**
0923:             * Returns the SQL statement with the current template values substituted.
0924:             * <p>
0925:             * <b>Note: </b>: This is identical to <code>compileQuery()</code> except
0926:             * instead of throwing SQLException if a parameter is <code>null</code>, it
0927:             * places ? instead.
0928:             * 
0929:             * @return the SQL statement
0930:             */
0931:            public String toString() {
0932:                synchronized (sbuf) {
0933:                    sbuf.setLength(0);
0934:                    sbuf.append(sql);
0935:                    int i;
0936:
0937:                    if (inStrings == null)
0938:                        return sbuf.toString();
0939:
0940:                    for (i = 0; i < inStrings.length; ++i) {
0941:                        if (inStrings[i] == null)
0942:                            sbuf.append('?');
0943:                        else
0944:                            sbuf.append(inStrings[i]);
0945:                    }
0946:                    return trimStringBuffer();
0947:                }
0948:            }
0949:
0950:            // ** JDBC 2 Extensions **
0951:
0952:            /**
0953:             * This parses the query and adds it to the current batch
0954:             * 
0955:             * @throws SQLException if an error occurs
0956:             */
0957:            public synchronized void addBatch() throws SQLException {
0958:                if (batch == null)
0959:                    batch = new Vector();
0960:                batch
0961:                        .addElement(new BatchElement(sql,
0962:                                compileParameters(false)));
0963:            }
0964:
0965:            /**
0966:             * Execute a batch of commands
0967:             * 
0968:             * @return an array containing update count that corresponding to the commands
0969:             *         that executed successfully
0970:             * @exception BatchUpdateException if an error occurs on one statement (the
0971:             *              number of updated rows for the successfully executed
0972:             *              statements can be found in
0973:             *              BatchUpdateException.getUpdateCounts())
0974:             */
0975:            public int[] executeBatch() throws BatchUpdateException {
0976:                if (batch == null || batch.isEmpty())
0977:                    return new int[0];
0978:
0979:                int size = batch.size();
0980:                int[] nbsRowsUpdated = new int[size];
0981:                int i = 0;
0982:
0983:                try {
0984:                    for (i = 0; i < size; i++) {
0985:                        BatchElement be = (BatchElement) batch.elementAt(i);
0986:                        nbsRowsUpdated[i] = this .executeUpdateWithSkeleton(be
0987:                                .getSqlTemplate(), be.getParameters());
0988:                    }
0989:                    return nbsRowsUpdated;
0990:                } catch (SQLException e) {
0991:                    String message = "Batch failed for request "
0992:                            + i
0993:                            + ": "
0994:                            + ((BatchElement) batch.elementAt(i))
0995:                                    .getSqlTemplate() + " (" + e + ")";
0996:
0997:                    // shrink the returned array
0998:                    int[] updateCounts = new int[i];
0999:                    System.arraycopy(nbsRowsUpdated, 0, updateCounts, 0, i);
1000:
1001:                    throw new BatchUpdateException(message, updateCounts);
1002:                } finally {
1003:                    batch.removeAllElements();
1004:                }
1005:            }
1006:
1007:            /**
1008:             * Returns the <code>MetaData</code> for the last <code>ResultSet</code>
1009:             * returned.
1010:             * 
1011:             * @return The ResultSet Metadata
1012:             * @throws SQLException if an error occurs
1013:             */
1014:            public java.sql.ResultSetMetaData getMetaData() throws SQLException {
1015:                java.sql.ResultSet rs = getResultSet();
1016:                if (rs != null)
1017:                    return rs.getMetaData();
1018:                else
1019:                    return connection.preparedStatementGetMetaData(sql);
1020:            }
1021:
1022:            /**
1023:             * @see java.sql.PreparedStatement#setArray(int, java.sql.Array)
1024:             */
1025:            public void setArray(int i, Array x) throws SQLException {
1026:                throw new NotImplementedException("setArray()");
1027:            }
1028:
1029:            /**
1030:             * @see java.sql.PreparedStatement#setBlob(int, Blob)
1031:             */
1032:            public void setBlob(int paramIndex, Blob sqlBlobParam)
1033:                    throws SQLException {
1034:                if (sqlBlobParam == null) {
1035:                    setParameterWithTag(paramIndex,
1036:                            PreparedStatementSerialization.BLOB_TAG, null);
1037:                    return;
1038:                }
1039:
1040:                // sqlBlobParam.getBytes() seems limited in size ?
1041:                // So we use .getBinaryStream()
1042:                InputStream blobBinStream = sqlBlobParam.getBinaryStream();
1043:
1044:                byte[] data = new byte[(int) sqlBlobParam.length()];
1045:                try {
1046:                    blobBinStream.read(data, 0, (int) sqlBlobParam.length());
1047:                } catch (Exception ioe) {
1048:                    throw new SQLException("Problem with data streaming");
1049:                }
1050:                try {
1051:                    synchronized (this .sbuf) {
1052:                        this .sbuf.setLength(0);
1053:                        /**
1054:                         * Encoded only for request inlining. Decoded right away by the
1055:                         * controller at static
1056:                         * {@link #setPreparedStatement(String, java.sql.PreparedStatement)}
1057:                         */
1058:                        this .sbuf.append(AbstractBlobFilter
1059:                                .getDefaultBlobFilter().encode(data));
1060:                        // this will make yet-another copy of the stringified blob.
1061:                        // as a short-term fix for SEQUOIA-106, we should inline this call.
1062:                        // The long term fix is to send binary parameters
1063:                        setParameterWithTag(paramIndex,
1064:                                PreparedStatementSerialization.BLOB_TAG,
1065:                                trimStringBuffer());
1066:                    }
1067:                } catch (OutOfMemoryError oome) {
1068:                    this .sbuf = null;
1069:                    System.gc();
1070:                    throw new SQLException("Out of memory");
1071:                }
1072:            }
1073:
1074:            /**
1075:             * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader,
1076:             *      int)
1077:             */
1078:            public void setCharacterStream(int i, java.io.Reader x, int length)
1079:                    throws SQLException {
1080:                char[] data = new char[length];
1081:                try {
1082:                    x.read(data, 0, length);
1083:                } catch (Exception ioe) {
1084:                    throw new SQLException("Problem with streaming of data");
1085:                }
1086:                setString(i, new String(data));
1087:            }
1088:
1089:            /**
1090:             * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob)
1091:             */
1092:            public void setClob(int i, java.sql.Clob clobArg)
1093:                    throws SQLException {
1094:                String serializedParam = (clobArg == null ? null : clobArg
1095:                        .getSubString(0, (int) clobArg.length()));
1096:
1097:                setParameterWithTag(i, PreparedStatementSerialization.CLOB_TAG,
1098:                        serializedParam);
1099:            }
1100:
1101:            /**
1102:             * @see java.sql.PreparedStatement#setNull(int, int, java.lang.String)
1103:             */
1104:            public void setNull(int i, int t, String s) throws SQLException {
1105:                setNull(i, t);
1106:            }
1107:
1108:            /**
1109:             * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref)
1110:             */
1111:            public void setRef(int i, Ref x) throws SQLException {
1112:                String serializedParam = (x == null ? null : x.toString());
1113:
1114:                setParameterWithTag(i, PreparedStatementSerialization.REF_TAG,
1115:                        serializedParam);
1116:            }
1117:
1118:            /**
1119:             * @see java.sql.PreparedStatement#setDate(int, java.sql.Date,
1120:             *      java.util.Calendar)
1121:             */
1122:            public void setDate(int i, java.sql.Date d, java.util.Calendar cal)
1123:                    throws SQLException {
1124:                if (d == null)
1125:                    setParameterWithTag(i,
1126:                            PreparedStatementSerialization.DATE_TAG, null);
1127:                else {
1128:                    if (cal == null)
1129:                        setDate(i, d);
1130:                    else {
1131:                        cal.setTime(d);
1132:                        setDate(i, new java.sql.Date(cal.getTime().getTime()));
1133:                    }
1134:                }
1135:            }
1136:
1137:            /**
1138:             * @see java.sql.PreparedStatement#setTime(int, java.sql.Time,
1139:             *      java.util.Calendar)
1140:             */
1141:            public void setTime(int i, Time t, java.util.Calendar cal)
1142:                    throws SQLException {
1143:                if (t == null)
1144:                    setParameterWithTag(i,
1145:                            PreparedStatementSerialization.TIME_TAG, null);
1146:                else {
1147:                    if (cal == null)
1148:                        setTime(i, t);
1149:                    else {
1150:                        cal.setTime(t);
1151:                        setTime(i, new java.sql.Time(cal.getTime().getTime()));
1152:                    }
1153:                }
1154:            }
1155:
1156:            /**
1157:             * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp,
1158:             *      java.util.Calendar)
1159:             */
1160:            public void setTimestamp(int i, Timestamp t, java.util.Calendar cal)
1161:                    throws SQLException {
1162:                if (t == null)
1163:                    setParameterWithTag(i,
1164:                            PreparedStatementSerialization.TIMESTAMP_TAG, null);
1165:                else {
1166:                    if (cal == null)
1167:                        setTimestamp(i, t);
1168:                    else {
1169:                        cal.setTime(t);
1170:                        setTimestamp(i, new java.sql.Timestamp(cal.getTime()
1171:                                .getTime()));
1172:                    }
1173:                }
1174:            }
1175:
1176:            // ------------------------- JDBC 3.0 -----------------------------------
1177:
1178:            /**
1179:             * Sets the designated parameter to the given <code>java.net.URL</code>
1180:             * value. The driver converts this to an SQL <code>DATALINK</code> value
1181:             * when it sends it to the database.
1182:             * 
1183:             * @param parameterIndex the first parameter is 1, the second is 2, ...
1184:             * @param x the <code>java.net.URL</code> object to be set
1185:             * @exception SQLException if a database access error occurs
1186:             * @since JDK 1.4
1187:             */
1188:            public void setURL(int parameterIndex, java.net.URL x)
1189:                    throws SQLException {
1190:                String serializedParam = (x == null ? null : x.toString());
1191:
1192:                setParameterWithTag(parameterIndex,
1193:                        PreparedStatementSerialization.URL_TAG, serializedParam);
1194:            }
1195:
1196:            /**
1197:             * Retrieves the number, types and properties of this
1198:             * <code>PreparedStatement</code> object's parameters.
1199:             * 
1200:             * @return a <code>ParameterMetaData</code> object that contains information
1201:             *         about the number, types and properties of this
1202:             *         <code>PreparedStatement</code> object's parameters
1203:             * @exception SQLException if a database access error occurs
1204:             * @see ParameterMetaData
1205:             * @since JDK 1.4
1206:             */
1207:            public ParameterMetaData getParameterMetaData() throws SQLException {
1208:                throw new NotImplementedException("getParameterMetaData");
1209:            }
1210:
1211:            // **************************************************************
1212:            // END OF PUBLIC INTERFACE
1213:            // **************************************************************
1214:
1215:            /**
1216:             * Stores a parameter into parameters String array. Called by most setXXX()
1217:             * methods.
1218:             * 
1219:             * @param paramIndex the index into the inString
1220:             * @param s a string to be stored
1221:             * @exception SQLException if something goes wrong
1222:             */
1223:            protected void setParameter(int paramIndex, String s)
1224:                    throws SQLException {
1225:                if (paramIndex < 1 || paramIndex > inStrings.length)
1226:                    throw new SQLException("Parameter index out of range.");
1227:                inStrings[paramIndex - 1] = s;
1228:            }
1229:
1230:            /**
1231:             * Return a stored parameter tag and value.
1232:             * 
1233:             * @param paramIndex the index into the inString
1234:             * @return a the parameter tag and the parameter value
1235:             * @exception SQLException if something goes wrong
1236:             */
1237:            protected String[] getParameterTagAndValue(int paramIndex)
1238:                    throws SQLException {
1239:                if (paramIndex < 1 || paramIndex > inStrings.length)
1240:                    throw new SQLException("Parameter index out of range.");
1241:                int typeStart = PreparedStatementSerialization.START_PARAM_TAG
1242:                        .length();
1243:
1244:                // Here we assume that all tags have the same length as the boolean tag.
1245:                String tagString = inStrings[paramIndex - 1];
1246:                String paramType = tagString.substring(typeStart, typeStart
1247:                        + PreparedStatementSerialization.BOOLEAN_TAG.length());
1248:                String paramValue = tagString
1249:                        .substring(
1250:                                typeStart
1251:                                        + PreparedStatementSerialization.BOOLEAN_TAG
1252:                                                .length(),
1253:                                tagString
1254:                                        .indexOf(PreparedStatementSerialization.END_PARAM_TAG));
1255:                paramValue = Strings.replace(paramValue,
1256:                        PreparedStatementSerialization.TAG_MARKER_ESCAPE,
1257:                        PreparedStatementSerialization.TAG_MARKER);
1258:                return new String[] { paramType, paramValue };
1259:            }
1260:
1261:            /**
1262:             * Stores parameter and its type as a <em>quoted</em> String, so the
1263:             * controller can decode them back.
1264:             * <p>
1265:             * We could avoid inlining the arguments and just tag them and send them apart
1266:             * as an object list. But this would imply a couple of changes elsewhere,
1267:             * among other: macro-handling, recoverylog,...
1268:             * 
1269:             * @param paramIndex the index into the inString
1270:             * @param typeTag type of the parameter
1271:             * @param param the parameter string to be stored
1272:             * @exception SQLException if something goes wrong
1273:             * @see PreparedStatementSerialization#setPreparedStatement(String,
1274:             *      java.sql.PreparedStatement)
1275:             */
1276:            void setParameterWithTag(int paramIndex, String typeTag,
1277:                    String param) throws SQLException {
1278:                if (isClosed())
1279:                    throw new SQLException(
1280:                            "Unable to set a parameter on a closed statement");
1281:
1282:                /**
1283:                 * insert TAGS so the controller can parse and "unset" the request using
1284:                 * {@link #setPreparedStatement(String, java.sql.PreparedStatement) 
1285:                 */
1286:                if (param == null)
1287:                    param = PreparedStatementSerialization.NULL_VALUE;
1288:                else
1289:                    // escape the markers in argument data
1290:                    param = Strings.replace(param,
1291:                            PreparedStatementSerialization.TAG_MARKER,
1292:                            PreparedStatementSerialization.TAG_MARKER_ESCAPE);
1293:
1294:                setParameter(paramIndex, new String(
1295:                        PreparedStatementSerialization.START_PARAM_TAG
1296:                                + typeTag + param
1297:                                + PreparedStatementSerialization.END_PARAM_TAG));
1298:            }
1299:
1300:            /**
1301:             * This class defines a BatchElement used for the batch update vector of
1302:             * PreparedStatements to execute.
1303:             * 
1304:             * @author <a href="mailto:emmanuel.cecchet@emicnetworks.com">Emmanuel Cecchet
1305:             *         </a>
1306:             * @version 1.0
1307:             */
1308:            protected class BatchElement {
1309:                private String sqlTemplate;
1310:                private String parameters;
1311:
1312:                /**
1313:                 * Creates a new <code>BatchElement</code> object
1314:                 * 
1315:                 * @param sqlTemplate SQL query template (aka skeleton)
1316:                 * @param parameters prepared statement parameters
1317:                 */
1318:                public BatchElement(String sqlTemplate, String parameters) {
1319:                    this .sqlTemplate = sqlTemplate;
1320:                    this .parameters = parameters;
1321:                }
1322:
1323:                /**
1324:                 * Returns the compiledSql value.
1325:                 * 
1326:                 * @return Returns the compiledSql.
1327:                 */
1328:                public String getParameters() {
1329:                    return parameters;
1330:                }
1331:
1332:                /**
1333:                 * Returns the sqlTemplate value.
1334:                 * 
1335:                 * @return Returns the sqlTemplate.
1336:                 */
1337:                public String getSqlTemplate() {
1338:                    return sqlTemplate;
1339:                }
1340:            }
1341:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.