Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 43356 invoked from network); 19 May 2007 17:59:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 May 2007 17:59:43 -0000 Received: (qmail 23468 invoked by uid 500); 19 May 2007 17:59:49 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 23407 invoked by uid 500); 19 May 2007 17:59:49 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 23392 invoked by uid 99); 19 May 2007 17:59:49 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 19 May 2007 10:59:49 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 19 May 2007 10:59:42 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id CC22E1A981A; Sat, 19 May 2007 10:59:21 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r539784 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ Date: Sat, 19 May 2007 17:59:20 -0000 To: derby-commits@db.apache.org From: kahatlen@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070519175921.CC22E1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kahatlen Date: Sat May 19 10:59:19 2007 New Revision: 539784 URL: http://svn.apache.org/viewvc?view=rev&rev=539784 Log: DERBY-2496: Implement Blob support for Locators Modified Blob tests so that they also work when locators are enabled. Fixed two bugs in the network protocol. Patch contributed by Øystein Grøvlen. File-by-file explanation of changes: M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/BlobTest.java - Adjusted tests to not expect Blob objects to be valid after transaction commit. M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java - Adjusted tests to not expect Blob objects to be valid after transaction commit. - Rewrote testSetBlobLengthless to take advantage of the existence of Connection.createBlob M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java - Adjusted tests to not expect Blob objects to be valid after transaction commit. M java/client/org/apache/derby/client/net/NetCursor.java - If the column value is zero, a locator was not sent. Instead, this means that the length of the LOB is 0. Changed locator() to return INVALID_LOCATOR when the column value is zero. M java/client/org/apache/derby/client/net/NetStatementRequest.java - If column is not nullable, a non-nullable locator must be requested. Otherwise, the server will send an extra byte for nullability which is not expected by the client. M java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java - Added an assert that checks that the underlying Blob object is locator based. M java/client/org/apache/derby/client/am/Blob.java - Add buffering for InputStreams by wrapping BlobLocatorInputStream in a BufferedInputStream. (Doing the same for OutputStreams is not that straight-forward since that requires that the stream is flushed before the statement is executed.) M java/client/org/apache/derby/client/am/BlobLocatorInputStream.java - Removed a TAB. Client code is supposed to be a TAB-free zone! 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/BlobLocatorInputStream.java db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.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/PreparedStatementTest.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.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=539784&r1=539783&r2=539784 ============================================================================== --- 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 Sat May 19 10:59:19 2007 @@ -21,11 +21,12 @@ package org.apache.derby.client.am; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.SQLException; -import java.util.ArrayList; import org.apache.derby.shared.common.reference.SQLState; @@ -267,7 +268,8 @@ { return binaryStream_; } else if (isLocator()) { - return new BlobLocatorInputStream(agent_.connection_, this); + return new BufferedInputStream( + new BlobLocatorInputStream(agent_.connection_, this)); } else { // binary string return new java.io.ByteArrayInputStream(binaryString_, dataOffset_, binaryString_.length - dataOffset_); @@ -654,10 +656,11 @@ InputStream retVal; if (isLocator()) { - retVal = new BlobLocatorInputStream(agent_.connection_, - this, - pos, - length); + retVal = new BufferedInputStream( + new BlobLocatorInputStream(agent_.connection_, + this, + pos, + length)); } else { // binary string retVal = new java.io.ByteArrayInputStream (binaryString_, Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java?view=diff&rev=539784&r1=539783&r2=539784 ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java Sat May 19 10:59:19 2007 @@ -26,7 +26,7 @@ import java.io.IOException; -import org.apache.derby.iapi.services.sanity.SanityManager; +import org.apache.derby.shared.common.sanity.SanityManager; /** * An InputStream that will use an locator to fetch the @@ -61,7 +61,7 @@ throws SqlException { if (SanityManager.DEBUG) { - SanityManager.ASSERT(blob.isLocator()); + SanityManager.ASSERT(blob.isLocator()); } this.connection = connection; this.blob = blob; Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java?view=diff&rev=539784&r1=539783&r2=539784 ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorOutputStream.java Sat May 19 10:59:19 2007 @@ -22,6 +22,8 @@ package org.apache.derby.client.am; import java.io.IOException; +import org.apache.derby.shared.common.sanity.SanityManager; + /** * An OutputStream that will use an locator to write * bytes to the Blob value on the server. @@ -51,6 +53,10 @@ public BlobLocatorOutputStream(Connection connection, Blob blob, long pos) throws SqlException { + if (SanityManager.DEBUG) { + SanityManager.ASSERT(blob.isLocator()); + } + if (pos-1 > blob.sqlLength()) { throw new IndexOutOfBoundsException(); } Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?view=diff&rev=539784&r1=539783&r2=539784 ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Sat May 19 10:59:19 2007 @@ -1060,7 +1060,8 @@ { int locator = get_INTEGER(column); // If Lob value was sent instead of locator, highest bit will be set - if ((locator & 0x8000) == 0x8000) { + // Zero is not a valid locator, it indicates a zero length value + if (((locator & 0x8000) == 0x8000) || (locator == 0)) { return Lob.INVALID_LOCATOR; } else { return locator; Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java?view=diff&rev=539784&r1=539783&r2=539784 ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java Sat May 19 10:59:19 2007 @@ -632,14 +632,19 @@ for (int i=0; iBlob without specifying length and read it back * for verification. - * - * Beacuse we don't yet support Connection.createBlob in the - * client driver, we must first insert data into the database and read back - * a Blob object. This object is then inserted into the - * database again. */ public void testSetBlobLengthless() throws IOException, SQLException { - // Insert test data. - InputStream is = new ByteArrayInputStream(BYTES); - psInsertBlob.setInt(1, key); - psInsertBlob.setBinaryStream(2, is); - psInsertBlob.execute(); - is.close(); - // Must fetch Blob from database because we don't support - // Connection.createBlob on the client yet. - psFetchBlob.setInt(1, key); - ResultSet rs = psFetchBlob.executeQuery(); - assertTrue("No results retrieved", rs.next()); - Blob insertBlob = rs.getBlob(1); + // Life span of Blob objects are the transaction. Need autocommit off + // to have Blob objects survive execution of next statement. + getConnection().setAutoCommit(false); + // Create Blob to be inserted + Blob insertBlob = getConnection().createBlob(); + OutputStream os = insertBlob.setBinaryStream(1); + os.write(BYTES); int secondKey = requestKey(); psInsertBlob.setInt(1, secondKey); psInsertBlob.setBlob(2, insertBlob); psInsertBlob.execute(); + os.close(); + psInsertBlob.close(); // Read back test data from database. psFetchBlob.setInt(1, secondKey); - rs = psFetchBlob.executeQuery(); + ResultSet rs = psFetchBlob.executeQuery(); assertTrue("No results retrieved", rs.next()); Blob blobRetrieved = rs.getBlob(1); @@ -753,12 +748,11 @@ psInsertBlob.setBinaryStream(2, is, BYTES.length); psInsertBlob.executeUpdate(); - //Now query to retrieve the Clob + // Now query to retrieve the Blob psFetchBlob.setInt(1, key); ResultSet rs = psFetchBlob.executeQuery(); rs.next(); Blob blobRetrieved = rs.getBlob(1); - rs.close(); try { InputStream is_ret = blobRetrieved.getBinaryStream(); @@ -766,6 +760,7 @@ } catch(IOException ioe) { fail("IOException while reading the Clob from the database"); } + rs.close(); // Because of autocommit, this will invalidate blobRetrieved for(int i=0;i