/* * Copyright (c) 2005, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package org.postgresql.test.jdbc3; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.postgresql.core.ServerVersion; import org.postgresql.test.TestUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; public class Jdbc3BlobTest { private final static String TABLE = "blobtest"; private final static String INSERT = "INSERT INTO " + TABLE + " VALUES (1, lo_creat(-1))"; private final static String SELECT = "SELECT ID, DATA FROM " + TABLE + " WHERE ID = 1"; private Connection _conn; @Before public void setUp() throws Exception { _conn = TestUtil.openDB(); TestUtil.createTable(_conn, TABLE, "ID INT PRIMARY KEY, DATA OID"); _conn.setAutoCommit(false); } @After public void tearDown() throws SQLException { _conn.setAutoCommit(true); try { Statement stmt = _conn.createStatement(); try { stmt.execute("SELECT lo_unlink(DATA) FROM " + TABLE); } finally { try { stmt.close(); } catch (Exception e) { } } } finally { TestUtil.dropTable(_conn, TABLE); TestUtil.closeDB(_conn); } } /** * Test the writing and reading of a single byte. */ @Test public void test1Byte() throws SQLException { byte[] data = {(byte) 'a'}; readWrite(data); } /** * Test the writing and reading of a few bytes. */ @Test public void testManyBytes() throws SQLException { byte[] data = "aaaaaaaaaa".getBytes(); readWrite(data); } /** * Test writing a single byte with an offset. */ @Test public void test1ByteOffset() throws SQLException { byte[] data = {(byte) 'a'}; readWrite(10, data); } /** * Test the writing and reading of a few bytes with an offset. */ @Test public void testManyBytesOffset() throws SQLException { byte[] data = "aaaaaaaaaa".getBytes(); readWrite(10, data); } /** * Tests all of the byte values from 0 - 255. */ @Test public void testAllBytes() throws SQLException { byte[] data = new byte[256]; for (int i = 0; i < data.length; i++) { data[i] = (byte) i; } readWrite(data); } @Test public void testTruncate() throws SQLException { if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3)) { return; } byte data[] = new byte[100]; for (byte i = 0; i < data.length; i++) { data[i] = i; } readWrite(data); PreparedStatement ps = _conn.prepareStatement(SELECT); ResultSet rs = ps.executeQuery(); assertTrue(rs.next()); Blob blob = rs.getBlob("DATA"); assertEquals(100, blob.length()); blob.truncate(50); assertEquals(50, blob.length()); blob.truncate(150); assertEquals(150, blob.length()); data = blob.getBytes(1, 200); assertEquals(150, data.length); for (byte i = 0; i < 50; i++) { assertEquals(i, data[i]); } for (int i = 50; i < 150; i++) { assertEquals(0, data[i]); } } /** * * @param data data to write * @throws SQLException if something goes wrong */ public void readWrite(byte[] data) throws SQLException { readWrite(1, data); } /** * * @param offset data offset * @param data data to write * @throws SQLException if something goes wrong */ public void readWrite(int offset, byte[] data) throws SQLException { PreparedStatement ps = _conn.prepareStatement(INSERT); ps.executeUpdate(); ps.close(); ps = _conn.prepareStatement(SELECT); ResultSet rs = ps.executeQuery(); assertTrue(rs.next()); Blob b = rs.getBlob("DATA"); b.setBytes(offset, data); rs.close(); ps.close(); ps = _conn.prepareStatement(SELECT); rs = ps.executeQuery(); assertTrue(rs.next()); b = rs.getBlob("DATA"); byte[] rspData = b.getBytes(offset, data.length); assertTrue("Request should be the same as the response", Arrays.equals(data, rspData)); rs.close(); ps.close(); } /** * Test the writing and reading of a single byte. */ @Test public void test1ByteStream() throws SQLException, IOException { byte[] data = {(byte) 'a'}; readWriteStream(data); } /** * Test the writing and reading of a few bytes. */ @Test public void testManyBytesStream() throws SQLException, IOException { byte[] data = "aaaaaaaaaa".getBytes(); readWriteStream(data); } /** * Test writing a single byte with an offset. */ @Test public void test1ByteOffsetStream() throws SQLException, IOException { byte[] data = {(byte) 'a'}; readWriteStream(10, data); } /** * Test the writing and reading of a few bytes with an offset. */ @Test public void testManyBytesOffsetStream() throws SQLException, IOException { byte[] data = "aaaaaaaaaa".getBytes(); readWriteStream(10, data); } /** * Tests all of the byte values from 0 - 255. */ @Test public void testAllBytesStream() throws SQLException, IOException { byte[] data = new byte[256]; for (int i = 0; i < data.length; i++) { data[i] = (byte) i; } readWriteStream(data); } public void readWriteStream(byte[] data) throws SQLException, IOException { readWriteStream(1, data); } /** * Reads then writes data to the blob via a stream. */ public void readWriteStream(int offset, byte[] data) throws SQLException, IOException { PreparedStatement ps = _conn.prepareStatement(INSERT); ps.executeUpdate(); ps.close(); ps = _conn.prepareStatement(SELECT); ResultSet rs = ps.executeQuery(); assertTrue(rs.next()); Blob b = rs.getBlob("DATA"); OutputStream out = b.setBinaryStream(offset); out.write(data); out.flush(); out.close(); rs.close(); ps.close(); ps = _conn.prepareStatement(SELECT); rs = ps.executeQuery(); assertTrue(rs.next()); b = rs.getBlob("DATA"); InputStream in = b.getBinaryStream(); byte[] rspData = new byte[data.length]; in.skip(offset - 1); in.read(rspData); in.close(); assertTrue("Request should be the same as the response", Arrays.equals(data, rspData)); rs.close(); ps.close(); } @Test public void testPattern() throws SQLException { byte[] data = "abcdefghijklmnopqrstuvwxyx0123456789".getBytes(); byte[] pattern = "def".getBytes(); PreparedStatement ps = _conn.prepareStatement(INSERT); ps.executeUpdate(); ps.close(); ps = _conn.prepareStatement(SELECT); ResultSet rs = ps.executeQuery(); assertTrue(rs.next()); Blob b = rs.getBlob("DATA"); b.setBytes(1, data); rs.close(); ps.close(); ps = _conn.prepareStatement(SELECT); rs = ps.executeQuery(); assertTrue(rs.next()); b = rs.getBlob("DATA"); long position = b.position(pattern, 1); byte[] rspData = b.getBytes(position, pattern.length); assertTrue("Request should be the same as the response", Arrays.equals(pattern, rspData)); rs.close(); ps.close(); } }