public byte[] getBytes() throws SQLException { if (savedObject_ != null) // @loch { // @loch // get value from RS.updateX(value) doConversion(); // @loch truncated_ = 0; outOfBounds_ = false; // @loch return value_; // @loch } // @loch int locatorLength = (int) locator_.getLength(); if (locatorLength == 0) return new byte[0]; DBLobData data = locator_.retrieveData(0, locatorLength); int actualLength = data.getLength(); byte[] bytes = new byte[actualLength]; System.arraycopy(data.getRawBytes(), data.getOffset(), bytes, 0, actualLength); truncated_ = 0; outOfBounds_ = false; return bytes; }
private void writeToServer() throws SQLException { try { Object object = savedObject_; if (object instanceof String) { String string = (String) object; int bidiStringType = settings_.getBidiStringType(); if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_; BidiConversionProperties bidiConversionProperties = new BidiConversionProperties(bidiStringType); // @KBA bidiConversionProperties.setBidiImplicitReordering( settings_.getBidiImplicitReordering()); // @KBA bidiConversionProperties.setBidiNumericOrderingRoundTrip( settings_.getBidiNumericOrdering()); // @KBA byte[] bytes = converter_.stringToByteArray( string, bidiConversionProperties); // @KBC changed to use bidiConversionProperties instead // of bidiStringType locator_.writeData(0L, bytes, true); // @K1C } else if (object instanceof Reader) { int length = scale_; // hack to get the length into the set method // Need to write even if there are 0 bytes in case we are batching and // the host server reuses the same handle for the previous locator; otherwise, // we'll have data in the current row from the previous row. if (length == 0) { locator_.writeData(0, new byte[0], 0, 0, true); // @K1C } else if (length > 0) { try { int blockSize = length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE ? length : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; int bidiStringType = settings_.getBidiStringType(); if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_; BidiConversionProperties bidiConversionProperties = new BidiConversionProperties(bidiStringType); // @KBA bidiConversionProperties.setBidiImplicitReordering( settings_.getBidiImplicitReordering()); // @KBA bidiConversionProperties.setBidiNumericOrderingRoundTrip( settings_.getBidiNumericOrdering()); // @KBA ReaderInputStream stream = new ReaderInputStream( (Reader) savedObject_, converter_.getCcsid(), bidiConversionProperties, blockSize); // @KBC changed to use bidiConversionProperties instead of // bidiStringType byte[] byteBuffer = new byte[blockSize]; int totalBytesRead = 0; int bytesRead = stream.read(byteBuffer, 0, blockSize); while (bytesRead > -1 && totalBytesRead < length) { locator_.writeData( (long) totalBytesRead, byteBuffer, 0, bytesRead, true); // totalBytesRead is our offset. @K1C totalBytesRead += bytesRead; int bytesRemaining = length - totalBytesRead; if (bytesRemaining < blockSize) { blockSize = bytesRemaining; if (stream.available() == 0 && blockSize != 0) { stream.close(); // @scan1 stream = new ReaderInputStream( (Reader) savedObject_, converter_.getCcsid(), bidiConversionProperties, blockSize); // do this so we don't read more chars out of the Reader than // we have to. //@KBC changed to use bidiConversionProperties // instead of bidiStringType } } bytesRead = stream.read(byteBuffer, 0, blockSize); } stream.close(); // @scan1 if (totalBytesRead < length) { // a length longer than the stream was specified JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else if (length == -2) // @readerlen new else-if block (read all data) { try { // String readerStr = JDUtilities.readerToString((Reader)savedObject_); int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; int bidiStringType = settings_.getBidiStringType(); if (bidiStringType == -1) bidiStringType = converter_.bidiStringType_; BidiConversionProperties bidiConversionProperties = new BidiConversionProperties(bidiStringType); // @KBA bidiConversionProperties.setBidiImplicitReordering( settings_.getBidiImplicitReordering()); // @KBA bidiConversionProperties.setBidiNumericOrderingRoundTrip( settings_.getBidiNumericOrdering()); // @KBA ReaderInputStream stream = new ReaderInputStream( (Reader) savedObject_, converter_.getCcsid(), bidiConversionProperties, blockSize); // @KBC changed to use bidiConversionProperties instead of // bidiStringType byte[] byteBuffer = new byte[blockSize]; int totalBytesRead = 0; int bytesRead = stream.read(byteBuffer, 0, blockSize); while (bytesRead > -1) { locator_.writeData( (long) totalBytesRead, byteBuffer, 0, bytesRead, true); // totalBytesRead is our offset. @K1C totalBytesRead += bytesRead; bytesRead = stream.read(byteBuffer, 0, blockSize); } stream.close(); // @scan1 } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } else if (object instanceof InputStream) { int length = scale_; // hack to get the length into the set method // Need to write even if there are 0 bytes in case we are batching and // the host server reuses the same handle for the previous locator; otherwise, // we'll have data in the current row from the previous row. if (length == 0) { locator_.writeData(0, new byte[0], 0, 0, true); // @K1C } else if (length > 0) { InputStream stream = (InputStream) savedObject_; int blockSize = length < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE ? length : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; byte[] byteBuffer = new byte[blockSize]; try { int totalBytesRead = 0; int bytesRead = stream.read(byteBuffer, 0, blockSize); while (bytesRead > -1 && totalBytesRead < length) { locator_.writeData( (long) totalBytesRead, byteBuffer, 0, bytesRead, true); // totalBytesRead is our offset. @K1C totalBytesRead += bytesRead; int bytesRemaining = length - totalBytesRead; if (bytesRemaining < blockSize) { blockSize = bytesRemaining; } bytesRead = stream.read(byteBuffer, 0, blockSize); } if (totalBytesRead < length) { // a length longer than the stream was specified JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else if (length == -2) // @readerlen new else-if block (read all data) { InputStream stream = (InputStream) savedObject_; int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; byte[] byteBuffer = new byte[blockSize]; try { int totalBytesRead = 0; int bytesRead = stream.read(byteBuffer, 0, blockSize); while (bytesRead > -1) { locator_.writeData( (long) totalBytesRead, byteBuffer, 0, bytesRead, true); // totalBytesRead is our offset. @K1C totalBytesRead += bytesRead; bytesRead = stream.read(byteBuffer, 0, blockSize); } } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } else if (JDUtilities.JDBCLevel_ >= 20 && object instanceof Clob) // @H0A check for jdbc level to know if lobs exist { // @G5A Start new code for updateable locator case boolean set = false; if (object instanceof AS400JDBCClobLocator) { AS400JDBCClobLocator clob = (AS400JDBCClobLocator) object; // Synchronize on a lock so that the user can't keep making updates // to the clob while we are taking updates off the vectors. synchronized (clob) { // See if we saved off our real object from earlier. if (clob.savedObject_ != null) { savedObject_ = clob.savedObject_; scale_ = clob.savedScale_; clob.savedObject_ = null; writeToServer(); return; } } } // @G5A If the code for updateable lob locators did not run, then run old code. if (!set) { Clob clob = (Clob) object; int length = (int) clob.length(); String substring = clob.getSubString(1, length); locator_.writeData(0L, converter_.stringToByteArray(substring), 0, length, true); // @K1C set = true; } else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } /*ifdef JDBC40 else if( object instanceof SQLXML ) //@PDA jdbc40 { SQLXML xml = (SQLXML)object; String stringVal = xml.getString(); locator_.writeData(0L, converter_.stringToByteArray(stringVal), 0, stringVal.length(), true); } endif */ else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } finally { savedObject_ = null; } scale_ = (int) locator_.getLength(); }
// @loch method to temporary convert from object input to output before even going to host // (writeToServer() does the conversion needed before writing to host) // This will only be used when resultSet.updateX(obj1) is called followed by a obj2 = // resultSet.getX() // Purpose is to do a local type conversion from obj1 to obj2 like other non-locator lob types private void doConversion() throws SQLException { int length_ = scale_; if (length_ == -1) { try { // try to get length from locator length_ = (int) locator_.getLength(); } catch (Exception e) { } } try { Object object = savedObject_; if (savedObject_ instanceof String) { value_ = (String) object; } else if (object instanceof Reader) { if (length_ >= 0) { try { int blockSize = length_ < AS400JDBCPreparedStatement.LOB_BLOCK_SIZE ? length_ : AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; Reader stream = (Reader) object; StringBuffer buf = new StringBuffer(); char[] charBuffer = new char[blockSize]; int totalCharsRead = 0; int charsRead = stream.read(charBuffer, 0, blockSize); while (charsRead > -1 && totalCharsRead < length_) { buf.append(charBuffer, 0, charsRead); totalCharsRead += charsRead; int charsRemaining = length_ - totalCharsRead; if (charsRemaining < blockSize) { blockSize = charsRemaining; } charsRead = stream.read(charBuffer, 0, blockSize); } value_ = buf.toString(); if (value_.length() < length_) { // a length longer than the stream was specified JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else if (length_ == -2) // @readerlen new else-if block (read all data) { try { int blockSize = AS400JDBCPreparedStatement.LOB_BLOCK_SIZE; Reader stream = (Reader) object; StringBuffer buf = new StringBuffer(); char[] charBuffer = new char[blockSize]; int totalCharsRead = 0; int charsRead = stream.read(charBuffer, 0, blockSize); while (charsRead > -1) { buf.append(charBuffer, 0, charsRead); totalCharsRead += charsRead; charsRead = stream.read(charBuffer, 0, blockSize); } value_ = buf.toString(); } catch (IOException ie) { JDError.throwSQLException(this, JDError.EXC_INTERNAL, ie); } } else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } } else if (object instanceof Clob) { Clob clob = (Clob) object; value_ = clob.getSubString(1, (int) clob.length()); } /* ifdef JDBC40 else if( object instanceof SQLXML ) { SQLXML xml = (SQLXML)object; value_ = xml.getString(); } endif */ else { JDError.throwSQLException(this, JDError.EXC_DATA_TYPE_MISMATCH); } // Truncate if necessary. int valueLength = value_.length(); if (valueLength > maxLength_) { value_ = value_.substring(0, maxLength_); } } finally { // nothing } }