Source Code Cross Referenced for UpdatableResultSet.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.profiler.ProfileEventSink;
0028:        import com.mysql.jdbc.profiler.ProfilerEvent;
0029:
0030:        import java.io.InputStream;
0031:        import java.io.Reader;
0032:        import java.math.BigDecimal;
0033:
0034:        import java.sql.SQLException;
0035:
0036:        import java.util.ArrayList;
0037:        import java.util.HashMap;
0038:        import java.util.Iterator;
0039:        import java.util.List;
0040:        import java.util.Map;
0041:        import java.util.TreeMap;
0042:
0043:        /**
0044:         * A result set that is updatable.
0045:         *
0046:         * @author Mark Matthews
0047:         */
0048:        public class UpdatableResultSet extends ResultSetImpl {
0049:            /** Marker for 'stream' data when doing INSERT rows */
0050:            protected final static byte[] STREAM_DATA_MARKER = "** STREAM DATA **" //$NON-NLS-1$
0051:            .getBytes();
0052:
0053:            protected SingleByteCharsetConverter charConverter;
0054:
0055:            private String charEncoding;
0056:
0057:            /** What is the default value for the column? */
0058:            private byte[][] defaultColumnValue;
0059:
0060:            /** PreparedStatement used to delete data */
0061:            private com.mysql.jdbc.PreparedStatement deleter = null;
0062:
0063:            private String deleteSQL = null;
0064:
0065:            private boolean initializedCharConverter = false;
0066:
0067:            /** PreparedStatement used to insert data */
0068:            protected com.mysql.jdbc.PreparedStatement inserter = null;
0069:
0070:            private String insertSQL = null;
0071:
0072:            /** Is this result set updateable? */
0073:            private boolean isUpdatable = false;
0074:
0075:            /** Reason the result set is not updatable */
0076:            private String notUpdatableReason = null;
0077:
0078:            /** List of primary keys */
0079:            private List primaryKeyIndicies = null;
0080:
0081:            private String qualifiedAndQuotedTableName;
0082:
0083:            private String quotedIdChar = null;
0084:
0085:            /** PreparedStatement used to refresh data */
0086:            private com.mysql.jdbc.PreparedStatement refresher;
0087:
0088:            private String refreshSQL = null;
0089:
0090:            /** The binary data for the 'current' row */
0091:            private ResultSetRow savedCurrentRow;
0092:
0093:            /** PreparedStatement used to delete data */
0094:            protected com.mysql.jdbc.PreparedStatement updater = null;
0095:
0096:            /** SQL for in-place modifcation */
0097:            private String updateSQL = null;
0098:
0099:            private boolean populateInserterWithDefaultValues = false;
0100:
0101:            private Map databasesUsedToTablesUsed = null;
0102:
0103:            /**
0104:             * Creates a new ResultSet object.
0105:             *
0106:             * @param catalog
0107:             *            the database in use when we were created
0108:             * @param fields
0109:             *            an array of Field objects (basically, the ResultSet MetaData)
0110:             * @param tuples
0111:             *            actual row data
0112:             * @param conn
0113:             *            the Connection that created us.
0114:             * @param creatorStmt
0115:             *            DOCUMENT ME!
0116:             *
0117:             * @throws SQLException
0118:             *             DOCUMENT ME!
0119:             */
0120:            protected UpdatableResultSet(String catalog, Field[] fields,
0121:                    RowData tuples, ConnectionImpl conn,
0122:                    StatementImpl creatorStmt) throws SQLException {
0123:                super (catalog, fields, tuples, conn, creatorStmt);
0124:                checkUpdatability();
0125:                this .populateInserterWithDefaultValues = this .connection
0126:                        .getPopulateInsertRowWithDefaultValues();
0127:            }
0128:
0129:            /**
0130:             * JDBC 2.0
0131:             *
0132:             * <p>
0133:             * Move to an absolute row number in the result set.
0134:             * </p>
0135:             *
0136:             * <p>
0137:             * If row is positive, moves to an absolute row with respect to the
0138:             * beginning of the result set. The first row is row 1, the second is row 2,
0139:             * etc.
0140:             * </p>
0141:             *
0142:             * <p>
0143:             * If row is negative, moves to an absolute row position with respect to the
0144:             * end of result set. For example, calling absolute(-1) positions the cursor
0145:             * on the last row, absolute(-2) indicates the next-to-last row, etc.
0146:             * </p>
0147:             *
0148:             * <p>
0149:             * An attempt to position the cursor beyond the first/last row in the result
0150:             * set, leaves the cursor before/after the first/last row, respectively.
0151:             * </p>
0152:             *
0153:             * <p>
0154:             * Note: Calling absolute(1) is the same as calling first(). Calling
0155:             * absolute(-1) is the same as calling last().
0156:             * </p>
0157:             *
0158:             * @param row
0159:             *            DOCUMENT ME!
0160:             *
0161:             * @return true if on the result set, false if off.
0162:             *
0163:             * @exception SQLException
0164:             *                if a database-access error occurs, or row is 0, or result
0165:             *                set type is TYPE_FORWARD_ONLY.
0166:             */
0167:            public synchronized boolean absolute(int row) throws SQLException {
0168:                return super .absolute(row);
0169:            }
0170:
0171:            /**
0172:             * JDBC 2.0
0173:             *
0174:             * <p>
0175:             * Moves to the end of the result set, just after the last row. Has no
0176:             * effect if the result set contains no rows.
0177:             * </p>
0178:             *
0179:             * @exception SQLException
0180:             *                if a database-access error occurs, or result set type is
0181:             *                TYPE_FORWARD_ONLY.
0182:             */
0183:            public synchronized void afterLast() throws SQLException {
0184:                super .afterLast();
0185:            }
0186:
0187:            /**
0188:             * JDBC 2.0
0189:             *
0190:             * <p>
0191:             * Moves to the front of the result set, just before the first row. Has no
0192:             * effect if the result set contains no rows.
0193:             * </p>
0194:             *
0195:             * @exception SQLException
0196:             *                if a database-access error occurs, or result set type is
0197:             *                TYPE_FORWARD_ONLY
0198:             */
0199:            public synchronized void beforeFirst() throws SQLException {
0200:                super .beforeFirst();
0201:            }
0202:
0203:            /**
0204:             * JDBC 2.0 The cancelRowUpdates() method may be called after calling an
0205:             * updateXXX() method(s) and before calling updateRow() to rollback the
0206:             * updates made to a row. If no updates have been made or updateRow() has
0207:             * already been called, then this method has no effect.
0208:             *
0209:             * @exception SQLException
0210:             *                if a database-access error occurs, or if called when on
0211:             *                the insert row.
0212:             */
0213:            public synchronized void cancelRowUpdates() throws SQLException {
0214:                checkClosed();
0215:
0216:                if (this .doingUpdates) {
0217:                    this .doingUpdates = false;
0218:                    this .updater.clearParameters();
0219:                }
0220:            }
0221:
0222:            /*
0223:             * (non-Javadoc)
0224:             *
0225:             * @see com.mysql.jdbc.ResultSet#checkRowPos()
0226:             */
0227:            protected void checkRowPos() throws SQLException {
0228:                checkClosed();
0229:
0230:                if (!this .onInsertRow) {
0231:                    super .checkRowPos();
0232:                }
0233:            }
0234:
0235:            /**
0236:             * Is this ResultSet updateable?
0237:             *
0238:             * @throws SQLException
0239:             *             DOCUMENT ME!
0240:             */
0241:            protected void checkUpdatability() throws SQLException {
0242:                if (this .fields == null) {
0243:                    // we've been created to be populated with cached
0244:                    // metadata, and we don't have the metadata yet,
0245:                    // we'll be called again by
0246:                    // Connection.initializeResultsMetadataFromCache()
0247:                    // when the metadata has been made available
0248:
0249:                    return;
0250:                }
0251:
0252:                String singleTableName = null;
0253:                String catalogName = null;
0254:
0255:                int primaryKeyCount = 0;
0256:
0257:                // We can only do this if we know that there is a currently
0258:                // selected database, or if we're talking to a > 4.1 version
0259:                // of MySQL server (as it returns database names in field
0260:                // info)
0261:                //
0262:                if ((this .catalog == null) || (this .catalog.length() == 0)) {
0263:                    this .catalog = this .fields[0].getDatabaseName();
0264:
0265:                    if ((this .catalog == null) || (this .catalog.length() == 0)) {
0266:                        throw SQLError.createSQLException(Messages
0267:                                .getString("UpdatableResultSet.43") //$NON-NLS-1$
0268:                                , SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$
0269:                    }
0270:                }
0271:
0272:                if (this .fields.length > 0) {
0273:                    singleTableName = this .fields[0].getOriginalTableName();
0274:                    catalogName = this .fields[0].getDatabaseName();
0275:
0276:                    if (singleTableName == null) {
0277:                        singleTableName = this .fields[0].getTableName();
0278:                        catalogName = this .catalog;
0279:                    }
0280:
0281:                    if (singleTableName != null
0282:                            && singleTableName.length() == 0) {
0283:                        this .isUpdatable = false;
0284:                        this .notUpdatableReason = Messages
0285:                                .getString("NotUpdatableReason.3");
0286:
0287:                        return;
0288:                    }
0289:
0290:                    if (this .fields[0].isPrimaryKey()) {
0291:                        primaryKeyCount++;
0292:                    }
0293:
0294:                    //
0295:                    // References only one table?
0296:                    //
0297:                    for (int i = 1; i < this .fields.length; i++) {
0298:                        String otherTableName = this .fields[i]
0299:                                .getOriginalTableName();
0300:                        String otherCatalogName = this .fields[i]
0301:                                .getDatabaseName();
0302:
0303:                        if (otherTableName == null) {
0304:                            otherTableName = this .fields[i].getTableName();
0305:                            otherCatalogName = this .catalog;
0306:                        }
0307:
0308:                        if (otherTableName != null
0309:                                && otherTableName.length() == 0) {
0310:                            this .isUpdatable = false;
0311:                            this .notUpdatableReason = Messages
0312:                                    .getString("NotUpdatableReason.3");
0313:
0314:                            return;
0315:                        }
0316:
0317:                        if ((singleTableName == null)
0318:                                || !otherTableName.equals(singleTableName)) {
0319:                            this .isUpdatable = false;
0320:                            this .notUpdatableReason = Messages
0321:                                    .getString("NotUpdatableReason.0");
0322:
0323:                            return;
0324:                        }
0325:
0326:                        // Can't reference more than one database
0327:                        if ((catalogName == null)
0328:                                || !otherCatalogName.equals(catalogName)) {
0329:                            this .isUpdatable = false;
0330:                            this .notUpdatableReason = Messages
0331:                                    .getString("NotUpdatableReason.1");
0332:
0333:                            return;
0334:                        }
0335:
0336:                        if (this .fields[i].isPrimaryKey()) {
0337:                            primaryKeyCount++;
0338:                        }
0339:                    }
0340:
0341:                    if ((singleTableName == null)
0342:                            || (singleTableName.length() == 0)) {
0343:                        this .isUpdatable = false;
0344:                        this .notUpdatableReason = Messages
0345:                                .getString("NotUpdatableReason.2");
0346:
0347:                        return;
0348:                    }
0349:                } else {
0350:                    this .isUpdatable = false;
0351:                    this .notUpdatableReason = Messages
0352:                            .getString("NotUpdatableReason.3");
0353:
0354:                    return;
0355:                }
0356:
0357:                if (this .connection.getStrictUpdates()) {
0358:                    java.sql.DatabaseMetaData dbmd = this .connection
0359:                            .getMetaData();
0360:
0361:                    java.sql.ResultSet rs = null;
0362:                    HashMap primaryKeyNames = new HashMap();
0363:
0364:                    try {
0365:                        rs = dbmd.getPrimaryKeys(catalogName, null,
0366:                                singleTableName);
0367:
0368:                        while (rs.next()) {
0369:                            String keyName = rs.getString(4);
0370:                            keyName = keyName.toUpperCase();
0371:                            primaryKeyNames.put(keyName, keyName);
0372:                        }
0373:                    } finally {
0374:                        if (rs != null) {
0375:                            try {
0376:                                rs.close();
0377:                            } catch (Exception ex) {
0378:                                AssertionFailedException.shouldNotHappen(ex);
0379:                            }
0380:
0381:                            rs = null;
0382:                        }
0383:                    }
0384:
0385:                    int existingPrimaryKeysCount = primaryKeyNames.size();
0386:
0387:                    if (existingPrimaryKeysCount == 0) {
0388:                        this .isUpdatable = false;
0389:                        this .notUpdatableReason = Messages
0390:                                .getString("NotUpdatableReason.5");
0391:
0392:                        return; // we can't update tables w/o keys
0393:                    }
0394:
0395:                    //
0396:                    // Contains all primary keys?
0397:                    //
0398:                    for (int i = 0; i < this .fields.length; i++) {
0399:                        if (this .fields[i].isPrimaryKey()) {
0400:                            String columnNameUC = this .fields[i].getName()
0401:                                    .toUpperCase();
0402:
0403:                            if (primaryKeyNames.remove(columnNameUC) == null) {
0404:                                // try original name
0405:                                String originalName = this .fields[i]
0406:                                        .getOriginalName();
0407:
0408:                                if (originalName != null) {
0409:                                    if (primaryKeyNames.remove(originalName
0410:                                            .toUpperCase()) == null) {
0411:                                        // we don't know about this key, so give up :(
0412:                                        this .isUpdatable = false;
0413:                                        this .notUpdatableReason = Messages
0414:                                                .getString(
0415:                                                        "NotUpdatableReason.6",
0416:                                                        new Object[] { originalName });
0417:
0418:                                        return;
0419:                                    }
0420:                                }
0421:                            }
0422:                        }
0423:                    }
0424:
0425:                    this .isUpdatable = primaryKeyNames.isEmpty();
0426:
0427:                    if (!this .isUpdatable) {
0428:                        if (existingPrimaryKeysCount > 1) {
0429:                            this .notUpdatableReason = Messages
0430:                                    .getString("NotUpdatableReason.7");
0431:                        } else {
0432:                            this .notUpdatableReason = Messages
0433:                                    .getString("NotUpdatableReason.4");
0434:                        }
0435:
0436:                        return;
0437:                    }
0438:                }
0439:
0440:                //
0441:                // Must have at least one primary key
0442:                //
0443:                if (primaryKeyCount == 0) {
0444:                    this .isUpdatable = false;
0445:                    this .notUpdatableReason = Messages
0446:                            .getString("NotUpdatableReason.4");
0447:
0448:                    return;
0449:                }
0450:
0451:                this .isUpdatable = true;
0452:                this .notUpdatableReason = null;
0453:
0454:                return;
0455:            }
0456:
0457:            /**
0458:             * JDBC 2.0 Delete the current row from the result set and the underlying
0459:             * database. Cannot be called when on the insert row.
0460:             *
0461:             * @exception SQLException
0462:             *                if a database-access error occurs, or if called when on
0463:             *                the insert row.
0464:             * @throws SQLException
0465:             *             if the ResultSet is not updatable or some other error occurs
0466:             */
0467:            public synchronized void deleteRow() throws SQLException {
0468:                checkClosed();
0469:
0470:                if (!this .isUpdatable) {
0471:                    throw new NotUpdatable(this .notUpdatableReason);
0472:                }
0473:
0474:                if (this .onInsertRow) {
0475:                    throw SQLError.createSQLException(Messages
0476:                            .getString("UpdatableResultSet.1")); //$NON-NLS-1$
0477:                } else if (this .rowData.size() == 0) {
0478:                    throw SQLError.createSQLException(Messages
0479:                            .getString("UpdatableResultSet.2")); //$NON-NLS-1$
0480:                } else if (isBeforeFirst()) {
0481:                    throw SQLError.createSQLException(Messages
0482:                            .getString("UpdatableResultSet.3")); //$NON-NLS-1$
0483:                } else if (isAfterLast()) {
0484:                    throw SQLError.createSQLException(Messages
0485:                            .getString("UpdatableResultSet.4")); //$NON-NLS-1$
0486:                }
0487:
0488:                if (this .deleter == null) {
0489:                    if (this .deleteSQL == null) {
0490:                        generateStatements();
0491:                    }
0492:
0493:                    this .deleter = this .connection
0494:                            .clientPrepareStatement(this .deleteSQL);
0495:                }
0496:
0497:                this .deleter.clearParameters();
0498:
0499:                String characterEncoding = null;
0500:
0501:                if (this .connection.getUseUnicode()) {
0502:                    characterEncoding = this .connection.getEncoding();
0503:                }
0504:
0505:                //
0506:                // FIXME: Use internal routines where possible for character
0507:                // conversion!
0508:                try {
0509:                    int numKeys = this .primaryKeyIndicies.size();
0510:
0511:                    if (numKeys == 1) {
0512:                        int index = ((Integer) this .primaryKeyIndicies.get(0))
0513:                                .intValue();
0514:                        String currentVal = ((characterEncoding == null) ? new String(
0515:                                (byte[]) this .this Row.getColumnValue(index))
0516:                                : new String((byte[]) this .this Row
0517:                                        .getColumnValue(index),
0518:                                        characterEncoding));
0519:                        this .deleter.setString(1, currentVal);
0520:                    } else {
0521:                        for (int i = 0; i < numKeys; i++) {
0522:                            int index = ((Integer) this .primaryKeyIndicies
0523:                                    .get(i)).intValue();
0524:                            String currentVal = ((characterEncoding == null) ? new String(
0525:                                    (byte[]) this .this Row.getColumnValue(index))
0526:                                    : new String((byte[]) this .this Row
0527:                                            .getColumnValue(index),
0528:                                            characterEncoding));
0529:                            this .deleter.setString(i + 1, currentVal);
0530:                        }
0531:                    }
0532:
0533:                    this .deleter.executeUpdate();
0534:                    this .rowData.removeRow(this .rowData.getCurrentRowNumber());
0535:                } catch (java.io.UnsupportedEncodingException encodingEx) {
0536:                    throw SQLError.createSQLException(Messages.getString(
0537:                            "UpdatableResultSet.39", //$NON-NLS-1$
0538:                            new Object[] { this .charEncoding }) //$NON-NLS-1$
0539:                            , SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$
0540:                }
0541:            }
0542:
0543:            private synchronized void extractDefaultValues()
0544:                    throws SQLException {
0545:                java.sql.DatabaseMetaData dbmd = this .connection.getMetaData();
0546:                this .defaultColumnValue = new byte[this .fields.length][];
0547:
0548:                java.sql.ResultSet columnsResultSet = null;
0549:                Iterator referencedDbs = this .databasesUsedToTablesUsed
0550:                        .entrySet().iterator();
0551:
0552:                while (referencedDbs.hasNext()) {
0553:                    Map.Entry dbEntry = (Map.Entry) referencedDbs.next();
0554:                    String databaseName = dbEntry.getKey().toString();
0555:
0556:                    Iterator referencedTables = ((Map) dbEntry.getValue())
0557:                            .entrySet().iterator();
0558:
0559:                    while (referencedTables.hasNext()) {
0560:                        Map.Entry tableEntry = (Map.Entry) referencedTables
0561:                                .next();
0562:                        String tableName = tableEntry.getKey().toString();
0563:                        Map columnNamesToIndices = (Map) tableEntry.getValue();
0564:
0565:                        try {
0566:                            columnsResultSet = dbmd.getColumns(this .catalog,
0567:                                    null, tableName, "%"); //$NON-NLS-1$
0568:
0569:                            while (columnsResultSet.next()) {
0570:                                String columnName = columnsResultSet
0571:                                        .getString("COLUMN_NAME"); //$NON-NLS-1$
0572:                                byte[] defaultValue = columnsResultSet
0573:                                        .getBytes("COLUMN_DEF"); //$NON-NLS-1$
0574:
0575:                                if (columnNamesToIndices
0576:                                        .containsKey(columnName)) {
0577:                                    int localColumnIndex = ((Integer) columnNamesToIndices
0578:                                            .get(columnName)).intValue();
0579:
0580:                                    this .defaultColumnValue[localColumnIndex] = defaultValue;
0581:                                } // else assert?
0582:                            }
0583:                        } finally {
0584:                            if (columnsResultSet != null) {
0585:                                columnsResultSet.close();
0586:
0587:                                columnsResultSet = null;
0588:                            }
0589:                        }
0590:                    }
0591:                }
0592:            }
0593:
0594:            /**
0595:             * JDBC 2.0
0596:             *
0597:             * <p>
0598:             * Moves to the first row in the result set.
0599:             * </p>
0600:             *
0601:             * @return true if on a valid row, false if no rows in the result set.
0602:             *
0603:             * @exception SQLException
0604:             *                if a database-access error occurs, or result set type is
0605:             *                TYPE_FORWARD_ONLY.
0606:             */
0607:            public synchronized boolean first() throws SQLException {
0608:                return super .first();
0609:            }
0610:
0611:            /**
0612:             * Figure out whether or not this ResultSet is updateable, and if so,
0613:             * generate the PreparedStatements to support updates.
0614:             *
0615:             * @throws SQLException
0616:             *             DOCUMENT ME!
0617:             * @throws NotUpdatable
0618:             *             DOCUMENT ME!
0619:             */
0620:            protected synchronized void generateStatements()
0621:                    throws SQLException {
0622:                if (!this .isUpdatable) {
0623:                    this .doingUpdates = false;
0624:                    this .onInsertRow = false;
0625:
0626:                    throw new NotUpdatable(this .notUpdatableReason);
0627:                }
0628:
0629:                String quotedId = getQuotedIdChar();
0630:
0631:                Map tableNamesSoFar = null;
0632:
0633:                if (this .connection.lowerCaseTableNames()) {
0634:                    tableNamesSoFar = new TreeMap(String.CASE_INSENSITIVE_ORDER);
0635:                    this .databasesUsedToTablesUsed = new TreeMap(
0636:                            String.CASE_INSENSITIVE_ORDER);
0637:                } else {
0638:                    tableNamesSoFar = new TreeMap();
0639:                    this .databasesUsedToTablesUsed = new TreeMap();
0640:                }
0641:
0642:                this .primaryKeyIndicies = new ArrayList();
0643:
0644:                StringBuffer fieldValues = new StringBuffer();
0645:                StringBuffer keyValues = new StringBuffer();
0646:                StringBuffer columnNames = new StringBuffer();
0647:                StringBuffer insertPlaceHolders = new StringBuffer();
0648:                StringBuffer allTablesBuf = new StringBuffer();
0649:                Map columnIndicesToTable = new HashMap();
0650:
0651:                boolean firstTime = true;
0652:                boolean keysFirstTime = true;
0653:
0654:                String equalsStr = this .connection
0655:                        .versionMeetsMinimum(3, 23, 0) ? "<=>" : "=";
0656:
0657:                for (int i = 0; i < this .fields.length; i++) {
0658:                    StringBuffer tableNameBuffer = new StringBuffer();
0659:                    Map columnNameToIndex = null;
0660:
0661:                    // FIXME: What about no table?
0662:                    if (this .fields[i].getOriginalTableName() != null) {
0663:
0664:                        String databaseName = this .fields[i].getDatabaseName();
0665:
0666:                        if ((databaseName != null)
0667:                                && (databaseName.length() > 0)) {
0668:                            tableNameBuffer.append(quotedId);
0669:                            tableNameBuffer.append(databaseName);
0670:                            tableNameBuffer.append(quotedId);
0671:                            tableNameBuffer.append('.');
0672:                        }
0673:
0674:                        String tableOnlyName = this .fields[i]
0675:                                .getOriginalTableName();
0676:
0677:                        tableNameBuffer.append(quotedId);
0678:                        tableNameBuffer.append(tableOnlyName);
0679:                        tableNameBuffer.append(quotedId);
0680:
0681:                        String fqTableName = tableNameBuffer.toString();
0682:
0683:                        if (!tableNamesSoFar.containsKey(fqTableName)) {
0684:                            if (!tableNamesSoFar.isEmpty()) {
0685:                                allTablesBuf.append(',');
0686:                            }
0687:
0688:                            allTablesBuf.append(fqTableName);
0689:                            tableNamesSoFar.put(fqTableName, fqTableName);
0690:                        }
0691:
0692:                        columnIndicesToTable.put(new Integer(i), fqTableName);
0693:
0694:                        columnNameToIndex = getColumnsToIndexMapForTableAndDB(
0695:                                databaseName, tableOnlyName);
0696:                    } else {
0697:                        String tableOnlyName = this .fields[i].getTableName();
0698:
0699:                        if (tableOnlyName != null) {
0700:                            tableNameBuffer.append(quotedId);
0701:                            tableNameBuffer.append(tableOnlyName);
0702:                            tableNameBuffer.append(quotedId);
0703:
0704:                            String fqTableName = tableNameBuffer.toString();
0705:
0706:                            if (!tableNamesSoFar.containsKey(fqTableName)) {
0707:                                if (!tableNamesSoFar.isEmpty()) {
0708:                                    allTablesBuf.append(',');
0709:                                }
0710:
0711:                                allTablesBuf.append(fqTableName);
0712:                                tableNamesSoFar.put(fqTableName, fqTableName);
0713:                            }
0714:
0715:                            columnIndicesToTable.put(new Integer(i),
0716:                                    fqTableName);
0717:
0718:                            columnNameToIndex = getColumnsToIndexMapForTableAndDB(
0719:                                    this .catalog, tableOnlyName);
0720:                        }
0721:                    }
0722:
0723:                    String originalColumnName = this .fields[i]
0724:                            .getOriginalName();
0725:                    String columnName = null;
0726:
0727:                    if (this .connection.getIO().hasLongColumnInfo()
0728:                            && (originalColumnName != null)
0729:                            && (originalColumnName.length() > 0)) {
0730:                        columnName = originalColumnName;
0731:                    } else {
0732:                        columnName = this .fields[i].getName();
0733:                    }
0734:
0735:                    if (columnNameToIndex != null && columnName != null) {
0736:                        columnNameToIndex.put(columnName, new Integer(i));
0737:                    }
0738:
0739:                    String originalTableName = this .fields[i]
0740:                            .getOriginalTableName();
0741:                    String tableName = null;
0742:
0743:                    if (this .connection.getIO().hasLongColumnInfo()
0744:                            && (originalTableName != null)
0745:                            && (originalTableName.length() > 0)) {
0746:                        tableName = originalTableName;
0747:                    } else {
0748:                        tableName = this .fields[i].getTableName();
0749:                    }
0750:
0751:                    StringBuffer fqcnBuf = new StringBuffer();
0752:                    String databaseName = this .fields[i].getDatabaseName();
0753:
0754:                    if (databaseName != null && databaseName.length() > 0) {
0755:                        fqcnBuf.append(quotedId);
0756:                        fqcnBuf.append(databaseName);
0757:                        fqcnBuf.append(quotedId);
0758:                        fqcnBuf.append('.');
0759:                    }
0760:
0761:                    fqcnBuf.append(quotedId);
0762:                    fqcnBuf.append(tableName);
0763:                    fqcnBuf.append(quotedId);
0764:                    fqcnBuf.append('.');
0765:                    fqcnBuf.append(quotedId);
0766:                    fqcnBuf.append(columnName);
0767:                    fqcnBuf.append(quotedId);
0768:
0769:                    String qualifiedColumnName = fqcnBuf.toString();
0770:
0771:                    if (this .fields[i].isPrimaryKey()) {
0772:                        this .primaryKeyIndicies
0773:                                .add(Constants.integerValueOf(i));
0774:
0775:                        if (!keysFirstTime) {
0776:                            keyValues.append(" AND "); //$NON-NLS-1$
0777:                        } else {
0778:                            keysFirstTime = false;
0779:                        }
0780:
0781:                        keyValues.append(qualifiedColumnName);
0782:                        keyValues.append(equalsStr);
0783:                        keyValues.append("?"); //$NON-NLS-1$
0784:                    }
0785:
0786:                    if (firstTime) {
0787:                        firstTime = false;
0788:                        fieldValues.append("SET "); //$NON-NLS-1$
0789:                    } else {
0790:                        fieldValues.append(","); //$NON-NLS-1$
0791:                        columnNames.append(","); //$NON-NLS-1$
0792:                        insertPlaceHolders.append(","); //$NON-NLS-1$
0793:                    }
0794:
0795:                    insertPlaceHolders.append("?"); //$NON-NLS-1$
0796:
0797:                    columnNames.append(qualifiedColumnName);
0798:
0799:                    fieldValues.append(qualifiedColumnName);
0800:                    fieldValues.append("=?"); //$NON-NLS-1$
0801:                }
0802:
0803:                this .qualifiedAndQuotedTableName = allTablesBuf.toString();
0804:
0805:                this .updateSQL = "UPDATE " + this .qualifiedAndQuotedTableName + " " //$NON-NLS-1$ //$NON-NLS-2$
0806:                        + fieldValues.toString() //$NON-NLS-1$ //$NON-NLS-2$
0807:                        + " WHERE " + keyValues.toString(); //$NON-NLS-1$
0808:                this .insertSQL = "INSERT INTO " + this .qualifiedAndQuotedTableName //$NON-NLS-1$
0809:                        + " (" + columnNames.toString() //$NON-NLS-1$ //$NON-NLS-2$
0810:                        + ") VALUES (" + insertPlaceHolders.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
0811:                this .refreshSQL = "SELECT " + columnNames.toString() + " FROM " //$NON-NLS-1$ //$NON-NLS-2$
0812:                        + this .qualifiedAndQuotedTableName //$NON-NLS-1$ //$NON-NLS-2$
0813:                        + " WHERE " + keyValues.toString(); //$NON-NLS-1$
0814:                this .deleteSQL = "DELETE FROM " + this .qualifiedAndQuotedTableName //$NON-NLS-1$
0815:                        + " WHERE " //$NON-NLS-1$ //$NON-NLS-2$
0816:                        + keyValues.toString();
0817:            }
0818:
0819:            private Map getColumnsToIndexMapForTableAndDB(String databaseName,
0820:                    String tableName) {
0821:                Map nameToIndex;
0822:                Map tablesUsedToColumnsMap = (Map) this .databasesUsedToTablesUsed
0823:                        .get(databaseName);
0824:
0825:                if (tablesUsedToColumnsMap == null) {
0826:                    if (this .connection.lowerCaseTableNames()) {
0827:                        tablesUsedToColumnsMap = new TreeMap(
0828:                                String.CASE_INSENSITIVE_ORDER);
0829:                    } else {
0830:                        tablesUsedToColumnsMap = new TreeMap();
0831:                    }
0832:
0833:                    this .databasesUsedToTablesUsed.put(databaseName,
0834:                            tablesUsedToColumnsMap);
0835:                }
0836:
0837:                nameToIndex = (Map) tablesUsedToColumnsMap.get(tableName);
0838:
0839:                if (nameToIndex == null) {
0840:                    nameToIndex = new HashMap();
0841:                    tablesUsedToColumnsMap.put(tableName, nameToIndex);
0842:                }
0843:
0844:                return nameToIndex;
0845:            }
0846:
0847:            private synchronized SingleByteCharsetConverter getCharConverter()
0848:                    throws SQLException {
0849:                if (!this .initializedCharConverter) {
0850:                    this .initializedCharConverter = true;
0851:
0852:                    if (this .connection.getUseUnicode()) {
0853:                        this .charEncoding = connection.getEncoding();
0854:                        this .charConverter = this .connection
0855:                                .getCharsetConverter(this .charEncoding);
0856:                    }
0857:                }
0858:
0859:                return this .charConverter;
0860:            }
0861:
0862:            /**
0863:             * JDBC 2.0 Return the concurrency of this result set. The concurrency used
0864:             * is determined by the statement that created the result set.
0865:             *
0866:             * @return the concurrency type, CONCUR_READ_ONLY, etc.
0867:             *
0868:             * @exception SQLException
0869:             *                if a database-access error occurs
0870:             */
0871:            public int getConcurrency() throws SQLException {
0872:                return (this .isUpdatable ? CONCUR_UPDATABLE : CONCUR_READ_ONLY);
0873:            }
0874:
0875:            private synchronized String getQuotedIdChar() throws SQLException {
0876:                if (this .quotedIdChar == null) {
0877:                    boolean useQuotedIdentifiers = this .connection
0878:                            .supportsQuotedIdentifiers();
0879:
0880:                    if (useQuotedIdentifiers) {
0881:                        java.sql.DatabaseMetaData dbmd = this .connection
0882:                                .getMetaData();
0883:                        this .quotedIdChar = dbmd.getIdentifierQuoteString();
0884:                    } else {
0885:                        this .quotedIdChar = ""; //$NON-NLS-1$
0886:                    }
0887:                }
0888:
0889:                return this .quotedIdChar;
0890:            }
0891:
0892:            /**
0893:             * JDBC 2.0 Insert the contents of the insert row into the result set and
0894:             * the database. Must be on the insert row when this method is called.
0895:             *
0896:             * @exception SQLException
0897:             *                if a database-access error occurs, if called when not on
0898:             *                the insert row, or if all non-nullable columns in the
0899:             *                insert row have not been given a value
0900:             */
0901:            public synchronized void insertRow() throws SQLException {
0902:                checkClosed();
0903:
0904:                if (!this .onInsertRow) {
0905:                    throw SQLError.createSQLException(Messages
0906:                            .getString("UpdatableResultSet.7")); //$NON-NLS-1$
0907:                }
0908:
0909:                this .inserter.executeUpdate();
0910:
0911:                long autoIncrementId = this .inserter.getLastInsertID();
0912:                int numFields = this .fields.length;
0913:                byte[][] newRow = new byte[numFields][];
0914:
0915:                for (int i = 0; i < numFields; i++) {
0916:                    if (this .inserter.isNull(i)) {
0917:                        newRow[i] = null;
0918:                    } else {
0919:                        newRow[i] = this .inserter.getBytesRepresentation(i);
0920:                    }
0921:
0922:                    //
0923:                    // WARN: This non-variant only holds if MySQL never allows more
0924:                    // than one auto-increment key (which is the way it is _today_)
0925:                    //
0926:                    if (this .fields[i].isAutoIncrement() && autoIncrementId > 0) {
0927:                        newRow[i] = String.valueOf(autoIncrementId).getBytes();
0928:                        this .inserter
0929:                                .setBytesNoEscapeNoQuotes(i + 1, newRow[i]);
0930:                    }
0931:                }
0932:
0933:                ResultSetRow resultSetRow = new ByteArrayRow(newRow);
0934:
0935:                refreshRow(this .inserter, resultSetRow);
0936:
0937:                this .rowData.addRow(resultSetRow);
0938:                resetInserter();
0939:            }
0940:
0941:            /**
0942:             * JDBC 2.0
0943:             *
0944:             * <p>
0945:             * Determine if the cursor is after the last row in the result set.
0946:             * </p>
0947:             *
0948:             * @return true if after the last row, false otherwise. Returns false when
0949:             *         the result set contains no rows.
0950:             *
0951:             * @exception SQLException
0952:             *                if a database-access error occurs.
0953:             */
0954:            public synchronized boolean isAfterLast() throws SQLException {
0955:                return super .isAfterLast();
0956:            }
0957:
0958:            /**
0959:             * JDBC 2.0
0960:             *
0961:             * <p>
0962:             * Determine if the cursor is before the first row in the result set.
0963:             * </p>
0964:             *
0965:             * @return true if before the first row, false otherwise. Returns false when
0966:             *         the result set contains no rows.
0967:             *
0968:             * @exception SQLException
0969:             *                if a database-access error occurs.
0970:             */
0971:            public synchronized boolean isBeforeFirst() throws SQLException {
0972:                return super .isBeforeFirst();
0973:            }
0974:
0975:            /**
0976:             * JDBC 2.0
0977:             *
0978:             * <p>
0979:             * Determine if the cursor is on the first row of the result set.
0980:             * </p>
0981:             *
0982:             * @return true if on the first row, false otherwise.
0983:             *
0984:             * @exception SQLException
0985:             *                if a database-access error occurs.
0986:             */
0987:            public synchronized boolean isFirst() throws SQLException {
0988:                return super .isFirst();
0989:            }
0990:
0991:            /**
0992:             * JDBC 2.0
0993:             *
0994:             * <p>
0995:             * Determine if the cursor is on the last row of the result set. Note:
0996:             * Calling isLast() may be expensive since the JDBC driver might need to
0997:             * fetch ahead one row in order to determine whether the current row is the
0998:             * last row in the result set.
0999:             * </p>
1000:             *
1001:             * @return true if on the last row, false otherwise.
1002:             *
1003:             * @exception SQLException
1004:             *                if a database-access error occurs.
1005:             */
1006:            public synchronized boolean isLast() throws SQLException {
1007:                return super .isLast();
1008:            }
1009:
1010:            boolean isUpdatable() {
1011:                return this .isUpdatable;
1012:            }
1013:
1014:            /**
1015:             * JDBC 2.0
1016:             *
1017:             * <p>
1018:             * Moves to the last row in the result set.
1019:             * </p>
1020:             *
1021:             * @return true if on a valid row, false if no rows in the result set.
1022:             *
1023:             * @exception SQLException
1024:             *                if a database-access error occurs, or result set type is
1025:             *                TYPE_FORWARD_ONLY.
1026:             */
1027:            public synchronized boolean last() throws SQLException {
1028:                return super .last();
1029:            }
1030:
1031:            /**
1032:             * JDBC 2.0 Move the cursor to the remembered cursor position, usually the
1033:             * current row. Has no effect unless the cursor is on the insert row.
1034:             *
1035:             * @exception SQLException
1036:             *                if a database-access error occurs, or the result set is
1037:             *                not updatable
1038:             * @throws SQLException
1039:             *             if the ResultSet is not updatable or some other error occurs
1040:             */
1041:            public synchronized void moveToCurrentRow() throws SQLException {
1042:                checkClosed();
1043:
1044:                if (!this .isUpdatable) {
1045:                    throw new NotUpdatable(this .notUpdatableReason);
1046:                }
1047:
1048:                if (this .onInsertRow) {
1049:                    this .onInsertRow = false;
1050:                    this .this Row = this .savedCurrentRow;
1051:                }
1052:            }
1053:
1054:            /**
1055:             * JDBC 2.0 Move to the insert row. The current cursor position is
1056:             * remembered while the cursor is positioned on the insert row. The insert
1057:             * row is a special row associated with an updatable result set. It is
1058:             * essentially a buffer where a new row may be constructed by calling the
1059:             * updateXXX() methods prior to inserting the row into the result set. Only
1060:             * the updateXXX(), getXXX(), and insertRow() methods may be called when the
1061:             * cursor is on the insert row. All of the columns in a result set must be
1062:             * given a value each time this method is called before calling insertRow().
1063:             * UpdateXXX()must be called before getXXX() on a column.
1064:             *
1065:             * @exception SQLException
1066:             *                if a database-access error occurs, or the result set is
1067:             *                not updatable
1068:             * @throws NotUpdatable
1069:             *             DOCUMENT ME!
1070:             */
1071:            public synchronized void moveToInsertRow() throws SQLException {
1072:                checkClosed();
1073:
1074:                if (!this .isUpdatable) {
1075:                    throw new NotUpdatable(this .notUpdatableReason);
1076:                }
1077:
1078:                if (this .inserter == null) {
1079:                    if (this .insertSQL == null) {
1080:                        generateStatements();
1081:                    }
1082:
1083:                    this .inserter = this .connection
1084:                            .clientPrepareStatement(this .insertSQL);
1085:                    if (this .populateInserterWithDefaultValues) {
1086:                        extractDefaultValues();
1087:                    }
1088:
1089:                    resetInserter();
1090:                } else {
1091:                    resetInserter();
1092:                }
1093:
1094:                int numFields = this .fields.length;
1095:
1096:                this .onInsertRow = true;
1097:                this .doingUpdates = false;
1098:                this .savedCurrentRow = this .this Row;
1099:                byte[][] newRowData = new byte[numFields][];
1100:                this .this Row = new ByteArrayRow(newRowData);
1101:
1102:                for (int i = 0; i < numFields; i++) {
1103:                    if (!this .populateInserterWithDefaultValues) {
1104:                        this .inserter.setBytesNoEscapeNoQuotes(i + 1, "DEFAULT"
1105:                                .getBytes());
1106:                        newRowData = null;
1107:                    } else {
1108:                        if (this .defaultColumnValue[i] != null) {
1109:                            Field f = this .fields[i];
1110:
1111:                            switch (f.getMysqlType()) {
1112:                            case MysqlDefs.FIELD_TYPE_DATE:
1113:                            case MysqlDefs.FIELD_TYPE_DATETIME:
1114:                            case MysqlDefs.FIELD_TYPE_NEWDATE:
1115:                            case MysqlDefs.FIELD_TYPE_TIME:
1116:                            case MysqlDefs.FIELD_TYPE_TIMESTAMP:
1117:
1118:                                if (this .defaultColumnValue[i].length > 7
1119:                                        && this .defaultColumnValue[i][0] == (byte) 'C'
1120:                                        && this .defaultColumnValue[i][1] == (byte) 'U'
1121:                                        && this .defaultColumnValue[i][2] == (byte) 'R'
1122:                                        && this .defaultColumnValue[i][3] == (byte) 'R'
1123:                                        && this .defaultColumnValue[i][4] == (byte) 'E'
1124:                                        && this .defaultColumnValue[i][5] == (byte) 'N'
1125:                                        && this .defaultColumnValue[i][6] == (byte) 'T'
1126:                                        && this .defaultColumnValue[i][7] == (byte) '_') {
1127:                                    this .inserter.setBytesNoEscapeNoQuotes(
1128:                                            i + 1, this .defaultColumnValue[i]);
1129:
1130:                                    break;
1131:                                }
1132:                            default:
1133:                                this .inserter.setBytes(i + 1,
1134:                                        this .defaultColumnValue[i], false,
1135:                                        false);
1136:                            }
1137:
1138:                            // This value _could_ be changed from a getBytes(), so we
1139:                            // need a copy....
1140:                            byte[] defaultValueCopy = new byte[this .defaultColumnValue[i].length];
1141:                            System.arraycopy(defaultColumnValue[i], 0,
1142:                                    defaultValueCopy, 0,
1143:                                    defaultValueCopy.length);
1144:                            newRowData[i] = defaultValueCopy;
1145:                        } else {
1146:                            this .inserter.setNull(i + 1, java.sql.Types.NULL);
1147:                            newRowData[i] = null;
1148:                        }
1149:                    }
1150:                }
1151:            }
1152:
1153:            // ---------------------------------------------------------------------
1154:            // Updates
1155:            // ---------------------------------------------------------------------
1156:
1157:            /**
1158:             * A ResultSet is initially positioned before its first row, the first call
1159:             * to next makes the first row the current row; the second call makes the
1160:             * second row the current row, etc.
1161:             *
1162:             * <p>
1163:             * If an input stream from the previous row is open, it is implicitly
1164:             * closed. The ResultSet's warning chain is cleared when a new row is read
1165:             * </p>
1166:             *
1167:             * @return true if the new current is valid; false if there are no more rows
1168:             *
1169:             * @exception SQLException
1170:             *                if a database access error occurs
1171:             */
1172:            public synchronized boolean next() throws SQLException {
1173:                return super .next();
1174:            }
1175:
1176:            /**
1177:             * The prev method is not part of JDBC, but because of the architecture of
1178:             * this driver it is possible to move both forward and backward within the
1179:             * result set.
1180:             *
1181:             * <p>
1182:             * If an input stream from the previous row is open, it is implicitly
1183:             * closed. The ResultSet's warning chain is cleared when a new row is read
1184:             * </p>
1185:             *
1186:             * @return true if the new current is valid; false if there are no more rows
1187:             *
1188:             * @exception SQLException
1189:             *                if a database access error occurs
1190:             */
1191:            public synchronized boolean prev() throws SQLException {
1192:                return super .prev();
1193:            }
1194:
1195:            /**
1196:             * JDBC 2.0
1197:             *
1198:             * <p>
1199:             * Moves to the previous row in the result set.
1200:             * </p>
1201:             *
1202:             * <p>
1203:             * Note: previous() is not the same as relative(-1) since it makes sense to
1204:             * call previous() when there is no current row.
1205:             * </p>
1206:             *
1207:             * @return true if on a valid row, false if off the result set.
1208:             *
1209:             * @exception SQLException
1210:             *                if a database-access error occurs, or result set type is
1211:             *                TYPE_FORWAR_DONLY.
1212:             */
1213:            public synchronized boolean previous() throws SQLException {
1214:                return super .previous();
1215:            }
1216:
1217:            /**
1218:             * Closes this ResultSet, releasing all resources.
1219:             *
1220:             * @param calledExplicitly
1221:             *            was this called from close()?
1222:             *
1223:             * @throws SQLException
1224:             *             if an error occurs.
1225:             */
1226:            public void realClose(boolean calledExplicitly) throws SQLException {
1227:                if (this .isClosed) {
1228:                    return;
1229:                }
1230:
1231:                SQLException sqlEx = null;
1232:
1233:                if (this .useUsageAdvisor) {
1234:                    if ((this .deleter == null) && (this .inserter == null)
1235:                            && (this .refresher == null)
1236:                            && (this .updater == null)) {
1237:                        this .eventSink = ProfileEventSink
1238:                                .getInstance(this .connection);
1239:
1240:                        String message = Messages
1241:                                .getString("UpdatableResultSet.34"); //$NON-NLS-1$
1242:
1243:                        this .eventSink.consumeEvent(new ProfilerEvent(
1244:                                ProfilerEvent.TYPE_WARN,
1245:                                "", //$NON-NLS-1$
1246:                                (this .owningStatement == null) ? "N/A" //$NON-NLS-1$
1247:                                        : this .owningStatement.currentCatalog, //$NON-NLS-1$
1248:                                this .connectionId,
1249:                                (this .owningStatement == null) ? (-1)
1250:                                        : this .owningStatement.getId(),
1251:                                this .resultId, System.currentTimeMillis(), 0,
1252:                                Constants.MILLIS_I18N, null,
1253:                                this .pointOfOrigin, message));
1254:                    }
1255:                }
1256:
1257:                try {
1258:                    if (this .deleter != null) {
1259:                        this .deleter.close();
1260:                    }
1261:                } catch (SQLException ex) {
1262:                    sqlEx = ex;
1263:                }
1264:
1265:                try {
1266:                    if (this .inserter != null) {
1267:                        this .inserter.close();
1268:                    }
1269:                } catch (SQLException ex) {
1270:                    sqlEx = ex;
1271:                }
1272:
1273:                try {
1274:                    if (this .refresher != null) {
1275:                        this .refresher.close();
1276:                    }
1277:                } catch (SQLException ex) {
1278:                    sqlEx = ex;
1279:                }
1280:
1281:                try {
1282:                    if (this .updater != null) {
1283:                        this .updater.close();
1284:                    }
1285:                } catch (SQLException ex) {
1286:                    sqlEx = ex;
1287:                }
1288:
1289:                super .realClose(calledExplicitly);
1290:
1291:                if (sqlEx != null) {
1292:                    throw sqlEx;
1293:                }
1294:            }
1295:
1296:            /**
1297:             * JDBC 2.0 Refresh the value of the current row with its current value in
1298:             * the database. Cannot be called when on the insert row. The refreshRow()
1299:             * method provides a way for an application to explicitly tell the JDBC
1300:             * driver to refetch a row(s) from the database. An application may want to
1301:             * call refreshRow() when caching or prefetching is being done by the JDBC
1302:             * driver to fetch the latest value of a row from the database. The JDBC
1303:             * driver may actually refresh multiple rows at once if the fetch size is
1304:             * greater than one. All values are refetched subject to the transaction
1305:             * isolation level and cursor sensitivity. If refreshRow() is called after
1306:             * calling updateXXX(), but before calling updateRow() then the updates made
1307:             * to the row are lost. Calling refreshRow() frequently will likely slow
1308:             * performance.
1309:             *
1310:             * @exception SQLException
1311:             *                if a database-access error occurs, or if called when on
1312:             *                the insert row.
1313:             * @throws NotUpdatable
1314:             *             DOCUMENT ME!
1315:             */
1316:            public synchronized void refreshRow() throws SQLException {
1317:                checkClosed();
1318:
1319:                if (!this .isUpdatable) {
1320:                    throw new NotUpdatable();
1321:                }
1322:
1323:                if (this .onInsertRow) {
1324:                    throw SQLError.createSQLException(Messages
1325:                            .getString("UpdatableResultSet.8")); //$NON-NLS-1$
1326:                } else if (this .rowData.size() == 0) {
1327:                    throw SQLError.createSQLException(Messages
1328:                            .getString("UpdatableResultSet.9")); //$NON-NLS-1$
1329:                } else if (isBeforeFirst()) {
1330:                    throw SQLError.createSQLException(Messages
1331:                            .getString("UpdatableResultSet.10")); //$NON-NLS-1$
1332:                } else if (isAfterLast()) {
1333:                    throw SQLError.createSQLException(Messages
1334:                            .getString("UpdatableResultSet.11")); //$NON-NLS-1$
1335:                }
1336:
1337:                refreshRow(this .updater, this .this Row);
1338:            }
1339:
1340:            private synchronized void refreshRow(
1341:                    PreparedStatement updateInsertStmt,
1342:                    ResultSetRow rowToRefresh) throws SQLException {
1343:                if (this .refresher == null) {
1344:                    if (this .refreshSQL == null) {
1345:                        generateStatements();
1346:                    }
1347:
1348:                    this .refresher = this .connection
1349:                            .clientPrepareStatement(this .refreshSQL);
1350:                }
1351:
1352:                this .refresher.clearParameters();
1353:
1354:                int numKeys = this .primaryKeyIndicies.size();
1355:
1356:                if (numKeys == 1) {
1357:                    byte[] dataFrom = null;
1358:                    int index = ((Integer) this .primaryKeyIndicies.get(0))
1359:                            .intValue();
1360:
1361:                    if (!this .doingUpdates && !this .onInsertRow) {
1362:                        dataFrom = (byte[]) rowToRefresh.getColumnValue(index);
1363:                    } else {
1364:                        dataFrom = updateInsertStmt
1365:                                .getBytesRepresentation(index);
1366:
1367:                        // Primary keys not set?
1368:                        if (updateInsertStmt.isNull(index)
1369:                                || (dataFrom.length == 0)) {
1370:                            dataFrom = (byte[]) rowToRefresh
1371:                                    .getColumnValue(index);
1372:                        } else {
1373:                            dataFrom = stripBinaryPrefix(dataFrom);
1374:                        }
1375:                    }
1376:
1377:                    this .refresher.setBytesNoEscape(1, dataFrom);
1378:                } else {
1379:                    for (int i = 0; i < numKeys; i++) {
1380:                        byte[] dataFrom = null;
1381:                        int index = ((Integer) this .primaryKeyIndicies.get(i))
1382:                                .intValue();
1383:
1384:                        if (!this .doingUpdates && !this .onInsertRow) {
1385:                            dataFrom = (byte[]) rowToRefresh
1386:                                    .getColumnValue(index);
1387:                        } else {
1388:                            dataFrom = updateInsertStmt
1389:                                    .getBytesRepresentation(index);
1390:
1391:                            // Primary keys not set?
1392:                            if (updateInsertStmt.isNull(index)
1393:                                    || (dataFrom.length == 0)) {
1394:                                dataFrom = (byte[]) rowToRefresh
1395:                                        .getColumnValue(index);
1396:                            } else {
1397:                                dataFrom = stripBinaryPrefix(dataFrom);
1398:                            }
1399:                        }
1400:
1401:                        this .refresher.setBytesNoEscape(i + 1, dataFrom);
1402:                    }
1403:                }
1404:
1405:                java.sql.ResultSet rs = null;
1406:
1407:                try {
1408:                    rs = this .refresher.executeQuery();
1409:
1410:                    int numCols = rs.getMetaData().getColumnCount();
1411:
1412:                    if (rs.next()) {
1413:                        for (int i = 0; i < numCols; i++) {
1414:                            byte[] val = rs.getBytes(i + 1);
1415:
1416:                            if ((val == null) || rs.wasNull()) {
1417:                                rowToRefresh.setColumnValue(i, null);
1418:                            } else {
1419:                                rowToRefresh.setColumnValue(i, rs
1420:                                        .getBytes(i + 1));
1421:                            }
1422:                        }
1423:                    } else {
1424:                        throw SQLError.createSQLException(Messages
1425:                                .getString("UpdatableResultSet.12"), //$NON-NLS-1$
1426:                                SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
1427:                    }
1428:                } finally {
1429:                    if (rs != null) {
1430:                        try {
1431:                            rs.close();
1432:                        } catch (SQLException ex) {
1433:                            ; // ignore
1434:                        }
1435:                    }
1436:                }
1437:            }
1438:
1439:            /**
1440:             * JDBC 2.0
1441:             *
1442:             * <p>
1443:             * Moves a relative number of rows, either positive or negative. Attempting
1444:             * to move beyond the first/last row in the result set positions the cursor
1445:             * before/after the the first/last row. Calling relative(0) is valid, but
1446:             * does not change the cursor position.
1447:             * </p>
1448:             *
1449:             * <p>
1450:             * Note: Calling relative(1) is different than calling next() since is makes
1451:             * sense to call next() when there is no current row, for example, when the
1452:             * cursor is positioned before the first row or after the last row of the
1453:             * result set.
1454:             * </p>
1455:             *
1456:             * @param rows
1457:             *            DOCUMENT ME!
1458:             *
1459:             * @return true if on a row, false otherwise.
1460:             *
1461:             * @exception SQLException
1462:             *                if a database-access error occurs, or there is no current
1463:             *                row, or result set type is TYPE_FORWARD_ONLY.
1464:             */
1465:            public synchronized boolean relative(int rows) throws SQLException {
1466:                return super .relative(rows);
1467:            }
1468:
1469:            private void resetInserter() throws SQLException {
1470:                this .inserter.clearParameters();
1471:
1472:                for (int i = 0; i < this .fields.length; i++) {
1473:                    this .inserter.setNull(i + 1, 0);
1474:                }
1475:            }
1476:
1477:            /**
1478:             * JDBC 2.0 Determine if this row has been deleted. A deleted row may leave
1479:             * a visible "hole" in a result set. This method can be used to detect holes
1480:             * in a result set. The value returned depends on whether or not the result
1481:             * set can detect deletions.
1482:             *
1483:             * @return true if deleted and deletes are detected
1484:             *
1485:             * @exception SQLException
1486:             *                if a database-access error occurs
1487:             * @throws NotImplemented
1488:             *             DOCUMENT ME!
1489:             *
1490:             * @see DatabaseMetaData#deletesAreDetected
1491:             */
1492:            public synchronized boolean rowDeleted() throws SQLException {
1493:                throw new NotImplemented();
1494:            }
1495:
1496:            /**
1497:             * JDBC 2.0 Determine if the current row has been inserted. The value
1498:             * returned depends on whether or not the result set can detect visible
1499:             * inserts.
1500:             *
1501:             * @return true if inserted and inserts are detected
1502:             *
1503:             * @exception SQLException
1504:             *                if a database-access error occurs
1505:             * @throws NotImplemented
1506:             *             DOCUMENT ME!
1507:             *
1508:             * @see DatabaseMetaData#insertsAreDetected
1509:             */
1510:            public synchronized boolean rowInserted() throws SQLException {
1511:                throw new NotImplemented();
1512:            }
1513:
1514:            /**
1515:             * JDBC 2.0 Determine if the current row has been updated. The value
1516:             * returned depends on whether or not the result set can detect updates.
1517:             *
1518:             * @return true if the row has been visibly updated by the owner or another,
1519:             *         and updates are detected
1520:             *
1521:             * @exception SQLException
1522:             *                if a database-access error occurs
1523:             * @throws NotImplemented
1524:             *             DOCUMENT ME!
1525:             *
1526:             * @see DatabaseMetaData#updatesAreDetected
1527:             */
1528:            public synchronized boolean rowUpdated() throws SQLException {
1529:                throw new NotImplemented();
1530:            }
1531:
1532:            /**
1533:             * Sets the concurrency type of this result set
1534:             *
1535:             * @param concurrencyFlag
1536:             *            the type of concurrency that this ResultSet should support.
1537:             */
1538:            protected void setResultSetConcurrency(int concurrencyFlag) {
1539:                super .setResultSetConcurrency(concurrencyFlag);
1540:
1541:                //
1542:                // FIXME: Issue warning when asked for updateable result set, but result
1543:                // set is not
1544:                // updatable
1545:                //
1546:                // if ((concurrencyFlag == CONCUR_UPDATABLE) && !isUpdatable()) {
1547:                // java.sql.SQLWarning warning = new java.sql.SQLWarning(
1548:                // NotUpdatable.NOT_UPDATEABLE_MESSAGE);
1549:                // }
1550:            }
1551:
1552:            private byte[] stripBinaryPrefix(byte[] dataFrom) {
1553:                return StringUtils.stripEnclosure(dataFrom, "_binary'", "'");
1554:            }
1555:
1556:            /**
1557:             * Reset UPDATE prepared statement to value in current row. This_Row MUST
1558:             * point to current, valid row.
1559:             *
1560:             * @throws SQLException
1561:             *             DOCUMENT ME!
1562:             */
1563:            protected synchronized void syncUpdate() throws SQLException {
1564:                if (this .updater == null) {
1565:                    if (this .updateSQL == null) {
1566:                        generateStatements();
1567:                    }
1568:
1569:                    this .updater = this .connection
1570:                            .clientPrepareStatement(this .updateSQL);
1571:                }
1572:
1573:                int numFields = this .fields.length;
1574:                this .updater.clearParameters();
1575:
1576:                for (int i = 0; i < numFields; i++) {
1577:                    if (this .this Row.getColumnValue(i) != null) {
1578:                        this .updater.setBytes(i + 1, (byte[]) this .this Row
1579:                                .getColumnValue(i), this .fields[i].isBinary(),
1580:                                false);
1581:                    } else {
1582:                        this .updater.setNull(i + 1, 0);
1583:                    }
1584:                }
1585:
1586:                int numKeys = this .primaryKeyIndicies.size();
1587:
1588:                if (numKeys == 1) {
1589:                    int index = ((Integer) this .primaryKeyIndicies.get(0))
1590:                            .intValue();
1591:                    byte[] keyData = (byte[]) this .this Row
1592:                            .getColumnValue(index);
1593:                    this .updater.setBytes(numFields + 1, keyData, false, false);
1594:                } else {
1595:                    for (int i = 0; i < numKeys; i++) {
1596:                        byte[] currentVal = (byte[]) this .this Row
1597:                                .getColumnValue(((Integer) this .primaryKeyIndicies
1598:                                        .get(i)).intValue());
1599:
1600:                        if (currentVal != null) {
1601:                            this .updater.setBytes(numFields + i + 1,
1602:                                    currentVal, false, false);
1603:                        } else {
1604:                            this .updater.setNull(numFields + i + 1, 0);
1605:                        }
1606:                    }
1607:                }
1608:            }
1609:
1610:            /**
1611:             * JDBC 2.0 Update a column with an ascii stream value. The updateXXX()
1612:             * methods are used to update column values in the current row, or the
1613:             * insert row. The updateXXX() methods do not update the underlying
1614:             * database, instead the updateRow() or insertRow() methods are called to
1615:             * update the database.
1616:             *
1617:             * @param columnIndex
1618:             *            the first column is 1, the second is 2, ...
1619:             * @param x
1620:             *            the new column value
1621:             * @param length
1622:             *            the length of the stream
1623:             *
1624:             * @exception SQLException
1625:             *                if a database-access error occurs
1626:             */
1627:            public synchronized void updateAsciiStream(int columnIndex,
1628:                    java.io.InputStream x, int length) throws SQLException {
1629:                if (!this .onInsertRow) {
1630:                    if (!this .doingUpdates) {
1631:                        this .doingUpdates = true;
1632:                        syncUpdate();
1633:                    }
1634:
1635:                    this .updater.setAsciiStream(columnIndex, x, length);
1636:                } else {
1637:                    this .inserter.setAsciiStream(columnIndex, x, length);
1638:                    this .this Row.setColumnValue(columnIndex - 1,
1639:                            STREAM_DATA_MARKER);
1640:                }
1641:            }
1642:
1643:            /**
1644:             * JDBC 2.0 Update a column with an ascii stream value. The updateXXX()
1645:             * methods are used to update column values in the current row, or the
1646:             * insert row. The updateXXX() methods do not update the underlying
1647:             * database, instead the updateRow() or insertRow() methods are called to
1648:             * update the database.
1649:             *
1650:             * @param columnName
1651:             *            the name of the column
1652:             * @param x
1653:             *            the new column value
1654:             * @param length
1655:             *            of the stream
1656:             *
1657:             * @exception SQLException
1658:             *                if a database-access error occurs
1659:             */
1660:            public synchronized void updateAsciiStream(String columnName,
1661:                    java.io.InputStream x, int length) throws SQLException {
1662:                updateAsciiStream(findColumn(columnName), x, length);
1663:            }
1664:
1665:            /**
1666:             * JDBC 2.0 Update a column with a BigDecimal value. The updateXXX() methods
1667:             * are used to update column values in the current row, or the insert row.
1668:             * The updateXXX() methods do not update the underlying database, instead
1669:             * the updateRow() or insertRow() methods are called to update the database.
1670:             *
1671:             * @param columnIndex
1672:             *            the first column is 1, the second is 2, ...
1673:             * @param x
1674:             *            the new column value
1675:             *
1676:             * @exception SQLException
1677:             *                if a database-access error occurs
1678:             */
1679:            public synchronized void updateBigDecimal(int columnIndex,
1680:                    BigDecimal x) throws SQLException {
1681:                if (!this .onInsertRow) {
1682:                    if (!this .doingUpdates) {
1683:                        this .doingUpdates = true;
1684:                        syncUpdate();
1685:                    }
1686:
1687:                    this .updater.setBigDecimal(columnIndex, x);
1688:                } else {
1689:                    this .inserter.setBigDecimal(columnIndex, x);
1690:
1691:                    if (x == null) {
1692:                        this .this Row.setColumnValue(columnIndex - 1, null);
1693:                    } else {
1694:                        this .this Row.setColumnValue(columnIndex - 1, x
1695:                                .toString().getBytes());
1696:                    }
1697:                }
1698:            }
1699:
1700:            /**
1701:             * JDBC 2.0 Update a column with a BigDecimal value. The updateXXX() methods
1702:             * are used to update column values in the current row, or the insert row.
1703:             * The updateXXX() methods do not update the underlying database, instead
1704:             * the updateRow() or insertRow() methods are called to update the database.
1705:             *
1706:             * @param columnName
1707:             *            the name of the column
1708:             * @param x
1709:             *            the new column value
1710:             *
1711:             * @exception SQLException
1712:             *                if a database-access error occurs
1713:             */
1714:            public synchronized void updateBigDecimal(String columnName,
1715:                    BigDecimal x) throws SQLException {
1716:                updateBigDecimal(findColumn(columnName), x);
1717:            }
1718:
1719:            /**
1720:             * JDBC 2.0 Update a column with a binary stream value. The updateXXX()
1721:             * methods are used to update column values in the current row, or the
1722:             * insert row. The updateXXX() methods do not update the underlying
1723:             * database, instead the updateRow() or insertRow() methods are called to
1724:             * update the database.
1725:             *
1726:             * @param columnIndex
1727:             *            the first column is 1, the second is 2, ...
1728:             * @param x
1729:             *            the new column value
1730:             * @param length
1731:             *            the length of the stream
1732:             *
1733:             * @exception SQLException
1734:             *                if a database-access error occurs
1735:             */
1736:            public synchronized void updateBinaryStream(int columnIndex,
1737:                    java.io.InputStream x, int length) throws SQLException {
1738:                if (!this .onInsertRow) {
1739:                    if (!this .doingUpdates) {
1740:                        this .doingUpdates = true;
1741:                        syncUpdate();
1742:                    }
1743:
1744:                    this .updater.setBinaryStream(columnIndex, x, length);
1745:                } else {
1746:                    this .inserter.setBinaryStream(columnIndex, x, length);
1747:
1748:                    if (x == null) {
1749:                        this .this Row.setColumnValue(columnIndex - 1, null);
1750:                    } else {
1751:                        this .this Row.setColumnValue(columnIndex - 1,
1752:                                STREAM_DATA_MARKER);
1753:                    }
1754:                }
1755:            }
1756:
1757:            /**
1758:             * JDBC 2.0 Update a column with a binary stream value. The updateXXX()
1759:             * methods are used to update column values in the current row, or the
1760:             * insert row. The updateXXX() methods do not update the underlying
1761:             * database, instead the updateRow() or insertRow() methods are called to
1762:             * update the database.
1763:             *
1764:             * @param columnName
1765:             *            the name of the column
1766:             * @param x
1767:             *            the new column value
1768:             * @param length
1769:             *            of the stream
1770:             *
1771:             * @exception SQLException
1772:             *                if a database-access error occurs
1773:             */
1774:            public synchronized void updateBinaryStream(String columnName,
1775:                    java.io.InputStream x, int length) throws SQLException {
1776:                updateBinaryStream(findColumn(columnName), x, length);
1777:            }
1778:
1779:            /**
1780:             * @see ResultSetInternalMethods#updateBlob(int, Blob)
1781:             */
1782:            public synchronized void updateBlob(int columnIndex,
1783:                    java.sql.Blob blob) throws SQLException {
1784:                if (!this .onInsertRow) {
1785:                    if (!this .doingUpdates) {
1786:                        this .doingUpdates = true;
1787:                        syncUpdate();
1788:                    }
1789:
1790:                    this .updater.setBlob(columnIndex, blob);
1791:                } else {
1792:                    this .inserter.setBlob(columnIndex, blob);
1793:
1794:                    if (blob == null) {
1795:                        this .this Row.setColumnValue(columnIndex - 1, null);
1796:                    } else {
1797:                        this .this Row.setColumnValue(columnIndex - 1,
1798:                                STREAM_DATA_MARKER);
1799:                    }
1800:                }
1801:            }
1802:
1803:            /**
1804:             * @see ResultSetInternalMethods#updateBlob(String, Blob)
1805:             */
1806:            public synchronized void updateBlob(String columnName,
1807:                    java.sql.Blob blob) throws SQLException {
1808:                updateBlob(findColumn(columnName), blob);
1809:            }
1810:
1811:            /**
1812:             * JDBC 2.0 Update a column with a boolean value. The updateXXX() methods
1813:             * are used to update column values in the current row, or the insert row.
1814:             * The updateXXX() methods do not update the underlying database, instead
1815:             * the updateRow() or insertRow() methods are called to update the database.
1816:             *
1817:             * @param columnIndex
1818:             *            the first column is 1, the second is 2, ...
1819:             * @param x
1820:             *            the new column value
1821:             *
1822:             * @exception SQLException
1823:             *                if a database-access error occurs
1824:             */
1825:            public synchronized void updateBoolean(int columnIndex, boolean x)
1826:                    throws SQLException {
1827:                if (!this .onInsertRow) {
1828:                    if (!this .doingUpdates) {
1829:                        this .doingUpdates = true;
1830:                        syncUpdate();
1831:                    }
1832:
1833:                    this .updater.setBoolean(columnIndex, x);
1834:                } else {
1835:                    this .inserter.setBoolean(columnIndex, x);
1836:
1837:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
1838:                            .getBytesRepresentation(columnIndex - 1));
1839:                }
1840:            }
1841:
1842:            /**
1843:             * JDBC 2.0 Update a column with a boolean value. The updateXXX() methods
1844:             * are used to update column values in the current row, or the insert row.
1845:             * The updateXXX() methods do not update the underlying database, instead
1846:             * the updateRow() or insertRow() methods are called to update the database.
1847:             *
1848:             * @param columnName
1849:             *            the name of the column
1850:             * @param x
1851:             *            the new column value
1852:             *
1853:             * @exception SQLException
1854:             *                if a database-access error occurs
1855:             */
1856:            public synchronized void updateBoolean(String columnName, boolean x)
1857:                    throws SQLException {
1858:                updateBoolean(findColumn(columnName), x);
1859:            }
1860:
1861:            /**
1862:             * JDBC 2.0 Update a column with a byte value. The updateXXX() methods are
1863:             * used to update column values in the current row, or the insert row. The
1864:             * updateXXX() methods do not update the underlying database, instead the
1865:             * updateRow() or insertRow() methods are called to update the database.
1866:             *
1867:             * @param columnIndex
1868:             *            the first column is 1, the second is 2, ...
1869:             * @param x
1870:             *            the new column value
1871:             *
1872:             * @exception SQLException
1873:             *                if a database-access error occurs
1874:             */
1875:            public synchronized void updateByte(int columnIndex, byte x)
1876:                    throws SQLException {
1877:                if (!this .onInsertRow) {
1878:                    if (!this .doingUpdates) {
1879:                        this .doingUpdates = true;
1880:                        syncUpdate();
1881:                    }
1882:
1883:                    this .updater.setByte(columnIndex, x);
1884:                } else {
1885:                    this .inserter.setByte(columnIndex, x);
1886:
1887:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
1888:                            .getBytesRepresentation(columnIndex - 1));
1889:                }
1890:            }
1891:
1892:            /**
1893:             * JDBC 2.0 Update a column with a byte value. The updateXXX() methods are
1894:             * used to update column values in the current row, or the insert row. The
1895:             * updateXXX() methods do not update the underlying database, instead the
1896:             * updateRow() or insertRow() methods are called to update the database.
1897:             *
1898:             * @param columnName
1899:             *            the name of the column
1900:             * @param x
1901:             *            the new column value
1902:             *
1903:             * @exception SQLException
1904:             *                if a database-access error occurs
1905:             */
1906:            public synchronized void updateByte(String columnName, byte x)
1907:                    throws SQLException {
1908:                updateByte(findColumn(columnName), x);
1909:            }
1910:
1911:            /**
1912:             * JDBC 2.0 Update a column with a byte array value. The updateXXX() methods
1913:             * are used to update column values in the current row, or the insert row.
1914:             * The updateXXX() methods do not update the underlying database, instead
1915:             * the updateRow() or insertRow() methods are called to update the database.
1916:             *
1917:             * @param columnIndex
1918:             *            the first column is 1, the second is 2, ...
1919:             * @param x
1920:             *            the new column value
1921:             *
1922:             * @exception SQLException
1923:             *                if a database-access error occurs
1924:             */
1925:            public synchronized void updateBytes(int columnIndex, byte[] x)
1926:                    throws SQLException {
1927:                if (!this .onInsertRow) {
1928:                    if (!this .doingUpdates) {
1929:                        this .doingUpdates = true;
1930:                        syncUpdate();
1931:                    }
1932:
1933:                    this .updater.setBytes(columnIndex, x);
1934:                } else {
1935:                    this .inserter.setBytes(columnIndex, x);
1936:
1937:                    this .this Row.setColumnValue(columnIndex - 1, x);
1938:                }
1939:            }
1940:
1941:            /**
1942:             * JDBC 2.0 Update a column with a byte array value. The updateXXX() methods
1943:             * are used to update column values in the current row, or the insert row.
1944:             * The updateXXX() methods do not update the underlying database, instead
1945:             * the updateRow() or insertRow() methods are called to update the database.
1946:             *
1947:             * @param columnName
1948:             *            the name of the column
1949:             * @param x
1950:             *            the new column value
1951:             *
1952:             * @exception SQLException
1953:             *                if a database-access error occurs
1954:             */
1955:            public synchronized void updateBytes(String columnName, byte[] x)
1956:                    throws SQLException {
1957:                updateBytes(findColumn(columnName), x);
1958:            }
1959:
1960:            /**
1961:             * JDBC 2.0 Update a column with a character stream value. The updateXXX()
1962:             * methods are used to update column values in the current row, or the
1963:             * insert row. The updateXXX() methods do not update the underlying
1964:             * database, instead the updateRow() or insertRow() methods are called to
1965:             * update the database.
1966:             *
1967:             * @param columnIndex
1968:             *            the first column is 1, the second is 2, ...
1969:             * @param x
1970:             *            the new column value
1971:             * @param length
1972:             *            the length of the stream
1973:             *
1974:             * @exception SQLException
1975:             *                if a database-access error occurs
1976:             */
1977:            public synchronized void updateCharacterStream(int columnIndex,
1978:                    java.io.Reader x, int length) throws SQLException {
1979:                if (!this .onInsertRow) {
1980:                    if (!this .doingUpdates) {
1981:                        this .doingUpdates = true;
1982:                        syncUpdate();
1983:                    }
1984:
1985:                    this .updater.setCharacterStream(columnIndex, x, length);
1986:                } else {
1987:                    this .inserter.setCharacterStream(columnIndex, x, length);
1988:
1989:                    if (x == null) {
1990:                        this .this Row.setColumnValue(columnIndex - 1, null);
1991:                    } else {
1992:                        this .this Row.setColumnValue(columnIndex - 1,
1993:                                STREAM_DATA_MARKER);
1994:                    }
1995:                }
1996:            }
1997:
1998:            /**
1999:             * JDBC 2.0 Update a column with a character stream value. The updateXXX()
2000:             * methods are used to update column values in the current row, or the
2001:             * insert row. The updateXXX() methods do not update the underlying
2002:             * database, instead the updateRow() or insertRow() methods are called to
2003:             * update the database.
2004:             *
2005:             * @param columnName
2006:             *            the name of the column
2007:             * @param reader
2008:             *            the new column value
2009:             * @param length
2010:             *            of the stream
2011:             *
2012:             * @exception SQLException
2013:             *                if a database-access error occurs
2014:             */
2015:            public synchronized void updateCharacterStream(String columnName,
2016:                    java.io.Reader reader, int length) throws SQLException {
2017:                updateCharacterStream(findColumn(columnName), reader, length);
2018:            }
2019:
2020:            /**
2021:             * @see ResultSetInternalMethods#updateClob(int, Clob)
2022:             */
2023:            public void updateClob(int columnIndex, java.sql.Clob clob)
2024:                    throws SQLException {
2025:                if (clob == null) {
2026:                    updateNull(columnIndex);
2027:                } else {
2028:                    updateCharacterStream(columnIndex, clob
2029:                            .getCharacterStream(), (int) clob.length());
2030:                }
2031:            }
2032:
2033:            /**
2034:             * JDBC 2.0 Update a column with a Date value. The updateXXX() methods are
2035:             * used to update column values in the current row, or the insert row. The
2036:             * updateXXX() methods do not update the underlying database, instead the
2037:             * updateRow() or insertRow() methods are called to update the database.
2038:             *
2039:             * @param columnIndex
2040:             *            the first column is 1, the second is 2, ...
2041:             * @param x
2042:             *            the new column value
2043:             *
2044:             * @exception SQLException
2045:             *                if a database-access error occurs
2046:             */
2047:            public synchronized void updateDate(int columnIndex, java.sql.Date x)
2048:                    throws SQLException {
2049:                if (!this .onInsertRow) {
2050:                    if (!this .doingUpdates) {
2051:                        this .doingUpdates = true;
2052:                        syncUpdate();
2053:                    }
2054:
2055:                    this .updater.setDate(columnIndex, x);
2056:                } else {
2057:                    this .inserter.setDate(columnIndex, x);
2058:
2059:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2060:                            .getBytesRepresentation(columnIndex - 1));
2061:                }
2062:            }
2063:
2064:            /**
2065:             * JDBC 2.0 Update a column with a Date value. The updateXXX() methods are
2066:             * used to update column values in the current row, or the insert row. The
2067:             * updateXXX() methods do not update the underlying database, instead the
2068:             * updateRow() or insertRow() methods are called to update the database.
2069:             *
2070:             * @param columnName
2071:             *            the name of the column
2072:             * @param x
2073:             *            the new column value
2074:             *
2075:             * @exception SQLException
2076:             *                if a database-access error occurs
2077:             */
2078:            public synchronized void updateDate(String columnName,
2079:                    java.sql.Date x) throws SQLException {
2080:                updateDate(findColumn(columnName), x);
2081:            }
2082:
2083:            /**
2084:             * JDBC 2.0 Update a column with a Double value. The updateXXX() methods are
2085:             * used to update column values in the current row, or the insert row. The
2086:             * updateXXX() methods do not update the underlying database, instead the
2087:             * updateRow() or insertRow() methods are called to update the database.
2088:             *
2089:             * @param columnIndex
2090:             *            the first column is 1, the second is 2, ...
2091:             * @param x
2092:             *            the new column value
2093:             *
2094:             * @exception SQLException
2095:             *                if a database-access error occurs
2096:             */
2097:            public synchronized void updateDouble(int columnIndex, double x)
2098:                    throws SQLException {
2099:                if (!this .onInsertRow) {
2100:                    if (!this .doingUpdates) {
2101:                        this .doingUpdates = true;
2102:                        syncUpdate();
2103:                    }
2104:
2105:                    this .updater.setDouble(columnIndex, x);
2106:                } else {
2107:                    this .inserter.setDouble(columnIndex, x);
2108:
2109:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2110:                            .getBytesRepresentation(columnIndex - 1));
2111:                }
2112:            }
2113:
2114:            /**
2115:             * JDBC 2.0 Update a column with a double value. The updateXXX() methods are
2116:             * used to update column values in the current row, or the insert row. The
2117:             * updateXXX() methods do not update the underlying database, instead the
2118:             * updateRow() or insertRow() methods are called to update the database.
2119:             *
2120:             * @param columnName
2121:             *            the name of the column
2122:             * @param x
2123:             *            the new column value
2124:             *
2125:             * @exception SQLException
2126:             *                if a database-access error occurs
2127:             */
2128:            public synchronized void updateDouble(String columnName, double x)
2129:                    throws SQLException {
2130:                updateDouble(findColumn(columnName), x);
2131:            }
2132:
2133:            /**
2134:             * JDBC 2.0 Update a column with a float value. The updateXXX() methods are
2135:             * used to update column values in the current row, or the insert row. The
2136:             * updateXXX() methods do not update the underlying database, instead the
2137:             * updateRow() or insertRow() methods are called to update the database.
2138:             *
2139:             * @param columnIndex
2140:             *            the first column is 1, the second is 2, ...
2141:             * @param x
2142:             *            the new column value
2143:             *
2144:             * @exception SQLException
2145:             *                if a database-access error occurs
2146:             */
2147:            public synchronized void updateFloat(int columnIndex, float x)
2148:                    throws SQLException {
2149:                if (!this .onInsertRow) {
2150:                    if (!this .doingUpdates) {
2151:                        this .doingUpdates = true;
2152:                        syncUpdate();
2153:                    }
2154:
2155:                    this .updater.setFloat(columnIndex, x);
2156:                } else {
2157:                    this .inserter.setFloat(columnIndex, x);
2158:
2159:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2160:                            .getBytesRepresentation(columnIndex - 1));
2161:                }
2162:            }
2163:
2164:            /**
2165:             * JDBC 2.0 Update a column with a float value. The updateXXX() methods are
2166:             * used to update column values in the current row, or the insert row. The
2167:             * updateXXX() methods do not update the underlying database, instead the
2168:             * updateRow() or insertRow() methods are called to update the database.
2169:             *
2170:             * @param columnName
2171:             *            the name of the column
2172:             * @param x
2173:             *            the new column value
2174:             *
2175:             * @exception SQLException
2176:             *                if a database-access error occurs
2177:             */
2178:            public synchronized void updateFloat(String columnName, float x)
2179:                    throws SQLException {
2180:                updateFloat(findColumn(columnName), x);
2181:            }
2182:
2183:            /**
2184:             * JDBC 2.0 Update a column with an integer value. The updateXXX() methods
2185:             * are used to update column values in the current row, or the insert row.
2186:             * The updateXXX() methods do not update the underlying database, instead
2187:             * the updateRow() or insertRow() methods are called to update the database.
2188:             *
2189:             * @param columnIndex
2190:             *            the first column is 1, the second is 2, ...
2191:             * @param x
2192:             *            the new column value
2193:             *
2194:             * @exception SQLException
2195:             *                if a database-access error occurs
2196:             */
2197:            public synchronized void updateInt(int columnIndex, int x)
2198:                    throws SQLException {
2199:                if (!this .onInsertRow) {
2200:                    if (!this .doingUpdates) {
2201:                        this .doingUpdates = true;
2202:                        syncUpdate();
2203:                    }
2204:
2205:                    this .updater.setInt(columnIndex, x);
2206:                } else {
2207:                    this .inserter.setInt(columnIndex, x);
2208:
2209:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2210:                            .getBytesRepresentation(columnIndex - 1));
2211:                }
2212:            }
2213:
2214:            /**
2215:             * JDBC 2.0 Update a column with an integer value. The updateXXX() methods
2216:             * are used to update column values in the current row, or the insert row.
2217:             * The updateXXX() methods do not update the underlying database, instead
2218:             * the updateRow() or insertRow() methods are called to update the database.
2219:             *
2220:             * @param columnName
2221:             *            the name of the column
2222:             * @param x
2223:             *            the new column value
2224:             *
2225:             * @exception SQLException
2226:             *                if a database-access error occurs
2227:             */
2228:            public synchronized void updateInt(String columnName, int x)
2229:                    throws SQLException {
2230:                updateInt(findColumn(columnName), x);
2231:            }
2232:
2233:            /**
2234:             * JDBC 2.0 Update a column with a long value. The updateXXX() methods are
2235:             * used to update column values in the current row, or the insert row. The
2236:             * updateXXX() methods do not update the underlying database, instead the
2237:             * updateRow() or insertRow() methods are called to update the database.
2238:             *
2239:             * @param columnIndex
2240:             *            the first column is 1, the second is 2, ...
2241:             * @param x
2242:             *            the new column value
2243:             *
2244:             * @exception SQLException
2245:             *                if a database-access error occurs
2246:             */
2247:            public synchronized void updateLong(int columnIndex, long x)
2248:                    throws SQLException {
2249:                if (!this .onInsertRow) {
2250:                    if (!this .doingUpdates) {
2251:                        this .doingUpdates = true;
2252:                        syncUpdate();
2253:                    }
2254:
2255:                    this .updater.setLong(columnIndex, x);
2256:                } else {
2257:                    this .inserter.setLong(columnIndex, x);
2258:
2259:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2260:                            .getBytesRepresentation(columnIndex - 1));
2261:                }
2262:            }
2263:
2264:            /**
2265:             * JDBC 2.0 Update a column with a long value. The updateXXX() methods are
2266:             * used to update column values in the current row, or the insert row. The
2267:             * updateXXX() methods do not update the underlying database, instead the
2268:             * updateRow() or insertRow() methods are called to update the database.
2269:             *
2270:             * @param columnName
2271:             *            the name of the column
2272:             * @param x
2273:             *            the new column value
2274:             *
2275:             * @exception SQLException
2276:             *                if a database-access error occurs
2277:             */
2278:            public synchronized void updateLong(String columnName, long x)
2279:                    throws SQLException {
2280:                updateLong(findColumn(columnName), x);
2281:            }
2282:
2283:            /**
2284:             * JDBC 2.0 Give a nullable column a null value. The updateXXX() methods are
2285:             * used to update column values in the current row, or the insert row. The
2286:             * updateXXX() methods do not update the underlying database, instead the
2287:             * updateRow() or insertRow() methods are called to update the database.
2288:             *
2289:             * @param columnIndex
2290:             *            the first column is 1, the second is 2, ...
2291:             *
2292:             * @exception SQLException
2293:             *                if a database-access error occurs
2294:             */
2295:            public synchronized void updateNull(int columnIndex)
2296:                    throws SQLException {
2297:                if (!this .onInsertRow) {
2298:                    if (!this .doingUpdates) {
2299:                        this .doingUpdates = true;
2300:                        syncUpdate();
2301:                    }
2302:
2303:                    this .updater.setNull(columnIndex, 0);
2304:                } else {
2305:                    this .inserter.setNull(columnIndex, 0);
2306:
2307:                    this .this Row.setColumnValue(columnIndex - 1, null);
2308:                }
2309:            }
2310:
2311:            /**
2312:             * JDBC 2.0 Update a column with a null value. The updateXXX() methods are
2313:             * used to update column values in the current row, or the insert row. The
2314:             * updateXXX() methods do not update the underlying database, instead the
2315:             * updateRow() or insertRow() methods are called to update the database.
2316:             *
2317:             * @param columnName
2318:             *            the name of the column
2319:             *
2320:             * @exception SQLException
2321:             *                if a database-access error occurs
2322:             */
2323:            public synchronized void updateNull(String columnName)
2324:                    throws SQLException {
2325:                updateNull(findColumn(columnName));
2326:            }
2327:
2328:            /**
2329:             * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
2330:             * are used to update column values in the current row, or the insert row.
2331:             * The updateXXX() methods do not update the underlying database, instead
2332:             * the updateRow() or insertRow() methods are called to update the database.
2333:             *
2334:             * @param columnIndex
2335:             *            the first column is 1, the second is 2, ...
2336:             * @param x
2337:             *            the new column value
2338:             *
2339:             * @exception SQLException
2340:             *                if a database-access error occurs
2341:             */
2342:            public synchronized void updateObject(int columnIndex, Object x)
2343:                    throws SQLException {
2344:                if (!this .onInsertRow) {
2345:                    if (!this .doingUpdates) {
2346:                        this .doingUpdates = true;
2347:                        syncUpdate();
2348:                    }
2349:
2350:                    this .updater.setObject(columnIndex, x);
2351:                } else {
2352:                    this .inserter.setObject(columnIndex, x);
2353:
2354:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2355:                            .getBytesRepresentation(columnIndex - 1));
2356:                }
2357:            }
2358:
2359:            /**
2360:             * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
2361:             * are used to update column values in the current row, or the insert row.
2362:             * The updateXXX() methods do not update the underlying database, instead
2363:             * the updateRow() or insertRow() methods are called to update the database.
2364:             *
2365:             * @param columnIndex
2366:             *            the first column is 1, the second is 2, ...
2367:             * @param x
2368:             *            the new column value
2369:             * @param scale
2370:             *            For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
2371:             *            this is the number of digits after the decimal. For all other
2372:             *            types this value will be ignored.
2373:             *
2374:             * @exception SQLException
2375:             *                if a database-access error occurs
2376:             */
2377:            public synchronized void updateObject(int columnIndex, Object x,
2378:                    int scale) throws SQLException {
2379:                if (!this .onInsertRow) {
2380:                    if (!this .doingUpdates) {
2381:                        this .doingUpdates = true;
2382:                        syncUpdate();
2383:                    }
2384:
2385:                    this .updater.setObject(columnIndex, x);
2386:                } else {
2387:                    this .inserter.setObject(columnIndex, x);
2388:
2389:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2390:                            .getBytesRepresentation(columnIndex - 1));
2391:                }
2392:            }
2393:
2394:            /**
2395:             * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
2396:             * are used to update column values in the current row, or the insert row.
2397:             * The updateXXX() methods do not update the underlying database, instead
2398:             * the updateRow() or insertRow() methods are called to update the database.
2399:             *
2400:             * @param columnName
2401:             *            the name of the column
2402:             * @param x
2403:             *            the new column value
2404:             *
2405:             * @exception SQLException
2406:             *                if a database-access error occurs
2407:             */
2408:            public synchronized void updateObject(String columnName, Object x)
2409:                    throws SQLException {
2410:                updateObject(findColumn(columnName), x);
2411:            }
2412:
2413:            /**
2414:             * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
2415:             * are used to update column values in the current row, or the insert row.
2416:             * The updateXXX() methods do not update the underlying database, instead
2417:             * the updateRow() or insertRow() methods are called to update the database.
2418:             *
2419:             * @param columnName
2420:             *            the name of the column
2421:             * @param x
2422:             *            the new column value
2423:             * @param scale
2424:             *            For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
2425:             *            this is the number of digits after the decimal. For all other
2426:             *            types this value will be ignored.
2427:             *
2428:             * @exception SQLException
2429:             *                if a database-access error occurs
2430:             */
2431:            public synchronized void updateObject(String columnName, Object x,
2432:                    int scale) throws SQLException {
2433:                updateObject(findColumn(columnName), x);
2434:            }
2435:
2436:            /**
2437:             * JDBC 2.0 Update the underlying database with the new contents of the
2438:             * current row. Cannot be called when on the insert row.
2439:             *
2440:             * @exception SQLException
2441:             *                if a database-access error occurs, or if called when on
2442:             *                the insert row
2443:             * @throws NotUpdatable
2444:             *             DOCUMENT ME!
2445:             */
2446:            public synchronized void updateRow() throws SQLException {
2447:                if (!this .isUpdatable) {
2448:                    throw new NotUpdatable(this .notUpdatableReason);
2449:                }
2450:
2451:                if (this .doingUpdates) {
2452:                    this .updater.executeUpdate();
2453:                    refreshRow();
2454:                    this .doingUpdates = false;
2455:                }
2456:
2457:                //
2458:                // fixes calling updateRow() and then doing more
2459:                // updates on same row...
2460:                syncUpdate();
2461:            }
2462:
2463:            /**
2464:             * JDBC 2.0 Update a column with a short value. The updateXXX() methods are
2465:             * used to update column values in the current row, or the insert row. The
2466:             * updateXXX() methods do not update the underlying database, instead the
2467:             * updateRow() or insertRow() methods are called to update the database.
2468:             *
2469:             * @param columnIndex
2470:             *            the first column is 1, the second is 2, ...
2471:             * @param x
2472:             *            the new column value
2473:             *
2474:             * @exception SQLException
2475:             *                if a database-access error occurs
2476:             */
2477:            public synchronized void updateShort(int columnIndex, short x)
2478:                    throws SQLException {
2479:                if (!this .onInsertRow) {
2480:                    if (!this .doingUpdates) {
2481:                        this .doingUpdates = true;
2482:                        syncUpdate();
2483:                    }
2484:
2485:                    this .updater.setShort(columnIndex, x);
2486:                } else {
2487:                    this .inserter.setShort(columnIndex, x);
2488:
2489:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2490:                            .getBytesRepresentation(columnIndex - 1));
2491:                }
2492:            }
2493:
2494:            /**
2495:             * JDBC 2.0 Update a column with a short value. The updateXXX() methods are
2496:             * used to update column values in the current row, or the insert row. The
2497:             * updateXXX() methods do not update the underlying database, instead the
2498:             * updateRow() or insertRow() methods are called to update the database.
2499:             *
2500:             * @param columnName
2501:             *            the name of the column
2502:             * @param x
2503:             *            the new column value
2504:             *
2505:             * @exception SQLException
2506:             *                if a database-access error occurs
2507:             */
2508:            public synchronized void updateShort(String columnName, short x)
2509:                    throws SQLException {
2510:                updateShort(findColumn(columnName), x);
2511:            }
2512:
2513:            /**
2514:             * JDBC 2.0 Update a column with a String value. The updateXXX() methods are
2515:             * used to update column values in the current row, or the insert row. The
2516:             * updateXXX() methods do not update the underlying database, instead the
2517:             * updateRow() or insertRow() methods are called to update the database.
2518:             *
2519:             * @param columnIndex
2520:             *            the first column is 1, the second is 2, ...
2521:             * @param x
2522:             *            the new column value
2523:             *
2524:             * @exception SQLException
2525:             *                if a database-access error occurs
2526:             */
2527:            public synchronized void updateString(int columnIndex, String x)
2528:                    throws SQLException {
2529:                checkClosed();
2530:
2531:                if (!this .onInsertRow) {
2532:                    if (!this .doingUpdates) {
2533:                        this .doingUpdates = true;
2534:                        syncUpdate();
2535:                    }
2536:
2537:                    this .updater.setString(columnIndex, x);
2538:                } else {
2539:                    this .inserter.setString(columnIndex, x);
2540:
2541:                    if (x == null) {
2542:                        this .this Row.setColumnValue(columnIndex - 1, null);
2543:                    } else {
2544:                        if (getCharConverter() != null) {
2545:                            this .this Row
2546:                                    .setColumnValue(
2547:                                            columnIndex - 1,
2548:                                            StringUtils
2549:                                                    .getBytes(
2550:                                                            x,
2551:                                                            this .charConverter,
2552:                                                            this .charEncoding,
2553:                                                            this .connection
2554:                                                                    .getServerCharacterEncoding(),
2555:                                                            this .connection
2556:                                                                    .parserKnowsUnicode()));
2557:                        } else {
2558:                            this .this Row.setColumnValue(columnIndex - 1, x
2559:                                    .getBytes());
2560:                        }
2561:                    }
2562:                }
2563:            }
2564:
2565:            /**
2566:             * JDBC 2.0 Update a column with a String value. The updateXXX() methods are
2567:             * used to update column values in the current row, or the insert row. The
2568:             * updateXXX() methods do not update the underlying database, instead the
2569:             * updateRow() or insertRow() methods are called to update the database.
2570:             *
2571:             * @param columnName
2572:             *            the name of the column
2573:             * @param x
2574:             *            the new column value
2575:             *
2576:             * @exception SQLException
2577:             *                if a database-access error occurs
2578:             */
2579:            public synchronized void updateString(String columnName, String x)
2580:                    throws SQLException {
2581:                updateString(findColumn(columnName), x);
2582:            }
2583:
2584:            /**
2585:             * JDBC 2.0 Update a column with a Time value. The updateXXX() methods are
2586:             * used to update column values in the current row, or the insert row. The
2587:             * updateXXX() methods do not update the underlying database, instead the
2588:             * updateRow() or insertRow() methods are called to update the database.
2589:             *
2590:             * @param columnIndex
2591:             *            the first column is 1, the second is 2, ...
2592:             * @param x
2593:             *            the new column value
2594:             *
2595:             * @exception SQLException
2596:             *                if a database-access error occurs
2597:             */
2598:            public synchronized void updateTime(int columnIndex, java.sql.Time x)
2599:                    throws SQLException {
2600:                if (!this .onInsertRow) {
2601:                    if (!this .doingUpdates) {
2602:                        this .doingUpdates = true;
2603:                        syncUpdate();
2604:                    }
2605:
2606:                    this .updater.setTime(columnIndex, x);
2607:                } else {
2608:                    this .inserter.setTime(columnIndex, x);
2609:
2610:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2611:                            .getBytesRepresentation(columnIndex - 1));
2612:                }
2613:            }
2614:
2615:            /**
2616:             * JDBC 2.0 Update a column with a Time value. The updateXXX() methods are
2617:             * used to update column values in the current row, or the insert row. The
2618:             * updateXXX() methods do not update the underlying database, instead the
2619:             * updateRow() or insertRow() methods are called to update the database.
2620:             *
2621:             * @param columnName
2622:             *            the name of the column
2623:             * @param x
2624:             *            the new column value
2625:             *
2626:             * @exception SQLException
2627:             *                if a database-access error occurs
2628:             */
2629:            public synchronized void updateTime(String columnName,
2630:                    java.sql.Time x) throws SQLException {
2631:                updateTime(findColumn(columnName), x);
2632:            }
2633:
2634:            /**
2635:             * JDBC 2.0 Update a column with a Timestamp value. The updateXXX() methods
2636:             * are used to update column values in the current row, or the insert row.
2637:             * The updateXXX() methods do not update the underlying database, instead
2638:             * the updateRow() or insertRow() methods are called to update the database.
2639:             *
2640:             * @param columnIndex
2641:             *            the first column is 1, the second is 2, ...
2642:             * @param x
2643:             *            the new column value
2644:             *
2645:             * @exception SQLException
2646:             *                if a database-access error occurs
2647:             */
2648:            public synchronized void updateTimestamp(int columnIndex,
2649:                    java.sql.Timestamp x) throws SQLException {
2650:                if (!this .onInsertRow) {
2651:                    if (!this .doingUpdates) {
2652:                        this .doingUpdates = true;
2653:                        syncUpdate();
2654:                    }
2655:
2656:                    this .updater.setTimestamp(columnIndex, x);
2657:                } else {
2658:                    this .inserter.setTimestamp(columnIndex, x);
2659:
2660:                    this .this Row.setColumnValue(columnIndex - 1, this .inserter
2661:                            .getBytesRepresentation(columnIndex - 1));
2662:                }
2663:            }
2664:
2665:            /**
2666:             * JDBC 2.0 Update a column with a Timestamp value. The updateXXX() methods
2667:             * are used to update column values in the current row, or the insert row.
2668:             * The updateXXX() methods do not update the underlying database, instead
2669:             * the updateRow() or insertRow() methods are called to update the database.
2670:             *
2671:             * @param columnName
2672:             *            the name of the column
2673:             * @param x
2674:             *            the new column value
2675:             *
2676:             * @exception SQLException
2677:             *                if a database-access error occurs
2678:             */
2679:            public synchronized void updateTimestamp(String columnName,
2680:                    java.sql.Timestamp x) throws SQLException {
2681:                updateTimestamp(findColumn(columnName), x);
2682:            }
2683:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.