KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > jdbc > EmbedResultSet


1 /*
2
3    Derby - Class org.apache.derby.impl.jdbc.EmbedResultSet
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.jdbc;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26 import org.apache.derby.iapi.error.StandardException;
27
28 import org.apache.derby.iapi.jdbc.EngineResultSet;
29 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
30 import org.apache.derby.iapi.sql.conn.StatementContext;
31
32 import org.apache.derby.iapi.sql.ResultSet;
33 import org.apache.derby.iapi.sql.ParameterValueSet;
34 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
35 import org.apache.derby.iapi.sql.execute.ExecCursorTableReference;
36 import org.apache.derby.iapi.sql.execute.ExecRow;
37 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
38 import org.apache.derby.impl.sql.execute.ScrollInsensitiveResultSet;
39
40 import org.apache.derby.iapi.sql.Activation;
41 import org.apache.derby.iapi.sql.execute.CursorActivation;
42
43 import org.apache.derby.iapi.types.DataTypeDescriptor;
44 import org.apache.derby.iapi.types.DataValueDescriptor;
45 import org.apache.derby.iapi.types.RawToBinaryFormatStream;
46 import org.apache.derby.iapi.types.ReaderToUTF8Stream;
47 import org.apache.derby.iapi.types.UserDataValue;
48 import org.apache.derby.iapi.types.VariableSizeDataValue;
49 import org.apache.derby.iapi.sql.ResultDescription;
50 import org.apache.derby.iapi.services.io.StreamStorable;
51
52 import org.apache.derby.iapi.services.io.LimitInputStream;
53 import org.apache.derby.iapi.services.io.NewByteArrayInputStream;
54 import org.apache.derby.iapi.services.io.LimitReader;
55 import org.apache.derby.iapi.error.ExceptionSeverity;
56 import org.apache.derby.iapi.reference.JDBC20Translation;
57 import org.apache.derby.iapi.reference.JDBC30Translation;
58 import org.apache.derby.iapi.reference.SQLState;
59 import org.apache.derby.iapi.util.StringUtil;
60 import org.apache.derby.iapi.util.ReuseFactory;
61
62 /* can't import these due to name overlap:
63 import java.sql.ResultSet;
64 */

65 import java.sql.Blob JavaDoc;
66 import java.sql.Clob JavaDoc;
67 import java.sql.Statement JavaDoc;
68 import java.sql.SQLException JavaDoc;
69 import java.sql.SQLWarning JavaDoc;
70 import java.sql.ResultSetMetaData JavaDoc;
71 import java.sql.Date JavaDoc;
72 import java.sql.Time JavaDoc;
73 import java.sql.Timestamp JavaDoc;
74 import java.sql.Types JavaDoc;
75
76 import java.io.Reader JavaDoc;
77 import java.io.InputStream JavaDoc;
78 import java.io.IOException JavaDoc;
79 import java.net.URL JavaDoc;
80
81 import java.util.Map JavaDoc;
82 import java.util.HashMap JavaDoc;
83 import java.util.Arrays JavaDoc;
84 import java.util.Calendar JavaDoc;
85
86 /**
87  * A EmbedResultSet for results from the EmbedStatement family.
88     <P><B>Supports</B>
89    <UL>
90    <LI> JSR 169
91    </UL>
92  * @author ames
93  */

94
95 public abstract class EmbedResultSet extends ConnectionChild
96     implements EngineResultSet, Comparable JavaDoc {
97
98     // cursor movement
99
protected static final int FIRST = 1;
100     protected static final int NEXT = 2;
101     protected static final int LAST = 3;
102     protected static final int PREVIOUS = 4;
103     protected static final int BEFOREFIRST = 5;
104     protected static final int AFTERLAST = 6;
105     protected static final int ABSOLUTE = 7;
106     protected static final int RELATIVE = 8;
107
108     /**
109      * The currentRow contains the data of the current row of the resultset.
110      * If the containing row array is null, the cursor is not postioned on a
111      * row
112      */

113     private final ExecRow currentRow;
114     protected boolean wasNull;
115     
116     /**
117      * Set if this ResultSet is definitely closed.
118      * If the connection has been closed, or the database
119      * or system shutdown but the ResultSet has not been
120      * closed explictly then this may be false. Once
121      * this object detects the connection is closed
122      * isClosed will be set to true.
123      */

124     boolean isClosed;
125     
126     private boolean isOnInsertRow;
127     private Object JavaDoc currentStream;
128
129     // immutable state
130
private ResultSet theResults;
131     private boolean forMetaData;
132     private ResultSetMetaData JavaDoc rMetaData;
133     private SQLWarning JavaDoc topWarning;
134
135     /**
136      This activation is set by EmbedStatement
137      for a single execution Activation. Ie.
138      a ResultSet from a Statement.executeQuery().
139      In this case the closing of this ResultSet will close
140      the activation or the finalization of the ResultSet
141      without it being closed will mark the Activation as unused.
142      c.f. EmbedPreparedStatement.finalize().
143     */

144     Activation singleUseActivation;
145
146     // Order of creation
147
final int order;
148
149   
150     private final ResultDescription resultDescription;
151     
152     /**
153      * A map which maps a column name to a column number.
154      * Entries only added when accessing columns with the name.
155      */

156     private Map JavaDoc columnNameMap;
157
158     // max rows limit for this result set
159
private int maxRows;
160     // The Maximum field size limt set for this result set
161
private final int maxFieldSize;
162
163     /*
164      * Incase of forward only cursors we limit the number of rows
165      * returned if the maxRows is set. The following varible is used
166      * to keep the count of number of rows returned to the user.
167      */

168     private int NumberofFetchedRows;
169
170
171     /**
172      * The statement object that originally created us.
173         we hang on to the statement to prevent GC from
174         closing it under us
175      */

176     private final EmbedStatement stmt;
177     
178     /**
179      * The statement that currently owns this ResultSet.
180      * Statements created in procedures are passed off
181      * to the Statement that called the procedure.
182      * This is to avoid the ResultSet being closed
183      * due to the Statement within the procedure
184      * or the nested Connection being closed.
185      */

186     private EmbedStatement owningStmt;
187     
188     /**
189      * Statement object the application used to
190      * create this ResultSet.
191      */

192     private Statement JavaDoc applicationStmt;
193     
194     private long timeoutMillis;
195
196     private final boolean isAtomic;
197
198     private final int concurrencyOfThisResultSet;
199
200     /* updateRow is used to keep the values which are updated with updateXXX()
201      * calls. It is used by both insertRow() and updateRow().
202      * It is initialized to null if the resultset is not updatable.
203      */

204     private final ExecRow updateRow;
205     
206     /* These are the columns which have been updated so far.
207      */

208     private boolean[] columnGotUpdated;
209     private boolean currentRowHasBeenUpdated; //Gets set to true after first updateXXX on a row. Gets reset to false when the cursor moves off the row
210

211     private int fetchDirection;
212     private int fetchSize;
213     
214     /**
215      * Indicates which columns have already been fetched
216      * as a stream for a row. Created on-demand by a getXXXStream call.
217      */

218     private boolean[] streamUsedFlags;
219     
220     /**
221      * This class provides the glue between the Cloudscape
222      * resultset and the JDBC resultset, mapping calls-to-calls.
223      */

224     public EmbedResultSet(EmbedConnection conn, ResultSet resultsToWrap,
225         boolean forMetaData, EmbedStatement stmt, boolean isAtomic)
226         throws SQLException JavaDoc {
227
228         super(conn);
229
230         if (SanityManager.DEBUG)
231         SanityManager.ASSERT(resultsToWrap!=null);
232         theResults = resultsToWrap;
233         
234         // ResultSet's for metadata are single use, they are created
235
// with a PreparedStatement internally, but that statement is
236
// never returned to the application.
237
if (this.forMetaData = forMetaData)
238             singleUseActivation = resultsToWrap.getActivation();
239         this.applicationStmt = this.stmt = owningStmt = stmt;
240
241         this.timeoutMillis = stmt == null
242             ? 0L
243             : (long)stmt.getQueryTimeout() * 1000L;
244
245         this.isAtomic = isAtomic;
246                 
247
248         //If the Statement object has CONCUR_READ_ONLY set on it then the concurrency on the ResultSet object will be CONCUR_READ_ONLY also.
249
//But, if the Statement object has CONCUR_UPDATABLE set on it, then the concurrency on the ResultSet object can be
250
//CONCUR_READ_ONLY or CONCUR_UPDATABLE depending on whether the underlying language resultset is updateable or not.
251
//If the underlying language resultset is not updateable, then the concurrency of the ResultSet object will be CONCUR_READ_ONLY
252
//and a warning will be issued on the ResultSet object.
253
if (stmt == null)
254             concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
255         else if (stmt.getResultSetConcurrency() == JDBC20Translation.CONCUR_READ_ONLY)
256             concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
257         else {
258             if (!isForUpdate()) { //language resultset not updatable
259
concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
260                 SQLWarning JavaDoc w = StandardException.newWarning(SQLState.QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET);
261                 addWarning(w);
262             } else
263                     concurrencyOfThisResultSet = JDBC20Translation.CONCUR_UPDATABLE;
264         }
265
266         // Fill in the column types
267
resultDescription = theResults.getResultDescription();
268         final ExecutionFactory factory = conn.getLanguageConnection().
269             getLanguageConnectionFactory().getExecutionFactory();
270         final int columnCount = getMetaData().getColumnCount();
271         this.currentRow = factory.getValueRow(columnCount);
272         this.columnNameMap = null;
273         currentRow.setRowArray(null);
274
275         // Only incur the cost of allocating and maintaining
276
// updated column information if the columns can be updated.
277
if (concurrencyOfThisResultSet == JDBC20Translation.CONCUR_UPDATABLE)
278         {
279             //initialize arrays related to updateRow implementation
280
columnGotUpdated = new boolean[columnCount];
281             updateRow = factory.getValueRow(columnCount);
282             for (int i = 1; i <= columnCount; i++) {
283                 updateRow.setColumn(i, resultDescription.getColumnDescriptor(i).
284                                     getType().getNull());
285             }
286             initializeUpdateRowModifiers();
287         } else {
288             updateRow = null;
289         }
290
291         // assign the max rows and maxfiled size limit for this result set
292
if (stmt != null)
293         {
294            // At connectivity level we handle only for forward only cursor
295
if (stmt.resultSetType == JDBC20Translation.TYPE_FORWARD_ONLY)
296                maxRows = stmt.maxRows;
297
298            maxFieldSize = stmt.MaxFieldSize;
299         }
300         else
301             maxFieldSize = 0;
302
303         order = conn.getResultSetOrderId();
304     }
305
306     /**
307         JDBC states that a ResultSet is closed when garbage collected.
308         We simply mark the activation as unused. Some later use
309         of the connection will clean everything up.
310
311         @exception Throwable Allows any exception to be thrown during finalize
312     */

313     protected void finalize() throws Throwable JavaDoc {
314         super.finalize();
315
316         if (singleUseActivation != null) {
317             singleUseActivation.markUnused();
318         }
319     }
320
321     private void checkNotOnInsertRow() throws SQLException JavaDoc {
322         if (isOnInsertRow) {
323             throw newSQLException(SQLState.NO_CURRENT_ROW);
324         }
325     }
326
327     // checkOnRow protects us from making requests of
328
// resultSet that would fail with NullPointerExceptions
329
// or milder problems due to not having a row.
330
protected final void checkOnRow() throws SQLException JavaDoc
331     {
332         if (currentRow.getRowArray() == null) {
333             throw newSQLException(SQLState.NO_CURRENT_ROW);
334         }
335     }
336
337     /**
338      * Initializes the currentRowHasBeenUpdated and columnGotUpdated fields
339      */

340     private void initializeUpdateRowModifiers() {
341         currentRowHasBeenUpdated = false;
342         Arrays.fill(columnGotUpdated, false);
343     }
344
345     /**
346         Check the column is in range *and* return the JDBC type of the column.
347
348         @exception SQLException ResultSet is not on a row or columnIndex is out of range.
349     */

350     final int getColumnType(int columnIndex) throws SQLException JavaDoc {
351         if (!isOnInsertRow) checkOnRow(); // first make sure there's a row
352

353         if (columnIndex < 1 ||
354             columnIndex > resultDescription.getColumnCount())
355             throw newSQLException(SQLState.COLUMN_NOT_FOUND,
356                          new Integer JavaDoc(columnIndex));
357
358         return resultDescription.getColumnDescriptor(columnIndex).getType().getJDBCTypeId();
359     }
360
361     /*
362      * java.sql.ResultSet interface
363      */

364     /**
365      * A ResultSet is initially positioned before its first row; the
366      * first call to next makes the first row the current row; the
367      * second call makes the second row the current row, etc.
368      *
369      * <P>If an input stream from the previous row is open, it is
370      * implicitly closed. The ResultSet's warning chain is cleared
371      * when a new row is read.
372      *
373      * @return true if the new current row is valid; false if there
374      * are no more rows
375      * @exception SQLException thrown on failure.
376      */

377     public boolean next() throws SQLException JavaDoc
378     {
379         // we seem to have some trigger paths which don't have
380
// statement initialized, may not need this check in those cases
381
if (maxRows !=0 )
382         {
383             NumberofFetchedRows++;
384             // check whether we hit the maxRows limit
385
if (NumberofFetchedRows > maxRows)
386             {
387                 //we return false for the next call when maxRows is hit
388
closeCurrentStream();
389                 return false;
390             }
391         }
392         return movePosition(NEXT, 0, "next");
393     }
394
395     protected boolean movePosition(int position, String JavaDoc positionText)
396         throws SQLException JavaDoc
397     {
398         return movePosition(position, 0, positionText);
399     }
400
401     protected boolean movePosition(int position, int row, String JavaDoc positionText)
402         throws SQLException JavaDoc
403     {
404         closeCurrentStream(); // closing currentStream does not depend on the
405
// underlying connection. Do this outside of
406
// the connection synchronization.
407

408         checkExecIfClosed(positionText); // checking result set closure does not depend
409
// on the underlying connection. Do this
410
// outside of the connection synchronization.
411

412         if (isOnInsertRow) {
413             moveToCurrentRow();
414         }
415
416
417         synchronized (getConnectionSynchronization()) {
418
419                     setupContextStack();
420             try {
421                 LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
422                 final ExecRow newRow;
423             try {
424
425                 /* Push and pop a StatementContext around a next call
426                  * so that the ResultSet will get correctly closed down
427                  * on an error.
428                  * (Cache the LanguageConnectionContext)
429                  */

430                 StatementContext statementContext =
431                     lcc.pushStatementContext(isAtomic,
432                          concurrencyOfThisResultSet==JDBC20Translation.CONCUR_READ_ONLY,
433                          getSQLText(),
434                          getParameterValueSet(),
435                                              false, timeoutMillis);
436
437                 switch (position)
438                 {
439                     case BEFOREFIRST:
440                         newRow = theResults.setBeforeFirstRow();
441                         break;
442
443                     case FIRST:
444                         newRow = theResults.getFirstRow();
445                         break;
446
447                     case NEXT:
448                         newRow = theResults.getNextRow();
449                         break;
450
451                     case LAST:
452                         newRow = theResults.getLastRow();
453                         break;
454
455                     case AFTERLAST:
456                         newRow = theResults.setAfterLastRow();
457                         break;
458
459                     case PREVIOUS:
460                         newRow = theResults.getPreviousRow();
461                         break;
462
463                     case ABSOLUTE:
464                         newRow = theResults.getAbsoluteRow(row);
465                         break;
466
467                     case RELATIVE:
468                         newRow = theResults.getRelativeRow(row);
469                         break;
470
471                     default:
472                         newRow = null;
473                         if (SanityManager.DEBUG)
474                         {
475                             SanityManager.THROWASSERT(
476                                 "Unexpected value for position - " + position);
477                         }
478                 }
479
480                 lcc.popStatementContext(statementContext, null);
481                 
482             } catch (Throwable JavaDoc t) {
483                 /*
484                  * Need to close the result set here because the error might
485                  * cause us to lose the current connection if this is an XA
486                  * connection and we won't be able to do the close later
487                  */

488                 throw closeOnTransactionError(t);
489             }
490          
491             SQLWarning JavaDoc w = theResults.getWarnings();
492             if (w != null) {
493                 if (topWarning == null)
494                     topWarning = w;
495                 else
496                     topWarning.setNextWarning(w);
497             }
498             
499             boolean onRow = (newRow!=null);
500             if (onRow) {
501                 currentRow.setRowArray(newRow.getRowArray());
502             } else {
503                 currentRow.setRowArray(null);
504             }
505             
506
507             //if (onRow && !(currentRow instanceof org.apache.derby.impl.sql.execute.ValueRow))
508
// System.out.println(currentRow.getClass());
509

510             // The ResultSet may implicitly close when when the ResultSet type
511
// is TYPE_FORWARD_ONLY and the next method of ResultSet returns
512
// false. This will cause a commit if autocommit = true.
513
if (!onRow && (position == NEXT)) {
514
515              // In case of resultset for MetaData, we will only commit
516
// if we are the only statement currently opened for this
517
// connection; otherwise we don't want to affect other
518
// resultSet's by committing the MetaData one.
519
// There is no internal xact (xact isolation) for MetaData type
520
// of resultSet; therefore committing (to release locks) would end
521
// up committing all the other resultSet for this connection.
522
//
523
// We do synchronize on the connection, therefore Activation count
524
// should be valid and protected.
525
//
526
//LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
527
if (forMetaData && (lcc.getActivationCount() > 1)) {
528                 // we do not want to commit here as there seems to be other
529
// statements/resultSets currently opened for this connection.
530
} else if (owningStmt != null &&
531                     owningStmt.getResultSetType() == TYPE_FORWARD_ONLY) {
532                  // allow the satement to commit if required.
533
owningStmt.resultSetClosing(this);
534              }
535             }
536
537             // Clear the indication of which columns were fetched as streams.
538
if (streamUsedFlags != null)
539                 Arrays.fill(streamUsedFlags, false);
540             if (columnGotUpdated != null && currentRowHasBeenUpdated) {
541                 initializeUpdateRowModifiers();
542             }
543             
544             return onRow;
545             } finally {
546                 restoreContextStack();
547             }
548         }
549
550     }
551
552
553
554
555     /**
556      * In some cases, it is desirable to immediately release a
557      * ResultSet's database and JDBC resources instead of waiting for
558      * this to happen when it is automatically closed; the close
559      * method provides this immediate release.
560      *
561      * <P><B>Note:</B> A ResultSet is automatically closed by the
562      * Statement that generated it when that Statement is closed,
563      * re-executed, or is used to retrieve the next result from a
564      * sequence of multiple results. A ResultSet is also automatically
565      * closed when it is garbage collected.
566      * @exception SQLException thrown on failure.
567      */

568     public void close() throws SQLException JavaDoc {
569
570         /* if this result is already closed, don't try to close again
571          * we may have closed it earlier because of an error and trying
572          * to close again will cause a different problem if the connection
573          * has been closed as in XA error handling
574          */

575         if (isClosed)
576             return;
577
578         closeCurrentStream(); // closing currentStream does not depend on the
579
// underlying connection. Do this outside of
580
// the connection synchronization.
581
// Would like to throw an exception if already closed, but
582
// some code assumes you can close a ResultSet more than once.
583
// checkIfClosed("close");
584

585         // synchronize out here so the close and the autocommit are
586
// both in the same sync block.
587
synchronized (getConnectionSynchronization()) {
588
589             try {
590                 setupContextStack(); // make sure there's context
591
} catch (SQLException JavaDoc se) {
592                 // we may get an exception here if this is part of an XA transaction
593
// and the transaction has been committed
594
// just give up and return
595
return;
596             }
597
598             try {
599                 try {
600                     theResults.finish(); // release the result set, don't just close it
601

602                     if (this.singleUseActivation != null)
603                     {
604                         this.singleUseActivation.close();
605                         this.singleUseActivation = null;
606                     }
607                     
608                 } catch (Throwable JavaDoc t) {
609                     throw handleException(t);
610                 }
611
612                 // In case of resultset for MetaData, we will only commit
613
// if we are the only statement currently opened for this
614
// connection; otherwise we don't want to affect other
615
// resultSet's by committing the MetaData one.
616
// There is no internal xact (xact isolation) for MetaData type
617
// of resultSet; therefore committing (to release locks) would end
618
// up committing all the other resultSet for this connection.
619
//
620
// We do synchronize on the connection, therefore Activation count
621
// should be valid and protected.
622
//
623
if (forMetaData) {
624
625                     LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
626                     if (lcc.getActivationCount() > 1) {
627                       // we do not want to commit here as there seems to be other
628
// statements/resultSets currently opened for this connection.
629
} else if (owningStmt != null)
630                         // allow the satement to commit if required.
631
owningStmt.resultSetClosing(this);
632         
633                 } else if (owningStmt != null) {
634                         // allow the satement to commit if required.
635
owningStmt.resultSetClosing(this);
636                 }
637
638             } finally {
639                 isClosed = true;
640                 restoreContextStack();
641             }
642
643             // the idea is to release resources, so:
644
currentRow.setRowArray(null);
645             rMetaData = null; // let it go, we can make a new one
646

647             // we hang on to theResults and messenger
648
// in case more calls come in on this resultSet
649
}
650
651     }
652
653     /**
654      * A column may have the value of SQL NULL; wasNull reports whether
655      * the last column read had this special value.
656      * Note that you must first call getXXX on a column to try to read
657      * its value and then call wasNull() to find if the value was
658      * the SQL NULL.
659      *
660      * <p> we take the least exception approach and simply return false
661      * if no column has been read yet.
662      *
663      * @return true if last column read was SQL NULL
664      *
665      * @exception SQLException Thrown if this ResultSet is closed
666      */

667     public final boolean wasNull() throws SQLException JavaDoc {
668         checkIfClosed("wasNull");
669         return wasNull;
670     }
671
672     //======================================================================
673
// Methods for accessing results by column index
674
//======================================================================
675

676     /**
677      * Get the value of a column in the current row as a Java String.
678      *
679      * @param columnIndex the first column is 1, the second is 2, ...
680      * @return the column value; if the value is SQL NULL, the result is null
681      * @exception SQLException thrown on failure.
682      */

683     public final String JavaDoc getString(int columnIndex) throws SQLException JavaDoc {
684         checkIfClosed("getString");
685
686             try {
687
688                 DataValueDescriptor dvd = getColumn(columnIndex);
689
690                 if (wasNull = dvd.isNull())
691                     return null;
692
693                 String JavaDoc value = dvd.getString();
694
695                 // check for the max field size limit
696
if (maxFieldSize > 0 && isMaxFieldSizeType(getColumnType(columnIndex)))
697                 {
698                     if (value.length() > maxFieldSize )
699                     {
700                         value = value.substring(0, maxFieldSize);
701                     }
702                 }
703      
704                 return value;
705
706             } catch (Throwable JavaDoc t) {
707                 throw noStateChangeException(t);
708             }
709     }
710
711     /**
712      * Get the value of a column in the current row as a Java boolean.
713      *
714      * @param columnIndex the first column is 1, the second is 2, ...
715      * @return the column value; if the value is SQL NULL, the result is false
716      * @exception SQLException thrown on failure.
717      */

718     public final boolean getBoolean(int columnIndex) throws SQLException JavaDoc {
719         checkIfClosed("getBoolean");
720
721         try {
722
723             DataValueDescriptor dvd = getColumn(columnIndex);
724
725             if (wasNull = dvd.isNull())
726                 return false;
727
728             return dvd.getBoolean();
729
730         } catch (StandardException t) {
731             throw noStateChangeException(t);
732         }
733     }
734
735     /**
736      * Get the value of a column in the current row as a Java byte.
737      *
738      * @param columnIndex the first column is 1, the second is 2, ...
739      * @return the column value; if the value is SQL NULL, the result is 0
740      * @exception SQLException thrown on failure.
741      */

742     public final byte getByte(int columnIndex) throws SQLException JavaDoc {
743         checkIfClosed("getByte");
744         try {
745
746             DataValueDescriptor dvd = getColumn(columnIndex);
747
748             if (wasNull = dvd.isNull())
749                 return 0;
750
751             return dvd.getByte();
752
753         } catch (StandardException t) {
754             throw noStateChangeException(t);
755         }
756     }
757
758     /**
759      * Get the value of a column in the current row as a Java short.
760      *
761      * @param columnIndex the first column is 1, the second is 2, ...
762      * @return the column value; if the value is SQL NULL, the result is 0
763      * @exception SQLException thrown on failure.
764      */

765     public final short getShort(int columnIndex) throws SQLException JavaDoc {
766         checkIfClosed("getShort");
767
768         try {
769
770             DataValueDescriptor dvd = getColumn(columnIndex);
771
772             if (wasNull = dvd.isNull())
773                 return 0;
774
775             return dvd.getShort();
776
777         } catch (StandardException t) {
778             throw noStateChangeException(t);
779         }
780     }
781
782     /**
783      * Get the value of a column in the current row as a Java int.
784      *
785      * @param columnIndex the first column is 1, the second is 2, ...
786      * @return the column value; if the value is SQL NULL, the result is 0
787      * @exception SQLException thrown on failure.
788      */

789     public final int getInt(int columnIndex) throws SQLException JavaDoc {
790         checkIfClosed("getInt");
791         try {
792
793             DataValueDescriptor dvd = getColumn(columnIndex);
794
795             if (wasNull = dvd.isNull())
796                 return 0;
797
798             return dvd.getInt();
799
800         } catch (StandardException t) {
801             throw noStateChangeException(t);
802         }
803     }
804
805     /**
806      * Get the value of a column in the current row as a Java long.
807      *
808      * @param columnIndex the first column is 1, the second is 2, ...
809      * @return the column value; if the value is SQL NULL, the result is 0
810      * @exception SQLException thrown on failure.
811      */

812     public final long getLong(int columnIndex) throws SQLException JavaDoc {
813         checkIfClosed("getLong");
814         try {
815
816             DataValueDescriptor dvd = getColumn(columnIndex);
817
818             if (wasNull = dvd.isNull())
819                 return 0;
820
821             return dvd.getLong();
822
823         } catch (StandardException t) {
824             throw noStateChangeException(t);
825         }
826     }
827
828     /**
829      * Get the value of a column in the current row as a Java float.
830      *
831      * @param columnIndex the first column is 1, the second is 2, ...
832      * @return the column value; if the value is SQL NULL, the result is 0
833      * @exception SQLException thrown on failure.
834      */

835     public final float getFloat(int columnIndex) throws SQLException JavaDoc {
836         checkIfClosed("getFloat");
837         try {
838
839             DataValueDescriptor dvd = getColumn(columnIndex);
840
841             if (wasNull = dvd.isNull())
842                 return 0.0F;
843
844             return dvd.getFloat();
845
846         } catch (StandardException t) {
847             throw noStateChangeException(t);
848         }
849     }
850
851     /**
852      * Get the value of a column in the current row as a Java double.
853      *
854      * @param columnIndex the first column is 1, the second is 2, ...
855      * @return the column value; if the value is SQL NULL, the result is 0
856      * @exception SQLException thrown on failure.
857      */

858     public final double getDouble(int columnIndex) throws SQLException JavaDoc {
859         checkIfClosed("getDouble");
860         try {
861
862             DataValueDescriptor dvd = getColumn(columnIndex);
863
864             if (wasNull = dvd.isNull())
865                 return 0.0;
866
867             return dvd.getDouble();
868
869         } catch (StandardException t) {
870             throw noStateChangeException(t);
871         }
872     }
873
874     /**
875      * Get the value of a column in the current row as a Java byte array.
876      * The bytes represent the raw values returned by the driver.
877      *
878      * @param columnIndex the first column is 1, the second is 2, ...
879      * @return the column value; if the value is SQL NULL, the result is null
880      * @exception SQLException thrown on failure.
881      */

882     public final byte[] getBytes(int columnIndex) throws SQLException JavaDoc {
883         checkIfClosed("getBytes");
884         try {
885
886             DataValueDescriptor dvd = getColumn(columnIndex);
887
888             if (wasNull = dvd.isNull())
889                 return null;
890
891             byte[] value = dvd.getBytes();
892
893             // check for the max field size limit
894
if (maxFieldSize > 0 && isMaxFieldSizeType(getColumnType(columnIndex)))
895             {
896                  if (value.length > maxFieldSize)
897                  {
898                      byte [] limited_value = new byte[maxFieldSize];
899                      System.arraycopy(value, 0, limited_value,
900                                                    0 , maxFieldSize);
901                      value = limited_value;
902                  }
903              }
904             
905             return value;
906
907         } catch (StandardException t) {
908             throw noStateChangeException(t);
909         }
910     }
911
912     /**
913      * Get the value of a column in the current row as a java.sql.Date object.
914      *
915      * @param columnIndex the first column is 1, the second is 2, ...
916      * @return the column value; if the value is SQL NULL, the result is null
917      * @exception SQLException thrown on failure.
918      */

919     public final Date JavaDoc getDate(int columnIndex) throws SQLException JavaDoc {
920         return getDate( columnIndex, (Calendar JavaDoc) null);
921     }
922
923     /**
924      * Get the value of a column in the current row as a java.sql.Time object.
925      *
926      * @param columnIndex the first column is 1, the second is 2, ...
927      * @return the column value; if the value is SQL NULL, the result is null
928      * @exception SQLException thrown on failure.
929      */

930     public final Time JavaDoc getTime(int columnIndex) throws SQLException JavaDoc {
931         return getTime( columnIndex, (Calendar JavaDoc) null);
932     }
933
934     /**
935      * Get the value of a column in the current row as a java.sql.Timestamp object.
936      *
937      * @param columnIndex the first column is 1, the second is 2, ...
938      * @return the column value; if the value is SQL NULL, the result is null
939      * @exception SQLException thrown on failure.
940      */

941     public final Timestamp JavaDoc getTimestamp(int columnIndex) throws SQLException JavaDoc {
942         return getTimestamp( columnIndex, (Calendar JavaDoc) null);
943     }
944
945     /**
946      * JDBC 2.0
947      *
948      * Get the value of a column in the current row as a java.sql.Date
949      * object. Use the calendar to construct an appropriate millisecond
950      * value for the Date, if the underlying database doesn't store
951      * timezone information.
952      *
953      * @param columnIndex the first column is 1, the second is 2, ...
954      * @param cal the calendar to use in constructing the date
955      * @return the column value; if the value is SQL NULL, the result is null
956      * @exception SQLException if a database-access error occurs.
957      */

958     public java.sql.Date JavaDoc getDate(int columnIndex, Calendar JavaDoc cal)
959         throws SQLException JavaDoc
960     {
961         checkIfClosed("getDate");
962         try {
963
964             DataValueDescriptor dvd = getColumn(columnIndex);
965
966             if (wasNull = dvd.isNull())
967                 return null;
968
969             if( cal == null)
970                 cal = getCal();
971             
972             return dvd.getDate( cal);
973
974         } catch (StandardException t) {
975             throw noStateChangeException(t);
976         }
977     }
978
979     /**
980      * JDBC 2.0
981      *
982      * Get the value of a column in the current row as a java.sql.Date
983      * object. Use the calendar to construct an appropriate millisecond
984      * value for the Date, if the underlying database doesn't store
985      * timezone information.
986      *
987      * @param columnName is the SQL name of the column
988      * @param cal the calendar to use in constructing the date
989      * @return the column value; if the value is SQL NULL, the result is null
990      * @exception SQLException if a database-access error occurs.
991      */

992     public java.sql.Date JavaDoc getDate(String JavaDoc columnName, Calendar JavaDoc cal)
993                 throws SQLException JavaDoc
994         {
995                 checkIfClosed("getDate");
996                 return getDate( findColumnName(columnName), cal);
997         }
998
999     /**
1000     * JDBC 2.0
1001     *
1002     * Get the value of a column in the current row as a java.sql.Time
1003     * object. Use the calendar to construct an appropriate millisecond
1004     * value for the Time, if the underlying database doesn't store
1005     * timezone information.
1006     *
1007     * @param columnIndex the first column is 1, the second is 2, ...
1008     * @param cal the calendar to use in constructing the time
1009     * @return the column value; if the value is SQL NULL, the result is null
1010     * @exception SQLException if a database-access error occurs.
1011     */

1012    public java.sql.Time JavaDoc getTime(int columnIndex, Calendar JavaDoc cal)
1013        throws SQLException JavaDoc
1014    {
1015        checkIfClosed("getTime");
1016        try {
1017
1018            DataValueDescriptor dvd = getColumn(columnIndex);
1019
1020            if (wasNull = dvd.isNull())
1021                return null;
1022
1023            if( cal == null)
1024                cal = getCal();
1025            return dvd.getTime( cal);
1026
1027        } catch (StandardException t) {
1028            throw noStateChangeException(t);
1029        }
1030    }
1031
1032    /**
1033     * JDBC 2.0
1034     *
1035     * Get the value of a column in the current row as a java.sql.Time
1036     * object. Use the calendar to construct an appropriate millisecond
1037     * value for the Time, if the underlying database doesn't store
1038     * timezone information.
1039     *
1040     * @param columnName is the SQL name of the column
1041     * @param cal the calendar to use in constructing the time
1042     * @return the column value; if the value is SQL NULL, the result is null
1043     * @exception SQLException if a database-access error occurs.
1044     */

1045    public java.sql.Time JavaDoc getTime(String JavaDoc columnName, Calendar JavaDoc cal)
1046           throws SQLException JavaDoc
1047        {
1048                checkIfClosed("getTime");
1049                return getTime( findColumnName( columnName), cal);
1050        }
1051
1052    /**
1053     * JDBC 2.0
1054     *
1055     * Get the value of a column in the current row as a java.sql.Timestamp
1056     * object. Use the calendar to construct an appropriate millisecond
1057     * value for the Timestamp, if the underlying database doesn't store
1058     * timezone information.
1059     *
1060     * @param columnName is the SQL name of the column
1061     * @param cal the calendar to use in constructing the timestamp
1062     * @return the column value; if the value is SQL NULL, the result is null
1063     * @exception SQLException if a database-access error occurs.
1064     */

1065    public java.sql.Timestamp JavaDoc getTimestamp(String JavaDoc columnName, Calendar JavaDoc cal)
1066      throws SQLException JavaDoc
1067        {
1068                checkIfClosed("getTimestamp");
1069                return getTimestamp(findColumnName(columnName), cal);
1070        }
1071
1072    /**
1073     * JDBC 2.0
1074     *
1075     * Get the value of a column in the current row as a java.sql.Timestamp
1076     * object. Use the calendar to construct an appropriate millisecond
1077     * value for the Timestamp, if the underlying database doesn't store
1078     * timezone information.
1079     *
1080     * @param columnIndex the first column is 1, the second is 2, ...
1081     * @param cal the calendar to use in constructing the timestamp
1082     * @return the column value; if the value is SQL NULL, the result is null
1083     * @exception SQLException if a database-access error occurs.
1084     */

1085    public java.sql.Timestamp JavaDoc getTimestamp(int columnIndex, Calendar JavaDoc cal)
1086        throws SQLException JavaDoc
1087    {
1088        checkIfClosed("getTimestamp");
1089        try {
1090
1091            DataValueDescriptor dvd = getColumn(columnIndex);
1092
1093            if (wasNull = dvd.isNull())
1094                return null;
1095
1096            if( cal == null)
1097                cal = getCal();
1098            return dvd.getTimestamp( cal);
1099
1100        } catch (StandardException t) {
1101            throw noStateChangeException(t);
1102        }
1103    }
1104
1105    /**
1106     * JDBC 2.0
1107     *
1108     * <p>Get the value of a column in the current row as a java.io.Reader.
1109     *
1110     * @exception SQLException database error.
1111     */

1112    public final java.io.Reader JavaDoc getCharacterStream(int columnIndex)
1113        throws SQLException JavaDoc
1114    {
1115        checkIfClosed("getCharacterStream");
1116        int lmfs;
1117        int colType = getColumnType(columnIndex);
1118        switch (colType) {
1119        case Types.CHAR:
1120        case Types.VARCHAR:
1121        case Types.LONGVARCHAR:
1122            lmfs = maxFieldSize;
1123            break;
1124        case Types.CLOB: // Embedded and JCC extension - CLOB is not subject to max field size.
1125
lmfs = 0;
1126            break;
1127
1128        // JDBC says to support these, but no defintion exists for the output.
1129
// match JCC which treats the bytes as a UTF16-BE stream
1130
case Types.BINARY:
1131        case Types.VARBINARY:
1132        case Types.LONGVARBINARY:
1133        case Types.BLOB:
1134            try {
1135                java.io.InputStream JavaDoc is = getBinaryStream(columnIndex);
1136                if (is == null)
1137                    return null;
1138                java.io.Reader JavaDoc r = new java.io.InputStreamReader JavaDoc(is, "UTF-16BE");
1139                currentStream = r;
1140                return r;
1141            } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
1142                throw new SQLException JavaDoc(uee.getMessage());
1143            }
1144        default:
1145            throw dataTypeConversion("java.io.Reader", columnIndex);
1146        }
1147
1148        Object JavaDoc syncLock = getConnectionSynchronization();
1149
1150        synchronized (syncLock) {
1151
1152        boolean pushStack = false;
1153        try {
1154
1155            useStream(columnIndex);
1156
1157            DataValueDescriptor dvd = getColumn(columnIndex);
1158
1159            if (wasNull = dvd.isNull()) { return null; }
1160
1161            pushStack = true;
1162            setupContextStack();
1163
1164            StreamStorable ss = (StreamStorable) dvd;
1165
1166            InputStream stream = ss.returnStream();
1167
1168            if (stream == null) {
1169
1170                String JavaDoc val = dvd.getString();
1171                if (lmfs > 0) {
1172                    if (val.length() > lmfs)
1173                        val = val.substring(0, lmfs);
1174                }
1175                java.io.Reader JavaDoc ret = new java.io.StringReader JavaDoc(val);
1176                currentStream = ret;
1177                return ret;
1178            }
1179
1180            java.io.Reader JavaDoc ret = new UTF8Reader(stream, lmfs, this, syncLock);
1181            currentStream = ret;
1182            return ret;
1183
1184        } catch (Throwable JavaDoc t) {
1185            throw noStateChangeException(t);
1186        } finally {
1187            if (pushStack) { restoreContextStack(); }
1188        }
1189      }
1190     }
1191
1192    /**
1193        Pushes a converter on top of getCharacterStream().
1194     *
1195     * @param columnIndex the first column is 1, the second is 2, ...
1196     * @return a Java input stream that delivers the database column value
1197     * as a stream of one byte ASCII characters. If the value is SQL NULL
1198     * then the result is null.
1199     * @exception SQLException thrown on failure.
1200     */

1201    public final InputStream getAsciiStream(int columnIndex) throws SQLException JavaDoc {
1202        checkIfClosed("getAsciiStream");
1203        int colType = getColumnType(columnIndex);
1204        switch (colType) {
1205        case Types.CHAR:
1206        case Types.VARCHAR:
1207        case Types.LONGVARCHAR:
1208        case Types.CLOB: // Embedded and JCC extension
1209
break;
1210
1211        // JDBC says to support these, we match JCC by returning the raw bytes.
1212
case Types.BINARY:
1213        case Types.VARBINARY:
1214        case Types.LONGVARBINARY:
1215        case Types.BLOB:
1216            return getBinaryStream(columnIndex);
1217
1218        default:
1219            throw dataTypeConversion("java.io.InputStream(ASCII)", columnIndex);
1220        }
1221
1222        java.io.Reader JavaDoc reader = getCharacterStream(columnIndex);
1223        if (reader == null)
1224            return null;
1225
1226        return new ReaderToAscii(reader);
1227    }
1228
1229    /**
1230     * Get the column as an InputStream. If the column is already of type
1231       InputStream then just return it, otherwise convert the column to a set
1232       of bytes and create a stream out of the bytes.
1233     *
1234     * @param columnIndex the first column is 1, the second is 2, ...
1235     * @return a Java input stream that delivers the database column value
1236     * as a stream of uninterpreted bytes. If the value is SQL NULL
1237     * then the result is null.
1238     * @exception SQLException thrown on failure.
1239     */

1240    public final InputStream getBinaryStream(int columnIndex) throws SQLException JavaDoc {
1241        checkIfClosed("getBinaryStream");
1242        int lmfs;
1243        int colType = getColumnType(columnIndex);
1244        switch (colType) {
1245        case Types.BINARY:
1246        case Types.VARBINARY:
1247        case Types.LONGVARBINARY:
1248            lmfs = maxFieldSize;
1249            break;
1250        case Types.BLOB:
1251            lmfs = 0;
1252            break;
1253
1254        default:
1255            throw dataTypeConversion("java.io.InputStream", columnIndex);
1256        }
1257
1258        Object JavaDoc syncLock = getConnectionSynchronization();
1259
1260        synchronized (syncLock) {
1261
1262        boolean pushStack = false;
1263        try {
1264            
1265            useStream(columnIndex);
1266
1267            DataValueDescriptor dvd = getColumn(columnIndex);
1268
1269            if (wasNull = dvd.isNull()) { return null; }
1270
1271            pushStack = true;
1272            setupContextStack();
1273
1274            StreamStorable ss = (StreamStorable) dvd;
1275
1276            InputStream stream = ss.returnStream();
1277
1278            if (stream == null)
1279            {
1280                stream = new NewByteArrayInputStream(dvd.getBytes());
1281            } else
1282            {
1283                stream = new BinaryToRawStream(stream, dvd);
1284            }
1285
1286            if (lmfs > 0)
1287            {
1288                // Just wrap the InputStream with a LimitInputStream class
1289
LimitInputStream limitResultIn = new LimitInputStream(stream);
1290                limitResultIn.setLimit(lmfs);
1291                stream = limitResultIn;
1292            }
1293            currentStream = stream;
1294            return stream;
1295
1296        } catch (Throwable JavaDoc t) {
1297            throw noStateChangeException(t);
1298        } finally {
1299            if (pushStack) { restoreContextStack(); }
1300        }
1301      }
1302    }
1303
1304    //======================================================================
1305
// Methods for accessing results by column name
1306
//======================================================================
1307

1308
1309    /**
1310     * Get the value of a column in the current row as a Java String.
1311     *
1312     * @param columnName is the SQL name of the column
1313     * @return the column value; if the value is SQL NULL, the result is null
1314     * @exception SQLException thrown on failure.
1315     */

1316    public final String JavaDoc getString(String JavaDoc columnName) throws SQLException JavaDoc {
1317        checkIfClosed("getString");
1318        return (getString(findColumnName(columnName)));
1319    }
1320
1321    /**
1322     * Get the value of a column in the current row as a Java boolean.
1323     *
1324     * @param columnName is the SQL name of the column
1325     * @return the column value; if the value is SQL NULL, the result is false
1326     * @exception SQLException thrown on failure.
1327     */

1328    public final boolean getBoolean(String JavaDoc columnName) throws SQLException JavaDoc {
1329        checkIfClosed("getBoolean");
1330        return (getBoolean(findColumnName(columnName)));
1331    }
1332
1333    /**
1334     * Get the value of a column in the current row as a Java byte.
1335     *
1336     * @param columnName is the SQL name of the column
1337     * @return the column value; if the value is SQL NULL, the result is 0
1338     * @exception SQLException thrown on failure.
1339     */

1340    public final byte getByte(String JavaDoc columnName) throws SQLException JavaDoc {
1341        checkIfClosed("getByte");
1342        return (getByte(findColumnName(columnName)));
1343    }
1344
1345    /**
1346     * Get the value of a column in the current row as a Java short.
1347     *
1348     * @param columnName is the SQL name of the column
1349     * @return the column value; if the value is SQL NULL, the result is 0
1350     * @exception SQLException thrown on failure.
1351     */

1352    public final short getShort(String JavaDoc columnName) throws SQLException JavaDoc {
1353        checkIfClosed("getShort");
1354        return (getShort(findColumnName(columnName)));
1355    }
1356
1357    /**
1358     * Get the value of a column in the current row as a Java int.
1359     *
1360     * @param columnName is the SQL name of the column
1361     * @return the column value; if the value is SQL NULL, the result is 0
1362     * @exception SQLException thrown on failure.
1363     */

1364    public final int getInt(String JavaDoc columnName) throws SQLException JavaDoc {
1365        checkIfClosed("getInt");
1366        return (getInt(findColumnName(columnName)));
1367    }
1368
1369    /**
1370     * Get the value of a column in the current row as a Java long.
1371     *
1372     * @param columnName is the SQL name of the column
1373     * @return the column value; if the value is SQL NULL, the result is 0
1374     * @exception SQLException thrown on failure.
1375     */

1376    public final long getLong(String JavaDoc columnName) throws SQLException JavaDoc {
1377        checkIfClosed("getLong");
1378        return (getLong(findColumnName(columnName)));
1379    }
1380
1381    /**
1382     * Get the value of a column in the current row as a Java float.
1383     *
1384     * @param columnName is the SQL name of the column
1385     * @return the column value; if the value is SQL NULL, the result is 0
1386     * @exception SQLException thrown on failure.
1387     */

1388    public final float getFloat(String JavaDoc columnName) throws SQLException JavaDoc {
1389        checkIfClosed("getFloat");
1390        return (getFloat(findColumnName(columnName)));
1391    }
1392
1393    /**
1394     * Get the value of a column in the current row as a Java double.
1395     *
1396     * @param columnName is the SQL name of the column
1397     * @return the column value; if the value is SQL NULL, the result is 0
1398     * @exception SQLException thrown on failure.
1399     */

1400    public final double getDouble(String JavaDoc columnName) throws SQLException JavaDoc {
1401        checkIfClosed("getDouble");
1402        return (getDouble(findColumnName(columnName)));
1403    }
1404
1405    /**
1406     * Get the value of a column in the current row as a Java byte array.
1407     * The bytes represent the raw values returned by the driver.
1408     *
1409     * @param columnName is the SQL name of the column
1410     * @return the column value; if the value is SQL NULL, the result is null
1411     * @exception SQLException thrown on failure.
1412     */

1413    public final byte[] getBytes(String JavaDoc columnName) throws SQLException JavaDoc {
1414        checkIfClosed("getBytes");
1415        return (getBytes(findColumnName(columnName)));
1416    }
1417
1418    /**
1419     * Get the value of a column in the current row as a java.sql.Date object.
1420     *
1421     * @param columnName is the SQL name of the column
1422     * @return the column value; if the value is SQL NULL, the result is null
1423     * @exception SQLException thrown on failure.
1424     */

1425    public final Date JavaDoc getDate(String JavaDoc columnName) throws SQLException JavaDoc {
1426        checkIfClosed("getDate");
1427        return (getDate(findColumnName(columnName)));
1428    }
1429
1430    /**
1431     * Get the value of a column in the current row as a java.sql.Time object.
1432     *
1433     * @param columnName is the SQL name of the column
1434     * @return the column value; if the value is SQL NULL, the result is null
1435     * @exception SQLException thrown on failure.
1436     */

1437    public final Time JavaDoc getTime(String JavaDoc columnName) throws SQLException JavaDoc {
1438        checkIfClosed("getTime");
1439        return (getTime(findColumnName(columnName)));
1440    }
1441
1442    /**
1443     * Get the value of a column in the current row as a java.sql.Timestamp object.
1444     *
1445     * @param columnName is the SQL name of the column
1446     * @return the column value; if the value is SQL NULL, the result is null
1447     * @exception SQLException thrown on failure.
1448     */

1449    public final Timestamp JavaDoc getTimestamp(String JavaDoc columnName) throws SQLException JavaDoc {
1450        checkIfClosed("getTimestamp");
1451        return (getTimestamp(findColumnName(columnName)));
1452    }
1453
1454    /**
1455     * JDBC 2.0
1456     *
1457     * <p>Get the value of a column in the current row as a java.io.Reader.
1458         *
1459         * @exception SQLException Feature not implemented for now.
1460     */

1461    public final java.io.Reader JavaDoc getCharacterStream(String JavaDoc columnName)
1462    throws SQLException JavaDoc {
1463        checkIfClosed("getCharacterStream");
1464        return (getCharacterStream(findColumnName(columnName)));
1465    }
1466
1467    /**
1468     * A column value can be retrieved as a stream of ASCII characters
1469     * and then read in chunks from the stream. This method is particularly
1470     * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
1471     * do any necessary conversion from the database format into ASCII.
1472     *
1473     * <P><B>Note:</B> All the data in the returned stream must
1474     * be read prior to getting the value of any other column. The
1475     * next call to a get method implicitly closes the stream.
1476     *
1477     * @param columnName is the SQL name of the column
1478     * @return a Java input stream that delivers the database column value
1479     * as a stream of one byte ASCII characters. If the value is SQL NULL
1480     * then the result is null.
1481     * @exception SQLException thrown on failure.
1482     */

1483    public final InputStream getAsciiStream(String JavaDoc columnName) throws SQLException JavaDoc {
1484        checkIfClosed("getAsciiStream");
1485        return (getAsciiStream(findColumnName(columnName)));
1486    }
1487
1488    /**
1489     * A column value can be retrieved as a stream of uninterpreted bytes
1490     * and then read in chunks from the stream. This method is particularly
1491     * suitable for retrieving large LONGVARBINARY values.
1492     *
1493     * <P><B>Note:</B> All the data in the returned stream must
1494     * be read prior to getting the value of any other column. The
1495     * next call to a get method implicitly closes the stream.
1496     *
1497     * @param columnName is the SQL name of the column
1498     * @return a Java input stream that delivers the database column value
1499     * as a stream of uninterpreted bytes. If the value is SQL NULL
1500     * then the result is null.
1501     * @exception SQLException thrown on failure.
1502     */

1503    public final InputStream getBinaryStream(String JavaDoc columnName) throws SQLException JavaDoc {
1504        checkIfClosed("getBinaryStream");
1505        return (getBinaryStream(findColumnName(columnName)));
1506    }
1507
1508    /**
1509     * JDBC 3.0
1510     *
1511     * Retrieves the value of the designated column in the current row of this
1512     * ResultSet object as a java.net.URL object in the Java programming
1513     * language.
1514     *
1515     * @param columnIndex -
1516     * the first column is 1, the second is 2
1517     * @return the column value as a java.net.URL object, if the value is SQL
1518     * NULL, the value returned is null in the Java programming language
1519     * @exception SQLException
1520     * Feature not implemented for now.
1521     */

1522    public URL JavaDoc getURL(int columnIndex) throws SQLException JavaDoc {
1523        throw Util.notImplemented();
1524    }
1525
1526    /**
1527     * JDBC 3.0
1528     *
1529     * Retrieves the value of the designated column in the current row of this
1530     * ResultSet object as a java.net.URL object in the Java programming
1531     * language.
1532     *
1533     * @param columnName -
1534     * the SQL name of the column
1535     * @return the column value as a java.net.URL object, if the value is SQL
1536     * NULL, the value returned is null in the Java programming language
1537     * @exception SQLException
1538     * Feature not implemented for now.
1539     */

1540    public URL JavaDoc getURL(String JavaDoc columnName) throws SQLException JavaDoc {
1541        throw Util.notImplemented();
1542    }
1543 
1544    //=====================================================================
1545
// Advanced features:
1546
//=====================================================================
1547

1548    /**
1549     * <p>The first warning reported by calls on this ResultSet is
1550     * returned. Subsequent ResultSet warnings will be chained to this
1551     * SQLWarning.
1552     *
1553     * <P>The warning chain is automatically cleared each time a new
1554     * row is read.
1555     *
1556     * <P><B>Note:</B> This warning chain only covers warnings caused
1557     * by ResultSet methods. Any warning caused by statement methods
1558     * (such as reading OUT parameters) will be chained on the
1559     * Statement object.
1560     *
1561     * @return the first SQLWarning or null
1562     *
1563     * @exception SQLException Thrown if this ResultSet is closed
1564     */

1565    public final SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc {
1566        checkIfClosed("getWarnings");
1567        return topWarning;
1568    }
1569
1570    /**
1571     * After this call getWarnings returns null until a new warning is
1572     * reported for this ResultSet.
1573     *
1574     * @exception SQLException Thrown if this ResultSet is closed
1575     */

1576    public final void clearWarnings() throws SQLException JavaDoc {
1577        checkIfClosed("clearWarnings");
1578        topWarning = null;
1579    }
1580
1581    /**
1582     * Get the name of the SQL cursor used by this ResultSet.
1583     *
1584     * <P>In SQL, a result table is retrieved through a cursor that is
1585     * named. The current row of a result can be updated or deleted
1586     * using a positioned update/delete statement that references the
1587     * cursor name.
1588     *
1589     * <P>JDBC supports this SQL feature by providing the name of the
1590     * SQL cursor used by a ResultSet. The current row of a ResultSet
1591     * is also the current row of this SQL cursor.
1592     *
1593     * <P><B>Note:</B> If positioned update is not supported a
1594     * SQLException is thrown
1595     *
1596     * @return the ResultSet's SQL cursor name
1597     * @exception SQLException thrown on failure.
1598     */

1599    public final String JavaDoc getCursorName() throws SQLException JavaDoc {
1600
1601      checkIfClosed("getCursorName"); // checking result set closure does not depend
1602
// on the underlying connection. Do this
1603
// outside of the connection synchronization.
1604

1605      return theResults.getCursorName();
1606    }
1607
1608    /**
1609     * The number, types and properties of a ResultSet's columns
1610     * are provided by the getMetaData method.
1611     *
1612     * @return the description of a ResultSet's columns
1613     * @exception SQLException thrown on failure.
1614     */

1615    public ResultSetMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
1616
1617      checkIfClosed("getMetaData"); // checking result set closure does not depend
1618
// on the underlying connection. Do this
1619
// outside of the connection synchronization.
1620

1621      synchronized (getConnectionSynchronization()) {
1622
1623
1624        if (rMetaData == null) {
1625            // cache this object and keep returning it
1626
rMetaData = newEmbedResultSetMetaData(resultDescription);
1627        }
1628        return rMetaData;
1629      }
1630    }
1631    
1632    /**
1633     * JDBC 4.0
1634     *
1635     * <p>
1636     * Retrieves the holdability for this <code>ResultSet</code>
1637     * object.
1638     *
1639     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1640     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1641     * @exception SQLException
1642     * if a database error occurs
1643     */

1644    public final int getHoldability() throws SQLException JavaDoc {
1645        checkIfClosed("getHoldability");
1646        if (theResults.getActivation().getResultSetHoldability()) {
1647            return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
1648        }
1649        return JDBC30Translation.CLOSE_CURSORS_AT_COMMIT;
1650    }
1651
1652    /**
1653     * <p>Get the value of a column in the current row as a Java object.
1654     *
1655     * <p>This method will return the value of the given column as a
1656     * Java object. The type of the Java object will be the default
1657     * Java Object type corresponding to the column's SQL type,
1658     * following the mapping specified in the JDBC spec.
1659     *
1660     * <p>This method may also be used to read datatabase specific abstract
1661     * data types.
1662     *
1663     * JDBC 2.0
1664     *
1665     * New behavior for getObject().
1666     * The behavior of method getObject() is extended to materialize
1667     * data of SQL user-defined types. When the column @columnIndex is
1668     * a structured or distinct value, the behavior of this method is as
1669     * if it were a call to: getObject(columnIndex,
1670     * this.getStatement().getConnection().getTypeMap()).
1671     *
1672     * @param columnIndex the first column is 1, the second is 2, ...
1673     * @return A java.lang.Object holding the column value.
1674     * @exception SQLException thrown on failure.
1675     */

1676    public final Object JavaDoc getObject(int columnIndex) throws SQLException JavaDoc {
1677        checkIfClosed("getObject");
1678
1679        // need special handling for some types.
1680
int colType = getColumnType(columnIndex);
1681        switch (colType) {
1682        case Types.CHAR:
1683        case Types.VARCHAR:
1684        case Types.LONGVARCHAR:
1685            // handles maxfield size correctly
1686
return getString(columnIndex);
1687
1688        case Types.CLOB:
1689            return getClob(columnIndex);
1690
1691        case Types.BINARY:
1692        case Types.VARBINARY:
1693        case Types.LONGVARBINARY:
1694            // handles maxfield size correctly
1695
return getBytes(columnIndex);
1696
1697        case Types.BLOB:
1698            return getBlob(columnIndex);
1699
1700        default:
1701            break;
1702        }
1703
1704        try {
1705
1706            DataValueDescriptor dvd = getColumn(columnIndex);
1707            if (wasNull = dvd.isNull())
1708                return null;
1709
1710            return dvd.getObject();
1711
1712        } catch (StandardException t) {
1713            throw noStateChangeException(t);
1714        }
1715    }
1716
1717    /**
1718     * <p>Get the value of a column in the current row as a Java object.
1719     *
1720     * <p>This method will return the value of the given column as a
1721     * Java object. The type of the Java object will be the default
1722     * Java Object type corresponding to the column's SQL type,
1723     * following the mapping specified in the JDBC spec.
1724     *
1725     * <p>This method may also be used to read datatabase specific abstract
1726     * data types.
1727     *
1728     * JDBC 2.0
1729     *
1730     * New behavior for getObject().
1731     * The behavior of method getObject() is extended to materialize
1732     * data of SQL user-defined types. When the column @columnName is
1733     * a structured or distinct value, the behavior of this method is as
1734     * if it were a call to: getObject(columnName,
1735     * this.getStatement().getConnection().getTypeMap()).
1736     *
1737     * @param columnName is the SQL name of the column
1738     * @return A java.lang.Object holding the column value.
1739     * @exception SQLException thrown on failure.
1740     */

1741    public final Object JavaDoc getObject(String JavaDoc columnName) throws SQLException JavaDoc {
1742        checkIfClosed("getObject");
1743        return (getObject(findColumnName(columnName)));
1744    }
1745
1746
1747    //----------------------------------------------------------------
1748

1749    /**
1750     * Map a Resultset column name to a ResultSet column index.
1751     *
1752     * @param columnName the name of the column
1753     * @return the column index
1754     * @exception SQLException thrown on failure.
1755     */

1756    public final int findColumn(String JavaDoc columnName) throws SQLException JavaDoc {
1757        checkIfClosed("findColumn");
1758        return findColumnName(columnName);
1759    }
1760    
1761    /////////////////////////////////////////////////////////////////////////
1762
//
1763
// JDBC 2.0 - New public methods
1764
//
1765
/////////////////////////////////////////////////////////////////////////
1766

1767
1768    //---------------------------------------------------------------------
1769
// Getter's and Setter's
1770
//---------------------------------------------------------------------
1771

1772    /**
1773     * JDBC 2.0
1774     *
1775     * Return the Statement that produced the ResultSet.
1776     *
1777     * @return the Statment that produced the result set, or null if the result
1778     * was produced some other way.
1779     * @exception SQLException if a database error occurs or the
1780     * result set is closed
1781     */

1782    public final Statement JavaDoc getStatement() throws SQLException JavaDoc
1783    {
1784            checkIfClosed("getStatement");
1785            return applicationStmt;
1786    }
1787    
1788    /**
1789     * Set the application Statement object that created this ResultSet.
1790     * Used when the Statement objects returned to the application
1791     * are wrapped for XA.
1792     */

1793    public final void setApplicationStatement(Statement JavaDoc applicationStmt)
1794    {
1795        this.applicationStmt = applicationStmt;
1796    }
1797
1798    //---------------------------------------------------------------------
1799
// Traversal/Positioning
1800
//---------------------------------------------------------------------
1801

1802    /**
1803     * JDBC 2.0
1804     *
1805     * <p>
1806     * Determine if the cursor is before the first row in the result set.
1807     *
1808     * @return true if before the first row, false otherwise. Returns false when
1809     * the result set contains no rows.
1810     * @exception SQLException
1811     * Thrown on error.
1812     */

1813    public boolean isBeforeFirst() throws SQLException JavaDoc {
1814        return checkRowPosition(ResultSet.ISBEFOREFIRST, "isBeforeFirst");
1815    }
1816
1817    /**
1818     * JDBC 2.0
1819     *
1820     * <p>
1821     * Determine if the cursor is after the last row in the result set.
1822     *
1823     * @return true if after the last row, false otherwise. Returns false when
1824     * the result set contains no rows.
1825     * @exception SQLException
1826     * Thrown on error.
1827     */

1828    public boolean isAfterLast() throws SQLException JavaDoc {
1829        return checkRowPosition(ResultSet.ISAFTERLAST, "isAfterLast");
1830    }
1831
1832    /**
1833     * JDBC 2.0
1834     *
1835     * <p>
1836     * Determine if the cursor is on the first row of the result set.
1837     *
1838     * @return true if on the first row, false otherwise.
1839     * @exception SQLException
1840     * Thrown on error.
1841     */

1842    public boolean isFirst() throws SQLException JavaDoc {
1843        return checkRowPosition(ResultSet.ISFIRST, "isFirst");
1844    }
1845
1846    /**
1847     * JDBC 2.0
1848     *
1849     * <p>
1850     * Determine if the cursor is on the last row of the result set. Note:
1851     * Calling isLast() may be expensive since the JDBC driver might need to
1852     * fetch ahead one row in order to determine whether the current row is the
1853     * last row in the result set.
1854     *
1855     * @return true if on the last row, false otherwise.
1856     * @exception SQLException
1857     * Thrown on error.
1858     */

1859    public boolean isLast() throws SQLException JavaDoc {
1860        return checkRowPosition(ResultSet.ISLAST, "isLast");
1861    }
1862
1863    /**
1864     * JDBC 2.0
1865     *
1866     * <p>
1867     * Moves to the front of the result set, just before the first row. Has no
1868     * effect if the result set contains no rows.
1869     *
1870     * @exception SQLException
1871     * if a database-access error occurs, or result set type is
1872     * TYPE_FORWARD_ONLY
1873     */

1874    public void beforeFirst() throws SQLException JavaDoc {
1875        // beforeFirst is only allowed on scroll cursors
1876
checkScrollCursor("beforeFirst()");
1877        movePosition(BEFOREFIRST, "beforeFirst");
1878    }
1879
1880    /**
1881     * JDBC 2.0
1882     *
1883     * <p>
1884     * Moves to the end of the result set, just after the last row. Has no
1885     * effect if the result set contains no rows.
1886     *
1887     * @exception SQLException
1888     * if a database-access error occurs, or result set type is
1889     * TYPE_FORWARD_ONLY.
1890     */

1891    public void afterLast() throws SQLException JavaDoc {
1892        // afterLast is only allowed on scroll cursors
1893
checkScrollCursor("afterLast()");
1894        movePosition(AFTERLAST, "afterLast");
1895    }
1896
1897    /**
1898     * JDBC 2.0
1899     *
1900     * <p>
1901     * Moves to the first row in the result set.
1902     *
1903     * @return true if on a valid row, false if no rows in the result set.
1904     * @exception SQLException
1905     * if a database-access error occurs, or result set type is
1906     * TYPE_FORWARD_ONLY.
1907     */

1908    public boolean first() throws SQLException JavaDoc {
1909        // first is only allowed on scroll cursors
1910
checkScrollCursor("first()");
1911        return movePosition(FIRST, "first");
1912    }
1913
1914    /**
1915     * JDBC 2.0
1916     *
1917     * <p>
1918     * Moves to the last row in the result set.
1919     *
1920     * @return true if on a valid row, false if no rows in the result set.
1921     * @exception SQLException
1922     * if a database-access error occurs, or result set type is
1923     * TYPE_FORWARD_ONLY.
1924     */

1925    public boolean last() throws SQLException JavaDoc {
1926        // last is only allowed on scroll cursors
1927
checkScrollCursor("last()");
1928        return movePosition(LAST, "last");
1929    }
1930
1931    /**
1932     * JDBC 2.0
1933     *
1934     * <p>
1935     * Determine the current row number. The first row is number 1, the second
1936     * number 2, etc.
1937     *
1938     * @return the current row number, else return 0 if there is no current row
1939     * @exception SQLException
1940     * if a database-access error occurs.
1941     */

1942    public int getRow() throws SQLException JavaDoc {
1943        // getRow() is only allowed on scroll cursors
1944
checkScrollCursor("getRow()");
1945
1946        /*
1947         * * We probably needn't bother getting the text of * the underlying
1948         * statement but it is better to be * consistent and we aren't
1949         * particularly worried * about performance of getRow().
1950         */

1951        return theResults.getRowNumber();
1952    }
1953
1954    /**
1955     * JDBC 2.0
1956     *
1957     * <p>
1958     * Move to an absolute row number in the result set.
1959     *
1960     * <p>
1961     * If row is positive, moves to an absolute row with respect to the
1962     * beginning of the result set. The first row is row 1, the second is row 2,
1963     * etc.
1964     *
1965     * <p>
1966     * If row is negative, moves to an absolute row position with respect to the
1967     * end of result set. For example, calling absolute(-1) positions the cursor
1968     * on the last row, absolute(-2) indicates the next-to-last row, etc.
1969     *
1970     * <p>
1971     * An attempt to position the cursor beyond the first/last row in the result
1972     * set, leaves the cursor before/after the first/last row, respectively.
1973     *
1974     * <p>
1975     * Note: Calling absolute(1) is the same as calling first(). Calling
1976     * absolute(-1) is the same as calling last().
1977     *
1978     * @return true if on the result set, false if off.
1979     * @exception SQLException
1980     * if a database-access error occurs, or row is 0, or result
1981     * set type is TYPE_FORWARD_ONLY.
1982     */

1983    public boolean absolute(int row) throws SQLException JavaDoc {
1984        // absolute is only allowed on scroll cursors
1985
checkScrollCursor("absolute()");
1986        return movePosition(ABSOLUTE, row, "absolute");
1987    }
1988
1989    /**
1990     * JDBC 2.0
1991     *
1992     * <p>
1993     * Moves a relative number of rows, either positive or negative. Attempting
1994     * to move beyond the first/last row in the result set positions the cursor
1995     * before/after the the first/last row. Calling relative(0) is valid, but
1996     * does not change the cursor position.
1997     *
1998     * <p>
1999     * Note: Calling relative(1) is different than calling next() since is makes
2000     * sense to call next() when there is no current row, for example, when the
2001     * cursor is positioned before the first row or after the last row of the
2002     * result set.
2003     *
2004     * @return true if on a row, false otherwise.
2005     * @exception SQLException
2006     * if a database-access error occurs, or there is no current
2007     * row, or result set type is TYPE_FORWARD_ONLY.
2008     */

2009    public boolean relative(int row) throws SQLException JavaDoc {
2010        // absolute is only allowed on scroll cursors
2011
checkScrollCursor("relative()");
2012        return movePosition(RELATIVE, row, "relative");
2013    }
2014
2015    /**
2016     * JDBC 2.0
2017     *
2018     * <p>
2019     * Moves to the previous row in the result set.
2020     *
2021     * <p>
2022     * Note: previous() is not the same as relative(-1) since it makes sense to
2023     * call previous() when there is no current row.
2024     *
2025     * @return true if on a valid row, false if off the result set.
2026     * @exception SQLException
2027     * if a database-access error occurs, or result set type is
2028     * TYPE_FORWAR_DONLY.
2029     */

2030    public boolean previous() throws SQLException JavaDoc {
2031        // previous is only allowed on scroll cursors
2032
checkScrollCursor("previous()");
2033        return movePosition(PREVIOUS, "previous");
2034    }
2035
2036    //---------------------------------------------------------------------
2037
// Properties
2038
//---------------------------------------------------------------------
2039

2040    /**
2041     * JDBC 2.0
2042     *
2043     * Give a hint as to the direction in which the rows in this result set will
2044     * be processed. The initial value is determined by the statement that
2045     * produced the result set. The fetch direction may be changed at any time.
2046     *
2047     * @exception SQLException
2048     * if a database-access error occurs, or the result set type
2049     * is TYPE_FORWARD_ONLY and direction is not FETCH_FORWARD.
2050     */

2051    public void setFetchDirection(int direction) throws SQLException JavaDoc {
2052        checkScrollCursor("setFetchDirection()");
2053        /*
2054         * FetchDirection is meaningless to us. We just save it off and return
2055         * the current value if asked.
2056         */

2057        fetchDirection = direction;
2058    }
2059
2060    /**
2061     * JDBC 2.0
2062     *
2063     * Return the fetch direction for this result set.
2064     *
2065     * @exception SQLException
2066     * if a database-access error occurs
2067     */

2068    public int getFetchDirection() throws SQLException JavaDoc {
2069        checkIfClosed("getFetchDirection");
2070        if (fetchDirection == 0) {
2071            // value is not set at the result set level
2072
// get it from the statement level
2073
return stmt.getFetchDirection();
2074        } else
2075            return fetchDirection;
2076    }
2077
2078    /**
2079     * JDBC 2.0
2080     *
2081     * Give the JDBC driver a hint as to the number of rows that should be
2082     * fetched from the database when more rows are needed for this result set.
2083     * If the fetch size specified is zero, then the JDBC driver ignores the
2084     * value, and is free to make its own best guess as to what the fetch size
2085     * should be. The default value is set by the statement that creates the
2086     * result set. The fetch size may be changed at any time.
2087     *
2088     * @param rows
2089     * the number of rows to fetch
2090     * @exception SQLException
2091     * if a database-access error occurs, or the condition 0 <=
2092     * rows <= this.getMaxRows() is not satisfied.
2093     */

2094    public void setFetchSize(int rows) throws SQLException JavaDoc {
2095        checkIfClosed("setFetchSize");
2096        if (rows < 0 || (stmt.getMaxRows() != 0 && rows > stmt.getMaxRows())) {
2097            throw Util.generateCsSQLException(SQLState.INVALID_FETCH_SIZE,
2098                    new Integer JavaDoc(rows));
2099        } else if (rows > 0) // if it is zero ignore the call
2100
{
2101            fetchSize = rows;
2102        }
2103    }
2104
2105    /**
2106     * JDBC 2.0
2107     *
2108     * Return the fetch size for this result set.
2109     *
2110     * @exception SQLException
2111     * if a database-access error occurs
2112     */

2113    public int getFetchSize() throws SQLException JavaDoc {
2114        checkIfClosed("getFetchSize");
2115        if (fetchSize == 0) {
2116            // value is not set at the result set level
2117
// get the default value from the statement
2118
return stmt.getFetchSize();
2119        } else
2120            return fetchSize;
2121    }
2122
2123    /**
2124     * JDBC 2.0
2125     *
2126     * Return the type of this result set. The type is determined based on the
2127     * statement that created the result set.
2128     *
2129     * @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
2130     * TYPE_SCROLL_SENSITIVE
2131     * @exception SQLException
2132     * if a database-access error occurs
2133     */

2134    public int getType() throws SQLException JavaDoc {
2135        checkIfClosed("getType");
2136        return stmt.getResultSetType();
2137    }
2138
2139    /**
2140     * JDBC 2.0
2141     *
2142     * Return the concurrency of this result set. The concurrency is determined
2143     * as follows If Statement object has CONCUR_READ_ONLY concurrency, then
2144     * ResultSet object will also have the CONCUR_READ_ONLY concurrency. But if
2145     * Statement object has CONCUR_UPDATABLE concurrency, then the concurrency
2146     * of ResultSet object depends on whether the underlying language resultset
2147     * is updatable or not. If the language resultset is updatable, then JDBC
2148     * ResultSet object will also have the CONCUR_UPDATABLE concurrency. If
2149     * lanugage resultset is not updatable, then JDBC ResultSet object
2150     * concurrency will be set to CONCUR_READ_ONLY.
2151     *
2152     * @return the concurrency type, CONCUR_READ_ONLY, etc.
2153     * @exception SQLException
2154     * if a database-access error occurs
2155     */

2156    public int getConcurrency() throws SQLException JavaDoc {
2157        checkIfClosed("getConcurrency");
2158        return concurrencyOfThisResultSet;
2159    }
2160
2161    //---------------------------------------------------------------------
2162
// Updates
2163
//---------------------------------------------------------------------
2164

2165    /**
2166     * JDBC 2.0
2167     *
2168     * Determine if the current row has been updated. The value returned depends
2169     * on whether or not the result set can detect updates.
2170     *
2171     * @return true if the row has been visibly updated by the owner or another,
2172     * and updates are detected
2173     * @exception SQLException
2174     * if a database-access error occurs
2175     *
2176     * @see EmbedDatabaseMetaData#updatesAreDetected
2177     */

2178    public boolean rowUpdated() throws SQLException JavaDoc {
2179        checkIfClosed("rowUpdated");
2180        checkNotOnInsertRow();
2181        checkOnRow();
2182
2183        boolean rvalue = false;
2184
2185        try {
2186            if (isForUpdate() &&
2187                    getType() == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
2188                rvalue = ((ScrollInsensitiveResultSet)theResults).isUpdated();
2189            }
2190        } catch (Throwable JavaDoc t) {
2191                handleException(t);
2192        }
2193        return rvalue;
2194    }
2195
2196    /**
2197     * JDBC 2.0
2198     *
2199     * Determine if the current row has been inserted. The value returned
2200     * depends on whether or not the result set can detect visible inserts.
2201     *
2202     * @return true if inserted and inserts are detected
2203     * @exception SQLException
2204     * if a database-access error occurs
2205     *
2206     * @see EmbedDatabaseMetaData#insertsAreDetected
2207     */

2208    public boolean rowInserted() throws SQLException JavaDoc {
2209        checkIfClosed("rowInserted");
2210        checkNotOnInsertRow();
2211        checkOnRow();
2212
2213        return false;
2214    }
2215
2216    /**
2217     * JDBC 2.0
2218     *
2219     * Determine if this row has been deleted. A deleted row may leave a visible
2220     * "hole" in a result set. This method can be used to detect holes in a
2221     * result set. The value returned depends on whether or not the result set
2222     * can detect deletions.
2223     *
2224     * @return true if deleted and deletes are detected
2225     * @exception SQLException
2226     * if a database-access error occurs
2227     *
2228     * @see EmbedDatabaseMetaData#deletesAreDetected
2229     */

2230    public boolean rowDeleted() throws SQLException JavaDoc {
2231        checkIfClosed("rowUpdated");
2232        checkNotOnInsertRow();
2233        checkOnRow();
2234
2235        boolean rvalue = false;
2236
2237        try {
2238            if (isForUpdate() &&
2239                    getType() == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
2240                rvalue = ((ScrollInsensitiveResultSet)theResults).isDeleted();
2241            }
2242        } catch (Throwable JavaDoc t) {
2243            handleException(t);
2244        }
2245        return rvalue;
2246    }
2247
2248    //do following few checks before accepting updateXXX resultset api
2249
protected void checksBeforeUpdateXXX(String JavaDoc methodName, int columnIndex) throws SQLException JavaDoc {
2250      checksBeforeUpdateOrDelete(methodName, columnIndex);
2251
2252      //1)Make sure for updateXXX methods, the column position is not out of range
2253
ResultDescription rd = theResults.getResultDescription();
2254      if (columnIndex < 1 || columnIndex > rd.getColumnCount())
2255        throw Util.generateCsSQLException(SQLState.LANG_INVALID_COLUMN_POSITION,
2256                    new Integer JavaDoc(columnIndex), String.valueOf(rd.getColumnCount()));
2257
2258      //2)Make sure the column corresponds to a column in the base table and it is not a derived column
2259
if (rd.getColumnDescriptor(columnIndex).getSourceTableName() == null)
2260        throw Util.generateCsSQLException(SQLState.COLUMN_NOT_FROM_BASE_TABLE,
2261                    methodName);
2262
2263      //3)If column not updatable then throw an exception
2264
if (!getMetaData().isWritable(columnIndex))
2265        throw Util.generateCsSQLException(SQLState.LANG_COLUMN_NOT_UPDATABLE_IN_CURSOR,
2266                    theResults.getResultDescription().getColumnDescriptor(columnIndex).getName(),
2267                    getCursorName());
2268    }
2269
2270    //do following few checks before accepting updateRow or deleteRow
2271
//1)Make sure JDBC ResultSet is not closed
2272
//2)Make sure this is an updatable ResultSet
2273
//3)Make sure JDBC ResultSet is positioned on a row
2274
//4)Make sure underneath language resultset is not closed
2275
protected void checksBeforeUpdateOrDelete(String JavaDoc methodName, int columnIndex) throws SQLException JavaDoc {
2276
2277      //1)Make sure JDBC ResultSet is not closed
2278
checkIfClosed(methodName);
2279
2280      //2)Make sure this is an updatable ResultSet
2281
checkUpdatableCursor(methodName);
2282
2283      //3)Make sure JDBC ResultSet is positioned on a row
2284
if (!isOnInsertRow) checkOnRow(); // make sure there's a current row
2285
//in case of autocommit on, if there was an exception which caused runtime rollback in this transaction prior to this call,
2286
//the rollback code will mark the language resultset closed (it doesn't mark the JDBC ResultSet closed).
2287
//That is why alongwith the earlier checkIfClosed call in this method, there is a check for language resultset close as well.
2288

2289      //4)Make sure underneath language resultset is not closed
2290
if (theResults.isClosed())
2291        throw Util.generateCsSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, methodName);
2292    }
2293
2294    //mark the column as updated and return DataValueDescriptor for it. It will be used by updateXXX methods to put new values
2295
protected DataValueDescriptor getDVDforColumnToBeUpdated(int columnIndex, String JavaDoc updateMethodName) throws StandardException, SQLException JavaDoc {
2296      checksBeforeUpdateXXX(updateMethodName, columnIndex);
2297      columnGotUpdated[columnIndex-1] = true;
2298      currentRowHasBeenUpdated = true;
2299      
2300      return updateRow.getColumn(columnIndex);
2301    }
2302
2303    /* do following few checks before accepting insertRow
2304     * 1) Make sure JDBC ResultSet is not closed
2305     * 2) Make sure this is an updatable ResultSet
2306     * 3) Make sure JDBC ResultSet is positioned on insertRow
2307     * 4) Make sure underneath language resultset is not closed
2308     */

2309    protected void checksBeforeInsert() throws SQLException JavaDoc {
2310        // 1)Make sure JDBC ResultSet is not closed
2311
checkIfClosed("insertRow");
2312
2313        // 2)Make sure this is an updatable ResultSet
2314
// if not updatable resultset, then throw exception
2315
checkUpdatableCursor("insertRow");
2316
2317        // 3)Make sure JDBC ResultSet is positioned on insertRow
2318
if (!isOnInsertRow) {
2319            throw newSQLException(SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW);
2320        }
2321
2322        // 4)Make sure underneath language resultset is not closed
2323
if (theResults.isClosed()) {
2324            throw Util.generateCsSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, "insertRow");
2325        }
2326    }
2327
2328    /**
2329     * Check whether it is OK to update a column using
2330     * <code>updateAsciiStream()</code>.
2331     *
2332     * @param columnIndex the column index (first column is 1)
2333     * @exception SQLException if the column could not be updated with
2334     * <code>updateAsciiStream()</code>
2335     */

2336    private void checksBeforeUpdateAsciiStream(int columnIndex)
2337        throws SQLException JavaDoc
2338    {
2339        checksBeforeUpdateXXX("updateAsciiStream", columnIndex);
2340        int colType = getColumnType(columnIndex);
2341        if (!DataTypeDescriptor.isAsciiStreamAssignable(colType)) {
2342            throw dataTypeConversion(columnIndex, "java.io.InputStream");
2343        }
2344    }
2345
2346    /**
2347     * Check whether it is OK to update a column using
2348     * <code>updateBinaryStream()</code>.
2349     *
2350     * @param columnIndex the column index (first column is 1)
2351     * @exception SQLException if the column could not be updated with
2352     * <code>updateBinaryStream()</code>
2353     */

2354    private void checksBeforeUpdateBinaryStream(int columnIndex)
2355        throws SQLException JavaDoc
2356    {
2357        checksBeforeUpdateXXX("updateBinaryStream", columnIndex);
2358        int colType = getColumnType(columnIndex);
2359        if (!DataTypeDescriptor.isBinaryStreamAssignable(colType)) {
2360            throw dataTypeConversion(columnIndex, "java.io.InputStream");
2361        }
2362    }
2363
2364    /**
2365     * Check whether it is OK to update a column using
2366     * <code>updateCharacterStream()</code>.
2367     *
2368     * @param columnIndex the column index (first column is 1)
2369     * @exception SQLException if the column could not be updated with
2370     * <code>updateCharacterStream()</code>
2371     */

2372    private void checksBeforeUpdateCharacterStream(int columnIndex)
2373        throws SQLException JavaDoc
2374    {
2375        checksBeforeUpdateXXX("updateCharacterStream", columnIndex);
2376        int colType = getColumnType(columnIndex);
2377        if (!DataTypeDescriptor.isCharacterStreamAssignable(colType)) {
2378            throw dataTypeConversion(columnIndex, "java.io.Reader");
2379        }
2380    }
2381    
2382    /**
2383     * JDBC 2.0
2384     *
2385     * Give a nullable column a null value.
2386     *
2387     * The updateXXX() methods are used to update column values in the current
2388     * row, or the insert row. The updateXXX() methods do not update the
2389     * underlying database, instead the updateRow() or insertRow() methods are
2390     * called to update the database.
2391     *
2392     * @param columnIndex
2393     * the first column is 1, the second is 2, ...
2394     * @exception SQLException
2395     * if a database-access error occurs
2396     */

2397    public void updateNull(int columnIndex) throws SQLException JavaDoc {
2398        try {
2399            getDVDforColumnToBeUpdated(columnIndex, "updateNull").setToNull();
2400        } catch (StandardException t) {
2401            throw noStateChangeException(t);
2402        }
2403    }
2404
2405    /**
2406     * JDBC 2.0
2407     *
2408     * Update a column with a boolean value.
2409     *
2410     * The updateXXX() methods are used to update column values in the current
2411     * row, or the insert row. The updateXXX() methods do not update the
2412     * underlying database, instead the updateRow() or insertRow() methods are
2413     * called to update the database.
2414     *
2415     * @param columnIndex
2416     * the first column is 1, the second is 2, ...
2417     * @param x
2418     * the new column value
2419     * @exception SQLException
2420     * if a database-access error occurs
2421     */

2422    public void updateBoolean(int columnIndex, boolean x) throws SQLException JavaDoc {
2423        try {
2424            getDVDforColumnToBeUpdated(columnIndex, "updateBoolean").setValue(x);
2425        } catch (StandardException t) {
2426            throw noStateChangeException(t);
2427        }
2428    }
2429
2430    /**
2431     * JDBC 2.0
2432     *
2433     * Update a column with a byte value.
2434     *
2435     * The updateXXX() methods are used to update column values in the current
2436     * row, or the insert row. The updateXXX() methods do not update the
2437     * underlying database, instead the updateRow() or insertRow() methods are
2438     * called to update the database.
2439     *
2440     * @param columnIndex
2441     * the first column is 1, the second is 2, ...
2442     * @param x
2443     * the new column value
2444     * @exception SQLException
2445     * if a database-access error occurs
2446     */

2447    public void updateByte(int columnIndex, byte x) throws SQLException JavaDoc {
2448        try {
2449            getDVDforColumnToBeUpdated(columnIndex, "updateByte").setValue(x);
2450        } catch (StandardException t) {
2451            throw noStateChangeException(t);
2452        }
2453    }
2454
2455    /**
2456     * JDBC 2.0
2457     *
2458     * Update a column with a short value.
2459     *
2460     * The updateXXX() methods are used to update column values in the current
2461     * row, or the insert row. The updateXXX() methods do not update the
2462     * underlying database, instead the updateRow() or insertRow() methods are
2463     * called to update the database.
2464     *
2465     * @param columnIndex
2466     * the first column is 1, the second is 2, ...
2467     * @param x
2468     * the new column value
2469     * @exception SQLException
2470     * if a database-access error occurs
2471     */

2472    public void updateShort(int columnIndex, short x) throws SQLException JavaDoc {
2473        try {
2474            getDVDforColumnToBeUpdated(columnIndex, "updateShort").setValue(x);
2475        } catch (StandardException t) {
2476            throw noStateChangeException(t);
2477        }
2478    }
2479
2480    /**
2481     * JDBC 2.0
2482     *
2483     * Update a column with an integer value.
2484     *
2485     * The updateXXX() methods are used to update column values in the current
2486     * row, or the insert row. The updateXXX() methods do not update the
2487     * underlying database, instead the updateRow() or insertRow() methods are
2488     * called to update the database.
2489     *
2490     * @param columnIndex
2491     * the first column is 1, the second is 2, ...
2492     * @param x
2493     * the new column value
2494     * @exception SQLException
2495     * if a database-access error occurs
2496     */

2497    public void updateInt(int columnIndex, int x) throws SQLException JavaDoc {
2498        try {
2499            getDVDforColumnToBeUpdated(columnIndex, "updateInt").setValue(x);
2500        } catch (StandardException t) {
2501            throw noStateChangeException(t);
2502        }
2503    }
2504
2505    /**
2506     * JDBC 2.0
2507     *
2508     * Update a column with a long value.
2509     *
2510     * The updateXXX() methods are used to update column values in the current
2511     * row, or the insert row. The updateXXX() methods do not update the
2512     * underlying database, instead the updateRow() or insertRow() methods are
2513     * called to update the database.
2514     *
2515     * @param columnIndex
2516     * the first column is 1, the second is 2, ...
2517     * @param x
2518     * the new column value
2519     * @exception SQLException
2520     * if a database-access error occurs
2521     */

2522    public void updateLong(int columnIndex, long x) throws SQLException JavaDoc {
2523        try {
2524            getDVDforColumnToBeUpdated(columnIndex, "updateLong").setValue(x);
2525        } catch (StandardException t) {
2526            throw noStateChangeException(t);
2527        }
2528    }
2529
2530    /**
2531     * JDBC 2.0
2532     *
2533     * Update a column with a float value.
2534     *
2535     * The updateXXX() methods are used to update column values in the current
2536     * row, or the insert row. The updateXXX() methods do not update the
2537     * underlying database, instead the updateRow() or insertRow() methods are
2538     * called to update the database.
2539     *
2540     * @param columnIndex
2541     * the first column is 1, the second is 2, ...
2542     * @param x
2543     * the new column value
2544     * @exception SQLException
2545     * if a database-access error occurs
2546     */

2547    public void updateFloat(int columnIndex, float x) throws SQLException JavaDoc {
2548        try {
2549            getDVDforColumnToBeUpdated(columnIndex, "updateFloat").setValue(x);
2550        } catch (StandardException t) {
2551            throw noStateChangeException(t);
2552        }
2553    }
2554
2555    /**
2556     * JDBC 2.0
2557     *
2558     * Update a column with a Double value.
2559     *
2560     * The updateXXX() methods are used to update column values in the current
2561     * row, or the insert row. The updateXXX() methods do not update the
2562     * underlying database, instead the updateRow() or insertRow() methods are
2563     * called to update the database.
2564     *
2565     * @param columnIndex
2566     * the first column is 1, the second is 2, ...
2567     * @param x
2568     * the new column value
2569     * @exception SQLException
2570     * if a database-access error occurs
2571     */

2572    public void updateDouble(int columnIndex, double x) throws SQLException JavaDoc {
2573        try {
2574            getDVDforColumnToBeUpdated(columnIndex, "updateDouble").setValue(x);
2575        } catch (StandardException t) {
2576            throw noStateChangeException(t);
2577        }
2578    }
2579
2580    /**
2581     * JDBC 2.0
2582     *
2583     * Update a column with a String value.
2584     *
2585     * The updateXXX() methods are used to update column values in the current
2586     * row, or the insert row. The updateXXX() methods do not update the
2587     * underlying database, instead the updateRow() or insertRow() methods are
2588     * 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     * @exception SQLException
2595     * if a database-access error occurs
2596     */

2597    public void updateString(int columnIndex, String JavaDoc x) throws SQLException JavaDoc {
2598        try {
2599            getDVDforColumnToBeUpdated(columnIndex, "updateString").setValue(x);
2600        } catch (StandardException t) {
2601            throw noStateChangeException(t);
2602        }
2603    }
2604
2605    /**
2606     * JDBC 2.0
2607     *
2608     * Update a column with a byte array value.
2609     *
2610     * The updateXXX() methods are used to update column values in the current
2611     * row, or the insert row. The updateXXX() methods do not update the
2612     * underlying database, instead the updateRow() or insertRow() methods are
2613     * called to update the database.
2614     *
2615     * @param columnIndex
2616     * the first column is 1, the second is 2, ...
2617     * @param x
2618     * the new column value
2619     * @exception SQLException
2620     * if a database-access error occurs
2621     */

2622    public void updateBytes(int columnIndex, byte x[]) throws SQLException JavaDoc {
2623        try {
2624            getDVDforColumnToBeUpdated(columnIndex, "updateBytes").setValue(x);
2625        } catch (StandardException t) {
2626            throw noStateChangeException(t);
2627        }
2628    }
2629
2630    /**
2631     * JDBC 2.0
2632     *
2633     * Update a column with a Date value.
2634     *
2635     * The updateXXX() methods are used to update column values in the current
2636     * row, or the insert row. The updateXXX() methods do not update the
2637     * underlying database, instead the updateRow() or insertRow() methods are
2638     * 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     * @exception SQLException
2645     * if a database-access error occurs
2646     */

2647    public void updateDate(int columnIndex, java.sql.Date JavaDoc x)
2648            throws SQLException JavaDoc {
2649        try {
2650            getDVDforColumnToBeUpdated(columnIndex, "updateDate").setValue(x);
2651        } catch (StandardException t) {
2652            throw noStateChangeException(t);
2653        }
2654    }
2655
2656    /**
2657     * JDBC 2.0
2658     *
2659     * Update a column with a Time value.
2660     *
2661     * The updateXXX() methods are used to update column values in the current
2662     * row, or the insert row. The updateXXX() methods do not update the
2663     * underlying database, instead the updateRow() or insertRow() methods are
2664     * called to update the database.
2665     *
2666     * @param columnIndex
2667     * the first column is 1, the second is 2, ...
2668     * @param x
2669     * the new column value
2670     * @exception SQLException
2671     * if a database-access error occurs
2672     */

2673    public void updateTime(int columnIndex, java.sql.Time JavaDoc x)
2674            throws SQLException JavaDoc {
2675        try {
2676            getDVDforColumnToBeUpdated(columnIndex, "updateTime").setValue(x);
2677        } catch (StandardException t) {
2678            throw noStateChangeException(t);
2679        }
2680    }
2681
2682    /**
2683     * JDBC 2.0
2684     *
2685     * Update a column with a Timestamp value.
2686     *
2687     * The updateXXX() methods are used to update column values in the current
2688     * row, or the insert row. The updateXXX() methods do not update the
2689     * underlying database, instead the updateRow() or insertRow() methods are
2690     * called to update the database.
2691     *
2692     * @param columnIndex
2693     * the first column is 1, the second is 2, ...
2694     * @param x
2695     * the new column value
2696     * @exception SQLException
2697     * if a database-access error occurs
2698     */

2699    public void updateTimestamp(int columnIndex, java.sql.Timestamp JavaDoc x)
2700            throws SQLException JavaDoc {
2701        try {
2702            getDVDforColumnToBeUpdated(columnIndex, "updateTimestamp").setValue(x);
2703        } catch (StandardException t) {
2704            throw noStateChangeException(t);
2705        }
2706    }
2707
2708    /**
2709     *
2710     * Update a column with an ascii stream value.
2711     *
2712     * The updateXXX() methods are used to update column values in the current
2713     * row, or the insert row. The updateXXX() methods do not update the
2714     * underlying database, instead the updateRow() or insertRow() methods are
2715     * called to update the database.
2716     *
2717     * @param columnIndex
2718     * the first column is 1, the second is 2, ...
2719     * @param x
2720     * the new column value
2721     * @param length
2722     * the length of the stream
2723     * @exception SQLException
2724     * if a database-access error occurs
2725     */

2726    public void updateAsciiStream(int columnIndex, java.io.InputStream JavaDoc x,
2727            long length) throws SQLException JavaDoc {
2728        checksBeforeUpdateAsciiStream(columnIndex);
2729
2730        java.io.Reader JavaDoc r = null;
2731        if (x != null)
2732        {
2733            try {
2734                r = new java.io.InputStreamReader JavaDoc(x, "ISO-8859-1");
2735            } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
2736                throw new SQLException JavaDoc(uee.getMessage());
2737            }
2738        }
2739        updateCharacterStreamInternal(columnIndex, r, false, length,
2740                "updateAsciiStream");
2741    }
2742
2743    /**
2744     * Updates the designated column with a character stream value.
2745     * The data will be read from the stream as needed until end-of-stream is
2746     * reached.
2747     *
2748     * The updater methods are used to update column values in the current row
2749     * or the insert row. The updater methods do not update the underlying
2750     * database; instead the <code>updateRow</code> or </code>insertRow</code>
2751     * methods are called to update the database.
2752     *
2753     * @param columnIndex the first column is 1, the second is 2, ...
2754     * @param x the new column value
2755     * @throws SQLException if the columnIndex is not valid; if a database
2756     * access error occurs; the result set concurrency is
2757     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2758     * result set
2759     */

2760    public void updateAsciiStream(int columnIndex, InputStream x)
2761            throws SQLException JavaDoc {
2762        checksBeforeUpdateAsciiStream(columnIndex);
2763
2764        java.io.Reader JavaDoc r = null;
2765        if (x != null) {
2766            try {
2767                r = new java.io.InputStreamReader JavaDoc(x, "ISO-8859-1");
2768            } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
2769                throw new SQLException JavaDoc(uee.getMessage());
2770            }
2771        }
2772        updateCharacterStreamInternal(columnIndex, r, true, -1,
2773                                      "updateAsciiStream");
2774    }
2775
2776    /**
2777     *
2778     * Update a column with a binary stream value.
2779     *
2780     * The updateXXX() methods are used to update column values in the current
2781     * row, or the insert row. The updateXXX() methods do not update the
2782     * underlying database, instead the updateRow() or insertRow() methods are
2783     * called to update the database.
2784     *
2785     * @param columnIndex
2786     * the first column is 1, the second is 2, ...
2787     * @param x
2788     * the new column value
2789     * @param length
2790     * the length of the stream
2791     * @exception SQLException
2792     * if a database-access error occurs
2793     */

2794    public void updateBinaryStream(int columnIndex, java.io.InputStream JavaDoc x,
2795            long length) throws SQLException JavaDoc {
2796        checksBeforeUpdateBinaryStream(columnIndex);
2797
2798        if (x == null)
2799        {
2800            updateNull(columnIndex);
2801            return;
2802        }
2803
2804        updateBinaryStreamInternal(columnIndex, x, false, length,
2805                                   "updateBinaryStream");
2806    }
2807
2808    /**
2809     * Updates the designated column with a binary stream value.
2810     * The data will be read from the stream as needed until end-of-stream is
2811     * reached.
2812     *
2813     * The updater methods are used to update column values in the current row
2814     * or the insert row. The updater methods do not update the underlying
2815     * database; instead the <code>updateRow</code> or <code>insertRow</code>
2816     * methods are called to update the database.
2817     *
2818     * @param columnIndex the first column is 1, the second is 2, ...
2819     * @param x the new column value
2820     * @throws SQLException if the columnLabel is not valid; if a database
2821     * access error occurs; the result set concurrency is
2822     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2823     * result set
2824     */

2825    public void updateBinaryStream(int columnIndex, InputStream x)
2826            throws SQLException JavaDoc {
2827        checksBeforeUpdateBinaryStream(columnIndex);
2828        updateBinaryStreamInternal(columnIndex, x, true, -1,
2829                                   "updateBinaryStream");
2830    }
2831
2832    /**
2833     * Set the given binary stream for the specified parameter.
2834     *
2835     * If <code>lengthLess</code> is <code>true</code>, the following
2836     * conditions are either not checked or verified at the execution time
2837     * of <code>updateRow</code>/<code>insertRow</code>:
2838     * <ol><li>If the stream length is negative.
2839     * <li>If the stream's actual length equals the specified length.</ol>
2840     * The <code>lengthLess</code> variable was added to differentiate between
2841     * streams with invalid lengths and streams without known lengths.
2842     *
2843     * @param columnIndex the 1-based index of the parameter to set.
2844     * @param x the data.
2845     * @param lengthLess tells whether we know the length of the data or not.
2846     * @param length the length of the data. Ignored if <code>lengthLess</code>
2847     * is <code>true</code>.
2848     * @param updateMethodName the name of the method calling us. Used in
2849     * error messages.
2850     * @throws SQLException if reading the data fails, or one of the data
2851     * checks fails.
2852     */

2853    private void updateBinaryStreamInternal(int columnIndex, InputStream x,
2854                final boolean lengthLess, long length, String JavaDoc updateMethodName)
2855            throws SQLException JavaDoc {
2856        RawToBinaryFormatStream rawStream;
2857        if (!lengthLess) {
2858            if (length < 0)
2859                throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
2860
2861            // max number of bytes that can be set to be inserted
2862
// in Derby is 2Gb-1 (ie Integer.MAX_VALUE).
2863
// (e.g into a blob column).
2864
if (length > Integer.MAX_VALUE ) {
2865                throw newSQLException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
2866                        getColumnSQLType(columnIndex));
2867            }
2868            rawStream = new RawToBinaryFormatStream(x, (int)length);
2869        } else {
2870            // Force length to -1 if stream is length less.
2871
length = -1;
2872            rawStream = new RawToBinaryFormatStream(x,
2873                    getMaxColumnWidth(columnIndex),
2874                    getColumnSQLType(columnIndex));
2875        }
2876
2877        try {
2878            getDVDforColumnToBeUpdated(columnIndex, updateMethodName).setValue(
2879                    rawStream, (int) length);
2880        } catch (StandardException t) {
2881            throw noStateChangeException(t);
2882        }
2883    }
2884
2885    /**
2886     * JDBC 4.0
2887     *
2888     * Update a column with a character stream value.
2889     *
2890     * The updateXXX() methods are used to update column values in the current
2891     * row, or the insert row. The updateXXX() methods do not update the
2892     * underlying database, instead the updateRow() or insertRow() methods are
2893     * called to update the database.
2894     *
2895     * @param columnIndex
2896     * the first column is 1, the second is 2, ...
2897     * @param x
2898     * the new column value
2899     * @param length
2900     * the length of the stream
2901     * @exception SQLException
2902     * if a database-access error occurs
2903     */

2904    public void updateCharacterStream(int columnIndex, java.io.Reader JavaDoc x,
2905            long length) throws SQLException JavaDoc {
2906        checksBeforeUpdateCharacterStream(columnIndex);
2907        updateCharacterStreamInternal(columnIndex, x, false, length,
2908                                      "updateCharacterStream");
2909    }
2910
2911    /**
2912     * Updates the designated column with a character stream value.
2913     * The data will be read from the stream as needed until end-of-stream is
2914     * reached.
2915     *
2916     * The updater methods are used to update column values in the current row
2917     * or the insert row. The updater methods do not update the underlying
2918     * database; instead the <code>updateRow</code> or </code>insertRow</code>
2919     * methods are called to update the database.
2920     *
2921     * @param columnIndex the first column is 1, the second is 2, ...
2922     * @param x the new column value
2923     * @throws SQLException if the columnIndex is not valid; if a database
2924     * access error occurs; the result set concurrency is
2925     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2926     * result set
2927     */

2928    public void updateCharacterStream(int columnIndex, Reader x)
2929            throws SQLException JavaDoc {
2930        checksBeforeUpdateCharacterStream(columnIndex);
2931        updateCharacterStreamInternal(columnIndex, x, true, -1,
2932                                      "updateCharacterStream");
2933    }
2934
2935    /**
2936     * Set the given character stream for the specified parameter.
2937     *
2938     * If <code>lengthLess</code> is <code>true</code>, the following
2939     * conditions are either not checked or verified at the execution time
2940     * of the prepared statement:
2941     * <ol><li>If the stream length is negative.
2942     * <li>If the stream's actual length equals the specified length.</ol>
2943     * The <code>lengthLess</code> variable was added to differentiate between
2944     * streams with invalid lengths and streams without known lengths.
2945     *
2946     * @param columnIndex the 1-based index of the parameter to set.
2947     * @param reader the data.
2948     * @param lengthLess tells whether we know the length of the data or not.
2949     * @param length the length of the data. Ignored if <code>lengthLess</code>
2950     * is <code>true</code>.
2951     * @throws SQLException if reading the data fails, or one of the data
2952     * checks fails.
2953     */

2954    private void updateCharacterStreamInternal(int columnIndex, Reader reader,
2955                                               final boolean lengthLess,
2956                                               long length,
2957                                               String JavaDoc updateMethodName)
2958            throws SQLException JavaDoc
2959    {
2960        try {
2961
2962            if (reader == null)
2963            {
2964                updateNull(columnIndex);
2965                return;
2966            }
2967            
2968            ReaderToUTF8Stream utfIn;
2969            int usableLength = -1;
2970            if (!lengthLess) {
2971                // check for -ve length here
2972
if (length < 0)
2973                    throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
2974
2975                // max number of characters that can be set to be inserted
2976
// in Derby is 2Gb-1 (ie Integer.MAX_VALUE).
2977
// (e.g into a CLOB column).
2978
if (length > Integer.MAX_VALUE ) {
2979                    throw newSQLException(
2980                            SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
2981                            getColumnSQLType(columnIndex));
2982                }
2983
2984                // length is +ve. at this point, all checks for negative
2985
// length has already been done
2986
usableLength = (int) length;
2987                int truncationLength = 0;
2988
2989                // Currently long varchar does not allow for truncation of
2990
// trailing blanks. For char and varchar types, current
2991
// mechanism of materializing when using streams seems fine
2992
// given their max limits. This change is fix for DERBY-352:
2993
// Insert of clobs using streams should not materialize the
2994
// entire stream into memory
2995
// In case of clobs, the truncation of trailing blanks is
2996
// factored in when reading from the stream without
2997
// materializing the entire stream, and so the special casing
2998
// for clob below.
2999
if (getColumnType(columnIndex) == Types.CLOB) {
3000                    // Need column width to figure out if truncation is
3001
// needed
3002
int colWidth = getMaxColumnWidth(columnIndex);
3003
3004                    // It is possible that the length of the stream passed in
3005
// is greater than the column width, in which case the data
3006
// from the stream needs to be truncated.
3007
// usableLength is the length of the data from stream
3008
// that can be used which is min(colWidth,length) provided
3009
// length - colWidth has trailing blanks only
3010
if (usableLength > colWidth) {
3011                        truncationLength = usableLength - colWidth;
3012                        usableLength = colWidth;
3013                    }
3014                }
3015
3016                utfIn = new ReaderToUTF8Stream(reader, usableLength,
3017                        truncationLength, getColumnSQLType(columnIndex));
3018            } else {
3019                int colWidth = getMaxColumnWidth(columnIndex);
3020                utfIn = new ReaderToUTF8Stream(
3021                            reader, colWidth, getColumnSQLType(columnIndex));
3022            }
3023
3024            // NOTE: The length argument to setValue is not used. If that
3025
// changes, the value might also have to change.
3026
getDVDforColumnToBeUpdated(columnIndex, updateMethodName).setValue(
3027                    utfIn, (int) usableLength);
3028        } catch (StandardException t) {
3029            throw noStateChangeException(t);
3030        }
3031    }
3032
3033    /**
3034     * JDBC 2.0
3035     *
3036     * Update a column with an Object value.
3037     *
3038     * The updateXXX() methods are used to update column values in the current
3039     * row, or the insert row. The updateXXX() methods do not update the
3040     * underlying database, instead the updateRow() or insertRow() methods are
3041     * called to update the database.
3042     *
3043     * @param columnIndex
3044     * the first column is 1, the second is 2, ...
3045     * @param x
3046     * the new column value
3047     * @param scale
3048     * For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
3049     * this is the number of digits after the decimal. For all other
3050     * types this value will be ignored.
3051     * @exception SQLException
3052     * if a database-access error occurs
3053     */

3054    public void updateObject(int columnIndex, Object JavaDoc x, int scale)
3055            throws SQLException JavaDoc {
3056        updateObject(columnIndex, x);
3057        /*
3058        * If the parameter type is DECIMAL or NUMERIC, then
3059        * we need to set them to the passed scale.
3060        */

3061        int colType = getColumnType(columnIndex);
3062        if ((colType == Types.DECIMAL) || (colType == Types.NUMERIC)) {
3063            if (scale < 0)
3064                throw newSQLException(SQLState.BAD_SCALE_VALUE, new Integer JavaDoc(scale));
3065
3066            try {
3067                DataValueDescriptor value = updateRow.getColumn(columnIndex);
3068
3069                int origvaluelen = value.getLength();
3070                ((VariableSizeDataValue)
3071                        value).setWidth(VariableSizeDataValue.IGNORE_PRECISION,
3072                            scale,
3073                            false);
3074
3075            } catch (StandardException t) {
3076                throw EmbedResultSet.noStateChangeException(t);
3077            }
3078        }
3079    }
3080
3081    /**
3082     * JDBC 2.0
3083     *
3084     * Update a column with an Object value.
3085     *
3086     * The updateXXX() methods are used to update column values in the current
3087     * row, or the insert row. The updateXXX() methods do not update the
3088     * underlying database, instead the updateRow() or insertRow() methods are
3089     * called to update the database.
3090     *
3091     * @param columnIndex
3092     * the first column is 1, the second is 2, ...
3093     * @param x
3094     * the new column value
3095     * @exception SQLException
3096     * if a database-access error occurs
3097     */

3098    public void updateObject(int columnIndex, Object JavaDoc x) throws SQLException JavaDoc {
3099        checksBeforeUpdateXXX("updateObject", columnIndex);
3100        int colType = getColumnType(columnIndex);
3101        if (colType == org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT) {
3102            try {
3103                ((UserDataValue) getDVDforColumnToBeUpdated(columnIndex, "updateObject")).setValue(x);
3104                return;
3105            } catch (StandardException t) {
3106                throw noStateChangeException(t);
3107            }
3108        }
3109
3110        if (x == null) {
3111            updateNull(columnIndex);
3112            return;
3113        }
3114
3115        if (x instanceof String JavaDoc) {
3116            updateString(columnIndex, (String JavaDoc) x);
3117            return;
3118        }
3119
3120        if (x instanceof Boolean JavaDoc) {
3121            updateBoolean(columnIndex, ((Boolean JavaDoc) x).booleanValue());
3122            return;
3123        }
3124
3125        if (x instanceof Short JavaDoc) {
3126            updateShort(columnIndex, ((Short JavaDoc) x).shortValue());
3127            return;
3128        }
3129
3130        if (x instanceof Integer JavaDoc) {
3131            updateInt(columnIndex, ((Integer JavaDoc) x).intValue());
3132            return;
3133        }
3134
3135        if (x instanceof Long JavaDoc) {
3136            updateLong(columnIndex, ((Long JavaDoc) x).longValue());
3137            return;
3138        }
3139
3140        if (x instanceof Float JavaDoc) {
3141            updateFloat(columnIndex, ((Float JavaDoc) x).floatValue());
3142            return;
3143        }
3144
3145        if (x instanceof Double JavaDoc) {
3146            updateDouble(columnIndex, ((Double JavaDoc) x).doubleValue());
3147            return;
3148        }
3149
3150        if (x instanceof byte[]) {
3151            updateBytes(columnIndex, (byte[]) x);
3152            return;
3153        }
3154
3155        if (x instanceof Date JavaDoc) {
3156            updateDate(columnIndex, (Date JavaDoc) x);
3157            return;
3158        }
3159
3160        if (x instanceof Time JavaDoc) {
3161            updateTime(columnIndex, (Time JavaDoc) x);
3162            return;
3163        }
3164
3165        if (x instanceof Timestamp JavaDoc) {
3166            updateTimestamp(columnIndex, (Timestamp JavaDoc) x);
3167            return;
3168        }
3169
3170        if (x instanceof Blob JavaDoc) {
3171            updateBlob(columnIndex, (Blob JavaDoc) x);
3172            return;
3173        }
3174
3175        if (x instanceof Clob JavaDoc) {
3176            updateClob(columnIndex, (Clob JavaDoc) x);
3177            return;
3178        }
3179
3180        throw dataTypeConversion(columnIndex, x.getClass().getName());
3181    }
3182
3183    /**
3184     * JDBC 2.0
3185     *
3186     * Update a column with a null value.
3187     *
3188     * The updateXXX() methods are used to update column values in the current
3189     * row, or the insert row. The updateXXX() methods do not update the
3190     * underlying database, instead the updateRow() or insertRow() methods are
3191     * called to update the database.
3192     *
3193     * @param columnName
3194     * the name of the column
3195     * @exception SQLException
3196     * if a database-access error occurs
3197     */

3198    public void updateNull(String JavaDoc columnName) throws SQLException JavaDoc {
3199        checkIfClosed("updateNull");
3200        updateNull(findColumnName(columnName));
3201    }
3202
3203    /**
3204     * JDBC 2.0
3205     *
3206     * Update a column with a boolean value.
3207     *
3208     * The updateXXX() methods are used to update column values in the current
3209     * row, or the insert row. The updateXXX() methods do not update the
3210     * underlying database, instead the updateRow() or insertRow() methods are
3211     * called to update the database.
3212     *
3213     * @param columnName
3214     * the name of the column
3215     * @param x
3216     * the new column value
3217     * @exception SQLException
3218     * if a database-access error occurs
3219     */

3220    public void updateBoolean(String JavaDoc columnName, boolean x) throws SQLException JavaDoc {
3221        checkIfClosed("updateBoolean");
3222        updateBoolean(findColumnName(columnName), x);
3223    }
3224
3225    /**
3226     * JDBC 2.0
3227     *
3228     * Update a column with a byte value.
3229     *
3230     * The updateXXX() methods are used to update column values in the current
3231     * row, or the insert row. The updateXXX() methods do not update the
3232     * underlying database, instead the updateRow() or insertRow() methods are
3233     * called to update the database.
3234     *
3235     * @param columnName
3236     * the name of the column
3237     * @param x
3238     * the new column value
3239     * @exception SQLException
3240     * if a database-access error occurs
3241     */

3242    public void updateByte(String JavaDoc columnName, byte x) throws SQLException JavaDoc {
3243        checkIfClosed("updateByte");
3244        updateByte(findColumnName(columnName), x);
3245    }
3246
3247    /**
3248     * JDBC 2.0
3249     *
3250     * Update a column with a short value.
3251     *
3252     * The updateXXX() methods are used to update column values in the current
3253     * row, or the insert row. The updateXXX() methods do not update the
3254     * underlying database, instead the updateRow() or insertRow() methods are
3255     * called to update the database.
3256     *
3257     * @param columnName
3258     * the name of the column
3259     * @param x
3260     * the new column value
3261     * @exception SQLException
3262     * if a database-access error occurs
3263     */

3264    public void updateShort(String JavaDoc columnName, short x) throws SQLException JavaDoc {
3265        checkIfClosed("updateShort");
3266        updateShort(findColumnName(columnName), x);
3267    }
3268
3269    /**
3270     * JDBC 2.0
3271     *
3272     * Update a column with an integer value.
3273     *
3274     * The updateXXX() methods are used to update column values in the current
3275     * row, or the insert row. The updateXXX() methods do not update the
3276     * underlying database, instead the updateRow() or insertRow() methods are
3277     * called to update the database.
3278     *
3279     * @param columnName
3280     * the name of the column
3281     * @param x
3282     * the new column value
3283     * @exception SQLException
3284     * if a database-access error occurs
3285     */

3286    public void updateInt(String JavaDoc columnName, int x) throws SQLException JavaDoc {
3287        checkIfClosed("updateInt");
3288        updateInt(findColumnName(columnName), x);
3289    }
3290
3291    /**
3292     * JDBC 2.0
3293     *
3294     * Update a column with a long value.
3295     *
3296     * The updateXXX() methods are used to update column values in the current
3297     * row, or the insert row. The updateXXX() methods do not update the
3298     * underlying database, instead the updateRow() or insertRow() methods are
3299     * called to update the database.
3300     *
3301     * @param columnName
3302     * the name of the column
3303     * @param x
3304     * the new column value
3305     * @exception SQLException
3306     * if a database-access error occurs
3307     */

3308    public void updateLong(String JavaDoc columnName, long x) throws SQLException JavaDoc {
3309        checkIfClosed("updateLong");
3310        updateLong(findColumnName(columnName), x);
3311    }
3312
3313    /**
3314     * JDBC 2.0
3315     *
3316     * Update a column with a float value.
3317     *
3318     * The updateXXX() methods are used to update column values in the current
3319     * row, or the insert row. The updateXXX() methods do not update the
3320     * underlying database, instead the updateRow() or insertRow() methods are
3321     * called to update the database.
3322     *
3323     * @param columnName
3324     * the name of the column
3325     * @param x
3326     * the new column value
3327     * @exception SQLException
3328     * if a database-access error occurs
3329     */

3330    public void updateFloat(String JavaDoc columnName, float x) throws SQLException JavaDoc {
3331        checkIfClosed("updateFloat");
3332        updateFloat(findColumnName(columnName), x);
3333    }
3334
3335    /**
3336     * JDBC 2.0
3337     *
3338     * Update a column with a double value.
3339     *
3340     * The updateXXX() methods are used to update column values in the current
3341     * row, or the insert row. The updateXXX() methods do not update the
3342     * underlying database, instead the updateRow() or insertRow() methods are
3343     * called to update the database.
3344     *
3345     * @param columnName
3346     * the name of the column
3347     * @param x
3348     * the new column value
3349     * @exception SQLException
3350     * if a database-access error occurs
3351     */

3352    public void updateDouble(String JavaDoc columnName, double x) throws SQLException JavaDoc {
3353        checkIfClosed("updateDouble");
3354        updateDouble(findColumnName(columnName), x);
3355    }
3356
3357    /**
3358     * JDBC 2.0
3359     *
3360     * Update a column with a String value.
3361     *
3362     * The updateXXX() methods are used to update column values in the current
3363     * row, or the insert row. The updateXXX() methods do not update the
3364     * underlying database, instead the updateRow() or insertRow() methods are
3365     * called to update the database.
3366     *
3367     * @param columnName
3368     * the name of the column
3369     * @param x
3370     * the new column value
3371     * @exception SQLException
3372     * if a database-access error occurs
3373     */

3374    public void updateString(String JavaDoc columnName, String JavaDoc x) throws SQLException JavaDoc {
3375        checkIfClosed("updateString");
3376        updateString(findColumnName(columnName), x);
3377    }
3378
3379    /**
3380     * JDBC 2.0
3381     *
3382     * Update a column with a byte array value.
3383     *
3384     * The updateXXX() methods are used to update column values in the current
3385     * row, or the insert row. The updateXXX() methods do not update the
3386     * underlying database, instead the updateRow() or insertRow() methods are
3387     * called to update the database.
3388     *
3389     * @param columnName
3390     * the name of the column
3391     * @param x
3392     * the new column value
3393     * @exception SQLException
3394     * if a database-access error occurs
3395     */

3396    public void updateBytes(String JavaDoc columnName, byte x[]) throws SQLException JavaDoc {
3397        checkIfClosed("updateBytes");
3398        updateBytes(findColumnName(columnName), x);
3399    }
3400
3401    /**
3402     * JDBC 2.0
3403     *
3404     * Update a column with a Date value.
3405     *
3406     * The updateXXX() methods are used to update column values in the current
3407     * row, or the insert row. The updateXXX() methods do not update the
3408     * underlying database, instead the updateRow() or insertRow() methods are
3409     * called to update the database.
3410     *
3411     * @param columnName
3412     * the name of the column
3413     * @param x
3414     * the new column value
3415     * @exception SQLException
3416     * if a database-access error occurs
3417     */

3418    public void updateDate(String JavaDoc columnName, java.sql.Date JavaDoc x)
3419            throws SQLException JavaDoc {
3420        checkIfClosed("updateDate");
3421        updateDate(findColumnName(columnName), x);
3422    }
3423
3424    /**
3425     * JDBC 2.0
3426     *
3427     * Update a column with a Time value.
3428     *
3429     * The updateXXX() methods are used to update column values in the current
3430     * row, or the insert row. The updateXXX() methods do not update the
3431     * underlying database, instead the updateRow() or insertRow() methods are
3432     * called to update the database.
3433     *
3434     * @param columnName
3435     * the name of the column
3436     * @param x
3437     * the new column value
3438     * @exception SQLException
3439     * if a database-access error occurs
3440     */

3441    public void updateTime(String JavaDoc columnName, java.sql.Time JavaDoc x)
3442            throws SQLException JavaDoc {
3443        checkIfClosed("updateTime");
3444        updateTime(findColumnName(columnName), x);
3445    }
3446
3447    /**
3448     * JDBC 2.0
3449     *
3450     * Update a column with a Timestamp value.
3451     *
3452     * The updateXXX() methods are used to update column values in the current
3453     * row, or the insert row. The updateXXX() methods do not update the
3454     * underlying database, instead the updateRow() or insertRow() methods are
3455     * called to update the database.
3456     *
3457     * @param columnName
3458     * the name of the column
3459     * @param x
3460     * the new column value
3461     * @exception SQLException
3462     * if a database-access error occurs
3463     */

3464    public void updateTimestamp(String JavaDoc columnName, java.sql.Timestamp JavaDoc x)
3465            throws SQLException JavaDoc {
3466        checkIfClosed("updateTimestamp");
3467        updateTimestamp(findColumnName(columnName), x);
3468    }
3469
3470    /**
3471     * JDBC 2.0
3472     *
3473     * Update a column with an ascii stream value.
3474     *
3475     * The updateXXX() methods are used to update column values in the current
3476     * row, or the insert row. The updateXXX() methods do not update the
3477     * underlying database, instead the updateRow() or insertRow() methods are
3478     * called to update the database.
3479     *
3480     * @param columnName
3481     * the name of the column
3482     * @param x
3483     * the new column value
3484     * @param length
3485     * of the stream
3486     * @exception SQLException
3487     * if a database-access error occurs
3488     */

3489    public void updateAsciiStream(String JavaDoc columnName, java.io.InputStream JavaDoc x,
3490            int length) throws SQLException JavaDoc {
3491        checkIfClosed("updateAsciiStream");
3492        updateAsciiStream(findColumnName(columnName), x, length);
3493    }
3494
3495    /**
3496     * JDBC 2.0
3497     *
3498     * Update a column with a binary stream value.
3499     *
3500     * The updateXXX() methods are used to update column values in the current
3501     * row, or the insert row. The updateXXX() methods do not update the
3502     * underlying database, instead the updateRow() or insertRow() methods are
3503     * called to update the database.
3504     *
3505     * @param columnName
3506     * the name of the column
3507     * @param x
3508     * the new column value
3509     * @param length
3510     * of the stream
3511     * @exception SQLException
3512     * if a database-access error occurs
3513     */

3514    public void updateBinaryStream(String JavaDoc columnName, java.io.InputStream JavaDoc x,
3515            int length) throws SQLException JavaDoc {
3516        checkIfClosed("updateBinaryStream");
3517        updateBinaryStream(findColumnName(columnName), x, length);
3518    }
3519
3520    /**
3521     * JDBC 2.0
3522     *
3523     * Update a column with a character stream value.
3524     *
3525     * The updateXXX() methods are used to update column values in the current
3526     * row, or the insert row. The updateXXX() methods do not update the
3527     * underlying database, instead the updateRow() or insertRow() methods are
3528     * called to update the database.
3529     *
3530     * @param columnName
3531     * the name of the column
3532     * @param reader
3533     * the new column value
3534     * @param length
3535     * length of the stream
3536     * @exception SQLException
3537     * if a database-access error occurs
3538     */

3539    public void updateCharacterStream(String JavaDoc columnName, java.io.Reader JavaDoc reader,
3540            int length) throws SQLException JavaDoc {
3541        checkIfClosed("updateCharacterStream");
3542        updateCharacterStream(findColumnName(columnName), reader, length);
3543    }
3544
3545    /**
3546     * JDBC 2.0
3547     *
3548     * Update a column with an Object value.
3549     *
3550     * The updateXXX() methods are used to update column values in the
3551     * current row, or the insert row. The updateXXX() methods do not
3552     * update the underlying database, instead the updateRow() or insertRow()
3553     * methods are called to update the database.
3554     *
3555     * @param columnName the name of the column
3556     * @param x the new column value
3557     * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
3558     * this is the number of digits after the decimal. For all other
3559     * types this value will be ignored.
3560     * @exception SQLException if a database-access error occurs
3561     */

3562    public void updateObject(String JavaDoc columnName, Object JavaDoc x, int scale)
3563      throws SQLException JavaDoc {
3564        checkIfClosed("updateObject");
3565        updateObject(findColumnName(columnName), x, scale);
3566    }
3567
3568    /**
3569     * JDBC 2.0
3570     *
3571     * Update a column with an Object value.
3572     *
3573     * The updateXXX() methods are used to update column values in the current
3574     * row, or the insert row. The updateXXX() methods do not update the
3575     * underlying database, instead the updateRow() or insertRow() methods are
3576     * called to update the database.
3577     *
3578     * @param columnName
3579     * the name of the column
3580     * @param x
3581     * the new column value
3582     * @exception SQLException
3583     * if a database-access error occurs
3584     */

3585    public void updateObject(String JavaDoc columnName, Object JavaDoc x) throws SQLException JavaDoc {
3586        checkIfClosed("updateObject");
3587        updateObject(findColumnName(columnName), x);
3588    }
3589
3590    /**
3591     * JDBC 2.0
3592     *
3593     * Insert the contents of the insert row into the result set and the
3594     * database. Must be on the insert row when this method is called.
3595     *
3596     * @exception SQLException
3597     * if a database-access error occurs, if called when not on
3598     * the insert row, or if all non-nullable columns in the
3599     * insert row have not been given a value
3600     */

3601    public void insertRow() throws SQLException JavaDoc {
3602        synchronized (getConnectionSynchronization()) {
3603            checksBeforeInsert();
3604            setupContextStack();
3605            LanguageConnectionContext lcc = null;
3606            StatementContext statementContext = null;
3607            try {
3608                /*
3609                 * construct the insert statement
3610                 *
3611                 * If no values have been supplied for a column, it will be set
3612                 * to the column's default value, if any.
3613                 * If no default value had been defined, the default value of a
3614                 * nullable column is set to NULL.
3615                 */

3616
3617                boolean foundOneColumnAlready = false;
3618                StringBuffer JavaDoc insertSQL = new StringBuffer JavaDoc("INSERT INTO ");
3619                StringBuffer JavaDoc valuesSQL = new StringBuffer JavaDoc("VALUES (");
3620                CursorActivation activation = getEmbedConnection().
3621                        getLanguageConnection().lookupCursorActivation(getCursorName());
3622
3623                ExecCursorTableReference targetTable =
3624                        activation.getPreparedStatement().getTargetTable();
3625                // got the underlying (schema.)table name
3626
insertSQL.append(getFullBaseTableName(targetTable));
3627                ResultDescription rd = theResults.getResultDescription();
3628
3629                insertSQL.append(" (");
3630                // in this for loop we are constructing list of column-names
3631
// and values (?) ,... part of the insert sql
3632
for (int i=1; i<=rd.getColumnCount(); i++) {
3633                    if (foundOneColumnAlready) {
3634                        insertSQL.append(",");
3635                        valuesSQL.append(",");
3636                    }
3637                    // using quotes around the column name
3638
// to preserve case sensitivity
3639
insertSQL.append(quoteSqlIdentifier(
3640                            rd.getColumnDescriptor(i).getName()));
3641                    if (columnGotUpdated[i-1]) {
3642                        valuesSQL.append("?");
3643                    } else {
3644                        valuesSQL.append("DEFAULT");
3645                    }
3646                    foundOneColumnAlready = true;
3647                }
3648                insertSQL.append(") ");
3649                valuesSQL.append(") ");
3650                insertSQL.append(valuesSQL);
3651
3652                lcc = getEmbedConnection().getLanguageConnection();
3653
3654                // Context used for preparing, don't set any timeout (use 0)
3655
statementContext = lcc.pushStatementContext(
3656                        isAtomic,
3657                        false,
3658                        insertSQL.toString(),
3659                        null,
3660                        false,
3661                        0L);
3662                org.apache.derby.iapi.sql.PreparedStatement ps =
3663                        lcc.prepareInternalStatement(insertSQL.toString());
3664                Activation act = ps.getActivation(lcc, false);
3665
3666                // in this for loop we are assigning values for parameters
3667
//in sql constructed earlier VALUES (?, ..)
3668
for (int i=1, paramPosition=0; i<=rd.getColumnCount(); i++) {
3669                    // if the column got updated, do following
3670
if (columnGotUpdated[i-1]) {
3671                        act.getParameterValueSet().
3672                                getParameterForSet(paramPosition++).
3673                                setValue(updateRow.getColumn(i));
3674                    }
3675                }
3676                // Don't see any timeout when inserting rows (use 0)
3677
//execute the insert
3678
org.apache.derby.iapi.sql.ResultSet rs =
3679                        ps.execute(act, true, 0L);
3680                rs.close();
3681                rs.finish();
3682
3683                lcc.popStatementContext(statementContext, null);
3684            } catch (StandardException t) {
3685                throw closeOnTransactionError(t);
3686            } finally {
3687                if (statementContext != null)
3688                    lcc.popStatementContext(statementContext, null);
3689                restoreContextStack();
3690            }
3691        }
3692    }
3693
3694    /**
3695     * JDBC 2.0
3696     *
3697     * Update the underlying database with the new contents of the
3698     * current row. Cannot be called when on the insert row.
3699     *
3700     * @exception SQLException if a database-access error occurs, or
3701     * if called when on the insert row
3702     */

3703    public void updateRow() throws SQLException JavaDoc {
3704            synchronized (getConnectionSynchronization()) {
3705        checksBeforeUpdateOrDelete("updateRow", -1);
3706        
3707        // Check that the cursor is not positioned on insertRow
3708
checkNotOnInsertRow();
3709        
3710        setupContextStack();
3711        LanguageConnectionContext lcc = null;
3712        StatementContext statementContext = null;
3713        try {
3714            if (currentRowHasBeenUpdated == false) //nothing got updated on this row
3715
return; //nothing to do since no updates were made to this row
3716

3717            //now construct the update where current of sql
3718
boolean foundOneColumnAlready = false;
3719            StringBuffer JavaDoc updateWhereCurrentOfSQL = new StringBuffer JavaDoc("UPDATE ");
3720            CursorActivation activation = getEmbedConnection().getLanguageConnection().lookupCursorActivation(getCursorName());
3721
3722
3723            ExecCursorTableReference targetTable = activation.getPreparedStatement().getTargetTable();
3724            updateWhereCurrentOfSQL.append(getFullBaseTableName(targetTable));//got the underlying (schema.)table name
3725
updateWhereCurrentOfSQL.append(" SET ");
3726            ResultDescription rd = theResults.getResultDescription();
3727
3728            for (int i=1; i<=rd.getColumnCount(); i++) { //in this for loop we are constructing columnname=?,... part of the update sql
3729
if (columnGotUpdated[i-1]) { //if the column got updated, do following
3730
if (foundOneColumnAlready)
3731                        updateWhereCurrentOfSQL.append(",");
3732                    //using quotes around the column name to preserve case sensitivity
3733
updateWhereCurrentOfSQL.append(quoteSqlIdentifier(
3734                            rd.getColumnDescriptor(i).getName()) + "=?");
3735                    foundOneColumnAlready = true;
3736                }
3737            }
3738            //using quotes around the cursor name to preserve case sensitivity
3739
updateWhereCurrentOfSQL.append(" WHERE CURRENT OF " +
3740                    quoteSqlIdentifier(getCursorName()));
3741            lcc = getEmbedConnection().getLanguageConnection();
3742
3743            // Context used for preparing, don't set any timeout (use 0)
3744
statementContext = lcc.pushStatementContext(isAtomic, false, updateWhereCurrentOfSQL.toString(), null, false, 0L);
3745            org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(updateWhereCurrentOfSQL.toString());
3746            Activation act = ps.getActivation(lcc, false);
3747
3748            //in this for loop we are assigning values for parameters in sql constructed earlier with columnname=?,...
3749
for (int i=1, paramPosition=0; i<=rd.getColumnCount(); i++) {
3750                if (columnGotUpdated[i-1]) //if the column got updated, do following
3751
act.getParameterValueSet().getParameterForSet(paramPosition++).setValue(updateRow.getColumn(i));
3752            }
3753            // Don't set any timeout when updating rows (use 0)
3754
// Execute the update where current of sql.
3755
org.apache.derby.iapi.sql.ResultSet rs = ps.execute(act, true, 0L);
3756            SQLWarning JavaDoc w = act.getWarnings();
3757            if (w != null) {
3758                addWarning(w);
3759            }
3760            rs.close();
3761            rs.finish();
3762            //For forward only resultsets, after a update, the ResultSet will be positioned right before the next row.
3763
if (getType() == TYPE_FORWARD_ONLY) {
3764                currentRow.setRowArray(null);
3765            } else {
3766                movePosition(RELATIVE, 0, "relative");
3767            }
3768            lcc.popStatementContext(statementContext, null);
3769        } catch (StandardException t) {
3770            throw closeOnTransactionError(t);
3771        } finally {
3772            if (statementContext != null)
3773                lcc.popStatementContext(statementContext, null);
3774            restoreContextStack();
3775            initializeUpdateRowModifiers();
3776        }
3777            }
3778    }
3779
3780    /**
3781     * JDBC 2.0
3782     *
3783     * Delete the current row from the result set and the underlying
3784     * database. Cannot be called when on the insert row.
3785     *
3786     * @exception SQLException if a database-access error occurs, or if
3787     * called when on the insert row.
3788     */

3789    public void deleteRow() throws SQLException JavaDoc {
3790        synchronized (getConnectionSynchronization()) {
3791            checksBeforeUpdateOrDelete("deleteRow", -1);
3792        
3793            // Check that the cursor is not positioned on insertRow
3794
checkNotOnInsertRow();
3795
3796            setupContextStack();
3797            
3798            LanguageConnectionContext lcc = null;
3799            StatementContext statementContext = null;
3800            
3801            //now construct the delete where current of sql
3802
try {
3803                StringBuffer JavaDoc deleteWhereCurrentOfSQL = new StringBuffer JavaDoc("DELETE FROM ");
3804                CursorActivation activation = getEmbedConnection().getLanguageConnection().lookupCursorActivation(getCursorName());
3805                deleteWhereCurrentOfSQL.append(getFullBaseTableName(activation.getPreparedStatement().getTargetTable()));//get the underlying (schema.)table name
3806
//using quotes around the cursor name to preserve case sensitivity
3807
deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF " +
3808                        quoteSqlIdentifier(getCursorName()));
3809
3810                lcc = getEmbedConnection().getLanguageConnection();
3811                
3812                // Context used for preparing, don't set any timeout (use 0)
3813
statementContext = lcc.pushStatementContext(isAtomic, false, deleteWhereCurrentOfSQL.toString(), null, false, 0L);
3814                org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(deleteWhereCurrentOfSQL.toString());
3815                // Get activation, so that we can get the warning from it
3816
Activation act = ps.getActivation(lcc, false);
3817                // Don't set any timeout when deleting rows (use 0)
3818
//execute delete where current of sql
3819
org.apache.derby.iapi.sql.ResultSet rs =
3820                        ps.execute(act, true, 0L);
3821                SQLWarning JavaDoc w = act.getWarnings();
3822                if (w != null) {
3823                    addWarning(w);
3824                }
3825                rs.close();
3826                rs.finish();
3827                //After a delete, the ResultSet will be positioned right before
3828
//the next row.
3829
currentRow.setRowArray(null);
3830                lcc.popStatementContext(statementContext, null);
3831            } catch (StandardException t) {
3832                    throw closeOnTransactionError(t);
3833            } finally {
3834                if (statementContext != null)
3835                    lcc.popStatementContext(statementContext, null);
3836                restoreContextStack();
3837                initializeUpdateRowModifiers();
3838            }
3839        }
3840    }
3841
3842    private String JavaDoc getFullBaseTableName(ExecCursorTableReference targetTable) {
3843        //using quotes to preserve case sensitivity
3844
if (targetTable.getSchemaName() != null)
3845            return quoteSqlIdentifier(targetTable.getSchemaName()) + "." +
3846                    quoteSqlIdentifier(targetTable.getBaseName());
3847        else
3848            return quoteSqlIdentifier(targetTable.getBaseName());
3849    }
3850
3851    private String JavaDoc quoteSqlIdentifier(String JavaDoc orgValue) {
3852        int i = 0, start = 0;
3853        String JavaDoc retValue = "";
3854        while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
3855            retValue += orgValue.substring(start, i) + "\"";
3856            start = i;
3857        }
3858        retValue += orgValue.substring(start, orgValue.length());
3859        return "\"" + retValue + "\"";
3860    }
3861    
3862    /**
3863     * JDBC 2.0
3864     *
3865     * Refresh the value of the current row with its current value in the
3866     * database. Cannot be called when on the insert row.
3867     *
3868     * The refreshRow() method provides a way for an application to explicitly
3869     * tell the JDBC driver to refetch a row(s) from the database. An
3870     * application may want to call refreshRow() when caching or prefetching is
3871     * being done by the JDBC driver to fetch the latest value of a row from the
3872     * database. The JDBC driver may actually refresh multiple rows at once if
3873     * the fetch size is greater than one.
3874     *
3875     * All values are refetched subject to the transaction isolation level and
3876     * cursor sensitivity. If refreshRow() is called after calling updateXXX(),
3877     * but before calling updateRow() then the updates made to the row are lost.
3878     * Calling refreshRow() frequently will likely slow performance.
3879     *
3880     * @exception SQLException
3881     * if a database-access error occurs, or if called when on
3882     * the insert row.
3883     */

3884    public void refreshRow() throws SQLException JavaDoc {
3885        throw Util.notImplemented();
3886    }
3887
3888    /**
3889     * JDBC 2.0
3890     *
3891     * The cancelRowUpdates() method may be called after calling an
3892     * updateXXX() method(s) and before calling updateRow() to rollback
3893     * the updates made to a row. If no updates have been made or
3894     * updateRow() has already been called, then this method has no
3895     * effect.
3896     *
3897     * @exception SQLException if a database-access error occurs, or if
3898     * called when on the insert row.
3899     *
3900     */

3901    public void cancelRowUpdates () throws SQLException JavaDoc {
3902        checksBeforeUpdateOrDelete("cancelRowUpdates", -1);
3903        
3904        checkNotOnInsertRow();
3905
3906        initializeUpdateRowModifiers();
3907    }
3908
3909    /**
3910     * JDBC 2.0
3911     *
3912     * Move to the insert row. The current cursor position is remembered while
3913     * the cursor is positioned on the insert row.
3914     *
3915     * The insert row is a special row associated with an updatable result set.
3916     * It is essentially a buffer where a new row may be constructed by calling
3917     * the updateXXX() methods prior to inserting the row into the result set.
3918     *
3919     * Only the updateXXX(), getXXX(), and insertRow() methods may be called
3920     * when the cursor is on the insert row. All of the columns in a result set
3921     * must be given a value each time this method is called before calling
3922     * insertRow(). UpdateXXX()must be called before getXXX() on a column.
3923     *
3924     * @exception SQLException
3925     * if a database-access error occurs, or the result set is
3926     * not updatable
3927     */

3928    public void moveToInsertRow() throws SQLException JavaDoc {
3929        checkExecIfClosed("moveToInsertRow");
3930
3931        // if not updatable resultset, then throw exception
3932
checkUpdatableCursor("moveToInsertRow");
3933
3934        synchronized (getConnectionSynchronization()) {
3935            try {
3936                // initialize state corresponding to insertRow/updateRow impl.
3937
initializeUpdateRowModifiers();
3938                isOnInsertRow = true;
3939                
3940                for (int i=1; i <= columnGotUpdated.length; i++) {
3941                    updateRow.setColumn(i,
3942                        resultDescription.getColumnDescriptor(i).getType().getNull());
3943                }
3944            } catch (Throwable JavaDoc ex) {
3945                handleException(ex);
3946            }
3947        }
3948    }
3949
3950    /**
3951     * JDBC 2.0
3952     *
3953     * Move the cursor to the remembered cursor position, usually the current
3954     * row. Has no effect unless the cursor is on the insert row.
3955     *
3956     * @exception SQLException
3957     * if a database-access error occurs, or the result set is
3958     * not updatable
3959     */

3960    public void moveToCurrentRow() throws SQLException JavaDoc {
3961        checkExecIfClosed("moveToCurrentRow");
3962
3963        // if not updatable resultset, then throw exception
3964
checkUpdatableCursor("moveToCurrentRow");
3965
3966        synchronized (getConnectionSynchronization()) {
3967            try {
3968
3969                if (isOnInsertRow) {
3970                    // initialize state corresponding to insertRow/updateRow impl.
3971
initializeUpdateRowModifiers();
3972
3973                    isOnInsertRow = false;
3974                }
3975            } catch (Throwable JavaDoc ex) {
3976                handleException(ex);
3977            }
3978        }
3979    }
3980
3981    /**
3982     * JDBC 2.0
3983     *
3984     * Get a BLOB column.
3985     *
3986     * @param columnIndex the first column is 1, the second is 2, ...
3987     * @return an object representing a BLOB
3988     */

3989    public Blob JavaDoc getBlob(int columnIndex) throws SQLException JavaDoc {
3990
3991        closeCurrentStream(); // closing currentStream does not depend on the
3992
// underlying connection. Do this outside of
3993
// the connection synchronization.
3994

3995        checkIfClosed("getBlob"); // checking result set closure does not depend
3996
// on the underlying connection. Do this
3997
// outside of the connection synchronization.
3998

3999        synchronized (getConnectionSynchronization()) {
4000            int colType = getColumnType(columnIndex);
4001
4002            // DB2, only allow getBlob on a BLOB column.
4003
if (colType != Types.BLOB)
4004                throw dataTypeConversion("java.sql.Blob", columnIndex);
4005
4006            boolean pushStack = false;
4007            try {
4008                DataValueDescriptor dvd = getColumn(columnIndex);
4009
4010                if (wasNull = dvd.isNull())
4011                    return null;
4012
4013                // should set up a context stack if we have a long column,
4014
// since a blob may keep a pointer to a long column in the
4015
// database
4016
if (dvd.getStream() != null)
4017                    pushStack = true;
4018
4019                if (pushStack)
4020                    setupContextStack();
4021
4022                return new EmbedBlob(dvd, getEmbedConnection());
4023            } catch (Throwable JavaDoc t) {
4024                throw handleException(t);
4025            } finally {
4026                if (pushStack)
4027                    restoreContextStack();
4028            }
4029        }
4030    }
4031
4032    /**
4033     * JDBC 2.0
4034     *
4035     * Get a CLOB column.
4036     *
4037     * @param columnIndex the first column is 1, the second is 2, ...
4038     * @return an object representing a CLOB
4039     */

4040    public final Clob JavaDoc getClob(int columnIndex) throws SQLException JavaDoc {
4041
4042        closeCurrentStream(); // closing currentStream does not depend on the
4043
// underlying connection. Do this outside of
4044
// the connection synchronization.
4045

4046        checkIfClosed("getClob"); // checking result set closure does not depend
4047
// on the underlying connection. Do this
4048
// outside of the connection synchronization.
4049

4050        synchronized (getConnectionSynchronization()) {
4051            int colType = getColumnType(columnIndex);
4052
4053            // DB2:, only allow getClob on a CLOB column.
4054
if (colType != Types.CLOB)
4055                throw dataTypeConversion("java.sql.Clob", columnIndex);
4056
4057            boolean pushStack = false;
4058            try {
4059
4060                DataValueDescriptor dvd = getColumn(columnIndex);
4061
4062                if (wasNull = dvd.isNull())
4063                    return null;
4064
4065                // should set up a context stack if we have a long column,
4066
// since a blob may keep a pointer to a long column in the
4067
// database
4068
if (dvd.getStream() != null)
4069                    pushStack = true;
4070
4071                if (pushStack)
4072                    setupContextStack();
4073
4074                return new EmbedClob(dvd, getEmbedConnection());
4075            } catch (Throwable JavaDoc t) {
4076                throw handleException(t);
4077            } finally {
4078                if (pushStack)
4079                    restoreContextStack();
4080            }
4081        }
4082    }
4083    
4084    /**
4085     * JDBC 2.0
4086     *
4087     * Get a BLOB column.
4088     *
4089     * @param columnName the column name
4090     * @return an object representing a BLOB
4091     */

4092    public final Blob JavaDoc getBlob(String JavaDoc columnName) throws SQLException JavaDoc {
4093        checkIfClosed("getBlob");
4094        return (getBlob(findColumnName(columnName)));
4095    }
4096
4097    /**
4098     * JDBC 2.0
4099     *
4100     * Get a CLOB column.
4101     *
4102     * @param columnName the column name
4103     * @return an object representing a CLOB
4104     * @exception SQLException
4105     * Feature not implemented for now.
4106     */

4107    public final Clob JavaDoc getClob(String JavaDoc columnName) throws SQLException JavaDoc {
4108        checkIfClosed("getClob");
4109        return (getClob(findColumnName(columnName)));
4110    }
4111
4112    
4113    /**
4114     * JDBC 3.0
4115     *
4116     * Updates the designated column with a java.sql.Blob value. The updater
4117     * methods are used to update column values in the current row or the insert
4118     * row. The updater methods do not update the underlying database; instead
4119     * the updateRow or insertRow methods are called to update the database.
4120     *
4121     * @param columnIndex -
4122     * the first column is 1, the second is 2
4123     * @param x -
4124     * the new column value
4125     * @exception SQLException
4126     * Feature not implemented for now.
4127     */

4128    public void updateBlob(int columnIndex, Blob JavaDoc x) throws SQLException JavaDoc {
4129        checksBeforeUpdateXXX("updateBlob", columnIndex);
4130        int colType = getColumnType(columnIndex);
4131        if (colType != Types.BLOB)
4132            throw dataTypeConversion(columnIndex, "java.sql.Blob");
4133
4134        if (x == null)
4135            updateNull(columnIndex);
4136        else {
4137            long length = x.length();
4138            updateBinaryStreamInternal(columnIndex, x.getBinaryStream(), false,
4139                                       length, "updateBlob");
4140        }
4141    }
4142
4143    /**
4144     * JDBC 3.0
4145     *
4146     * Updates the designated column with a java.sql.Blob value. The updater
4147     * methods are used to update column values in the current row or the insert
4148     * row. The updater methods do not update the underlying database; instead
4149     * the updateRow or insertRow methods are called to update the database.
4150     *
4151     * @param columnName -
4152     * the SQL name of the column
4153     * @param x -
4154     * the new column value
4155     * @exception SQLException
4156     * Feature not implemented for now.
4157     */

4158    public void updateBlob(String JavaDoc columnName, Blob JavaDoc x) throws SQLException JavaDoc {
4159        checkIfClosed("updateBlob");
4160        updateBlob(findColumnName(columnName), x);
4161    }
4162
4163    /**
4164     * JDBC 3.0
4165     *
4166     * Updates the designated column with a java.sql.Clob value. The updater
4167     * methods are used to update column values in the current row or the insert
4168     * row. The updater methods do not update the underlying database; instead
4169     * the updateRow or insertRow methods are called to update the database.
4170     *
4171     * @param columnIndex -
4172     * the first column is 1, the second is 2
4173     * @param x -
4174     * the new column value
4175     * @exception SQLException
4176     * Feature not implemented for now.
4177     */

4178    public void updateClob(int columnIndex, Clob JavaDoc x) throws SQLException JavaDoc {
4179        checksBeforeUpdateXXX("updateClob", columnIndex);
4180        int colType = getColumnType(columnIndex);
4181        if (colType != Types.CLOB)
4182            throw dataTypeConversion(columnIndex, "java.sql.Clob");
4183
4184        if (x == null)
4185        {
4186            updateNull(columnIndex);
4187        }
4188        else
4189        {
4190            
4191            long length = x.length();
4192
4193            updateCharacterStreamInternal(
4194                columnIndex, x.getCharacterStream(), false, length,
4195                "updateClob");
4196        }
4197    }
4198
4199    /**
4200     * JDBC 3.0
4201     *
4202     * Updates the designated column with a java.sql.Clob value. The updater
4203     * methods are used to update column values in the current row or the insert
4204     * row. The updater methods do not update the underlying database; instead
4205     * the updateRow or insertRow methods are called to update the database.
4206     *
4207     * @param columnName -
4208     * the SQL name of the column
4209     * @param x -
4210     * the new column value
4211     * @exception SQLException
4212     * Feature not implemented for now.
4213     */

4214    public void updateClob(String JavaDoc columnName, Clob JavaDoc x) throws SQLException JavaDoc {
4215        checkIfClosed("updateClob");
4216        updateClob(findColumnName(columnName), x);
4217    }
4218    
4219    
4220    /*
4221     * * End of JDBC public methods.
4222     */

4223
4224    /**
4225     * Map a Resultset column name to a ResultSet column index.
4226     *
4227     * @param columnName
4228     * the name of the column
4229     * @return the column index
4230     * @exception SQLException
4231     * thrown on failure.
4232     */

4233    protected int findColumnName(String JavaDoc columnName)
4234                        throws SQLException JavaDoc {
4235        // n.b. if we went through the JDBC interface,
4236
// there is a caching implementation in the JDBC doc
4237
// (appendix C). But we go through our own info, for now.
4238

4239        if (columnName == null)
4240            throw newSQLException(SQLState.NULL_COLUMN_NAME);
4241        
4242        final Map JavaDoc workMap;
4243                           
4244        synchronized (this) {
4245            if (columnNameMap==null) {
4246                // updateXXX and getXXX methods are case insensitive and the
4247
// first column should be returned. The loop goes backward to
4248
// create a map which preserves this property.
4249
columnNameMap = new HashMap JavaDoc();
4250                for (int i = resultDescription.getColumnCount(); i>=1; i--) {
4251                    
4252                    final String JavaDoc key = StringUtil.
4253                        SQLToUpperCase(resultDescription.
4254                            getColumnDescriptor(i).getName());
4255                    
4256                    final Integer JavaDoc value = ReuseFactory.getInteger(i);
4257                    
4258                    columnNameMap.put(key, value);
4259                }
4260            }
4261            workMap = columnNameMap;
4262        }
4263        
4264        Integer JavaDoc val = (Integer JavaDoc) workMap.get(columnName);
4265        if (val==null) {
4266            val = (Integer JavaDoc) workMap.get(StringUtil.SQLToUpperCase(columnName));
4267        }
4268        if (val==null) {
4269            throw newSQLException(SQLState.COLUMN_NOT_FOUND, columnName);
4270        } else {
4271            return val.intValue();
4272        }
4273    }
4274
4275
4276
4277    //
4278
// methods to be overridden in subimplementations
4279
// that want to stay within their subimplementation.
4280
//
4281
protected EmbedResultSetMetaData newEmbedResultSetMetaData(ResultDescription resultDesc) {
4282        return factory.newEmbedResultSetMetaData(resultDesc.getColumnInfo());
4283    }
4284
4285    /**
4286     * Documented behaviour for streams is that they are implicitly closed on
4287     * the next get*() method call.
4288     */

4289    private final void closeCurrentStream() {
4290
4291        if (currentStream != null) {
4292            try {
4293                // 99% of the time, the stream is already closed.
4294
synchronized(this)
4295                {
4296                    if (currentStream != null) {
4297                        if (currentStream instanceof java.io.Reader JavaDoc)
4298                            ((java.io.Reader JavaDoc) currentStream).close();
4299                        else
4300                            ((java.io.InputStream JavaDoc) currentStream).close();
4301                    }
4302                }
4303            } catch (IOException JavaDoc ioe) {
4304                // just ignore, caller has already read the data they require
4305
} finally {
4306                currentStream = null;
4307            }
4308        }
4309    }
4310
4311    /**
4312     * Throw an exception if this ResultSet is closed.
4313     *
4314     * @param operation The operation the caller is trying to perform
4315     *
4316     * @exception SQLException Thrown if this ResultSet is closed.
4317     */

4318    final void checkIfClosed(String JavaDoc operation) throws SQLException JavaDoc {
4319        if (isClosed) {
4320            throw newSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, operation);
4321        }
4322    }
4323
4324    /**
4325     * Throw an exception if this ResultSet is closed or its
4326     * Connection has been closed. If the ResultSet has not
4327     * been explictly closed but the Connection is closed,
4328     * then this ResultSet will be marked as closed.
4329     */

4330    final void checkExecIfClosed(String JavaDoc operation) throws SQLException JavaDoc {
4331        
4332        checkIfClosed(operation);
4333
4334        java.sql.Connection JavaDoc appConn = getEmbedConnection().getApplicationConnection();
4335
4336        // Currently disconnected, i.e. a detached gobal transaction
4337
if (appConn == null)
4338            throw Util.noCurrentConnection();
4339            
4340        if (appConn.isClosed()) {
4341            closeCurrentStream();
4342            isClosed = true;
4343            throw Util.noCurrentConnection();
4344        }
4345    }
4346    
4347    /**
4348     * Try to see if we can fish the SQL Statement out of the local statement.
4349     * @return null if we cannot figure out what SQL Statement is currently
4350     * executing
4351     */

4352    protected String JavaDoc getSQLText()
4353    {
4354        if (stmt == null)
4355            return null;
4356
4357        return stmt.getSQLText();
4358    }
4359
4360    /**
4361     * Try to see if we can fish the pvs out of the local statement.
4362     * @return null if we cannot figure out what parameter value set is currently
4363     * using
4364     */

4365    protected ParameterValueSet getParameterValueSet()
4366    {
4367        if (stmt == null)
4368            return null;
4369
4370        return stmt.getParameterValueSet();
4371    }
4372
4373    private static boolean isMaxFieldSizeType(int colType){
4374        return (colType == Types.BINARY || colType == Types.VARBINARY ||
4375            colType == Types.LONGVARBINARY || colType == Types.CHAR ||
4376            colType == Types.VARCHAR || colType == Types.LONGVARCHAR);
4377    }
4378    /*
4379     * close result set if we have a transaction level error
4380     */

4381    final SQLException JavaDoc closeOnTransactionError(Throwable JavaDoc thrownException) throws SQLException JavaDoc
4382    {
4383        SQLException JavaDoc sqle = handleException(thrownException);
4384        if (thrownException instanceof StandardException)
4385        {
4386            StandardException se = (StandardException) thrownException;
4387            int severity = se.getSeverity();
4388            if (severity == ExceptionSeverity.TRANSACTION_SEVERITY)
4389            {
4390                try {
4391                    close();
4392                } catch (Throwable JavaDoc t) {
4393                    SQLException JavaDoc top = handleException(t);
4394                    top.setNextException(sqle);
4395                    sqle = top;
4396                }
4397            }
4398        }
4399
4400        return sqle;
4401    }
4402
4403
4404    /**
4405        Get the column value for a getXXX() call.
4406        This method:
4407        <UL>
4408        <LI> Closes the current stream (as per JDBC)
4409        <LI> Throws a SQLException if the result set is closed
4410        <LI> Throws a SQLException if the ResultSet is not on a row
4411        <LI> Throws a SQLException if the columnIndex is out of range
4412        <LI> Returns the DataValueDescriptor for the column.
4413        </UL>
4414    */

4415    protected final DataValueDescriptor getColumn(int columnIndex)
4416        throws SQLException JavaDoc, StandardException {
4417
4418      closeCurrentStream();
4419
4420      if (columnIndex < 1 || columnIndex > currentRow.nColumns()) {
4421          throw newSQLException(SQLState.COLUMN_NOT_FOUND,
4422                                new Integer JavaDoc(columnIndex));
4423      }
4424      if (isOnInsertRow || currentRowHasBeenUpdated && columnGotUpdated[columnIndex -1]) {
4425          return updateRow.getColumn(columnIndex);
4426      } else {
4427          checkOnRow(); // make sure there's a row
4428
return currentRow.getColumn(columnIndex);
4429      }
4430    }
4431
4432
4433    /**
4434        An exception on many method calls to JDBC objects does not change the state
4435        of the transaction or statement, or even the underlying object. This method
4436        simply wraps the excecption in a SQLException. Examples are:
4437        <UL>
4438        <LI> getXXX() calls on ResultSet - ResultSet is not closed.
4439        <LI> setXXX() calls on PreparedStatement - ResultSet is not closed.
4440        </UL>
4441        In addition these exceptions must not call higher level objects to
4442        be closed (e.g. when executing a server side Java procedure). See bug 4397
4443
4444    */

4445    static final SQLException JavaDoc noStateChangeException(Throwable JavaDoc thrownException) {
4446
4447        // Any exception on a setXXX/getXXX method does not close
4448
// the ResultSet or the Statement. So we only need
4449
// to convert the exception to a SQLException.
4450

4451        return TransactionResourceImpl.wrapInSQLException((SQLException JavaDoc) null, thrownException);
4452
4453    }
4454
4455    /**
4456        A dynamic result set was created in a procedure by a nested connection.
4457        Once the procedure returns, there is a good chance that connection is closed,
4458        so we re-attach the result set to the connection of the statement the called
4459        the procedure, which will be still open.
4460    */

4461    void setDynamicResultSet(EmbedStatement owningStmt) {
4462
4463        this.owningStmt = owningStmt;
4464        this.localConn = owningStmt.getEmbedConnection();
4465    }
4466
4467    /*
4468    ** Comparable (for ordering dynamic result sets from procedures)
4469    */

4470
4471    public final int compareTo(Object JavaDoc other) {
4472
4473        EmbedResultSet olrs = (EmbedResultSet) other;
4474
4475        return order - olrs.order;
4476
4477    }
4478    
4479    /**
4480     * Checks if the result set has a scrollable cursor.
4481     *
4482     * @param methodName name of the method which requests the check
4483     * @exception SQLException if the result set is closed or its type
4484     * is <code>TYPE_FORWARD_ONLY</code>
4485     */

4486    private void checkScrollCursor(String JavaDoc methodName) throws SQLException JavaDoc {
4487        checkIfClosed(methodName);
4488        if (stmt.getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY)
4489            throw Util
4490                    .newEmbedSQLException(
4491                            SQLState.NOT_ON_FORWARD_ONLY_CURSOR,
4492                            new Object JavaDoc[] { methodName },
4493                            StandardException
4494                                    .getSeverityFromIdentifier(SQLState.NOT_ON_FORWARD_ONLY_CURSOR));
4495    }
4496    
4497    private void checkUpdatableCursor(String JavaDoc operation) throws SQLException JavaDoc {
4498        if (getConcurrency() != JDBC20Translation.CONCUR_UPDATABLE) {
4499            throw Util.generateCsSQLException(
4500                    SQLState.UPDATABLE_RESULTSET_API_DISALLOWED,
4501                    operation);
4502        }
4503    }
4504
4505    
4506    private boolean checkRowPosition(int position, String JavaDoc positionText)
4507            throws SQLException JavaDoc {
4508        // beforeFirst is only allowed on scroll cursors
4509
checkScrollCursor(positionText);
4510
4511        synchronized (getConnectionSynchronization()) {
4512            setupContextStack();
4513            try {
4514                try {
4515
4516                    /*
4517                     * Push and pop a StatementContext around a next call so
4518                     * that the ResultSet will get correctly closed down on an
4519                     * error. (Cache the LanguageConnectionContext)
4520                     */

4521                    LanguageConnectionContext lcc = getEmbedConnection()
4522                            .getLanguageConnection();
4523                    // No timeout for this operation (use 0)
4524
StatementContext statementContext =
4525                        lcc.pushStatementContext(isAtomic,
4526                         concurrencyOfThisResultSet==JDBC20Translation.CONCUR_READ_ONLY,
4527                         getSQLText(),
4528                                                 getParameterValueSet(),
4529                                                 false, 0L);
4530
4531                    boolean result = theResults.checkRowPosition(position);
4532
4533                    lcc.popStatementContext(statementContext, null);
4534
4535                    return result;
4536
4537                } catch (Throwable JavaDoc t) {
4538                    /*
4539                     * Need to close the result set here because the error might
4540                     * cause us to lose the current connection if this is an XA
4541                     * connection and we won't be able to do the close later
4542                     */

4543                    throw closeOnTransactionError(t);
4544                }
4545
4546            } finally {
4547                restoreContextStack();
4548            }
4549        }
4550    }
4551    /**
4552     * * Is this result set from a select for update statement?
4553     */

4554    public final boolean isForUpdate()
4555    {
4556        if (theResults instanceof NoPutResultSet)
4557            return ((NoPutResultSet) theResults).isForUpdate();
4558        return false;
4559    }
4560    
4561    final String JavaDoc getColumnSQLType(int column)
4562    {
4563        return resultDescription.getColumnDescriptor(column)
4564                       .getType().getTypeId().getSQLTypeName();
4565    }
4566
4567    /**
4568     * Return the user-defined maximum size of the column.
4569     *
4570     * Note that this may be different from the maximum column size Derby is
4571     * able, or allowed, to handle (called 'maximum maximum length').
4572     *
4573     * @param columnIndex the 1-based index of the column
4574     * @return the maximum length of the column
4575     */

4576    private final int getMaxColumnWidth(int columnIndex) {
4577        return resultDescription.getColumnDescriptor(columnIndex).
4578                    getType().getMaximumWidth();
4579    }
4580
4581    private final SQLException JavaDoc dataTypeConversion(String JavaDoc targetType, int column) {
4582        return newSQLException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, targetType,
4583                getColumnSQLType(column));
4584    }
4585
4586    private final SQLException JavaDoc dataTypeConversion(int column, String JavaDoc targetType) {
4587        return newSQLException(SQLState.LANG_DATA_TYPE_GET_MISMATCH,
4588                getColumnSQLType(column), targetType);
4589    }
4590    
4591    /**
4592     * Mark a column as already having a stream accessed from it.
4593     * If the stream was already accessed, then throw an exception.
4594     * @param columnIndex
4595     * @throws SQLException
4596     */

4597    final void useStream(int columnIndex) throws SQLException JavaDoc {
4598        
4599        if (streamUsedFlags == null)
4600            streamUsedFlags = new boolean[getMetaData().getColumnCount()];
4601        
4602        else if (streamUsedFlags[columnIndex - 1])
4603            throw newSQLException(SQLState.LANG_STREAM_RETRIEVED_ALREADY);
4604        
4605        streamUsedFlags[columnIndex - 1] = true;
4606    }
4607
4608    /**
4609     * JDBC 4.0
4610     *
4611     * <p>
4612     * Checks whether this <code>ResultSet</code> object has been
4613     * closed, either automatically or because <code>close()</code>
4614     * has been called.
4615     *
4616     * @return <code>true</code> if the <code>ResultSet</code> is
4617     * closed, <code>false</code> otherwise
4618     * @exception SQLException if a database error occurs
4619     */

4620    public final boolean isClosed() throws SQLException JavaDoc {
4621        if (isClosed) return true;
4622        try {
4623            // isClosed is not updated when EmbedConnection.close() is
4624
// called, so we need to check the status of the
4625
// connection
4626
checkExecIfClosed("");
4627            return false;
4628        } catch (SQLException JavaDoc sqle) {
4629            return isClosed;
4630        }
4631    }
4632     
4633     /**
4634      * Adds a warning to the end of the warning chain.
4635      *
4636      * @param w The warning to add to the warning chain.
4637      */

4638     private void addWarning(SQLWarning JavaDoc w) {
4639         if (topWarning == null) {
4640             topWarning = w;
4641         } else {
4642             topWarning.setNextWarning(w);
4643         }
4644     }
4645
4646     /**
4647      *
4648      * JDBC 2.0
4649      *
4650      * Update a column with an ascii stream value.
4651      *
4652      * The updateXXX() methods are used to update column values in the current
4653      * row, or the insert row. The updateXXX() methods do not update the
4654      * underlying database, instead the updateRow() or insertRow() methods are
4655      * called to update the database.
4656      *
4657      * @param columnIndex
4658      * the first column is 1, the second is 2, ...
4659      * @param x
4660      * the new column value
4661      * @param length
4662      * the length of the stream
4663      * @exception SQLException
4664      * if a database-access error occurs
4665      */

4666     public void updateAsciiStream(int columnIndex, java.io.InputStream JavaDoc x,
4667         int length) throws SQLException JavaDoc {
4668         checkIfClosed("updateAsciiStream");
4669         updateAsciiStream(columnIndex,x,(long)length);
4670     }
4671
4672     /**
4673      *
4674      * JDBC 2.0
4675      *
4676      * Update a column with a binary stream value.
4677      *
4678      * The updateXXX() methods are used to update column values in the current
4679      * row, or the insert row. The updateXXX() methods do not update the
4680      * underlying database, instead the updateRow() or insertRow() methods are
4681      * called to update the database.
4682      *
4683      * @param columnIndex
4684      * the first column is 1, the second is 2, ...
4685      * @param x
4686      * the new column value
4687      * @param length
4688      * the length of the stream
4689      * @exception SQLException
4690      * if a database-access error occurs
4691      */

4692     public void updateBinaryStream(int columnIndex, java.io.InputStream JavaDoc x,
4693         int length) throws SQLException JavaDoc {
4694         checkIfClosed("updateBinaryStream");
4695         updateBinaryStream(columnIndex,x,(long)length);
4696     }
4697
4698     /**
4699      *
4700      * JDBC 2.0
4701      *
4702      * Update a column with a character stream value.
4703      *
4704      * The updateXXX() methods are used to update column values in the current
4705      * row, or the insert row. The updateXXX() methods do not update the
4706      * underlying database, instead the updateRow() or insertRow() methods are
4707      * called to update the database.
4708      *
4709      * @param columnIndex
4710      * the first column is 1, the second is 2, ...
4711      * @param x
4712      * the new column value
4713      * @param length
4714      * the length of the stream
4715      * @exception SQLException
4716      * if a database-access error occurs
4717      */

4718     public void updateCharacterStream(int columnIndex, java.io.Reader JavaDoc x,
4719         int length) throws SQLException JavaDoc {
4720         checkIfClosed("updateCharacterStream");
4721         updateCharacterStream(columnIndex,x,(long)length);
4722     }
4723
4724     /**
4725      *
4726      * JDBC 4.0
4727      *
4728      * Update a column with an ascii stream value.
4729      *
4730      * The updateXXX() methods are used to update column values in the current
4731      * row, or the insert row. The updateXXX() methods do not update the
4732      * underlying database, instead the updateRow() or insertRow() methods are
4733      * called to update the database.
4734      *
4735      * @param columnName
4736      * the name of the column
4737      * @param x
4738      * the new column value
4739      * @param length
4740      * of the stream
4741      * @exception SQLException
4742      * if a database-access error occurs
4743      */

4744     public void updateAsciiStream(String JavaDoc columnName, java.io.InputStream JavaDoc x,
4745         long length) throws SQLException JavaDoc {
4746         checkIfClosed("updateAsciiStream");
4747         updateAsciiStream(findColumnName(columnName),x,length);
4748     }
4749
4750    /**
4751     * Updates the designated column with a character stream value.
4752     * The data will be read from the stream as needed until end-of-stream is
4753     * reached.
4754     *
4755     * The updater methods are used to update column values in the current row
4756     * or the insert row. The updater methods do not update the underlying
4757     * database; instead the <code>updateRow</code> or </code>insertRow</code>
4758     * methods are called to update the database.
4759     *
4760     * @param columnName the label for the column specified with the SQL AS
4761     * clause. If the SQL AS clause was not specified, then the label is
4762     * the name of the column
4763     * @param x the new column value
4764     * @throws SQLException if the columnIndex is not valid; if a database
4765     * access error occurs; the result set concurrency is
4766     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4767     * result set
4768     */

4769    public void updateAsciiStream(String JavaDoc columnName, InputStream x)
4770            throws SQLException JavaDoc {
4771        checkIfClosed("updateAsciiStream");
4772        updateAsciiStream(findColumnName(columnName), x);
4773    }
4774
4775     /**
4776      *
4777      * JDBC 4.0
4778      *
4779      * Update a column with a binary stream value.
4780      *
4781      * The updateXXX() methods are used to update column values in the current
4782      * row, or the insert row. The updateXXX() methods do not update the
4783      * underlying database, instead the updateRow() or insertRow() methods are
4784      * called to update the database.
4785      *
4786      * @param columnName
4787      * the name of the column
4788      * @param x
4789      * the new column value
4790      * @param length
4791      * of the stream
4792      * @exception SQLException
4793      * if a database-access error occurs
4794      */

4795
4796     public void updateBinaryStream(String JavaDoc columnName, java.io.InputStream JavaDoc x,
4797         long length) throws SQLException JavaDoc {
4798         checkIfClosed("updateBinaryStream");
4799         updateBinaryStream(findColumnName(columnName),x,length);
4800     }
4801
4802    /**
4803     * Updates the designated column with a binary stream value.
4804     * The data will be read from the stream as needed until end-of-stream is
4805     * reached.
4806     *
4807     * The updater methods are used to update column values in the current row
4808     * or the insert row. The updater methods do not update the underlying
4809     * database; instead the <code>updateRow</code> or <code>insertRow</code>
4810     * methods are called to update the database.
4811     *
4812     * @param columnName the label for the column specified with the SQL AS
4813     * clause. If the SQL AS clause was not specified, then the label is
4814     * the name of the column
4815     * @param x the new column value
4816     * @throws SQLException if the columnLabel is not valid; if a database
4817     * access error occurs; the result set concurrency is
4818     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4819     * result set
4820     */

4821    public void updateBinaryStream(String JavaDoc columnName, InputStream x)
4822            throws SQLException JavaDoc {
4823        checkIfClosed("updateBinaryStream");
4824        updateBinaryStream(findColumnName(columnName), x);
4825    }
4826
4827     /**
4828      * JDBC 4.0
4829      *
4830      * Update a column with a character stream value.
4831      *
4832      * The updateXXX() methods are used to update column values in the current
4833      * row, or the insert row. The updateXXX() methods do not update the
4834      * underlying database, instead the updateRow() or insertRow() methods are
4835      * called to update the database.
4836      *
4837      * @param columnName
4838      * the name of the column
4839      * @param reader
4840      * the new column value
4841      * @param length
4842      * length of the stream
4843      * @exception SQLException
4844      * if a database-access error occurs
4845      */

4846     public void updateCharacterStream(String JavaDoc columnName, java.io.Reader JavaDoc reader,
4847         long length) throws SQLException JavaDoc {
4848         checkIfClosed("updateCharacterStream");
4849         updateCharacterStream(findColumnName(columnName),reader,length);
4850     }
4851
4852    /**
4853     * Updates the designated column with a character stream value.
4854     * The data will be read from the stream as needed until end-of-stream is
4855     * reached.
4856     *
4857     * The updater methods are used to update column values in the current row
4858     * or the insert row. The updater methods do not update the underlying
4859     * database; instead the <code>updateRow</code> or </code>insertRow</code>
4860     * methods are called to update the database.
4861     *
4862     * @param columnName the label for the column specified with the SQL AS
4863     * clause. If the SQL AS clause was not specified, then the label is
4864     * the name of the column
4865     * @param reader the new column value
4866     * @throws SQLException if the columnIndex is not valid; if a database
4867     * access error occurs; the result set concurrency is
4868     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4869     * result set
4870     */

4871    public void updateCharacterStream(String JavaDoc columnName, Reader reader)
4872            throws SQLException JavaDoc {
4873        checkIfClosed("updateCharacterStream");
4874        updateCharacterStream(findColumnName(columnName), reader);
4875    }
4876
4877     /**
4878      *
4879      * JDBC 4.0
4880      *
4881      * Updates the designated column with a java.sql.Blob value. The updater
4882      * methods are used to update column values in the current row or the insert
4883      * row. The updater methods do not update the underlying database; instead
4884      * the updateRow or insertRow methods are called to update the database.
4885      *
4886      * @param columnIndex -
4887      * the first column is 1, the second is 2
4888      * @param x -
4889      * the new column value
4890      * @param length -
4891      * the length of the Blob datatype
4892      * @exception SQLException
4893      *
4894      */

4895     public void updateBlob(int columnIndex, InputStream x, long length)
4896     throws SQLException JavaDoc {
4897         checksBeforeUpdateXXX("updateBlob", columnIndex);
4898         int colType = getColumnType(columnIndex);
4899         if (colType != Types.BLOB)
4900             throw dataTypeConversion(columnIndex, "java.sql.Blob");
4901
4902         if (x == null)
4903             updateNull(columnIndex);
4904         else {
4905             updateBinaryStreamInternal(columnIndex, x, false, length,
4906                                        "updateBlob");
4907         }
4908     }
4909
4910    /**
4911     * Updates the designated column using the given input stream.
4912     * The data will be read from the stream as needed until end-of-stream is reached.
4913     *
4914     * The updater methods are used to update column values in the current row
4915     * or the insert row. The updater methods do not update the underlying
4916     * database; instead the updateRow or insertRow methods are called to
4917     * update the database.
4918     *
4919     * @param columnIndex the first column is 1, the second is 2, ...
4920     * @param x an object that contains the data to set the
4921     * parameter value to.
4922     * @throws SQLException if the columnIndex is not valid; if a database
4923     * access error occurs; the result set concurrency is
4924     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4925     * result set
4926     */

4927    public void updateBlob(int columnIndex, InputStream x)
4928           throws SQLException JavaDoc {
4929       checksBeforeUpdateXXX("updateBlob", columnIndex);
4930       int colType = getColumnType(columnIndex);
4931       if (colType != Types.BLOB) {
4932            throw dataTypeConversion(columnIndex, "java.sql.Blob");
4933       }
4934       updateBinaryStreamInternal(columnIndex, x, true, -1, "updateBlob");
4935    }
4936
4937     /**
4938      *
4939      * JDBC 4.0
4940      *
4941      * Updates the designated column with a java.sql.Blob value. The updater
4942      * methods are used to update column values in the current row or the insert
4943      * row. The updater methods do not update the underlying database; instead
4944      * the updateRow or insertRow methods are called to update the database.
4945      *
4946      * @param columnName -
4947      * the name of the column to be updated
4948      * @param x -
4949      * the new column value
4950      * @param length -
4951      * the length of the Blob datatype
4952      * @exception SQLException
4953      *
4954      */

4955
4956     public void updateBlob(String JavaDoc columnName, InputStream x, long length)
4957     throws SQLException JavaDoc {
4958         checkIfClosed("updateBlob");
4959         updateBlob(findColumnName(columnName),x,length);
4960     }
4961
4962    /**
4963     * Updates the designated column using the given input stream.
4964     * The data will be read from the stream as needed until end-of-stream is reached.
4965     *
4966     * The updater methods are used to update column values in the current row
4967     * or the insert row. The updater methods do not update the underlying
4968     * database; instead the updateRow or insertRow methods are called to
4969     * update the database.
4970     *
4971     * @param columnName the label for the column specified with the SQL AS
4972     * clause. If the SQL AS clause was not specified, then the label is
4973     * the name of the column
4974     * @param x an object that contains the data to set the
4975     * parameter value to.
4976     * @throws SQLException if the columnIndex is not valid; if a database
4977     * access error occurs; the result set concurrency is
4978     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4979     * result set
4980     */

4981    public void updateBlob(String JavaDoc columnName, InputStream x)
4982           throws SQLException JavaDoc {
4983       checkIfClosed("updateBlob");
4984       updateBlob(findColumnName(columnName), x);
4985    }
4986
4987     /**
4988      *
4989      * JDBC 4.0
4990      *
4991      * Updates the designated column with a java.sql.Clob value. The updater
4992      * methods are used to update column values in the current row or the insert
4993      * row. The updater methods do not update the underlying database; instead
4994      * the updateRow or insertRow methods are called to update the database.
4995      *
4996      * @param columnIndex -
4997      * the first column is 1, the second is 2
4998      * @param x -
4999      * the new column value
5000      * @exception SQLException
5001      * Feature not implemented for now.
5002      */

5003     public void updateClob(int columnIndex, Reader x, long length)
5004     throws SQLException JavaDoc {
5005         checksBeforeUpdateXXX("updateClob", columnIndex);
5006         int colType = getColumnType(columnIndex);
5007         if (colType != Types.CLOB)
5008             throw dataTypeConversion(columnIndex, "java.sql.Clob");
5009
5010         if (x == null) {
5011             updateNull(columnIndex);
5012         } else {
5013             updateCharacterStreamInternal(
5014                 columnIndex, x, false, length, "updateClob");
5015         }
5016     }
5017
5018    /**
5019     * Updates the designated column using the given <code>Reader</code>
5020     * object.
5021     *
5022     * The data will be read from the stream as needed until end-of-stream is
5023     * reached. The JDBC driver will do any necessary conversion from
5024     * <code>UNICODE</code> to the database char format.
5025     *
5026     * The updater methods are used to update column values in the current row
5027     * or the insert row. The updater methods do not update the underlying
5028     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5029     * methods are called to update the database.
5030     *
5031     * @param columnIndex the first column is 1, the second is 2, ...
5032     * @param x an object that contains the data to set the parameter
5033     * value to
5034     * @throws SQLException if the columnIndex is not valid; if a database
5035     * access error occurs; the result set concurrency is
5036     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5037     * result set
5038     */

5039    public void updateClob(int columnIndex, Reader x)
5040           throws SQLException JavaDoc {
5041        checksBeforeUpdateXXX("updateClob", columnIndex);
5042        int colType = getColumnType(columnIndex);
5043        if (colType != Types.CLOB) {
5044            throw dataTypeConversion(columnIndex, "java.sql.Clob");
5045        }
5046        updateCharacterStreamInternal(columnIndex, x, true, -1, "updateClob");
5047    }
5048
5049     /**
5050      *
5051      * JDBC 4.0
5052      *
5053      * Updates the designated column with a java.sql.Clob value. The updater
5054      * methods are used to update column values in the current row or the insert
5055      * row. The updater methods do not update the underlying database; instead
5056      * the updateRow or insertRow methods are called to update the database.
5057      *
5058      * @param columnName -
5059      * the name of the Clob column
5060      * @param x -
5061      * the new column value
5062      * @exception SQLException
5063      * Feature not implemented for now.
5064      */

5065
5066     public void updateClob(String JavaDoc columnName, Reader x, long length)
5067     throws SQLException JavaDoc {
5068         checkIfClosed("updateClob");
5069         updateClob(findColumnName(columnName),x,length);
5070     }
5071
5072    /**
5073     * Updates the designated column using the given <code>Reader</code>
5074     * object.
5075     *
5076     * The data will be read from the stream as needed until end-of-stream is
5077     * reached. The JDBC driver will do any necessary conversion from
5078     * <code>UNICODE</code> to the database char format.
5079     *
5080     * The updater methods are used to update column values in the current row
5081     * or the insert row. The updater methods do not update the underlying
5082     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5083     * methods are called to update the database.
5084     *
5085     * @param columnName the label for the column specified with the SQL AS
5086     * clause. If the SQL AS clause was not specified, then the label is
5087     * the name of the column
5088     * @param x an object that contains the data to set the parameter
5089     * value to
5090     * @throws SQLException if the columnIndex is not valid; if a database
5091     * access error occurs; the result set concurrency is
5092     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5093     * result set
5094     */

5095    public void updateClob(String JavaDoc columnName, Reader x)
5096           throws SQLException JavaDoc {
5097       checkIfClosed("updateClob");
5098       updateClob(findColumnName(columnName), x);
5099    }
5100}
5101
Popular Tags