public Clob getClob() throws SQLException { truncated_ = 0; outOfBounds_ = false; if (savedObject_ != null) // @loch { // @loch // get value from RS.updateX(value) doConversion(); // @loch truncated_ = 0; outOfBounds_ = false; // @loch return new AS400JDBCClob(value_, maxLength_); // @loch } // @loch AS400JDBCClobLocator locatorReturn = new AS400JDBCClobLocator(new JDLobLocator(locator_), converter_, savedObject_, scale_); if (ConvTable.isMixedCCSID(converter_.ccsid_)) { // Since this is a mixed CCSID, the locator APIs with length, etc.. do not work correctly // @J5A We read the whole thing and convert to a local clob. savedObject_ = locatorReturn.getSubString((long) 1, (int) locatorReturn.length()); return new AS400JDBCClob((String) savedObject_, maxLength_); // @loch } return locatorReturn; }
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(); }