0001: /*
0002:
0003: Derby - Class org.apache.derby.client.am.Cursor
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.client.am;
0023:
0024: import org.apache.derby.shared.common.reference.SQLState;
0025:
0026: import java.sql.SQLException;
0027: import java.io.UnsupportedEncodingException;
0028:
0029: // When we calculate column offsets make sure we calculate the correct offsets for double byte charactr5er data
0030: // length from server is number of chars, not bytes
0031: // Direct byte-level converters are called directly by this class, cross converters are deferred to the CrossConverters class.
0032:
0033: public abstract class Cursor {
0034: protected Agent agent_;
0035:
0036: //-----------------------------varchar representations------------------------
0037:
0038: public final static int STRING = 0;
0039: public final static int VARIABLE_STRING = 2; // uses a 2-byte length indicator
0040: public final static int VARIABLE_SHORT_STRING = 1; // aka Pascal L; uses a 1-byte length indicator
0041: public final static int NULL_TERMINATED_STRING = 3;
0042:
0043: public final static int BYTES = 4;
0044: public final static int VARIABLE_BYTES = 5;
0045: public final static int VARIABLE_SHORT_BYTES = 6;
0046: public final static int NULL_TERMINATED_BYTES = 7;
0047:
0048: public final static int SBCS_CLOB = 8;
0049: public final static int MBCS_CLOB = 9;
0050: public final static int DBCS_CLOB = 10;
0051: //-----------------------------internal state---------------------------------
0052:
0053: //-------------Structures for holding and scrolling the data -----------------
0054: public byte[] dataBuffer_;
0055: public java.io.ByteArrayOutputStream dataBufferStream_;
0056: public int position_; // This is the read head
0057: public int lastValidBytePosition_;
0058: public boolean hasLobs_; // is there at least one LOB column?
0059:
0060: // Current row positioning
0061: protected int currentRowPosition_;
0062: private int nextRowPosition_;
0063: // Let's new up a 2-dimensional array based on fetch-size and reuse so that
0064: protected int[] columnDataPosition_;
0065:
0066: // This is the actual, computed lengths of varchar fields, not the max length from query descriptor or DA
0067: protected int[] columnDataComputedLength_;
0068: // populate this for
0069:
0070: // All the data is in the buffers, but user may not have necessarily stepped to the last row yet.
0071: // This flag indicates that the server has returned all the rows, and is positioned
0072: // after last, for both scrollable and forward-only cursors.
0073: // For singleton cursors, this memeber will be set to true as soon as next is called.
0074: private boolean allRowsReceivedFromServer_;
0075:
0076: // Total number of rows read so far.
0077: // This should never exceed this.statement.maxRows
0078: int rowsRead_;
0079:
0080: // Maximum column size limit in bytes.
0081: int maxFieldSize_ = 0;
0082:
0083: // Row positioning for all cached rows
0084: // For scrollable result sets, these lists hold the offsets into the cached rowset buffer for each row of data.
0085: protected java.util.ArrayList columnDataPositionCache_ = new java.util.ArrayList();
0086: protected java.util.ArrayList columnDataLengthCache_ = new java.util.ArrayList();
0087: protected java.util.ArrayList columnDataIsNullCache_ = new java.util.ArrayList();
0088: public java.util.ArrayList isUpdateDeleteHoleCache_ = new java.util.ArrayList();
0089: public boolean isUpdateDeleteHole_;
0090:
0091: // State to keep track of when a row has been updated,
0092: // cf. corresponding set and get accessors. Only implemented for
0093: // scrollable updatable insensitive result sets for now.
0094: private boolean isRowUpdated_;
0095:
0096: final static public java.lang.Boolean ROW_IS_NULL = new Boolean(
0097: true);
0098: final static public java.lang.Boolean ROW_IS_NOT_NULL = new Boolean(
0099: false);
0100:
0101: java.sql.Date recyclableDate_ = null;
0102: java.sql.Time recyclableTime_ = null;
0103: java.sql.Timestamp recyclableTimestamp_ = null;
0104:
0105: // For the net, this data comes from the query descriptor.
0106:
0107: public int[] jdbcTypes_;
0108: public int columns_;
0109: public boolean[] nullable_;
0110: public String[] charsetName_;
0111: public boolean[] isNull_;
0112: public int[] fdocaLength_; // this is the max length for
0113:
0114: //----------------------------------------------------------------------------
0115:
0116: public int[] ccsid_;
0117: char[] charBuffer_;
0118:
0119: //---------------------constructors/finalizer---------------------------------
0120:
0121: public Cursor(Agent agent) {
0122: agent_ = agent;
0123: isRowUpdated_ = false;
0124: dataBufferStream_ = new java.io.ByteArrayOutputStream();
0125: }
0126:
0127: public Cursor(Agent agent, byte[] dataBuffer) {
0128: this (agent);
0129: dataBuffer_ = dataBuffer;
0130: setAllRowsReceivedFromServer(false);
0131: }
0132:
0133: public void setNumberOfColumns(int numberOfColumns) {
0134: columnDataPosition_ = new int[numberOfColumns];
0135: columnDataComputedLength_ = new int[numberOfColumns];
0136:
0137: columns_ = numberOfColumns;
0138: nullable_ = new boolean[numberOfColumns];
0139: charsetName_ = new String[numberOfColumns];
0140:
0141: ccsid_ = new int[numberOfColumns];
0142:
0143: isNull_ = new boolean[numberOfColumns];
0144: jdbcTypes_ = new int[numberOfColumns];
0145: }
0146:
0147: /**
0148: * Makes the next row the current row. Returns true if the current
0149: * row position is a valid row position.
0150: *
0151: * @param allowServerFetch if false, don't fetch more data from
0152: * the server even if more data is needed
0153: * @return <code>true</code> if current row position is valid
0154: * @exception SqlException if an error occurs
0155: */
0156: protected boolean stepNext(boolean allowServerFetch)
0157: throws SqlException {
0158: // local variable usd to hold the returned value from calculateColumnOffsetsForRow()
0159: boolean rowPositionIsValid = true;
0160:
0161: // reset lob data
0162: // clears out Cursor.lobs_ calculated for the current row when cursor is moved.
0163: clearLobData_();
0164:
0165: // mark the start of a new row.
0166: makeNextRowPositionCurrent();
0167:
0168: // Moving out of the hole, set isUpdateDeleteHole to false
0169: isUpdateDeleteHole_ = false;
0170:
0171: isRowUpdated_ = false;
0172:
0173: // Drive the CNTQRY outside of calculateColumnOffsetsForRow() if the dataBuffer_
0174: // contains no data since it has no abilities to handle replies other than
0175: // the QRYDTA, i.e. ENDQRYRM when the result set contains no more rows.
0176: while (!dataBufferHasUnprocessedData()) {
0177: if (allRowsReceivedFromServer_) {
0178: return false;
0179: }
0180: getMoreData_();
0181: }
0182:
0183: // The parameter passed in here is used as an index into the cached rowset for
0184: // scrollable cursors, for the arrays to be reused. It is not used for forward-only
0185: // cursors, so just pass in 0.
0186: rowPositionIsValid = calculateColumnOffsetsForRow_(0,
0187: allowServerFetch);
0188: markNextRowPosition();
0189: return rowPositionIsValid;
0190: }
0191:
0192: /**
0193: * Makes the next row the current row. Returns true if the current
0194: * row position is a valid row position.
0195: *
0196: * @return <code>true</code> if current row position is valid
0197: * @exception SqlException if an error occurs
0198: */
0199: public boolean next() throws SqlException {
0200: return stepNext(true);
0201: }
0202:
0203: //--------------------------reseting cursor state-----------------------------
0204:
0205: /**
0206: * Set the value of value of allRowsReceivedFromServer_.
0207: *
0208: * @param b a <code>boolean</code> value indicating whether all
0209: * rows are received from the server
0210: */
0211: public void setAllRowsReceivedFromServer(boolean b) {
0212: allRowsReceivedFromServer_ = b;
0213: }
0214:
0215: /**
0216: * Return <code>true</code> if all rows are received from the
0217: * server.
0218: *
0219: * @return <code>true</code> if all rows are received from the
0220: * server.
0221: */
0222: public final boolean allRowsReceivedFromServer() {
0223: return allRowsReceivedFromServer_;
0224: }
0225:
0226: public final boolean currentRowPositionIsEqualToNextRowPosition() {
0227: return (currentRowPosition_ == nextRowPosition_);
0228: }
0229:
0230: // reset the beginning and ending position in the data buffer to 0
0231: // reset the currentRowPosition and nextRowPosition to 0
0232: // reset lastRowReached and sqlcode100Received to false
0233: // clear the column data offsets cache
0234: public final void resetDataBuffer() {
0235: position_ = 0;
0236: lastValidBytePosition_ = 0;
0237: currentRowPosition_ = 0;
0238: nextRowPosition_ = 0;
0239: setAllRowsReceivedFromServer(false);
0240: dataBufferStream_.reset();
0241: }
0242:
0243: public final boolean dataBufferHasUnprocessedData() {
0244: return (lastValidBytePosition_ - position_) > 0;
0245: }
0246:
0247: /**
0248: * Calculate the column offsets for a row.
0249: *
0250: * @param row row index
0251: * @param allowServerFetch if true, allow fetching more data from
0252: * server
0253: * @return <code>true</code> if the current row position is a
0254: * valid row position.
0255: * @exception SqlException
0256: * @exception DisconnectException
0257: */
0258: protected abstract boolean calculateColumnOffsetsForRow_(int row,
0259: boolean allowServerFetch) throws SqlException,
0260: DisconnectException;
0261:
0262: protected abstract void clearLobData_();
0263:
0264: protected abstract void getMoreData_() throws SqlException;
0265:
0266: // Associate a new underlying COM or SQLDA output data buffer for this converter.
0267: public final void setBuffer(byte[] dataBuffer) {
0268: dataBuffer_ = dataBuffer;
0269: }
0270:
0271: public final void setIsUpdataDeleteHole(int row, boolean isRowNull) {
0272: isUpdateDeleteHole_ = isRowNull;
0273: Boolean nullIndicator = (isUpdateDeleteHole_ == true) ? ROW_IS_NULL
0274: : ROW_IS_NOT_NULL;
0275: if (isUpdateDeleteHoleCache_.size() == row) {
0276: isUpdateDeleteHoleCache_.add(nullIndicator);
0277: } else {
0278: isUpdateDeleteHoleCache_.set(row, nullIndicator);
0279: }
0280: }
0281:
0282: /**
0283: * Keep track of updated status for this row.
0284: *
0285: * @param isRowUpdated true if row has been updated
0286: *
0287: * @see Cursor#getIsRowUpdated
0288: */
0289: public final void setIsRowUpdated(boolean isRowUpdated) {
0290: isRowUpdated_ = isRowUpdated;
0291: }
0292:
0293: /**
0294: * Get updated status for this row.
0295: * Minion of ResultSet#rowUpdated.
0296: *
0297: * @see Cursor#setIsRowUpdated
0298: */
0299: public final boolean getIsRowUpdated() {
0300: return isRowUpdated_;
0301: }
0302:
0303: /**
0304: * Get deleted status for this row.
0305: * Minion of ResultSet#rowDeleted.
0306: *
0307: * @see Cursor#setIsUpdataDeleteHole
0308: */
0309: public final boolean getIsUpdateDeleteHole() {
0310: return isUpdateDeleteHole_;
0311: }
0312:
0313: //---------------------------cursor positioning-------------------------------
0314:
0315: final int getPosition() {
0316: return position_;
0317: }
0318:
0319: final void setPosition(int newPosition) {
0320: position_ = newPosition;
0321: }
0322:
0323: public final void markCurrentRowPosition() {
0324: currentRowPosition_ = position_;
0325: }
0326:
0327: public final void markNextRowPosition() {
0328: nextRowPosition_ = position_;
0329: }
0330:
0331: public final void makeNextRowPositionCurrent() {
0332: currentRowPosition_ = nextRowPosition_;
0333: }
0334:
0335: final void repositionCursorToCurrentRow() {
0336: position_ = currentRowPosition_;
0337: }
0338:
0339: final void repositionCursorToNextRow() {
0340: position_ = nextRowPosition_;
0341: }
0342:
0343: public final byte[] getDataBuffer() {
0344: return dataBuffer_;
0345: }
0346:
0347: public final int getDataBufferLength() {
0348: return dataBuffer_.length;
0349: }
0350:
0351: public final int getLastValidBytePosition() {
0352: return lastValidBytePosition_;
0353: }
0354:
0355: // This tracks the total number of rows read into the client side buffer for
0356: // this result set, irregardless of scrolling.
0357: // Per jdbc semantics, this should never exceed statement.maxRows.
0358: // This event should be generated in the materialized cursor's implementation
0359: // of calculateColumnOffsetsForRow().
0360: public final void incrementRowsReadEvent() {
0361: rowsRead_++;
0362: }
0363:
0364: //------- the following getters are called on known column types -------------
0365: // Direct conversions only, cross conversions are handled by another set of getters.
0366:
0367: // Build a Java short from a 2-byte signed binary representation.
0368: private final short get_SMALLINT(int column) {
0369: return org.apache.derby.client.am.SignedBinary.getShort(
0370: dataBuffer_, columnDataPosition_[column - 1]);
0371: }
0372:
0373: // Build a Java int from a 4-byte signed binary representation.
0374: private final int get_INTEGER(int column) {
0375: return org.apache.derby.client.am.SignedBinary.getInt(
0376: dataBuffer_, columnDataPosition_[column - 1]);
0377: }
0378:
0379: // Build a Java long from an 8-byte signed binary representation.
0380: private final long get_BIGINT(int column) {
0381: return org.apache.derby.client.am.SignedBinary.getLong(
0382: dataBuffer_, columnDataPosition_[column - 1]);
0383: }
0384:
0385: // Build a Java float from a 4-byte floating point representation.
0386: private final float get_FLOAT(int column) {
0387: return org.apache.derby.client.am.FloatingPoint.getFloat(
0388: dataBuffer_, columnDataPosition_[column - 1]);
0389: }
0390:
0391: // Build a Java double from an 8-byte floating point representation.
0392: private final double get_DOUBLE(int column) {
0393: return org.apache.derby.client.am.FloatingPoint.getDouble(
0394: dataBuffer_, columnDataPosition_[column - 1]);
0395: }
0396:
0397: // Build a java.math.BigDecimal from a fixed point decimal byte representation.
0398: private final java.math.BigDecimal get_DECIMAL(int column)
0399: throws SqlException {
0400: try {
0401: return org.apache.derby.client.am.Decimal.getBigDecimal(
0402: dataBuffer_, columnDataPosition_[column - 1],
0403: getColumnPrecision(column - 1),
0404: getColumnScale(column - 1));
0405: } catch (java.io.UnsupportedEncodingException e) {
0406: throw new SqlException(agent_.logWriter_,
0407: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0408: "DECIMAL", "java.math.BigDecimal", e);
0409: }
0410: }
0411:
0412: // Build a Java double from a fixed point decimal byte representation.
0413: private final double getDoubleFromDECIMAL(int column)
0414: throws SqlException {
0415: try {
0416: return org.apache.derby.client.am.Decimal.getDouble(
0417: dataBuffer_, columnDataPosition_[column - 1],
0418: getColumnPrecision(column - 1),
0419: getColumnScale(column - 1));
0420: } catch (java.lang.IllegalArgumentException e) {
0421: throw new SqlException(agent_.logWriter_,
0422: new ClientMessageId(
0423: SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE),
0424: "double", e);
0425: } catch (java.io.UnsupportedEncodingException e) {
0426: throw new SqlException(agent_.logWriter_,
0427: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0428: "DECIMAL", "double", e);
0429: }
0430: }
0431:
0432: // Build a Java long from a fixed point decimal byte representation.
0433: private final long getLongFromDECIMAL(int column)
0434: throws SqlException {
0435: try {
0436: return org.apache.derby.client.am.Decimal.getLong(
0437: dataBuffer_, columnDataPosition_[column - 1],
0438: getColumnPrecision(column - 1),
0439: getColumnScale(column - 1));
0440: } catch (java.lang.IllegalArgumentException e) {
0441: throw new SqlException(agent_.logWriter_,
0442: new ClientMessageId(
0443: SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE),
0444: "long", e);
0445: } catch (java.io.UnsupportedEncodingException e) {
0446: throw new SqlException(agent_.logWriter_,
0447: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0448: "DECIMAL", "long", e);
0449: }
0450: }
0451:
0452: // Build a Java String from a database VARCHAR or LONGVARCHAR field.
0453: //
0454: // Depending on the ccsid, length is the number of chars or number of bytes.
0455: // For 2-byte character ccsids, length is the number of characters,
0456: // for all other cases length is the number of bytes.
0457: // The length does not include the null terminator.
0458: private final String getVARCHAR(int column) throws SqlException {
0459: String tempString = null;
0460: try {
0461: if (ccsid_[column - 1] == 1200) {
0462: return getStringWithoutConvert(
0463: columnDataPosition_[column - 1] + 2,
0464: columnDataComputedLength_[column - 1] - 2);
0465: }
0466:
0467: // check for null encoding is needed because the net layer
0468: // will no longer throw an exception if the server didn't specify
0469: // a mixed or double byte ccsid (ccsid = 0). this check for null in the
0470: // cursor is only required for types which can have mixed or double
0471: // byte ccsids.
0472: if (charsetName_[column - 1] == null) {
0473: throw new SqlException(
0474: agent_.logWriter_,
0475: new ClientMessageId(
0476: SQLState.CHARACTER_CONVERTER_NOT_AVAILABLE));
0477: }
0478:
0479: tempString = new String(dataBuffer_,
0480: columnDataPosition_[column - 1] + 2,
0481: columnDataComputedLength_[column - 1] - 2,
0482: charsetName_[column - 1]);
0483: return (maxFieldSize_ == 0) ? tempString : tempString
0484: .substring(0, java.lang.Math.min(maxFieldSize_,
0485: tempString.length()));
0486: } catch (java.io.UnsupportedEncodingException e) {
0487: throw new SqlException(agent_.logWriter_,
0488: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0489: "VARCHAR", "String", e);
0490: }
0491: }
0492:
0493: // Build a Java String from a database CHAR field.
0494: private final String getCHAR(int column) throws SqlException {
0495: String tempString = null;
0496: if (ccsid_[column - 1] == 1200) {
0497: return getStringWithoutConvert(
0498: columnDataPosition_[column - 1],
0499: columnDataComputedLength_[column - 1]);
0500: }
0501:
0502: try {
0503: // check for null encoding is needed because the net layer
0504: // will no longer throw an exception if the server didn't specify
0505: // a mixed or double byte ccsid (ccsid = 0). this check for null in the
0506: // cursor is only required for types which can have mixed or double
0507: // byte ccsids.
0508: if (charsetName_[column - 1] == null) {
0509: throw new SqlException(
0510: agent_.logWriter_,
0511: new ClientMessageId(
0512: SQLState.CHARACTER_CONVERTER_NOT_AVAILABLE));
0513: }
0514:
0515: tempString = new String(dataBuffer_,
0516: columnDataPosition_[column - 1],
0517: columnDataComputedLength_[column - 1],
0518: charsetName_[column - 1]);
0519: return (maxFieldSize_ == 0) ? tempString : tempString
0520: .substring(0, java.lang.Math.min(maxFieldSize_,
0521: tempString.length()));
0522: } catch (java.io.UnsupportedEncodingException e) {
0523: throw new SqlException(agent_.logWriter_,
0524: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0525: "CHAR", "String", e);
0526: }
0527: }
0528:
0529: // Build a JDBC Date object from the DERBY ISO DATE field.
0530: private final java.sql.Date getDATE(int column) throws SqlException {
0531: try {
0532: return org.apache.derby.client.am.DateTime.dateBytesToDate(
0533: dataBuffer_, columnDataPosition_[column - 1],
0534: recyclableDate_, charsetName_[column - 1]);
0535: } catch (UnsupportedEncodingException e) {
0536: throw new SqlException(agent_.logWriter_,
0537: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0538: "DATE", "java.sql.Date", e);
0539: }
0540:
0541: }
0542:
0543: // Build a JDBC Time object from the DERBY ISO TIME field.
0544: private final java.sql.Time getTIME(int column) throws SqlException {
0545: try {
0546: return org.apache.derby.client.am.DateTime.timeBytesToTime(
0547: dataBuffer_, columnDataPosition_[column - 1],
0548: recyclableTime_, charsetName_[column - 1]);
0549: } catch (UnsupportedEncodingException e) {
0550: throw new SqlException(agent_.logWriter_,
0551: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0552: "TIME", "java.sql.Time", e);
0553: }
0554: }
0555:
0556: // Build a JDBC Timestamp object from the DERBY ISO TIMESTAMP field.
0557: private final java.sql.Timestamp getTIMESTAMP(int column)
0558: throws SqlException {
0559:
0560: try {
0561: return org.apache.derby.client.am.DateTime
0562: .timestampBytesToTimestamp(dataBuffer_,
0563: columnDataPosition_[column - 1],
0564: recyclableTimestamp_,
0565: charsetName_[column - 1]);
0566: } catch (java.io.UnsupportedEncodingException e) {
0567: throw new SqlException(agent_.logWriter_,
0568: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0569: "TIMESTAMP", "java.sql.Timestamp", e);
0570: }
0571: }
0572:
0573: // Build a JDBC Timestamp object from the DERBY ISO DATE field.
0574: private final java.sql.Timestamp getTimestampFromDATE(int column)
0575: throws SqlException {
0576: try {
0577: return org.apache.derby.client.am.DateTime
0578: .dateBytesToTimestamp(dataBuffer_,
0579: columnDataPosition_[column - 1],
0580: recyclableTimestamp_,
0581: charsetName_[column - 1]);
0582: } catch (UnsupportedEncodingException e) {
0583: throw new SqlException(agent_.logWriter_,
0584: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0585: "DATE", "java.sql.Timestamp", e);
0586: }
0587: }
0588:
0589: // Build a JDBC Timestamp object from the DERBY ISO TIME field.
0590: private final java.sql.Timestamp getTimestampFromTIME(int column)
0591: throws SqlException {
0592: try {
0593: return org.apache.derby.client.am.DateTime
0594: .timeBytesToTimestamp(dataBuffer_,
0595: columnDataPosition_[column - 1],
0596: recyclableTimestamp_,
0597: charsetName_[column - 1]);
0598: } catch (UnsupportedEncodingException e) {
0599: throw new SqlException(agent_.logWriter_,
0600: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0601: "TIME", "java.sql.Timestamp", e);
0602: }
0603: }
0604:
0605: // Build a JDBC Date object from the DERBY ISO TIMESTAMP field.
0606: private final java.sql.Date getDateFromTIMESTAMP(int column)
0607: throws SqlException {
0608: try {
0609: return org.apache.derby.client.am.DateTime
0610: .timestampBytesToDate(dataBuffer_,
0611: columnDataPosition_[column - 1],
0612: recyclableDate_, charsetName_[column - 1]);
0613: } catch (UnsupportedEncodingException e) {
0614: throw new SqlException(agent_.logWriter_,
0615: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0616: "TIMESTAMP", "java.sql.Date", e);
0617: }
0618: }
0619:
0620: // Build a JDBC Time object from the DERBY ISO TIMESTAMP field.
0621: private final java.sql.Time getTimeFromTIMESTAMP(int column)
0622: throws SqlException {
0623: try {
0624: return org.apache.derby.client.am.DateTime
0625: .timestampBytesToTime(dataBuffer_,
0626: columnDataPosition_[column - 1],
0627: recyclableTime_, charsetName_[column - 1]);
0628: } catch (UnsupportedEncodingException e) {
0629: throw new SqlException(agent_.logWriter_,
0630: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0631: "TIMESTAMP", "java.sql.Time", e);
0632: }
0633: }
0634:
0635: private final String getStringFromDATE(int column)
0636: throws SqlException {
0637: return getDATE(column).toString();
0638: }
0639:
0640: // Build a string object from the DERBY byte TIME representation.
0641: private final String getStringFromTIME(int column)
0642: throws SqlException {
0643: return getTIME(column).toString();
0644: }
0645:
0646: // Build a string object from the DERBY byte TIMESTAMP representation.
0647: private final String getStringFromTIMESTAMP(int column)
0648: throws SqlException {
0649: return getTIMESTAMP(column).toString();
0650: }
0651:
0652: // Extract bytes from a database java.sql.Types.BINARY field.
0653: // This is the DERBY type CHAR(n) FOR BIT DATA.
0654: private final byte[] get_CHAR_FOR_BIT_DATA(int column)
0655: throws SqlException {
0656: // There is no limit to the size of a column if maxFieldSize is zero.
0657: // Otherwise, use the smaller of maxFieldSize and the actual column length.
0658: int columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column - 1]
0659: : java.lang.Math.min(maxFieldSize_,
0660: columnDataComputedLength_[column - 1]);
0661:
0662: byte[] bytes = new byte[columnLength];
0663: System.arraycopy(dataBuffer_, columnDataPosition_[column - 1],
0664: bytes, 0, columnLength);
0665: return bytes;
0666: }
0667:
0668: // Extract bytes from a database java.sql.Types.VARBINARY or LONGVARBINARY field.
0669: // This includes the DERBY types:
0670: // VARCHAR(n) FOR BIT DATA
0671: // LONG VARCHAR(n) FOR BIT DATA
0672: private final byte[] get_VARCHAR_FOR_BIT_DATA(int column)
0673: throws SqlException {
0674: byte[] bytes;
0675: int columnLength = 0;
0676: columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column - 1] - 2
0677: : java.lang.Math.min(maxFieldSize_,
0678: columnDataComputedLength_[column - 1] - 2);
0679: bytes = new byte[columnLength];
0680: System.arraycopy(dataBuffer_,
0681: columnDataPosition_[column - 1] + 2, bytes, 0,
0682: bytes.length);
0683: return bytes;
0684: }
0685:
0686: abstract public Blob getBlobColumn_(int column, Agent agent)
0687: throws SqlException;
0688:
0689: abstract public Clob getClobColumn_(int column, Agent agent)
0690: throws SqlException;
0691:
0692: // get the raw clob bytes, without translation. dataOffset must be int[1]
0693: abstract public byte[] getClobBytes_(int column, int[] dataOffset /*output*/)
0694: throws SqlException;
0695:
0696: //------- the following getters perform any necessary cross-conversion _------
0697:
0698: final boolean getBoolean(int column) throws SqlException {
0699: switch (jdbcTypes_[column - 1]) {
0700: case java.sql.Types.SMALLINT:
0701: return agent_.crossConverters_
0702: .getBooleanFromShort(get_SMALLINT(column));
0703: case java.sql.Types.INTEGER:
0704: return agent_.crossConverters_
0705: .getBooleanFromInt(get_INTEGER(column));
0706: case java.sql.Types.BIGINT:
0707: return agent_.crossConverters_
0708: .getBooleanFromLong(get_BIGINT(column));
0709: case java.sql.Types.REAL:
0710: return agent_.crossConverters_
0711: .getBooleanFromFloat(get_FLOAT(column));
0712: case java.sql.Types.DOUBLE:
0713: return agent_.crossConverters_
0714: .getBooleanFromDouble(get_DOUBLE(column));
0715: case java.sql.Types.DECIMAL:
0716: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0717: return agent_.crossConverters_
0718: .getBooleanFromLong(getLongFromDECIMAL(column));
0719: case java.sql.Types.CHAR:
0720: return agent_.crossConverters_
0721: .getBooleanFromString(getCHAR(column));
0722: case java.sql.Types.VARCHAR:
0723: case java.sql.Types.LONGVARCHAR:
0724: return agent_.crossConverters_
0725: .getBooleanFromString(getVARCHAR(column));
0726: default:
0727: throw new ColumnTypeConversionException(agent_.logWriter_,
0728: "java.sql.Types " + jdbcTypes_[column - 1],
0729: "boolean");
0730: }
0731: }
0732:
0733: final byte getByte(int column) throws SqlException {
0734: // This needs to be changed to use jdbcTypes[]
0735: switch (jdbcTypes_[column - 1]) {
0736: case java.sql.Types.SMALLINT:
0737: return agent_.crossConverters_
0738: .getByteFromShort(get_SMALLINT(column));
0739: case java.sql.Types.INTEGER:
0740: return agent_.crossConverters_
0741: .getByteFromInt(get_INTEGER(column));
0742: case java.sql.Types.BIGINT:
0743: return agent_.crossConverters_
0744: .getByteFromLong(get_BIGINT(column));
0745: case java.sql.Types.REAL:
0746: return agent_.crossConverters_
0747: .getByteFromFloat(get_FLOAT(column));
0748: case java.sql.Types.DOUBLE:
0749: return agent_.crossConverters_
0750: .getByteFromDouble(get_DOUBLE(column));
0751: case java.sql.Types.DECIMAL:
0752: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0753: return agent_.crossConverters_
0754: .getByteFromLong(getLongFromDECIMAL(column));
0755: case java.sql.Types.CHAR:
0756: return agent_.crossConverters_
0757: .getByteFromString(getCHAR(column));
0758: case java.sql.Types.VARCHAR:
0759: case java.sql.Types.LONGVARCHAR:
0760: return agent_.crossConverters_
0761: .getByteFromString(getVARCHAR(column));
0762: default:
0763: throw new ColumnTypeConversionException(agent_.logWriter_,
0764: "java.sql.Types " + jdbcTypes_[column - 1], "byte");
0765: }
0766: }
0767:
0768: final short getShort(int column) throws SqlException {
0769: switch (jdbcTypes_[column - 1]) {
0770: case java.sql.Types.SMALLINT:
0771: return get_SMALLINT(column);
0772: case java.sql.Types.INTEGER:
0773: return agent_.crossConverters_
0774: .getShortFromInt(get_INTEGER(column));
0775: case java.sql.Types.BIGINT:
0776: return agent_.crossConverters_
0777: .getShortFromLong(get_BIGINT(column));
0778: case java.sql.Types.REAL:
0779: return agent_.crossConverters_
0780: .getShortFromFloat(get_FLOAT(column));
0781: case java.sql.Types.DOUBLE:
0782: return agent_.crossConverters_
0783: .getShortFromDouble(get_DOUBLE(column));
0784: case java.sql.Types.DECIMAL:
0785: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0786: return agent_.crossConverters_
0787: .getShortFromLong(getLongFromDECIMAL(column));
0788: case java.sql.Types.CHAR:
0789: return agent_.crossConverters_
0790: .getShortFromString(getCHAR(column));
0791: case java.sql.Types.VARCHAR:
0792: case java.sql.Types.LONGVARCHAR:
0793: return agent_.crossConverters_
0794: .getShortFromString(getVARCHAR(column));
0795: default:
0796: throw new ColumnTypeConversionException(agent_.logWriter_,
0797: "java.sql.Types " + jdbcTypes_[column - 1], "short");
0798: }
0799: }
0800:
0801: final int getInt(int column) throws SqlException {
0802: switch (jdbcTypes_[column - 1]) {
0803: case java.sql.Types.SMALLINT:
0804: return (int) get_SMALLINT(column);
0805: case java.sql.Types.INTEGER:
0806: return get_INTEGER(column);
0807: case java.sql.Types.BIGINT:
0808: return agent_.crossConverters_
0809: .getIntFromLong(get_BIGINT(column));
0810: case java.sql.Types.REAL:
0811: return agent_.crossConverters_
0812: .getIntFromFloat(get_FLOAT(column));
0813: case java.sql.Types.DOUBLE:
0814: return agent_.crossConverters_
0815: .getIntFromDouble(get_DOUBLE(column));
0816: case java.sql.Types.DECIMAL:
0817: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0818: return agent_.crossConverters_
0819: .getIntFromLong(getLongFromDECIMAL(column));
0820: case java.sql.Types.CHAR:
0821: return agent_.crossConverters_
0822: .getIntFromString(getCHAR(column));
0823: case java.sql.Types.VARCHAR:
0824: case java.sql.Types.LONGVARCHAR:
0825: return agent_.crossConverters_
0826: .getIntFromString(getVARCHAR(column));
0827: default:
0828: throw new ColumnTypeConversionException(agent_.logWriter_,
0829: "java.sql.Types " + jdbcTypes_[column - 1], "int");
0830: }
0831: }
0832:
0833: final long getLong(int column) throws SqlException {
0834: switch (jdbcTypes_[column - 1]) {
0835: case java.sql.Types.SMALLINT:
0836: return (long) get_SMALLINT(column);
0837: case java.sql.Types.INTEGER:
0838: return (long) get_INTEGER(column);
0839: case java.sql.Types.BIGINT:
0840: return get_BIGINT(column);
0841: case java.sql.Types.REAL:
0842: return agent_.crossConverters_
0843: .getLongFromFloat(get_FLOAT(column));
0844: case java.sql.Types.DOUBLE:
0845: return agent_.crossConverters_
0846: .getLongFromDouble(get_DOUBLE(column));
0847: case java.sql.Types.DECIMAL:
0848: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0849: return getLongFromDECIMAL(column);
0850: case java.sql.Types.CHAR:
0851: return agent_.crossConverters_
0852: .getLongFromString(getCHAR(column));
0853: case java.sql.Types.VARCHAR:
0854: case java.sql.Types.LONGVARCHAR:
0855: return agent_.crossConverters_
0856: .getLongFromString(getVARCHAR(column));
0857: default:
0858: throw new ColumnTypeConversionException(agent_.logWriter_,
0859: "java.sql.Types " + jdbcTypes_[column - 1], "long");
0860: }
0861: }
0862:
0863: final float getFloat(int column) throws SqlException {
0864: switch (jdbcTypes_[column - 1]) {
0865: case java.sql.Types.REAL:
0866: return get_FLOAT(column);
0867: case java.sql.Types.DOUBLE:
0868: return agent_.crossConverters_
0869: .getFloatFromDouble(get_DOUBLE(column));
0870: case java.sql.Types.DECIMAL:
0871: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0872: return agent_.crossConverters_
0873: .getFloatFromDouble(getDoubleFromDECIMAL(column));
0874: case java.sql.Types.SMALLINT:
0875: return (float) get_SMALLINT(column);
0876: case java.sql.Types.INTEGER:
0877: return (float) get_INTEGER(column);
0878: case java.sql.Types.BIGINT:
0879: return (float) get_BIGINT(column);
0880: case java.sql.Types.CHAR:
0881: return agent_.crossConverters_
0882: .getFloatFromString(getCHAR(column));
0883: case java.sql.Types.VARCHAR:
0884: case java.sql.Types.LONGVARCHAR:
0885: return agent_.crossConverters_
0886: .getFloatFromString(getVARCHAR(column));
0887: default:
0888: throw new ColumnTypeConversionException(agent_.logWriter_,
0889: "java.sql.Types " + jdbcTypes_[column - 1], "float");
0890: }
0891: }
0892:
0893: final double getDouble(int column) throws SqlException {
0894: switch (jdbcTypes_[column - 1]) {
0895: case java.sql.Types.REAL:
0896: double d = (double) get_FLOAT(column);
0897: return d;
0898: //return (double) get_FLOAT (column);
0899: case java.sql.Types.DOUBLE:
0900: return get_DOUBLE(column);
0901: case java.sql.Types.DECIMAL:
0902: // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
0903: return getDoubleFromDECIMAL(column);
0904: case java.sql.Types.SMALLINT:
0905: return (double) get_SMALLINT(column);
0906: case java.sql.Types.INTEGER:
0907: return (double) get_INTEGER(column);
0908: case java.sql.Types.BIGINT:
0909: return (double) get_BIGINT(column);
0910: case java.sql.Types.CHAR:
0911: return agent_.crossConverters_
0912: .getDoubleFromString(getCHAR(column));
0913: case java.sql.Types.VARCHAR:
0914: case java.sql.Types.LONGVARCHAR:
0915: return agent_.crossConverters_
0916: .getDoubleFromString(getVARCHAR(column));
0917: default:
0918: throw new ColumnTypeConversionException(agent_.logWriter_,
0919: "java.sql.Types " + jdbcTypes_[column - 1],
0920: "double");
0921: }
0922: }
0923:
0924: final java.math.BigDecimal getBigDecimal(int column)
0925: throws SqlException {
0926: switch (jdbcTypes_[column - 1]) {
0927: case java.sql.Types.DECIMAL:
0928: return get_DECIMAL(column);
0929: case java.sql.Types.REAL:
0930: // Can't use the following commented out line because it changes precision of the result.
0931: //return new java.math.BigDecimal (get_FLOAT (column));
0932: float f = get_FLOAT(column);
0933: return new java.math.BigDecimal(String.valueOf(f));
0934: case java.sql.Types.DOUBLE:
0935: // Can't use the following commented out line because it changes precision of the result.
0936: return new java.math.BigDecimal(String
0937: .valueOf(get_DOUBLE(column)));
0938: case java.sql.Types.SMALLINT:
0939: return java.math.BigDecimal.valueOf(get_SMALLINT(column));
0940: case java.sql.Types.INTEGER:
0941: return java.math.BigDecimal.valueOf(get_INTEGER(column));
0942: case java.sql.Types.BIGINT:
0943: return java.math.BigDecimal.valueOf(get_BIGINT(column));
0944: case java.sql.Types.CHAR:
0945: return agent_.crossConverters_
0946: .getBigDecimalFromString(getCHAR(column));
0947: case java.sql.Types.VARCHAR:
0948: case java.sql.Types.LONGVARCHAR:
0949: return agent_.crossConverters_
0950: .getBigDecimalFromString(getVARCHAR(column));
0951: default:
0952: throw new ColumnTypeConversionException(agent_.logWriter_,
0953: "java.sql.Types " + jdbcTypes_[column - 1],
0954: "java.math.BigDecimal");
0955: }
0956: }
0957:
0958: final java.sql.Date getDate(int column) throws SqlException {
0959: switch (jdbcTypes_[column - 1]) {
0960: case java.sql.Types.DATE:
0961: return getDATE(column);
0962: case java.sql.Types.TIMESTAMP:
0963: return getDateFromTIMESTAMP(column);
0964: case java.sql.Types.CHAR:
0965: return agent_.crossConverters_
0966: .getDateFromString(getCHAR(column));
0967: case java.sql.Types.VARCHAR:
0968: case java.sql.Types.LONGVARCHAR:
0969: return agent_.crossConverters_
0970: .getDateFromString(getVARCHAR(column));
0971: default:
0972: throw new ColumnTypeConversionException(agent_.logWriter_,
0973: "java.sql.Types " + jdbcTypes_[column - 1],
0974: "java.sql.Date");
0975: }
0976: }
0977:
0978: final java.sql.Time getTime(int column) throws SqlException {
0979: switch (jdbcTypes_[column - 1]) {
0980: case java.sql.Types.TIME:
0981: return getTIME(column);
0982: case java.sql.Types.TIMESTAMP:
0983: return getTimeFromTIMESTAMP(column);
0984: case java.sql.Types.CHAR:
0985: return agent_.crossConverters_
0986: .getTimeFromString(getCHAR(column));
0987: case java.sql.Types.VARCHAR:
0988: case java.sql.Types.LONGVARCHAR:
0989: return agent_.crossConverters_
0990: .getTimeFromString(getVARCHAR(column));
0991: default:
0992: throw new ColumnTypeConversionException(agent_.logWriter_,
0993: "java.sql.Types " + jdbcTypes_[column - 1],
0994: "java.sql.Time");
0995: }
0996: }
0997:
0998: final java.sql.Timestamp getTimestamp(int column)
0999: throws SqlException {
1000: switch (jdbcTypes_[column - 1]) {
1001: case java.sql.Types.TIMESTAMP:
1002: return getTIMESTAMP(column);
1003: case java.sql.Types.DATE:
1004: return getTimestampFromDATE(column);
1005: case java.sql.Types.TIME:
1006: return getTimestampFromTIME(column);
1007: case java.sql.Types.CHAR:
1008: return agent_.crossConverters_
1009: .getTimestampFromString(getCHAR(column));
1010: case java.sql.Types.VARCHAR:
1011: case java.sql.Types.LONGVARCHAR:
1012: return agent_.crossConverters_
1013: .getTimestampFromString(getVARCHAR(column));
1014: default:
1015: throw new ColumnTypeConversionException(agent_.logWriter_,
1016: "java.sql.Types " + jdbcTypes_[column - 1],
1017: "java.sql.Timestamp");
1018: }
1019: }
1020:
1021: final String getString(int column) throws SqlException {
1022: try {
1023: String tempString = null;
1024: switch (jdbcTypes_[column - 1]) {
1025: case java.sql.Types.CHAR:
1026: return getCHAR(column);
1027: case java.sql.Types.VARCHAR:
1028: case java.sql.Types.LONGVARCHAR:
1029: return getVARCHAR(column);
1030:
1031: case java.sql.Types.SMALLINT:
1032: return String.valueOf(get_SMALLINT(column));
1033: case java.sql.Types.INTEGER:
1034: return String.valueOf(get_INTEGER(column));
1035: case java.sql.Types.BIGINT:
1036: return String.valueOf(get_BIGINT(column));
1037: case java.sql.Types.REAL:
1038: return String.valueOf(get_FLOAT(column));
1039: case java.sql.Types.DOUBLE:
1040: return String.valueOf(get_DOUBLE(column));
1041: case java.sql.Types.DECIMAL:
1042: // We could get better performance here if we didn't materialize the BigDecimal,
1043: // but converted directly from decimal bytes to a string.
1044: return String.valueOf(get_DECIMAL(column));
1045: case java.sql.Types.DATE:
1046: return getStringFromDATE(column);
1047: case java.sql.Types.TIME:
1048: return getStringFromTIME(column);
1049: case java.sql.Types.TIMESTAMP:
1050: return getStringFromTIMESTAMP(column);
1051: case Types.BINARY:
1052: tempString = agent_.crossConverters_
1053: .getStringFromBytes(get_CHAR_FOR_BIT_DATA(column));
1054: return (maxFieldSize_ == 0) ? tempString : tempString
1055: .substring(0, java.lang.Math.min(maxFieldSize_,
1056: tempString.length()));
1057: case java.sql.Types.VARBINARY:
1058: case java.sql.Types.LONGVARBINARY:
1059: tempString = agent_.crossConverters_
1060: .getStringFromBytes(get_VARCHAR_FOR_BIT_DATA(column));
1061: return (maxFieldSize_ == 0) ? tempString : tempString
1062: .substring(0, java.lang.Math.min(maxFieldSize_,
1063: tempString.length()));
1064: case java.sql.Types.BLOB:
1065: Blob b = (Blob) getBlobColumn_(column, agent_);
1066: return agent_.crossConverters_.getStringFromBytes(b
1067: .getBytes(1, (int) b.length()));
1068: case java.sql.Types.CLOB:
1069: Clob c = getClobColumn_(column, agent_);
1070: return c.getSubString(1, (int) c.length());
1071: default:
1072: throw new ColumnTypeConversionException(
1073: agent_.logWriter_, "java.sql.Types "
1074: + jdbcTypes_[column - 1], "String");
1075: }
1076: } catch (SQLException se) {
1077: throw new SqlException(se);
1078: }
1079: }
1080:
1081: final byte[] getBytes(int column) throws SqlException {
1082: try {
1083: switch (jdbcTypes_[column - 1]) {
1084: case java.sql.Types.BINARY:
1085: return get_CHAR_FOR_BIT_DATA(column);
1086: case java.sql.Types.VARBINARY:
1087: case java.sql.Types.LONGVARBINARY:
1088: return get_VARCHAR_FOR_BIT_DATA(column);
1089: case java.sql.Types.BLOB:
1090: Blob b = (Blob) getBlobColumn_(column, agent_);
1091: return b.getBytes(1, (int) b.length());
1092: default:
1093: throw new ColumnTypeConversionException(
1094: agent_.logWriter_, "java.sql.Types "
1095: + jdbcTypes_[column - 1], "byte[]");
1096: }
1097: } catch (SQLException se) {
1098: throw new SqlException(se);
1099: }
1100: }
1101:
1102: public final java.io.InputStream getBinaryStream(int column)
1103: throws SqlException {
1104: try {
1105: switch (jdbcTypes_[column - 1]) {
1106: case java.sql.Types.BINARY:
1107: return new java.io.ByteArrayInputStream(
1108: get_CHAR_FOR_BIT_DATA(column));
1109: case java.sql.Types.VARBINARY:
1110: case java.sql.Types.LONGVARBINARY:
1111: return new java.io.ByteArrayInputStream(
1112: get_VARCHAR_FOR_BIT_DATA(column));
1113: case java.sql.Types.BLOB:
1114: Blob b = (Blob) getBlobColumn_(column, agent_);
1115: return b.getBinaryStream();
1116: default:
1117: throw new ColumnTypeConversionException(
1118: agent_.logWriter_, "java.sql.Types "
1119: + jdbcTypes_[column - 1],
1120: "java.io.InputStream");
1121: }
1122: } catch (SQLException se) {
1123: throw new SqlException(se);
1124: }
1125: }
1126:
1127: public final java.io.InputStream getAsciiStream(int column)
1128: throws SqlException {
1129: try {
1130: switch (jdbcTypes_[column - 1]) {
1131: case java.sql.Types.CLOB:
1132: Clob c = getClobColumn_(column, agent_);
1133: return c.getAsciiStream();
1134: case java.sql.Types.CHAR:
1135: try {
1136: return new java.io.ByteArrayInputStream(getCHAR(
1137: column).getBytes("US-ASCII"));
1138: } catch (java.io.UnsupportedEncodingException e) {
1139: throw new SqlException(agent_.logWriter_,
1140: new ClientMessageId(
1141: SQLState.UNSUPPORTED_ENCODING),
1142: "CHAR", "java.io.InputStream", e);
1143: }
1144: case java.sql.Types.VARCHAR:
1145: case java.sql.Types.LONGVARCHAR:
1146: try {
1147: return new java.io.ByteArrayInputStream(getVARCHAR(
1148: column).getBytes("US-ASCII"));
1149: } catch (java.io.UnsupportedEncodingException e) {
1150: throw new SqlException(agent_.logWriter_,
1151: new ClientMessageId(
1152: SQLState.UNSUPPORTED_ENCODING),
1153: "VARCHAR/LONGVARCHAR",
1154: "java.io.InputStream", e);
1155: }
1156: case java.sql.Types.BINARY:
1157: return new java.io.ByteArrayInputStream(
1158: get_CHAR_FOR_BIT_DATA(column));
1159: case java.sql.Types.VARBINARY:
1160: case java.sql.Types.LONGVARBINARY:
1161: return new java.io.ByteArrayInputStream(
1162: get_VARCHAR_FOR_BIT_DATA(column));
1163: case java.sql.Types.BLOB:
1164: Blob b = (Blob) getBlobColumn_(column, agent_);
1165: return b.getBinaryStream();
1166: default:
1167: throw new ColumnTypeConversionException(
1168: agent_.logWriter_, "java.sql.Types "
1169: + jdbcTypes_[column - 1],
1170: "java.io.InputStream");
1171: }
1172: } catch (SQLException se) {
1173: throw new SqlException(se);
1174: }
1175: }
1176:
1177: public final java.io.InputStream getUnicodeStream(int column)
1178: throws SqlException {
1179: try {
1180: switch (jdbcTypes_[column - 1]) {
1181: case java.sql.Types.CLOB: {
1182: Clob c = getClobColumn_(column, agent_);
1183: String s = c.getSubString(1L, (int) c.length());
1184: try {
1185: return new java.io.ByteArrayInputStream(s
1186: .getBytes("UTF-8"));
1187: } catch (java.io.UnsupportedEncodingException e) {
1188: throw new SqlException(agent_.logWriter_,
1189: new ClientMessageId(
1190: SQLState.UNSUPPORTED_ENCODING),
1191: "CLOB", "UnicodeStream", e);
1192: }
1193: }
1194: case java.sql.Types.CHAR: {
1195: try {
1196: return new java.io.ByteArrayInputStream(getCHAR(
1197: column).getBytes("UTF-8"));
1198: } catch (java.io.UnsupportedEncodingException e) {
1199: throw new SqlException(agent_.logWriter_,
1200: new ClientMessageId(
1201: SQLState.UNSUPPORTED_ENCODING),
1202: "CHAR", "UnicodeStream", e);
1203: }
1204: }
1205: case java.sql.Types.VARCHAR:
1206: case java.sql.Types.LONGVARCHAR:
1207: try {
1208: return new java.io.ByteArrayInputStream(getVARCHAR(
1209: column).getBytes("UTF-8"));
1210: } catch (java.io.UnsupportedEncodingException e) {
1211: throw new SqlException(agent_.logWriter_,
1212: new ClientMessageId(
1213: SQLState.UNSUPPORTED_ENCODING),
1214: "VARCHAR/LONGVARCHAR", "UnicodeStream", e);
1215: }
1216: case java.sql.Types.BINARY:
1217: return new java.io.ByteArrayInputStream(
1218: get_CHAR_FOR_BIT_DATA(column));
1219: case java.sql.Types.VARBINARY:
1220: case java.sql.Types.LONGVARBINARY:
1221: return new java.io.ByteArrayInputStream(
1222: get_VARCHAR_FOR_BIT_DATA(column));
1223: case java.sql.Types.BLOB:
1224: Blob b = (Blob) getBlobColumn_(column, agent_);
1225: return b.getBinaryStream();
1226: default:
1227: throw new ColumnTypeConversionException(
1228: agent_.logWriter_, "java.sql.Types "
1229: + jdbcTypes_[column - 1],
1230: "UnicodeStream");
1231: }
1232: } catch (SQLException se) {
1233: throw new SqlException(se);
1234: }
1235: }
1236:
1237: public final java.io.Reader getCharacterStream(int column)
1238: throws SqlException {
1239: try {
1240: switch (jdbcTypes_[column - 1]) {
1241: case java.sql.Types.CLOB:
1242: Clob c = getClobColumn_(column, agent_);
1243: return c.getCharacterStream();
1244: case java.sql.Types.CHAR:
1245: return new java.io.StringReader(getCHAR(column));
1246: case java.sql.Types.VARCHAR:
1247: case java.sql.Types.LONGVARCHAR:
1248: return new java.io.StringReader(getVARCHAR(column));
1249: case java.sql.Types.BINARY:
1250: try {
1251: return new java.io.InputStreamReader(
1252: new java.io.ByteArrayInputStream(
1253: get_CHAR_FOR_BIT_DATA(column)),
1254: "UTF-16BE");
1255: } catch (java.io.UnsupportedEncodingException e) {
1256: throw new SqlException(agent_.logWriter_,
1257: new ClientMessageId(
1258: SQLState.UNSUPPORTED_ENCODING),
1259: "BINARY", "java.io.Reader", e);
1260: }
1261: case java.sql.Types.VARBINARY:
1262: case java.sql.Types.LONGVARBINARY:
1263: try {
1264: return new java.io.InputStreamReader(
1265: new java.io.ByteArrayInputStream(
1266: get_VARCHAR_FOR_BIT_DATA(column)),
1267: "UTF-16BE");
1268: } catch (java.io.UnsupportedEncodingException e) {
1269: throw new SqlException(agent_.logWriter_,
1270: new ClientMessageId(
1271: SQLState.UNSUPPORTED_ENCODING),
1272: "VARBINARY/LONGVARBINARY",
1273: "java.io.Reader", e);
1274: }
1275: case java.sql.Types.BLOB:
1276: try {
1277: Blob b = (Blob) getBlobColumn_(column, agent_);
1278: return new java.io.InputStreamReader(b
1279: .getBinaryStream(), "UTF-16BE");
1280: } catch (java.io.UnsupportedEncodingException e) {
1281: throw new SqlException(agent_.logWriter_,
1282: new ClientMessageId(
1283: SQLState.UNSUPPORTED_ENCODING),
1284: "BLOB", "java.io.Reader", e);
1285: }
1286: default:
1287: throw new ColumnTypeConversionException(
1288: agent_.logWriter_, "java.sql.Types "
1289: + jdbcTypes_[column - 1],
1290: "java.io.Reader");
1291: }
1292: } catch (SQLException se) {
1293: throw new SqlException(se);
1294: }
1295: }
1296:
1297: public final java.sql.Blob getBlob(int column) throws SqlException {
1298: switch (jdbcTypes_[column - 1]) {
1299: case Types.BLOB:
1300: return getBlobColumn_(column, agent_);
1301: default:
1302: throw new ColumnTypeConversionException(agent_.logWriter_,
1303: "java.sql.Types " + jdbcTypes_[column - 1],
1304: "java.sql.Blob");
1305: }
1306: }
1307:
1308: public final java.sql.Clob getClob(int column) throws SqlException {
1309: switch (jdbcTypes_[column - 1]) {
1310: case Types.CLOB:
1311: return getClobColumn_(column, agent_);
1312: default:
1313: throw new ColumnTypeConversionException(agent_.logWriter_,
1314: "java.sql.Types " + jdbcTypes_[column - 1],
1315: "java.sql.Clob");
1316: }
1317: }
1318:
1319: public final java.sql.Array getArray(int column)
1320: throws SqlException {
1321: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1322: SQLState.NOT_IMPLEMENTED), "getArray(int)");
1323: }
1324:
1325: public final java.sql.Ref getRef(int column) throws SqlException {
1326: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1327: SQLState.NOT_IMPLEMENTED), "getRef(int)");
1328: }
1329:
1330: public final Object getObject(int column) throws SqlException {
1331: switch (jdbcTypes_[column - 1]) {
1332: case java.sql.Types.SMALLINT:
1333: return new Integer(get_SMALLINT(column)); // See Table 4 in JDBC 1 spec (pg. 932 in jdbc book)
1334: case java.sql.Types.INTEGER:
1335: return new Integer(get_INTEGER(column));
1336: case java.sql.Types.BIGINT:
1337: return new Long(get_BIGINT(column));
1338: case java.sql.Types.REAL:
1339: return new Float(get_FLOAT(column));
1340: case java.sql.Types.DOUBLE:
1341: return new Double(get_DOUBLE(column));
1342: case java.sql.Types.DECIMAL:
1343: return get_DECIMAL(column);
1344: case java.sql.Types.DATE:
1345: return getDATE(column);
1346: case java.sql.Types.TIME:
1347: return getTIME(column);
1348: case java.sql.Types.TIMESTAMP:
1349: return getTIMESTAMP(column);
1350: case java.sql.Types.CHAR:
1351: return getCHAR(column);
1352: case java.sql.Types.VARCHAR:
1353: case java.sql.Types.LONGVARCHAR:
1354: return getVARCHAR(column);
1355: case Types.BINARY:
1356: return get_CHAR_FOR_BIT_DATA(column);
1357: case java.sql.Types.VARBINARY:
1358: case java.sql.Types.LONGVARBINARY:
1359: return get_VARCHAR_FOR_BIT_DATA(column);
1360: case java.sql.Types.BLOB:
1361: return getBlobColumn_(column, agent_);
1362: case java.sql.Types.CLOB:
1363: return getClobColumn_(column, agent_);
1364: default:
1365: throw new ColumnTypeConversionException(agent_.logWriter_,
1366: "java.sql.Types " + jdbcTypes_[column - 1],
1367: "Object");
1368: }
1369: }
1370:
1371: public final void allocateCharBuffer() {
1372: // compute the maximum char length
1373: int maxCharLength = 0;
1374: for (int i = 0; i < columns_; i++) {
1375: switch (jdbcTypes_[i]) {
1376: case Types.CHAR:
1377: case Types.VARCHAR:
1378: case Types.LONGVARCHAR:
1379: if (fdocaLength_[i] > maxCharLength) {
1380: maxCharLength = fdocaLength_[i];
1381: }
1382: }
1383: }
1384:
1385: // allocate char buffer to accomodate largest result column
1386: charBuffer_ = new char[maxCharLength];
1387: }
1388:
1389: private final String getStringWithoutConvert(int position,
1390: int actualLength) throws SqlException {
1391: int start = position;
1392: int end = position + actualLength;
1393:
1394: int charCount = 0;
1395: while (start < end) {
1396: charBuffer_[charCount++] = (char) (((dataBuffer_[start] & 0xff) << 8) | (dataBuffer_[start + 1] & 0xff));
1397: start += 2;
1398: }
1399:
1400: return new String(charBuffer_, 0, charCount);
1401: }
1402:
1403: public void nullDataForGC() {
1404: dataBuffer_ = null;
1405: dataBufferStream_ = null;
1406: columnDataPosition_ = null;
1407: columnDataComputedLength_ = null;
1408: columnDataPositionCache_ = null;
1409: columnDataLengthCache_ = null;
1410: columnDataIsNullCache_ = null;
1411: jdbcTypes_ = null;
1412: nullable_ = null;
1413: charsetName_ = null;
1414: this .ccsid_ = null;
1415: isUpdateDeleteHoleCache_ = null;
1416: isNull_ = null;
1417: fdocaLength_ = null;
1418: charBuffer_ = null;
1419: }
1420:
1421: private final int getColumnPrecision(int column) {
1422: return ((fdocaLength_[column] >> 8) & 0xff);
1423: }
1424:
1425: private final int getColumnScale(int column) {
1426: return (fdocaLength_[column] & 0xff);
1427: }
1428:
1429: // Only used by Sqlca.getMessage() when using a locale encoding
1430: // to convert errror message text instead of relying on server encoding as usual.
1431: final byte[] getBytesFromVARCHAR(int column) throws SqlException {
1432: byte[] bytes;
1433: bytes = new byte[columnDataComputedLength_[column - 1] - 2];
1434: System.arraycopy(dataBuffer_,
1435: columnDataPosition_[column - 1] + 2, bytes, 0,
1436: bytes.length);
1437: return bytes;
1438: }
1439: }
|