| /* |
| * |
| * Derby - Class CharacterStreamsTest |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
| * either express or implied. See the License for the specific |
| * language governing permissions and limitations under the License. |
| */ |
| package org.apache.derbyTesting.functionTests.tests.jdbcapi; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.Reader; |
| import java.io.StringReader; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| import junit.framework.Test; |
| import org.apache.derbyTesting.functionTests.util.streams.CharAlphabet; |
| import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader; |
| import org.apache.derbyTesting.junit.BaseJDBCTestCase; |
| import org.apache.derbyTesting.junit.TestConfiguration; |
| |
| /** |
| * Tests the following PreparedStatement methods: |
| * -> setCharacterStream(int parameterIndex, InputStream x, int length) |
| * -> setAsciiStream(int parameterIndex, Reader reader, int length) |
| */ |
| public class CharacterStreamsTest extends BaseJDBCTestCase { |
| |
| public static Test suite() { |
| // Run only in embedded mode until DERBY-2017 is fixed. |
| return TestConfiguration.embeddedSuite(CharacterStreamsTest.class); |
| } |
| |
| /** Creates a new instance of CharacterStreamsTest */ |
| public CharacterStreamsTest(String name) { |
| super(name); |
| } |
| |
| /** |
| * Test PreparedStatement.setAsciiStream() with column of type CHAR |
| */ |
| public void testSetAsciiStreamIntoChar() throws Exception { |
| runTestSetAsciiStream(1); |
| } |
| |
| /** |
| * Test PreparedStatement.setAsciiStream() with column of type VARCHAR |
| */ |
| public void testSetAsciiStreamIntoVarchar() throws Exception { |
| runTestSetAsciiStream(2); |
| } |
| |
| /** |
| * Test PreparedStatement.setAsciiStream() with column of type LONG VARCHAR |
| */ |
| public void testSetAsciiStreamIntoLongVarchar() throws Exception { |
| runTestSetAsciiStream(3); |
| } |
| |
| /** |
| * Test PreparedStatement.setAsciiStream() with column of type CLOB |
| */ |
| public void testSetAsciiStreamIntoClob() throws Exception { |
| runTestSetAsciiStream(4); |
| } |
| |
| /** |
| * Test PreparedStatement.setCharacterStream() with column of type CHAR |
| */ |
| public void testSetCharacterStreamIntoChar() throws Exception { |
| runTestSetCharacterStream(1); |
| } |
| |
| /** |
| * Test PreparedStatement.setCharacterStream() with column of type VARCHAR |
| */ |
| public void testSetCharacterStreamIntoVarchar() throws Exception { |
| runTestSetCharacterStream(2); |
| } |
| |
| /** |
| * Test PreparedStatement.setCharacterStream() with column of type |
| * LONG VARCHAR |
| */ |
| public void testSetCharacterStreamIntoLongVarchar() throws Exception { |
| runTestSetCharacterStream(3); |
| } |
| |
| /** |
| * Test PreparedStatement.setCharacterStream() with column of type CLOB |
| */ |
| public void testSetCharacterStreamIntoClob() throws Exception { |
| runTestSetCharacterStream(4); |
| } |
| |
| /** |
| * Test PreparedStatement.setAsciiStream() with streams with sizes from |
| * 60characters to 32K characters |
| */ |
| public void testSetAsciiStreamLongValues() throws Exception { |
| runTestSetAsciiStreamLongValues(); |
| } |
| |
| /** |
| * Test PreparedStatement.setCharacterStream() with streams with sizes from |
| * 60 characters to 32K characters |
| */ |
| public void testSetCharacterStreamLongValues() throws Exception { |
| runTestSetCharacterStreamLongValues(); |
| } |
| |
| private void runTestSetAsciiStream(int col) throws Exception { |
| PreparedStatement psi = prepareStatement( |
| "insert into charstream(c, vc, lvc, lob) " + |
| "values(?,?,?,?)"); |
| PreparedStatement psq = prepareStatement( |
| "select id, c, {fn length(c)} AS CLEN, " + |
| "cast (vc as varchar(25)) AS VC, " + |
| "{fn length(vc)} AS VCLEN, " + |
| "cast (lvc as varchar(25)) AS LVC, " + |
| "{fn length(lvc)} AS LVCLEN, " + |
| "cast (lob as varchar(25)) AS LOB, " + |
| "{fn length(lob)} AS LOBLEN " + |
| "from charstream " + |
| "where id > ? order by 1"); |
| |
| // test setAsciiStream into CHAR |
| println("\nTest setAsciiStream into CHAR"); |
| psi.setString(1, null); |
| psi.setString(2, null); |
| psi.setString(3, null); |
| psi.setString(4, null); |
| int maxid = getMaxId(); |
| setAscii(psi, col); |
| psq.setInt(1, maxid); |
| verifyAsciiStreamResults(psq.executeQuery(), col); |
| |
| // Show results as various streams |
| PreparedStatement psStreams = prepareStatement( |
| "SELECT id, c, vc, lvc, lob " + |
| "FROM charstream where id > ? order by 1"); |
| psStreams.setInt(1, maxid); |
| verifyResultsUsingAsciiStream(psStreams.executeQuery(), col); |
| verifyResultsUsingCharacterStream(psStreams.executeQuery(), col); |
| verifyResultsUsingCharacterStreamBlock(psStreams.executeQuery(), col); |
| psStreams.close(); |
| |
| psi.close(); |
| psq.close(); |
| |
| } |
| private void runTestSetCharacterStream(int col) throws Exception { |
| PreparedStatement psi = prepareStatement( |
| "insert into charstream(c, vc, lvc, lob) " + |
| "values(?,?,?,?)"); |
| PreparedStatement psq = prepareStatement( |
| "select id, c, {fn length(c)} AS CLEN, " + |
| "cast (vc as varchar(25)) AS VC, " + |
| "{fn length(vc)} AS VCLEN, " + |
| "cast (lvc as varchar(25)) AS LVC, " + |
| "{fn length(lvc)} AS LVCLEN, " + |
| "cast (lob as varchar(25)) AS LOB, " + |
| "{fn length(lob)} AS LOBLEN " + |
| "from charstream " + |
| "where id > ? order by 1"); |
| |
| // test setCharacterStream into CHAR |
| println("\nTest setCharacterStream into CHAR"); |
| psi.setString(1, null); |
| psi.setString(2, null); |
| psi.setString(3, null); |
| psi.setString(4, null); |
| int maxid = getMaxId(); |
| setCharacter(psi, col); |
| psq.setInt(1, maxid); |
| verifyCharStreamResults(psq.executeQuery(), col); |
| |
| psi.close(); |
| psq.close(); |
| } |
| |
| private void runTestSetAsciiStreamLongValues() throws Exception { |
| // now insert long values using streams and check them programatically. |
| PreparedStatement psi = prepareStatement( |
| "insert into charstream(c, vc, lvc, lob) " + |
| "values(?,?,?,?)"); |
| PreparedStatement psDel = prepareStatement("DELETE FROM charstream"); |
| PreparedStatement psq2 = |
| prepareStatement("select c, vc, lvc, lob from charstream"); |
| |
| // now insert long values using streams and check them programatically. |
| println("setAsciiStream(LONG ASCII STREAMS)"); |
| checkAsciiStreams(psDel, psi, psq2, 18, 104, 67, 67); |
| checkAsciiStreams(psDel, psi, psq2, 25, 16732, 14563, 14563); |
| checkAsciiStreams(psDel, psi, psq2, 1, 32433, 32673, 32673); |
| checkAsciiStreams(psDel, psi, psq2, 0, 32532, 32700, 32700); |
| |
| psi.close(); |
| psDel.close(); |
| psq2.close(); |
| } |
| |
| private void runTestSetCharacterStreamLongValues() throws Exception { |
| // now insert long values using streams and check them programatically. |
| PreparedStatement psi = prepareStatement( |
| "insert into charstream(c, vc, lvc, lob) " + |
| "values(?,?,?,?)"); |
| PreparedStatement psDel = prepareStatement("DELETE FROM charstream"); |
| PreparedStatement psqSQLLength = prepareStatement( |
| "select length(c), length(vc), length(lvc), length(lob) " + |
| "from charstream"); |
| PreparedStatement psq2 = |
| prepareStatement("select c, vc, lvc, lob from charstream"); |
| |
| println("setCharacterStream(LONG CHARACTER STREAMS WITH UNICODE)"); |
| checkCharacterStreams( |
| psDel, psi, psq2, psqSQLLength, 14, 93, 55, 55, 0); |
| checkCharacterStreams( |
| psDel, psi, psq2, psqSQLLength, 21, 10887, 10887, 10887, 3); |
| checkCharacterStreams( |
| psDel, psi, psq2, psqSQLLength, 25, 19332, 18733, 18733, 0); |
| checkCharacterStreams( |
| psDel, psi, psq2, psqSQLLength, 1, 32433, 32673, 32673, 0); |
| checkCharacterStreams( |
| psDel, psi, psq2, psqSQLLength, 0, 32532, 32700, 32700, 0); |
| |
| psi.close(); |
| psDel.close(); |
| psq2.close(); |
| } |
| |
| private int getMaxId() throws SQLException { |
| |
| Statement stmt = createStatement(); |
| ResultSet rs = stmt.executeQuery("select max(id) from charstream"); |
| rs.next(); |
| int maxid = rs.getInt(1); |
| rs.close(); |
| stmt.close(); |
| return maxid; |
| } |
| |
| private void setAscii(PreparedStatement ps, int targetCol) |
| throws Exception { |
| byte[] asciiBytes = null; |
| // correct byte count |
| println("CORRECT NUMBER OF BYTES IN STREAM"); |
| asciiBytes = ASCII_VALUE.getBytes("US-ASCII"); |
| ps.setAsciiStream(targetCol, |
| new ByteArrayInputStream(asciiBytes), LEN_ASCII_VALUE); |
| ps.executeUpdate(); |
| |
| // less bytes than stream contains. JDBC 3.0 indicates it should throw |
| // an exception (in Tutorial & reference book) |
| println("MORE BYTES IN STREAM THAN PASSED IN VALUE"); |
| try { |
| asciiBytes = "against Republicans George W. Bush ". |
| getBytes("US-ASCII"); |
| ps.setAsciiStream(targetCol, |
| new ByteArrayInputStream(asciiBytes), 19); |
| ps.executeUpdate(); |
| fail("FAIL - MORE BYTES IN ASCII STREAM THAN SPECIFIED LENGTH"); |
| } catch (SQLException sqle) { |
| assertSQLState("XJ001", sqle); |
| } |
| |
| // more bytes than the stream contains JDBC 3.0 changed to indicate an |
| // exception should be thrown. (in Tutorial & reference book) |
| println("LESS BYTES IN STREAM THAN PASSED IN VALUE"); |
| try { |
| asciiBytes = "and Dick Cheney.".getBytes("US-ASCII"); |
| ps.setAsciiStream(targetCol, |
| new ByteArrayInputStream(asciiBytes), 17); |
| ps.executeUpdate(); |
| fail("FAIL - LESS BYTES IN ASCII STREAM THAN SPECIFIED LENGTH"); |
| } catch (SQLException sqle) { |
| assertSQLState("XJ001", sqle); |
| } |
| |
| // null |
| println("NULL ASCII STREAM"); |
| ps.setAsciiStream(targetCol, null, 1); |
| ps.executeUpdate(); |
| |
| } |
| |
| private void setCharacter(PreparedStatement ps, int targetCol) |
| throws Exception { |
| Reader reader = null; |
| |
| // correct character count |
| reader = new StringReader(CHAR_VALUE1); |
| ps.setCharacterStream(targetCol, reader, LEN_CHAR_VALUE1); |
| ps.executeUpdate(); |
| |
| reader = new StringReader(CHAR_VALUE2); |
| ps.setCharacterStream(targetCol, reader, LEN_CHAR_VALUE2); |
| ps.executeUpdate(); |
| |
| // less bytes than stream contains. |
| try { |
| reader = new StringReader("for comments he made at"); |
| ps.setCharacterStream(targetCol, reader, 20); |
| ps.executeUpdate(); |
| fail("FAIL - MORE CHARACTERS IN READER THAN SPECIFIED LENGTH"); |
| } catch (SQLException sqle) { |
| assertSQLState("XJ001", sqle); |
| } |
| |
| // more bytes than the stream contains, |
| // JDBC 3.0 changed to indicate an exception should be thrown. |
| try { |
| reader = new StringReader("a birthday party"); |
| ps.setCharacterStream(targetCol, reader, 17); |
| ps.executeUpdate(); |
| fail("FAIL - LESS CHARACTERS IN READER THAN SPECIFIED LENGTH"); |
| } catch (SQLException sqle) { |
| assertSQLState("XJ001", sqle); |
| } |
| |
| // null |
| ps.setCharacterStream(targetCol, null, 1); |
| ps.executeUpdate(); |
| } |
| |
| private void verifyAsciiStreamResults(ResultSet rs, int col) |
| throws Exception |
| { |
| String value; |
| int length; |
| |
| // First row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col * 2); |
| assertFalse("FAIL - value should not be null", rs.wasNull()); |
| length = rs.getInt((col * 2) + 1); |
| assertFalse("FAIL - length should not be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, |
| ASCII_VALUE, value.trim()); |
| assertEquals("FAIL - wrong length " + col, LEN_ASCII_VALUE, length); |
| |
| // null row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col * 2); |
| assertTrue("FAIL - value should be null", rs.wasNull()); |
| length = rs.getInt((col * 2) + 1); |
| assertTrue("FAIL - length should be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, null, value); |
| assertEquals("FAIL - wrong length " + col, 0, length); |
| |
| assertFalse("FAIL - more rows than expected", rs.next()); |
| } |
| |
| private void verifyCharStreamResults(ResultSet rs, int col) |
| throws Exception { |
| String value; |
| int length; |
| |
| // First row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col * 2); |
| assertFalse("FAIL - value should not be null", rs.wasNull()); |
| length = rs.getInt((col * 2) + 1); |
| assertFalse("FAIL - length should not be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, |
| CHAR_VALUE1, value.trim()); |
| assertEquals("FAIL - wrong length " + col, LEN_CHAR_VALUE1, length); |
| |
| // Second row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col * 2); |
| assertFalse("FAIL - value should not be null", rs.wasNull()); |
| length = rs.getInt((col * 2) + 1); |
| assertFalse("FAIL - length should not be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, |
| CHAR_VALUE2, value.trim()); |
| assertEquals("FAIL - wrong length " + col, LEN_CHAR_VALUE2, length); |
| |
| // null row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col * 2); |
| assertTrue("FAIL - value should be null", rs.wasNull()); |
| length = rs.getInt((col * 2) + 1); |
| assertTrue("FAIL - length should be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, null, value); |
| assertEquals("FAIL - wrong length " + col, 0, length); |
| |
| assertFalse("FAIL - more rows than expected", rs.next()); |
| rs.close(); |
| } |
| |
| private void verifyResultsUsingAsciiStream(ResultSet rs, int col) |
| throws Exception |
| { |
| InputStream valueStream; |
| String value; |
| |
| // First row |
| assertTrue("FAIL - row not found", rs.next()); |
| valueStream = rs.getAsciiStream(col + 1); |
| assertFalse("FAIL - value should not be null", rs.wasNull()); |
| |
| byte[] valueBytes = new byte[LEN_ASCII_VALUE]; |
| assertEquals("FAIL - wrong length read from stream", LEN_ASCII_VALUE, |
| valueStream.read(valueBytes)); |
| assertEquals("FAIL - wrong value on column " + col, |
| ASCII_VALUE, new String(valueBytes, "US-ASCII")); |
| |
| // null row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col + 1); |
| assertTrue("FAIL - value should be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, null, value); |
| |
| assertFalse("FAIL - more rows than expected", rs.next()); |
| rs.close(); |
| } |
| |
| private void verifyResultsUsingCharacterStream(ResultSet rs, int col) |
| throws Exception |
| { |
| Reader valueReader; |
| String value; |
| |
| // First row |
| assertTrue("FAIL - row not found", rs.next()); |
| // Read characters one by one |
| valueReader = rs.getCharacterStream(col + 1); |
| StringBuffer sb = new StringBuffer(); |
| int c = 0; |
| while ((c = valueReader.read()) != -1) { |
| sb.append((char)c); |
| } |
| value = sb.toString().trim(); |
| assertEquals("FAIL - wrong length read from stream", LEN_ASCII_VALUE, |
| value.length()); |
| assertEquals("FAIL - wrong value on column " + col, |
| ASCII_VALUE, value); |
| |
| // null row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col + 1); |
| assertTrue("FAIL - value should be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, null, value); |
| |
| assertFalse("FAIL - more rows than expected", rs.next()); |
| rs.close(); |
| } |
| |
| private void verifyResultsUsingCharacterStreamBlock(ResultSet rs, int col) |
| throws Exception |
| { |
| Reader valueReader; |
| String value; |
| |
| // First row |
| assertTrue("FAIL - row not found", rs.next()); |
| valueReader = rs.getCharacterStream(col + 1); |
| assertFalse("FAIL - value should not be null", rs.wasNull()); |
| // Read all characters in a block |
| char[] valueChars = new char[LEN_ASCII_VALUE]; |
| assertEquals("FAIL - wrong length read from stream", LEN_ASCII_VALUE, |
| valueReader.read(valueChars)); |
| assertEquals("FAIL - wrong value on column " + col, |
| ASCII_VALUE, new String(valueChars)); |
| |
| // null row |
| assertTrue("FAIL - row not found", rs.next()); |
| value = rs.getString(col + 1); |
| assertTrue("FAIL - value should be null", rs.wasNull()); |
| |
| assertEquals("FAIL - wrong value on column " + col, null, value); |
| |
| assertFalse("FAIL - more rows than expected", rs.next()); |
| rs.close(); |
| } |
| |
| private void checkAsciiStreams( |
| PreparedStatement psDel, |
| PreparedStatement psi, |
| PreparedStatement psq2, |
| int cl, int vcl, int lvcl, int lob) |
| throws SQLException, IOException { |
| |
| psDel.executeUpdate(); |
| |
| // now insert long values using streams and check them programatically. |
| psi.setAsciiStream(1, new c3AsciiStream(cl), cl); |
| psi.setAsciiStream(2, new c3AsciiStream(vcl), vcl); |
| psi.setAsciiStream(3, new c3AsciiStream(lvcl), lvcl); |
| psi.setAsciiStream(4, new c3AsciiStream(lob), lob); |
| psi.executeUpdate(); |
| |
| ResultSet rs = psq2.executeQuery(); |
| rs.next(); |
| |
| InputStream is = rs.getAsciiStream(1); |
| checkAsciiStream(is, cl, 25); |
| |
| is = rs.getAsciiStream(2); |
| checkAsciiStream(is, vcl, -1); |
| |
| is = rs.getAsciiStream(3); |
| checkAsciiStream(is, lvcl, -1); |
| |
| is = rs.getAsciiStream(4); |
| checkAsciiStream(is, lob, -1); |
| |
| rs.close(); |
| |
| rs = psq2.executeQuery(); |
| rs.next(); |
| |
| Reader r = rs.getCharacterStream(1); |
| checkAsciiStream(r, cl, 25); |
| |
| r = rs.getCharacterStream(2); |
| checkAsciiStream(r, vcl, -1); |
| |
| r = rs.getCharacterStream(3); |
| checkAsciiStream(r, lvcl, -1); |
| |
| r = rs.getCharacterStream(4); |
| checkAsciiStream(r, lob, -1); |
| |
| rs.close(); |
| |
| // and check as Strings |
| rs = psq2.executeQuery(); |
| rs.next(); |
| |
| r = new StringReader(rs.getString(1)); |
| checkAsciiStream(r, cl, 25); |
| |
| r = new StringReader(rs.getString(2)); |
| checkAsciiStream(r, vcl, -1); |
| |
| r = new StringReader(rs.getString(3)); |
| checkAsciiStream(r, lvcl, -1); |
| |
| r = new StringReader(rs.getString(4)); |
| checkAsciiStream(r, lob, -1); |
| |
| rs.close(); |
| } |
| |
| private Reader getSourceStream(int length, int bytesPerChar) { |
| switch (bytesPerChar) { |
| case 0: |
| return new c3Reader(length); |
| case 1: |
| return new LoopingAlphabetReader(length, |
| CharAlphabet.modernLatinLowercase()); |
| case 2: |
| return new LoopingAlphabetReader(length, |
| CharAlphabet.tamil()); |
| case 3: |
| return new LoopingAlphabetReader(length, |
| CharAlphabet.cjkSubset()); |
| default: |
| fail("Illegal value of bytesPerChar: " + bytesPerChar); |
| return null; |
| } |
| } |
| |
| private void checkCharacterStreams( |
| PreparedStatement psDel, |
| PreparedStatement psi, |
| PreparedStatement psq2, |
| PreparedStatement psqSQLLength, |
| int cl, int vcl, int lvcl, int lob, |
| int bytesPerChar) |
| throws SQLException, IOException { |
| psDel.executeUpdate(); |
| |
| psi.setCharacterStream(1, getSourceStream(cl, bytesPerChar), cl); |
| psi.setCharacterStream(2, getSourceStream(vcl, bytesPerChar), vcl); |
| psi.setCharacterStream(3, getSourceStream(lvcl, bytesPerChar), lvcl); |
| psi.setCharacterStream(4, getSourceStream(lob, bytesPerChar), lob); |
| psi.executeUpdate(); |
| |
| ResultSet rsLength = psqSQLLength.executeQuery(); |
| assertTrue(rsLength.next()); |
| assertEquals(25, rsLength.getInt(1)); // CHAR |
| assertEquals(vcl, rsLength.getInt(2)); // VARCHAR |
| assertEquals(lvcl, rsLength.getInt(3)); // LONG VARCHAR |
| assertEquals(lob, rsLength.getInt(4)); //CLOB |
| assertFalse(rsLength.next()); |
| rsLength.close(); |
| |
| ResultSet rs = psq2.executeQuery(); |
| rs.next(); |
| |
| InputStream is = rs.getAsciiStream(1); |
| checkCharStream(is, cl, 25, bytesPerChar); |
| |
| is = rs.getAsciiStream(2); |
| checkCharStream(is, vcl, -1, bytesPerChar); |
| |
| is = rs.getAsciiStream(3); |
| checkCharStream(is, lvcl, -1, bytesPerChar); |
| |
| is = rs.getAsciiStream(4); |
| checkCharStream(is, lob, -1, bytesPerChar); |
| |
| rs.close(); |
| |
| rs = psq2.executeQuery(); |
| rs.next(); |
| |
| Reader r = rs.getCharacterStream(1); |
| checkCharStream(r, cl, 25, bytesPerChar); |
| |
| r = rs.getCharacterStream(2); |
| checkCharStream(r, vcl, -1, bytesPerChar); |
| |
| r = rs.getCharacterStream(3); |
| checkCharStream(r, lvcl, -1, bytesPerChar); |
| |
| r = rs.getCharacterStream(4); |
| checkCharStream(r, lob, -1, bytesPerChar); |
| |
| rs.close(); |
| |
| // check converting them into Strings work |
| rs = psq2.executeQuery(); |
| rs.next(); |
| |
| String suv = rs.getString(1); |
| r = new StringReader(suv); |
| checkCharStream(r, cl, 25, bytesPerChar); |
| |
| suv = rs.getString(2); |
| r = new StringReader(suv); |
| checkCharStream(r, vcl, -1, bytesPerChar); |
| |
| suv = rs.getString(3); |
| r = new StringReader(suv); |
| checkCharStream(r, lvcl, -1, bytesPerChar); |
| |
| suv = rs.getString(4); |
| r = new StringReader(suv); |
| checkCharStream(r, lob, -1, bytesPerChar); |
| |
| rs.close(); |
| |
| } |
| |
| private void checkAsciiStream(InputStream is, int length, int fixedLen) |
| throws IOException |
| { |
| |
| InputStream orig = new c3AsciiStream(length); |
| |
| int count = 0; |
| for (;;) { |
| |
| int o = orig == null ? |
| (count == fixedLen ? -2 : 0x20) : orig.read(); |
| int c = is.read(); |
| if (o == -1) { |
| orig = null; |
| if (fixedLen != -1 && fixedLen != length) |
| o = ' '; |
| } |
| if (o == -2) |
| o = -1; |
| |
| assertEquals("FAIL - wrong value at position " + count, o, c); |
| if (orig == null) { |
| if (fixedLen == -1) |
| break; |
| } |
| |
| if (c == -1 && fixedLen != -1) |
| break; |
| |
| count++; |
| } |
| if (fixedLen != -1) |
| length = fixedLen; |
| |
| assertEquals("FAIL - wrong length", length, count); |
| is.close(); |
| } |
| |
| private void checkAsciiStream(Reader r, int length, int fixedLen) |
| throws IOException |
| { |
| |
| InputStream orig = new c3AsciiStream(length); |
| |
| int count = 0; |
| for (;;) { |
| |
| int o = orig == null ? |
| (count == fixedLen ? -2 : 0x20) : orig.read(); |
| int c = r.read(); |
| if (o == -1) { |
| orig = null; |
| if (fixedLen != -1 && fixedLen != length) |
| o = ' '; |
| } |
| if (o == -2) |
| o = -1; |
| |
| assertEquals("FAIL - wrong value", o, c); |
| if (orig == null) { |
| if (fixedLen == -1) |
| break; |
| } |
| |
| if (c == -1 && fixedLen != -1) |
| break; |
| |
| count++; |
| } |
| if (fixedLen != -1) |
| length = fixedLen; |
| |
| assertEquals("FAIL - wrong length", length, count); |
| r.close(); |
| } |
| |
| private void checkCharStream(InputStream is, int length, int fixedLen, |
| int bytesPerChar) |
| throws IOException |
| { |
| |
| Reader orig = getSourceStream(length, bytesPerChar); |
| |
| int count = 0; |
| for (;;) { |
| |
| int o = orig == null ? |
| (count == fixedLen ? -2 : 0x20) : orig.read(); |
| int c = is.read(); |
| if (o == -1) { |
| orig = null; |
| if (fixedLen != -1 && fixedLen != length) |
| o = ' '; |
| } |
| if (o == -2) |
| o = -1; |
| |
| if (o != -1) { |
| if (o <= 255) |
| o = o & 0xFF; // convert to single byte extended ASCII |
| else |
| o = '?'; // out of range character. |
| } |
| |
| assertEquals("FAIL - wrong value", o, c); |
| if (orig == null) { |
| if (fixedLen == -1) |
| break; |
| } |
| |
| if (c == -1 && fixedLen != -1) |
| break; |
| |
| count++; |
| } |
| if (fixedLen != -1) |
| length = fixedLen; |
| |
| assertEquals("FAIL - wrong length", length, count); |
| is.close(); |
| } |
| |
| private void checkCharStream(Reader r, int length, int fixedLen, |
| int bytesPerChar) |
| throws IOException |
| { |
| |
| Reader orig = getSourceStream(length, bytesPerChar); |
| |
| int count = 0; |
| for (;;) { |
| |
| int o = (orig == null) ? |
| (count == fixedLen ? -2 : 0x20) : orig.read(); |
| int c = r.read(); |
| if (o == -1) { |
| orig = null; |
| if (fixedLen != -1 && fixedLen != length) |
| o = ' '; |
| } |
| if (o == -2) |
| o = -1; |
| |
| assertEquals("FAIL - wrong value", o, c); |
| if (orig == null) { |
| if (fixedLen == -1) |
| break; |
| } |
| |
| if (c == -1 && fixedLen != -1) |
| break; |
| |
| count++; |
| } |
| if (fixedLen != -1) |
| length = fixedLen; |
| |
| assertEquals("FAIL - wrong length", length, count); |
| r.close(); |
| } |
| |
| |
| protected void setUp() throws Exception { |
| createStatement().executeUpdate( |
| "create table charstream(" + |
| "id int GENERATED ALWAYS AS IDENTITY primary key, " + |
| "c char(25), " + |
| "vc varchar(32532), " + |
| "lvc long varchar, " + |
| "lob clob(300K))"); |
| } |
| |
| protected void tearDown() throws Exception { |
| rollback(); |
| createStatement().executeUpdate("DROP TABLE charstream"); |
| commit(); |
| super.tearDown(); |
| } |
| |
| private final static String ASCII_VALUE = "Lieberman ran with Gore"; |
| private final static int LEN_ASCII_VALUE = 23; |
| |
| private final static String CHAR_VALUE1 = "A Mississippi Republican"; |
| private final static int LEN_CHAR_VALUE1 = 24; |
| |
| private final static String CHAR_VALUE2 = "Lott has apologized"; |
| private final static int LEN_CHAR_VALUE2 = 19; |
| |
| } |
| |
| |
| class c3AsciiStream extends InputStream { |
| |
| private final int size; |
| private int count; |
| c3AsciiStream(int size) { |
| this.size = size; |
| } |
| public int read(byte[] buf, int off, int length) { |
| if (count >= size) |
| return -1; |
| |
| if (length > (size - count)) |
| length = (size - count); |
| |
| // ensure the readers don't always get a full buffer, |
| // makes sure they are not assuming the buffer will be filled. |
| |
| if (length > 20) |
| length -= 17; |
| |
| for (int i = 0; i < length ; i++) { |
| buf[off + i] = (byte) count++; |
| } |
| |
| return length; |
| } |
| |
| private byte[] rd = new byte[1]; |
| public int read() { |
| |
| int read = read(rd, 0, 1); |
| if (read == -1) |
| return -1; |
| return rd[0] & 0xFF; |
| } |
| |
| public void close() { |
| } |
| } |
| |
| class c3Reader extends Reader { |
| |
| private final int size; |
| private int count; |
| c3Reader(int size) { |
| this.size = size; |
| } |
| public int read(char[] buf, int off, int length) { |
| if (count >= size) |
| return -1; |
| |
| if (length > (size - count)) |
| length = (size - count); |
| |
| // ensure the readers don't always get a full buffer, |
| // makes sure they are not assuming the buffer will be filled. |
| |
| if (length > 20) |
| length -= 17; |
| |
| for (int i = 0; i < length ; i++) { |
| char c; |
| switch (count % 3) { |
| case 0: |
| c = (char) (count & 0x7F); // one byte UTF8 |
| break; |
| case 1: |
| c = (char) ((count + 0x7F) & 0x07FF); // two byte UTF8 |
| break; |
| default: |
| case 2: |
| c = (char) (count + 0x07FF); // three byte UTF8 |
| break; |
| |
| } |
| buf[off + i] = c; |
| count++; |
| } |
| return length; |
| } |
| |
| public void close() { |
| } |
| } |