use of org.apache.derby.iapi.types.ReaderToUTF8Stream in project derby by apache.
the class EmbedPreparedStatement method setCharacterStreamInternal.
/**
* Set the given character stream for the specified parameter.
*
* If <code>lengthLess</code> is <code>true</code>, the following
* conditions are either not checked or verified at the execution time
* of the prepared statement:
* <ol><li>If the stream length is negative.
* <li>If the stream's actual length equals the specified length.</ol>
* The <code>lengthLess</code> variable was added to differentiate between
* streams with invalid lengths and streams without known lengths.
*
* @param parameterIndex the 1-based index of the parameter to set.
* @param reader the data.
* @param lengthLess tells whether we know the length of the data or not.
* @param length the length of the data. Ignored if <code>lengthLess</code>
* is <code>true</code>.
*/
private void setCharacterStreamInternal(int parameterIndex, Reader reader, final boolean lengthLess, long length) throws SQLException {
// Check for negative length if length is specified.
if (!lengthLess && length < 0)
throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
int jdbcTypeId = getParameterJDBCType(parameterIndex);
if (reader == null) {
setNull(parameterIndex, jdbcTypeId);
return;
}
/*
The value stored should not exceed the maximum value that can be
stored in an integer
This checking needs to be done because currently derby does not
support Clob sizes greater than 2G-1
*/
if (!lengthLess && length > Integer.MAX_VALUE)
throw newSQLException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, getParameterSQLType(parameterIndex));
try {
ReaderToUTF8Stream utfIn;
final StringDataValue dvd = (StringDataValue) getParms().getParameter(parameterIndex - 1);
dvd.setStreamHeaderFormat(usePreTenFiveHdrFormat());
// Need column width to figure out if truncation is needed
DataTypeDescriptor[] dtd = preparedStatement.getParameterTypes();
int colWidth = dtd[parameterIndex - 1].getMaximumWidth();
// Holds either UNKNOWN_LOGICAL_LENGTH or the exact logical length.
int usableLength = DataValueDescriptor.UNKNOWN_LOGICAL_LENGTH;
if (!lengthLess) {
// We cast the length from long to int. This wouldn't be
// appropriate if the limit of 2G-1 is decided to be increased
// at a later stage.
usableLength = (int) length;
int truncationLength = 0;
// for clob below.
if (jdbcTypeId == Types.CLOB) {
// length - colWidth has trailing blanks only
if (usableLength > colWidth) {
truncationLength = usableLength - colWidth;
usableLength = colWidth;
}
}
// Create a stream with truncation.
utfIn = new ReaderToUTF8Stream(reader, usableLength, truncationLength, getParameterSQLType(parameterIndex), dvd.getStreamHeaderGenerator());
} else {
// Create a stream without exactness checks,
// but with a maximum limit.
utfIn = new ReaderToUTF8Stream(reader, colWidth, getParameterSQLType(parameterIndex), dvd.getStreamHeaderGenerator());
}
// JDBC is one-based, DBMS is zero-based.
// Note that for lengthless stream, usableLength will be
// the maximum length for the column.
// This is okay, based on the observation that
// setValue does not use the value for anything at all.
getParms().getParameterForSet(parameterIndex - 1).setValue(utfIn, usableLength);
} catch (StandardException t) {
throw EmbedResultSet.noStateChangeException(t);
}
}
use of org.apache.derby.iapi.types.ReaderToUTF8Stream in project derby by apache.
the class EmbedResultSet method updateCharacterStreamInternal.
/**
* Set the given character stream for the specified parameter.
*
* If <code>lengthLess</code> is <code>true</code>, the following
* conditions are either not checked or verified at the execution time
* of the prepared statement:
* <ol><li>If the stream length is negative.
* <li>If the stream's actual length equals the specified length.</ol>
* The <code>lengthLess</code> variable was added to differentiate between
* streams with invalid lengths and streams without known lengths.
*
* @param columnIndex the 1-based index of the parameter to set.
* @param reader the data.
* @param lengthLess tells whether we know the length of the data or not.
* @param length the length of the data. Ignored if <code>lengthLess</code>
* is <code>true</code>.
* @throws SQLException if reading the data fails, or one of the data
* checks fails.
*/
private void updateCharacterStreamInternal(int columnIndex, Reader reader, final boolean lengthLess, long length, String updateMethodName) throws SQLException {
try {
if (reader == null) {
updateNull(columnIndex);
return;
}
final StringDataValue dvd = (StringDataValue) getDVDforColumnToBeUpdated(columnIndex, updateMethodName);
// In the case of updatable result sets, we cannot guarantee that a
// context is pushed when the header needs to be generated. To fix
// this, tell the DVD/generator which header format to use.
dvd.setStreamHeaderFormat(Boolean.valueOf(!getEmbedConnection().getDatabase().getDataDictionary().checkVersion(DataDictionary.DD_VERSION_DERBY_10_5, null)));
ReaderToUTF8Stream utfIn;
int usableLength = DataValueDescriptor.UNKNOWN_LOGICAL_LENGTH;
if (!lengthLess) {
// check for -ve length here
if (length < 0)
throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
// (e.g into a CLOB column).
if (length > Integer.MAX_VALUE) {
throw newSQLException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, getColumnSQLType(columnIndex));
}
// length is +ve. at this point, all checks for negative
// length has already been done
usableLength = (int) length;
int truncationLength = 0;
// for clob below.
if (getColumnType(columnIndex) == Types.CLOB) {
// Need column width to figure out if truncation is
// needed
int colWidth = getMaxColumnWidth(columnIndex);
// length - colWidth has trailing blanks only
if (usableLength > colWidth) {
truncationLength = usableLength - colWidth;
usableLength = colWidth;
}
}
utfIn = new ReaderToUTF8Stream(reader, usableLength, truncationLength, getColumnSQLType(columnIndex), dvd.getStreamHeaderGenerator());
} else {
int colWidth = getMaxColumnWidth(columnIndex);
utfIn = new ReaderToUTF8Stream(reader, colWidth, getColumnSQLType(columnIndex), dvd.getStreamHeaderGenerator());
}
dvd.setValue(utfIn, usableLength);
} catch (StandardException t) {
throw noStateChangeException(t);
}
}
use of org.apache.derby.iapi.types.ReaderToUTF8Stream in project derby by apache.
the class UTF8UtilTest method testSkipFullyOnValidLongStreamCJK.
/**
* Tests that <code>skipFully</code> successfully skips the requested
* characters and returns the correct number of bytes skipped.
*
* @throws IOException if the test fails for some unexpected reason
*/
public void testSkipFullyOnValidLongStreamCJK() throws IOException {
final int charLength = 161019;
InputStream in = new ReaderToUTF8Stream(new LoopingAlphabetReader(charLength, CharAlphabet.cjkSubset()), charLength, 0, TYPENAME, new CharStreamHeaderGenerator());
// Skip encoded length added by ReaderToUTF8Stream.
in.skip(HEADER_LENGTH);
// Returns count in bytes, we are using CJK chars so multiply length
// with 3 to get expected number of bytes.
assertEquals(charLength * 3, UTF8Util.skipFully(in, charLength));
}
use of org.apache.derby.iapi.types.ReaderToUTF8Stream in project derby by apache.
the class UTF8UtilTest method testSkipUntilEOFOnShortStreamCJK.
public void testSkipUntilEOFOnShortStreamCJK() throws IOException {
final int charLength = 5;
InputStream in = new ReaderToUTF8Stream(new LoopingAlphabetReader(charLength, CharAlphabet.cjkSubset()), charLength, 0, TYPENAME, new CharStreamHeaderGenerator());
// Skip encoded length added by ReaderToUTF8Stream.
in.skip(HEADER_LENGTH);
assertEquals(charLength, UTF8Util.skipUntilEOF(in));
}
use of org.apache.derby.iapi.types.ReaderToUTF8Stream in project derby by apache.
the class UTF8UtilTest method testSkipFullyOnTooShortStreamCJK.
/**
* Tests that <code>skipFully</code> throws exception if the stream contains
* less characters than the requested number of characters to skip.
*
* @throws IOException if the test fails for some unexpected reason
*/
public void testSkipFullyOnTooShortStreamCJK() throws IOException {
final int charLength = 161019;
InputStream in = new ReaderToUTF8Stream(new LoopingAlphabetReader(charLength, CharAlphabet.cjkSubset()), charLength, 0, TYPENAME, new ClobStreamHeaderGenerator(true));
// Skip encoded length added by ReaderToUTF8Stream.
in.skip(HEADER_LENGTH);
try {
UTF8Util.skipFully(in, charLength + 100);
fail("Should have failed because of too short stream.");
} catch (EOFException eofe) {
// As expected, do nothing.
}
}
Aggregations