db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r677578 - /db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
Date Thu, 17 Jul 2008 13:21:12 GMT
Author: kristwaa
Date: Thu Jul 17 06:21:12 2008
New Revision: 677578

URL: http://svn.apache.org/viewvc?rev=677578&view=rev
Log:
DERBY-3768: Make EmbedBlob.length use skip instead of read.
Merged revisions 675169 (derby-3768-1b-length_skip.diff) and 676571 (derby-3768-2a-misc_fixes.diff)
from trunk.

Modified:
    db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java?rev=677578&r1=677577&r2=677578&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java Thu
Jul 17 06:21:12 2008
@@ -25,18 +25,15 @@
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.jdbc.EngineLOB;
-import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.reference.Limits;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.types.Resetable;
-import org.apache.derby.iapi.services.io.NewByteArrayInputStream;
 import org.apache.derby.iapi.services.io.InputStreamUtil;
-import org.apache.derby.iapi.services.io.ArrayInputStream;
 
 import java.sql.SQLException;
 import java.sql.Blob;
 import java.io.InputStream;
-import java.io.EOFException;
 import java.io.IOException;
 
 /**
@@ -70,18 +67,34 @@
 
 final class EmbedBlob extends ConnectionChild implements Blob, EngineLOB
 {
-    // blob is either materialized or still in stream
+    /**
+     * Tells whether the Blob has been materialized or not.
+     * <p>
+     * Materialization happens when the Blob is updated by the user. A
+     * materialized Blob is represented either in memory or in a temporary file
+     * on disk, depending on size.
+     * <p>
+     * A Blob that has not been materialized is represented by a stream into the
+     * Derby store, and is read-only.
+     */
     private boolean         materialized;
     private InputStream     myStream;
     
-    // locator key for lob. used by Network Server.
-    private int             locator;
+    /**
+     * Locator value for this Blob, used as a handle by the client driver to
+     * map operations to the correct Blob on the server side.
+     *
+     * @see #getLocator()
+     */
+    private int locator = 0;
     
-    /*
-     * Length of the BLOB if known. Set to -1 if
-     * the current length of the BLOB is not known.
+    /**
+     * Length of the stream representing the Blob.
+     * <p>
+     * Set to -1 when the stream has been materialized {@link #materialized} or
+     * the length of the stream is not currently known.
      */
-    private long myLength = -1;
+    private long streamLength = -1;
     
     // note: cannot control position of the stream since user can do a getBinaryStream
     private long            pos;
@@ -183,6 +196,8 @@
                 if (se.getMessageId().equals(SQLState.DATA_CONTAINER_CLOSED)) {
                     throw StandardException
                             .newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
+                } else {
+                    throw se;
                 }
             }
             // set up the buffer for trashing the bytes to set the position of
@@ -275,8 +290,8 @@
         catch (IOException e) {
             throw Util.setStreamFailure (e);
         }
-        if (myLength != -1)
-            return myLength;
+        if (streamLength != -1)
+            return streamLength;
         
         boolean pushStack = false;
         try
@@ -291,21 +306,30 @@
                 setPosition(0);
                 // If possible get the length from the encoded
                 // length at the front of the raw stream.
-                if ((myLength = biStream.getLength()) != -1) {
+                if ((streamLength = biStream.getLength()) != -1) {
                     biStream.close();
-                   return myLength;
+                   return streamLength;
                 }
                 
                 // Otherwise have to read the entire stream!
                 for (;;)
                 {
-                    int size = biStream.read(buf);
-                    if (size == -1)
-                        break;
-                    pos += size;
+                    long skipped = biStream.skip(Limits.DB2_LOB_MAXWIDTH);
+                    if (SanityManager.DEBUG) {
+                        SanityManager.ASSERT(skipped >= 0);
+                    }
+                    pos += skipped;
+                    // If skip reports zero bytes skipped, verify EOF.
+                    if (skipped == 0) {
+                        if (biStream.read() == -1) {
+                            break; // Exit the loop, no more data.
+                        } else {
+                            pos++;
+                        }
+                    }
                 }
                 // Save for future uses.
-                myLength = pos;
+                streamLength = pos;
                 biStream.close();
                 return pos;
             }
@@ -795,6 +819,7 @@
                 control.copyData (myStream, length());
                 len = (int) control.write(bytes, offset, len, pos - 1);
                 myStream.close();
+                streamLength = -1;
                 materialized = true;
             }
             return len;
@@ -835,6 +860,7 @@
                                             getEmbedConnection().getDBName());
                     control.copyData (myStream, pos - 1);
                     myStream.close ();
+                    streamLength = -1;
                     materialized = true;
                     return control.getOutputStream(pos - 1);
 
@@ -872,6 +898,7 @@
                     control = new LOBStreamControl (getEmbedConnection().getDBName());
                     control.copyData (myStream, len);
                     myStream.close();
+                    streamLength = -1;
                     materialized = true;
                 }
             }
@@ -906,10 +933,12 @@
         //valid
         isValid = false;
         
-        //remove entry from connection
-        localConn.removeLOBMapping(locator);
+        // Remove entry from connection if a locator has been created.
+        if (this.locator != 0) {
+            localConn.removeLOBMapping(locator);
+        }
         //initialialize length to default value -1
-        myLength = -1;
+        streamLength = -1;
         
         //if it is a stream then close it.
         //if a array of bytes then initialize it to null



Mime
View raw message