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]