Search in sources :

Example 1 with StringDataValue

use of org.apache.derby.iapi.types.StringDataValue 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);
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ReaderToUTF8Stream(org.apache.derby.iapi.types.ReaderToUTF8Stream) StringDataValue(org.apache.derby.iapi.types.StringDataValue)

Example 2 with StringDataValue

use of org.apache.derby.iapi.types.StringDataValue in project derby by apache.

the class EmbedResultSet method getCharacterStream.

/**
 * JDBC 2.0
 *
 * <p>Get the value of a column in the current row as a java.io.Reader.
 *
 * @exception SQLException database error.
 */
public final java.io.Reader getCharacterStream(int columnIndex) throws SQLException {
    checkIfClosed("getCharacterStream");
    int lmfs;
    int colType = getColumnType(columnIndex);
    switch(colType) {
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
            lmfs = maxFieldSize;
            break;
        case // Embedded and JCC extension - CLOB is not subject to max field size.
        Types.CLOB:
            lmfs = 0;
            break;
        // match JCC which treats the bytes as a UTF16-BE stream
        case Types.BINARY:
        case Types.VARBINARY:
        case Types.LONGVARBINARY:
        case Types.BLOB:
            try {
                java.io.InputStream is = getBinaryStream(columnIndex);
                if (is == null)
                    return null;
                java.io.Reader r = new java.io.InputStreamReader(is, "UTF-16BE");
                currentStream = r;
                return r;
            } catch (java.io.UnsupportedEncodingException uee) {
                throw new SQLException(uee.getMessage());
            }
        default:
            throw dataTypeConversion("java.io.Reader", columnIndex);
    }
    Object syncLock = getConnectionSynchronization();
    synchronized (syncLock) {
        boolean pushStack = false;
        try {
            useStreamOrLOB(columnIndex);
            StringDataValue dvd = (StringDataValue) getColumn(columnIndex);
            if (wasNull = dvd.isNull()) {
                return null;
            }
            pushStack = true;
            setupContextStack();
            // The reader we will return to the user
            java.io.Reader ret;
            if (dvd.hasStream()) {
                CharacterStreamDescriptor csd = dvd.getStreamWithDescriptor();
                // See if we have to enforce a max field size.
                if (lmfs > 0) {
                    csd = new CharacterStreamDescriptor.Builder().copyState(csd).maxCharLength(lmfs).build();
                }
                ret = new UTF8Reader(csd, this, syncLock);
            } else {
                String val = dvd.getString();
                if (lmfs > 0) {
                    if (val.length() > lmfs)
                        val = val.substring(0, lmfs);
                }
                ret = new java.io.StringReader(val);
            }
            currentStream = ret;
            return ret;
        } catch (Throwable t) {
            throw noStateChangeException(t);
        } finally {
            if (pushStack) {
                restoreContextStack();
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) Reader(java.io.Reader) CharacterStreamDescriptor(org.apache.derby.iapi.jdbc.CharacterStreamDescriptor) StringDataValue(org.apache.derby.iapi.types.StringDataValue) InputStream(java.io.InputStream)

Example 3 with StringDataValue

use of org.apache.derby.iapi.types.StringDataValue 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);
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) ReaderToUTF8Stream(org.apache.derby.iapi.types.ReaderToUTF8Stream) StringDataValue(org.apache.derby.iapi.types.StringDataValue)

Example 4 with StringDataValue

use of org.apache.derby.iapi.types.StringDataValue in project derby by apache.

the class EmbedCallableStatement method getCharacterStream.

// JDBC 4.0 methods
/**
 * Retrieves the value of the designated parameter as a
 * <code>java.io.Reader</code> object in the Java programming language.
 * Introduced in JDBC 4.0.
 *
 * @param parameterIndex the first parameter is 1, the second is 2, ...
 * @return a <code>java.io.Reader</code> object that contains the parameter
 * value; if the value is SQL <code>NULL</code>, the value returned
 * is <code>null</code> in the Java programming language.
 * @throws SQLException if a database access error occurs or this method is
 * called on a closed <code>CallableStatement</code>
 */
public final Reader getCharacterStream(int parameterIndex) throws SQLException {
    checkStatus();
    // Make sure the specified parameter has mode OUT or IN/OUT.
    switch(getParms().getParameterMode(parameterIndex)) {
        case (ParameterMetaData.parameterModeIn):
        case (ParameterMetaData.parameterModeUnknown):
            throw newSQLException(SQLState.LANG_NOT_OUTPUT_PARAMETER, Integer.toString(parameterIndex));
    }
    Reader reader = null;
    int paramType = getParameterJDBCType(parameterIndex);
    switch(paramType) {
        // Handle character/string types.
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
        case Types.CLOB:
            boolean pushStack = false;
            Object syncObject = getConnectionSynchronization();
            synchronized (syncObject) {
                try {
                    StringDataValue param = (StringDataValue) getParms().getParameterForGet(parameterIndex - 1);
                    if (param.isNull()) {
                        break;
                    }
                    pushStack = true;
                    setupContextStack();
                    if (param.hasStream()) {
                        CharacterStreamDescriptor csd = param.getStreamWithDescriptor();
                        reader = new UTF8Reader(csd, this, syncObject);
                    } else {
                        reader = new StringReader(param.getString());
                    }
                } catch (Throwable t) {
                    throw EmbedResultSet.noStateChangeException(t);
                } finally {
                    if (pushStack) {
                        restoreContextStack();
                    }
                }
            }
            // End synchronized block
            break;
        // Match JCC which treats the bytes as a UTF-16BE stream.
        case Types.BINARY:
        case Types.VARBINARY:
        case Types.LONGVARBINARY:
        case Types.BLOB:
            try {
                InputStream is = getBinaryStream(parameterIndex);
                if (is != null) {
                    reader = new InputStreamReader(is, "UTF-16BE");
                }
                break;
            } catch (UnsupportedEncodingException uee) {
                throw newSQLException(uee.getMessage());
            }
        default:
            throw newSQLException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, "java.io.Reader", Util.typeName(paramType));
    }
    // Update wasNull.
    wasNull = (reader == null);
    return reader;
}
Also used : InputStreamReader(java.io.InputStreamReader) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) StringReader(java.io.StringReader) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) StringReader(java.io.StringReader) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CharacterStreamDescriptor(org.apache.derby.iapi.jdbc.CharacterStreamDescriptor) StringDataValue(org.apache.derby.iapi.types.StringDataValue)

Example 5 with StringDataValue

use of org.apache.derby.iapi.types.StringDataValue in project derby by apache.

the class UTF8ReaderTest method testRepositioningSimple.

/**
 * Tests simple repositioning.
 */
public void testRepositioningSimple() throws IOException, SQLException, StandardException {
    setAutoCommit(false);
    Statement stmt = createStatement();
    ResultSet rs = stmt.executeQuery("select * from Utf8ReaderTest where id = 101");
    rs.next();
    final int size = rs.getInt(2);
    StringDataValue dvd = (StringDataValue) ((EmbedResultSet) rs).getColumn(3);
    StoreStreamClob ssClob = new StoreStreamClob(dvd.getStreamWithDescriptor(), (EmbedResultSet) rs);
    Reader reader = ssClob.getInternalReader(1);
    assertEquals('a', reader.read());
    // Get internal readers and do stuff.
    // Get first character.
    checkInternalStream(1, ssClob);
    // Skip forwards inside buffer.
    checkInternalStream(26, ssClob);
    // Skip forwards, refill buffer.
    checkInternalStream(17003, ssClob);
    // Skip until end.
    checkInternalStream(size, ssClob);
    assertEquals(-1, reader.read());
    // Rewind and refill buffer.
    checkInternalStream(10, ssClob);
    try {
        // Should fail, invalid pos.
        checkInternalStream(size * 2, ssClob);
        fail("Should have failed due to invalid position");
    } catch (EOFException eofe) {
    // As expected, do nothing.
    }
}
Also used : PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) EOFException(java.io.EOFException) LoopingAlphabetReader(org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader) Reader(java.io.Reader) StringDataValue(org.apache.derby.iapi.types.StringDataValue)

Aggregations

StringDataValue (org.apache.derby.iapi.types.StringDataValue)10 Reader (java.io.Reader)5 PreparedStatement (java.sql.PreparedStatement)3 ResultSet (java.sql.ResultSet)3 Statement (java.sql.Statement)3 LoopingAlphabetReader (org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader)3 InputStream (java.io.InputStream)2 CharacterStreamDescriptor (org.apache.derby.iapi.jdbc.CharacterStreamDescriptor)2 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)2 ReaderToUTF8Stream (org.apache.derby.iapi.types.ReaderToUTF8Stream)2 StandardException (org.apache.derby.shared.common.error.StandardException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 EOFException (java.io.EOFException)1 InputStreamReader (java.io.InputStreamReader)1 StringReader (java.io.StringReader)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 SQLException (java.sql.SQLException)1 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1 DataValueFactory (org.apache.derby.iapi.types.DataValueFactory)1