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 kr...@apache.org on 2008/10/31 11:29:52 UTC
svn commit: r709375 - in /db/derby/code/branches/10.4/java:
engine/org/apache/derby/impl/jdbc/ testing/org/apache/derby/impl/jdbc/
testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/
Author: kristwaa
Date: Fri Oct 31 03:29:46 2008
New Revision: 709375
URL: http://svn.apache.org/viewvc?rev=709375&view=rev
Log:
DERBY-3793: Remove unnecessary methods from InternalClob interface.
Backported revisions 678724 (1b) and 691608 (2b) to 10.4.
Had to do one minor manual change, because TestConfiguration.setAutoCommit(boolean) doesn't exist in 10.4.
Modified:
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/ClobUpdatableReader.java
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/InternalClob.java
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/StoreStreamClob.java
db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java
db/derby/code/branches/10.4/java/testing/org/apache/derby/impl/jdbc/InternalClobTest.java
db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ClobTest.java
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/ClobUpdatableReader.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/ClobUpdatableReader.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/ClobUpdatableReader.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/ClobUpdatableReader.java Fri Oct 31 03:29:46 2008
@@ -114,7 +114,6 @@
InternalClob internalClob = clob.getInternalClob();
materialized = internalClob.isWritable();
if (materialized) {
- long byteLength = internalClob.getByteLength();
this.stream = internalClob.getRawByteStream();
// Position the stream on pos using the init method.
init ((LOBInputStream)stream, pos);
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/InternalClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/InternalClob.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/InternalClob.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/InternalClob.java Fri Oct 31 03:29:46 2008
@@ -40,31 +40,6 @@
interface InternalClob {
/**
- * Gets the number of bytes contained in the Clob.
- *
- * @return Number of bytes in the Clob.
- * @throws IOException if accessing underlying I/O resources fail
- * @throws SQLException if accessing underlying resources fail
- */
- long getByteLength() throws IOException, SQLException;
-
- /**
- * Obtains the byte position for the given character position.
- * <p>
- * The range of valid character positions is
- * <code>1 - Clob.getCharLength() +1</code>, inclusive. The upper bound is
- * used when appending to the Clob. Note that specifying a character
- * position that is more than one longer than the Clob raises an exception.
- *
- * @param charPos character position. The first position is <code>1</code>.
- * @return A 0-based byte position.
- * @throws EOFException if the position is bigger than the Clob
- * @throws IOException if accessing the underlying I/O resources fail
- * @throws SQLException if the specified character position is invalid
- */
- long getBytePosition(long charPos) throws IOException, SQLException;
-
- /**
* Gets the number of characters in the Clob.
*
* @return Number of characters in the Clob.
@@ -81,10 +56,15 @@
* stream, it is up to the Clob representation which one it uses.
* <p>
* This stream may be an internal store stream, and should not be directly
- * published to the end user (returned through the JDBC API). There are two
- * motivations for this; the stream may be closed by the end user when it is
- * not supposed to, and operations on the stream might throw exceptions we
- * do not want to present to the end user unwrapped.
+ * published to the end user (returned through the JDBC API). There are
+ * three reasons for this:
+ * <ul> <li>the stream may be closed by the end user when it is
+ * not supposed to</li>
+ * <li>operations on the stream might throw exceptions we don't want to
+ * present to the end user unwrapped</li>
+ * <li>the stream may contain a Derby specific end-of-stream marker
+ * </li>
+ * </ul>
* <p>
* The primary use of this method is to clone the Clob contents without
* going via char (or String). Make sure the clone uses the same encoding
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java Fri Oct 31 03:29:46 2008
@@ -357,8 +357,14 @@
/**
* Copies bytes from stream to local storage.
- * @param inStream
- * @param length length to be copied
+ * <p>
+ * Note that specifying the length as {@code Long.MAX_VALUE} results in
+ * reading data from the stream until EOF is reached, but no length checking
+ * will be performed.
+ *
+ * @param inStream the stream to copy from
+ * @param length number of bytes to be copied, or {@code Long.MAX_VALUE} to
+ * copy everything until EOF is reached
* @throws IOException, StandardException
*/
synchronized void copyData(InputStream inStream, long length)
@@ -368,12 +374,31 @@
while (sz < length) {
int len = (int) Math.min (length - sz, bufferSize);
len = inStream.read(data, 0, len);
- if (len < 0)
- throw new EOFException("Reached end-of-stream " +
- "prematurely at " + sz);
+ if (len == -1) {
+ if (length != Long.MAX_VALUE) {
+ // We reached EOF before all the requested bytes are read.
+ throw new EOFException("Reached end-of-stream " +
+ "prematurely at " + sz + ", expected " + length);
+ } else {
+ // End of data, but no length checking.
+ break;
+ }
+ }
write(data, 0, len, sz);
sz += len;
}
+ // If we copied until EOF, see if we have a Derby end-of-stream marker.
+ if (length == Long.MAX_VALUE) {
+ long curLength = getLength();
+ byte[] eos = new byte[3];
+ // Read the three last bytes, marker is 0xE0 0x00 0x00.
+ read(eos, 0, 3, curLength -3);
+ if ((eos[0] & 0xFF) == 0xE0 && (eos[1] & 0xFF) == 0x00 &&
+ (eos[2] & 0xFF) == 0x00) {
+ // Remove Derby end-of-stream-marker.
+ truncate(curLength -3);
+ }
+ }
}
protected void finalize() throws Throwable {
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/StoreStreamClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/StoreStreamClob.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/StoreStreamClob.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/StoreStreamClob.java Fri Oct 31 03:29:46 2008
@@ -53,9 +53,6 @@
final class StoreStreamClob
implements InternalClob {
- /** Maximum value used when requesting bytes/chars to be skipped. */
- private static final long SKIP_BUFFER_SIZE = 8*1024; // 8 KB
-
/** Tells whether this Clob has been released or not. */
private volatile boolean released = false;
@@ -113,45 +110,6 @@
}
/**
- * Returns the number of bytes in the Clob.
- *
- * @return The number of bytes in the Clob.
- * @throws IOException if accessing the I/O resources fail
- * @throws SQLException if accessing the store resources fail
- */
- public long getByteLength()
- throws IOException, SQLException {
- checkIfValid();
- // Read through the whole stream to get the length.
- long byteLength = 0;
- try {
- this.conChild.setupContextStack();
- this.positionedStoreStream.reposition(0L);
- // See if length is encoded in the stream.
- int us1 = this.positionedStoreStream.read();
- int us2 = this.positionedStoreStream.read();
- byteLength = (us1 << 8) + (us2 << 0);
- if (byteLength == 0) {
- while (true) {
- long skipped =
- this.positionedStoreStream.skip(SKIP_BUFFER_SIZE);
- if (skipped <= 0) {
- break;
- }
- byteLength += skipped;
- }
- // Subtract 3 bytes for the end-of-stream marker.
- byteLength -= 3;
- }
- return byteLength;
- } catch (StandardException se) {
- throw Util.generateCsSQLException(se);
- } finally {
- this.conChild.restoreContextStack();
- }
- }
-
- /**
* Returns the number of characters in the Clob.
*
* @return Number of characters in the Clob.
@@ -234,20 +192,6 @@
}
/**
- * Returns the byte position for the specified character position.
- *
- * @param charPos character position. First character is at position 1.
- * @return Corresponding byte position. First byte is at position 0.
- * @throws EOFException if the position is bigger then the Clob
- * @throws IOException if accessing the underlying I/O resources fail
- * @throws SQLException if accessing the underlying store resources fail
- */
- public long getBytePosition(long charPos)
- throws IOException, SQLException {
- return UTF8Util.skipFully(getRawByteStream(), charPos -1);
- }
-
- /**
* Not supported.
*
* @see InternalClob#getWriter
Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java Fri Oct 31 03:29:46 2008
@@ -170,9 +170,9 @@
* the Clob length +1
* @throws IOException if accessing underlying I/O resources fail
*/
- public synchronized long getBytePosition (final long charPos)
+ //@GuardedBy(this)
+ private long getBytePosition (final long charPos)
throws IOException {
- checkIfValid();
long bytePos;
if (charPos == this.posCache.getCharPos()) {
// We already know the position.
@@ -395,8 +395,8 @@
private void copyClobContent(InternalClob clob)
throws IOException, SQLException {
try {
- long byteLength = clob.getByteLength();
- this.bytes.copyData(clob.getRawByteStream(), byteLength);
+ // Specify LONG.MAX_VALUE to copy data until EOF.
+ this.bytes.copyData(clob.getRawByteStream(), Long.MAX_VALUE);
} catch (StandardException se) {
throw Util.generateCsSQLException(se);
}
Modified: db/derby/code/branches/10.4/java/testing/org/apache/derby/impl/jdbc/InternalClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derby/impl/jdbc/InternalClobTest.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derby/impl/jdbc/InternalClobTest.java (original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derby/impl/jdbc/InternalClobTest.java Fri Oct 31 03:29:46 2008
@@ -125,27 +125,6 @@
* UnsupportedOperationException is allowed for read-only Clobs.
*/
- public void testGetByteLengthAfterRelease()
- throws IOException, SQLException {
- iClob.release();
- try {
- iClob.getByteLength();
- fail("Exception should have been raised, but was not");
- } catch (IllegalStateException ise) {
- // This is as expected.
- }
- }
-
- public void testGetBytePositionAfterRelease()
- throws IOException, SQLException {
- iClob.release();
- try {
- iClob.getBytePosition(1L);
- fail("Exception should have been raised, but was not");
- } catch (IllegalStateException ise) {
- // This is as expected.
- }
- }
public void testGetCharLengthAfterRelease()
throws IOException, SQLException {
iClob.release();
@@ -230,53 +209,6 @@
/* End of XXXAfterRelease tests. */
- public void testGetByteLength()
- throws IOException, SQLException {
- assertEquals(this.initialByteLength, iClob.getByteLength());
- }
-
- public void testGetBytePosition_first()
- throws IOException, SQLException {
- assertEquals(0L, iClob.getBytePosition(1L));
- }
-
- public void testGetBytePosition_second()
- throws IOException, SQLException {
- assertEquals(bytesPerChar, iClob.getBytePosition(2L));
- }
-
- public void testGetBytePosition_last()
- throws IOException, SQLException {
- assertEquals(initialByteLength - bytesPerChar,
- iClob.getBytePosition(this.initialCharLength));
- }
-
- public void testGetBytePosition_lastPlussOne()
- throws IOException, SQLException {
- assertEquals(initialByteLength,
- iClob.getBytePosition(this.initialCharLength +1));
- }
-
- public void testGetBytePosition_lastPlussTwo()
- throws IOException, SQLException {
- try {
- long pos = iClob.getBytePosition(this.initialCharLength +2);
- fail("Length +2 should have no valid byte position, got " + pos);
- } catch (EOFException ioe) {
- // As expected for Derby.
- }
- }
-
- public void testGetBytePosition_lastPlussThousand()
- throws IOException, SQLException {
- try {
- long pos = iClob.getBytePosition(this.initialCharLength +1000);
- fail("Length +1000 should have no valid byte position, got " + pos);
- } catch (EOFException ioe) {
- // As expected for Derby.
- }
- }
-
public void testGetCharLength()
throws IOException, SQLException {
assertEquals(this.initialCharLength, iClob.getCharLength());
Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ClobTest.java?rev=709375&r1=709374&r2=709375&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ClobTest.java (original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ClobTest.java Fri Oct 31 03:29:46 2008
@@ -35,6 +35,7 @@
import java.sql.Connection;
import java.sql.Clob;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -204,6 +205,63 @@
newContent, this.clob.getSubString(1, newContent.length()));
}
+ /**
+ * Tests that Derby specific end-of-stream markers aren't passed over to
+ * the temporary Clob, which doesn't use such markers.
+ * <p>
+ * Passing the marker over will normally result in a UTF encoding exception.
+ * <p>
+ * ID USAGE: reads id 2, writes id 10002
+ */
+ public void testInsertCharacter_ReadOnlyToTemporary()
+ throws IOException, SQLException {
+ getConnection().setAutoCommit(false);
+ // Insert data, a medium sized Clob to store it as a stream.
+ Statement stmt = createStatement();
+ PreparedStatement ps = prepareStatement(
+ "insert into ClobTestData values (?,?)");
+ int initalSize = 128*1024;
+ ps.setInt(1, 2);
+ ps.setCharacterStream(
+ 2, new LoopingAlphabetReader(initalSize), initalSize);
+ ps.executeUpdate();
+
+ // Select the Clob, and change one character.
+ PreparedStatement psSelect = prepareStatement(
+ "select dClob from ClobTestData where id = ?");
+ psSelect.setInt(1, 2);
+ ResultSet lRs = psSelect.executeQuery();
+ lRs.next();
+ Clob lClob = lRs.getClob(1);
+ lClob.setString(1, "K");
+ Reader r = lClob.getCharacterStream();
+ assertEquals('K', r.read());
+ long length = 1;
+ while (true) {
+ // Since we're skipping characters, the bytes have to be decoded
+ // and we will detect any encoding errors.
+ long skipped = r.skip(4096);
+ if (skipped > 0) {
+ length += skipped;
+ } else {
+ break;
+ }
+ }
+ lRs.close();
+ assertEquals("Wrong length!", initalSize, length);
+ // Reports the correct length, now try to insert it.
+ ps.setInt(1, 10003);
+ ps.setClob(2, lClob);
+ ps.executeUpdate();
+ // Fetch it back.
+ psSelect.setInt(1, 10003);
+ lRs = psSelect.executeQuery();
+ lRs.next();
+ Clob lClob2 = lRs.getClob(1);
+ assertEquals(lClob.getCharacterStream(), lClob2.getCharacterStream());
+ assertEquals(initalSize, lClob2.length());
+ }
+
public void testPositionWithString_ASCII_SimplePartialRecurringPattern()
throws IOException, SQLException {
String token = "xxSPOTxx";
@@ -289,7 +347,8 @@
// Obtain a Clob containing the empty string ("").
Statement stmt = createStatement();
// Keep reference to the result set to be able to close it.
- this.rs = stmt.executeQuery("select * from ClobTestData");
+ this.rs = stmt.executeQuery(
+ "select dClob from ClobTestData where id = 1");
assertTrue(this.rs.next());
this.clob = this.rs.getClob(1);
}
@@ -441,8 +500,8 @@
Connection con = getConnection();
Statement stmt = con.createStatement();
stmt.execute("create table ClobTestData (" +
- "dClob CLOB)");
- stmt.executeUpdate("insert into ClobTestData values ('')");
+ "id int unique, dClob CLOB)");
+ stmt.executeUpdate("insert into ClobTestData values (1, '')");
stmt.close();
}