postgresql-jdbc.git / summary / log / commit / refs

commit    1764c90f12c9ed864b94de742ec71185f4d779b2
Author:   Alexis Meneses <alexismeneses@users.noreply.github.com>
Date:     Sun Nov 23 19:47:17 2014 +0000

    Added support for jdbc4 Blob.getBinaryStream(long,long)


org/postgresql/jdbc4/AbstractJdbc4Blob.java | 14 ++++++++- org/postgresql/largeobject/BlobInputStream.java | 27 ++++++++++++++++ org/postgresql/largeobject/LargeObject.java | 11 +++++++ org/postgresql/test/jdbc4/BlobTest.java | 42 +++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/org/postgresql/jdbc4/AbstractJdbc4Blob.java b/org/postgresql/jdbc4/AbstractJdbc4Blob.java index 8e2fc557..f422dd2e 100644 --- a/org/postgresql/jdbc4/AbstractJdbc4Blob.java +++ b/org/postgresql/jdbc4/AbstractJdbc4Blob.java @@ -10,6 +10,8 @@ package org.postgresql.jdbc4; import java.sql.*; +import org.postgresql.largeobject.LargeObject; + public abstract class AbstractJdbc4Blob extends org.postgresql.jdbc3.AbstractJdbc3Blob { @@ -21,7 +23,17 @@ public abstract class AbstractJdbc4Blob extends org.postgresql.jdbc3.AbstractJdb public synchronized java.io.InputStream getBinaryStream(long pos, long length) throws SQLException { checkFreed(); - throw org.postgresql.Driver.notImplemented(this.getClass(), "getBinaryStream(long, long)"); + LargeObject subLO = getLo(false).copy(); + addSubLO(subLO); + if (pos > Integer.MAX_VALUE) + { + subLO.seek64(pos - 1, LargeObject.SEEK_SET); + } + else + { + subLO.seek((int) pos - 1, LargeObject.SEEK_SET); + } + return subLO.getInputStream(length); } } diff --git a/org/postgresql/largeobject/BlobInputStream.java b/org/postgresql/largeobject/BlobInputStream.java index 8d128d80..d0ec4610 100644 --- a/org/postgresql/largeobject/BlobInputStream.java +++ b/org/postgresql/largeobject/BlobInputStream.java @@ -21,6 +21,11 @@ public class BlobInputStream extends InputStream */ private LargeObject lo; + /** + * The absolute position + */ + private long apos; + /** * Buffer used to improve performance */ @@ -41,6 +46,11 @@ public class BlobInputStream extends InputStream */ private int mpos = 0; + /** + * The limit + */ + private long limit = -1; + /** * @param lo LargeObject to read from */ @@ -53,12 +63,24 @@ public class BlobInputStream extends InputStream * @param lo LargeObject to read from * @param bsize buffer size */ + public BlobInputStream(LargeObject lo, int bsize) + { + this(lo, 1024, -1); + } + + /** + * @param lo LargeObject to read from + * @param bsize buffer size + */ + public BlobInputStream(LargeObject lo, int bsize, long limit) { this.lo = lo; buffer = null; bpos = 0; + apos = 0; this.bsize = bsize; + this.limit = limit; } /** @@ -69,6 +91,10 @@ public class BlobInputStream extends InputStream checkClosed(); try { + if (limit > 0 && apos >= limit) + { + return -1; + } if (buffer == null || bpos >= buffer.length) { buffer = lo.read(bsize); @@ -88,6 +114,7 @@ public class BlobInputStream extends InputStream } bpos++; + apos++; return ret; } diff --git a/org/postgresql/largeobject/LargeObject.java b/org/postgresql/largeobject/LargeObject.java index 8a2928a4..324fc9b0 100644 --- a/org/postgresql/largeobject/LargeObject.java +++ b/org/postgresql/largeobject/LargeObject.java @@ -410,6 +410,17 @@ public class LargeObject return new BlobInputStream(this, 4096); } + /** + * Returns an InputStream from this object, that will limit the amount of data that is visible + * + * @param limit maximum number of bytes the resulting stream will serve + * @exception SQLException if a database-access error occurs. + */ + public InputStream getInputStream(long limit) throws SQLException + { + return new BlobInputStream(this, 4096, limit); + } + /** * Returns an OutputStream to this object. * diff --git a/org/postgresql/test/jdbc4/BlobTest.java b/org/postgresql/test/jdbc4/BlobTest.java index 6b91ce83..4e1e1a7d 100644 --- a/org/postgresql/test/jdbc4/BlobTest.java +++ b/org/postgresql/test/jdbc4/BlobTest.java @@ -1,6 +1,7 @@ package org.postgresql.test.jdbc4; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; @@ -97,4 +98,45 @@ public class BlobTest extends TestCase selectStmt.close(); } } + + public void testGetBinaryStreamWithBoundaries() throws Exception + { + byte[] data = new String("Cras vestibulum tellus eu sapien imperdiet ornare.").getBytes("UTF-8"); + PreparedStatement insertPS = _conn.prepareStatement(TestUtil.insertSQL("testblob", "lo", "?")); + try + { + insertPS.setBlob(1, new ByteArrayInputStream(data), data.length); + insertPS.executeUpdate(); + } + finally + { + insertPS.close(); + } + + Statement selectStmt = _conn.createStatement(); + try + { + ResultSet rs = selectStmt.executeQuery(TestUtil.selectSQL("testblob", "lo")); + assertTrue(rs.next()); + + byte[] actualData = new byte[10]; + Blob actualBlob = rs.getBlob(1); + InputStream stream = actualBlob.getBinaryStream(6, 10); + try + { + stream.read(actualData); + Assert.assertEquals("Stream should be at end", -1, stream.read(new byte[1])); + } + finally + { + stream.close(); + } + Assert.assertEquals("vestibulum", new String(actualData, "UTF-8")); + } + finally + { + selectStmt.close(); + } + } + } [parent: 27397a24d3fd]