From bb7b71826d7a32752ace2f4574752a401fb7fa0f Mon Sep 17 00:00:00 2001 From: Peter Mount Date: Wed, 14 Feb 2001 17:45:17 +0000 Subject: Web Feb 14 17:29:00 GMT 2001 peter@retep.org.uk - Fixed bug in LargeObject & BlobOutputStream where the stream's output was not flushed when either the stream or the blob were closed. - Fixed PreparedStatement.setBinaryStream() where it ignored the length --- .../org/postgresql/jdbc2/PreparedStatement.java | 4 +- .../postgresql/largeobject/BlobOutputStream.java | 1 + .../org/postgresql/largeobject/LargeObject.java | 30 +++- .../jdbc/org/postgresql/test/JDBC2Tests.java | 5 +- .../jdbc/org/postgresql/test/jdbc2/BlobTest.java | 184 +++++++++++++++++++++ 5 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java (limited to 'src/interfaces/jdbc/org/postgresql') diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java index a0f1d0713c..93a175267d 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java @@ -431,9 +431,11 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta // is buffered internally anyhow, so there would be no performance // boost gained, if anything it would be worse! int c=x.read(); - while(c>-1) { + int p=0; + while(c>-1 && p0); + + // Now compare the blob & the file. Note this actually tests the + // InputStream implementation! + assert(compareBlobs(con)); + + JDBC2Tests.closeDB(con); + } catch(Exception ex) { + assert(ex.getMessage(),false); + } + } + + /** + * Tests one method of uploading a blob to the database + */ + public void testUploadBlob_NATIVE() { + try { + Connection con = JDBC2Tests.openDB(); + + JDBC2Tests.createTable(con,BLOB_TABLE_FMT); + + con.setAutoCommit(false); + assert(!con.getAutoCommit()); + + assert(uploadFile(con,"build.xml",NATIVE_STREAM)>0); + + // Now compare the blob & the file. Note this actually tests the + // InputStream implementation! + assert(compareBlobs(con)); + + JDBC2Tests.closeDB(con); + } catch(Exception ex) { + assert(ex.getMessage(),false); + } + } + + private static final int LOOP = 0; // LargeObject API using loop + private static final int NATIVE_STREAM = 1; // LargeObject API using OutputStream + private static final int JDBC_STREAM = 2; // JDBC API using OutputStream + + /** + * Helper - uploads a file into a blob using old style methods. We use this + * because it always works, and we can use it as a base to test the new + * methods. + */ + private int uploadFile(Connection con,String file,int method) throws Exception { + LargeObjectManager lom = ((org.postgresql.Connection)con).getLargeObjectAPI(); + + FileInputStream fis = new FileInputStream(file); + + int oid = lom.create(LargeObjectManager.READWRITE); + LargeObject blob = lom.open(oid); + + int s,t; + byte buf[]; + OutputStream os; + + switch(method) + { + case LOOP: + buf = new byte[2048]; + t=0; + while((s=fis.read(buf,0,buf.length))>0) { + t+=s; + blob.write(buf,0,s); + } + break; + + case NATIVE_STREAM: + os = blob.getOutputStream(); + s= fis.read(); + while(s>-1) { + os.write(s); + s=fis.read(); + } + os.close(); + break; + + case JDBC_STREAM: + File f = new File(file); + PreparedStatement ps = con.prepareStatement(JDBC2Tests.insert("?")); + ps.setBinaryStream(1,fis,(int) f.length()); + ps.execute(); + break; + + default: + assert("Unknown method in uploadFile",false); + } + + blob.close(); + fis.close(); + + // Insert into the table + Statement st = con.createStatement(); + st.executeUpdate(JDBC2Tests.insert("id,lo","'"+file+"',"+oid)); + con.commit(); + st.close(); + + return oid; + } + + /** + * Helper - compares the blobs in a table with a local file. Note this alone + * tests the InputStream methods! + */ + private boolean compareBlobs(Connection con) throws Exception { + boolean result=true; + + LargeObjectManager lom = ((org.postgresql.Connection)con).getLargeObjectAPI(); + + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery(JDBC2Tests.select("id,lo")); + assert(rs!=null); + + while(rs.next()) { + String file = rs.getString(1); + int oid = rs.getInt(2); + + FileInputStream fis = new FileInputStream(file); + LargeObject blob = lom.open(oid); + InputStream bis = blob.getInputStream(); + + int f=fis.read(); + int b=bis.read(); + int c=0; + while(f>=0 && b>=0 & result) { + result=(f==b); + f=fis.read(); + b=bis.read(); + c++; + } + result=result && f==-1 && b==-1; + + if(!result) + System.out.println("\nBlob compare failed at "+c+" of "+blob.size()); + + blob.close(); + fis.close(); + } + rs.close(); + st.close(); + + return result; + } +} -- cgit v1.2.1