Source Code Cross Referenced for ServerPreparedStatement.java in  » Database-JDBC-Connection-Pool » mysql-connector-java-5.1.3 » com » mysql » jdbc » 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 » mysql connector java 5.1.3 » com.mysql.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         Copyright (C) 2002-2007 MySQL AB
0003:
0004:         This program is free software; you can redistribute it and/or modify
0005:         it under the terms of version 2 of the GNU General Public License as 
0006:         published by the Free Software Foundation.
0007:
0008:         There are special exceptions to the terms and conditions of the GPL 
0009:         as it is applied to this software. View the full text of the 
0010:         exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
0011:         software distribution.
0012:
0013:         This program is distributed in the hope that it will be useful,
0014:         but WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016:         GNU General Public License for more details.
0017:
0018:         You should have received a copy of the GNU General Public License
0019:         along with this program; if not, write to the Free Software
0020:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0021:
0022:
0023:
0024:         */
0025:        package com.mysql.jdbc;
0026:
0027:        import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
0028:        import com.mysql.jdbc.exceptions.MySQLTimeoutException;
0029:        import com.mysql.jdbc.profiler.ProfileEventSink;
0030:        import com.mysql.jdbc.profiler.ProfilerEvent;
0031:
0032:        import java.io.IOException;
0033:        import java.io.InputStream;
0034:        import java.io.Reader;
0035:        import java.io.UnsupportedEncodingException;
0036:
0037:        import java.lang.reflect.Constructor;
0038:        import java.lang.reflect.InvocationTargetException;
0039:        import java.math.BigDecimal;
0040:
0041:        import java.net.URL;
0042:
0043:        import java.sql.Array;
0044:        import java.sql.Blob;
0045:        import java.sql.Clob;
0046:        import java.sql.Date;
0047:        import java.sql.ParameterMetaData;
0048:        import java.sql.Ref;
0049:        import java.sql.ResultSet;
0050:        import java.sql.SQLException;
0051:        import java.sql.Time;
0052:        import java.sql.Timestamp;
0053:        import java.sql.Types;
0054:
0055:        import java.util.ArrayList;
0056:        import java.util.Calendar;
0057:        import java.util.Properties;
0058:        import java.util.TimeZone;
0059:
0060:        /**
0061:         * JDBC Interface for MySQL-4.1 and newer server-side PreparedStatements.
0062:         * 
0063:         * @author Mark Matthews
0064:         * @version $Id: ServerPreparedStatement.java,v 1.1.2.2 2005/05/17 14:58:56
0065:         *          mmatthews Exp $
0066:         */
0067:        public class ServerPreparedStatement extends PreparedStatement {
0068:            private static final Constructor JDBC_4_SPS_CTOR;
0069:
0070:            static {
0071:                if (Util.isJdbc4()) {
0072:                    try {
0073:                        JDBC_4_SPS_CTOR = Class.forName(
0074:                                "com.mysql.jdbc.JDBC4ServerPreparedStatement")
0075:                                .getConstructor(
0076:                                        new Class[] { ConnectionImpl.class,
0077:                                                String.class, String.class,
0078:                                                Integer.TYPE, Integer.TYPE });
0079:                    } catch (SecurityException e) {
0080:                        throw new RuntimeException(e);
0081:                    } catch (NoSuchMethodException e) {
0082:                        throw new RuntimeException(e);
0083:                    } catch (ClassNotFoundException e) {
0084:                        throw new RuntimeException(e);
0085:                    }
0086:                } else {
0087:                    JDBC_4_SPS_CTOR = null;
0088:                }
0089:            }
0090:
0091:            protected static final int BLOB_STREAM_READ_BUF_SIZE = 8192;
0092:
0093:            static class BatchedBindValues {
0094:                BindValue[] batchedParameterValues;
0095:
0096:                BatchedBindValues(BindValue[] paramVals) {
0097:                    int numParams = paramVals.length;
0098:
0099:                    this .batchedParameterValues = new BindValue[numParams];
0100:
0101:                    for (int i = 0; i < numParams; i++) {
0102:                        this .batchedParameterValues[i] = new BindValue(
0103:                                paramVals[i]);
0104:                    }
0105:                }
0106:            }
0107:
0108:            public static class BindValue {
0109:
0110:                long boundBeforeExecutionNum = 0;
0111:
0112:                public long bindLength; /* Default length of data */
0113:
0114:                int bufferType; /* buffer type */
0115:
0116:                byte byteBinding;
0117:
0118:                double doubleBinding;
0119:
0120:                float floatBinding;
0121:
0122:                int intBinding;
0123:
0124:                public boolean isLongData; /* long data indicator */
0125:
0126:                public boolean isNull; /* NULL indicator */
0127:
0128:                boolean isSet = false; /* has this parameter been set? */
0129:
0130:                long longBinding;
0131:
0132:                short shortBinding;
0133:
0134:                public Object value; /* The value to store */
0135:
0136:                BindValue() {
0137:                }
0138:
0139:                BindValue(BindValue copyMe) {
0140:                    this .value = copyMe.value;
0141:                    this .isSet = copyMe.isSet;
0142:                    this .isLongData = copyMe.isLongData;
0143:                    this .isNull = copyMe.isNull;
0144:                    this .bufferType = copyMe.bufferType;
0145:                    this .bindLength = copyMe.bindLength;
0146:                    this .byteBinding = copyMe.byteBinding;
0147:                    this .shortBinding = copyMe.shortBinding;
0148:                    this .intBinding = copyMe.intBinding;
0149:                    this .longBinding = copyMe.longBinding;
0150:                    this .floatBinding = copyMe.floatBinding;
0151:                    this .doubleBinding = copyMe.doubleBinding;
0152:                }
0153:
0154:                void reset() {
0155:                    this .isSet = false;
0156:                    this .value = null;
0157:                    this .isLongData = false;
0158:
0159:                    this .byteBinding = 0;
0160:                    this .shortBinding = 0;
0161:                    this .intBinding = 0;
0162:                    this .longBinding = 0L;
0163:                    this .floatBinding = 0;
0164:                    this .doubleBinding = 0D;
0165:                }
0166:
0167:                public String toString() {
0168:                    return toString(false);
0169:                }
0170:
0171:                public String toString(boolean quoteIfNeeded) {
0172:                    if (this .isLongData) {
0173:                        return "' STREAM DATA '";
0174:                    }
0175:
0176:                    switch (this .bufferType) {
0177:                    case MysqlDefs.FIELD_TYPE_TINY:
0178:                        return String.valueOf(byteBinding);
0179:                    case MysqlDefs.FIELD_TYPE_SHORT:
0180:                        return String.valueOf(shortBinding);
0181:                    case MysqlDefs.FIELD_TYPE_LONG:
0182:                        return String.valueOf(intBinding);
0183:                    case MysqlDefs.FIELD_TYPE_LONGLONG:
0184:                        return String.valueOf(longBinding);
0185:                    case MysqlDefs.FIELD_TYPE_FLOAT:
0186:                        return String.valueOf(floatBinding);
0187:                    case MysqlDefs.FIELD_TYPE_DOUBLE:
0188:                        return String.valueOf(doubleBinding);
0189:                    case MysqlDefs.FIELD_TYPE_TIME:
0190:                    case MysqlDefs.FIELD_TYPE_DATE:
0191:                    case MysqlDefs.FIELD_TYPE_DATETIME:
0192:                    case MysqlDefs.FIELD_TYPE_TIMESTAMP:
0193:                    case MysqlDefs.FIELD_TYPE_VAR_STRING:
0194:                    case MysqlDefs.FIELD_TYPE_STRING:
0195:                    case MysqlDefs.FIELD_TYPE_VARCHAR:
0196:                        if (quoteIfNeeded) {
0197:                            return "'" + String.valueOf(value) + "'";
0198:                        } else {
0199:                            return String.valueOf(value);
0200:                        }
0201:                    default:
0202:                        if (value instanceof  byte[]) {
0203:                            return "byte data";
0204:
0205:                        } else {
0206:                            if (quoteIfNeeded) {
0207:                                return "'" + String.valueOf(value) + "'";
0208:                            } else {
0209:                                return String.valueOf(value);
0210:                            }
0211:                        }
0212:                    }
0213:                }
0214:            }
0215:
0216:            /* 1 (length) + 2 (year) + 1 (month) + 1 (day) */
0217:            private static final byte MAX_DATE_REP_LENGTH = (byte) 5;
0218:
0219:            /*
0220:             * 1 (length) + 2 (year) + 1 (month) + 1 (day) + 1 (hour) + 1 (minute) + 1
0221:             * (second) + 4 (microseconds)
0222:             */
0223:            private static final byte MAX_DATETIME_REP_LENGTH = 12;
0224:
0225:            /*
0226:             * 1 (length) + 1 (is negative) + 4 (day count) + 1 (hour) + 1 (minute) + 1
0227:             * (seconds) + 4 (microseconds)
0228:             */
0229:            private static final byte MAX_TIME_REP_LENGTH = 13;
0230:
0231:            private void storeTime(Buffer intoBuf, Time tm) throws SQLException {
0232:
0233:                intoBuf.ensureCapacity(9);
0234:                intoBuf.writeByte((byte) 8); // length
0235:                intoBuf.writeByte((byte) 0); // neg flag
0236:                intoBuf.writeLong(0); // tm->day, not used
0237:
0238:                Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
0239:
0240:                synchronized (sessionCalendar) {
0241:                    java.util.Date oldTime = sessionCalendar.getTime();
0242:                    try {
0243:                        sessionCalendar.setTime(tm);
0244:                        intoBuf.writeByte((byte) sessionCalendar
0245:                                .get(Calendar.HOUR_OF_DAY));
0246:                        intoBuf.writeByte((byte) sessionCalendar
0247:                                .get(Calendar.MINUTE));
0248:                        intoBuf.writeByte((byte) sessionCalendar
0249:                                .get(Calendar.SECOND));
0250:
0251:                        // intoBuf.writeLongInt(0); // tm-second_part
0252:                    } finally {
0253:                        sessionCalendar.setTime(oldTime);
0254:                    }
0255:                }
0256:            }
0257:
0258:            /**
0259:             * Flag indicating whether or not the long parameters have been 'switched'
0260:             * back to normal parameters. We can not execute() if clearParameters()
0261:             * hasn't been called in this case.
0262:             */
0263:            private boolean detectedLongParameterSwitch = false;
0264:
0265:            /**
0266:             * The number of fields in the result set (if any) for this
0267:             * PreparedStatement.
0268:             */
0269:            private int fieldCount;
0270:
0271:            /** Has this prepared statement been marked invalid? */
0272:            private boolean invalid = false;
0273:
0274:            /** If this statement has been marked invalid, what was the reason? */
0275:            private SQLException invalidationException;
0276:
0277:            /** Does this query modify data? */
0278:            private boolean isSelectQuery;
0279:
0280:            private Buffer outByteBuffer;
0281:
0282:            /** Bind values for individual fields */
0283:            private BindValue[] parameterBindings;
0284:
0285:            /** Field-level metadata for parameters */
0286:            private Field[] parameterFields;
0287:
0288:            /** Field-level metadata for result sets. */
0289:            private Field[] resultFields;
0290:
0291:            /** Do we need to send/resend types to the server? */
0292:            private boolean sendTypesToServer = false;
0293:
0294:            /** The ID that the server uses to identify this PreparedStatement */
0295:            private long serverStatementId;
0296:
0297:            /** The type used for string bindings, changes from version-to-version */
0298:            private int stringTypeCode = MysqlDefs.FIELD_TYPE_STRING;
0299:
0300:            private boolean serverNeedsResetBeforeEachExecution;
0301:
0302:            /**
0303:             * Creates a prepared statement instance -- We need to provide factory-style
0304:             * methods so we can support both JDBC3 (and older) and JDBC4 runtimes,
0305:             * otherwise the class verifier complains when it tries to load JDBC4-only
0306:             * interface classes that are present in JDBC4 method signatures.
0307:             */
0308:
0309:            protected static ServerPreparedStatement getInstance(
0310:                    ConnectionImpl conn, String sql, String catalog,
0311:                    int resultSetType, int resultSetConcurrency)
0312:                    throws SQLException {
0313:                if (!Util.isJdbc4()) {
0314:                    return new ServerPreparedStatement(conn, sql, catalog,
0315:                            resultSetType, resultSetConcurrency);
0316:                }
0317:
0318:                try {
0319:                    return (ServerPreparedStatement) JDBC_4_SPS_CTOR
0320:                            .newInstance(new Object[] {
0321:                                    conn,
0322:                                    sql,
0323:                                    catalog,
0324:                                    Constants.integerValueOf(resultSetType),
0325:                                    Constants
0326:                                            .integerValueOf(resultSetConcurrency) });
0327:                } catch (IllegalArgumentException e) {
0328:                    throw new SQLException(e.toString(),
0329:                            SQLError.SQL_STATE_GENERAL_ERROR);
0330:                } catch (InstantiationException e) {
0331:                    throw new SQLException(e.toString(),
0332:                            SQLError.SQL_STATE_GENERAL_ERROR);
0333:                } catch (IllegalAccessException e) {
0334:                    throw new SQLException(e.toString(),
0335:                            SQLError.SQL_STATE_GENERAL_ERROR);
0336:                } catch (InvocationTargetException e) {
0337:                    Throwable target = e.getTargetException();
0338:
0339:                    if (target instanceof  SQLException) {
0340:                        throw (SQLException) target;
0341:                    }
0342:
0343:                    throw new SQLException(target.toString(),
0344:                            SQLError.SQL_STATE_GENERAL_ERROR);
0345:                }
0346:            }
0347:
0348:            /**
0349:             * Creates a new ServerPreparedStatement object.
0350:             * 
0351:             * @param conn
0352:             *            the connection creating us.
0353:             * @param sql
0354:             *            the SQL containing the statement to prepare.
0355:             * @param catalog
0356:             *            the catalog in use when we were created.
0357:             * 
0358:             * @throws SQLException
0359:             *             If an error occurs
0360:             */
0361:            protected ServerPreparedStatement(ConnectionImpl conn, String sql,
0362:                    String catalog, int resultSetType, int resultSetConcurrency)
0363:                    throws SQLException {
0364:                super (conn, catalog);
0365:
0366:                checkNullOrEmptyQuery(sql);
0367:
0368:                this .isSelectQuery = StringUtils.startsWithIgnoreCaseAndWs(sql,
0369:                        "SELECT"); //$NON-NLS-1$
0370:
0371:                if (this .connection.versionMeetsMinimum(5, 0, 0)) {
0372:                    this .serverNeedsResetBeforeEachExecution = !this .connection
0373:                            .versionMeetsMinimum(5, 0, 3);
0374:                } else {
0375:                    this .serverNeedsResetBeforeEachExecution = !this .connection
0376:                            .versionMeetsMinimum(4, 1, 10);
0377:                }
0378:
0379:                this .useTrueBoolean = this .connection.versionMeetsMinimum(3,
0380:                        21, 23);
0381:                this .hasLimitClause = (StringUtils.indexOfIgnoreCase(sql,
0382:                        "LIMIT") != -1); //$NON-NLS-1$
0383:                this .firstCharOfStmt = StringUtils.firstNonWsCharUc(sql);
0384:                String statementComment = this .connection.getStatementComment();
0385:
0386:                this .originalSql = (statementComment == null) ? sql : "/* "
0387:                        + statementComment + " */ " + sql;
0388:
0389:                if (this .connection.versionMeetsMinimum(4, 1, 2)) {
0390:                    this .stringTypeCode = MysqlDefs.FIELD_TYPE_VAR_STRING;
0391:                } else {
0392:                    this .stringTypeCode = MysqlDefs.FIELD_TYPE_STRING;
0393:                }
0394:
0395:                try {
0396:                    serverPrepare(sql);
0397:                } catch (SQLException sqlEx) {
0398:                    realClose(false, true);
0399:                    // don't wrap SQLExceptions
0400:                    throw sqlEx;
0401:                } catch (Exception ex) {
0402:                    realClose(false, true);
0403:
0404:                    throw SQLError.createSQLException(ex.toString(),
0405:                            SQLError.SQL_STATE_GENERAL_ERROR);
0406:                }
0407:
0408:                setResultSetType(resultSetType);
0409:                setResultSetConcurrency(resultSetConcurrency);
0410:
0411:                this .parameterTypes = new int[this .parameterCount];
0412:            }
0413:
0414:            /**
0415:             * JDBC 2.0 Add a set of parameters to the batch.
0416:             * 
0417:             * @exception SQLException
0418:             *                if a database-access error occurs.
0419:             * 
0420:             * @see StatementImpl#addBatch
0421:             */
0422:            public synchronized void addBatch() throws SQLException {
0423:                checkClosed();
0424:
0425:                if (this .batchedArgs == null) {
0426:                    this .batchedArgs = new ArrayList();
0427:                }
0428:
0429:                this .batchedArgs.add(new BatchedBindValues(
0430:                        this .parameterBindings));
0431:            }
0432:
0433:            protected String asSql(boolean quoteStreamsAndUnknowns)
0434:                    throws SQLException {
0435:
0436:                if (this .isClosed) {
0437:                    return "statement has been closed, no further internal information available";
0438:                }
0439:
0440:                PreparedStatement pStmtForSub = null;
0441:
0442:                try {
0443:                    pStmtForSub = PreparedStatement.getInstance(
0444:                            this .connection, this .originalSql,
0445:                            this .currentCatalog);
0446:
0447:                    int numParameters = pStmtForSub.parameterCount;
0448:                    int ourNumParameters = this .parameterCount;
0449:
0450:                    for (int i = 0; (i < numParameters)
0451:                            && (i < ourNumParameters); i++) {
0452:                        if (this .parameterBindings[i] != null) {
0453:                            if (this .parameterBindings[i].isNull) {
0454:                                pStmtForSub.setNull(i + 1, Types.NULL);
0455:                            } else {
0456:                                BindValue bindValue = this .parameterBindings[i];
0457:
0458:                                //
0459:                                // Handle primitives first
0460:                                //
0461:                                switch (bindValue.bufferType) {
0462:
0463:                                case MysqlDefs.FIELD_TYPE_TINY:
0464:                                    pStmtForSub.setByte(i + 1,
0465:                                            bindValue.byteBinding);
0466:                                    break;
0467:                                case MysqlDefs.FIELD_TYPE_SHORT:
0468:                                    pStmtForSub.setShort(i + 1,
0469:                                            bindValue.shortBinding);
0470:                                    break;
0471:                                case MysqlDefs.FIELD_TYPE_LONG:
0472:                                    pStmtForSub.setInt(i + 1,
0473:                                            bindValue.intBinding);
0474:                                    break;
0475:                                case MysqlDefs.FIELD_TYPE_LONGLONG:
0476:                                    pStmtForSub.setLong(i + 1,
0477:                                            bindValue.longBinding);
0478:                                    break;
0479:                                case MysqlDefs.FIELD_TYPE_FLOAT:
0480:                                    pStmtForSub.setFloat(i + 1,
0481:                                            bindValue.floatBinding);
0482:                                    break;
0483:                                case MysqlDefs.FIELD_TYPE_DOUBLE:
0484:                                    pStmtForSub.setDouble(i + 1,
0485:                                            bindValue.doubleBinding);
0486:                                    break;
0487:                                default:
0488:                                    pStmtForSub.setObject(i + 1,
0489:                                            this .parameterBindings[i].value);
0490:                                    break;
0491:                                }
0492:                            }
0493:                        }
0494:                    }
0495:
0496:                    return pStmtForSub.asSql(quoteStreamsAndUnknowns);
0497:                } finally {
0498:                    if (pStmtForSub != null) {
0499:                        try {
0500:                            pStmtForSub.close();
0501:                        } catch (SQLException sqlEx) {
0502:                            ; // ignore
0503:                        }
0504:                    }
0505:                }
0506:            }
0507:
0508:            /*
0509:             * (non-Javadoc)
0510:             * 
0511:             * @see com.mysql.jdbc.Statement#checkClosed()
0512:             */
0513:            protected void checkClosed() throws SQLException {
0514:                if (this .invalid) {
0515:                    throw this .invalidationException;
0516:                }
0517:
0518:                super .checkClosed();
0519:            }
0520:
0521:            /**
0522:             * @see java.sql.PreparedStatement#clearParameters()
0523:             */
0524:            public void clearParameters() throws SQLException {
0525:                checkClosed();
0526:                clearParametersInternal(true);
0527:            }
0528:
0529:            private void clearParametersInternal(boolean clearServerParameters)
0530:                    throws SQLException {
0531:                boolean hadLongData = false;
0532:
0533:                if (this .parameterBindings != null) {
0534:                    for (int i = 0; i < this .parameterCount; i++) {
0535:                        if ((this .parameterBindings[i] != null)
0536:                                && this .parameterBindings[i].isLongData) {
0537:                            hadLongData = true;
0538:                        }
0539:
0540:                        this .parameterBindings[i].reset();
0541:                    }
0542:                }
0543:
0544:                if (clearServerParameters && hadLongData) {
0545:                    serverResetStatement();
0546:
0547:                    this .detectedLongParameterSwitch = false;
0548:                }
0549:            }
0550:
0551:            protected boolean isCached = false;
0552:
0553:            protected void setClosed(boolean flag) {
0554:                this .isClosed = flag;
0555:            }
0556:
0557:            /**
0558:             * @see java.sql.Statement#close()
0559:             */
0560:            public void close() throws SQLException {
0561:                if (this .isCached) {
0562:                    this .isClosed = true;
0563:                    this .connection.recachePreparedStatement(this );
0564:                    return;
0565:                }
0566:
0567:                realClose(true, true);
0568:            }
0569:
0570:            private void dumpCloseForTestcase() {
0571:                StringBuffer buf = new StringBuffer();
0572:                this .connection.generateConnectionCommentBlock(buf);
0573:                buf.append("DEALLOCATE PREPARE debug_stmt_");
0574:                buf.append(this .statementId);
0575:                buf.append(";\n");
0576:
0577:                this .connection.dumpTestcaseQuery(buf.toString());
0578:            }
0579:
0580:            private void dumpExecuteForTestcase() throws SQLException {
0581:                StringBuffer buf = new StringBuffer();
0582:
0583:                for (int i = 0; i < this .parameterCount; i++) {
0584:                    this .connection.generateConnectionCommentBlock(buf);
0585:
0586:                    buf.append("SET @debug_stmt_param");
0587:                    buf.append(this .statementId);
0588:                    buf.append("_");
0589:                    buf.append(i);
0590:                    buf.append("=");
0591:
0592:                    if (this .parameterBindings[i].isNull) {
0593:                        buf.append("NULL");
0594:                    } else {
0595:                        buf.append(this .parameterBindings[i].toString(true));
0596:                    }
0597:
0598:                    buf.append(";\n");
0599:                }
0600:
0601:                this .connection.generateConnectionCommentBlock(buf);
0602:
0603:                buf.append("EXECUTE debug_stmt_");
0604:                buf.append(this .statementId);
0605:
0606:                if (this .parameterCount > 0) {
0607:                    buf.append(" USING ");
0608:                    for (int i = 0; i < this .parameterCount; i++) {
0609:                        if (i > 0) {
0610:                            buf.append(", ");
0611:                        }
0612:
0613:                        buf.append("@debug_stmt_param");
0614:                        buf.append(this .statementId);
0615:                        buf.append("_");
0616:                        buf.append(i);
0617:
0618:                    }
0619:                }
0620:
0621:                buf.append(";\n");
0622:
0623:                this .connection.dumpTestcaseQuery(buf.toString());
0624:            }
0625:
0626:            private void dumpPrepareForTestcase() throws SQLException {
0627:
0628:                StringBuffer buf = new StringBuffer(
0629:                        this .originalSql.length() + 64);
0630:
0631:                this .connection.generateConnectionCommentBlock(buf);
0632:
0633:                buf.append("PREPARE debug_stmt_");
0634:                buf.append(this .statementId);
0635:                buf.append(" FROM \"");
0636:                buf.append(this .originalSql);
0637:                buf.append("\";\n");
0638:
0639:                this .connection.dumpTestcaseQuery(buf.toString());
0640:            }
0641:
0642:            /**
0643:             * @see java.sql.Statement#executeBatch()
0644:             */
0645:            public synchronized int[] executeBatch() throws SQLException {
0646:                if (this .connection.isReadOnly()) {
0647:                    throw SQLError.createSQLException(Messages
0648:                            .getString("ServerPreparedStatement.2") //$NON-NLS-1$
0649:                            + Messages.getString("ServerPreparedStatement.3"), //$NON-NLS-1$
0650:                            SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
0651:                }
0652:
0653:                checkClosed();
0654:
0655:                synchronized (this .connection.getMutex()) {
0656:                    clearWarnings();
0657:
0658:                    // Store this for later, we're going to 'swap' them out
0659:                    // as we execute each batched statement...
0660:                    BindValue[] oldBindValues = this .parameterBindings;
0661:
0662:                    try {
0663:                        int[] updateCounts = null;
0664:
0665:                        if (this .batchedArgs != null) {
0666:                            int nbrCommands = this .batchedArgs.size();
0667:                            updateCounts = new int[nbrCommands];
0668:
0669:                            if (this .retrieveGeneratedKeys) {
0670:                                this .batchedGeneratedKeys = new ArrayList(
0671:                                        nbrCommands);
0672:                            }
0673:
0674:                            for (int i = 0; i < nbrCommands; i++) {
0675:                                updateCounts[i] = -3;
0676:                            }
0677:
0678:                            SQLException sqlEx = null;
0679:
0680:                            int commandIndex = 0;
0681:
0682:                            BindValue[] previousBindValuesForBatch = null;
0683:
0684:                            for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) {
0685:                                Object arg = this .batchedArgs.get(commandIndex);
0686:
0687:                                if (arg instanceof  String) {
0688:                                    updateCounts[commandIndex] = executeUpdate((String) arg);
0689:                                } else {
0690:                                    this .parameterBindings = ((BatchedBindValues) arg).batchedParameterValues;
0691:
0692:                                    try {
0693:                                        // We need to check types each time, as
0694:                                        // the user might have bound different
0695:                                        // types in each addBatch()
0696:
0697:                                        if (previousBindValuesForBatch != null) {
0698:                                            for (int j = 0; j < this .parameterBindings.length; j++) {
0699:                                                if (this .parameterBindings[j].bufferType != previousBindValuesForBatch[j].bufferType) {
0700:                                                    this .sendTypesToServer = true;
0701:
0702:                                                    break;
0703:                                                }
0704:                                            }
0705:                                        }
0706:
0707:                                        try {
0708:                                            updateCounts[commandIndex] = executeUpdate(
0709:                                                    false, true);
0710:                                        } finally {
0711:                                            previousBindValuesForBatch = this .parameterBindings;
0712:                                        }
0713:
0714:                                        if (this .retrieveGeneratedKeys) {
0715:                                            java.sql.ResultSet rs = null;
0716:
0717:                                            try {
0718:                                                // we don't want to use our version,
0719:                                                // because we've altered the behavior of
0720:                                                // ours to support batch updates
0721:                                                // (catch-22)
0722:                                                // Ideally, what we need here is
0723:                                                // super.super.getGeneratedKeys()
0724:                                                // but that construct doesn't exist in
0725:                                                // Java, so that's why there's
0726:                                                // this kludge.
0727:                                                rs = getGeneratedKeysInternal();
0728:
0729:                                                while (rs.next()) {
0730:                                                    this .batchedGeneratedKeys
0731:                                                            .add(new ByteArrayRow(
0732:                                                                    new byte[][] { rs
0733:                                                                            .getBytes(1) }));
0734:                                                }
0735:                                            } finally {
0736:                                                if (rs != null) {
0737:                                                    rs.close();
0738:                                                }
0739:                                            }
0740:                                        }
0741:                                    } catch (SQLException ex) {
0742:                                        updateCounts[commandIndex] = EXECUTE_FAILED;
0743:
0744:                                        if (this .continueBatchOnError) {
0745:                                            sqlEx = ex;
0746:                                        } else {
0747:                                            int[] newUpdateCounts = new int[commandIndex];
0748:                                            System.arraycopy(updateCounts, 0,
0749:                                                    newUpdateCounts, 0,
0750:                                                    commandIndex);
0751:
0752:                                            throw new java.sql.BatchUpdateException(
0753:                                                    ex.getMessage(), ex
0754:                                                            .getSQLState(), ex
0755:                                                            .getErrorCode(),
0756:                                                    newUpdateCounts);
0757:                                        }
0758:                                    }
0759:                                }
0760:                            }
0761:
0762:                            if (sqlEx != null) {
0763:                                throw new java.sql.BatchUpdateException(sqlEx
0764:                                        .getMessage(), sqlEx.getSQLState(),
0765:                                        sqlEx.getErrorCode(), updateCounts);
0766:                            }
0767:                        }
0768:
0769:                        return (updateCounts != null) ? updateCounts
0770:                                : new int[0];
0771:                    } finally {
0772:                        this .parameterBindings = oldBindValues;
0773:                        this .sendTypesToServer = true;
0774:
0775:                        clearBatch();
0776:                    }
0777:                }
0778:            }
0779:
0780:            /**
0781:             * @see com.mysql.jdbc.PreparedStatement#executeInternal(int,
0782:             *      com.mysql.jdbc.Buffer, boolean, boolean)
0783:             */
0784:            protected com.mysql.jdbc.ResultSetInternalMethods executeInternal(
0785:                    int maxRowsToRetrieve, Buffer sendPacket,
0786:                    boolean createStreamingResultSet,
0787:                    boolean queryIsSelectOnly, Field[] metadataFromCache,
0788:                    boolean isBatch) throws SQLException {
0789:                this .numberOfExecutions++;
0790:
0791:                // We defer to server-side execution
0792:                try {
0793:                    return serverExecute(maxRowsToRetrieve,
0794:                            createStreamingResultSet, metadataFromCache);
0795:                } catch (SQLException sqlEx) {
0796:                    // don't wrap SQLExceptions
0797:                    if (this .connection.getEnablePacketDebug()) {
0798:                        this .connection.getIO().dumpPacketRingBuffer();
0799:                    }
0800:
0801:                    if (this .connection.getDumpQueriesOnException()) {
0802:                        String extractedSql = toString();
0803:                        StringBuffer messageBuf = new StringBuffer(extractedSql
0804:                                .length() + 32);
0805:                        messageBuf
0806:                                .append("\n\nQuery being executed when exception was thrown:\n\n");
0807:                        messageBuf.append(extractedSql);
0808:
0809:                        sqlEx = ConnectionImpl.appendMessageToException(sqlEx,
0810:                                messageBuf.toString());
0811:                    }
0812:
0813:                    throw sqlEx;
0814:                } catch (Exception ex) {
0815:                    if (this .connection.getEnablePacketDebug()) {
0816:                        this .connection.getIO().dumpPacketRingBuffer();
0817:                    }
0818:
0819:                    SQLException sqlEx = SQLError.createSQLException(ex
0820:                            .toString(), SQLError.SQL_STATE_GENERAL_ERROR);
0821:
0822:                    if (this .connection.getDumpQueriesOnException()) {
0823:                        String extractedSql = toString();
0824:                        StringBuffer messageBuf = new StringBuffer(extractedSql
0825:                                .length() + 32);
0826:                        messageBuf
0827:                                .append("\n\nQuery being executed when exception was thrown:\n\n");
0828:                        messageBuf.append(extractedSql);
0829:
0830:                        sqlEx = ConnectionImpl.appendMessageToException(sqlEx,
0831:                                messageBuf.toString());
0832:                    }
0833:
0834:                    throw sqlEx;
0835:                }
0836:            }
0837:
0838:            /**
0839:             * @see com.mysql.jdbc.PreparedStatement#fillSendPacket()
0840:             */
0841:            protected Buffer fillSendPacket() throws SQLException {
0842:                return null; // we don't use this type of packet
0843:            }
0844:
0845:            /**
0846:             * @see com.mysql.jdbc.PreparedStatement#fillSendPacket(byte,
0847:             *      java.io.InputStream, boolean, int)
0848:             */
0849:            protected Buffer fillSendPacket(byte[][] batchedParameterStrings,
0850:                    InputStream[] batchedParameterStreams,
0851:                    boolean[] batchedIsStream, int[] batchedStreamLengths)
0852:                    throws SQLException {
0853:                return null; // we don't use this type of packet
0854:            }
0855:
0856:            /**
0857:             * Returns the structure representing the value that (can be)/(is)
0858:             * bound at the given parameter index.
0859:             * 
0860:             * @param parameterIndex 1-based
0861:             * @param forLongData is this for a stream?
0862:             * @return
0863:             * @throws SQLException
0864:             */
0865:            protected BindValue getBinding(int parameterIndex,
0866:                    boolean forLongData) throws SQLException {
0867:                checkClosed();
0868:
0869:                if (this .parameterBindings.length == 0) {
0870:                    throw SQLError.createSQLException(Messages
0871:                            .getString("ServerPreparedStatement.8"), //$NON-NLS-1$
0872:                            SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
0873:                }
0874:
0875:                parameterIndex--;
0876:
0877:                if ((parameterIndex < 0)
0878:                        || (parameterIndex >= this .parameterBindings.length)) {
0879:                    throw SQLError.createSQLException(Messages
0880:                            .getString("ServerPreparedStatement.9") //$NON-NLS-1$
0881:                            + (parameterIndex + 1)
0882:                            + Messages.getString("ServerPreparedStatement.10") //$NON-NLS-1$
0883:                            + this .parameterBindings.length,
0884:                            SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
0885:                }
0886:
0887:                if (this .parameterBindings[parameterIndex] == null) {
0888:                    this .parameterBindings[parameterIndex] = new BindValue();
0889:                } else {
0890:                    if (this .parameterBindings[parameterIndex].isLongData
0891:                            && !forLongData) {
0892:                        this .detectedLongParameterSwitch = true;
0893:                    }
0894:                }
0895:
0896:                this .parameterBindings[parameterIndex].isSet = true;
0897:                this .parameterBindings[parameterIndex].boundBeforeExecutionNum = this .numberOfExecutions;
0898:
0899:                return this .parameterBindings[parameterIndex];
0900:            }
0901:
0902:            /**
0903:             * @see com.mysql.jdbc.PreparedStatement#getBytes(int)
0904:             */
0905:            byte[] getBytes(int parameterIndex) throws SQLException {
0906:                BindValue bindValue = getBinding(parameterIndex, false);
0907:
0908:                if (bindValue.isNull) {
0909:                    return null;
0910:                } else if (bindValue.isLongData) {
0911:                    throw new NotImplemented();
0912:                } else {
0913:                    if (this .outByteBuffer == null) {
0914:                        this .outByteBuffer = new Buffer(this .connection
0915:                                .getNetBufferLength());
0916:                    }
0917:
0918:                    this .outByteBuffer.clear();
0919:
0920:                    int originalPosition = this .outByteBuffer.getPosition();
0921:
0922:                    storeBinding(this .outByteBuffer, bindValue, this .connection
0923:                            .getIO());
0924:
0925:                    int newPosition = this .outByteBuffer.getPosition();
0926:
0927:                    int length = newPosition - originalPosition;
0928:
0929:                    byte[] valueAsBytes = new byte[length];
0930:
0931:                    System.arraycopy(this .outByteBuffer.getByteBuffer(),
0932:                            originalPosition, valueAsBytes, 0, length);
0933:
0934:                    return valueAsBytes;
0935:                }
0936:            }
0937:
0938:            /**
0939:             * @see java.sql.PreparedStatement#getMetaData()
0940:             */
0941:            public java.sql.ResultSetMetaData getMetaData() throws SQLException {
0942:                checkClosed();
0943:
0944:                if (this .resultFields == null) {
0945:                    return null;
0946:                }
0947:
0948:                return new ResultSetMetaData(this .resultFields, this .connection
0949:                        .getUseOldAliasMetadataBehavior());
0950:            }
0951:
0952:            /**
0953:             * @see java.sql.PreparedStatement#getParameterMetaData()
0954:             */
0955:            public ParameterMetaData getParameterMetaData() throws SQLException {
0956:                checkClosed();
0957:
0958:                if (this .parameterMetaData == null) {
0959:                    this .parameterMetaData = new MysqlParameterMetadata(
0960:                            this .parameterFields, this .parameterCount);
0961:                }
0962:
0963:                return this .parameterMetaData;
0964:            }
0965:
0966:            /**
0967:             * @see com.mysql.jdbc.PreparedStatement#isNull(int)
0968:             */
0969:            boolean isNull(int paramIndex) {
0970:                throw new IllegalArgumentException(Messages
0971:                        .getString("ServerPreparedStatement.7")); //$NON-NLS-1$
0972:            }
0973:
0974:            /**
0975:             * Closes this connection and frees all resources.
0976:             * 
0977:             * @param calledExplicitly
0978:             *            was this called from close()?
0979:             * 
0980:             * @throws SQLException
0981:             *             if an error occurs
0982:             */
0983:            protected void realClose(boolean calledExplicitly,
0984:                    boolean closeOpenResults) throws SQLException {
0985:                if (this .isClosed) {
0986:                    return;
0987:                }
0988:
0989:                if (this .connection != null) {
0990:                    if (this .connection.getAutoGenerateTestcaseScript()) {
0991:                        dumpCloseForTestcase();
0992:                    }
0993:
0994:                    //
0995:                    // Don't communicate with the server if we're being
0996:                    // called from the finalizer...
0997:                    // 
0998:                    // This will leak server resources, but if we don't do this,
0999:                    // we'll deadlock (potentially, because there's no guarantee
1000:                    // when, what order, and what concurrency finalizers will be
1001:                    // called with). Well-behaved programs won't rely on finalizers
1002:                    // to clean up their statements.
1003:                    //
1004:
1005:                    SQLException exceptionDuringClose = null;
1006:
1007:                    if (calledExplicitly && !this .connection.isClosed()) {
1008:                        synchronized (this .connection.getMutex()) {
1009:                            try {
1010:
1011:                                MysqlIO mysql = this .connection.getIO();
1012:
1013:                                Buffer packet = mysql.getSharedSendPacket();
1014:
1015:                                packet
1016:                                        .writeByte((byte) MysqlDefs.COM_CLOSE_STATEMENT);
1017:                                packet.writeLong(this .serverStatementId);
1018:
1019:                                mysql.sendCommand(
1020:                                        MysqlDefs.COM_CLOSE_STATEMENT, null,
1021:                                        packet, true, null);
1022:                            } catch (SQLException sqlEx) {
1023:                                exceptionDuringClose = sqlEx;
1024:                            }
1025:                        }
1026:                    }
1027:
1028:                    super .realClose(calledExplicitly, closeOpenResults);
1029:
1030:                    clearParametersInternal(false);
1031:                    this .parameterBindings = null;
1032:
1033:                    this .parameterFields = null;
1034:                    this .resultFields = null;
1035:
1036:                    if (exceptionDuringClose != null) {
1037:                        throw exceptionDuringClose;
1038:                    }
1039:                }
1040:            }
1041:
1042:            /**
1043:             * Used by Connection when auto-reconnecting to retrieve 'lost' prepared
1044:             * statements.
1045:             * 
1046:             * @throws SQLException
1047:             *             if an error occurs.
1048:             */
1049:            protected void rePrepare() throws SQLException {
1050:                this .invalidationException = null;
1051:
1052:                try {
1053:                    serverPrepare(this .originalSql);
1054:                } catch (SQLException sqlEx) {
1055:                    // don't wrap SQLExceptions
1056:                    this .invalidationException = sqlEx;
1057:                } catch (Exception ex) {
1058:                    this .invalidationException = SQLError.createSQLException(ex
1059:                            .toString(), SQLError.SQL_STATE_GENERAL_ERROR);
1060:                }
1061:
1062:                if (this .invalidationException != null) {
1063:                    this .invalid = true;
1064:
1065:                    this .parameterBindings = null;
1066:
1067:                    this .parameterFields = null;
1068:                    this .resultFields = null;
1069:
1070:                    if (this .results != null) {
1071:                        try {
1072:                            this .results.close();
1073:                        } catch (Exception ex) {
1074:                            ;
1075:                        }
1076:                    }
1077:
1078:                    if (this .connection != null) {
1079:                        if (this .maxRowsChanged) {
1080:                            this .connection.unsetMaxRows(this );
1081:                        }
1082:
1083:                        if (!this .connection.getDontTrackOpenResources()) {
1084:                            this .connection.unregisterStatement(this );
1085:                        }
1086:                    }
1087:                }
1088:            }
1089:
1090:            /**
1091:             * Tells the server to execute this prepared statement with the current
1092:             * parameter bindings.
1093:             * 
1094:             * <pre>
1095:             * 
1096:             * 
1097:             *    -   Server gets the command 'COM_EXECUTE' to execute the
1098:             *        previously         prepared query. If there is any param markers;
1099:             *  then client will send the data in the following format:
1100:             * 
1101:             *  [COM_EXECUTE:1]
1102:             *  [STMT_ID:4]
1103:             *  [NULL_BITS:(param_count+7)/8)]
1104:             *  [TYPES_SUPPLIED_BY_CLIENT(0/1):1]
1105:             *  [[length]data]
1106:             *  [[length]data] .. [[length]data].
1107:             * 
1108:             *  (Note: Except for string/binary types; all other types will not be
1109:             *  supplied with length field)
1110:             * 
1111:             *  
1112:             * </pre>
1113:             * 
1114:             * @param maxRowsToRetrieve
1115:             *            DOCUMENT ME!
1116:             * @param createStreamingResultSet
1117:             *            DOCUMENT ME!
1118:             * 
1119:             * @return DOCUMENT ME!
1120:             * 
1121:             * @throws SQLException
1122:             */
1123:            private com.mysql.jdbc.ResultSetInternalMethods serverExecute(
1124:                    int maxRowsToRetrieve, boolean createStreamingResultSet,
1125:                    Field[] metadataFromCache) throws SQLException {
1126:                synchronized (this .connection.getMutex()) {
1127:                    if (this .detectedLongParameterSwitch) {
1128:                        // Check when values were bound
1129:                        boolean firstFound = false;
1130:                        long boundTimeToCheck = 0;
1131:
1132:                        for (int i = 0; i < this .parameterCount - 1; i++) {
1133:                            if (this .parameterBindings[i].isLongData) {
1134:                                if (firstFound
1135:                                        && boundTimeToCheck != this .parameterBindings[i].boundBeforeExecutionNum) {
1136:                                    throw SQLError
1137:                                            .createSQLException(
1138:                                                    Messages
1139:                                                            .getString("ServerPreparedStatement.11") //$NON-NLS-1$
1140:                                                            + Messages
1141:                                                                    .getString("ServerPreparedStatement.12"), //$NON-NLS-1$
1142:                                                    SQLError.SQL_STATE_DRIVER_NOT_CAPABLE);
1143:                                } else {
1144:                                    firstFound = true;
1145:                                    boundTimeToCheck = this .parameterBindings[i].boundBeforeExecutionNum;
1146:                                }
1147:                            }
1148:                        }
1149:
1150:                        // Okay, we've got all "newly"-bound streams, so reset 
1151:                        // server-side state to clear out previous bindings
1152:
1153:                        serverResetStatement();
1154:                    }
1155:
1156:                    // Check bindings
1157:                    for (int i = 0; i < this .parameterCount; i++) {
1158:                        if (!this .parameterBindings[i].isSet) {
1159:                            throw SQLError
1160:                                    .createSQLException(
1161:                                            Messages
1162:                                                    .getString("ServerPreparedStatement.13") + (i + 1) //$NON-NLS-1$
1163:                                                    + Messages
1164:                                                            .getString("ServerPreparedStatement.14"),
1165:                                            SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1166:                        }
1167:                    }
1168:
1169:                    //
1170:                    // Send all long data
1171:                    //
1172:                    for (int i = 0; i < this .parameterCount; i++) {
1173:                        if (this .parameterBindings[i].isLongData) {
1174:                            serverLongData(i, this .parameterBindings[i]);
1175:                        }
1176:                    }
1177:
1178:                    if (this .connection.getAutoGenerateTestcaseScript()) {
1179:                        dumpExecuteForTestcase();
1180:                    }
1181:
1182:                    //
1183:                    // store the parameter values
1184:                    //
1185:                    MysqlIO mysql = this .connection.getIO();
1186:
1187:                    Buffer packet = mysql.getSharedSendPacket();
1188:
1189:                    packet.clear();
1190:                    packet.writeByte((byte) MysqlDefs.COM_EXECUTE);
1191:                    packet.writeLong(this .serverStatementId);
1192:
1193:                    boolean usingCursor = false;
1194:
1195:                    if (this .connection.versionMeetsMinimum(4, 1, 2)) {
1196:                        // we only create cursor-backed result sets if
1197:                        // a) The query is a SELECT
1198:                        // b) The server supports it
1199:                        // c) We know it is forward-only (note this doesn't
1200:                        // preclude updatable result sets)
1201:                        // d) The user has set a fetch size
1202:                        if (this .resultFields != null
1203:                                && this .connection.isCursorFetchEnabled()
1204:                                && getResultSetType() == ResultSet.TYPE_FORWARD_ONLY
1205:                                && getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY
1206:                                && getFetchSize() > 0) {
1207:                            packet.writeByte(MysqlDefs.OPEN_CURSOR_FLAG);
1208:                            usingCursor = true;
1209:                        } else {
1210:                            packet.writeByte((byte) 0); // placeholder for flags
1211:                        }
1212:
1213:                        packet.writeLong(1); // placeholder for parameter
1214:                        // iterations
1215:                    }
1216:
1217:                    /* Reserve place for null-marker bytes */
1218:                    int nullCount = (this .parameterCount + 7) / 8;
1219:
1220:                    // if (mysql.versionMeetsMinimum(4, 1, 2)) {
1221:                    // nullCount = (this.parameterCount + 9) / 8;
1222:                    // }
1223:                    int nullBitsPosition = packet.getPosition();
1224:
1225:                    for (int i = 0; i < nullCount; i++) {
1226:                        packet.writeByte((byte) 0);
1227:                    }
1228:
1229:                    byte[] nullBitsBuffer = new byte[nullCount];
1230:
1231:                    /* In case if buffers (type) altered, indicate to server */
1232:                    packet.writeByte(this .sendTypesToServer ? (byte) 1
1233:                            : (byte) 0);
1234:
1235:                    if (this .sendTypesToServer) {
1236:                        /*
1237:                         * Store types of parameters in first in first package that is
1238:                         * sent to the server.
1239:                         */
1240:                        for (int i = 0; i < this .parameterCount; i++) {
1241:                            packet
1242:                                    .writeInt(this .parameterBindings[i].bufferType);
1243:                        }
1244:                    }
1245:
1246:                    //
1247:                    // store the parameter values
1248:                    //
1249:                    for (int i = 0; i < this .parameterCount; i++) {
1250:                        if (!this .parameterBindings[i].isLongData) {
1251:                            if (!this .parameterBindings[i].isNull) {
1252:                                storeBinding(packet, this .parameterBindings[i],
1253:                                        mysql);
1254:                            } else {
1255:                                nullBitsBuffer[i / 8] |= (1 << (i & 7));
1256:                            }
1257:                        }
1258:                    }
1259:
1260:                    //
1261:                    // Go back and write the NULL flags
1262:                    // to the beginning of the packet
1263:                    //
1264:                    int endPosition = packet.getPosition();
1265:                    packet.setPosition(nullBitsPosition);
1266:                    packet.writeBytesNoNull(nullBitsBuffer);
1267:                    packet.setPosition(endPosition);
1268:
1269:                    long begin = 0;
1270:
1271:                    boolean logSlowQueries = this .connection
1272:                            .getLogSlowQueries();
1273:                    boolean gatherPerformanceMetrics = this .connection
1274:                            .getGatherPerformanceMetrics();
1275:
1276:                    if (this .profileSQL || logSlowQueries
1277:                            || gatherPerformanceMetrics) {
1278:                        begin = mysql.getCurrentTimeNanosOrMillis();
1279:                    }
1280:
1281:                    resetCancelledState();
1282:
1283:                    CancelTask timeoutTask = null;
1284:
1285:                    try {
1286:                        if (this .connection.getEnableQueryTimeouts()
1287:                                && this .timeoutInMillis != 0
1288:                                && this .connection.versionMeetsMinimum(5, 0, 0)) {
1289:                            timeoutTask = new CancelTask(this );
1290:                            this .connection.getCancelTimer().schedule(
1291:                                    timeoutTask, this .timeoutInMillis);
1292:                        }
1293:
1294:                        Buffer resultPacket = mysql.sendCommand(
1295:                                MysqlDefs.COM_EXECUTE, null, packet, false,
1296:                                null);
1297:
1298:                        long queryEndTime = 0L;
1299:
1300:                        if (logSlowQueries || gatherPerformanceMetrics
1301:                                || this .profileSQL) {
1302:                            queryEndTime = mysql.getCurrentTimeNanosOrMillis();
1303:                        }
1304:
1305:                        if (timeoutTask != null) {
1306:                            timeoutTask.cancel();
1307:
1308:                            if (timeoutTask.caughtWhileCancelling != null) {
1309:                                throw timeoutTask.caughtWhileCancelling;
1310:                            }
1311:
1312:                            timeoutTask = null;
1313:                        }
1314:
1315:                        synchronized (this .cancelTimeoutMutex) {
1316:                            if (this .wasCancelled) {
1317:                                SQLException cause = null;
1318:
1319:                                if (this .wasCancelledByTimeout) {
1320:                                    cause = new MySQLTimeoutException();
1321:                                } else {
1322:                                    cause = new MySQLStatementCancelledException();
1323:                                }
1324:
1325:                                resetCancelledState();
1326:
1327:                                throw cause;
1328:                            }
1329:                        }
1330:
1331:                        boolean queryWasSlow = false;
1332:
1333:                        if (logSlowQueries || gatherPerformanceMetrics) {
1334:                            long elapsedTime = queryEndTime - begin;
1335:
1336:                            if (logSlowQueries
1337:                                    && (elapsedTime >= mysql
1338:                                            .getSlowQueryThreshold())) {
1339:                                queryWasSlow = true;
1340:
1341:                                StringBuffer mesgBuf = new StringBuffer(
1342:                                        48 + this .originalSql.length());
1343:                                mesgBuf
1344:                                        .append(Messages
1345:                                                .getString("ServerPreparedStatement.15")); //$NON-NLS-1$
1346:                                mesgBuf.append(mysql.getSlowQueryThreshold());
1347:                                mesgBuf
1348:                                        .append(Messages
1349:                                                .getString("ServerPreparedStatement.15a")); //$NON-NLS-1$
1350:                                mesgBuf.append(elapsedTime);
1351:                                mesgBuf
1352:                                        .append(Messages
1353:                                                .getString("ServerPreparedStatement.16")); //$NON-NLS-1$
1354:
1355:                                mesgBuf.append("as prepared: ");
1356:                                mesgBuf.append(this .originalSql);
1357:                                mesgBuf
1358:                                        .append("\n\n with parameters bound:\n\n");
1359:                                mesgBuf.append(asSql(true));
1360:
1361:                                this .eventSink
1362:                                        .consumeEvent(new ProfilerEvent(
1363:                                                ProfilerEvent.TYPE_SLOW_QUERY,
1364:                                                "", this .currentCatalog, this .connection.getId(), //$NON-NLS-1$
1365:                                                getId(), 0, System
1366:                                                        .currentTimeMillis(),
1367:                                                elapsedTime, mysql
1368:                                                        .getQueryTimingUnits(),
1369:                                                null, new Throwable(), mesgBuf
1370:                                                        .toString()));
1371:                            }
1372:
1373:                            if (gatherPerformanceMetrics) {
1374:                                this .connection
1375:                                        .registerQueryExecutionTime(elapsedTime);
1376:                            }
1377:                        }
1378:
1379:                        this .connection.incrementNumberOfPreparedExecutes();
1380:
1381:                        if (this .profileSQL) {
1382:                            this .eventSink = ProfileEventSink
1383:                                    .getInstance(this .connection);
1384:
1385:                            this .eventSink
1386:                                    .consumeEvent(new ProfilerEvent(
1387:                                            ProfilerEvent.TYPE_EXECUTE,
1388:                                            "", this .currentCatalog, //$NON-NLS-1$
1389:                                            this .connectionId,
1390:                                            this .statementId,
1391:                                            -1,
1392:                                            System.currentTimeMillis(),
1393:                                            (int) (mysql
1394:                                                    .getCurrentTimeNanosOrMillis() - begin),
1395:                                            mysql.getQueryTimingUnits(), null,
1396:                                            new Throwable(),
1397:                                            truncateQueryToLog(asSql(true))));
1398:                        }
1399:
1400:                        com.mysql.jdbc.ResultSetInternalMethods rs = mysql
1401:                                .readAllResults(this , maxRowsToRetrieve,
1402:                                        this .resultSetType,
1403:                                        this .resultSetConcurrency,
1404:                                        createStreamingResultSet,
1405:                                        this .currentCatalog, resultPacket,
1406:                                        true, this .fieldCount,
1407:                                        metadataFromCache);
1408:
1409:                        if (this .profileSQL) {
1410:                            long fetchEndTime = mysql
1411:                                    .getCurrentTimeNanosOrMillis();
1412:
1413:                            this .eventSink
1414:                                    .consumeEvent(new ProfilerEvent(
1415:                                            ProfilerEvent.TYPE_FETCH,
1416:                                            "", this .currentCatalog, this .connection.getId(), //$NON-NLS-1$
1417:                                            getId(),
1418:                                            0 /* FIXME rs.resultId */, System
1419:                                                    .currentTimeMillis(),
1420:                                            (fetchEndTime - queryEndTime),
1421:                                            mysql.getQueryTimingUnits(), null,
1422:                                            new Throwable(), null));
1423:                        }
1424:
1425:                        if (queryWasSlow
1426:                                && this .connection.getExplainSlowQueries()) {
1427:                            String queryAsString = asSql(true);
1428:
1429:                            mysql.explainSlowQuery(queryAsString.getBytes(),
1430:                                    queryAsString);
1431:                        }
1432:
1433:                        if (!createStreamingResultSet
1434:                                && this .serverNeedsResetBeforeEachExecution) {
1435:                            serverResetStatement(); // clear any long data...
1436:                        }
1437:
1438:                        this .sendTypesToServer = false;
1439:                        this .results = rs;
1440:
1441:                        if (mysql.hadWarnings()) {
1442:                            mysql.scanForAndThrowDataTruncation();
1443:                        }
1444:
1445:                        return rs;
1446:                    } finally {
1447:                        if (timeoutTask != null) {
1448:                            timeoutTask.cancel();
1449:                        }
1450:                    }
1451:                }
1452:            }
1453:
1454:            /**
1455:             * Sends stream-type data parameters to the server.
1456:             * 
1457:             * <pre>
1458:             * 
1459:             *  Long data handling:
1460:             * 
1461:             *  - Server gets the long data in pieces with command type 'COM_LONG_DATA'.
1462:             *  - The packet recieved will have the format as:
1463:             *    [COM_LONG_DATA:     1][STMT_ID:4][parameter_number:2][type:2][data]
1464:             *  - Checks if the type is specified by client, and if yes reads the type,
1465:             *    and  stores the data in that format.
1466:             *  - It's up to the client to check for read data ended. The server doesn't
1467:             *    care;  and also server doesn't notify to the client that it got the
1468:             *    data  or not; if there is any error; then during execute; the error
1469:             *    will  be returned
1470:             *  
1471:             * </pre>
1472:             * 
1473:             * @param parameterIndex
1474:             *            DOCUMENT ME!
1475:             * @param longData
1476:             *            DOCUMENT ME!
1477:             * 
1478:             * @throws SQLException
1479:             *             if an error occurs.
1480:             */
1481:            private void serverLongData(int parameterIndex, BindValue longData)
1482:                    throws SQLException {
1483:                synchronized (this .connection.getMutex()) {
1484:                    MysqlIO mysql = this .connection.getIO();
1485:
1486:                    Buffer packet = mysql.getSharedSendPacket();
1487:
1488:                    Object value = longData.value;
1489:
1490:                    if (value instanceof  byte[]) {
1491:                        packet.clear();
1492:                        packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
1493:                        packet.writeLong(this .serverStatementId);
1494:                        packet.writeInt((parameterIndex));
1495:
1496:                        packet.writeBytesNoNull((byte[]) longData.value);
1497:
1498:                        mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
1499:                                packet, true, null);
1500:                    } else if (value instanceof  InputStream) {
1501:                        storeStream(mysql, parameterIndex, packet,
1502:                                (InputStream) value);
1503:                    } else if (value instanceof  java.sql.Blob) {
1504:                        storeStream(mysql, parameterIndex, packet,
1505:                                ((java.sql.Blob) value).getBinaryStream());
1506:                    } else if (value instanceof  Reader) {
1507:                        storeReader(mysql, parameterIndex, packet,
1508:                                (Reader) value);
1509:                    } else {
1510:                        throw SQLError.createSQLException(Messages
1511:                                .getString("ServerPreparedStatement.18") //$NON-NLS-1$
1512:                                + value.getClass().getName() + "'", //$NON-NLS-1$
1513:                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
1514:                    }
1515:                }
1516:            }
1517:
1518:            private void serverPrepare(String sql) throws SQLException {
1519:                synchronized (this .connection.getMutex()) {
1520:                    MysqlIO mysql = this .connection.getIO();
1521:
1522:                    if (this .connection.getAutoGenerateTestcaseScript()) {
1523:                        dumpPrepareForTestcase();
1524:                    }
1525:
1526:                    try {
1527:                        long begin = 0;
1528:
1529:                        if (StringUtils.startsWithIgnoreCaseAndWs(sql,
1530:                                "LOAD DATA")) { //$NON-NLS-1$
1531:                            this .isLoadDataQuery = true;
1532:                        } else {
1533:                            this .isLoadDataQuery = false;
1534:                        }
1535:
1536:                        if (this .connection.getProfileSql()) {
1537:                            begin = System.currentTimeMillis();
1538:                        }
1539:
1540:                        String characterEncoding = null;
1541:                        String connectionEncoding = this .connection
1542:                                .getEncoding();
1543:
1544:                        if (!this .isLoadDataQuery
1545:                                && this .connection.getUseUnicode()
1546:                                && (connectionEncoding != null)) {
1547:                            characterEncoding = connectionEncoding;
1548:                        }
1549:
1550:                        Buffer prepareResultPacket = mysql.sendCommand(
1551:                                MysqlDefs.COM_PREPARE, sql, null, false,
1552:                                characterEncoding);
1553:
1554:                        if (this .connection.versionMeetsMinimum(4, 1, 1)) {
1555:                            // 4.1.1 and newer use the first byte
1556:                            // as an 'ok' or 'error' flag, so move
1557:                            // the buffer pointer past it to
1558:                            // start reading the statement id.
1559:                            prepareResultPacket.setPosition(1);
1560:                        } else {
1561:                            // 4.1.0 doesn't use the first byte as an
1562:                            // 'ok' or 'error' flag
1563:                            prepareResultPacket.setPosition(0);
1564:                        }
1565:
1566:                        this .serverStatementId = prepareResultPacket.readLong();
1567:                        this .fieldCount = prepareResultPacket.readInt();
1568:                        this .parameterCount = prepareResultPacket.readInt();
1569:                        this .parameterBindings = new BindValue[this .parameterCount];
1570:
1571:                        for (int i = 0; i < this .parameterCount; i++) {
1572:                            this .parameterBindings[i] = new BindValue();
1573:                        }
1574:
1575:                        this .connection.incrementNumberOfPrepares();
1576:
1577:                        if (this .profileSQL) {
1578:                            this .eventSink.consumeEvent(new ProfilerEvent(
1579:                                    ProfilerEvent.TYPE_PREPARE,
1580:                                    "", this .currentCatalog, //$NON-NLS-1$
1581:                                    this .connectionId, this .statementId, -1,
1582:                                    System.currentTimeMillis(), mysql
1583:                                            .getCurrentTimeNanosOrMillis()
1584:                                            - begin, mysql
1585:                                            .getQueryTimingUnits(), null,
1586:                                    new Throwable(), truncateQueryToLog(sql)));
1587:                        }
1588:
1589:                        if (this .parameterCount > 0) {
1590:                            if (this .connection.versionMeetsMinimum(4, 1, 2)
1591:                                    && !mysql.isVersion(5, 0, 0)) {
1592:                                this .parameterFields = new Field[this .parameterCount];
1593:
1594:                                Buffer metaDataPacket = mysql.readPacket();
1595:
1596:                                int i = 0;
1597:
1598:                                while (!metaDataPacket.isLastDataPacket()
1599:                                        && (i < this .parameterCount)) {
1600:                                    this .parameterFields[i++] = mysql
1601:                                            .unpackField(metaDataPacket, false);
1602:                                    metaDataPacket = mysql.readPacket();
1603:                                }
1604:                            }
1605:                        }
1606:
1607:                        if (this .fieldCount > 0) {
1608:                            this .resultFields = new Field[this .fieldCount];
1609:
1610:                            Buffer fieldPacket = mysql.readPacket();
1611:
1612:                            int i = 0;
1613:
1614:                            // Read in the result set column information
1615:                            while (!fieldPacket.isLastDataPacket()
1616:                                    && (i < this .fieldCount)) {
1617:                                this .resultFields[i++] = mysql.unpackField(
1618:                                        fieldPacket, false);
1619:                                fieldPacket = mysql.readPacket();
1620:                            }
1621:                        }
1622:                    } catch (SQLException sqlEx) {
1623:                        if (this .connection.getDumpQueriesOnException()) {
1624:                            StringBuffer messageBuf = new StringBuffer(
1625:                                    this .originalSql.length() + 32);
1626:                            messageBuf
1627:                                    .append("\n\nQuery being prepared when exception was thrown:\n\n");
1628:                            messageBuf.append(this .originalSql);
1629:
1630:                            sqlEx = ConnectionImpl.appendMessageToException(
1631:                                    sqlEx, messageBuf.toString());
1632:                        }
1633:
1634:                        throw sqlEx;
1635:                    } finally {
1636:                        // Leave the I/O channel in a known state...there might be
1637:                        // packets out there
1638:                        // that we're not interested in
1639:                        this .connection.getIO().clearInputStream();
1640:                    }
1641:                }
1642:            }
1643:
1644:            private String truncateQueryToLog(String sql) {
1645:                String query = null;
1646:
1647:                if (sql.length() > this .connection.getMaxQuerySizeToLog()) {
1648:                    StringBuffer queryBuf = new StringBuffer(this .connection
1649:                            .getMaxQuerySizeToLog() + 12);
1650:                    queryBuf.append(sql.substring(0, this .connection
1651:                            .getMaxQuerySizeToLog()));
1652:                    queryBuf.append(Messages.getString("MysqlIO.25"));
1653:
1654:                    query = queryBuf.toString();
1655:                } else {
1656:                    query = sql;
1657:                }
1658:
1659:                return query;
1660:            }
1661:
1662:            private void serverResetStatement() throws SQLException {
1663:                synchronized (this .connection.getMutex()) {
1664:
1665:                    MysqlIO mysql = this .connection.getIO();
1666:
1667:                    Buffer packet = mysql.getSharedSendPacket();
1668:
1669:                    packet.clear();
1670:                    packet.writeByte((byte) MysqlDefs.COM_RESET_STMT);
1671:                    packet.writeLong(this .serverStatementId);
1672:
1673:                    try {
1674:                        mysql.sendCommand(MysqlDefs.COM_RESET_STMT, null,
1675:                                packet, !this .connection.versionMeetsMinimum(4,
1676:                                        1, 2), null);
1677:                    } catch (SQLException sqlEx) {
1678:                        throw sqlEx;
1679:                    } catch (Exception ex) {
1680:                        throw SQLError.createSQLException(ex.toString(),
1681:                                SQLError.SQL_STATE_GENERAL_ERROR);
1682:                    } finally {
1683:                        mysql.clearInputStream();
1684:                    }
1685:                }
1686:            }
1687:
1688:            /**
1689:             * @see java.sql.PreparedStatement#setArray(int, java.sql.Array)
1690:             */
1691:            public void setArray(int i, Array x) throws SQLException {
1692:                throw new NotImplemented();
1693:            }
1694:
1695:            /**
1696:             * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream,
1697:             *      int)
1698:             */
1699:            public void setAsciiStream(int parameterIndex, InputStream x,
1700:                    int length) throws SQLException {
1701:                checkClosed();
1702:
1703:                if (x == null) {
1704:                    setNull(parameterIndex, java.sql.Types.BINARY);
1705:                } else {
1706:                    BindValue binding = getBinding(parameterIndex, true);
1707:                    setType(binding, MysqlDefs.FIELD_TYPE_BLOB);
1708:
1709:                    binding.value = x;
1710:                    binding.isNull = false;
1711:                    binding.isLongData = true;
1712:
1713:                    if (this .connection.getUseStreamLengthsInPrepStmts()) {
1714:                        binding.bindLength = length;
1715:                    } else {
1716:                        binding.bindLength = -1;
1717:                    }
1718:                }
1719:            }
1720:
1721:            /**
1722:             * @see java.sql.PreparedStatement#setBigDecimal(int, java.math.BigDecimal)
1723:             */
1724:            public void setBigDecimal(int parameterIndex, BigDecimal x)
1725:                    throws SQLException {
1726:                checkClosed();
1727:
1728:                if (x == null) {
1729:                    setNull(parameterIndex, java.sql.Types.DECIMAL);
1730:                } else {
1731:
1732:                    BindValue binding = getBinding(parameterIndex, false);
1733:
1734:                    if (this .connection.versionMeetsMinimum(5, 0, 3)) {
1735:                        setType(binding, MysqlDefs.FIELD_TYPE_NEW_DECIMAL);
1736:                    } else {
1737:                        setType(binding, this .stringTypeCode);
1738:                    }
1739:
1740:                    binding.value = StringUtils.fixDecimalExponent(StringUtils
1741:                            .consistentToString(x));
1742:                    binding.isNull = false;
1743:                    binding.isLongData = false;
1744:                }
1745:            }
1746:
1747:            /**
1748:             * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream,
1749:             *      int)
1750:             */
1751:            public void setBinaryStream(int parameterIndex, InputStream x,
1752:                    int length) throws SQLException {
1753:                checkClosed();
1754:
1755:                if (x == null) {
1756:                    setNull(parameterIndex, java.sql.Types.BINARY);
1757:                } else {
1758:                    BindValue binding = getBinding(parameterIndex, true);
1759:                    setType(binding, MysqlDefs.FIELD_TYPE_BLOB);
1760:
1761:                    binding.value = x;
1762:                    binding.isNull = false;
1763:                    binding.isLongData = true;
1764:
1765:                    if (this .connection.getUseStreamLengthsInPrepStmts()) {
1766:                        binding.bindLength = length;
1767:                    } else {
1768:                        binding.bindLength = -1;
1769:                    }
1770:                }
1771:            }
1772:
1773:            /**
1774:             * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob)
1775:             */
1776:            public void setBlob(int parameterIndex, Blob x) throws SQLException {
1777:                checkClosed();
1778:
1779:                if (x == null) {
1780:                    setNull(parameterIndex, java.sql.Types.BINARY);
1781:                } else {
1782:                    BindValue binding = getBinding(parameterIndex, true);
1783:                    setType(binding, MysqlDefs.FIELD_TYPE_BLOB);
1784:
1785:                    binding.value = x;
1786:                    binding.isNull = false;
1787:                    binding.isLongData = true;
1788:
1789:                    if (this .connection.getUseStreamLengthsInPrepStmts()) {
1790:                        binding.bindLength = x.length();
1791:                    } else {
1792:                        binding.bindLength = -1;
1793:                    }
1794:                }
1795:            }
1796:
1797:            /**
1798:             * @see java.sql.PreparedStatement#setBoolean(int, boolean)
1799:             */
1800:            public void setBoolean(int parameterIndex, boolean x)
1801:                    throws SQLException {
1802:                setByte(parameterIndex, (x ? (byte) 1 : (byte) 0));
1803:            }
1804:
1805:            /**
1806:             * @see java.sql.PreparedStatement#setByte(int, byte)
1807:             */
1808:            public void setByte(int parameterIndex, byte x) throws SQLException {
1809:                checkClosed();
1810:
1811:                BindValue binding = getBinding(parameterIndex, false);
1812:                setType(binding, MysqlDefs.FIELD_TYPE_TINY);
1813:
1814:                binding.value = null;
1815:                binding.byteBinding = x;
1816:                binding.isNull = false;
1817:                binding.isLongData = false;
1818:            }
1819:
1820:            /**
1821:             * @see java.sql.PreparedStatement#setBytes(int, byte)
1822:             */
1823:            public void setBytes(int parameterIndex, byte[] x)
1824:                    throws SQLException {
1825:                checkClosed();
1826:
1827:                if (x == null) {
1828:                    setNull(parameterIndex, java.sql.Types.BINARY);
1829:                } else {
1830:                    BindValue binding = getBinding(parameterIndex, false);
1831:                    setType(binding, MysqlDefs.FIELD_TYPE_VAR_STRING);
1832:
1833:                    binding.value = x;
1834:                    binding.isNull = false;
1835:                    binding.isLongData = false;
1836:                }
1837:            }
1838:
1839:            /**
1840:             * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader,
1841:             *      int)
1842:             */
1843:            public void setCharacterStream(int parameterIndex, Reader reader,
1844:                    int length) throws SQLException {
1845:                checkClosed();
1846:
1847:                if (reader == null) {
1848:                    setNull(parameterIndex, java.sql.Types.BINARY);
1849:                } else {
1850:                    BindValue binding = getBinding(parameterIndex, true);
1851:                    setType(binding, MysqlDefs.FIELD_TYPE_BLOB);
1852:
1853:                    binding.value = reader;
1854:                    binding.isNull = false;
1855:                    binding.isLongData = true;
1856:
1857:                    if (this .connection.getUseStreamLengthsInPrepStmts()) {
1858:                        binding.bindLength = length;
1859:                    } else {
1860:                        binding.bindLength = -1;
1861:                    }
1862:                }
1863:            }
1864:
1865:            /**
1866:             * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob)
1867:             */
1868:            public void setClob(int parameterIndex, Clob x) throws SQLException {
1869:                checkClosed();
1870:
1871:                if (x == null) {
1872:                    setNull(parameterIndex, java.sql.Types.BINARY);
1873:                } else {
1874:                    BindValue binding = getBinding(parameterIndex, true);
1875:                    setType(binding, MysqlDefs.FIELD_TYPE_BLOB);
1876:
1877:                    binding.value = x.getCharacterStream();
1878:                    binding.isNull = false;
1879:                    binding.isLongData = true;
1880:
1881:                    if (this .connection.getUseStreamLengthsInPrepStmts()) {
1882:                        binding.bindLength = x.length();
1883:                    } else {
1884:                        binding.bindLength = -1;
1885:                    }
1886:                }
1887:            }
1888:
1889:            /**
1890:             * Set a parameter to a java.sql.Date value. The driver converts this to a
1891:             * SQL DATE value when it sends it to the database.
1892:             * 
1893:             * @param parameterIndex
1894:             *            the first parameter is 1, the second is 2, ...
1895:             * @param x
1896:             *            the parameter value
1897:             * 
1898:             * @exception SQLException
1899:             *                if a database-access error occurs.
1900:             */
1901:            public void setDate(int parameterIndex, Date x) throws SQLException {
1902:                setDate(parameterIndex, x, null);
1903:            }
1904:
1905:            /**
1906:             * Set a parameter to a java.sql.Date value. The driver converts this to a
1907:             * SQL DATE value when it sends it to the database.
1908:             * 
1909:             * @param parameterIndex
1910:             *            the first parameter is 1, the second is 2, ...
1911:             * @param x
1912:             *            the parameter value
1913:             * @param cal
1914:             *            the calendar to interpret the date with
1915:             * 
1916:             * @exception SQLException
1917:             *                if a database-access error occurs.
1918:             */
1919:            public void setDate(int parameterIndex, Date x, Calendar cal)
1920:                    throws SQLException {
1921:                if (x == null) {
1922:                    setNull(parameterIndex, java.sql.Types.DATE);
1923:                } else {
1924:                    BindValue binding = getBinding(parameterIndex, false);
1925:                    setType(binding, MysqlDefs.FIELD_TYPE_DATE);
1926:
1927:                    binding.value = x;
1928:                    binding.isNull = false;
1929:                    binding.isLongData = false;
1930:                }
1931:            }
1932:
1933:            /**
1934:             * @see java.sql.PreparedStatement#setDouble(int, double)
1935:             */
1936:            public void setDouble(int parameterIndex, double x)
1937:                    throws SQLException {
1938:                checkClosed();
1939:
1940:                if (!this .connection.getAllowNanAndInf()
1941:                        && (x == Double.POSITIVE_INFINITY
1942:                                || x == Double.NEGATIVE_INFINITY || Double
1943:                                .isNaN(x))) {
1944:                    throw SQLError
1945:                            .createSQLException(
1946:                                    "'"
1947:                                            + x
1948:                                            + "' is not a valid numeric or approximate numeric value",
1949:                                    SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
1950:
1951:                }
1952:
1953:                BindValue binding = getBinding(parameterIndex, false);
1954:                setType(binding, MysqlDefs.FIELD_TYPE_DOUBLE);
1955:
1956:                binding.value = null;
1957:                binding.doubleBinding = x;
1958:                binding.isNull = false;
1959:                binding.isLongData = false;
1960:            }
1961:
1962:            /**
1963:             * @see java.sql.PreparedStatement#setFloat(int, float)
1964:             */
1965:            public void setFloat(int parameterIndex, float x)
1966:                    throws SQLException {
1967:                checkClosed();
1968:
1969:                BindValue binding = getBinding(parameterIndex, false);
1970:                setType(binding, MysqlDefs.FIELD_TYPE_FLOAT);
1971:
1972:                binding.value = null;
1973:                binding.floatBinding = x;
1974:                binding.isNull = false;
1975:                binding.isLongData = false;
1976:            }
1977:
1978:            /**
1979:             * @see java.sql.PreparedStatement#setInt(int, int)
1980:             */
1981:            public void setInt(int parameterIndex, int x) throws SQLException {
1982:                checkClosed();
1983:
1984:                BindValue binding = getBinding(parameterIndex, false);
1985:                setType(binding, MysqlDefs.FIELD_TYPE_LONG);
1986:
1987:                binding.value = null;
1988:                binding.intBinding = x;
1989:                binding.isNull = false;
1990:                binding.isLongData = false;
1991:            }
1992:
1993:            /**
1994:             * @see java.sql.PreparedStatement#setLong(int, long)
1995:             */
1996:            public void setLong(int parameterIndex, long x) throws SQLException {
1997:                checkClosed();
1998:
1999:                BindValue binding = getBinding(parameterIndex, false);
2000:                setType(binding, MysqlDefs.FIELD_TYPE_LONGLONG);
2001:
2002:                binding.value = null;
2003:                binding.longBinding = x;
2004:                binding.isNull = false;
2005:                binding.isLongData = false;
2006:            }
2007:
2008:            /**
2009:             * @see java.sql.PreparedStatement#setNull(int, int)
2010:             */
2011:            public void setNull(int parameterIndex, int sqlType)
2012:                    throws SQLException {
2013:                checkClosed();
2014:
2015:                BindValue binding = getBinding(parameterIndex, false);
2016:
2017:                //
2018:                // Don't re-set types, but use something if this
2019:                // parameter was never specified
2020:                //
2021:                if (binding.bufferType == 0) {
2022:                    setType(binding, MysqlDefs.FIELD_TYPE_NULL);
2023:                }
2024:
2025:                binding.value = null;
2026:                binding.isNull = true;
2027:                binding.isLongData = false;
2028:            }
2029:
2030:            /**
2031:             * @see java.sql.PreparedStatement#setNull(int, int, java.lang.String)
2032:             */
2033:            public void setNull(int parameterIndex, int sqlType, String typeName)
2034:                    throws SQLException {
2035:                checkClosed();
2036:
2037:                BindValue binding = getBinding(parameterIndex, false);
2038:
2039:                //
2040:                // Don't re-set types, but use something if this
2041:                // parameter was never specified
2042:                //
2043:                if (binding.bufferType == 0) {
2044:                    setType(binding, MysqlDefs.FIELD_TYPE_NULL);
2045:                }
2046:
2047:                binding.value = null;
2048:                binding.isNull = true;
2049:                binding.isLongData = false;
2050:            }
2051:
2052:            /**
2053:             * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref)
2054:             */
2055:            public void setRef(int i, Ref x) throws SQLException {
2056:                throw new NotImplemented();
2057:            }
2058:
2059:            /**
2060:             * @see java.sql.PreparedStatement#setShort(int, short)
2061:             */
2062:            public void setShort(int parameterIndex, short x)
2063:                    throws SQLException {
2064:                checkClosed();
2065:
2066:                BindValue binding = getBinding(parameterIndex, false);
2067:                setType(binding, MysqlDefs.FIELD_TYPE_SHORT);
2068:
2069:                binding.value = null;
2070:                binding.shortBinding = x;
2071:                binding.isNull = false;
2072:                binding.isLongData = false;
2073:            }
2074:
2075:            /**
2076:             * @see java.sql.PreparedStatement#setString(int, java.lang.String)
2077:             */
2078:            public void setString(int parameterIndex, String x)
2079:                    throws SQLException {
2080:                checkClosed();
2081:
2082:                if (x == null) {
2083:                    setNull(parameterIndex, java.sql.Types.CHAR);
2084:                } else {
2085:                    BindValue binding = getBinding(parameterIndex, false);
2086:
2087:                    setType(binding, this .stringTypeCode);
2088:
2089:                    binding.value = x;
2090:                    binding.isNull = false;
2091:                    binding.isLongData = false;
2092:                }
2093:            }
2094:
2095:            /**
2096:             * Set a parameter to a java.sql.Time value.
2097:             * 
2098:             * @param parameterIndex
2099:             *            the first parameter is 1...));
2100:             * @param x
2101:             *            the parameter value
2102:             * 
2103:             * @throws SQLException
2104:             *             if a database access error occurs
2105:             */
2106:            public void setTime(int parameterIndex, java.sql.Time x)
2107:                    throws SQLException {
2108:                setTimeInternal(parameterIndex, x, null, this .connection
2109:                        .getDefaultTimeZone(), false);
2110:            }
2111:
2112:            /**
2113:             * Set a parameter to a java.sql.Time value. The driver converts this to a
2114:             * SQL TIME value when it sends it to the database, using the given
2115:             * timezone.
2116:             * 
2117:             * @param parameterIndex
2118:             *            the first parameter is 1...));
2119:             * @param x
2120:             *            the parameter value
2121:             * @param cal
2122:             *            the timezone to use
2123:             * 
2124:             * @throws SQLException
2125:             *             if a database access error occurs
2126:             */
2127:            public void setTime(int parameterIndex, java.sql.Time x,
2128:                    Calendar cal) throws SQLException {
2129:                setTimeInternal(parameterIndex, x, cal, cal.getTimeZone(), true);
2130:            }
2131:
2132:            /**
2133:             * Set a parameter to a java.sql.Time value. The driver converts this to a
2134:             * SQL TIME value when it sends it to the database, using the given
2135:             * timezone.
2136:             * 
2137:             * @param parameterIndex
2138:             *            the first parameter is 1...));
2139:             * @param x
2140:             *            the parameter value
2141:             * @param tz
2142:             *            the timezone to use
2143:             * 
2144:             * @throws SQLException
2145:             *             if a database access error occurs
2146:             */
2147:            public void setTimeInternal(int parameterIndex, java.sql.Time x,
2148:                    Calendar targetCalendar, TimeZone tz, boolean rollForward)
2149:                    throws SQLException {
2150:                if (x == null) {
2151:                    setNull(parameterIndex, java.sql.Types.TIME);
2152:                } else {
2153:                    BindValue binding = getBinding(parameterIndex, false);
2154:                    setType(binding, MysqlDefs.FIELD_TYPE_TIME);
2155:
2156:                    Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
2157:
2158:                    synchronized (sessionCalendar) {
2159:                        binding.value = TimeUtil.changeTimezone(
2160:                                this .connection, sessionCalendar,
2161:                                targetCalendar, x, tz, this .connection
2162:                                        .getServerTimezoneTZ(), rollForward);
2163:                    }
2164:
2165:                    binding.isNull = false;
2166:                    binding.isLongData = false;
2167:                }
2168:            }
2169:
2170:            /**
2171:             * Set a parameter to a java.sql.Timestamp value. The driver converts this
2172:             * to a SQL TIMESTAMP value when it sends it to the database.
2173:             * 
2174:             * @param parameterIndex
2175:             *            the first parameter is 1, the second is 2, ...
2176:             * @param x
2177:             *            the parameter value
2178:             * 
2179:             * @throws SQLException
2180:             *             if a database-access error occurs.
2181:             */
2182:            public void setTimestamp(int parameterIndex, java.sql.Timestamp x)
2183:                    throws SQLException {
2184:                setTimestampInternal(parameterIndex, x, null, this .connection
2185:                        .getDefaultTimeZone(), false);
2186:            }
2187:
2188:            /**
2189:             * Set a parameter to a java.sql.Timestamp value. The driver converts this
2190:             * to a SQL TIMESTAMP value when it sends it to the database.
2191:             * 
2192:             * @param parameterIndex
2193:             *            the first parameter is 1, the second is 2, ...
2194:             * @param x
2195:             *            the parameter value
2196:             * @param cal
2197:             *            the timezone to use
2198:             * 
2199:             * @throws SQLException
2200:             *             if a database-access error occurs.
2201:             */
2202:            public void setTimestamp(int parameterIndex, java.sql.Timestamp x,
2203:                    Calendar cal) throws SQLException {
2204:                setTimestampInternal(parameterIndex, x, cal, cal.getTimeZone(),
2205:                        true);
2206:            }
2207:
2208:            protected void setTimestampInternal(int parameterIndex,
2209:                    java.sql.Timestamp x, Calendar targetCalendar, TimeZone tz,
2210:                    boolean rollForward) throws SQLException {
2211:                if (x == null) {
2212:                    setNull(parameterIndex, java.sql.Types.TIMESTAMP);
2213:                } else {
2214:                    BindValue binding = getBinding(parameterIndex, false);
2215:                    setType(binding, MysqlDefs.FIELD_TYPE_DATETIME);
2216:
2217:                    Calendar sessionCalendar = this .connection
2218:                            .getUseJDBCCompliantTimezoneShift() ? this .connection
2219:                            .getUtcCalendar()
2220:                            : getCalendarInstanceForSessionOrNew();
2221:
2222:                    synchronized (sessionCalendar) {
2223:                        binding.value = TimeUtil.changeTimezone(
2224:                                this .connection, sessionCalendar,
2225:                                targetCalendar, x, tz, this .connection
2226:                                        .getServerTimezoneTZ(), rollForward);
2227:                    }
2228:
2229:                    binding.isNull = false;
2230:                    binding.isLongData = false;
2231:                }
2232:            }
2233:
2234:            protected void setType(BindValue oldValue, int bufferType) {
2235:                if (oldValue.bufferType != bufferType) {
2236:                    this .sendTypesToServer = true;
2237:                }
2238:
2239:                oldValue.bufferType = bufferType;
2240:            }
2241:
2242:            /**
2243:             * DOCUMENT ME!
2244:             * 
2245:             * @param parameterIndex
2246:             *            DOCUMENT ME!
2247:             * @param x
2248:             *            DOCUMENT ME!
2249:             * @param length
2250:             *            DOCUMENT ME!
2251:             * 
2252:             * @throws SQLException
2253:             *             DOCUMENT ME!
2254:             * @throws NotImplemented
2255:             *             DOCUMENT ME!
2256:             * 
2257:             * @see java.sql.PreparedStatement#setUnicodeStream(int,
2258:             *      java.io.InputStream, int)
2259:             * @deprecated
2260:             */
2261:            public void setUnicodeStream(int parameterIndex, InputStream x,
2262:                    int length) throws SQLException {
2263:                checkClosed();
2264:
2265:                throw new NotImplemented();
2266:            }
2267:
2268:            /**
2269:             * @see java.sql.PreparedStatement#setURL(int, java.net.URL)
2270:             */
2271:            public void setURL(int parameterIndex, URL x) throws SQLException {
2272:                checkClosed();
2273:
2274:                setString(parameterIndex, x.toString());
2275:            }
2276:
2277:            /**
2278:             * Method storeBinding.
2279:             * 
2280:             * @param packet
2281:             * @param bindValue
2282:             * @param mysql
2283:             *            DOCUMENT ME!
2284:             * 
2285:             * @throws SQLException
2286:             *             DOCUMENT ME!
2287:             */
2288:            private void storeBinding(Buffer packet, BindValue bindValue,
2289:                    MysqlIO mysql) throws SQLException {
2290:                try {
2291:                    Object value = bindValue.value;
2292:
2293:                    //
2294:                    // Handle primitives first
2295:                    //
2296:                    switch (bindValue.bufferType) {
2297:
2298:                    case MysqlDefs.FIELD_TYPE_TINY:
2299:                        packet.writeByte(bindValue.byteBinding);
2300:                        return;
2301:                    case MysqlDefs.FIELD_TYPE_SHORT:
2302:                        packet.ensureCapacity(2);
2303:                        packet.writeInt(bindValue.shortBinding);
2304:                        return;
2305:                    case MysqlDefs.FIELD_TYPE_LONG:
2306:                        packet.ensureCapacity(4);
2307:                        packet.writeLong(bindValue.intBinding);
2308:                        return;
2309:                    case MysqlDefs.FIELD_TYPE_LONGLONG:
2310:                        packet.ensureCapacity(8);
2311:                        packet.writeLongLong(bindValue.longBinding);
2312:                        return;
2313:                    case MysqlDefs.FIELD_TYPE_FLOAT:
2314:                        packet.ensureCapacity(4);
2315:                        packet.writeFloat(bindValue.floatBinding);
2316:                        return;
2317:                    case MysqlDefs.FIELD_TYPE_DOUBLE:
2318:                        packet.ensureCapacity(8);
2319:                        packet.writeDouble(bindValue.doubleBinding);
2320:                        return;
2321:                    case MysqlDefs.FIELD_TYPE_TIME:
2322:                        storeTime(packet, (Time) value);
2323:                        return;
2324:                    case MysqlDefs.FIELD_TYPE_DATE:
2325:                    case MysqlDefs.FIELD_TYPE_DATETIME:
2326:                    case MysqlDefs.FIELD_TYPE_TIMESTAMP:
2327:                        storeDateTime(packet, (java.util.Date) value, mysql);
2328:                        return;
2329:                    case MysqlDefs.FIELD_TYPE_VAR_STRING:
2330:                    case MysqlDefs.FIELD_TYPE_STRING:
2331:                    case MysqlDefs.FIELD_TYPE_VARCHAR:
2332:                    case MysqlDefs.FIELD_TYPE_DECIMAL:
2333:                    case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
2334:                        if (value instanceof  byte[]) {
2335:                            packet.writeLenBytes((byte[]) value);
2336:                        } else if (!this .isLoadDataQuery) {
2337:                            packet.writeLenString((String) value,
2338:                                    this .charEncoding, this .connection
2339:                                            .getServerCharacterEncoding(),
2340:                                    this .charConverter, this .connection
2341:                                            .parserKnowsUnicode(),
2342:                                    this .connection);
2343:                        } else {
2344:                            packet.writeLenBytes(((String) value).getBytes());
2345:                        }
2346:
2347:                        return;
2348:                    }
2349:
2350:                } catch (UnsupportedEncodingException uEE) {
2351:                    throw SQLError.createSQLException(Messages
2352:                            .getString("ServerPreparedStatement.22") //$NON-NLS-1$
2353:                            + this .connection.getEncoding() + "'", //$NON-NLS-1$
2354:                            SQLError.SQL_STATE_GENERAL_ERROR);
2355:                }
2356:            }
2357:
2358:            private void storeDataTime412AndOlder(Buffer intoBuf,
2359:                    java.util.Date dt) throws SQLException {
2360:
2361:                Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
2362:
2363:                synchronized (sessionCalendar) {
2364:                    java.util.Date oldTime = sessionCalendar.getTime();
2365:
2366:                    try {
2367:                        intoBuf.ensureCapacity(8);
2368:                        intoBuf.writeByte((byte) 7); // length
2369:
2370:                        sessionCalendar.setTime(dt);
2371:
2372:                        int year = sessionCalendar.get(Calendar.YEAR);
2373:                        int month = sessionCalendar.get(Calendar.MONTH) + 1;
2374:                        int date = sessionCalendar.get(Calendar.DATE);
2375:
2376:                        intoBuf.writeInt(year);
2377:                        intoBuf.writeByte((byte) month);
2378:                        intoBuf.writeByte((byte) date);
2379:
2380:                        if (dt instanceof  java.sql.Date) {
2381:                            intoBuf.writeByte((byte) 0);
2382:                            intoBuf.writeByte((byte) 0);
2383:                            intoBuf.writeByte((byte) 0);
2384:                        } else {
2385:                            intoBuf.writeByte((byte) sessionCalendar
2386:                                    .get(Calendar.HOUR_OF_DAY));
2387:                            intoBuf.writeByte((byte) sessionCalendar
2388:                                    .get(Calendar.MINUTE));
2389:                            intoBuf.writeByte((byte) sessionCalendar
2390:                                    .get(Calendar.SECOND));
2391:                        }
2392:                    } finally {
2393:                        sessionCalendar.setTime(oldTime);
2394:                    }
2395:                }
2396:            }
2397:
2398:            private void storeDateTime(Buffer intoBuf, java.util.Date dt,
2399:                    MysqlIO mysql) throws SQLException {
2400:                if (this .connection.versionMeetsMinimum(4, 1, 3)) {
2401:                    storeDateTime413AndNewer(intoBuf, dt);
2402:                } else {
2403:                    storeDataTime412AndOlder(intoBuf, dt);
2404:                }
2405:            }
2406:
2407:            private void storeDateTime413AndNewer(Buffer intoBuf,
2408:                    java.util.Date dt) throws SQLException {
2409:                Calendar sessionCalendar = (dt instanceof  Timestamp && this .connection
2410:                        .getUseJDBCCompliantTimezoneShift()) ? this .connection
2411:                        .getUtcCalendar()
2412:                        : getCalendarInstanceForSessionOrNew();
2413:
2414:                synchronized (sessionCalendar) {
2415:                    java.util.Date oldTime = sessionCalendar.getTime();
2416:
2417:                    try {
2418:                        sessionCalendar.setTime(dt);
2419:
2420:                        if (dt instanceof  java.sql.Date) {
2421:                            sessionCalendar.set(Calendar.HOUR_OF_DAY, 0);
2422:                            sessionCalendar.set(Calendar.MINUTE, 0);
2423:                            sessionCalendar.set(Calendar.SECOND, 0);
2424:                        }
2425:
2426:                        byte length = (byte) 7;
2427:
2428:                        if (dt instanceof  java.sql.Timestamp) {
2429:                            length = (byte) 11;
2430:                        }
2431:
2432:                        intoBuf.ensureCapacity(length);
2433:
2434:                        intoBuf.writeByte(length); // length
2435:
2436:                        int year = sessionCalendar.get(Calendar.YEAR);
2437:                        int month = sessionCalendar.get(Calendar.MONTH) + 1;
2438:                        int date = sessionCalendar.get(Calendar.DAY_OF_MONTH);
2439:
2440:                        intoBuf.writeInt(year);
2441:                        intoBuf.writeByte((byte) month);
2442:                        intoBuf.writeByte((byte) date);
2443:
2444:                        if (dt instanceof  java.sql.Date) {
2445:                            intoBuf.writeByte((byte) 0);
2446:                            intoBuf.writeByte((byte) 0);
2447:                            intoBuf.writeByte((byte) 0);
2448:                        } else {
2449:                            intoBuf.writeByte((byte) sessionCalendar
2450:                                    .get(Calendar.HOUR_OF_DAY));
2451:                            intoBuf.writeByte((byte) sessionCalendar
2452:                                    .get(Calendar.MINUTE));
2453:                            intoBuf.writeByte((byte) sessionCalendar
2454:                                    .get(Calendar.SECOND));
2455:                        }
2456:
2457:                        if (length == 11) {
2458:                            //	MySQL expects microseconds, not nanos
2459:                            intoBuf.writeLong(((java.sql.Timestamp) dt)
2460:                                    .getNanos() / 1000);
2461:                        }
2462:
2463:                    } finally {
2464:                        sessionCalendar.setTime(oldTime);
2465:                    }
2466:                }
2467:            }
2468:
2469:            //
2470:            // TO DO: Investigate using NIO to do this faster
2471:            //
2472:            private void storeReader(MysqlIO mysql, int parameterIndex,
2473:                    Buffer packet, Reader inStream) throws SQLException {
2474:                String forcedEncoding = this .connection
2475:                        .getClobCharacterEncoding();
2476:
2477:                String clobEncoding = (forcedEncoding == null ? this .connection
2478:                        .getEncoding() : forcedEncoding);
2479:
2480:                int maxBytesChar = 2;
2481:
2482:                if (clobEncoding != null) {
2483:                    if (!clobEncoding.equals("UTF-16")) {
2484:                        maxBytesChar = this .connection
2485:                                .getMaxBytesPerChar(clobEncoding);
2486:
2487:                        if (maxBytesChar == 1) {
2488:                            maxBytesChar = 2; // for safety
2489:                        }
2490:                    } else {
2491:                        maxBytesChar = 4;
2492:                    }
2493:                }
2494:
2495:                char[] buf = new char[BLOB_STREAM_READ_BUF_SIZE / maxBytesChar];
2496:
2497:                int numRead = 0;
2498:
2499:                int bytesInPacket = 0;
2500:                int totalBytesRead = 0;
2501:                int bytesReadAtLastSend = 0;
2502:                int packetIsFullAt = this .connection.getBlobSendChunkSize();
2503:
2504:                try {
2505:                    packet.clear();
2506:                    packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
2507:                    packet.writeLong(this .serverStatementId);
2508:                    packet.writeInt((parameterIndex));
2509:
2510:                    boolean readAny = false;
2511:
2512:                    while ((numRead = inStream.read(buf)) != -1) {
2513:                        readAny = true;
2514:
2515:                        byte[] valueAsBytes = StringUtils.getBytes(buf, null,
2516:                                clobEncoding, this .connection
2517:                                        .getServerCharacterEncoding(), 0,
2518:                                numRead, this .connection.parserKnowsUnicode());
2519:
2520:                        packet.writeBytesNoNull(valueAsBytes, 0,
2521:                                valueAsBytes.length);
2522:
2523:                        bytesInPacket += valueAsBytes.length;
2524:                        totalBytesRead += valueAsBytes.length;
2525:
2526:                        if (bytesInPacket >= packetIsFullAt) {
2527:                            bytesReadAtLastSend = totalBytesRead;
2528:
2529:                            mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2530:                                    packet, true, null);
2531:
2532:                            bytesInPacket = 0;
2533:                            packet.clear();
2534:                            packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
2535:                            packet.writeLong(this .serverStatementId);
2536:                            packet.writeInt((parameterIndex));
2537:                        }
2538:                    }
2539:
2540:                    if (totalBytesRead != bytesReadAtLastSend) {
2541:                        mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2542:                                packet, true, null);
2543:                    }
2544:
2545:                    if (!readAny) {
2546:                        mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2547:                                packet, true, null);
2548:                    }
2549:                } catch (IOException ioEx) {
2550:                    throw SQLError
2551:                            .createSQLException(Messages
2552:                                    .getString("ServerPreparedStatement.24") //$NON-NLS-1$
2553:                                    + ioEx.toString(),
2554:                                    SQLError.SQL_STATE_GENERAL_ERROR);
2555:                } finally {
2556:                    if (this .connection.getAutoClosePStmtStreams()) {
2557:                        if (inStream != null) {
2558:                            try {
2559:                                inStream.close();
2560:                            } catch (IOException ioEx) {
2561:                                ; // ignore
2562:                            }
2563:                        }
2564:                    }
2565:                }
2566:            }
2567:
2568:            private void storeStream(MysqlIO mysql, int parameterIndex,
2569:                    Buffer packet, InputStream inStream) throws SQLException {
2570:                byte[] buf = new byte[BLOB_STREAM_READ_BUF_SIZE];
2571:
2572:                int numRead = 0;
2573:
2574:                try {
2575:                    int bytesInPacket = 0;
2576:                    int totalBytesRead = 0;
2577:                    int bytesReadAtLastSend = 0;
2578:                    int packetIsFullAt = this .connection.getBlobSendChunkSize();
2579:
2580:                    packet.clear();
2581:                    packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
2582:                    packet.writeLong(this .serverStatementId);
2583:                    packet.writeInt((parameterIndex));
2584:
2585:                    boolean readAny = false;
2586:
2587:                    while ((numRead = inStream.read(buf)) != -1) {
2588:
2589:                        readAny = true;
2590:
2591:                        packet.writeBytesNoNull(buf, 0, numRead);
2592:                        bytesInPacket += numRead;
2593:                        totalBytesRead += numRead;
2594:
2595:                        if (bytesInPacket >= packetIsFullAt) {
2596:                            bytesReadAtLastSend = totalBytesRead;
2597:
2598:                            mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2599:                                    packet, true, null);
2600:
2601:                            bytesInPacket = 0;
2602:                            packet.clear();
2603:                            packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
2604:                            packet.writeLong(this .serverStatementId);
2605:                            packet.writeInt((parameterIndex));
2606:                        }
2607:                    }
2608:
2609:                    if (totalBytesRead != bytesReadAtLastSend) {
2610:                        mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2611:                                packet, true, null);
2612:                    }
2613:
2614:                    if (!readAny) {
2615:                        mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null,
2616:                                packet, true, null);
2617:                    }
2618:                } catch (IOException ioEx) {
2619:                    throw SQLError
2620:                            .createSQLException(Messages
2621:                                    .getString("ServerPreparedStatement.25") //$NON-NLS-1$
2622:                                    + ioEx.toString(),
2623:                                    SQLError.SQL_STATE_GENERAL_ERROR);
2624:                } finally {
2625:                    if (this .connection.getAutoClosePStmtStreams()) {
2626:                        if (inStream != null) {
2627:                            try {
2628:                                inStream.close();
2629:                            } catch (IOException ioEx) {
2630:                                ; // ignore
2631:                            }
2632:                        }
2633:                    }
2634:                }
2635:            }
2636:
2637:            /**
2638:             * @see java.lang.Object#toString()
2639:             */
2640:            public String toString() {
2641:                StringBuffer toStringBuf = new StringBuffer();
2642:
2643:                toStringBuf.append("com.mysql.jdbc.ServerPreparedStatement["); //$NON-NLS-1$
2644:                toStringBuf.append(this .serverStatementId);
2645:                toStringBuf.append("] - "); //$NON-NLS-1$
2646:
2647:                try {
2648:                    toStringBuf.append(asSql());
2649:                } catch (SQLException sqlEx) {
2650:                    toStringBuf.append(Messages
2651:                            .getString("ServerPreparedStatement.6")); //$NON-NLS-1$
2652:                    toStringBuf.append(sqlEx);
2653:                }
2654:
2655:                return toStringBuf.toString();
2656:            }
2657:
2658:            protected long getServerStatementId() {
2659:                return serverStatementId;
2660:            }
2661:
2662:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.