You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2007/04/13 18:23:23 UTC
svn commit: r528546 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ engine/org/apache/derby/loc/
shared/org/apache/derby/shared/common/reference/
testing/org/apache/derbyTesting/functionTests/tests/jdbc4/
Author: kahatlen
Date: Fri Apr 13 09:23:18 2007
New Revision: 528546
URL: http://svn.apache.org/viewvc?view=rev&rev=528546
Log:
DERBY-2444: Implement not implemented methods
Blob.getBinaryStream(long pos, long length) and
Clob.getCharacterStream(long pos, long length) in the Network Client
Patch contributed by V. Narayanan.
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/Lob.java
db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobClobTestSetup.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClobTest.java
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java Fri Apr 13 09:23:18 2007
@@ -520,9 +520,40 @@
}
}
+ /**
+ * Returns an <code>InputStream</code> object that contains a partial <code>
+ * Blob</code> value, starting with the byte specified by pos,
+ * which is length bytes in length.
+ *
+ * @param pos the offset to the first byte of the partial value to
+ * be retrieved. The first byte in the <code>Blob</code> is at position 1.
+ * @param length the length in bytes of the partial value to be retrieved
+ * @return <code>InputStream</code> through which the partial
+ * <code>Blob</code> value can be read.
+ * @throws SQLException if pos is less than 1 or if pos is greater than
+ * the number of bytes in the <code>Blob</code> or if pos + length is
+ * greater than the number of bytes in the <code>Blob</code>
+ *
+ * @throws SQLException.
+ */
public InputStream getBinaryStream(long pos, long length)
throws SQLException {
- throw SQLExceptionFactory.notImplemented("getBinaryStream(long,long)");
+ //call checkValidity to exit by throwing a SQLException if
+ //the Blob object has been freed by calling free() on it
+ checkValidity();
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "getBinaryStream",
+ (int) pos, length);
+ }
+ checkPosAndLength(pos, length);
+ InputStream retVal = new java.io.ByteArrayInputStream
+ (binaryString_, (int)(dataOffset_ + pos - 1), (int)length);
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceExit(this, "getBinaryStream", retVal);
+ }
+ return retVal;
+ }
}
//------------------ Material layer event callback methods -------------------
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java Fri Apr 13 09:23:18 2007
@@ -772,10 +772,50 @@
}
}
+ /**
+ * Returns a <code>Reader</code> object that contains a partial
+ * <code>Clob</code> value, starting with the character specified by pos,
+ * which is length characters in length.
+ *
+ * @param pos the offset to the first character of the partial value to
+ * be retrieved. The first character in the Clob is at position 1.
+ * @param length the length in characters of the partial value to be
+ * retrieved.
+ * @return <code>Reader</code> through which the partial <code>Clob</code>
+ * value can be read.
+ * @throws SQLException if pos is less than 1 or if pos is greater than the
+ * number of
+ * characters in the <code>Clob</code> or if pos + length is greater than
+ * the number of
+ * characters in the <code>Clob</code>
+ *
+ * @throws SQLException.
+ */
public Reader getCharacterStream(long pos, long length)
throws SQLException {
- throw SQLExceptionFactory.notImplemented(
- "getCharacterStream(long,long");
+ //call checkValidity to exit by throwing a SQLException if
+ //the Clob object has been freed by calling free() on it
+ checkValidity();
+
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "getCharacterStream",
+ (int) pos, length);
+ }
+ checkPosAndLength(pos, length);
+ String retVal_str = null;
+ try {
+ retVal_str = getSubStringX(pos, (int)length);
+ }
+ catch(SqlException sqle) {
+ throw sqle.getSQLException();
+ }
+ Reader retVal = new java.io.StringReader(retVal_str);
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceExit(this, "getCharacterStream", retVal);
+ }
+ return retVal;
+ }
}
//----------------------------helper methods----------------------------------
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Lob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Lob.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Lob.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Lob.java Fri Apr 13 09:23:18 2007
@@ -212,4 +212,38 @@
return willBeLayerBStreamed_;
}
+ /**
+ * Checks the <code>pos</code> and <code>length</code>.
+ *
+ * @param pos a long that contains the position that needs to be checked
+ * @param length a long that contains the length that needs to be checked
+ * @throws SQLException if
+ * a) pos <= 0
+ * b) pos > (length of LOB)
+ * c) length < 0
+ * d) pos + length > (length of LOB)
+ */
+ protected void checkPosAndLength(long pos, long length)
+ throws SQLException {
+ if (pos <= 0) {
+ throw new SqlException(agent_.logWriter_,
+ new ClientMessageId(SQLState.BLOB_BAD_POSITION),
+ new Long(pos)).getSQLException();
+ }
+ if (pos > this.length()) {
+ throw new SqlException(agent_.logWriter_,
+ new ClientMessageId(SQLState.BLOB_POSITION_TOO_LARGE),
+ new Long(pos)).getSQLException();
+ }
+ if (length < 0) {
+ throw new SqlException(agent_.logWriter_,
+ new ClientMessageId(SQLState.BLOB_NONPOSITIVE_LENGTH),
+ new Integer((int)length)).getSQLException();
+ }
+ if ((pos + length) > this.length()) {
+ throw new SqlException(agent_.logWriter_,
+ new ClientMessageId(SQLState.POS_AND_LENGTH_GREATER_THAN_LOB),
+ new Long(pos), new Long(length)).getSQLException();
+ }
+ }
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Fri Apr 13 09:23:18 2007
@@ -4217,6 +4217,13 @@
</msg>
<msg>
+ <name>XJ087.S</name>
+ <text>Sum of position('{0}') and length('{1}') is greater than the size of the LOB.</text>
+ <arg>pos</arg>
+ <arg>length</arg>
+ </msg>
+
+ <msg>
<name>XJ088.S</name>
<text>Invalid operation: wasNull() called with no data retrieved.</text>
</msg>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Apr 13 09:23:18 2007
@@ -1457,6 +1457,7 @@
String COLUMN_NOT_FROM_BASE_TABLE = "XJ084.U";
String STREAM_EOF = "XJ085.S";
String CURSOR_NOT_POSITIONED_ON_INSERT_ROW = "XJ086.S";
+ String POS_AND_LENGTH_GREATER_THAN_LOB = "XJ087.S";
String WASNULL_INVALID = "XJ088.S";
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobClobTestSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobClobTestSetup.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobClobTestSetup.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobClobTestSetup.java Fri Apr 13 09:23:18 2007
@@ -46,6 +46,12 @@
public static final int ID_NULLVALUES = 1;
/** Constant for accessing the row with sample values. */
public static final int ID_SAMPLEVALUES = 2;
+ /**
+ * ID is used to store the latest unique value for the ID column
+ * Start from 3 since 1 is used for null values and 2 is used for
+ * sample values.
+ */
+ public static int ID = 3;
/** Blob data. */
private static final byte[] blobData = new byte[] {
@@ -155,6 +161,14 @@
rs.close();
stmt.close();
return clob;
+ }
+
+ /**
+ * Returns new unique ID values that can be used in these tests.
+ * @return an integer that represents an unique ID value.
+ */
+ public static int getID() {
+ return ID++;
}
} // End class BlobClobTestSetup
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java Fri Apr 13 09:23:18 2007
@@ -374,10 +374,143 @@
fail("Don't know how to handle type " + type);
return null; // unreachable statement
}
+
+ /**
+ * Tests the implementation of the method
+ * getBinaryStream(long pos, long length)
+ * in the NetworkClient.
+ *
+ * @throws Exception
+ */
+ public void clientTestGetBinaryStreamLong()
+ throws Exception {
+ byte[] BYTES1 = {
+ 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x69, 0x68, 0x67, 0x66, 0x65
+ };
+
+ InputStream is = new java.io.ByteArrayInputStream(BYTES1);
+
+ PreparedStatement ps = prepareStatement(
+ "insert into BLOBCLOB(ID, BLOBDATA) values(?,?)");
+ int id = BlobClobTestSetup.getID();
+ ps.setInt(1,id);
+ ps.setBinaryStream(2,is);
+ ps.execute();
+ ps.close();
+
+ Statement st = createStatement();
+
+ ResultSet rs = st.executeQuery("select BLOBDATA from " +
+ "BLOBCLOB where ID="+id);
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ InputStream is_1 = blob.getBinaryStream(2L,5L);
+ InputStream is_2 = new java.io.ByteArrayInputStream(BYTES1,1,5);
+
+ rs.close();
+ st.close();
+
+ assertEquals(is_2,is_1);
+ }
+ /**
+ * Tests the exceptions thrown by the getBinaryStream
+ * (long pos, long length) for the following conditions
+ * a) pos <= 0
+ * b) pos > (length of LOB)
+ * c) length < 0
+ * d) pos + length > (length of LOB).
+ *
+ * @throws SQLException.
+ */
+ public void clientTestGetBinaryStreamLongExceptionConditions()
+ throws SQLException {
+ byte[] BYTES1 = {
+ 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x69, 0x68, 0x67, 0x66, 0x65
+ };
+
+ InputStream is = new java.io.ByteArrayInputStream(BYTES1);
+
+ PreparedStatement ps = prepareStatement(
+ "insert into BLOBCLOB(ID, BLOBDATA) values(?,?)");
+ int id = BlobClobTestSetup.getID();
+ ps.setInt(1,id);
+ ps.setBinaryStream(2,is);
+ ps.execute();
+ ps.close();
+
+ Statement st = createStatement();
+
+ ResultSet rs = st.executeQuery("select BLOBDATA from " +
+ "BLOBCLOB where ID="+id);
+ rs.next();
+ Blob blob = rs.getBlob(1);
+ // check the case where pos <= 0
+ try {
+ // set pos as negative
+ blob.getBinaryStream(-2L,5L);
+ //Should not come here. The exception has to be thrown.
+ fail("FAIL: Expected SQLException for pos being negative " +
+ "not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when pos <= 0 is XJ070
+ assertSQLState("XJ070", sqle);
+ }
+
+ // check for the case pos > length of Blob
+ try {
+ // set the pos to any value greater than the Blob length
+ blob.getBinaryStream(blob.length()+1, 5L);
+ //Should not come here. The exception has to be thrown.
+ fail("FAIL: Expected SQLException for position being greater than " +
+ "length of LOB not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when pos > length of Blob
+ // is XJ076
+ assertSQLState("XJ076", sqle);
+ }
+
+ //check for the case when length < 0
+ try {
+ // set length as negative
+ blob.getBinaryStream(2L, -5L);
+ // Should not come here. The exception has to be thrown.
+ fail("Fail: expected exception for the length being negative " +
+ "not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when length < 0 of Blob
+ // is XJ071
+ assertSQLState("XJ071", sqle);
+ }
+
+ //check for the case when pos + length > length of Blob
+ try {
+ // set pos + length > length of Blob
+ blob.getBinaryStream((blob.length() - 4), 10L);
+ // Should not come here. The exception has to be thrown.
+ fail("Fail: expected exception for the sum of position and length" +
+ " being greater than the LOB size not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when length < 0 of Blob
+ // is XJ087
+ assertSQLState("XJ087", sqle);
+ }
+ }
+
- public void testGetBinaryStringLongNotImplemented()
- throws SQLException {
+ /**
+ * Tests the getBinaryStream(long pos, long length) on the Embedded side.
+ * @throws SQLException
+ */
+ public void embeddedTestGetBinaryStringLongNotImplemented()
+ throws SQLException {
try {
blob.getBinaryStream(5l, 10l);
fail("Blob.getBinaryStream(long,long) should not be implemented");
@@ -390,13 +523,23 @@
* Create test suite for this test.
*/
public static Test suite() {
- TestSuite suite = new TestSuite("BlobTest suite");
- suite.addTest(new BlobClobTestSetup(
- new TestSuite(BlobTest.class, "BlobTest:embedded")));
- suite.addTest(TestConfiguration.clientServerDecorator(
- new BlobClobTestSetup(new TestSuite(BlobTest.class,
- "BlobTest:client"))));
- return suite;
+ TestSuite btSuite = new TestSuite("BlobTest suite");
+
+ TestSuite embedded = new TestSuite("BlobTest:embedded");
+ embedded.addTestSuite(BlobTest.class);
+ embedded.addTest(new BlobTest(
+ "embeddedTestGetBinaryStringLongNotImplemented"));
+ btSuite.addTest(new BlobClobTestSetup(embedded));
+
+ TestSuite client = new TestSuite("BlobTest:client");
+ client.addTestSuite(BlobTest.class);
+ client.addTest(new BlobTest("clientTestGetBinaryStreamLong"));
+ client.addTest(new BlobTest("clientTestGetBinaryStreamLong" +
+ "ExceptionConditions"));
+ btSuite.addTest(TestConfiguration.clientServerDecorator(
+ new BlobClobTestSetup(client)));
+
+ return btSuite;
}
} // End class BlobTest
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClobTest.java?view=diff&rev=528546&r1=528545&r2=528546
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClobTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClobTest.java Fri Apr 13 09:23:18 2007
@@ -375,8 +375,14 @@
return null; // unreachable statement
}
- public void testGetCharacterStreamLongNotImplemented()
- throws SQLException {
+ /**
+ * Tests the getCharacterStream(long pos, long length) on the
+ * Embedded side.
+ *
+ * @throws SQLException
+ */
+ public void embeddedTestGetCharacterStreamLongNotImplemented()
+ throws SQLException {
try {
clob.getCharacterStream(5l, 10l);
fail("Clob.getCharacterStream(long,long)" +
@@ -387,16 +393,149 @@
}
/**
+ * Tests the implementation of getCharacterStream(long pos, long length)
+ * in the NetworkClient.
+ * @throws Exception
+ */
+ public void clientTestGetCharacterStreamLong()
+ throws Exception {
+ String str1 = "This is a test String. This is a test String";
+
+ Reader r1 = new java.io.StringReader(str1);
+
+ PreparedStatement ps = prepareStatement(
+ "insert into BLOBCLOB(ID, CLOBDATA) values(?,?)");
+ int id = BlobClobTestSetup.getID();
+ ps.setInt(1,id);
+ ps.setCharacterStream(2,r1);
+ ps.execute();
+ ps.close();
+
+ Statement st = createStatement();
+
+ ResultSet rs = st.executeQuery("select CLOBDATA from " +
+ "BLOBCLOB where ID="+id);
+ rs.next();
+ Clob clob = rs.getClob(1);
+
+ Reader r_1 = clob.getCharacterStream(2L,5L);
+ String str2 = str1.substring(1,6);
+ Reader r_2 = new java.io.StringReader(str2);
+
+ rs.close();
+ st.close();
+
+ assertEquals(r_2,r_1);
+ }
+
+ /**
+ * Tests the exceptions thrown by the getCharacterStream
+ * (long pos, long length) for the following conditions
+ * a) pos <= 0
+ * b) pos > (length of LOB)
+ * c) length < 0
+ * d) pos + length > (length of LOB).
+ *
+ * @throws SQLException.
+ */
+ public void clientTestGetCharacterStreamLongExceptionConditions()
+ throws SQLException {
+ String str1 = "This is a test String. This is a test String";
+
+ Reader r1 = new java.io.StringReader(str1);
+
+ PreparedStatement ps = prepareStatement(
+ "insert into BLOBCLOB(ID, CLOBDATA) values(?,?)");
+ int id = BlobClobTestSetup.getID();
+ ps.setInt(1,id);
+ ps.setCharacterStream(2,r1);
+ ps.execute();
+ ps.close();
+
+ Statement st = createStatement();
+
+ ResultSet rs = st.executeQuery("select CLOBDATA from " +
+ "BLOBCLOB where ID="+id);
+ rs.next();
+ Clob clob = rs.getClob(1);
+ // check the case where pos <= 0
+ try {
+ // set pos as negative
+ clob.getCharacterStream(-2L,5L);
+ //Should not come here. The exception has to be thrown.
+ fail("FAIL: Expected SQLException for pos being negative " +
+ "not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when pos <= 0 is XJ070
+ assertSQLState("XJ070", sqle);
+ }
+
+ // check for the case pos > length of clob
+ try {
+ // set the pos to any value greater than the Clob length
+ clob.getCharacterStream(clob.length()+1, 5L);
+ //Should not come here. The exception has to be thrown.
+ fail("FAIL: Expected SQLException for position being greater than " +
+ "length of LOB not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when pos > length of Clob
+ // is XJ076
+ assertSQLState("XJ076", sqle);
+ }
+
+ //check for the case when length < 0
+ try {
+ // set length as negative
+ clob.getCharacterStream(2L, -5L);
+ // Should not come here. The exception has to be thrown.
+ fail("Fail: expected exception for the length being negative " +
+ "not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when length < 0 of Clob
+ // is XJ071
+ assertSQLState("XJ071", sqle);
+ }
+
+ //check for the case when pos + length > length of Clob
+ try {
+ // set pos + length > length of Clob
+ clob.getCharacterStream((clob.length() - 4), 10L);
+ // Should not come here. The exception has to be thrown.
+ fail("Fail: expected exception for the sum of position and length" +
+ " being greater than the LOB size not thrown");
+ }
+ catch(SQLException sqle) {
+ // The SQLState for the exception thrown when length < 0 of Clob
+ // is XJ087
+ assertSQLState("XJ087", sqle);
+ }
+ }
+
+
+ /**
* Create test suite for this test.
*/
public static Test suite() {
- TestSuite suite = new TestSuite("ClobTest suite");
- suite.addTest(new BlobClobTestSetup(
- new TestSuite(ClobTest.class, "ClobTest:embedded")));
- suite.addTest(TestConfiguration.clientServerDecorator(
- new BlobClobTestSetup(new TestSuite(ClobTest.class,
- "ClobTest:client"))));
- return suite;
+ TestSuite ctSuite = new TestSuite("ClobTest suite");
+
+ TestSuite embedded = new TestSuite("ClobTest:embedded");
+ embedded.addTestSuite(ClobTest.class);
+ embedded.addTest(new ClobTest(
+ "embeddedTestGetCharacterStreamLongNotImplemented"));
+ ctSuite.addTest(new BlobClobTestSetup(embedded));
+
+ TestSuite client = new TestSuite("ClobTest:client");
+ client.addTestSuite(ClobTest.class);
+ client.addTest(new ClobTest("clientTestGetCharacterStreamLong"));
+ client.addTest(new ClobTest("clientTestGetCharacterStreamLong" +
+ "ExceptionConditions"));
+ ctSuite.addTest(TestConfiguration.clientServerDecorator(
+ new BlobClobTestSetup(client)));
+
+ return ctSuite;
}
} // End class ClobTest