KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > client > am > ResultSet


1 /*
2
3    Derby - Class org.apache.derby.client.am.ResultSet
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.client.am;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.Reader JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import org.apache.derby.client.am.SQLExceptionFactory;
29 import org.apache.derby.shared.common.reference.SQLState;
30 import org.apache.derby.shared.common.i18n.MessageUtil;
31
32 public abstract class ResultSet implements java.sql.ResultSet JavaDoc,
33         ResultSetCallbackInterface {
34     //---------------------navigational members-----------------------------------
35

36     public Statement statement_;
37     public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
38
private SqlWarning warnings_;
39     public Cursor cursor_;
40     protected Agent agent_;
41
42     public Section generatedSection_ = null;
43
44     private CloseFilterInputStream is_;
45
46     //---------------------navigational cheat-links-------------------------------
47
// Cheat-links are for convenience only, and are not part of the conceptual model.
48
// Warning:
49
// Cheat-links should only be defined for invariant state data.
50
// That is, the state data is set by the constructor and never changes.
51

52     // Alias for statement_.connection
53
public final Connection connection_;
54
55     //----------------------------- constants ------------------------------------
56

57     public final static int scrollOrientation_relative__ = 1;
58     public final static int scrollOrientation_absolute__ = 2;
59     public final static int scrollOrientation_after__ = 3;
60     public final static int scrollOrientation_before__ = 4;
61     public final static int scrollOrientation_prior__ = 5;
62     public final static int scrollOrientation_first__ = 6;
63     public final static int scrollOrientation_last__ = 7;
64     public final static int scrollOrientation_current__ = 8;
65     public final static int scrollOrientation_next__ = 0;
66
67     public final static int updatability_unknown__ = 0;
68     public final static int updatability_readOnly__ = 1;
69     public final static int updatability_delete__ = 2;
70     public final static int updatability_update__ = 4;
71
72     public final static int sensitivity_unknown__ = 0;
73     public final static int sensitivity_insensitive__ = 1;
74     public final static int sensitivity_sensitive_static__ = 2;
75     public final static int sensitivity_sensitive_dynamic__ = 3;
76
77     static final private int WAS_NULL = 1;
78     static final private int WAS_NOT_NULL = 2;
79     static final private int WAS_NULL_UNSET = 0;
80
81     static final public int NEXT_ROWSET = 1;
82     static final public int PREVIOUS_ROWSET = 2;
83     static final public int ABSOLUTE_ROWSET = 3;
84     static final public int FIRST_ROWSET = 4;
85     static final public int LAST_ROWSET = 5;
86     static final public int RELATIVE_ROWSET = 6;
87     static final public int REFRESH_ROWSET = 7;
88     // determines if a cursor is a:
89
// Return to Client - not to be read by the stored procedure only by client
90
// Return to Caller
91
public static final byte DDM_RETURN_CALLER = 0x01;
92     public static final byte DDM_RETURN_CLIENT = 0x02;
93
94     //-----------------------------state------------------------------------------
95

96     // Note:
97
// Result set meta data as described by the SQLDA is described in ColumnMetaData.
98

99     private int wasNull_ = WAS_NULL_UNSET;
100
101     // ResultSet returnability for Stored Procedure cursors
102
// determines if a cursor is a:
103
// Return to Client - not to be read by the stored procedure only by client
104
// Return to Caller - only calling JSP can read it, not the client
105
protected byte rsReturnability_ = DDM_RETURN_CLIENT;
106
107     // This means the client-side jdbc result set object is open.
108
boolean openOnClient_ = true;
109     // This means a server-side DERBY query section (cursor) for this result set is in the open state.
110
// A jdbc result set may remain open even after the server has closed its cursor
111
// (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
112
public boolean openOnServer_ = true;
113
114     // there is a query terminating sqlca returned from the server when the server closes
115
// it's cursor and the client moves to the close-only state.
116
public Sqlca queryTerminatingSqlca_;
117
118     // Only true for forward cursors after next() returns false (+100).
119
// Used to prevent multiple commits for subsequent next() calls.
120
boolean autoCommitted_ = false;
121
122     // Before the first call to next() or any cursor positioning method, the cursor position is invalid
123
// and getter methods cannot be called.
124
// Also, if a cursor is exhausted (+100), the cursor position is invalid.
125
public boolean isValidCursorPosition_ = false;
126
127     public boolean cursorHold_;
128
129     // query instance identifier returned on open by uplevel servers.
130
// this value plus the package information uniquely identifies a query.
131
// it is 64 bits long and it's value is unarchitected.
132
public long queryInstanceIdentifier_ = 0;
133
134     public int resultSetType_;
135     public int resultSetConcurrency_;
136     public int resultSetHoldability_;
137     public boolean scrollable_ = false;
138     public int sensitivity_;
139     public boolean isRowsetCursor_ = false;
140     public boolean isBeforeFirst_ = true;
141     public boolean isAfterLast_ = false;
142     public boolean isFirst_ = false;
143     public boolean isLast_ = false;
144     public boolean rowsetContainsLastRow_ = false;
145     public Sqlca[] rowsetSqlca_;
146
147     // Gets its initial value from the statement when the result set is created.
148
// It can be modified by setFetchSize and retrieved via getFetchSize.
149
protected int suggestedFetchSize_;
150
151     // Set by the net layer based on suggestedFetchSize_, protocol
152
// type, scrollability and presence of lobs.
153
public int fetchSize_;
154
155     public int fetchDirection_;
156
157     public long rowCount_ = -1;
158
159     protected long absolutePosition_ = 0; // absolute position of the current row
160
protected long firstRowInRowset_ = 0; // absolute position of the first row in the current rowset
161
protected long lastRowInRowset_ = 0; // absolute position of the last row in the current rowset
162
protected long currentRowInRowset_ = -1; // relative position to the first row in the current rowsetwel
163

164     protected long absoluteRowNumberForTheIntendedRow_;
165
166     private boolean isOnInsertRow_ = false; // reserved for later
167
protected boolean isOnCurrentRow_ = true;
168     public int rowsReceivedInCurrentRowset_ = 0; // keep track of the number of rows received in the
169
// current rowset so far
170

171     // maybe be able to consolidate with rowsReceivedInCurrentRowset_
172
// Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
173
// fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
174
// Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
175
// for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
176
// when it's reset. By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
177
// request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
178
// otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
179
public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
180
// be received to complete the rowset
181

182     private Object JavaDoc updatedColumns_[];
183
184     // Keeps track of whether a column has been updated. If a column is updated to null,
185
// the object array updatedColumns_ entry is null, and we will use this array to distinguish
186
// between column not updated and column updated to null.
187
private boolean columnUpdated_[];
188
189     public PreparedStatement preparedStatementForUpdate_;
190     public PreparedStatement preparedStatementForDelete_;
191     public PreparedStatement preparedStatementForInsert_;
192
193     // Nesting level of the result set in a stored procedure
194
public int nestingLevel_ = -1;
195
196     // Whenever a commit occurs, it unpositions the cursor on the server. We need to
197
// reposition the cursor before updating/deleting again. This flag will be set to true
198
// whenever a commit happens, and reset to false again after we repositoin the cursor.
199
public boolean cursorUnpositionedOnServer_ = false;
200     
201     // Keep maxRows in the ResultSet, so that changes to maxRow in the statement
202
// do not affect the resultSet after it has been created
203
private int maxRows_;
204     
205     private boolean[] streamUsedFlags_;
206     
207     //---------------------constructors/finalizer---------------------------------
208

209     protected ResultSet(Agent agent,
210                         Statement statement,
211                         Cursor cursor,
212                         int resultSetType,
213                         int resultSetConcurrency,
214                         int resultSetHoldability) {
215         agent_ = agent;
216         statement_ = statement;
217         connection_ = statement_.connection_;
218         cursor_ = cursor;
219         if (cursor_ != null) {
220             cursor_.maxFieldSize_ = statement_.maxFieldSize_;
221         }
222         resultSetType_ = resultSetType;
223         resultSetConcurrency_ = resultSetConcurrency;
224         resultSetHoldability_ = resultSetHoldability;
225         fetchDirection_ = statement_.fetchDirection_;
226         suggestedFetchSize_ = statement_.fetchSize_;
227
228         maxRows_ = statement_.maxRows_;
229         
230         // Only set the warning if actual resultSetType returned by the server is less
231
// than the application requested resultSetType.
232
// TYPE_FORWARD_ONLY = 1003
233
// TYPE_SCROLL_INSENSITIVE = 1004
234
// TYPE_SCROLL_SENSITIVE = 1005
235
if (resultSetType_ < statement_.resultSetType_) {
236             statement_.accumulateWarning(
237                 new SqlWarning(
238                     agent_.logWriter_,
239                     new ClientMessageId(SQLState.INVALID_RESULTSET_TYPE),
240                         new Integer JavaDoc(statement_.resultSetType_),
241                         new Integer JavaDoc(resultSetType_)));
242         }
243
244         // Only set the warning if actual resultSetConcurrency returned by the server is
245
// less than the application requested resultSetConcurrency.
246
// CONCUR_READ_ONLY = 1007
247
// CONCUR_UPDATABLE = 1008
248
if (resultSetConcurrency_ < statement_.resultSetConcurrency_) {
249             accumulateWarning(
250                 new SqlWarning(
251                     agent_.logWriter_,
252                     new ClientMessageId(
253                     SQLState.QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET)));
254                 
255         }
256
257         listenToUnitOfWork();
258     }
259
260     // ---------------------------jdbc 1------------------------------------------
261

262     public final boolean next() throws SQLException JavaDoc {
263         try
264         {
265             synchronized (connection_) {
266                 if (agent_.loggingEnabled()) {
267                     agent_.logWriter_.traceEntry(this, "next");
268                 }
269                 boolean isValidCursorPosition = nextX();
270                 if (agent_.loggingEnabled()) {
271                     agent_.logWriter_.traceExit(this, "next", isValidCursorPosition);
272                 }
273                 return isValidCursorPosition;
274             }
275         }
276         catch ( SqlException se )
277         {
278             throw se.getSQLException();
279         }
280     }
281
282     // used by DBMD
283
boolean nextX() throws SqlException {
284         checkForClosedResultSet();
285         clearWarningsX();
286
287         moveToCurrentRowX();
288         
289         wasNull_ = ResultSet.WAS_NULL_UNSET;
290
291         // discard all previous updates when moving the cursor
292
resetUpdatedColumns();
293     
294     unuseStreams();
295
296         // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
297
if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
298             // cursor is null for singleton selects that do not return data.
299
isValidCursorPosition_ = (cursor_ == null) ? false : cursor_.next();
300
301             // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
302
// then we must count the rows returned in the rowset to make sure we received a
303
// complete rowset. if not, we need to complete the rowset on the next fetch.
304
if (fetchSize_ != 0) {
305                 if (rowsYetToBeReceivedForRowset_ == 0) {
306                     rowsYetToBeReceivedForRowset_ = fetchSize_;
307                 }
308                 if (isValidCursorPosition_) {
309                     rowsYetToBeReceivedForRowset_--;
310                 }
311             }
312
313             // Auto-commit semantics for exhausted cursors follows.
314
// From Connection.setAutoCommit() javadoc:
315
// The commit occurs when the statement completes or the next execute occurs, whichever comes first.
316
// In the case of statements returning a ResultSet object, the statement completes when the
317
// last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
318
// In advanced cases, a single statement may return multiple results as well as output parameter values.
319
// In these cases, the commit occurs when all results and output parameter values have been retrieved.
320
// we will check to see if the forward only result set has gone past the end,
321
// we will close the result set, the autocommit logic is in the closeX() method
322
//
323
//Aug 24, 2005: Auto-commit logic is no longer in the closeX() method. Insted it has been
324
//moved to Statement and is handled in a manner similar to the embedded driver.
325
// if (!isValidCursorPosition_ && // We've gone past the end (+100)
326
// cursor_ != null) {
327
if ((!isValidCursorPosition_ && cursor_ != null) ||
328                     (maxRows_ > 0 && cursor_.rowsRead_ > maxRows_)) {
329                 isValidCursorPosition_ = false;
330
331                 // if not on a valid row and the query is closed at the server.
332
// check for an error which may have caused the cursor to terminate.
333
// if there were no more rows because of an error, then this method
334
// should throw an SqlException rather than just returning false.
335
// depending on how this works with scrollable cursors, there may be
336
// a better way/more common place for this logic.
337
SqlException sqlException = null;
338                 if (!openOnServer_) {
339                     int sqlcode = Utils.getSqlcodeFromSqlca(queryTerminatingSqlca_);
340                     if (sqlcode > 0 && sqlcode != 100) {
341                         accumulateWarning(new SqlWarning(agent_.logWriter_, queryTerminatingSqlca_));
342                     } else if (sqlcode < 0) {
343                         sqlException = new SqlException(agent_.logWriter_, queryTerminatingSqlca_);
344                     }
345                 }
346             
347                 try {
348                     statement_.resultSetCommitting(this);
349                 } catch (SqlException sqle) {
350                     sqlException = Utils.accumulateSQLException(sqle, sqlException);
351                 }
352                 
353                 if (sqlException != null)
354                     throw sqlException;
355             }
356         }
357
358         // for scrollable ResultSet's,
359
// if the "next" request is still fetching within the current rowset,
360
// update column info from cache and increment the current row index
361
// else
362
// fetch the next rowset from the server
363
else {
364
365             // These flags will only be used for dynamic cursors where we don't know the row count
366
// and can't keep track of the absolute position of the cursor.
367
isAfterLast_ = false;
368             isLast_ = false;
369
370             // if the next row is still within the current rowset
371
if (rowIsInCurrentRowset(firstRowInRowset_ + currentRowInRowset_ + 1, scrollOrientation_next__)) {
372                 isValidCursorPosition_ = true;
373                 currentRowInRowset_++;
374             } else {
375                 checkAndThrowReceivedQueryTerminatingException();
376                 isValidCursorPosition_ = getNextRowset();
377             }
378
379             if (isValidCursorPosition_) {
380                 updateColumnInfoFromCache();
381                 // check if there is a non-null SQLCA for the current row for rowset cursors
382
checkRowsetSqlca();
383                 if (isBeforeFirst_) {
384                     isFirst_ = true;
385                 }
386                 isBeforeFirst_ = false;
387             } else {
388                 isFirst_ = false;
389                 return isValidCursorPosition_;
390             }
391         }
392
393         // for forward-only cursors, check if rowsRead_ > maxRows_.
394
// for scrollable cursors, check if absolute row number > maxRows_.
395
// maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
396
if (!openOnClient_) {
397             isValidCursorPosition_ = false;
398         } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0 &&
399                 (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
400             isValidCursorPosition_ = false;
401         }
402         return isValidCursorPosition_;
403     }
404
405
406     public void close() throws SQLException JavaDoc {
407         try
408         {
409             synchronized (connection_) {
410                 if (agent_.loggingEnabled()) {
411                     agent_.logWriter_.traceEntry(this, "close");
412                 }
413                 closeX();
414             }
415         }
416         catch ( SqlException se )
417         {
418             throw se.getSQLException();
419         }
420     }
421
422     // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
423
// that we later check to drive a commit.
424
// An untraced version of close()
425
public final void closeX() throws SqlException {
426         if (!openOnClient_) {
427             return;
428         }
429         preClose_();
430         try {
431             if (openOnServer_) {
432                 flowCloseAndAutoCommitIfNotAutoCommitted();
433             } else {
434                 statement_.resultSetCommitting(this);
435             }
436         } finally {
437             markClosed(true);
438         }
439
440         if (statement_.openOnClient_ && statement_.isCatalogQuery_) {
441             statement_.closeX();
442         }
443
444         nullDataForGC();
445     }
446
447     public void nullDataForGC() {
448         // This method is called by closeX(). We cannot call this if cursor is cached,
449
// otherwise it will cause NullPointerException's when cursor is reused.
450
// Cursor is only cached for PreparedStatement's.
451
if (cursor_ != null && !statement_.isPreparedStatement_) {
452             cursor_.nullDataForGC();
453         }
454         cursor_ = null;
455         resultSetMetaData_ = null;
456     }
457
458     void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
459         agent_.beginWriteChain(statement_);
460         boolean performedAutoCommit = writeCloseAndAutoCommit();
461         agent_.flow(statement_);
462         readCloseAndAutoCommit(performedAutoCommit);
463         agent_.endReadChain();
464     }
465
466     private boolean writeCloseAndAutoCommit() throws SqlException {
467         // set autoCommitted_ to false so commit will flow following
468
// close cursor if autoCommit is true.
469
autoCommitted_ = false;
470         if (generatedSection_ == null) { // none call statement result set case
471
writeCursorClose_(statement_.section_);
472         } else { // call statement result set(s) case
473
writeCursorClose_(generatedSection_);
474         }
475         return statement_.resultSetCommitting(this, true);
476     }
477
478     private void readCloseAndAutoCommit(boolean readAutoCommit) throws SqlException {
479         readCursorClose_();
480         if (readAutoCommit)
481             readAutoCommitIfNotAutoCommitted();
482     }
483
484     void writeClose() throws SqlException {
485         // set autoCommitted_ to false so commit will flow following
486
// close cursor if autoCommit is true.
487
autoCommitted_ = false;
488         if (generatedSection_ == null) { // none call statement result set case
489
writeCursorClose_(statement_.section_);
490         } else { // call statement result set(s) case
491
writeCursorClose_(generatedSection_);
492         }
493     }
494
495     void readClose() throws SqlException {
496         try {
497             if (generatedSection_ == null) { // none call statement result set case
498
readCursorClose_();
499             } else { // call statement result set(s) case
500
readCursorClose_();
501             }
502         } finally {
503             markClosed();
504         }
505     }
506
507     // precondition: transaction state allows for auto commit to generate flow
508
private void writeAutoCommitIfNotAutoCommitted() throws SqlException {
509         if (connection_.autoCommit_ && !autoCommitted_) {
510             connection_.writeAutoCommit();
511         }
512     }
513
514     private void readAutoCommitIfNotAutoCommitted() throws SqlException {
515         if (connection_.autoCommit_ && !autoCommitted_) {
516             connection_.readAutoCommit();
517             markAutoCommitted();
518         }
519     }
520
521     public boolean wasNull() throws SQLException JavaDoc {
522         try
523         {
524             if (agent_.loggingEnabled()) {
525                 agent_.logWriter_.traceEntry(this, "wasNull");
526             }
527             checkForClosedResultSet();
528
529             if (wasNull_ == ResultSet.WAS_NULL_UNSET) {
530                 throw new SqlException(agent_.logWriter_,
531                     new ClientMessageId(SQLState.WASNULL_INVALID));
532             }
533
534             if (agent_.loggingEnabled()) {
535                 agent_.logWriter_.traceExit(this, "wasNull", wasNull_ == ResultSet.WAS_NULL);
536             }
537             return wasNull_ == ResultSet.WAS_NULL;
538         }
539         catch ( SqlException se )
540         {
541             throw se.getSQLException();
542         }
543     }
544
545     //------------------- getters on column index --------------------------------
546

547     // Live life on the edge and run unsynchronized
548
public boolean getBoolean(int column) throws SQLException JavaDoc {
549         try
550         {
551             closeCloseFilterInputStream();
552
553             if (agent_.loggingEnabled()) {
554                 agent_.logWriter_.traceEntry(this, "getBoolean", column);
555             }
556             checkGetterPreconditions(column);
557             boolean result = false;
558             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
559                 if (isOnInsertRow_ && updatedColumns_[column - 1] == null) {
560                     result = false;
561                 } else {
562                     result = agent_.crossConverters_.setBooleanFromObject(
563                             updatedColumns_[column - 1],
564                             resultSetMetaData_.types_[column - 1]);
565                 }
566             } else {
567                 result = isNull(column) ? false : cursor_.getBoolean(column);
568             }
569             if (agent_.loggingEnabled()) {
570                 agent_.logWriter_.traceExit(this, "getBoolean", result);
571             }
572             setWasNull(column); // Placed close to the return to minimize risk of thread interference
573
return result;
574         }
575         catch ( SqlException se )
576         {
577             throw se.getSQLException();
578         }
579     }
580
581     // Live life on the edge and run unsynchronized
582
public byte getByte(int column) throws SQLException JavaDoc {
583         try
584         {
585             closeCloseFilterInputStream();
586
587             if (agent_.loggingEnabled()) {
588                 agent_.logWriter_.traceEntry(this, "getByte", column);
589             }
590             checkGetterPreconditions(column);
591             byte result = 0;
592             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
593                 if ((isOnInsertRow_) && (updatedColumns_[column - 1] == null)) {
594                     result = 0;
595                 } else {
596                     result = agent_.crossConverters_.setByteFromObject(
597                             updatedColumns_[column - 1],
598                             resultSetMetaData_.types_[column - 1]);
599                 }
600             } else {
601                 result = isNull(column) ? 0 : cursor_.getByte(column);
602             }
603             if (agent_.loggingEnabled()) {
604                 agent_.logWriter_.traceExit(this, "getByte", result);
605             }
606             setWasNull(column); // Placed close to the return to minimize risk of thread interference
607
return result;
608         }
609         catch ( SqlException se )
610         {
611             throw se.getSQLException();
612         }
613     }
614
615     // Live life on the edge and run unsynchronized
616
public short getShort(int column) throws SQLException JavaDoc {
617         try
618         {
619             closeCloseFilterInputStream();
620
621             if (agent_.loggingEnabled()) {
622                 agent_.logWriter_.traceEntry(this, "getShort", column);
623             }
624             checkGetterPreconditions(column);
625             short result = 0;
626             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
627                 if (isOnInsertRow_ && updatedColumns_[column - 1] == null) {
628                     result = 0;
629                 } else {
630                     result = ((Short JavaDoc) agent_.crossConverters_.setObject(
631                             java.sql.Types.SMALLINT,
632                             updatedColumns_[column - 1])).shortValue();
633                 }
634             } else {
635                 result = isNull(column) ? 0 : cursor_.getShort(column);
636             }
637             if (agent_.loggingEnabled()) {
638                 agent_.logWriter_.traceExit(this, "getShort", result);
639             }
640             setWasNull(column); // Placed close to the return to minimize risk of thread interference
641
return result;
642         }
643         catch ( SqlException se )
644         {
645             throw se.getSQLException();
646         }
647     }
648
649     // Live life on the edge and run unsynchronized
650
public int getInt(int column) throws SQLException JavaDoc {
651         try
652         {
653             closeCloseFilterInputStream();
654
655             if (agent_.loggingEnabled()) {
656                 agent_.logWriter_.traceEntry(this, "getInt", column);
657             }
658             checkGetterPreconditions(column);
659             int result = 0;
660             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
661                 if (isOnInsertRow_ && updatedColumns_[column - 1] == null) {
662                     result = 0;
663                 } else {
664                     result = ((Integer JavaDoc) agent_.crossConverters_.setObject(
665                             java.sql.Types.INTEGER,
666                             updatedColumns_[column - 1])).intValue();
667                 }
668             } else {
669                 result = isNull(column) ? 0 : cursor_.getInt(column);
670             }
671             if (agent_.loggingEnabled()) {
672                 agent_.logWriter_.traceExit(this, "getInt", result);
673             }
674             setWasNull(column); // this is placed here close to the return to minimize risk of race condition.
675
return result;
676         }
677         catch ( SqlException se )
678         {
679             throw se.getSQLException();
680         }
681     }
682
683     // Live life on the edge and run unsynchronized
684
public long getLong(int column) throws SQLException JavaDoc {
685         try
686         {
687             closeCloseFilterInputStream();
688
689             if (agent_.loggingEnabled()) {
690                 agent_.logWriter_.traceEntry(this, "getLong", column);
691             }
692             checkGetterPreconditions(column);
693             long result = 0;
694             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
695                 if (isOnInsertRow_ && updatedColumns_[column - 1] == null) {
696                     result = 0;
697                 } else {
698                     result = ((Long JavaDoc) agent_.crossConverters_.setObject(
699                             java.sql.Types.BIGINT,
700                             updatedColumns_[column - 1])).longValue();
701                 }
702             } else {
703                 result = isNull(column) ? 0 : cursor_.getLong(column);
704             }
705             if (agent_.loggingEnabled()) {
706                 agent_.logWriter_.traceExit(this, "getLong", result);
707             }
708             setWasNull(column); // Placed close to the return to minimize risk of thread interference
709
return result;
710         }
711         catch ( SqlException se )
712         {
713             throw se.getSQLException();
714         }
715     }
716
717     // Live life on the edge and run unsynchronized
718
public float getFloat(int column) throws SQLException JavaDoc {
719         try
720         {
721             closeCloseFilterInputStream();
722
723             if (agent_.loggingEnabled()) {
724                 agent_.logWriter_.traceEntry(this, "getFloat", column);
725             }
726             checkGetterPreconditions(column);
727             float result = 0;
728             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
729                 if ((isOnInsertRow_ && updatedColumns_[column - 1] == null)) {
730                     result = 0;
731                 } else {
732                     result = ((Float JavaDoc) agent_.crossConverters_.setObject(
733                             java.sql.Types.REAL,
734                             updatedColumns_[column - 1])).floatValue();
735                 }
736             } else {
737                 result = isNull(column) ? 0 : cursor_.getFloat(column);
738             }
739             if (agent_.loggingEnabled()) {
740                 agent_.logWriter_.traceExit(this, "getFloat", result);
741             }
742             setWasNull(column); // Placed close to the return to minimize risk of thread interference
743
return result;
744         }
745         catch ( SqlException se )
746         {
747             throw se.getSQLException();
748         }
749     }
750
751     // Live life on the edge and run unsynchronized
752
public double getDouble(int column) throws SQLException JavaDoc {
753         try
754         {
755             closeCloseFilterInputStream();
756
757             if (agent_.loggingEnabled()) {
758                 agent_.logWriter_.traceEntry(this, "getDouble", column);
759             }
760             checkGetterPreconditions(column);
761             double result = 0;
762             if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
763                 if (isOnInsertRow_ && updatedColumns_[column - 1] == null) {
764                     result = 0;
765                 } else {
766                     result = ((Double JavaDoc) agent_.crossConverters_.setObject(
767                             java.sql.Types.DOUBLE,
768                             updatedColumns_[column - 1])).doubleValue();
769                 }
770             } else {
771                 result = isNull(column) ? 0 : cursor_.getDouble(column);
772             }
773             if (agent_.loggingEnabled()) {
774                 agent_.logWriter_.traceExit(this, "getDouble", result);
775             }
776             setWasNull(column); // Placed close to the return to minimize risk of thread interference
777
return result;
778         }
779         catch ( SqlException se )
780         {
781             throw se.getSQLException();
782         }
783     }
784
785     // Live life on the edge and run unsynchronized
786
public java.math.BigDecimal JavaDoc getBigDecimal(int column, int scale) throws SQLException JavaDoc {
787         try
788         {
789             closeCloseFilterInputStream();
790
791             if (agent_.loggingEnabled()) {
792                 agent_.logWriter_.traceDeprecatedEntry(this, "getBigDecimal", column, scale);
793             }
794             checkGetterPreconditions(column);
795             java.math.BigDecimal JavaDoc result = null;
796             if (wasNonNullSensitiveUpdate(column)) {
797                 result =
798                         ((java.math.BigDecimal JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.DECIMAL,
799                                 updatedColumns_[column - 1])).setScale(scale, java.math.BigDecimal.ROUND_DOWN);
800             } else {
801                 result =
802                         isNull(column) ? null : cursor_.getBigDecimal(column).setScale(scale, java.math.BigDecimal.ROUND_DOWN);
803             }
804             if (agent_.loggingEnabled()) {
805                 agent_.logWriter_.traceDeprecatedExit(this, "getBigDecimal", result);
806             }
807             setWasNull(column); // Placed close to the return to minimize risk of thread interference
808
return result;
809         }
810         catch ( SqlException se )
811         {
812             throw se.getSQLException();
813         }
814     }
815
816     // Live life on the edge and run unsynchronized
817
public java.math.BigDecimal JavaDoc getBigDecimal(int column) throws SQLException JavaDoc {
818         try
819         {
820
821             closeCloseFilterInputStream();
822
823             if (agent_.loggingEnabled()) {
824                 agent_.logWriter_.traceEntry(this, "getBigDecimal", column);
825             }
826             checkGetterPreconditions(column);
827             java.math.BigDecimal JavaDoc result = null;
828             if (wasNonNullSensitiveUpdate(column)) {
829                 result =
830                         (java.math.BigDecimal JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.DECIMAL,
831                                 updatedColumns_[column - 1]);
832             } else {
833                 result = isNull(column) ? null : cursor_.getBigDecimal(column);
834             }
835             if (agent_.loggingEnabled()) {
836                 agent_.logWriter_.traceExit(this, "getBigDecimal", result);
837             }
838             setWasNull(column); // Placed close to the return to minimize risk of thread interference
839
return result;
840         }
841         catch ( SqlException se )
842         {
843             throw se.getSQLException();
844         }
845     }
846
847     // Live life on the edge and run unsynchronized
848
public java.sql.Date JavaDoc getDate(int column) throws SQLException JavaDoc {
849         try
850         {
851             closeCloseFilterInputStream();
852
853             if (agent_.loggingEnabled()) {
854                 agent_.logWriter_.traceEntry(this, "getDate", column);
855             }
856             checkGetterPreconditions(column);
857             java.sql.Date JavaDoc result = null;
858             if (wasNonNullSensitiveUpdate(column)) {
859                 result = (java.sql.Date JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.DATE, updatedColumns_[column - 1]);
860             } else {
861                 result = isNull(column) ? null : cursor_.getDate(column);
862             }
863             if (agent_.loggingEnabled()) {
864                 agent_.logWriter_.traceExit(this, "getDate", result);
865             }
866             setWasNull(column); // Placed close to the return to minimize risk of thread interference
867
return result;
868         }
869         catch ( SqlException se )
870         {
871             throw se.getSQLException();
872         }
873     }
874
875     // Live life on the edge and run unsynchronized
876
public java.sql.Date JavaDoc getDate(int column, java.util.Calendar JavaDoc calendar) throws SQLException JavaDoc {
877         try
878         {
879             closeCloseFilterInputStream();
880
881             if (agent_.loggingEnabled()) {
882                 agent_.logWriter_.traceEntry(this, "getDate", column, calendar);
883             }
884             java.sql.Date JavaDoc date = getDate(column);
885             if (calendar == null) {
886                 throw new SqlException(agent_.logWriter_,
887                     new ClientMessageId(SQLState.CALENDAR_IS_NULL));
888             }
889             if (date != null) {
890                 java.util.Calendar JavaDoc targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
891                 targetCalendar.clear();
892                 targetCalendar.setTime(date);
893                 java.util.Calendar JavaDoc defaultCalendar = java.util.Calendar.getInstance();
894                 defaultCalendar.clear();
895                 defaultCalendar.setTime(date);
896                 long timeZoneOffset =
897                         targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
898                         targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
899                 date.setTime(date.getTime() - timeZoneOffset);
900             }
901             if (agent_.loggingEnabled()) {
902                 agent_.logWriter_.traceExit(this, "getDate", date);
903             }
904             return date;
905         }
906         catch ( SqlException se )
907         {
908             throw se.getSQLException();
909         }
910     }
911
912     // Live life on the edge and run unsynchronized
913
public java.sql.Time JavaDoc getTime(int column) throws SQLException JavaDoc {
914         try
915         {
916             closeCloseFilterInputStream();
917
918             if (agent_.loggingEnabled()) {
919                 agent_.logWriter_.traceEntry(this, "getTime", column);
920             }
921             checkGetterPreconditions(column);
922             java.sql.Time JavaDoc result = null;
923             if (wasNonNullSensitiveUpdate(column)) {
924                 result = (java.sql.Time JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.TIME, updatedColumns_[column - 1]);
925             } else {
926                 result = isNull(column) ? null : cursor_.getTime(column);
927             }
928             if (agent_.loggingEnabled()) {
929                 agent_.logWriter_.traceExit(this, "getTime", result);
930             }
931             setWasNull(column); // Placed close to the return to minimize risk of thread interference
932
return result;
933         }
934         catch ( SqlException se )
935         {
936             throw se.getSQLException();
937         }
938     }
939
940     // Live life on the edge and run unsynchronized
941
public java.sql.Time JavaDoc getTime(int column, java.util.Calendar JavaDoc calendar) throws SQLException JavaDoc {
942         try
943         {
944             closeCloseFilterInputStream();
945
946             if (agent_.loggingEnabled()) {
947                 agent_.logWriter_.traceEntry(this, "getTime", column, calendar);
948             }
949             java.sql.Time JavaDoc time = getTime(column);
950             if (calendar == null) {
951                 throw new SqlException(agent_.logWriter_,
952                     new ClientMessageId(SQLState.CALENDAR_IS_NULL));
953             }
954             if (time != null) {
955                 java.util.Calendar JavaDoc targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
956                 targetCalendar.clear();
957                 targetCalendar.setTime(time);
958                 java.util.Calendar JavaDoc defaultCalendar = java.util.Calendar.getInstance();
959                 defaultCalendar.clear();
960                 defaultCalendar.setTime(time);
961                 long timeZoneOffset =
962                         targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
963                         targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
964                 time.setTime(time.getTime() - timeZoneOffset);
965             }
966             if (agent_.loggingEnabled()) {
967                 agent_.logWriter_.traceExit(this, "getTime", time);
968             }
969             return time;
970         }
971         catch ( SqlException se )
972         {
973             throw se.getSQLException();
974         }
975     }
976
977     // Live life on the edge and run unsynchronized
978
public java.sql.Timestamp JavaDoc getTimestamp(int column) throws SQLException JavaDoc {
979         try
980         {
981             closeCloseFilterInputStream();
982
983             if (agent_.loggingEnabled()) {
984                 agent_.logWriter_.traceEntry(this, "getTimestamp", column);
985             }
986             checkGetterPreconditions(column);
987             java.sql.Timestamp JavaDoc result = null;
988             if (wasNonNullSensitiveUpdate(column)) {
989                 result = (java.sql.Timestamp JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.TIMESTAMP, updatedColumns_[column - 1]);
990             } else {
991                 result = isNull(column) ? null : cursor_.getTimestamp(column);
992             }
993             if (agent_.loggingEnabled()) {
994                 agent_.logWriter_.traceExit(this, "getTimestamp", result);
995             }
996             setWasNull(column); // Placed close to the return to minimize risk of thread interference
997
return result;
998         }
999         catch ( SqlException se )
1000        {
1001            throw se.getSQLException();
1002        }
1003    }
1004
1005    // Live life on the edge and run unsynchronized
1006
public java.sql.Timestamp JavaDoc getTimestamp(int column, java.util.Calendar JavaDoc calendar) throws SQLException JavaDoc {
1007        try
1008        {
1009            closeCloseFilterInputStream();
1010
1011            if (agent_.loggingEnabled()) {
1012                agent_.logWriter_.traceEntry(this, "getTimestamp", column, calendar);
1013            }
1014            java.sql.Timestamp JavaDoc timestamp = getTimestamp(column);
1015            if (calendar == null) {
1016                throw new SqlException(agent_.logWriter_,
1017                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
1018            }
1019            if (timestamp != null) {
1020                int nano = timestamp.getNanos();
1021                java.util.Calendar JavaDoc targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
1022                targetCalendar.clear();
1023                targetCalendar.setTime(timestamp);
1024                java.util.Calendar JavaDoc defaultCalendar = java.util.Calendar.getInstance();
1025                defaultCalendar.clear();
1026                defaultCalendar.setTime(timestamp);
1027                long timeZoneOffset =
1028                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
1029                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
1030                timestamp.setTime(timestamp.getTime() - timeZoneOffset);
1031                timestamp.setNanos(nano);
1032            }
1033            if (agent_.loggingEnabled()) {
1034                agent_.logWriter_.traceExit(this, "getTimestamp", timestamp);
1035            }
1036            return timestamp;
1037        }
1038        catch ( SqlException se )
1039        {
1040            throw se.getSQLException();
1041        }
1042    }
1043
1044    // Live life on the edge and run unsynchronized
1045
public String JavaDoc getString(int column) throws SQLException JavaDoc {
1046        try
1047        {
1048            closeCloseFilterInputStream();
1049
1050            if (agent_.loggingEnabled()) {
1051                agent_.logWriter_.traceEntry(this, "getString", column);
1052            }
1053            checkGetterPreconditions(column);
1054            String JavaDoc result = null;
1055            if (wasNonNullSensitiveUpdate(column)) {
1056                result = (String JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.CHAR, updatedColumns_[column - 1]);
1057            } else {
1058                result = isNull(column) ? null : cursor_.getString(column);
1059            }
1060            if (agent_.loggingEnabled()) {
1061                agent_.logWriter_.traceExit(this, "getString", result);
1062            }
1063            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1064
return result;
1065        }
1066        catch ( SqlException se )
1067        {
1068            throw se.getSQLException();
1069        }
1070    }
1071
1072    // Live life on the edge and run unsynchronized
1073
public byte[] getBytes(int column) throws SQLException JavaDoc {
1074        try
1075        {
1076            closeCloseFilterInputStream();
1077
1078            if (agent_.loggingEnabled()) {
1079                agent_.logWriter_.traceEntry(this, "getBytes", column);
1080            }
1081            checkGetterPreconditions(column);
1082            byte[] result = null;
1083            if (wasNonNullSensitiveUpdate(column)) {
1084                result = (byte[]) agent_.crossConverters_.setObject(java.sql.Types.BINARY, updatedColumns_[column - 1]);
1085            } else {
1086                result = isNull(column) ? null : cursor_.getBytes(column);
1087            }
1088            if (agent_.loggingEnabled()) {
1089                agent_.logWriter_.traceExit(this, "getBytes", result);
1090            }
1091            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1092
return result;
1093        }
1094        catch ( SqlException se )
1095        {
1096            throw se.getSQLException();
1097        }
1098    }
1099
1100    // Live life on the edge and run unsynchronized
1101
public java.io.InputStream JavaDoc getBinaryStream(int column) throws SQLException JavaDoc {
1102        try
1103        {
1104            closeCloseFilterInputStream();
1105
1106            if (agent_.loggingEnabled()) {
1107                agent_.logWriter_.traceEntry(this, "getBinaryStream", column);
1108            }
1109
1110            checkGetterPreconditions(column);
1111        useStream(column);
1112
1113            java.io.InputStream JavaDoc result = null;
1114            if (wasNonNullSensitiveUpdate(column)) {
1115                result = new java.io.ByteArrayInputStream JavaDoc((byte[]) agent_.crossConverters_.setObject(java.sql.Types.BINARY, updatedColumns_[column - 1]));
1116            } else {
1117                result = isNull(column) ? null : cursor_.getBinaryStream(column);
1118            }
1119            if (agent_.loggingEnabled()) {
1120                agent_.logWriter_.traceExit(this, "getBinaryStream", result);
1121            }
1122            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1123
return createCloseFilterInputStream(result);
1124        }
1125        catch ( SqlException se )
1126        {
1127            throw se.getSQLException();
1128        }
1129    }
1130
1131    // Live life on the edge and run unsynchronized
1132
public java.io.InputStream JavaDoc getAsciiStream(int column) throws SQLException JavaDoc {
1133        try
1134        {
1135            closeCloseFilterInputStream();
1136
1137            if (agent_.loggingEnabled()) {
1138                agent_.logWriter_.traceEntry(this, "getAsciiStream", column);
1139            }
1140
1141            checkGetterPreconditions(column);
1142        useStream(column);
1143
1144            java.io.InputStream JavaDoc result = null;
1145            if (wasNonNullSensitiveUpdate(column)) {
1146
1147            result = new AsciiStream((String JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.CHAR,
1148                                                updatedColumns_[column - 1]));
1149            } else {
1150                result = isNull(column) ? null : cursor_.getAsciiStream(column);
1151            }
1152            if (agent_.loggingEnabled()) {
1153                agent_.logWriter_.traceExit(this, "getAsciiStream", result);
1154            }
1155            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1156
return createCloseFilterInputStream(result);
1157        }
1158        catch ( SqlException se )
1159        {
1160            throw se.getSQLException();
1161        }
1162    }
1163
1164    /**
1165     * Retrieve the value of the specified column as a stream of two-byte
1166     * Unicode characters. Deprecated in JDBC 2.0 and this method will just
1167     * throw a feature not implemented exception.
1168     *
1169     * @param column the column to retrieve as a Unicode stream
1170     * @exception SQLException throws feature not implemented
1171     */

1172    public java.io.InputStream JavaDoc getUnicodeStream(int column) throws SQLException JavaDoc {
1173        if (agent_.loggingEnabled()) {
1174            agent_.logWriter_.traceDeprecatedEntry(this, "getUnicodeStream",
1175                                                   column);
1176        }
1177
1178        throw SQLExceptionFactory.notImplemented ("getUnicodeStream");
1179    }
1180
1181    // Live life on the edge and run unsynchronized
1182
public java.io.Reader JavaDoc getCharacterStream(int column) throws SQLException JavaDoc {
1183        try
1184        {
1185            closeCloseFilterInputStream();
1186
1187            if (agent_.loggingEnabled()) {
1188                agent_.logWriter_.traceEntry(this, "getCharacterStream", column);
1189            }
1190
1191            checkGetterPreconditions(column);
1192        useStream(column);
1193
1194            java.io.Reader JavaDoc result = null;
1195            if (wasNonNullSensitiveUpdate(column)) {
1196                result = new java.io.StringReader JavaDoc
1197                        ((String JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.CHAR, updatedColumns_[column - 1]));
1198            } else {
1199                result = isNull(column) ? null : cursor_.getCharacterStream(column);
1200            }
1201            if (agent_.loggingEnabled()) {
1202                agent_.logWriter_.traceExit(this, "getCharacterStream", result);
1203            }
1204            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1205
return result;
1206        }
1207        catch ( SqlException se )
1208        {
1209            throw se.getSQLException();
1210        }
1211    }
1212
1213    // Live life on the edge and run unsynchronized
1214
public java.sql.Blob JavaDoc getBlob(int column) throws SQLException JavaDoc {
1215        try
1216        {
1217            closeCloseFilterInputStream();
1218
1219            if (agent_.loggingEnabled()) {
1220                agent_.logWriter_.traceEntry(this, "getBlob", column);
1221            }
1222            checkGetterPreconditions(column);
1223            java.sql.Blob JavaDoc result = null;
1224            if (wasNonNullSensitiveUpdate(column)) {
1225                result = (java.sql.Blob JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.BLOB,
1226                        updatedColumns_[column - 1]);
1227            } else {
1228                result = isNull(column) ? null : cursor_.getBlob(column);
1229            }
1230            if (agent_.loggingEnabled()) {
1231                agent_.logWriter_.traceExit(this, "getBlob", result);
1232            }
1233            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1234
return result;
1235        }
1236        catch ( SqlException se )
1237        {
1238            throw se.getSQLException();
1239        }
1240    }
1241
1242    // Live life on the edge and run unsynchronized
1243
public java.sql.Clob JavaDoc getClob(int column) throws SQLException JavaDoc {
1244        try
1245        {
1246            closeCloseFilterInputStream();
1247
1248            if (agent_.loggingEnabled()) {
1249                agent_.logWriter_.traceEntry(this, "getClob", column);
1250            }
1251            checkGetterPreconditions(column);
1252            java.sql.Clob JavaDoc result = null;
1253            if (wasNonNullSensitiveUpdate(column)) {
1254                result = (java.sql.Clob JavaDoc) agent_.crossConverters_.setObject(java.sql.Types.CLOB,
1255                        updatedColumns_[column - 1]);
1256            } else {
1257                result = isNull(column) ? null : cursor_.getClob(column);
1258            }
1259            if (agent_.loggingEnabled()) {
1260                agent_.logWriter_.traceExit(this, "getClob", result);
1261            }
1262            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1263
return result;
1264        }
1265        catch ( SqlException se )
1266        {
1267            throw se.getSQLException();
1268        }
1269    }
1270
1271    // Live life on the edge and run unsynchronized
1272
public java.sql.Ref JavaDoc getRef(int column) throws SQLException JavaDoc {
1273        try
1274        {
1275            closeCloseFilterInputStream();
1276
1277            if (agent_.loggingEnabled()) {
1278                agent_.logWriter_.traceEntry(this, "getRef", column);
1279            }
1280            checkGetterPreconditions(column);
1281            java.sql.Ref JavaDoc result = isNull(column) ? null : cursor_.getRef(column);
1282            if (true) {
1283                throw new SqlException(agent_.logWriter_,
1284                    new ClientMessageId(SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1285            }
1286            if (agent_.loggingEnabled()) {
1287                agent_.logWriter_.traceExit(this, "getRef", result);
1288            }
1289            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1290
return result;
1291        }
1292        catch ( SqlException se )
1293        {
1294            throw se.getSQLException();
1295        }
1296    }
1297
1298    // Live life on the edge and run unsynchronized
1299
public java.sql.Array JavaDoc getArray(int column) throws SQLException JavaDoc {
1300        try
1301        {
1302            closeCloseFilterInputStream();
1303
1304            if (agent_.loggingEnabled()) {
1305                agent_.logWriter_.traceEntry(this, "getArray", column);
1306            }
1307            checkGetterPreconditions(column);
1308            java.sql.Array JavaDoc result = isNull(column) ? null : cursor_.getArray(column);
1309            if (true) {
1310                throw new SqlException(agent_.logWriter_,
1311                    new ClientMessageId(SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1312            }
1313            if (agent_.loggingEnabled()) {
1314                agent_.logWriter_.traceExit(this, "getArray", result);
1315            }
1316            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1317
return result;
1318        }
1319        catch ( SqlException se )
1320        {
1321            throw se.getSQLException();
1322        }
1323    }
1324
1325    // Live life on the edge and run unsynchronized
1326
public Object JavaDoc getObject(int column) throws SQLException JavaDoc {
1327        try
1328        {
1329            closeCloseFilterInputStream();
1330
1331            if (agent_.loggingEnabled()) {
1332                agent_.logWriter_.traceEntry(this, "getObject", column);
1333            }
1334            Object JavaDoc result = getObjectX(column);
1335            if (agent_.loggingEnabled()) {
1336                agent_.logWriter_.traceExit(this, "getObject", result);
1337            }
1338            return result;
1339        }
1340        catch ( SqlException se )
1341        {
1342            throw se.getSQLException();
1343        }
1344    }
1345
1346    // used by DBMD
1347
Object JavaDoc getObjectX(int column) throws SqlException {
1348        checkGetterPreconditions(column);
1349        Object JavaDoc result = null;
1350        if (wasNonNullSensitiveUpdate(column)) {
1351            result = updatedColumns_[column - 1];
1352        } else {
1353            result = isNull(column) ? null : cursor_.getObject(column);
1354        }
1355        setWasNull(column); // Placed close to the return to minimize risk of thread interference
1356
return result;
1357    }
1358
1359    // Live life on the edge and run unsynchronized
1360
public Object JavaDoc getObject(int column, java.util.Map JavaDoc map) throws SQLException JavaDoc {
1361        try
1362        {
1363            closeCloseFilterInputStream();
1364
1365            if (agent_.loggingEnabled()) {
1366                agent_.logWriter_.traceEntry(this, "getObject", column, map);
1367            }
1368            checkGetterPreconditions(column);
1369            Object JavaDoc result = null;
1370            if (wasNonNullSensitiveUpdate(column)) {
1371                result = updatedColumns_[column - 1];
1372            } else {
1373                result = isNull(column) ? null : cursor_.getObject(column);
1374            }
1375            if (true) {
1376                throw new SqlException(agent_.logWriter_,
1377                    new ClientMessageId(SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1378            }
1379            if (agent_.loggingEnabled()) {
1380                agent_.logWriter_.traceExit(this, "getObject", result);
1381            }
1382            setWasNull(column); // Placed close to the return to minimize risk of thread interference
1383
return result;
1384        }
1385        catch ( SqlException se )
1386        {
1387            throw se.getSQLException();
1388        }
1389    }
1390
1391    //----------------------------------------------------------------------------
1392

1393    // This method only returns true if there is a new non-null updated value.
1394
// If the resultset is updatable, sensitive, and updated, return the new non-null updated value.
1395
// Otherwise this method will return false.
1396
// If the column is updated to null, or if the column has not been update but is null,
1397
// a null will be returned by isNull(), which first calls wasNullSensitiveUpdate() to check for a column
1398
// that is updated to null, and columnUpdated_ is checked there.
1399
private boolean wasNonNullSensitiveUpdate(int column) {
1400        return
1401                updatedColumns_ != null &&
1402                updatedColumns_[column - 1] != null;
1403    }
1404
1405    // if updatedColumns_ entry is null, but columnUpdated_ entry
1406
// indicates column has been updated, then column is updated to null.
1407
private boolean wasNullSensitiveUpdate(int column) {
1408        return
1409                updatedColumns_ != null &&
1410                updatedColumns_[column - 1] == null &&
1411                columnUpdated_[column - 1];
1412    }
1413
1414    private void setWasNull(int column) {
1415        if (wasNullSensitiveUpdate(column) || (isOnInsertRow_ && updatedColumns_[column - 1] == null)) {
1416            wasNull_ = WAS_NULL;
1417        } else {
1418            wasNull_ = (cursor_.isNull_ == null || cursor_.isNull_[column - 1]) ? WAS_NULL : WAS_NOT_NULL;
1419        }
1420    }
1421
1422    private boolean isNull(int column) {
1423        if (wasNullSensitiveUpdate(column)) {
1424            return true;
1425        } else {
1426            return (cursor_.isUpdateDeleteHole_ == true || cursor_.isNull_[column - 1]);
1427        }
1428    }
1429
1430    // ------------- Methods for accessing results by column name ----------------
1431

1432    public final boolean getBoolean(String JavaDoc columnName) throws SQLException JavaDoc {
1433        try
1434        {
1435            if (agent_.loggingEnabled()) {
1436                agent_.logWriter_.traceEntry(this, "getBoolean", columnName);
1437            }
1438            return getBoolean(findColumnX(columnName));
1439        }
1440        catch ( SqlException se )
1441        {
1442            throw se.getSQLException();
1443        }
1444    }
1445
1446    public final byte getByte(String JavaDoc columnName) throws SQLException JavaDoc {
1447        try
1448        {
1449            if (agent_.loggingEnabled()) {
1450                agent_.logWriter_.traceEntry(this, "getByte", columnName);
1451            }
1452            return getByte(findColumnX(columnName));
1453        }
1454        catch ( SqlException se )
1455        {
1456            throw se.getSQLException();
1457        }
1458    }
1459
1460    public final short getShort(String JavaDoc columnName) throws SQLException JavaDoc {
1461        try
1462        {
1463            if (agent_.loggingEnabled()) {
1464                agent_.logWriter_.traceEntry(this, "getShort", columnName);
1465            }
1466            return getShort(findColumnX(columnName));
1467        }
1468        catch ( SqlException se )
1469        {
1470            throw se.getSQLException();
1471        }
1472    }
1473
1474    public final int getInt(String JavaDoc columnName) throws SQLException JavaDoc {
1475        try
1476        {
1477            if (agent_.loggingEnabled()) {
1478                agent_.logWriter_.traceEntry(this, "getInt", columnName);
1479            }
1480            return getInt(findColumnX(columnName));
1481        }
1482        catch ( SqlException se )
1483        {
1484            throw se.getSQLException();
1485        }
1486    }
1487
1488    public final long getLong(String JavaDoc columnName) throws SQLException JavaDoc {
1489        try
1490        {
1491            if (agent_.loggingEnabled()) {
1492                agent_.logWriter_.traceEntry(this, "getLong", columnName);
1493            }
1494            return getLong(findColumnX(columnName));
1495        }
1496        catch ( SqlException se )
1497        {
1498            throw se.getSQLException();
1499        }
1500    }
1501
1502    public final float getFloat(String JavaDoc columnName) throws SQLException JavaDoc {
1503        try
1504        {
1505            if (agent_.loggingEnabled()) {
1506                agent_.logWriter_.traceEntry(this, "getFloat", columnName);
1507            }
1508            return getFloat(findColumnX(columnName));
1509        }
1510        catch ( SqlException se )
1511        {
1512            throw se.getSQLException();
1513        }
1514    }
1515
1516    public final double getDouble(String JavaDoc columnName) throws SQLException JavaDoc {
1517        try
1518        {
1519            if (agent_.loggingEnabled()) {
1520                agent_.logWriter_.traceEntry(this, "getDouble", columnName);
1521            }
1522            return getDouble(findColumnX(columnName));
1523        }
1524        catch ( SqlException se )
1525        {
1526            throw se.getSQLException();
1527        }
1528    }
1529
1530    public final java.math.BigDecimal JavaDoc getBigDecimal(String JavaDoc columnName, int scale) throws SQLException JavaDoc {
1531        try
1532        {
1533            if (agent_.loggingEnabled()) {
1534                agent_.logWriter_.traceDeprecatedEntry(this, "getBigDecimal", columnName, scale);
1535            }
1536            return getBigDecimal(findColumnX(columnName), scale);
1537        }
1538        catch ( SqlException se )
1539        {
1540            throw se.getSQLException();
1541        }
1542    }
1543
1544    public final java.math.BigDecimal JavaDoc getBigDecimal(String JavaDoc columnName) throws SQLException JavaDoc {
1545        try
1546        {
1547            if (agent_.loggingEnabled()) {
1548                agent_.logWriter_.traceEntry(this, "getBigDecimal", columnName);
1549            }
1550            return getBigDecimal(findColumnX(columnName));
1551        }
1552        catch ( SqlException se )
1553        {
1554            throw se.getSQLException();
1555        }
1556    }
1557
1558    public final java.sql.Date JavaDoc getDate(String JavaDoc columnName) throws SQLException JavaDoc {
1559        try
1560        {
1561            if (agent_.loggingEnabled()) {
1562                agent_.logWriter_.traceEntry(this, "getDate", columnName);
1563            }
1564            return getDate(findColumnX(columnName));
1565        }
1566        catch ( SqlException se )
1567        {
1568            throw se.getSQLException();
1569        }
1570    }
1571
1572    public final java.sql.Date JavaDoc getDate(String JavaDoc columnName, java.util.Calendar JavaDoc cal) throws SQLException JavaDoc {
1573        try
1574        {
1575            if (agent_.loggingEnabled()) {
1576                agent_.logWriter_.traceEntry(this, "getDate", columnName, cal);
1577            }
1578            return getDate(findColumnX(columnName), cal);
1579        }
1580        catch ( SqlException se )
1581        {
1582            throw se.getSQLException();
1583        }
1584    }
1585
1586    public final java.sql.Time JavaDoc getTime(String JavaDoc columnName) throws SQLException JavaDoc {
1587        try
1588        {
1589            if (agent_.loggingEnabled()) {
1590                agent_.logWriter_.traceEntry(this, "getTime", columnName);
1591            }
1592            return getTime(findColumnX(columnName));
1593        }
1594        catch ( SqlException se )
1595        {
1596            throw se.getSQLException();
1597        }
1598    }
1599
1600    public final java.sql.Time JavaDoc getTime(String JavaDoc columnName, java.util.Calendar JavaDoc cal) throws SQLException JavaDoc {
1601        try
1602        {
1603            if (agent_.loggingEnabled()) {
1604                agent_.logWriter_.traceEntry(this, "getTime", columnName, cal);
1605            }
1606            return getTime(findColumnX(columnName), cal);
1607        }
1608        catch ( SqlException se )
1609        {
1610            throw se.getSQLException();
1611        }
1612    }
1613
1614    public final java.sql.Timestamp JavaDoc getTimestamp(String JavaDoc columnName) throws SQLException JavaDoc {
1615        try
1616        {
1617            if (agent_.loggingEnabled()) {
1618                agent_.logWriter_.traceEntry(this, "getTimestamp", columnName);
1619            }
1620            return getTimestamp(findColumnX(columnName));
1621        }
1622        catch ( SqlException se )
1623        {
1624            throw se.getSQLException();
1625        }
1626    }
1627
1628    public final java.sql.Timestamp JavaDoc getTimestamp(String JavaDoc columnName, java.util.Calendar JavaDoc cal) throws SQLException JavaDoc {
1629        try
1630        {
1631            if (agent_.loggingEnabled()) {
1632                agent_.logWriter_.traceEntry(this, "getTimestamp", columnName, cal);
1633            }
1634            return getTimestamp(findColumnX(columnName), cal);
1635        }
1636        catch ( SqlException se )
1637        {
1638            throw se.getSQLException();
1639        }
1640    }
1641
1642    public final String JavaDoc getString(String JavaDoc columnName) throws SQLException JavaDoc {
1643        try
1644        {
1645            if (agent_.loggingEnabled()) {
1646                agent_.logWriter_.traceEntry(this, "getString", columnName);
1647            }
1648            return getString(findColumnX(columnName));
1649        }
1650        catch ( SqlException se )
1651        {
1652            throw se.getSQLException();
1653        }
1654    }
1655
1656    public final byte[] getBytes(String JavaDoc columnName) throws SQLException JavaDoc {
1657        try
1658        {
1659            if (agent_.loggingEnabled()) {
1660                agent_.logWriter_.traceEntry(this, "getBytes", columnName);
1661            }
1662            return getBytes(findColumnX(columnName));
1663        }
1664        catch ( SqlException se )
1665        {
1666            throw se.getSQLException();
1667        }
1668    }
1669
1670    public final java.io.InputStream JavaDoc getBinaryStream(String JavaDoc columnName) throws SQLException JavaDoc {
1671        try
1672        {
1673            if (agent_.loggingEnabled()) {
1674                agent_.logWriter_.traceEntry(this, "getBinaryStream", columnName);
1675            }
1676            return getBinaryStream(findColumnX(columnName));
1677        }
1678        catch ( SqlException se )
1679        {
1680            throw se.getSQLException();
1681        }
1682    }
1683
1684    public final java.io.InputStream JavaDoc getAsciiStream(String JavaDoc columnName) throws SQLException JavaDoc {
1685        try
1686        {
1687            if (agent_.loggingEnabled()) {
1688                agent_.logWriter_.traceEntry(this, "getAsciiStream", columnName);
1689            }
1690            return getAsciiStream(findColumnX(columnName));
1691        }
1692        catch ( SqlException se )
1693        {
1694            throw se.getSQLException();
1695        }
1696    }
1697
1698    public final java.io.InputStream JavaDoc getUnicodeStream(String JavaDoc columnName) throws SQLException JavaDoc {
1699        try
1700        {
1701            if (agent_.loggingEnabled()) {
1702                agent_.logWriter_.traceDeprecatedEntry(this, "getUnicodeStream", columnName);
1703            }
1704            return getUnicodeStream(findColumnX(columnName));
1705        }
1706        catch ( SqlException se )
1707        {
1708            throw se.getSQLException();
1709        }
1710    }
1711
1712    public final java.io.Reader JavaDoc getCharacterStream(String JavaDoc columnName) throws SQLException JavaDoc {
1713        try
1714        {
1715            if (agent_.loggingEnabled()) {
1716                agent_.logWriter_.traceEntry(this, "getCharacterStream", columnName);
1717            }
1718            return getCharacterStream(findColumnX(columnName));
1719        }
1720        catch ( SqlException se )
1721        {
1722            throw se.getSQLException();
1723        }
1724    }
1725
1726    public final java.sql.Blob JavaDoc getBlob(String JavaDoc columnName) throws SQLException JavaDoc {
1727        try
1728        {
1729            if (agent_.loggingEnabled()) {
1730                agent_.logWriter_.traceEntry(this, "getBlob", columnName);
1731            }
1732            return getBlob(findColumnX(columnName));
1733        }
1734        catch ( SqlException se )
1735        {
1736            throw se.getSQLException();
1737        }
1738    }
1739
1740    public final java.sql.Clob JavaDoc getClob(String JavaDoc columnName) throws SQLException JavaDoc {
1741        try
1742        {
1743            if (agent_.loggingEnabled()) {
1744                agent_.logWriter_.traceEntry(this, "getClob", columnName);
1745            }
1746            return getClob(findColumnX(columnName));
1747        }
1748        catch ( SqlException se )
1749        {
1750            throw se.getSQLException();
1751        }
1752    }
1753
1754    public final java.sql.Array JavaDoc getArray(String JavaDoc columnName) throws SQLException JavaDoc {
1755        try
1756        {
1757            if (agent_.loggingEnabled()) {
1758                agent_.logWriter_.traceEntry(this, "getArray", columnName);
1759            }
1760            return getArray(findColumnX(columnName));
1761        }
1762        catch ( SqlException se )
1763        {
1764            throw se.getSQLException();
1765        }
1766    }
1767
1768    public final java.sql.Ref JavaDoc getRef(String JavaDoc columnName) throws SQLException JavaDoc {
1769        try
1770        {
1771            if (agent_.loggingEnabled()) {
1772                agent_.logWriter_.traceEntry(this, "getRef", columnName);
1773            }
1774            return getRef(findColumnX(columnName));
1775        }
1776        catch ( SqlException se )
1777        {
1778            throw se.getSQLException();
1779        }
1780    }
1781
1782    public final Object JavaDoc getObject(String JavaDoc columnName) throws SQLException JavaDoc {
1783        try
1784        {
1785            if (agent_.loggingEnabled()) {
1786                agent_.logWriter_.traceEntry(this, "getObject", columnName);
1787            }
1788            return getObject(findColumnX(columnName));
1789        }
1790        catch ( SqlException se )
1791        {
1792            throw se.getSQLException();
1793        }
1794    }
1795
1796    public final Object JavaDoc getObject(String JavaDoc columnName, java.util.Map JavaDoc map) throws SQLException JavaDoc {
1797        try
1798        {
1799            if (agent_.loggingEnabled()) {
1800                agent_.logWriter_.traceEntry(this, "getObject", columnName, map);
1801            }
1802            return getObject(findColumnX(columnName), map);
1803        }
1804        catch ( SqlException se )
1805        {
1806            throw se.getSQLException();
1807        }
1808    }
1809
1810    // ----------------Advanced features -----------------------------------------
1811

1812    /**
1813     * Returns the first <code>SQLWarning</code> reported on this
1814     * <code>ResultSet</code> object, or <code>null</code> if there
1815     * are no warnings. Subsequent warnings are chained on the
1816     * returned object.
1817     *
1818     * @return the first <code>SQLWarning</code> in the chain, or
1819     * <code>null</code> if no warnings are reported
1820     * @exception SQLException if a database error occurs or the
1821     * result set is closed
1822     */

1823    public final java.sql.SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc {
1824        try {
1825            checkForClosedResultSet();
1826        } catch (SqlException se) {
1827            throw se.getSQLException();
1828        }
1829        if (agent_.loggingEnabled()) {
1830            agent_.logWriter_.traceExit(this, "getWarnings", warnings_);
1831        }
1832        return warnings_ == null ? null : warnings_.getSQLWarning();
1833    }
1834
1835    /**
1836     * Clear all warnings on this <code>ResultSet</code> and make
1837     * subsequent calls to <code>getWarnings()</code> return
1838     * <code>null</code> until a new warning is reported.
1839     *
1840     * @exception SQLException if a database error occurs or the
1841     * result set is closed
1842     */

1843    public final void clearWarnings() throws SQLException JavaDoc {
1844        synchronized (connection_) {
1845            if (agent_.loggingEnabled()) {
1846                agent_.logWriter_.traceEntry(this, "clearWarnings");
1847            }
1848            try {
1849                checkForClosedResultSet();
1850            } catch (SqlException se) {
1851                throw se.getSQLException();
1852            }
1853            clearWarningsX();
1854        }
1855    }
1856
1857    // An untraced version of clearWarnings()
1858
public final void clearWarningsX() {
1859        warnings_ = null;
1860    }
1861
1862    public String JavaDoc getCursorName() throws SQLException JavaDoc {
1863        try
1864        {
1865            synchronized (connection_) {
1866                if (agent_.loggingEnabled()) {
1867                    agent_.logWriter_.traceEntry(this, "getCursorName");
1868                }
1869                checkForClosedResultSet();
1870                if (generatedSection_ != null) {
1871                    return "stored procedure generated cursor:" + generatedSection_.getServerCursorName();
1872                }
1873                if (statement_.cursorName_ == null) {// cursor name is not assigned yet
1874
statement_.cursorName_ = statement_.section_.getServerCursorName();
1875                }
1876                if (agent_.loggingEnabled()) {
1877                    agent_.logWriter_.traceExit(this, "getCursorName", statement_.cursorName_);
1878                }
1879                return statement_.cursorName_;
1880            }
1881        }
1882        catch ( SqlException se )
1883        {
1884            throw se.getSQLException();
1885        }
1886    }
1887
1888    public java.sql.ResultSetMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
1889        try
1890        {
1891            if (agent_.loggingEnabled()) {
1892                agent_.logWriter_.traceEntry(this, "getMetaData");
1893            }
1894            java.sql.ResultSetMetaData JavaDoc resultSetMetaData = getMetaDataX();
1895            if (agent_.loggingEnabled()) {
1896                agent_.logWriter_.traceExit(this, "getMetaData", resultSetMetaData);
1897            }
1898            return resultSetMetaData;
1899        }
1900        catch ( SqlException se )
1901        {
1902            throw se.getSQLException();
1903        }
1904    }
1905
1906    // used by DBMD
1907
ColumnMetaData getMetaDataX() throws SqlException {
1908        checkForClosedResultSet();
1909        return resultSetMetaData_;
1910    }
1911
1912
1913    public final int findColumn(String JavaDoc columnName) throws SQLException JavaDoc {
1914        try
1915        {
1916            synchronized (connection_) {
1917                if (agent_.loggingEnabled()) {
1918                    agent_.logWriter_.traceEntry(this, "findColumn", columnName);
1919                }
1920                int column = findColumnX(columnName);
1921                if (agent_.loggingEnabled()) {
1922                    agent_.logWriter_.traceExit(this, "findColumn", column);
1923                }
1924                return column;
1925            }
1926        }
1927        catch ( SqlException se )
1928        {
1929            throw se.getSQLException();
1930        }
1931    }
1932
1933    // An untraced version of findColumn()
1934
private final int findColumnX(String JavaDoc columnName) throws SqlException {
1935        checkForClosedResultSet();
1936        return resultSetMetaData_.findColumnX(columnName);
1937    }
1938
1939    //-------------------------- Traversal/Positioning ---------------------------
1940

1941    public boolean isBeforeFirst() throws SQLException JavaDoc {
1942        try
1943        {
1944            if (agent_.loggingEnabled()) {
1945                agent_.logWriter_.traceEntry(this, "isBeforeFirst");
1946            }
1947            checkForClosedResultSet();
1948            checkThatResultSetTypeIsScrollable();
1949            // Returns false if the ResultSet contains no rows.
1950
boolean isBeforeFirst = isBeforeFirstX();
1951            if (agent_.loggingEnabled()) {
1952                agent_.logWriter_.traceExit(this, "isBeforeFirst", isBeforeFirst);
1953            }
1954            return isBeforeFirst;
1955        }
1956        catch ( SqlException se )
1957        {
1958            throw se.getSQLException();
1959        }
1960    }
1961
1962    private boolean isBeforeFirstX() throws SqlException {
1963        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
1964            return isBeforeFirst_;
1965        } else
1966        //return ((resultSetContainsNoRows()) ? false : (currentRowInRowset_ == -1));
1967
{
1968            return ((currentRowInRowset_ == -1) && !resultSetContainsNoRows());
1969        }
1970    }
1971
1972    public boolean isAfterLast() throws SQLException JavaDoc {
1973        try
1974        {
1975            if (agent_.loggingEnabled()) {
1976                agent_.logWriter_.traceEntry(this, "isAfterLast");
1977            }
1978            checkForClosedResultSet();
1979            checkThatResultSetTypeIsScrollable();
1980            // Returns false if the ResultSet contains no rows.
1981
boolean isAfterLast = isAfterLastX();
1982            if (agent_.loggingEnabled()) {
1983                agent_.logWriter_.traceExit(this, "isAfterLast", isAfterLast);
1984            }
1985            return isAfterLast;
1986        }
1987        catch ( SqlException se )
1988        {
1989            throw se.getSQLException();
1990        }
1991    }
1992
1993    private boolean isAfterLastX() throws SqlException {
1994        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
1995            return isAfterLast_;
1996        } else {
1997            return (resultSetContainsNoRows() ? false :
1998                    (firstRowInRowset_ == currentRowInRowset_ &&
1999                    currentRowInRowset_ == lastRowInRowset_ &&
2000                    lastRowInRowset_ == 0 &&
2001                    absolutePosition_ == (maxRows_ == 0 ? rowCount_ + 1 : maxRows_ + 1)));
2002        }
2003    }
2004
2005    public boolean isFirst() throws SQLException JavaDoc {
2006        try
2007        {
2008            if (agent_.loggingEnabled()) {
2009                agent_.logWriter_.traceEntry(this, "isFirst");
2010            }
2011            checkForClosedResultSet();
2012            checkThatResultSetTypeIsScrollable();
2013            // Not necessary to get the rowCount_ since currentRowInRowset_ is initialized to -1,
2014
// and it will not be changed if there is no rows in the ResultSet.
2015
boolean isFirst = isFirstX();
2016            if (agent_.loggingEnabled()) {
2017                agent_.logWriter_.traceExit(this, "isFirst", isFirst);
2018            }
2019            return isFirst;
2020        }
2021        catch ( SqlException se )
2022        {
2023            throw se.getSQLException();
2024        }
2025    }
2026
2027    private boolean isFirstX() {
2028        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2029            return isFirst_;
2030        }
2031        return (firstRowInRowset_ == 1 && currentRowInRowset_ == 0);
2032    }
2033
2034    public boolean isLast() throws SQLException JavaDoc {
2035        try
2036        {
2037            if (agent_.loggingEnabled()) {
2038                agent_.logWriter_.traceEntry(this, "isLast");
2039            }
2040            checkForClosedResultSet();
2041            checkThatResultSetTypeIsScrollable();
2042            // Returns false if the ResultSet contains no rows.
2043
boolean isLast = isLastX();
2044            if (agent_.loggingEnabled()) {
2045                agent_.logWriter_.traceExit(this, "isLast", isLast);
2046            }
2047            return isLast;
2048        }
2049        catch ( SqlException se )
2050        {
2051            throw se.getSQLException();
2052        }
2053    }
2054
2055    private boolean isLastX() throws SqlException {
2056        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2057            return isLast_;
2058        } else {
2059            return (resultSetContainsNoRows() ? false :
2060                    (firstRowInRowset_ + currentRowInRowset_) == rowCount_);
2061        }
2062    }
2063
2064    public void beforeFirst() throws SQLException JavaDoc {
2065        try
2066        {
2067            synchronized (connection_) {
2068                if (agent_.loggingEnabled()) {
2069                    agent_.logWriter_.traceEntry(this, "beforeFirst");
2070                }
2071                checkForClosedResultSet();
2072                checkThatResultSetTypeIsScrollable();
2073                clearWarningsX();
2074                beforeFirstX();
2075            }
2076        }
2077        catch ( SqlException se )
2078        {
2079            throw se.getSQLException();
2080        }
2081    }
2082
2083    private void beforeFirstX() throws SqlException {
2084        
2085    resetRowsetFlags();
2086    unuseStreams();
2087
2088        moveToCurrentRowX();
2089
2090        // this method has no effect if the result set has no rows.
2091
// only send cntqry to position the cursor before first if
2092
// resultset contains rows and it is not already before first, or
2093
// if the cursor is a dynamic cursor.
2094
if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
2095                (!resultSetContainsNoRows() && !isServersCursorPositionBeforeFirst())) {
2096            moveToBeforeFirst();
2097        }
2098        isBeforeFirst_ = true;
2099        setRowsetBeforeFirstEvent();
2100        cursor_.resetDataBuffer();
2101        resetRowsetSqlca();
2102        isValidCursorPosition_ = false;
2103    }
2104
2105    public void afterLast() throws SQLException JavaDoc {
2106        try
2107        {
2108            synchronized (connection_) {
2109                if (agent_.loggingEnabled()) {
2110                    agent_.logWriter_.traceEntry(this, "afterLast");
2111                }
2112                checkForClosedResultSet();
2113                checkThatResultSetTypeIsScrollable();
2114                clearWarningsX();
2115                afterLastX();
2116            }
2117        }
2118        catch ( SqlException se )
2119        {
2120            throw se.getSQLException();
2121        }
2122    }
2123
2124    private void afterLastX() throws SqlException {
2125        resetRowsetFlags();
2126    unuseStreams();
2127    
2128        moveToCurrentRowX();
2129
2130        // this method has no effect if the result set has no rows.
2131
// only send cntqry to position the cursor after last if
2132
// resultset contains rows and it is not already after last, or
2133
// if the cursor is a dynamic cursor.
2134
if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
2135                (!resultSetContainsNoRows() && !isServerCursorPositionAfterLast())) {
2136            moveToAfterLast();
2137        }
2138        isAfterLast_ = true;
2139        setRowsetAfterLastEvent();
2140        cursor_.resetDataBuffer();
2141        resetRowsetSqlca();
2142        isValidCursorPosition_ = false;
2143    }
2144
2145    public boolean first() throws SQLException JavaDoc {
2146        try
2147        {
2148            synchronized (connection_) {
2149                if (agent_.loggingEnabled()) {
2150                    agent_.logWriter_.traceEntry(this, "first");
2151                }
2152                boolean isValidCursorPosition = firstX();
2153                if (agent_.loggingEnabled()) {
2154                    agent_.logWriter_.traceExit(this, "first", isValidCursorPosition);
2155                }
2156                return isValidCursorPosition;
2157            }
2158        }
2159        catch ( SqlException se )
2160        {
2161            throw se.getSQLException();
2162        }
2163    }
2164
2165    private boolean firstX() throws SqlException {
2166        checkForClosedResultSet();
2167        checkThatResultSetTypeIsScrollable();
2168        clearWarningsX();
2169        
2170        moveToCurrentRowX();
2171
2172        wasNull_ = ResultSet.WAS_NULL_UNSET;
2173
2174        // discard all previous updates when moving the cursor
2175
resetUpdatedColumns();
2176
2177        resetRowsetFlags();
2178    unuseStreams();
2179
2180        // if first row is not in the current rowset, fetch the first rowset from the server.
2181
// rowIsInCurrentRowset with orientation first will always return false for dynamic cursors.
2182
if (rowIsInCurrentRowset(1, scrollOrientation_first__)) {
2183            isValidCursorPosition_ = true;
2184            currentRowInRowset_ = 0;
2185        } else {
2186            checkAndThrowReceivedQueryTerminatingException();
2187            isValidCursorPosition_ = getFirstRowset();
2188        }
2189
2190        if (isValidCursorPosition_) {
2191            updateColumnInfoFromCache();
2192            isFirst_ = true;
2193            // check if there is a non-null SQLCA for the row for rowset cursors
2194
checkRowsetSqlca();
2195        }
2196
2197        return isValidCursorPosition_;
2198    }
2199
2200    public boolean last() throws SQLException JavaDoc {
2201        try
2202        {
2203            synchronized (connection_) {
2204                if (agent_.loggingEnabled()) {
2205                    agent_.logWriter_.traceEntry(this, "last");
2206                }
2207                boolean isValidCursorPosition = lastX();
2208                if (agent_.loggingEnabled()) {
2209                    agent_.logWriter_.traceExit(this, "last", isValidCursorPosition);
2210                }
2211                return isValidCursorPosition;
2212            }
2213        }
2214        catch ( SqlException se )
2215        {
2216            throw se.getSQLException();
2217        }
2218    }
2219
2220    private boolean lastX() throws SqlException {
2221        checkForClosedResultSet();
2222        checkThatResultSetTypeIsScrollable();
2223        clearWarningsX();
2224        
2225        moveToCurrentRowX();
2226
2227        wasNull_ = ResultSet.WAS_NULL_UNSET;
2228
2229        // discard all previous updates when moving the cursor
2230
resetUpdatedColumns();
2231
2232        resetRowsetFlags();
2233    unuseStreams();
2234
2235        // only get the rowCount for static cursors.
2236
if (rowCountIsUnknown()) {
2237            getRowCount();
2238        }
2239        long row = rowCount_;
2240        if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0) {
2241            if (rowCount_ > maxRows_) {
2242                row = maxRows_;
2243            }
2244        }
2245
2246        // rowIsInCurrentRowset with orientation last will always return false for dynamic cursors.
2247
if (rowIsInCurrentRowset(row, scrollOrientation_last__)) {
2248            isValidCursorPosition_ = true;
2249            currentRowInRowset_ = row - firstRowInRowset_;
2250        } else {
2251            checkAndThrowReceivedQueryTerminatingException();
2252            isValidCursorPosition_ = getLastRowset(row);
2253        }
2254
2255        if (isValidCursorPosition_) {
2256            updateColumnInfoFromCache();
2257            isLast_ = true;
2258            // check if there is a non-null SQLCA for the current row for rowset cursors
2259
checkRowsetSqlca();
2260        }
2261
2262        return isValidCursorPosition_;
2263    }
2264
2265    public int getRow() throws SQLException JavaDoc {
2266        try
2267        {
2268            synchronized (connection_) {
2269                if (agent_.loggingEnabled()) {
2270                    agent_.logWriter_.traceEntry(this, "getRow");
2271                }
2272                int row = getRowX();
2273                if (agent_.loggingEnabled()) {
2274                    agent_.logWriter_.traceExit(this, "getRow", row);
2275                }
2276                return row;
2277            }
2278        }
2279        catch ( SqlException se )
2280        {
2281            throw se.getSQLException();
2282        }
2283    }
2284
2285    private int getRowX() throws SqlException {
2286        checkForClosedResultSet();
2287        long row;
2288        checkThatResultSetIsNotDynamic();
2289        if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
2290        // for forward-only cursors, getRow() should return 0 if cursor is not on a valid row,
2291
// i.e. afterlast.
2292
{
2293            row = (cursor_.allRowsReceivedFromServer() &&
2294                    cursor_.currentRowPositionIsEqualToNextRowPosition()) ? 0 : cursor_.rowsRead_;
2295        } else {
2296            if (rowCountIsUnknown()) {
2297                // commented out here because the following method is called the first thing
2298
// inside getRowCount();
2299
//checkAndThrowReceivedQueryTerminatingException();
2300
getRowCount();
2301            }
2302            if (rowCount_ == 0 || currentRowInRowset_ < 0) // || currentRowInRowset_ > rowCount_)
2303
{
2304                row = 0;
2305            } else {
2306                row = firstRowInRowset_ + currentRowInRowset_;
2307            }
2308        }
2309        if (row > Integer.MAX_VALUE) {
2310            this.accumulateWarning(new SqlWarning(agent_.logWriter_,
2311                new ClientMessageId(SQLState.NUMBER_OF_ROWS_TOO_LARGE_FOR_INT),
2312                new Long JavaDoc(row)));
2313        }
2314        return (int) row;
2315    }
2316
2317    public boolean absolute(int row) throws SQLException JavaDoc {
2318        try
2319        {
2320            synchronized (connection_) {
2321                if (agent_.loggingEnabled()) {
2322                    agent_.logWriter_.traceEntry(this, "absolute", row);
2323                }
2324                boolean isValidCursorPosition = absoluteX(row);
2325                if (agent_.loggingEnabled()) {
2326                    agent_.logWriter_.traceExit(this, "absolute", isValidCursorPosition);
2327                }
2328                return isValidCursorPosition;
2329            }
2330        }
2331        catch ( SqlException se )
2332        {
2333            throw se.getSQLException();
2334        }
2335    }
2336
2337    public boolean absoluteX(int row) throws SqlException {
2338        checkForClosedResultSet();
2339        checkThatResultSetTypeIsScrollable();
2340        clearWarningsX();
2341
2342        moveToCurrentRowX();
2343
2344        wasNull_ = ResultSet.WAS_NULL_UNSET;
2345
2346        // discard all previous updates when moving the cursor.
2347
resetUpdatedColumns();
2348
2349        resetRowsetFlags();
2350    unuseStreams();
2351
2352        if (maxRows_ > 0) {
2353            // if "row" is positive and > maxRows, fetch afterLast
2354
// else if "row" is negative, and abs(row) > maxRows, fetch beforeFirst
2355
if (row > 0 && row > maxRows_) {
2356                afterLastX();
2357                isValidCursorPosition_ = false;
2358                return isValidCursorPosition_;
2359            } else if (row <= 0 && java.lang.Math.abs(row) > maxRows_) {
2360                beforeFirstX();
2361                isValidCursorPosition_ = false;
2362                return isValidCursorPosition_;
2363            }
2364        }
2365
2366        int fetchAbsoluteRow = 0;
2367        if (rowCountIsUnknown()) {
2368            getRowCount();
2369        }
2370        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2371            fetchAbsoluteRow = row;
2372        } else
2373        // calculate the positive absolute row number based on rowCount for static or insensitive cursors.
2374
{
2375            fetchAbsoluteRow = (row >= 0) ? row : (int) (rowCount_ + row + 1);
2376        }
2377
2378        // rowIsInCurrentRowset with orientation absolute will always return false for dynamic cursors.
2379
if (rowIsInCurrentRowset(fetchAbsoluteRow, scrollOrientation_absolute__)) {
2380            isValidCursorPosition_ = true;
2381            currentRowInRowset_ = fetchAbsoluteRow - firstRowInRowset_;
2382        } else {
2383            checkAndThrowReceivedQueryTerminatingException();
2384            isValidCursorPosition_ = getAbsoluteRowset(fetchAbsoluteRow);
2385        }
2386
2387        if (isValidCursorPosition_) {
2388            updateColumnInfoFromCache();
2389            if (row == 1) {
2390                isFirst_ = true;
2391            }
2392            if (row == -1) {
2393                isLast_ = true;
2394            }
2395            // check if there is a non-null SQLCA for the row for rowset cursors
2396
checkRowsetSqlca();
2397        }
2398
2399        return isValidCursorPosition_;
2400    }
2401
2402    public boolean relative(int rows) throws SQLException JavaDoc {
2403        try
2404        {
2405            synchronized (connection_) {
2406                if (agent_.loggingEnabled()) {
2407                    agent_.logWriter_.traceEntry(this, "relative", rows);
2408                }
2409                boolean isValidCursorPosition = relativeX(rows);
2410                if (agent_.loggingEnabled()) {
2411                    agent_.logWriter_.traceExit(this, "relative", isValidCursorPosition);
2412                }
2413                return isValidCursorPosition;
2414            }
2415        }
2416        catch ( SqlException se )
2417        {
2418            throw se.getSQLException();
2419        }
2420    }
2421
2422    private boolean relativeX(int rows) throws SqlException {
2423        checkForClosedResultSet();
2424        checkThatResultSetTypeIsScrollable();
2425        clearWarningsX();
2426        
2427        moveToCurrentRowX();
2428        
2429        wasNull_ = ResultSet.WAS_NULL_UNSET;
2430
2431        // discard all previous updates when moving the cursor.
2432
resetUpdatedColumns();
2433    
2434    unuseStreams();
2435
2436        // If the resultset is empty, relative(n) is a null operation
2437
if (resultSetContainsNoRows()) {
2438            isValidCursorPosition_ = false;
2439            return isValidCursorPosition_;
2440        }
2441        
2442        // relative(0) is a null-operation, but the retruned result is
2443
// dependent on wether the cursorposition is on a row or not.
2444
// Scroll insensitive updatable should see own changes, so relative(0)
2445
// has to refetch the row.
2446
if (rows == 0) {
2447            if (resultSetConcurrency_ == ResultSet.CONCUR_UPDATABLE &&
2448                resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) {
2449                // re-fetch currentRow
2450
isValidCursorPosition_ = getAbsoluteRowset(absolutePosition_);
2451            } else {
2452                if (isBeforeFirstX() || isAfterLastX()) {
2453                    isValidCursorPosition_ = false;
2454                } else {
2455                    isValidCursorPosition_ = true;
2456                }
2457            }
2458            return isValidCursorPosition_;
2459        }
2460
2461        // Handle special cases when the cursor is before first or
2462
// after last, since the following code assumes we ar on a
2463
// valid cursor
2464
if (isBeforeFirstX()) {
2465            if (rows > 0) {
2466                nextX();
2467                return relativeX(rows-1);
2468            } else {
2469                isValidCursorPosition_ = false;
2470                return isValidCursorPosition_;
2471            }
2472        }
2473        if (isAfterLastX()) {
2474            if (rows < 0) {
2475                previousX();
2476                return relativeX(rows+1);
2477            } else {
2478                isValidCursorPosition_ = false;
2479                return isValidCursorPosition_;
2480            }
2481        }
2482        // Ok, now we are on a row and ready to do some real positioning.....
2483

2484        resetRowsetFlags();
2485
2486        // currentAbsoluteRowNumber is used for static cursors only.
2487
long currentAbsoluteRowNumber = firstRowInRowset_ + currentRowInRowset_;
2488
2489        // if "rows" is positive, and currentRow+rows > maxRows, fetch afterLast.
2490
// if "rows" is negative, and if the absolute value of "rows" is greater than
2491
// the currentrow number, will fetch beforeFirst anyways. do not need to check
2492
// for maxRows.
2493
if (sensitivity_ != sensitivity_sensitive_dynamic__ &&
2494                maxRows_ > 0 && rows > 0 && currentAbsoluteRowNumber + rows > maxRows_) {
2495            afterLastX();
2496            isValidCursorPosition_ = false;
2497            return isValidCursorPosition_;
2498        }
2499
2500        if (rowIsInCurrentRowset(currentAbsoluteRowNumber + rows, scrollOrientation_relative__)) {
2501            currentRowInRowset_ += rows;
2502            isValidCursorPosition_ = true;
2503        } else {
2504            checkAndThrowReceivedQueryTerminatingException();
2505            long rowNumber =
2506                    (sensitivity_ == sensitivity_sensitive_dynamic__) ? currentRowInRowset_ + rows :
2507                    currentAbsoluteRowNumber + rows - absolutePosition_;
2508            if (maxRows_ < Math.abs(rowNumber) && maxRows_ != 0) {
2509                if (rowNumber > 0) {
2510                    afterLastX();
2511                } else {
2512                    beforeFirstX();
2513                }
2514                isValidCursorPosition_ = false;
2515                return isValidCursorPosition_;
2516            }
2517            isValidCursorPosition_ = getRelativeRowset(rowNumber);
2518        }
2519
2520        if (isValidCursorPosition_) {
2521            updateColumnInfoFromCache();
2522            // check if there is a non-null SQLCA for the row for rowset cursors
2523
checkRowsetSqlca();
2524        }
2525
2526        return isValidCursorPosition_;
2527    }
2528
2529    public boolean previous() throws SQLException JavaDoc {
2530        try
2531        {
2532            synchronized (connection_) {
2533                if (agent_.loggingEnabled()) {
2534                    agent_.logWriter_.traceEntry(this, "previous");
2535                }
2536                boolean isValidCursorPosition = previousX();
2537                if (agent_.loggingEnabled()) {
2538                    agent_.logWriter_.traceExit(this, "previous", isValidCursorPosition);
2539                }
2540                return isValidCursorPosition;
2541            }
2542        }
2543        catch ( SqlException se )
2544        {
2545            throw se.getSQLException();
2546        }
2547    }
2548
2549    private boolean previousX() throws SqlException {
2550        checkForClosedResultSet();
2551        checkThatResultSetTypeIsScrollable();
2552        clearWarningsX();
2553        
2554        moveToCurrentRowX();
2555
2556        wasNull_ = ResultSet.WAS_NULL_UNSET;
2557
2558        // discard all previous updates when moving the cursor.
2559
resetUpdatedColumns();
2560    
2561    unuseStreams();
2562
2563        isBeforeFirst_ = false;
2564        isFirst_ = false;
2565
2566        if (rowIsInCurrentRowset(firstRowInRowset_ + currentRowInRowset_ - 1, scrollOrientation_prior__)) {
2567            isValidCursorPosition_ = true;
2568            currentRowInRowset_--;
2569        } else {
2570            checkAndThrowReceivedQueryTerminatingException();
2571            isValidCursorPosition_ = getPreviousRowset();
2572        }
2573
2574        if (isValidCursorPosition_) {
2575            updateColumnInfoFromCache();
2576            // check if there is a non-null SQLCA for the row for rowset cursors
2577
checkRowsetSqlca();
2578            if (isAfterLast_) {
2579                isLast_ = true;
2580            }
2581            isAfterLast_ = false;
2582        } else {
2583            return isValidCursorPosition_;
2584        }
2585
2586        if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0 &&
2587                (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
2588            isValidCursorPosition_ = false;
2589        }
2590        // auto-close result set if this is the last row from server and return false
2591
return isValidCursorPosition_;
2592    }
2593
2594    public void setFetchDirection(int direction) throws SQLException JavaDoc {
2595        try
2596        {
2597            synchronized (connection_) {
2598                if (agent_.loggingEnabled()) {
2599                    agent_.logWriter_.traceEntry(this, "setFetchDirection", direction);
2600                }
2601                checkForClosedResultSet();
2602                checkThatResultSetTypeIsScrollable();
2603
2604                switch (direction) {
2605                case java.sql.ResultSet.FETCH_FORWARD:
2606                case java.sql.ResultSet.FETCH_REVERSE:
2607                case java.sql.ResultSet.FETCH_UNKNOWN:
2608                    fetchDirection_ = direction;
2609                    break;
2610                default:
2611                    throw new SqlException(agent_.logWriter_,
2612                        new ClientMessageId(SQLState.INVALID_FETCH_DIRECTION),
2613                        new Integer JavaDoc(direction));
2614                }
2615            }
2616        }
2617        catch ( SqlException se )
2618        {
2619            throw se.getSQLException();
2620        }
2621    }
2622
2623    public int getFetchDirection() throws SQLException JavaDoc {
2624        try
2625        {
2626            checkForClosedResultSet();
2627            if (agent_.loggingEnabled()) {
2628                agent_.logWriter_.traceExit(this, "getFetchDirection", fetchDirection_);
2629            }
2630            return fetchDirection_;
2631        }
2632        catch ( SqlException se )
2633        {
2634            throw se.getSQLException();
2635        }
2636    }
2637
2638    public void setFetchSize(int rows) throws SQLException JavaDoc {
2639        try
2640        {
2641            synchronized (connection_) {
2642                if (agent_.loggingEnabled()) {
2643                    agent_.logWriter_.traceEntry(this, "setFetchSize", rows);
2644                }
2645                checkForClosedResultSet();
2646                if (rows < 0 || (maxRows_ != 0 && rows > maxRows_)) {
2647                    throw new SqlException(agent_.logWriter_,
2648                        new ClientMessageId(SQLState.INVALID_FETCH_SIZE),
2649                        new Integer JavaDoc(rows)).getSQLException();
2650                }
2651                setFetchSize_(rows);
2652            }
2653        }
2654        catch ( SqlException se )
2655        {
2656            throw se.getSQLException();
2657        }
2658    }
2659
2660    public int getFetchSize() throws SQLException JavaDoc {
2661        try
2662        {
2663            if (agent_.loggingEnabled()) {
2664                agent_.logWriter_.traceExit(this, "getFetchSize", fetchSize_);
2665            }
2666            checkForClosedResultSet();
2667            return suggestedFetchSize_;
2668        }
2669        catch ( SqlException se )
2670        {
2671            throw se.getSQLException();
2672        }
2673    }
2674
2675    public int getType() throws SQLException JavaDoc {
2676        try
2677        {
2678            if (agent_.loggingEnabled()) {
2679                agent_.logWriter_.traceExit(this, "getType", resultSetType_);
2680            }
2681            checkForClosedResultSet();
2682            return resultSetType_;
2683        }
2684        catch ( SqlException se )
2685        {
2686            throw se.getSQLException();
2687        }
2688    }
2689
2690    public int getConcurrency() throws SQLException JavaDoc {
2691        try
2692        {
2693            if (agent_.loggingEnabled()) {
2694                agent_.logWriter_.traceExit(this, "getConcurrency", resultSetConcurrency_);
2695            }
2696            checkForClosedResultSet();
2697            return resultSetConcurrency_;
2698        }
2699        catch ( SqlException se )
2700        {
2701            throw se.getSQLException();
2702        }
2703    }
2704
2705    //----------------------------- Updates --------------------------------------
2706

2707    public boolean rowUpdated() throws SQLException JavaDoc {
2708        try
2709        {
2710            checkForClosedResultSet();
2711            checkPositionedOnPlainRow();
2712
2713            boolean rowUpdated = cursor_.getIsRowUpdated();
2714
2715            if (agent_.loggingEnabled()) {
2716                agent_.logWriter_.traceExit(this, "rowUpdated", rowUpdated);
2717            }
2718            return rowUpdated;
2719        }
2720        catch ( SqlException se )
2721        {
2722            throw se.getSQLException();
2723        }
2724    }
2725
2726    public boolean rowInserted() throws SQLException JavaDoc {
2727        try
2728        {
2729            checkForClosedResultSet();
2730            checkPositionedOnPlainRow();
2731
2732            boolean rowInserted = false;
2733
2734            // Not implemented for any result set type,
2735
// so it always returns false.
2736

2737            if (agent_.loggingEnabled()) {
2738                agent_.logWriter_.traceExit(this, "rowInserted", rowInserted);
2739            }
2740            return rowInserted;
2741        }
2742        catch ( SqlException se )
2743        {
2744            throw se.getSQLException();
2745        }
2746    }
2747
2748    public boolean rowDeleted() throws SQLException JavaDoc {
2749        try
2750        {
2751            checkForClosedResultSet();
2752            checkPositionedOnPlainRow();
2753
2754            boolean rowDeleted =
2755                (resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) ?
2756                cursor_.getIsUpdateDeleteHole() : false;
2757
2758            if (agent_.loggingEnabled()) {
2759                agent_.logWriter_.traceExit(this, "rowDeleted", rowDeleted);
2760            }
2761            return rowDeleted;
2762        }
2763        catch ( SqlException se )
2764        {
2765            throw se.getSQLException();
2766        }
2767    }
2768
2769    // --------------------------- update column methods -------------------------
2770

2771    public void updateNull(int column) throws SQLException JavaDoc {
2772        try
2773        {
2774            synchronized (connection_) {
2775                if (agent_.loggingEnabled()) {
2776                    agent_.logWriter_.traceEntry(this, "updateNull", column);
2777                }
2778                checkUpdatePreconditions(column, "updateNull");
2779                if (!resultSetMetaData_.nullable_[column - 1]) {
2780                    throw new SqlException(agent_.logWriter_,
2781                        new ClientMessageId(SQLState.LANG_NULL_INTO_NON_NULL),
2782                        new Integer JavaDoc(column));
2783                }
2784                updateColumn(column, null);
2785            }
2786        }
2787        catch ( SqlException se )
2788        {
2789            throw se.getSQLException();
2790        }
2791    }
2792
2793    public void updateBoolean(int column, boolean x) throws SQLException JavaDoc {
2794        try
2795        {
2796            synchronized (connection_) {
2797                if (agent_.loggingEnabled()) {
2798                    agent_.logWriter_.traceEntry(this, "updateBoolean", column, x);
2799                }
2800                checkUpdatePreconditions(column, "updateBoolean");
2801                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2802            }
2803        }
2804        catch ( SqlException se )
2805        {
2806            throw se.getSQLException();
2807        }
2808    }
2809
2810    public void updateByte(int column, byte x) throws SQLException JavaDoc {
2811        try
2812        {
2813            synchronized (connection_) {
2814                if (agent_.loggingEnabled()) {
2815                    agent_.logWriter_.traceEntry(this, "updateByte", column, x);
2816                }
2817                checkUpdatePreconditions(column, "updateByte");
2818                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2819            }
2820        }
2821        catch ( SqlException se )
2822        {
2823            throw se.getSQLException();
2824        }
2825    }
2826
2827    public void updateShort(int column, short x) throws SQLException JavaDoc {
2828        try
2829        {
2830            synchronized (connection_) {
2831                if (agent_.loggingEnabled()) {
2832                    agent_.logWriter_.traceEntry(this, "updateShort", column, x);
2833                }
2834                checkUpdatePreconditions(column, "updateShort");
2835                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2836            }
2837        }
2838        catch ( SqlException se )
2839        {
2840            throw se.getSQLException();
2841        }
2842    }
2843
2844    public void updateInt(int column, int x) throws SQLException JavaDoc {
2845        try
2846        {
2847            synchronized (connection_) {
2848                if (agent_.loggingEnabled()) {
2849                    agent_.logWriter_.traceEntry(this, "updateInt", column, x);
2850                }
2851                checkUpdatePreconditions(column, "updateInt");
2852                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2853            }
2854        }
2855        catch ( SqlException se )
2856        {
2857            throw se.getSQLException();
2858        }
2859    }
2860
2861    public void updateLong(int column, long x) throws SQLException JavaDoc {
2862        try
2863        {
2864            synchronized (connection_) {
2865                if (agent_.loggingEnabled()) {
2866                    agent_.logWriter_.traceEntry(this, "updateLong", column, x);
2867                }
2868                checkUpdatePreconditions(column, "updateLong");
2869                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2870            }
2871        }
2872        catch ( SqlException se )
2873        {
2874            throw se.getSQLException();
2875        }
2876    }
2877
2878    public void updateFloat(int column, float x) throws SQLException JavaDoc {
2879        try
2880        {
2881            synchronized (connection_) {
2882                if (agent_.loggingEnabled()) {
2883                    agent_.logWriter_.traceEntry(this, "updateFloat", column, x);
2884                }
2885                checkUpdatePreconditions(column, "updateFloat");
2886                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2887            }
2888        }
2889        catch ( SqlException se )
2890        {
2891            throw se.getSQLException();
2892        }
2893    }
2894
2895    public void updateDouble(int column, double x) throws SQLException JavaDoc {
2896        try
2897        {
2898            synchronized (connection_) {
2899                if (agent_.loggingEnabled()) {
2900                    agent_.logWriter_.traceEntry(this, "updateDouble", column, x);
2901                }
2902                checkUpdatePreconditions(column, "updateDouble");
2903                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2904            }
2905        }
2906        catch ( SqlException se )
2907        {
2908            throw se.getSQLException();
2909        }
2910    }
2911
2912    public void updateBigDecimal(int column, java.math.BigDecimal JavaDoc x) throws SQLException JavaDoc {
2913        try
2914        {
2915            synchronized (connection_) {
2916                if (agent_.loggingEnabled()) {
2917                    agent_.logWriter_.traceEntry(this, "updateBigDecimal", column, x);
2918                }
2919                checkUpdatePreconditions(column, "updateBigDecimal");
2920                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2921            }
2922        }
2923        catch ( SqlException se )
2924        {
2925            throw se.getSQLException();
2926        }
2927    }
2928
2929    public void updateDate(int column, java.sql.Date JavaDoc x) throws SQLException JavaDoc {
2930        try
2931        {
2932            synchronized (connection_) {
2933                if (agent_.loggingEnabled()) {
2934                    agent_.logWriter_.traceEntry(this, "updateDate", column, x);
2935                }
2936                checkUpdatePreconditions(column, "updateDate");
2937                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2938            }
2939        }
2940        catch ( SqlException se )
2941        {
2942            throw se.getSQLException();
2943        }
2944    }
2945
2946    public void updateTime(int column, java.sql.Time JavaDoc x) throws SQLException JavaDoc {
2947        try
2948        {
2949            synchronized (connection_) {
2950                if (agent_.loggingEnabled()) {
2951                    agent_.logWriter_.traceEntry(this, "updateTime", column, x);
2952                }
2953                checkUpdatePreconditions(column, "updateTime");
2954                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2955            }
2956        }
2957        catch ( SqlException se )
2958        {
2959            throw se.getSQLException();
2960        }
2961    }
2962
2963    public void updateTimestamp(int column, java.sql.Timestamp JavaDoc x) throws SQLException JavaDoc {
2964        try
2965        {
2966            synchronized (connection_) {
2967                if (agent_.loggingEnabled()) {
2968                    agent_.logWriter_.traceEntry(this, "updateTimestamp", column, x);
2969                }
2970                checkUpdatePreconditions(column, "updateTimestamp");
2971                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2972            }
2973        }
2974        catch ( SqlException se )
2975        {
2976            throw se.getSQLException();
2977        }
2978    }
2979
2980    public void updateString(int column, String JavaDoc x) throws SQLException JavaDoc {
2981        try
2982        {
2983            synchronized (connection_) {
2984                if (agent_.loggingEnabled()) {
2985                    agent_.logWriter_.traceEntry(this, "updateString", column, x);
2986                }
2987                checkUpdatePreconditions(column, "updateString");
2988                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
2989            }
2990        }
2991        catch ( SqlException se )
2992        {
2993            throw se.getSQLException();
2994        }
2995    }
2996
2997    public void updateBytes(int column, byte x[]) throws SQLException JavaDoc {
2998        try
2999        {
3000            synchronized (connection_) {
3001                if (agent_.loggingEnabled()) {
3002                    agent_.logWriter_.traceEntry(this, "updateBytes", column, x);
3003                }
3004                checkUpdatePreconditions(column, "updateBytes");
3005                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
3006            }
3007        }
3008        catch ( SqlException se )
3009        {
3010            throw se.getSQLException();
3011        }
3012    }
3013
3014    public void updateBinaryStream(int column,
3015                                   java.io.InputStream JavaDoc x,
3016                                   int length) throws SQLException JavaDoc {
3017        try
3018        {
3019            synchronized (connection_) {
3020                if (agent_.loggingEnabled()) {
3021                    agent_.logWriter_.traceEntry(this, "", column, x, length);
3022                }
3023                checkUpdatePreconditions(column, "updateBinaryStream");
3024                updateColumn(column, agent_.crossConverters_.setObjectFromBinaryStream(resultSetMetaData_.types_[column - 1], x, length));
3025            }
3026        }
3027        catch ( SqlException se )
3028        {
3029            throw se.getSQLException();
3030        }
3031    }
3032
3033    public void updateAsciiStream(int column,
3034                                  java.io.InputStream JavaDoc x,
3035                                  int length) throws SQLException JavaDoc {
3036        try
3037        {
3038            synchronized (connection_) {
3039                if (agent_.loggingEnabled()) {
3040                    agent_.logWriter_.traceEntry(this, "updateAsciiStream", column, x, length);
3041                }
3042                checkUpdatePreconditions(column, "updateAsciiStream");
3043                updateColumn(column, agent_.crossConverters_.setObjectFromCharacterStream(resultSetMetaData_.types_[column - 1], x, "US-ASCII", length));
3044            }
3045        }
3046        catch ( SqlException se )
3047        {
3048            throw se.getSQLException();
3049        }
3050    }
3051
3052    public void updateCharacterStream(int column,
3053                                      java.io.Reader JavaDoc x,
3054                                      int length) throws SQLException JavaDoc {
3055        try
3056        {
3057            synchronized (connection_) {
3058                if (agent_.loggingEnabled()) {
3059                    agent_.logWriter_.traceEntry(this, "updateCharacterStream", column, x, length);
3060                }
3061                checkUpdatePreconditions(column, "updateCharacterStream");
3062                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x, length));
3063            }
3064        }
3065        catch ( SqlException se )
3066        {
3067            throw se.getSQLException();
3068        }
3069    }
3070
3071    public void updateObject(int column, Object JavaDoc x, int scale) throws SQLException JavaDoc {
3072        try
3073        {
3074            synchronized (connection_) {
3075                if (agent_.loggingEnabled()) {
3076                    agent_.logWriter_.traceEntry(this, "updateObject", column, x, scale);
3077                }
3078                checkUpdatePreconditions(column, "updateObject");
3079                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
3080            }
3081        }
3082        catch ( SqlException se )
3083        {
3084            throw se.getSQLException();
3085        }
3086    }
3087
3088    public void updateObject(int column, Object JavaDoc x) throws SQLException JavaDoc {
3089        try
3090        {
3091            synchronized (connection_) {
3092                if (agent_.loggingEnabled()) {
3093                    agent_.logWriter_.traceEntry(this, "updateObject", column, x);
3094                }
3095                checkUpdatePreconditions(column, "updateObject");
3096                updateColumn(column, agent_.crossConverters_.setObject(resultSetMetaData_.types_[column - 1], x));
3097            }
3098        }
3099        catch ( SqlException se )
3100        {
3101            throw se.getSQLException();
3102        }
3103    }
3104
3105    public void updateNCharacterStream(int columnIndex, Reader JavaDoc x)
3106            throws SQLException JavaDoc {
3107        throw jdbc3MethodNotSupported();
3108    }
3109
3110    public void updateNClob(int columnIndex, Reader JavaDoc reader)
3111            throws SQLException JavaDoc {
3112        throw jdbc3MethodNotSupported();
3113    }
3114
3115    // ---------------------- update on column name methods ----------------------
3116

3117    public void updateNull(String JavaDoc columnName) throws SQLException JavaDoc {
3118        try
3119        {
3120            if (agent_.loggingEnabled()) {
3121                agent_.logWriter_.traceEntry(this, "updateNull", columnName);
3122            }
3123            updateNull(findColumnX(columnName));
3124        }
3125        catch ( SqlException se )
3126        {
3127            throw se.getSQLException();
3128        }
3129    }
3130
3131    public void updateBoolean(String JavaDoc columnName, boolean x) throws SQLException JavaDoc {
3132        try
3133        {
3134            if (agent_.loggingEnabled()) {
3135                agent_.logWriter_.traceEntry(this, "updateBoolean", columnName, x);
3136            }
3137            updateBoolean(findColumnX(columnName), x);
3138        }
3139        catch ( SqlException se )
3140        {
3141            throw se.getSQLException();
3142        }
3143    }
3144
3145    public void updateByte(String JavaDoc columnName, byte x) throws SQLException JavaDoc {
3146        try
3147        {
3148            if (agent_.loggingEnabled()) {
3149                agent_.logWriter_.traceEntry(this, "updateByte", columnName, x);
3150            }
3151            updateByte(findColumnX(columnName), x);
3152        }
3153        catch ( SqlException se )
3154        {
3155            throw se.getSQLException();
3156        }
3157    }
3158
3159    public void updateShort(String JavaDoc columnName, short x) throws SQLException JavaDoc {
3160        try
3161        {
3162            if (agent_.loggingEnabled()) {
3163                agent_.logWriter_.traceEntry(this, "updateShort", columnName, x);
3164            }
3165            updateShort(findColumnX(columnName), x);
3166        }
3167        catch ( SqlException se )
3168        {
3169            throw se.getSQLException();
3170        }
3171    }
3172
3173    public void updateInt(String JavaDoc columnName, int x) throws SQLException JavaDoc {
3174        try
3175        {
3176            if (agent_.loggingEnabled()) {
3177                agent_.logWriter_.traceEntry(this, "updateInt", columnName, x);
3178            }
3179            updateInt(findColumnX(columnName), x);
3180        }
3181        catch ( SqlException se )
3182        {
3183            throw se.getSQLException();
3184        }
3185    }
3186
3187    public void updateLong(String JavaDoc columnName, long x) throws SQLException JavaDoc {
3188        try
3189        {
3190            if (agent_.loggingEnabled()) {
3191                agent_.logWriter_.traceEntry(this, "updateLong", columnName, x);
3192            }
3193            updateLong(findColumnX(columnName), x);
3194        }
3195        catch ( SqlException se )
3196        {
3197            throw se.getSQLException();
3198        }
3199    }
3200
3201    public void updateFloat(String JavaDoc columnName, float x) throws SQLException JavaDoc {
3202        try
3203        {
3204            if (agent_.loggingEnabled()) {
3205                agent_.logWriter_.traceEntry(this, "updateFloat", columnName, x);
3206            }
3207            updateFloat(findColumnX(columnName), x);
3208        }
3209        catch ( SqlException se )
3210        {
3211            throw se.getSQLException();
3212        }
3213    }
3214
3215    public void updateDouble(String JavaDoc columnName, double x) throws SQLException JavaDoc {
3216        try
3217        {
3218            if (agent_.loggingEnabled()) {
3219                agent_.logWriter_.traceEntry(this, "updateDouble", columnName, x);
3220            }
3221            updateDouble(findColumnX(columnName), x);
3222        }
3223        catch ( SqlException se )
3224        {
3225            throw se.getSQLException();
3226        }
3227    }
3228
3229    public void updateBigDecimal(String JavaDoc columnName, java.math.BigDecimal JavaDoc x) throws SQLException JavaDoc {
3230        try
3231        {
3232            if (agent_.loggingEnabled()) {
3233                agent_.logWriter_.traceEntry(this, "updateBigDecimal", columnName, x);
3234            }
3235            updateBigDecimal(findColumnX(columnName), x);
3236        }
3237        catch ( SqlException se )
3238        {
3239            throw se.getSQLException();
3240        }
3241    }
3242
3243    public void updateDate(String JavaDoc columnName, java.sql.Date JavaDoc x) throws SQLException JavaDoc {
3244        try
3245        {
3246            if (agent_.loggingEnabled()) {
3247                agent_.logWriter_.traceEntry(this, "updateDate", columnName, x);
3248            }
3249            updateDate(findColumnX(columnName), x);
3250        }
3251        catch ( SqlException se )
3252        {
3253            throw se.getSQLException();
3254        }
3255    }
3256
3257    public void updateTime(String JavaDoc columnName, java.sql.Time JavaDoc x) throws SQLException JavaDoc {
3258        try
3259        {
3260            if (agent_.loggingEnabled()) {
3261                agent_.logWriter_.traceEntry(this, "updateTime", columnName, x);
3262            }
3263            updateTime(findColumnX(columnName), x);
3264        }
3265        catch ( SqlException se )
3266        {
3267            throw se.getSQLException();
3268        }
3269    }
3270
3271    public void updateTimestamp(String JavaDoc columnName, java.sql.Timestamp JavaDoc x) throws SQLException JavaDoc {
3272        try
3273        {
3274            if (agent_.loggingEnabled()) {
3275                agent_.logWriter_.traceEntry(this, "updateTimestamp", columnName, x);
3276            }
3277            updateTimestamp(findColumnX(columnName), x);
3278        }
3279        catch ( SqlException se )
3280        {
3281            throw se.getSQLException();
3282        }
3283    }
3284
3285    public void updateString(String JavaDoc columnName, String JavaDoc x) throws SQLException JavaDoc {
3286        try
3287        {
3288            if (agent_.loggingEnabled()) {
3289                agent_.logWriter_.traceEntry(this, "updateString", columnName, x);
3290            }
3291            updateString(findColumnX(columnName), x);
3292        }
3293        catch ( SqlException se )
3294        {
3295            throw se.getSQLException();
3296        }
3297    }
3298
3299    public void updateBytes(String JavaDoc columnName, byte x[]) throws SQLException JavaDoc {
3300        try
3301        {
3302            if (agent_.loggingEnabled()) {
3303                agent_.logWriter_.traceEntry(this, "updateBytes", columnName, x);
3304            }
3305            updateBytes(findColumnX(columnName), x);
3306        }
3307        catch ( SqlException se )
3308        {
3309            throw se.getSQLException();
3310        }
3311    }
3312
3313    public void updateBinaryStream(String JavaDoc columnName,
3314                                   java.io.InputStream JavaDoc x,
3315                                   int length) throws SQLException JavaDoc {
3316        try
3317        {
3318            if (agent_.loggingEnabled()) {
3319                agent_.logWriter_.traceEntry(this, "updateBinaryStream", columnName, x, length);
3320            }
3321            updateBinaryStream(findColumnX(columnName), x, length);
3322        }
3323        catch ( SqlException se )
3324        {
3325            throw se.getSQLException();
3326        }
3327    }
3328
3329    public void updateAsciiStream(String JavaDoc columnName,
3330                                  java.io.InputStream JavaDoc x,
3331                                  int length) throws SQLException JavaDoc {
3332        try
3333        {
3334            if (agent_.loggingEnabled()) {
3335                agent_.logWriter_.traceEntry(this, "updateAsciiStream", columnName, x, length);
3336            }
3337            updateAsciiStream(findColumnX(columnName), x, length);
3338        }
3339        catch ( SqlException se )
3340        {
3341            throw se.getSQLException();
3342        }
3343    }
3344
3345    public void updateCharacterStream(String JavaDoc columnName,
3346                                      java.io.Reader JavaDoc x,
3347                                      int length) throws SQLException JavaDoc {
3348        try
3349        {
3350            if (agent_.loggingEnabled()) {
3351                agent_.logWriter_.traceEntry(this, "updateCharacterStream", columnName, x, length);
3352            }
3353            updateCharacterStream(findColumnX(columnName), x, length);
3354        }
3355        catch ( SqlException se )
3356        {
3357            throw se.getSQLException();
3358        }
3359    }
3360
3361    public void updateObject(String JavaDoc columnName, Object JavaDoc x, int scale) throws SQLException JavaDoc {
3362        try
3363        {
3364            if (agent_.loggingEnabled()) {
3365                agent_.logWriter_.traceEntry(this, "updateObject", columnName, x, scale);
3366            }
3367            updateObject(findColumnX(columnName), x, scale);
3368        }
3369        catch ( SqlException se )
3370        {
3371            throw se.getSQLException();
3372        }
3373    }
3374
3375    public void updateObject(String JavaDoc columnName, Object JavaDoc x) throws SQLException JavaDoc {
3376        try
3377        {
3378            if (agent_.loggingEnabled()) {
3379                agent_.logWriter_.traceEntry(this, "updateObject", columnName, x);
3380            }
3381            updateObject(findColumnX(columnName), x);
3382        }
3383        catch ( SqlException se )
3384        {
3385            throw se.getSQLException();
3386        }
3387    }
3388
3389    public void updateNCharacterStream(String JavaDoc columnName, Reader JavaDoc x)
3390            throws SQLException JavaDoc {
3391        throw jdbc3MethodNotSupported();
3392    }
3393
3394    public void updateNClob(String JavaDoc columnName, Reader JavaDoc reader)
3395            throws SQLException JavaDoc {
3396        throw jdbc3MethodNotSupported();
3397    }
3398
3399    // ---------------------------------------------------------------------------
3400

3401    public void insertRow() throws SQLException JavaDoc {
3402        try
3403        {
3404            synchronized (connection_) {
3405                if (agent_.loggingEnabled()) {
3406                    agent_.logWriter_.traceEntry(this, "insertRow");
3407                }
3408                insertRowX();
3409            }
3410        }
3411        catch ( SqlException se )
3412        {
3413            throw se.getSQLException();
3414        }
3415    }
3416
3417    private void insertRowX() throws SqlException {
3418        checkForClosedResultSet();
3419    checkForUpdatableResultSet("insertRow");
3420        if (isOnCurrentRow_) {
3421            throw new SqlException(agent_.logWriter_,
3422                new ClientMessageId(SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW));
3423       }
3424 
3425        // if not on a valid row, then do not accept updateXXX calls
3426
if (!isValidCursorPosition_) {
3427            throw new SqlException(agent_.logWriter_,
3428                new ClientMessageId(SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3429        }
3430
3431        // User might not be updating all the updatable columns selected in the
3432
// select sql and hence every insertRow on the same ResultSet can be
3433
// potentially different than the previous one. Because of that, we
3434
// should get a new prepared statement to do inserts every time
3435
getPreparedStatementForInsert();
3436
3437        // build the inputs array for the prepared statement for insert
3438
int paramNumber = 0;
3439        for (int i = 0; i < updatedColumns_.length; i++) {
3440            if (resultSetMetaData_.sqlxUpdatable_[i] == 1) {
3441                // Since user may choose not to update all the columns in the
3442
// select list, check first if the column has been updated
3443
if (columnUpdated_[i] == true) {
3444                    paramNumber++;
3445
3446                    // column is updated either if the updatedColumns_ entry is not null,
3447
// or if the updatedColumns_ entry is null, but columnUpdated is
3448
// set to true, which means columns is updated to a null.
3449
if (updatedColumns_[i] != null ||
3450                            (updatedColumns_[i] == null && columnUpdated_[i])) {
3451                        preparedStatementForInsert_.setInput(
3452                                paramNumber,
3453                                updatedColumns_[i]);
3454                    }
3455                }
3456            }
3457        }
3458        try {
3459            insert();
3460        } catch (SqlException e) {
3461            throw e;
3462        }
3463    }
3464    
3465    public void updateRow() throws java.sql.SQLException JavaDoc {
3466        try
3467        {
3468            synchronized (connection_) {
3469                if (agent_.loggingEnabled()) {
3470                    agent_.logWriter_.traceEntry(this, "updateRow");
3471                }
3472                // If updateXXX were issued on the row before updateRow and
3473
// the result set if forward only, then position the ResultSet
3474
// to right before the next row after updateRow.
3475
if (updateRowX() && (getType() ==
3476                                     ResultSet.TYPE_FORWARD_ONLY)) {
3477                    isValidCursorPosition_ = false;
3478                }
3479            }
3480        }
3481        catch ( SqlException se )
3482        {
3483            throw se.getSQLException();
3484        }
3485    }
3486
3487    //if no updateXXX were issued before this updateRow, then return false
3488
private boolean updateRowX() throws SqlException {
3489        checkForClosedResultSet();
3490        
3491        checkForUpdatableResultSet("updateRow");
3492        
3493        if (isOnInsertRow_) {
3494            throw new SqlException(agent_.logWriter_,
3495                new ClientMessageId(SQLState.NO_CURRENT_ROW));
3496        }
3497
3498        //if not on a valid row, then do not accept updateXXX calls
3499
if (!isValidCursorPosition_)
3500            throw new SqlException(agent_.logWriter_,
3501                new ClientMessageId(SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3502
3503        // If no updateXXX has been called on this ResultSet object, then
3504
// updatedColumns_ will be null and hence no action required
3505
if (updatedColumns_ == null) {
3506            return false;
3507        }
3508
3509        // updateXXX has been called on this ResultSet object, but check if it
3510
// has been called on the current row. If no column got updated on this
3511
// current row, then just return.
3512
boolean didAnyColumnGetUpdated = false;
3513        for (int i=0; i < updatedColumns_.length; i++) {
3514            if (columnUpdated_[i]) {
3515                didAnyColumnGetUpdated = true;
3516                break;
3517            }
3518        }
3519        if (didAnyColumnGetUpdated == false)
3520            return false;
3521
3522        // User might not be updating all the updatable columns selected in the
3523
// select sql and hence every updateRow on the same ResultSet can be
3524
// potentially different than the previous one. Because of that, we
3525
// should get a new prepared statement to do updates every time
3526
getPreparedStatementForUpdate();
3527
3528        // build the inputs array for the prepared statement for update
3529
int paramNumber = 0;
3530        for (int i = 0; i < updatedColumns_.length; i++) {
3531            if (resultSetMetaData_.sqlxUpdatable_[i] == 1) {
3532                // Since user may choose not to update all the columns in the
3533
// select list, check first if the column has been updated
3534
if (columnUpdated_[i] == false)
3535                    continue;
3536                paramNumber++;
3537
3538                // column is updated either if the updatedColumns_ entry is not null,
3539
// or if the updatedColumns_ entry is null, but columnUpdated_ boolean is
3540
// set to true, which means columns is updated to a null.
3541
if (updatedColumns_[i] != null ||
3542                        (updatedColumns_[i] == null && columnUpdated_[i])) {
3543                    preparedStatementForUpdate_.setInput(paramNumber, updatedColumns_[i]);
3544                } else {
3545                    // Check if the original column is null. Calling CrossConverters.setObject on a null
3546
// column causes "Data Conversion" Exception.
3547
Object JavaDoc originalObj;
3548                    try {
3549                        originalObj = getObject(i + 1);
3550                    } catch ( SQLException JavaDoc se ) {
3551                        throw new SqlException(se);
3552                    }
3553                    
3554                    if (originalObj == null) {
3555                        preparedStatementForUpdate_.setInput(paramNumber, null);
3556                    } else {
3557                        preparedStatementForUpdate_.setInput(paramNumber, agent_.crossConverters_.setObject(resultSetMetaData_.types_[i], originalObj));
3558                    }
3559                }
3560            }
3561        }
3562        // need to cancel updates if the actual update was not successful at the server.
3563
// alternative is to check for updateCount_ in "positionToCurrentRowAndUpdate".
3564
// cancelRowUpdates if updateCount_ != 1
3565
try {
3566            if (isRowsetCursor_ ||
3567                    sensitivity_ == sensitivity_sensitive_dynamic__ ||
3568                    sensitivity_ == sensitivity_sensitive_static__) {
3569                update();
3570            } else {
3571                positionToCurrentRowAndUpdate();
3572            }
3573        } finally {
3574            resetUpdatedColumns();
3575        }
3576
3577        // Ensure the data is reset
3578
if (resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) {
3579            if (preparedStatementForUpdate_.updateCount_ > 0) {
3580                // This causes a round-trip
3581
getAbsoluteRowset(absolutePosition_);
3582            }
3583        }
3584
3585        return true;
3586    }
3587
3588    public void deleteRow() throws java.sql.SQLException JavaDoc {
3589        try
3590        {
3591            synchronized (connection_) {
3592                if (agent_.loggingEnabled()) {
3593                    agent_.logWriter_.traceEntry(this, "deleteRow");
3594                }
3595                deleteRowX();
3596                //the cursor is not positioned on the deleted row after deleteRow.
3597
//User needs to issue ResultSet.next to reposition the ResultSet
3598
//on a valid row
3599
isValidCursorPosition_ = false;
3600            }
3601        }
3602        catch ( SqlException se )
3603        {
3604            throw se.getSQLException();
3605        }
3606    }
3607
3608    private void deleteRowX() throws SqlException {
3609        checkForClosedResultSet();
3610        
3611        checkForUpdatableResultSet("deleteRow");
3612
3613        // discard all previous updates
3614
resetUpdatedColumns();
3615
3616        if (isOnInsertRow_) {
3617            throw new SqlException(agent_.logWriter_,
3618                new ClientMessageId(SQLState.NO_CURRENT_ROW));
3619        }
3620
3621        if (preparedStatementForDelete_ == null) {
3622            getPreparedStatementForDelete();
3623        }
3624
3625        if (isRowsetCursor_ ||
3626                sensitivity_ == sensitivity_sensitive_dynamic__ ||
3627                sensitivity_ == sensitivity_sensitive_static__) {
3628            delete();
3629        } else {
3630            positionToCurrentRowAndDelete();
3631        }
3632
3633        if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
3634            cursor_.isUpdateDeleteHole_ = true;
3635        } else {
3636            if (preparedStatementForDelete_.updateCount_ > 0) {
3637                
3638                cursor_.isUpdateDeleteHoleCache_.set((int) currentRowInRowset_,
3639                                                     Cursor.ROW_IS_NULL);
3640                cursor_.isUpdateDeleteHole_ =
3641                    ((Boolean JavaDoc) cursor_.isUpdateDeleteHoleCache_.
3642                     get((int) currentRowInRowset_)).booleanValue();
3643            }
3644        }
3645    }
3646
3647    public void refreshRow() throws SQLException JavaDoc {
3648        try
3649        {
3650            synchronized (connection_) {
3651                if (agent_.loggingEnabled()) {
3652                    agent_.logWriter_.traceEntry(this, "refreshRow");
3653                }
3654                refreshRowX();
3655            }
3656        }
3657        catch ( SqlException se )
3658        {
3659            throw se.getSQLException();
3660        }
3661    }
3662
3663    private void refreshRowX() throws SqlException {
3664        checkForClosedResultSet();
3665        checkThatResultSetTypeIsScrollable();
3666    checkForUpdatableResultSet("refreshRow");
3667        if (isBeforeFirstX() || isAfterLastX() || isOnInsertRow_) {
3668            throw new SqlException(agent_.logWriter_,
3669                new ClientMessageId(SQLState.NO_CURRENT_ROW));
3670        }
3671    
3672        // this method does nothing if ResultSet is TYPE_SCROLL_INSENSITIVE
3673
if (resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE) {
3674            isValidCursorPosition_ = getRefreshRowset();
3675            try {
3676                cancelRowUpdates();
3677            } catch ( SQLException JavaDoc sqle ) {
3678                throw new SqlException(sqle);
3679            }
3680        
3681            unuseStreams();
3682        
3683        }
3684    }
3685
3686    public void cancelRowUpdates() throws SQLException JavaDoc {
3687        try
3688        {
3689            synchronized (connection_) {
3690                if (agent_.loggingEnabled()) {
3691                    agent_.logWriter_.traceEntry(this, "cancelRowUpdates");
3692                }
3693                checkForClosedResultSet();
3694                checkForUpdatableResultSet("cancelRowUpdates");
3695                if (isOnInsertRow_) {
3696                    throw new SqlException(agent_.logWriter_,
3697                        new ClientMessageId(SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW));
3698                }
3699
3700                // if not on a valid row, then do not accept cancelRowUpdates call
3701
if (!isValidCursorPosition_)
3702                    throw new SqlException(agent_.logWriter_,
3703                        new ClientMessageId(SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3704                // Reset updated columns
3705
resetUpdatedColumns();
3706            }
3707        }
3708        catch ( SqlException se )
3709        {
3710            throw se.getSQLException();
3711        }
3712    }
3713
3714    public void moveToInsertRow() throws SQLException JavaDoc {
3715        try
3716        {
3717            synchronized (connection_) {
3718                if (agent_.loggingEnabled()) {
3719                    agent_.logWriter_.traceEntry(this, "moveToInsertRow");
3720                }
3721                checkForClosedResultSet();
3722                checkForUpdatableResultSet("moveToInsertRow");
3723
3724                resetUpdatedColumnsForInsert();
3725
3726                isOnInsertRow_ = true;
3727                isOnCurrentRow_ = false;
3728                isValidCursorPosition_ = true;
3729            }
3730        }
3731        catch ( SqlException se )
3732        {
3733            throw se.getSQLException();
3734        }
3735    }
3736
3737    public void moveToCurrentRow() throws SQLException JavaDoc {
3738        try
3739        {
3740            synchronized (connection_) {
3741                if (agent_.loggingEnabled()) {
3742                    agent_.logWriter_.traceEntry(this, "moveToCurrentRow");
3743                }
3744                checkForClosedResultSet();
3745                checkForUpdatableResultSet("moveToCurrentRow");
3746
3747                moveToCurrentRowX();
3748            }
3749        }
3750        catch ( SqlException se )
3751        {
3752            throw se.getSQLException();
3753        }
3754    }
3755    
3756    private void moveToCurrentRowX() throws SqlException {
3757        if (isOnInsertRow_) {
3758            resetUpdatedColumns();
3759            isOnInsertRow_ = false;
3760            isOnCurrentRow_ = true;
3761            if (currentRowInRowset_ > 0) {
3762                updateColumnInfoFromCache();
3763            }
3764            isValidCursorPosition_ = true;
3765        }
3766    }
3767
3768    /**
3769     * Retrieves the <code>Statement</code> object that produced this
3770     * object, or <code>null</code> if the <code>ResultSet</code> was
3771     * not produced by a <code>Statement</code> object.
3772     *
3773     * @return the <code>Statement</code> that produced this object or
3774     * <code>null</code>
3775     * @exception SQLException if a database error occurs or the
3776     * result set is closed
3777     */

3778    public java.sql.Statement JavaDoc getStatement() throws SQLException JavaDoc {
3779        try {
3780            checkForClosedResultSet();
3781        } catch (SqlException se) {
3782            throw se.getSQLException();
3783        }
3784        if (agent_.loggingEnabled()) {
3785            agent_.logWriter_.traceExit(this, "getStatement", statement_);
3786        }
3787        return statement_;
3788    }
3789
3790    //-------------------------- JDBC 3.0 ----------------------------------------
3791

3792    public java.net.URL JavaDoc getURL(int columnIndex) throws SQLException JavaDoc {
3793        throw jdbc3MethodNotSupported();
3794    }
3795
3796    public java.net.URL JavaDoc getURL(String JavaDoc columnName) throws SQLException JavaDoc {
3797        throw jdbc3MethodNotSupported();
3798    }
3799
3800    public void updateRef(int columnIndex, java.sql.Ref JavaDoc x) throws SQLException JavaDoc {
3801        throw jdbc3MethodNotSupported();
3802    }
3803
3804    public void updateRef(String JavaDoc columnName, java.sql.Ref JavaDoc x) throws SQLException JavaDoc {
3805        throw jdbc3MethodNotSupported();
3806    }
3807
3808    public void updateBlob(int columnIndex, java.sql.Blob JavaDoc x) throws SQLException JavaDoc {
3809        throw jdbc3MethodNotSupported();
3810    }
3811
3812    public void updateBlob(String JavaDoc columnName, java.sql.Blob JavaDoc x) throws SQLException JavaDoc {
3813        throw jdbc3MethodNotSupported();
3814    }
3815
3816    public void updateClob(int columnIndex, java.sql.Clob JavaDoc x) throws SQLException JavaDoc {
3817        throw jdbc3MethodNotSupported();
3818    }
3819
3820    public void updateClob(String JavaDoc columnName, java.sql.Clob JavaDoc x) throws SQLException JavaDoc {
3821        throw jdbc3MethodNotSupported();
3822    }
3823
3824    public void updateArray(int columnIndex, java.sql.Array JavaDoc x) throws SQLException JavaDoc {
3825        throw jdbc3MethodNotSupported();
3826    }
3827
3828    public void updateArray(String JavaDoc columnName, java.sql.Array JavaDoc x) throws SQLException JavaDoc {
3829        throw jdbc3MethodNotSupported();
3830    }
3831
3832    public boolean repositionScrollableResultSetBeforeJDBC1PositionedUpdateDelete() throws SqlException {
3833        boolean repositionedCursor = false;
3834
3835        // calculate the absolutePosition of the current row directly.
3836
long rowToFetch = getRowUncast() - absolutePosition_;
3837
3838        // if rowToFetch is zero, already positioned on the current row
3839
if (rowToFetch != 0) {
3840            writePositioningFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
3841                    scrollOrientation_relative__,
3842                    rowToFetch);
3843            // adjust the absolute position on the client
3844
absolutePosition_ += rowToFetch;
3845            repositionedCursor = true;
3846        }
3847        return repositionedCursor;
3848    }
3849    //--------------------categorize the methods below -----------------
3850

3851    public void flowPositioningFetch(int scrollOrientation,
3852                                     int rowToFetch) throws DisconnectException {
3853        // need the try-catch block here because agent_.beginWriteChain throws
3854
// an SqlException
3855
try {
3856            agent_.beginWriteChain(statement_);
3857
3858            writePositioningFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
3859                    scrollOrientation,
3860                    rowToFetch);
3861
3862            agent_.flow(statement_);
3863            readPositioningFetch_();
3864            agent_.endReadChain();
3865        } catch (SqlException e) {
3866            throw new DisconnectException(agent_, e);
3867        }
3868    }
3869
3870    protected void positionToCurrentRowAndUpdate() throws SqlException {
3871        agent_.beginWriteChain(statement_);
3872
3873        // calculate the position of the current row relative to the absolute position on server
3874
long currentRowPosRelativeToAbsoluteRowPos = getRowUncast() - absolutePosition_;
3875
3876        // if currentRowPosRelativeToAbsoluteRowPos is zero, already on the current row
3877
// reposition only if a commit has been sent
3878
// do not reposition forward-only cursors
3879
if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY &&
3880                (currentRowPosRelativeToAbsoluteRowPos != 0 ||
3881                (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3882            writePositioningFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
3883                    scrollOrientation_relative__,
3884                    currentRowPosRelativeToAbsoluteRowPos);
3885        }
3886
3887        // re-prepare the update statement if repreparing is needed after a commit.
3888
if (!preparedStatementForUpdate_.openOnServer_) {
3889            preparedStatementForUpdate_.materialPreparedStatement_.writePrepare_(preparedStatementForUpdate_.sql_,
3890                    preparedStatementForUpdate_.section_);
3891        }
3892        
3893        try {
3894            writeUpdateRow(false);
3895        } catch ( SQLException JavaDoc se ) {
3896            throw new SqlException(se);
3897        }
3898        
3899
3900        agent_.flow(statement_);
3901
3902        // adjust the absolute position on the client
3903
absolutePosition_ += currentRowPosRelativeToAbsoluteRowPos;
3904
3905        if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY &&
3906                (currentRowPosRelativeToAbsoluteRowPos != 0 ||
3907                (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3908            readPositioningFetch_();
3909            cursorUnpositionedOnServer_ = false;
3910            listenToUnitOfWork();
3911        }
3912
3913        // read prepare replies if the update statement is re-prepared after a commit.
3914
if (!preparedStatementForUpdate_.openOnServer_) {
3915            preparedStatementForUpdate_.materialPreparedStatement_.readPrepare_();
3916        }
3917        readUpdateRow();
3918
3919        agent_.endReadChain();
3920    }
3921
3922    protected void insert() throws SqlException {
3923        agent_.beginWriteChain(statement_);
3924
3925        // re-prepare the insert statement if repreparing is needed after a commit.
3926
if (!preparedStatementForInsert_.openOnServer_) {
3927            preparedStatementForInsert_.materialPreparedStatement_.writePrepare_(
3928                    preparedStatementForInsert_.sql_,
3929                    preparedStatementForInsert_.section_);
3930        }
3931
3932        try {
3933            writeInsertRow(false);
3934        } catch (SQLException JavaDoc se ) {
3935            throw new SqlException(se);
3936        }
3937
3938        agent_.flow(statement_);
3939
3940        // read prepare replies if the update statement is re-prepared after a commit.
3941
if (!preparedStatementForInsert_.openOnServer_) {
3942            preparedStatementForInsert_.materialPreparedStatement_.readPrepare_();
3943        }
3944
3945        readInsertRow();
3946
3947        agent_.endReadChain();
3948     }
3949
3950    
3951    protected void update() throws SqlException {
3952        agent_.beginWriteChain(statement_);
3953
3954        // re-prepare the update statement if repreparing is needed after a commit.
3955
if (!preparedStatementForUpdate_.openOnServer_) {
3956            preparedStatementForUpdate_.materialPreparedStatement_.writePrepare_(preparedStatementForUpdate_.sql_,
3957                    preparedStatementForUpdate_.section_);
3958        }
3959
3960        if (isRowsetCursor_) {
3961            try {
3962                preparedStatementForUpdate_.setInt(updatedColumns_.length + 1, (int) (currentRowInRowset_ + 1));
3963            } catch ( SQLException JavaDoc se ) {
3964                throw new SqlException(se);
3965            }
3966        }
3967
3968        boolean chainAutoCommit = connection_.willAutoCommitGenerateFlow();
3969        try {
3970            writeUpdateRow(chainAutoCommit);
3971        } catch (SQLException JavaDoc se ) {
3972            throw new SqlException(se);
3973        }
3974        if (chainAutoCommit) {
3975            connection_.writeCommit();
3976        }
3977
3978        agent_.flow(statement_);
3979
3980        // read prepare replies if the update statement is re-prepared after a commit.
3981
if (!preparedStatementForUpdate_.openOnServer_) {
3982            preparedStatementForUpdate_.materialPreparedStatement_.readPrepare_();
3983        }
3984
3985        readUpdateRow();
3986
3987        if (chainAutoCommit) {
3988            connection_.readCommit();
3989        }
3990        agent_.endReadChain();
3991    }
3992
3993    protected void positionToCurrentRowAndDelete() throws SqlException {
3994        agent_.beginWriteChain(statement_);
3995
3996        // calculate the position of the current row relative to the absolute position on server
3997
long currentRowPosRelativeToAbsoluteRowPos = getRowUncast() - absolutePosition_;
3998
3999        // if rowToFetch is zero, already positioned on the current row
4000
// do not reposition forward-only cursors.
4001
if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY &&
4002                (currentRowPosRelativeToAbsoluteRowPos != 0 ||
4003                (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
4004            writePositioningFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
4005                    scrollOrientation_relative__,
4006                    currentRowPosRelativeToAbsoluteRowPos);
4007        }
4008
4009        // re-prepare the update statement if repreparing is needed after a commit.
4010
if (!preparedStatementForDelete_.openOnServer_) {
4011            preparedStatementForDelete_.materialPreparedStatement_.writePrepare_(preparedStatementForDelete_.sql_,
4012                    preparedStatementForDelete_.section_);
4013        }
4014
4015        try {
4016            writeDeleteRow();
4017        } catch ( SQLException JavaDoc sqle ) {
4018            throw new SqlException(sqle);
4019        }
4020
4021        agent_.flow(statement_);
4022
4023        // adjust the absolute position on the client.
4024
absolutePosition_ += currentRowPosRelativeToAbsoluteRowPos;
4025
4026        if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY &&
4027                (currentRowPosRelativeToAbsoluteRowPos != 0 ||
4028                (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
4029            readPositioningFetch_();
4030            cursorUnpositionedOnServer_ = false;
4031            listenToUnitOfWork();
4032        }
4033
4034        // read prepare replies if the update statement is re-prepared after a commit.
4035
if (!preparedStatementForDelete_.openOnServer_) {
4036            preparedStatementForDelete_.materialPreparedStatement_.readPrepare_();
4037        }
4038        readDeleteRow();
4039
4040        agent_.endReadChain();
4041    }
4042
4043    protected void delete() throws SqlException {
4044        try
4045        {
4046            agent_.beginWriteChain(statement_);
4047
4048            // re-prepare the update statement if repreparing is needed after a commit.
4049
if (!preparedStatementForDelete_.openOnServer_) {
4050                preparedStatementForDelete_.materialPreparedStatement_.writePrepare_(preparedStatementForDelete_.sql_,
4051                        preparedStatementForDelete_.section_);
4052            }
4053
4054            if (isRowsetCursor_) {
4055                preparedStatementForDelete_.setInt(1, (int) (currentRowInRowset_ + 1));
4056            }
4057
4058            writeDeleteRow();
4059
4060            if (connection_.autoCommit_) {
4061                connection_.writeAutoCommit();
4062            }
4063
4064            agent_.flow(statement_);
4065
4066            // read prepare replies if the update statement is re-prepared after a commit.
4067
if (!preparedStatementForDelete_.openOnServer_) {
4068                preparedStatementForDelete_.materialPreparedStatement_.readPrepare_();
4069            }
4070            readDeleteRow();
4071            if (connection_.autoCommit_) {
4072                connection_.readAutoCommit();
4073            }
4074            agent_.endReadChain();
4075        }
4076        catch ( SQLException JavaDoc se )
4077        {
4078            throw new SqlException(se);
4079        }
4080    }
4081
4082    // Resets all rowset related flags.
4083
// Called by getRowSet() from material layer.
4084
public void setRowsetAfterLastEvent() throws SqlException {
4085        firstRowInRowset_ = 0;
4086        lastRowInRowset_ = 0;
4087        absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1 : maxRows_ + 1;
4088        currentRowInRowset_ = 0;
4089        rowsReceivedInCurrentRowset_ = 0;
4090    }
4091
4092    public void setRowsetBeforeFirstEvent() throws SqlException {
4093        firstRowInRowset_ = 0;
4094        lastRowInRowset_ = 0;
4095        absolutePosition_ = 0;
4096        currentRowInRowset_ = -1;
4097        rowsReceivedInCurrentRowset_ = 0;
4098    }
4099
4100    public void setRowsetNoRowsEvent() {
4101        rowCount_ = 0;
4102        firstRowInRowset_ = 0;
4103        lastRowInRowset_ = 0;
4104        absolutePosition_ = 0;
4105        currentRowInRowset_ = -1;
4106        rowsReceivedInCurrentRowset_ = 0;
4107    }
4108
4109    private boolean isServersCursorPositionBeforeFirst() throws SqlException {
4110        return (isBeforeFirstX() && firstRowInRowset_ == 0 && lastRowInRowset_ == 0 && absolutePosition_ == 0);
4111    }
4112
4113    private boolean isServerCursorPositionAfterLast() throws SqlException {
4114        return (absolutePosition_ == (rowCount_ + 1));
4115    }
4116
4117    public void setValidCursorPosition(boolean isValidCursorPosition) {
4118        isValidCursorPosition_ = isValidCursorPosition;
4119    }
4120
4121    protected void moveToAfterLast() throws DisconnectException {
4122        flowPositioningFetch(ResultSet.scrollOrientation_after__, 0);
4123    }
4124
4125    // Positions the cursor at before the first row.
4126
protected void moveToBeforeFirst() throws DisconnectException {
4127        flowPositioningFetch(ResultSet.scrollOrientation_before__, 0);
4128    }
4129
4130    // analyze the error handling here, and whether or not can be pushed to common
4131
// can we make this the common layer fetch method
4132
// Called by the read/skip Fdoca bytes methods in the net
4133
// whenever data reads exhaust the internal buffer used by this reply
4134
public void flowFetch() throws DisconnectException, SqlException {
4135        agent_.beginWriteChain(statement_);
4136        writeFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_);
4137        agent_.flow(statement_);
4138        readFetch_();
4139        agent_.endReadChain();
4140    }
4141
4142    public void writeInsertRow(boolean chainedWritesFollowingSetLob) throws SQLException JavaDoc {
4143        try
4144        {
4145            preparedStatementForInsert_.materialPreparedStatement_.writeExecute_(
4146                    preparedStatementForInsert_.section_,
4147                    preparedStatementForInsert_.parameterMetaData_,
4148                    preparedStatementForInsert_.parameters_,
4149                    (preparedStatementForInsert_.parameterMetaData_ == null ? 0 :
4150                        preparedStatementForInsert_.parameterMetaData_.getColumnCount()),
4151                    false, // false means we're not expecting output
4152
chainedWritesFollowingSetLob); // chaining after the execute
4153
}
4154        catch ( SqlException se )
4155        {
4156            throw se.getSQLException();
4157        }
4158    }
4159    
4160    public void writeUpdateRow(boolean chainedWritesFollowingSetLob) throws SQLException JavaDoc {
4161        try
4162        {
4163            preparedStatementForUpdate_.materialPreparedStatement_.writeExecute_(preparedStatementForUpdate_.section_,
4164                    preparedStatementForUpdate_.parameterMetaData_,
4165                    preparedStatementForUpdate_.parameters_,
4166                    preparedStatementForUpdate_.parameterMetaData_.getColumnCount(),
4167                    false, // false means we're not expecting output
4168
chainedWritesFollowingSetLob); // chaining after the execute
4169
}
4170        catch ( SqlException se )
4171        {
4172            throw se.getSQLException();
4173        }
4174    }
4175
4176    public void writeDeleteRow() throws SQLException JavaDoc {
4177        try
4178        {
4179            if (isRowsetCursor_) {
4180                preparedStatementForDelete_.materialPreparedStatement_.writeExecute_(preparedStatementForDelete_.section_,
4181                        preparedStatementForDelete_.parameterMetaData_,
4182                        preparedStatementForDelete_.parameters_,
4183                        preparedStatementForDelete_.parameterMetaData_.getColumnCount(),
4184                        false, // false means we're not expecting output
4185
false); // false means we don't chain anything after the execute
4186
} else {
4187                preparedStatementForDelete_.materialPreparedStatement_.writeExecute_(preparedStatementForDelete_.section_,
4188                        null, // do not need parameterMetaData since there is no input
4189
null, // no inputs
4190
0, // number of input columns is 0 for positioned delete
4191
false, // false means we're not expecting output
4192
false); // false means we don't chain anything after the execute
4193
}
4194        }
4195        catch ( SqlException se )
4196        {
4197            throw se.getSQLException();
4198        }
4199    }
4200
4201    public void readInsertRow() throws DisconnectException, SqlException {
4202        preparedStatementForInsert_.materialPreparedStatement_.readExecute_();
4203    }
4204
4205    public void readUpdateRow() throws DisconnectException, SqlException {
4206        preparedStatementForUpdate_.materialPreparedStatement_.readExecute_();
4207        accumulateWarning(preparedStatementForUpdate_.getSqlWarnings());
4208    }
4209
4210    public void readDeleteRow() throws DisconnectException, SqlException {
4211        preparedStatementForDelete_.materialPreparedStatement_.readExecute_();
4212        accumulateWarning(preparedStatementForDelete_.getSqlWarnings());
4213    }
4214
4215    //------------------material layer event callback methods-----------------------
4216

4217    boolean listenToUnitOfWork_ = false;
4218
4219    public void listenToUnitOfWork() {
4220        if (!listenToUnitOfWork_) {
4221            listenToUnitOfWork_ = true;
4222            connection_.CommitAndRollbackListeners_.put(this, null);
4223        }
4224    }
4225
4226    public void completeLocalCommit(java.util.Iterator JavaDoc listenerIterator) {
4227        cursorUnpositionedOnServer_ = true;
4228        markAutoCommitted();
4229        if (!cursorHold_) {
4230            // only non-held cursors need to be closed at commit
4231
markClosed();
4232            nullOutReferenceInStatement();
4233            // remove from listener list
4234
listenerIterator.remove();
4235            listenToUnitOfWork_ = false;
4236        }
4237    }
4238
4239    public void completeLocalRollback(java.util.Iterator JavaDoc listenerIterator) {
4240        markAutoCommitted();
4241        // all cursors need to be closed at rollback
4242
markClosed();
4243        nullOutReferenceInStatement();
4244        // remove from listener list
4245
listenerIterator.remove();
4246        listenToUnitOfWork_ = false;
4247    }
4248
4249    private void nullOutReferenceInStatement() {
4250        if (statement_.resultSet_ == this) {
4251            statement_.resultSet_ = null;
4252        }
4253        /*
4254         * Aug 10, 2005: Do we really only want to only null out the one resultSet?
4255         * The only time this method is called is from completeLocalCommit or
4256         * completeLocalRollback, both of which affect *all* ResultSets
4257         */

4258        if (statement_.resultSetList_ != null) {
4259            for (int i = 0; i < statement_.resultSetList_.length; i++) {
4260                if (statement_.resultSetList_[i] == this) {
4261                    statement_.resultSetList_[i] = null;
4262                }
4263            }
4264        }
4265    }
4266
4267    /**
4268     * Mark this ResultSet as closed. The ResultSet will not be
4269     * removed from the commit and rollback listeners list in
4270     * <code>org.apache.derby.client.am.Connection</code>.
4271     */

4272    void markClosed() {
4273        markClosed(false);
4274    }
4275
4276    /**
4277     * Mark this ResultSet as closed.
4278     *
4279     * @param removeListener if true the ResultSet will be removed
4280     * from the commit and rollback listeners list in
4281     * <code>org.apache.derby.client.am.Connection</code>.
4282     */

4283    void markClosed(boolean removeListener) {
4284        openOnClient_ = false;
4285        openOnServer_ = false;
4286        statement_.resetCursorNameAndRemoveFromWhereCurrentOfMappings(); // for SELECT...FOR UPDATE queries
4287
statement_.removeClientCursorNameFromCache();
4288        markPositionedUpdateDeletePreparedStatementsClosed();
4289        if (removeListener) {
4290            connection_.CommitAndRollbackListeners_.remove(this);
4291        }
4292    }
4293
4294    /**
4295     * Mark this ResultSet as closed on the server.
4296     */

4297    public void markClosedOnServer() {
4298        openOnServer_ = false;
4299    }
4300
4301    void markAutoCommitted() {
4302        autoCommitted_ = true;
4303    }
4304
4305    // The query was ended at the server because all rows have been retrieved.
4306
public void earlyCloseComplete(Sqlca sqlca) {
4307        markClosedOnServer();
4308        queryTerminatingSqlca_ = sqlca;
4309        cursor_.setAllRowsReceivedFromServer(true);
4310    }
4311
4312    public int completeSqlca(Sqlca sqlca) {
4313        if (sqlca == null) {
4314            return 0;
4315        }
4316        int sqlcode = sqlca.getSqlCode();
4317        if (sqlcode == 100 || sqlcode == 20237) {
4318            cursor_.setAllRowsReceivedFromServer(true);
4319        } else if (sqlcode < 0) {
4320            connection_.agent_.accumulateReadException(new SqlException(agent_.logWriter_, sqlca));
4321        } else if (sqlcode > 0) {
4322            accumulateWarning(new SqlWarning(agent_.logWriter_, sqlca));
4323        }
4324        return sqlcode;
4325    }
4326
4327    // Set rowCount.
4328
public void setRowCountEvent(long rowCount) throws DisconnectException {
4329        // Only set the row count if it's unknown, to prevent clobbering of a valid value.
4330
if (rowCount_ == -1) {
4331            rowCount_ = rowCount;
4332        }
4333    }
4334
4335    // This method will not work if e is chained.
4336
// It is assumed that e is a single warning and is not chained.
4337
public void accumulateWarning(SqlWarning e) {
4338        if (warnings_ == null) {
4339            warnings_ = e;
4340        } else {
4341            warnings_.setNextException(e);
4342        }
4343    }
4344
4345    //-------------------------------helper methods-------------------------------
4346
protected boolean rowCountIsUnknown() {
4347        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4348            return false;
4349        } else {
4350            return rowCount_ == -1;
4351        }
4352    }
4353
4354    protected boolean rowCountIsKnown() {
4355        return rowCount_ != -1;
4356    }
4357
4358    private void updateColumn(int column, Object JavaDoc value) {
4359        if (updatedColumns_ == null) {
4360            updatedColumns_ = new Object JavaDoc[resultSetMetaData_.columns_];
4361        }
4362        if (columnUpdated_ == null) {
4363            columnUpdated_ = new boolean[resultSetMetaData_.columns_];
4364        }
4365
4366        updatedColumns_[column - 1] = value;
4367        columnUpdated_[column - 1] = true;
4368    }
4369    
4370    /*
4371     * Builds the insert statement that will be used well calling insertRow
4372     *
4373     * If no values have been supplied for a column, it will be set
4374     * to the column's default value, if any.
4375     * If no default value had been defined, the default value of a
4376     * nullable column is set to NULL.
4377     */

4378    private String JavaDoc buildInsertString() throws SqlException {
4379        int column;
4380        boolean foundOneUpdatedColumnAlready = false;
4381        
4382        StringBuffer JavaDoc insertSQL = new StringBuffer JavaDoc("INSERT INTO ");
4383        StringBuffer JavaDoc valuesSQL = new StringBuffer JavaDoc("VALUES (");
4384
4385        insertSQL.append(getTableName());
4386        insertSQL.append(" (");
4387        
4388        for (column = 1; column <= resultSetMetaData_.columns_; column++) {
4389            if (foundOneUpdatedColumnAlready) {
4390                insertSQL.append(",");
4391                valuesSQL.append(",");
4392            }
4393            //using quotes around the column name to preserve case sensitivity
4394
try {
4395                insertSQL.append(quoteSqlIdentifier(
4396                        resultSetMetaData_.getColumnName(column)));
4397            } catch ( SQLException JavaDoc sqle ) {
4398                throw new SqlException(sqle);
4399            }
4400            if (columnUpdated_[column - 1]) {
4401                valuesSQL.append("?");
4402            } else {
4403                valuesSQL.append("DEFAULT");
4404            }
4405            foundOneUpdatedColumnAlready = true;
4406        }
4407        
4408        insertSQL.append(") ");
4409        valuesSQL.append(") ");
4410        insertSQL.append(valuesSQL.toString());
4411        
4412        return(insertSQL.toString());
4413    }
4414    
4415    private String JavaDoc buildUpdateString() throws SqlException {
4416        int column;
4417        int numColumns = 0;
4418
4419        // For Derby, eg update t1 set c1=?, c2=? where current of cursorname
4420
boolean foundOneUpdatedColumnAlready = false;
4421        String JavaDoc updateString = "UPDATE " + getTableName() + " SET ";
4422
4423        for (column = 1; column <= resultSetMetaData_.columns_; column++) {
4424            if (columnUpdated_[column - 1]) {
4425                if (foundOneUpdatedColumnAlready) {
4426                    updateString += ",";
4427                }
4428                try {
4429                    updateString += quoteSqlIdentifier(
4430                            resultSetMetaData_.getColumnName(column)) +
4431                            " = ? ";
4432                } catch ( SQLException JavaDoc sqle ) {
4433                    throw new SqlException(sqle);
4434                }
4435                numColumns++;
4436                foundOneUpdatedColumnAlready = true;
4437            }
4438        }
4439        if (foundOneUpdatedColumnAlready == false) //no columns updated on this row
4440
{
4441            return null;
4442        }
4443        updateString = updateString + " WHERE CURRENT OF " + getServerCursorName();
4444
4445        if (isRowsetCursor_) {
4446            updateString += " FOR ROW ? OF ROWSET";
4447        }
4448
4449        return updateString;
4450    }
4451
4452    private String JavaDoc buildDeleteString() throws SqlException {
4453        String JavaDoc deleteString = "DELETE FROM ";
4454
4455        // build the delete string using the server's cursor name
4456
deleteString += (getTableName() + " WHERE CURRENT OF \"" + getServerCursorName() + "\"");
4457
4458        if (isRowsetCursor_) {
4459            deleteString += " FOR ROW ? OF ROWSET";
4460        }
4461
4462        return deleteString;
4463    }
4464
4465    //Go through all the columns in the select list to see if we can find a
4466
//base table column and use that column's metadata to get the table name
4467
//But, it is possible to have a sql of the form
4468
//select 1,2 from t1 for update
4469
//This sql will not be a good candidate for updateXXX calls(both in embedded
4470
//and Network Server mode) since there is no updatable column in the select
4471
//list. But a user can use a sql like that to issue deleteRow. In Network
4472
//Server mode though, this sql will fail for deleteRow because none of the
4473
//columns are from base table and w/o a base table column, there is no way
4474
//to find the table name for delete
4475
private String JavaDoc getTableName() throws SqlException {
4476        String JavaDoc tableName = "";
4477        int baseTableColumn = 0;
4478        int totalColumns;
4479        try {
4480            totalColumns = resultSetMetaData_.getColumnCount();
4481        } catch ( SQLException JavaDoc sqle ) {
4482            throw new SqlException(sqle);
4483        }
4484        for (; baseTableColumn < totalColumns; baseTableColumn++) {
4485            if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null)
4486                break;
4487        }
4488
4489        //if following true, then there are no base table columns in select list
4490
if (baseTableColumn == totalColumns)
4491            baseTableColumn = 0;
4492
4493        //dervied column like select 2 from t1, has null schema and table name
4494
if (resultSetMetaData_.sqlxSchema_[baseTableColumn] != null && !resultSetMetaData_.sqlxSchema_[baseTableColumn].equals("")) {
4495            tableName += quoteSqlIdentifier(
4496                    resultSetMetaData_.sqlxSchema_[baseTableColumn]) + ".";
4497        }
4498        if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null) {
4499            tableName += quoteSqlIdentifier(
4500                    resultSetMetaData_.sqlxBasename_[baseTableColumn]);
4501        }
4502        return tableName;
4503    }
4504
4505    private String JavaDoc quoteSqlIdentifier(String JavaDoc orgValue) {
4506        int i = 0, start = 0;
4507        String JavaDoc retValue = "";
4508        while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
4509            retValue += orgValue.substring(start, i) + "\"";
4510            start = i;
4511        }
4512        retValue += orgValue.substring(start, orgValue.length());
4513        return "\"" + retValue + "\"";
4514    }
4515    
4516    private String JavaDoc getServerCursorName() throws SqlException {
4517        return statement_.section_.getServerCursorName();
4518    }
4519
4520    private void getPreparedStatementForInsert() throws SqlException {
4521        // each column is associated with a tableName in the extended describe info.
4522
String JavaDoc insertString = buildInsertString();
4523
4524        try {
4525            preparedStatementForInsert_ = (PreparedStatement)statement_.connection_.
4526                    prepareStatement(insertString);
4527        } catch ( SQLException JavaDoc sqle ) {
4528            throw new SqlException(sqle);
4529        }
4530    }
4531
4532    private void getPreparedStatementForUpdate() throws SqlException {
4533        // each column is associated with a tableName in the extended describe info.
4534
String JavaDoc updateString = buildUpdateString();
4535
4536        if (updateString == null) {
4537            throw new SqlException(agent_.logWriter_,
4538                new ClientMessageId(SQLState.CURSOR_NO_UPDATE_CALLS_ON_CURRENT_ROW));
4539        }
4540        preparedStatementForUpdate_ =
4541                statement_.connection_.preparePositionedUpdateStatement(updateString,
4542                        statement_.section_.getPositionedUpdateSection());
4543
4544    }
4545
4546    private void getPreparedStatementForDelete() throws SqlException {
4547        // each column is associated with a tableName in the extended describe info.
4548
String JavaDoc deleteString = buildDeleteString();
4549
4550        preparedStatementForDelete_ =
4551                statement_.connection_.preparePositionedUpdateStatement(deleteString,
4552                        statement_.section_.getPositionedUpdateSection()); // update section
4553
}
4554
4555    private final void resetUpdatedColumnsForInsert() {
4556        // initialize updateColumns with nulls for all columns
4557
if (updatedColumns_ == null) {
4558            updatedColumns_ = new Object JavaDoc[resultSetMetaData_.columns_];
4559        }
4560        if (columnUpdated_ != null) {
4561            columnUpdated_ = new boolean[resultSetMetaData_.columns_];
4562        }
4563        for (int i = 0; i < updatedColumns_.length; i++) {
4564            updateColumn(i+1, null);
4565        }
4566        for (int i = 0; i < columnUpdated_.length; i++) {
4567            columnUpdated_[i] = false;
4568        }
4569    }
4570
4571    private final void resetUpdatedColumns() {
4572        if (updatedColumns_ != null) {
4573            for (int i = 0; i < updatedColumns_.length; i++) {
4574                updatedColumns_[i] = null;
4575            }
4576        }
4577        if (columnUpdated_ != null) {
4578            for (int i = 0; i < columnUpdated_.length; i++) {
4579                columnUpdated_[i] = false;
4580            }
4581        }
4582    }
4583
4584    private final long getRowUncast() {
4585        return firstRowInRowset_ + currentRowInRowset_;
4586    }
4587
4588    private final void checkGetterPreconditions(int column) throws SqlException {
4589        checkForClosedResultSet();
4590        checkForValidColumnIndex(column);
4591        checkForValidCursorPosition();
4592    }
4593
4594    private final void checkUpdatePreconditions(int column,
4595                        String JavaDoc operation)
4596    throws SqlException {
4597
4598        checkForClosedResultSet();
4599        checkForValidColumnIndex(column);
4600    checkForUpdatableResultSet(operation);
4601
4602        if (!isOnCurrentRow_ && !isOnInsertRow_) {
4603            throw new SqlException(agent_.logWriter_,
4604                new ClientMessageId(SQLState.CURSOR_NOT_ON_CURRENT_OR_INSERT_ROW));
4605        }
4606
4607        if (resultSetMetaData_.sqlxUpdatable_ == null || resultSetMetaData_.sqlxUpdatable_[column - 1] != 1) {
4608            throw new SqlException(agent_.logWriter_,
4609                new ClientMessageId(SQLState.CURSOR_COLUMN_NOT_UPDATABLE));
4610        }
4611
4612        //if not on a valid row, then do not accept updateXXX calls
4613
if (!isValidCursorPosition_)
4614            throw new SqlException(agent_.logWriter_,
4615                new ClientMessageId(SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
4616    }
4617
4618    final void checkForValidColumnIndex(int column) throws SqlException {
4619        if (column < 1 || column > resultSetMetaData_.columns_) {
4620            throw new SqlException(agent_.logWriter_,
4621                new ClientMessageId(SQLState.LANG_INVALID_COLUMN_POSITION),
4622                new Integer JavaDoc(column), new Integer JavaDoc(resultSetMetaData_.columns_));
4623        }
4624    }
4625
4626    protected final void checkForClosedResultSet() throws SqlException {
4627        if (!openOnClient_) {
4628            agent_.checkForDeferredExceptions();
4629            throw new SqlException(agent_.logWriter_,
4630                new ClientMessageId(SQLState.CLIENT_RESULT_SET_NOT_OPEN));
4631        } else {
4632            agent_.checkForDeferredExceptions();
4633        }
4634    }
4635
4636    private final void checkForUpdatableResultSet(String JavaDoc operation)
4637        throws SqlException {
4638        if (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY) {
4639            throw new SqlException(agent_.logWriter_,
4640                    new ClientMessageId(SQLState.UPDATABLE_RESULTSET_API_DISALLOWED),
4641                    operation);
4642        }
4643    }
4644    
4645    private final void checkForValidCursorPosition() throws SqlException {
4646        if (!isValidCursorPosition_) {
4647            throw new SqlException(agent_.logWriter_,
4648                new ClientMessageId(SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
4649        }
4650    }
4651
4652
4653    private final void checkPositionedOnPlainRow() throws SqlException {
4654        if (isOnInsertRow_ || !isValidCursorPosition_) {
4655            throw new SqlException
4656                (agent_.logWriter_,
4657                 new ClientMessageId(SQLState.NO_CURRENT_ROW));
4658        }
4659    }
4660
4661
4662    private final void checkThatResultSetTypeIsScrollable() throws SqlException {
4663        if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
4664            throw new SqlException(agent_.logWriter_,
4665                new ClientMessageId(SQLState.CURSOR_MUST_BE_SCROLLABLE));
4666        }
4667    }
4668
4669    private final void checkThatResultSetIsNotDynamic() throws SqlException {
4670        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4671            throw new SqlException(agent_.logWriter_,
4672                new ClientMessageId(SQLState.CURSOR_INVALID_FOR_SENSITIVE_DYNAMIC));
4673        }
4674    }
4675
4676    private boolean resultSetContainsNoRows() throws SqlException {
4677        if (rowCountIsUnknown()) {
4678            getRowCount();
4679        }
4680        return (rowCount_ == 0);
4681    }
4682
4683    private boolean rowIsInCurrentRowset(long rowNumber, int orientation) throws SqlException {
4684        if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4685            switch (orientation) {
4686            case scrollOrientation_next__:
4687                if (isAfterLast_) {
4688                    return false;
4689                } else {
4690                    return (currentRowInRowset_ + 1 < rowsReceivedInCurrentRowset_);
4691                }
4692            case scrollOrientation_prior__:
4693                if (isBeforeFirst_) {
4694                    return false;
4695                } else {
4696                    return (currentRowInRowset_ - 1 >= 0);
4697                }
4698            case scrollOrientation_relative__:
4699                return (rowNumber < rowsReceivedInCurrentRowset_ && rowNumber >= 0);
4700
4701                // for dynamic cursors, we will not be able to check whether a row is in the cache for
4702
// FIRST, ABSOLUTE, AND LAST
4703
case scrollOrientation_first__:
4704            case scrollOrientation_absolute__:
4705            case scrollOrientation_last__:
4706                return false;
4707            default:
4708                return false;
4709            }
4710        } else {
4711            return rowIsInCurrentRowset(rowNumber);
4712        }
4713    }
4714
4715    private boolean rowIsInCurrentRowset(long rowNumber) throws SqlException {
4716        // firstRowInRowset_ is equal to lastRowInRowset_ if there is only one row
4717
// in the rowset or if fetchSize_ is 1. however, return false if firstRowInRowset_
4718
// is equal to lastRowInRowset_ and also equal to zero which means there is no
4719
// valid row in the current rowset.
4720
if (firstRowInRowset_ == lastRowInRowset_ && firstRowInRowset_ == 0) {
4721            return false;
4722        }
4723        if (rowNumber >= firstRowInRowset_ &&
4724                rowNumber <= lastRowInRowset_) {
4725            return true;
4726        } else {
4727            return false;
4728        }
4729    }
4730
4731    private void markPositionedUpdateDeletePreparedStatementsClosed() {
4732        if (preparedStatementForUpdate_ != null) {
4733            preparedStatementForUpdate_.markClosed();
4734            preparedStatementForUpdate_ = null;
4735        }
4736        if (preparedStatementForDelete_ != null) {
4737            preparedStatementForDelete_.markClosed();
4738            preparedStatementForDelete_ = null;
4739        }
4740    }
4741
4742    protected void updateColumnInfoFromCache() {
4743        // currentRowInRowset_ should never be bigger than the max value of an int,
4744
// because we have a driver imposed limit of fetch size 1000.
4745
cursor_.columnDataPosition_ =
4746                (int[]) cursor_.columnDataPositionCache_.get((int) currentRowInRowset_);
4747        cursor_.columnDataComputedLength_ =
4748                (int[]) cursor_.columnDataLengthCache_.get((int) currentRowInRowset_);
4749        cursor_.isNull_ =
4750                (boolean[]) cursor_.columnDataIsNullCache_.get((int) currentRowInRowset_);
4751        cursor_.isUpdateDeleteHole_ = ((Boolean JavaDoc) cursor_.isUpdateDeleteHoleCache_.get((int) currentRowInRowset_)).booleanValue();
4752    }
4753
4754    protected final void checkAndThrowReceivedQueryTerminatingException() throws SqlException {
4755        // If we are in a split row, and before sending CNTQRY, check whether an ENDQRYRM
4756
// has been received.
4757
if (!openOnServer_) {
4758            SqlException sqlException = null;
4759            int sqlcode = org.apache.derby.client.am.Utils.getSqlcodeFromSqlca(queryTerminatingSqlca_);
4760            if (sqlcode < 0) {
4761                sqlException = new SqlException(agent_.logWriter_, queryTerminatingSqlca_);
4762            } else if (sqlcode > 0 && sqlcode != 100) {
4763                accumulateWarning(new SqlWarning(agent_.logWriter_, queryTerminatingSqlca_));
4764            }
4765            try {
4766                closeX(); // the auto commit logic is in closeX()
4767
} catch (SqlException e) {
4768                sqlException.setNextException(e);
4769            }
4770            if (sqlException != null) {
4771                throw sqlException;
4772            }
4773        }
4774    }
4775
4776    public void parseScrollableRowset() throws SqlException {
4777        // modified check from qrydtaReturned to cursor.dataBufferHasUnprocesseData()
4778
if (cursor_.dataBufferHasUnprocessedData() && scrollable_) {
4779            parseRowset_();
4780            adjustFirstRowset();
4781
4782            // This method is only called after open query to parse out the very first rowset
4783
// received.
4784
if (cursor_.allRowsReceivedFromServer() &&
4785                rowsReceivedInCurrentRowset_ == 0) {
4786                setRowsetNoRowsEvent();
4787            }
4788        }
4789    }
4790
4791    // determines if a cursor is a:
4792
// Return to Client - not to be read by the stored procedure only by client
4793
// Return to Caller - only calling JSP can read it, not the client
4794
public byte getRSReturnability() {
4795        return rsReturnability_;
4796    }
4797
4798    public void setRSReturnability(byte rsReturnability) { // valid return type set it
4799
if ((rsReturnability == DDM_RETURN_CALLER) ||
4800                (rsReturnability == DDM_RETURN_CLIENT)) {
4801            rsReturnability_ = rsReturnability;
4802        } else { // unknown return type, set DDM_RETURN_CALLER
4803
rsReturnability_ = DDM_RETURN_CALLER;
4804        }
4805    }
4806
4807//------------------------------------------------------------------------------
4808
// Push the getXXXRowset_() methods up from the material layers
4809
//------------------------------------------------------------------------------
4810
// This method is called to retrieve the total number of rows in the result set
4811
// and then reposition the cursor to where it was before.
4812
// The rowCount_ comes back in the SQLCA in fields SQLERRD1 and SQLERRD2 when
4813
// sqlcode is +100.
4814
protected void getRowCount() throws SqlException {
4815        // if already received an ENDQRYRM at open, check sqlcode and throw an exception
4816
checkAndThrowReceivedQueryTerminatingException();
4817
4818        agent_.beginWriteChain(statement_);
4819
4820        Section section = (generatedSection_ == null) ? statement_.section_ : generatedSection_;
4821
4822        // send the first CNTQRY to place cursor after last to retrieve the rowCount_.
4823
writePositioningFetch_(section, scrollOrientation_after__, 0);
4824        // if this is a non-dynamic rowset cursor, reposition the cursor to the first row in rowset
4825
// after the fetch after. Cache info and cursor positions on the client should not change.
4826
if (isRowsetCursor_ && sensitivity_ != sensitivity_sensitive_dynamic__ && firstRowInRowset_ != 0) {
4827            writePositioningFetch_(section, scrollOrientation_absolute__, firstRowInRowset_);
4828        }
4829
4830        agent_.flow(statement_);
4831
4832        readPositioningFetch_();
4833        if (isRowsetCursor_ && sensitivity_ != sensitivity_sensitive_dynamic__ && firstRowInRowset_ != 0) {
4834            readPositioningFetch_();
4835        }
4836
4837        agent_.endReadChain();
4838
4839        // if rowCount_ is not updated, check for exceptions
4840
if (rowCount_ == -1) {
4841            checkAndThrowReceivedQueryTerminatingException();
4842        }
4843
4844        if (isRowsetCursor_ && sensitivity_ != sensitivity_sensitive_dynamic__ && firstRowInRowset_ != 0) {
4845            absolutePosition_ = firstRowInRowset_;
4846        } else {
4847            absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1 : maxRows_ + 1;
4848        }
4849    }
4850
4851    private void flowGetRowset(int orientation, long rowNumber) throws SqlException {
4852        // clear lobs before fetching rows
4853
cursor_.clearLobData_();
4854        cursor_.resetDataBuffer();
4855        agent_.beginWriteChain(statement_);
4856        
4857        writeScrollableFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
4858                fetchSize_,
4859                orientation,
4860                rowNumber,
4861                true); // true means to discard any pending partial
4862
// row and pending query blocks
4863

4864        // reset the number of rows received to 0.
4865
// cannot use rowsRead_ here because this is reset every time a new rowset is fetched
4866
rowsReceivedInCurrentRowset_ = 0;
4867
4868        agent_.flow(statement_);
4869        readScrollableFetch_();
4870        agent_.endReadChain();
4871    }
4872
4873    private boolean getNextRowset() throws SqlException {
4874        // for rowset cursors or dynamic, non-rowset cursors
4875
if (isRowsetCursor_ || sensitivity_ == sensitivity_sensitive_dynamic__) {
4876            // check if the next row contains a +100 before fetching from the server.
4877
// since index starts from 0, the actual row number for the current row is (currentRowInRowset_+1)
4878
// and the actual row number for the next row is (currentRowInRowset_+2)
4879
int sqlcode = checkRowsetSqlca((int) currentRowInRowset_ + 2);
4880            if (sqlcode == 100) {
4881                isAfterLast_ = true;
4882                return false;
4883            }
4884            flowGetRowset(scrollOrientation_next__, 0);
4885        } else {
4886            // for all other cursors:
4887
// sensitive static, insensitive, non-rowset cursors
4888
// if already afterLast, return false
4889
// if already on the last row and have received a +100, do not fetch again, return false
4890
if (resultSetContainsNoRows() || isAfterLastX()) {
4891                return false;
4892            } else if (firstRowInRowset_ + currentRowInRowset_ == lastRowInRowset_ &&
4893                    cursor_.allRowsReceivedFromServer()) {
4894                isAfterLast_ = true;
4895                setRowsetAfterLastEvent();
4896                return false;
4897            }
4898
4899            // rowNumber to fetch is 1 if absolute position is equal to the last row
4900
// in the rowset
4901
long rowNumber = 1;
4902            int orientation = scrollOrientation_relative__;
4903
4904            // Normally absolute position is equal to last row in the rowset, but in cases
4905
// of previous "update where current of"s, absolute position may be somewhere
4906
// else in the current rowset, thus rowNumber needs to be recalculated based on
4907
// where in the rowset the absolute position is.
4908
if (absolutePosition_ < lastRowInRowset_) {
4909                rowNumber = lastRowInRowset_ - absolutePosition_ + 1;
4910                absolutePosition_ = lastRowInRowset_;
4911            }
4912            // the following case happens when a getRowCount() is called and we flow a fetch after
4913
// to get the rowCount.
4914
else if (absolutePosition_ > lastRowInRowset_) {
4915                rowNumber = lastRowInRowset_ + 1;
4916                orientation = scrollOrientation_absolute__;
4917            }
4918
4919            flowGetRowset(orientation, rowNumber);
4920        }
4921
4922        parseRowset_();
4923
4924        // If no row was received but received sqlcode +100, then the cursor is
4925
// positioned after last.
4926
if (rowsReceivedInCurrentRowset_ == 0 &&
4927            cursor_.allRowsReceivedFromServer()) {
4928            isAfterLast_ = true;
4929            setRowsetAfterLastEvent();
4930            return false;
4931        }
4932
4933        // adjust the cursor positions for sensitive static or insensitive cursors only
4934
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
4935            adjustNextRowset();
4936        }
4937        currentRowInRowset_ = 0;
4938        return true;
4939    }
4940
4941    private void adjustNextRowset() {
4942        firstRowInRowset_ = lastRowInRowset_ + 1;
4943        lastRowInRowset_ = lastRowInRowset_ + rowsReceivedInCurrentRowset_;
4944        setAbsolutePositionBasedOnAllRowsReceived();
4945        //currentRowInRowset_ = 0;
4946
}
4947
4948    private boolean getPreviousRowset() throws SqlException {
4949        int orientation = scrollOrientation_relative__;
4950        long rowNumber = 0;
4951        boolean isAfterLast = false;
4952
4953        // for rowset cursors or dynamic, non-rowset cursors
4954
if (isRowsetCursor_ || sensitivity_ == sensitivity_sensitive_dynamic__) {
4955            // check if we already received a +20237 before fetching from the server.
4956
if (currentRowInRowset_ == 0 && rowsetSqlca_ != null && rowsetSqlca_[0] != null &&
4957                    rowsetSqlca_[0].getSqlCode() == 20237) {
4958                isBeforeFirst_ = true;
4959                setRowsetBeforeFirstEvent();
4960                return false;
4961            }
4962            flowGetRowset(scrollOrientation_prior__, 0);
4963        } else {
4964            // for all other cursors:
4965
// sensitive static, insensitive, non-rowset cursors
4966
if (resultSetContainsNoRows() || isBeforeFirstX()) {
4967                return false;
4968            }
4969            rowNumber = firstRowInRowset_ - absolutePosition_ - fetchSize_;
4970            isAfterLast = isAfterLastX();
4971            if (isFirstX()) {
4972                rowNumber = 0;
4973                orientation = scrollOrientation_absolute__;
4974            }
4975            // If the cursor is after last, fetch the last rowset which includes the last row.
4976
else if (isAfterLast) {
4977                rowNumber = (-1) * fetchSize_;
4978            }
4979            // if the distance from the absolute position is less than fetch size, fetch from row 1
4980
if (rowNumber * (-1) >= absolutePosition_) {
4981                rowNumber = 1;
4982                orientation = scrollOrientation_absolute__;
4983            }
4984            
4985            // If afterLast and maxRows > 0, go backward from maxRows and not
4986
// from last row in the resultSet
4987
if (maxRows_ > 0 && orientation == scrollOrientation_relative__ && isAfterLast) {
4988                rowNumber += maxRows_ + 1;
4989                orientation = scrollOrientation_absolute__;
4990            }
4991            
4992            flowGetRowset(orientation, rowNumber);
4993        }
4994
4995        parseRowset_();
4996
4997        // If no row was received but received sqlcode +100, then the cursor is
4998
// positioned before first.
4999
if (rowsReceivedInCurrentRowset_ == 0 &&
5000            cursor_.allRowsReceivedFromServer()) {
5001            isBeforeFirst_ = true;
5002            setRowsetBeforeFirstEvent();
5003            return false;
5004        }
5005
5006        // adjust the cursor positions for sensitive static or insensitive cursors only
5007
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5008            adjustPreviousRowset(orientation, rowNumber, isAfterLast);
5009        } else {
5010            currentRowInRowset_ = rowsReceivedInCurrentRowset_ - 1;
5011        }
5012        return true;
5013    }
5014
5015    private void adjustPreviousRowset(int orientation, long rowNumber, boolean isAfterLastRow) throws SqlException {
5016        if (orientation == scrollOrientation_absolute__ && rowNumber == 1) {
5017            // Subtracting 2 because the currentRowInRowset_ index starts at 0, and all
5018
// the other indexes starts at 1.
5019
currentRowInRowset_ = (isAfterLastRow) ? absolutePosition_ - 2 : firstRowInRowset_ - 2;
5020            firstRowInRowset_ = 1;
5021            lastRowInRowset_ = rowsReceivedInCurrentRowset_;
5022            absolutePosition_ = (isAfterLastRow) ? lastRowInRowset_ + 1 : lastRowInRowset_;
5023        } else {
5024            if (maxRows_ == 0)
5025                lastRowInRowset_ = (isAfterLastRow) ? rowCount_ : firstRowInRowset_ - 1;
5026            else
5027                lastRowInRowset_ = (isAfterLastRow) ? maxRows_ : firstRowInRowset_ - 1;
5028            firstRowInRowset_ = lastRowInRowset_ - rowsReceivedInCurrentRowset_ + 1;
5029            absolutePosition_ = lastRowInRowset_;
5030            currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
5031        }
5032    }
5033
5034    private boolean getAbsoluteRowset(long row) throws SqlException {
5035        int orientation = scrollOrientation_absolute__;
5036        // absolute(0) is not allowed on a rowset cursor, will get -644 from the server
5037
// remap to fetch before.
5038
if (isRowsetCursor_ && row == 0) {
5039            orientation = scrollOrientation_before__;
5040        } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && row < 0) {
5041            row = 0;
5042        }
5043
5044        flowGetRowset(orientation, row);
5045        parseRowset_();
5046
5047        // If no row was received but received sqlcode +100, then the cursor is
5048
// positioned after last or before first.
5049
if ((rowsReceivedInCurrentRowset_ == 0 &&
5050             cursor_.allRowsReceivedFromServer()) ||
5051                orientation == scrollOrientation_before__) {
5052            if (row > 0) {
5053                setRowsetAfterLastEvent();
5054                isAfterLast_ = true;
5055            } else {
5056                setRowsetBeforeFirstEvent();
5057                isBeforeFirst_ = true;
5058            }
5059            return false;
5060        }
5061
5062        // adjust the cursor positions for sensitive static or insensitive cursors only
5063
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5064            adjustAbsoluteRowset(row);
5065        }
5066        currentRowInRowset_ = 0;
5067        return true;
5068    }
5069
5070    private void adjustAbsoluteRowset(long rowNumber) {
5071        firstRowInRowset_ = rowNumber;
5072        lastRowInRowset_ = firstRowInRowset_ + rowsReceivedInCurrentRowset_ - 1;
5073        setAbsolutePositionBasedOnAllRowsReceived();
5074        //currentRowInRowset_ = 0;
5075
}
5076
5077    private boolean getRelativeRowset(long rows) throws SqlException {
5078        if (rows == 0 &&
5079                (cursor_.allRowsReceivedFromServer() ||
5080                 absolutePosition_ > rowCount_)) {
5081            setRowsetAfterLastEvent();
5082            isAfterLast_ = true;
5083            return false;
5084        }
5085
5086        flowGetRowset(scrollOrientation_relative__, rows);
5087        parseRowset_();
5088
5089        if (rowsReceivedInCurrentRowset_ == 0 &&
5090            cursor_.allRowsReceivedFromServer()) {
5091            if (rows > 0) {
5092                setRowsetAfterLastEvent();
5093                isAfterLast_ = true;
5094            } else {
5095                setRowsetBeforeFirstEvent();
5096                isBeforeFirst_ = true;
5097            }
5098            return false;
5099        }
5100
5101        // adjust the cursor positions for sensitive static or insensitive cursors only
5102
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5103            adjustRelativeRowset(rows);
5104        }
5105        currentRowInRowset_ = 0;
5106        return true;
5107    }
5108
5109    private void adjustRelativeRowset(long rowNumber) {
5110        firstRowInRowset_ = absolutePosition_ + rowNumber;
5111        lastRowInRowset_ = firstRowInRowset_ + rowsReceivedInCurrentRowset_ - 1;
5112        setAbsolutePositionBasedOnAllRowsReceived();
5113    }
5114
5115    private boolean getFirstRowset() throws SqlException {
5116        flowGetRowset(scrollOrientation_absolute__, 1);
5117        parseRowset_();
5118
5119        // If no row was received but received sqlcode +100, then no row in the result set
5120
if (rowsReceivedInCurrentRowset_ == 0 &&
5121            cursor_.allRowsReceivedFromServer()) {
5122            resetRowsetFlags();
5123            this.setRowsetNoRowsEvent();
5124            return false;
5125        }
5126
5127        // adjust the cursor positions for sensitive static or insensitive cursors only
5128
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5129            adjustFirstRowset();
5130        }
5131        currentRowInRowset_ = 0;
5132        return true;
5133    }
5134
5135    private void adjustFirstRowset() {
5136        firstRowInRowset_ = 1;
5137        lastRowInRowset_ = rowsReceivedInCurrentRowset_;
5138        setAbsolutePositionBasedOnAllRowsReceived();
5139        //currentRowInRowset_ = 0;
5140
}
5141
5142    private boolean getLastRowset(long row) throws SqlException {
5143        if (sensitivity_ != sensitivity_sensitive_dynamic__ && rowCount_ == 0) {
5144            isAfterLast_ = false;
5145            isBeforeFirst_ = false;
5146            setRowsetNoRowsEvent();
5147            return false;
5148        } else if (isRowsetCursor_ || sensitivity_ == sensitivity_sensitive_dynamic__) {
5149            flowGetRowset(scrollOrientation_last__, 0);
5150        } else {
5151            // If fetchSize_ is smaller than the total number of rows in the ResultSet,
5152
// then fetch one rowset of fetchSize_ number of rows. Otherwise, we will
5153
// fetch all rows in the ResultSet, so start fetching from row 1.
5154
long rowNumber;
5155            if (maxRows_ == 0) {
5156                rowNumber = (fetchSize_ < row) ? ((-1) * fetchSize_) : 1;
5157            } else {
5158                rowNumber = (fetchSize_ < row) ? (maxRows_ - fetchSize_) + 1 : 1;
5159            }
5160            flowGetRowset(scrollOrientation_absolute__, rowNumber);
5161        }
5162        parseRowset_();
5163
5164        if (rowsReceivedInCurrentRowset_ == 0 &&
5165            cursor_.allRowsReceivedFromServer()) {
5166            isAfterLast_ = true;
5167            setRowsetAfterLastEvent();
5168            return false;
5169        }
5170
5171        // adjust the cursor positions for sensitive static or insensitive cursors only
5172
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5173            adjustLastRowset(row);
5174        } else {
5175            currentRowInRowset_ = rowsReceivedInCurrentRowset_ - 1;
5176        }
5177        return true;
5178    }
5179
5180    private void adjustLastRowset(long row) {
5181        lastRowInRowset_ = row;
5182        firstRowInRowset_ = lastRowInRowset_ - rowsReceivedInCurrentRowset_ + 1;
5183        if (firstRowInRowset_ <= 0) {
5184            firstRowInRowset_ = 1;
5185        }
5186        setAbsolutePositionBasedOnAllRowsReceived();
5187        currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
5188    }
5189
5190    private boolean getRefreshRowset() throws SqlException {
5191        if (isRowsetCursor_) {
5192            flowGetRowset(scrollOrientation_current__, 0);
5193        } else {
5194            flowGetRowset(scrollOrientation_relative__, (-1) * (absolutePosition_ - firstRowInRowset_));
5195        }
5196
5197        parseRowset_();
5198
5199        // Rowset indexes do not change when rowset is refreshed.
5200
// The only exception is absolutePosition_. It may be different after the refresh.
5201
if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5202            adjustRefreshRowset();
5203        }
5204        return true;
5205    }
5206
5207    private void adjustRefreshRowset() {
5208        setAbsolutePositionBasedOnAllRowsReceived();
5209        updateColumnInfoFromCache();
5210    }
5211
5212    private void setAbsolutePositionBasedOnAllRowsReceived() {
5213        absolutePosition_ = (cursor_.allRowsReceivedFromServer()) ?
5214                lastRowInRowset_ + 1 : lastRowInRowset_;
5215    }
5216
5217    // ------------------------------- abstract box car methods --------------------------------------
5218
public abstract void writeFetch_(Section section) throws SqlException;
5219
5220    public abstract void readFetch_() throws SqlException;
5221
5222
5223    public abstract void writeScrollableFetch_(Section section,
5224                                               int fetchSize, // need to send fetchSize in case when we get an
5225
// incomplete rowset, the fetchSize is the remaining
5226
// number of the rows in the rowset.
5227
int orientation,
5228                                               long rowToFetch,
5229                                               boolean resetQueryBlocks) throws SqlException;
5230
5231    public abstract void readScrollableFetch_() throws SqlException;
5232
5233    public abstract void writePositioningFetch_(Section section,
5234                                                int orientation,
5235                                                long rowToFetch) throws SqlException;
5236
5237    public abstract void readPositioningFetch_() throws SqlException;
5238
5239    public abstract void writeCursorClose_(Section section) throws SqlException;
5240
5241    public abstract void readCursorClose_() throws SqlException;
5242
5243    protected abstract void parseRowset_() throws SqlException;
5244
5245    public abstract void setFetchSize_(int rows);
5246
5247    /**
5248     * Method that is invoked by <code>closeX()</code> before the
5249     * result set is actually being closed. Subclasses may override
5250     * this method if work needs to be done before closing.
5251     *
5252     * @exception SqlException
5253     */

5254    protected abstract void preClose_() throws SqlException;
5255
5256    public ConnectionCallbackInterface getConnectionCallbackInterface() {
5257        return connection_;
5258    }
5259
5260    public StatementCallbackInterface getStatementCallbackInterface() {
5261        return statement_;
5262    }
5263
5264    public void expandRowsetSqlca() {
5265        // rowsetSqlca_ index starts from 1. entry 0 is reserved for warning +20237
5266
// if rowset size is n, then the (n+1)th entry is reserved for the +100 if one is received.
5267
// thus the size of the rowsetSqlca_ needs to be fetchSize_+2
5268
if (isRowsetCursor_ &&
5269                (rowsetSqlca_ == null || rowsetSqlca_.length < fetchSize_ + 2)) {
5270            rowsetSqlca_ = new Sqlca[fetchSize_ + 2];
5271        }
5272    }
5273
5274    private final int checkRowsetSqlca() throws SqlException {
5275        return checkRowsetSqlca((int) currentRowInRowset_ + 1);
5276    }
5277
5278    private final int checkRowsetSqlca(int row) throws SqlException {
5279        int sqlcode = 0;
5280        if (!isRowsetCursor_ || rowsetSqlca_ == null || rowsetSqlca_[row] == null) {
5281            warnings_ = null; // clear any previous warnings
5282
return sqlcode;
5283        }
5284
5285        Sqlca sqlca = rowsetSqlca_[row];
5286        if (sqlca != null) {
5287            sqlcode = sqlca.getSqlCode();
5288            if (sqlcode < 0) {
5289                throw new SqlException(agent_.logWriter_, sqlca);
5290            } else if (sqlcode > 0 && (sqlcode != 100 && sqlcode != +20237)) {
5291                accumulateWarning(new SqlWarning(agent_.logWriter_, sqlca));
5292            }
5293        }
5294        return sqlcode;
5295    }
5296
5297    private void resetRowsetFlags() {
5298        isBeforeFirst_ = false;
5299        isAfterLast_ = false;
5300        isFirst_ = false;
5301        isLast_ = false;
5302    }
5303
5304    private void resetRowsetSqlca() {
5305        if (rowsetSqlca_ != null) {
5306            for (int i = 0; i < rowsetSqlca_.length; i++) {
5307                rowsetSqlca_[i] = null;
5308            }
5309        }
5310    }
5311    
5312    
5313    private CloseFilterInputStream createCloseFilterInputStream(java.io.InputStream JavaDoc is) throws SqlException {
5314        
5315        if(is == null){
5316            return null;
5317        }
5318
5319        if( is_ == is ){
5320            return is_;
5321        }
5322        
5323        closeCloseFilterInputStream();
5324        
5325        is_ = new CloseFilterInputStream(is);
5326        
5327        return is_;
5328        
5329    }
5330    
5331    
5332    private void closeCloseFilterInputStream() throws SqlException {
5333        
5334        if(is_ != null){
5335            try{
5336                is_.close();
5337                
5338            }catch(IOException JavaDoc e){
5339                throw new SqlException(agent_.logWriter_ ,
5340                    new ClientMessageId(SQLState.JAVA_EXCEPTION),
5341                    "java.io.IOException", e.getMessage(), e);
5342            }
5343            
5344            is_ = null;
5345            
5346        }
5347    }
5348    
5349    
5350    void useStream(int columnIndex) throws SqlException {
5351    
5352    if(streamUsedFlags_[columnIndex - 1]){
5353        throw new SqlException(agent_.logWriter_,
5354            new ClientMessageId(SQLState.LANG_STREAM_RETRIEVED_ALREADY));
5355    }
5356
5357    streamUsedFlags_[columnIndex - 1] = true;
5358
5359    }
5360
5361
5362    private void unuseStreams(){
5363    
5364    if(streamUsedFlags_ == null){
5365        streamUsedFlags_ = new boolean[ resultSetMetaData_.columns_ ];
5366        return;
5367    }
5368
5369    for(int i = 0;
5370        i < streamUsedFlags_.length;
5371        i ++){
5372        
5373        streamUsedFlags_[i] = false;
5374        
5375    }
5376    
5377    }
5378
5379    private SQLException JavaDoc jdbc3MethodNotSupported()
5380    {
5381        return new SqlException(agent_.logWriter_,
5382            new ClientMessageId(SQLState.JDBC_METHOD_NOT_IMPLEMENTED)).
5383            getSQLException();
5384    }
5385    
5386    // -------------------------- JDBC 4.0 --------------------------
5387

5388    /**
5389     * Retrieves the holdability for this <code>ResultSet</code>
5390     * object.
5391     *
5392     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
5393     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
5394     * @exception SQLException if a database error occurs
5395     */

5396    public final int getHoldability() throws SQLException JavaDoc {
5397        if (agent_.loggingEnabled()) {
5398            agent_.logWriter_.traceEntry(this, "getHoldability");
5399        }
5400        try {
5401            checkForClosedResultSet();
5402        } catch (SqlException se) {
5403            throw se.getSQLException();
5404        }
5405        if (agent_.loggingEnabled()) {
5406            agent_.logWriter_.traceExit(this, "getHoldability",
5407                                        resultSetHoldability_);
5408        }
5409        return resultSetHoldability_;
5410    }
5411    
5412    /**
5413     * Checks whether this <code>ResultSet</code> object has been
5414     * closed, either automatically or because <code>close()</code>
5415     * has been called.
5416     *
5417     * @return <code>true</code> if the <code>ResultSet</code> is
5418     * closed, <code>false</code> otherwise
5419     * @exception SQLException if a database error occurs
5420     */

5421    public final boolean isClosed() throws SQLException JavaDoc {
5422        if (agent_.loggingEnabled()) {
5423            agent_.logWriter_.traceEntry(this, "isClosed");
5424        }
5425        final boolean isClosed = !openOnClient_;
5426        if (agent_.loggingEnabled()) {
5427            agent_.logWriter_.traceExit(this, "isClosed", isClosed);
5428        }
5429        return isClosed;
5430    }
5431
5432    /**
5433     * Updates the designated column with an ascii stream value.
5434     * The data will be read from the stream as needed until end-of-stream is
5435     * reached.
5436     *
5437     * The updater methods are used to update column values in the current row
5438     * or the insert row. The updater methods do not update the underlying
5439     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5440     * methods are called to update the database.
5441     *
5442     * @param columnIndex the first column is 1, the second is 2, ...
5443     * @param x the new column value
5444     * @throws SQLException if the columnIndex is not valid; if a database
5445     * access error occurs; the result set concurrency is
5446     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5447     * result set
5448     */

5449    public void updateAsciiStream(int columnIndex, InputStream JavaDoc x)
5450            throws SQLException JavaDoc {
5451        synchronized (connection_) {
5452            if (agent_.loggingEnabled()) {
5453                agent_.logWriter_.traceEntry(this, "updateAsciiStream",
5454                        columnIndex, x);
5455            }
5456            try {
5457                checkUpdatePreconditions(columnIndex, "updateAsciiStream");
5458                updateColumn(columnIndex,
5459                        agent_.crossConverters_.setObjectFromCharacterStream(
5460                            resultSetMetaData_.types_[columnIndex -1],
5461                            x,
5462                            "US-ASCII",
5463                            CrossConverters.UNKNOWN_LENGTH));
5464            } catch (SqlException se) {
5465                throw se.getSQLException();
5466            }
5467        }
5468    }
5469
5470    /**
5471     * Update a column with an ascii stream value.
5472     *
5473     * The updateXXX() methods are used to update column values in the current
5474     * row, or the insert row. The updateXXX() methods do not update the
5475     * underlying database, instead the updateRow() or insertRow() methods are
5476     * called to update the database.
5477     *
5478     * @param columnIndex
5479     * the first column is 1, the second is 2, ...
5480     * @param x
5481     * the new column value
5482     * @param length
5483     * the length of the stream
5484     * @exception SQLException
5485     * if a database-access error occurs
5486     */

5487    public void updateAsciiStream(int columnIndex, InputStream JavaDoc x,
5488                    long length) throws SQLException JavaDoc {
5489        if(length > Integer.MAX_VALUE)
5490                throw new SqlException(agent_.logWriter_,
5491                    new ClientMessageId(SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5492                    new Long JavaDoc(length), new Integer JavaDoc(Integer.MAX_VALUE)).getSQLException();
5493        else
5494            updateAsciiStream(columnIndex,x,(int)length);
5495    }
5496
5497    /**
5498     * Updates the designated column with a binary stream value.
5499     * The data will be read from the stream as needed until end-of-stream is
5500     * reached.
5501     *
5502     * The updater methods are used to update column values in the current row
5503     * or the insert row. The updater methods do not update the underlying
5504     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5505     * methods are called to update the database.
5506     *
5507     * @param columnIndex the first column is 1, the second is 2, ...
5508     * @param x the new column value
5509     * @throws SQLException if the columnIndex is not valid; if a database
5510     * access error occurs; the result set concurrency is
5511     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5512     * result set
5513     */

5514    public void updateBinaryStream(int columnIndex, InputStream JavaDoc x)
5515            throws SQLException JavaDoc {
5516        synchronized (connection_) {
5517            if (agent_.loggingEnabled()) {
5518                agent_.logWriter_.traceEntry(this, "updateBinaryStream",
5519                        columnIndex, x);
5520            }
5521            try {
5522                checkUpdatePreconditions(columnIndex, "updateBinaryStream");
5523                updateColumn(columnIndex,
5524                             agent_.crossConverters_.setObjectFromBinaryStream(
5525                                    resultSetMetaData_.types_[columnIndex -1],
5526                                    x,
5527                                    CrossConverters.UNKNOWN_LENGTH));
5528            } catch (SqlException se) {
5529                throw se.getSQLException();
5530            }
5531        }
5532    }
5533
5534    /**
5535     * Update a column with a binary stream value.
5536     *
5537     * The updateXXX() methods are used to update column values in the current
5538     * row, or the insert row. The updateXXX() methods do not update the
5539     * underlying database, instead the updateRow() or insertRow() methods are
5540     * called to update the database.
5541     *
5542     * @param columnIndex
5543     * the first column is 1, the second is 2, ...
5544     * @param x
5545     * the new column value
5546     * @param length
5547     * the length of the stream
5548     * @exception SQLException
5549     * if a database-access error occurs
5550     */

5551    public void updateBinaryStream(int columnIndex, InputStream JavaDoc x,
5552        long length) throws SQLException JavaDoc {
5553         if(length > Integer.MAX_VALUE)
5554                throw new SqlException(agent_.logWriter_,
5555                    new ClientMessageId(SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5556                    new Long JavaDoc(length), new Integer JavaDoc(Integer.MAX_VALUE)).getSQLException();
5557        else
5558            updateBinaryStream(columnIndex,x,(int)length);
5559
5560     }
5561
5562    /**
5563     * Updates the designated column using the given input stream.
5564     * The data will be read from the stream as needed until end-of-stream is
5565     * reached.
5566     *
5567     * The updater methods are used to update column values in the current row
5568     * or the insert row. The updater methods do not update the underlying
5569     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5570     * methods are called to update the database.
5571     *
5572     * @param columnIndex the first column is 1, the second is 2, ...
5573     * @param x the new column value
5574     * @throws SQLException if the columnIndex is not valid; if a database
5575     * access error occurs; the result set concurrency is
5576     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5577     * result set
5578     */

5579    public void updateBlob(int columnIndex, InputStream JavaDoc x)
5580            throws SQLException JavaDoc {
5581        synchronized (connection_) {
5582            if (agent_.loggingEnabled()) {
5583                agent_.logWriter_.traceEntry(this, "updateBlob",
5584                        columnIndex, x);
5585            }
5586            try {
5587                checkUpdatePreconditions(columnIndex, "updateBlob");
5588                updateColumn(columnIndex,
5589                             agent_.crossConverters_.setObject(
5590                                    resultSetMetaData_.types_[columnIndex -1],
5591                                    new Blob(agent_, x)));
5592            } catch (SqlException se) {
5593                throw se.getSQLException();
5594            }
5595        }
5596    }
5597
5598    /**
5599     * Updates the designated column with a character stream value.
5600     * The data will be read from the stream as needed until end-of-stream is
5601     * reached.
5602     *
5603     * The updater methods are used to update column values in the current row
5604     * or the insert row. The updater methods do not update the underlying
5605     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5606     * methods are called to update the database.
5607     *
5608     * @param columnIndex the first column is 1, the second is 2, ...
5609     * @param reader the new column value
5610     * @throws SQLException if the columnLabel is not valid; if a database
5611     * access error occurs; the result set concurrency is
5612     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5613     * result set
5614     */

5615    public void updateCharacterStream(int columnIndex, Reader JavaDoc reader)
5616            throws SQLException JavaDoc {
5617        synchronized (connection_) {
5618            try {
5619                if (agent_.loggingEnabled()) {
5620                    agent_.logWriter_.traceEntry(this, "updateCharacterStream",
5621                            columnIndex, reader);
5622                }
5623                checkUpdatePreconditions(columnIndex, "updateCharacterStream");
5624                updateColumn(columnIndex,
5625                             agent_.crossConverters_.setObject(
5626                                    resultSetMetaData_.types_[columnIndex -1],
5627                                    reader,
5628                                    CrossConverters.UNKNOWN_LENGTH));
5629            } catch (SqlException se) {
5630                throw se.getSQLException();
5631            }
5632        }
5633    }
5634
5635    /**
5636     * Update a column with a character stream value.
5637     *
5638     * The updateXXX() methods are used to update column values in the current
5639     * row, or the insert row. The updateXXX() methods do not update the
5640     * underlying database, instead the updateRow() or insertRow() methods are
5641     * called to update the database.
5642     *
5643     * @param columnIndex
5644     * the first column is 1, the second is 2, ...
5645     * @param x
5646     * the new column value
5647     * @param length
5648     * the length of the stream
5649     * @exception SQLException
5650     * if a database-access error occurs
5651     */

5652    public void updateCharacterStream(int columnIndex, Reader JavaDoc x,
5653                    long length) throws SQLException JavaDoc {
5654        if(length > Integer.MAX_VALUE)
5655                throw new SqlException(agent_.logWriter_,
5656                    new ClientMessageId(SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5657                    new Long JavaDoc(length), new Integer JavaDoc(Integer.MAX_VALUE)).getSQLException();
5658        else
5659            updateCharacterStream(columnIndex,x,(int)length);
5660    }
5661
5662    /**
5663     * Updates the designated column using the given <code>Reader</code>
5664     * object.
5665     * The data will be read from the stream as needed until end-of-stream is
5666     * reached. The JDBC driver will do any necessary conversion from UNICODE
5667     * to the database char format.
5668     *
5669     * The updater methods are used to update column values in the current row
5670     * or the insert row. The updater methods do not update the underlying
5671     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5672     * methods are called to update the database.
5673     *
5674     * @param columnIndex the first column is 1, the second is 2, ...
5675     * @param reader an object that contains the data to set the parameter
5676     * value to.
5677     * @throws SQLException if the columnIndex is not valid; if a database
5678     * access error occurs; the result set concurrency is
5679     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5680     * result set
5681     */

5682    public void updateClob(int columnIndex, Reader JavaDoc reader)
5683            throws SQLException JavaDoc {
5684        synchronized (connection_) {
5685            if (agent_.loggingEnabled()) {
5686                agent_.logWriter_.traceEntry(this, "updateClob",
5687                        columnIndex, reader);
5688            }
5689            try {
5690                checkUpdatePreconditions(columnIndex, "updateClob");
5691                updateColumn(columnIndex,
5692                             agent_.crossConverters_.setObject(
5693                                 resultSetMetaData_.types_[columnIndex -1],
5694                                 new Clob(agent_, reader)));
5695            } catch (SqlException se) {
5696                throw se.getSQLException();
5697            }
5698        }
5699    }
5700
5701    /**
5702     * Updates the designated column with an ascii stream value.
5703     * The data will be read from the stream as needed until end-of-stream is
5704     * reached.
5705     *
5706     * The updater methods are used to update column values in the current row
5707     * or the insert row. The updater methods do not update the underlying
5708     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5709     * methods are called to update the database.
5710     *
5711     * @param columnName the label for the column specified with the SQL AS
5712     * clause. If the SQL AS clause was not specified, then the label is
5713     * the name of the column
5714     * @param x the new column value
5715     * @throws SQLException if the columnLabel is not valid; if a database
5716     * access error occurs; the result set concurrency is
5717     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5718     * result set
5719     */

5720    public void updateAsciiStream(String JavaDoc columnName, InputStream JavaDoc x)
5721            throws SQLException JavaDoc {
5722        try {
5723            updateAsciiStream(findColumnX(columnName), x);
5724        } catch (SqlException se) {
5725            throw se.getSQLException();
5726        }
5727    }
5728
5729    /**
5730     * Update a column with an ascii stream value.
5731     *
5732     * The updateXXX() methods are used to update column values in the current
5733     * row, or the insert row. The updateXXX() methods do not update the
5734     * underlying database, instead the updateRow() or insertRow() methods are
5735     * called to update the database.
5736     *
5737     * @param columnName
5738     * the name of the column
5739     * @param x
5740     * the new column value
5741     * @param length
5742     * of the stream
5743     * @exception SQLException
5744     * if a database-access error occurs
5745     */

5746    public void updateAsciiStream(String JavaDoc columnName, InputStream JavaDoc x,
5747                    long length) throws SQLException JavaDoc {
5748        try {
5749            updateAsciiStream(findColumnX(columnName), x, length);
5750        }
5751        catch(SqlException sqle) {
5752            throw sqle.getSQLException();
5753        }
5754    }
5755
5756    /**
5757     * Updates the designated column with a binary stream value.
5758     * The data will be read from the stream as needed until end-of-stream is
5759     * reached.
5760     *
5761     * The updater methods are used to update column values in the current row
5762     * or the insert row. The updater methods do not update the underlying
5763     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5764     * methods are called to update the database.
5765     *
5766     * @param columnLabel the label for the column specified with the SQL AS
5767     * clause. If the SQL AS clause was not specified, then the label is
5768     * the name of the column
5769     * @param x the new column value
5770     * @throws SQLException if the columnLabel is not valid; if a database
5771     * access error occurs; the result set concurrency is
5772     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5773     * result set
5774     */

5775    public void updateBinaryStream(String JavaDoc columnLabel, InputStream JavaDoc x)
5776            throws SQLException JavaDoc {
5777        try {
5778            updateBinaryStream(findColumnX(columnLabel), x);
5779        } catch (SqlException se) {
5780            throw se.getSQLException();
5781        }
5782    }
5783
5784    /**
5785     * Update a column with a binary stream value.
5786     *
5787     * The updateXXX() methods are used to update column values in the current
5788     * row, or the insert row. The updateXXX() methods do not update the
5789     * underlying database, instead the updateRow() or insertRow() methods are
5790     * called to update the database.
5791     *
5792     * @param columnName
5793     * the name of the column
5794     * @param x
5795     * the new column value
5796     * @param length
5797     * of the stream
5798     * @exception SQLException
5799     * if a database-access error occurs
5800     */

5801    public void updateBinaryStream(String JavaDoc columnName, InputStream JavaDoc x,
5802                    long length) throws SQLException JavaDoc {
5803        try {
5804            updateBinaryStream(findColumnX(columnName), x, length);
5805        }
5806        catch(SqlException sqle) {
5807            throw sqle.getSQLException();
5808        }
5809    }
5810
5811    /**
5812     * Updates the designated column using the given input stream.
5813     * The data will be read from the stream as needed until end-of-stream is
5814     * reached.
5815     *
5816     * The updater methods are used to update column values in the current row
5817     * or the insert row. The updater methods do not update the underlying
5818     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5819     * methods are called to update the database.
5820     *
5821     * @param columnLabel the label for the column specified with the SQL AS
5822     * clause. If the SQL AS clause was not specified, then the label is
5823     * the name of the column
5824     * @param x the new column value
5825     * @throws SQLException if the columnLabel is not valid; if a database
5826     * access error occurs; the result set concurrency is
5827     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5828     * result set
5829     */

5830    public void updateBlob(String JavaDoc columnLabel, InputStream JavaDoc x)
5831            throws SQLException JavaDoc {
5832        try {
5833            updateBlob(findColumnX(columnLabel), x);
5834        } catch (SqlException se) {
5835            throw se.getSQLException();
5836        }
5837    }
5838
5839    /**
5840     * Updates the designated column with a character stream value.
5841     * The data will be read from the stream as needed until end-of-stream is
5842     * reached.
5843     *
5844     * The updater methods are used to update column values in the current row
5845     * or the insert row. The updater methods do not update the underlying
5846     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5847     * methods are called to update the database.
5848     *
5849     * @param columnLabel the label for the column specified with the SQL AS
5850     * clause. If the SQL AS clause was not specified, then the label is
5851     * the name of the column
5852     * @param reader the new column value
5853     * @throws SQLException if the columnLabel is not valid; if a database
5854     * access error occurs; the result set concurrency is
5855     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5856     * result set
5857     */

5858    public void updateCharacterStream(String JavaDoc columnLabel, Reader JavaDoc reader)
5859            throws SQLException JavaDoc {
5860        try {
5861            updateCharacterStream(findColumnX(columnLabel), reader);
5862        } catch (SqlException se) {
5863            throw se.getSQLException();
5864        }
5865    }
5866
5867    /**
5868     * Update a column with a character stream value.
5869     *
5870     * The updateXXX() methods are used to update column values in the current
5871     * row, or the insert row. The updateXXX() methods do not update the
5872     * underlying database, instead the updateRow() or insertRow() methods are
5873     * called to update the database.
5874     *
5875     * @param columnName
5876     * the name of the column
5877     * @param reader
5878     * the new column value
5879     * @param length
5880     * length of the stream
5881     * @exception SQLException
5882     * if a database-access error occurs
5883     */

5884    public void updateCharacterStream(String JavaDoc columnName, Reader JavaDoc reader,
5885        long length) throws SQLException JavaDoc {
5886         try {
5887             updateCharacterStream(findColumnX(columnName), reader, length);
5888         }
5889         catch(SqlException sqle) {
5890             throw sqle.getSQLException();
5891         }
5892     }
5893
5894    /**
5895     * Updates the designated column using the given <code>Reader</code>
5896     * object.
5897     * The data will be read from the stream as needed until end-of-stream is
5898     * reached. The JDBC driver will do any necessary conversion from UNICODE
5899     * to the database char format.
5900     *
5901     * The updater methods are used to update column values in the current row
5902     * or the insert row. The updater methods do not update the underlying
5903     * database; instead the <code>updateRow</code> or <code>insertRow</code>
5904     * methods are called to update the database.
5905     *
5906     * @param columnLabel the label for the column specified with the SQL AS
5907     * clause. If the SQL AS clause was not specified, then the label is
5908     * the name of the column
5909     * @param reader an object that contains the data to set the parameter
5910     * value to.
5911     * @throws SQLException if the columnIndex is not valid; if a database
5912     * access error occurs; the result set concurrency is
5913     * <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5914     * result set
5915     */

5916    public void updateClob(String JavaDoc columnLabel, Reader JavaDoc reader)
5917            throws SQLException JavaDoc {
5918        try {
5919            updateClob(findColumnX(columnLabel), reader);
5920        } catch (SqlException se) {
5921            throw se.getSQLException();
5922        }
5923    }
5924}
5925
Popular Tags