/*
 * $Id$
 *
 * Test getting and setting data on a bytea field.
 */
package org.postgresql.test.jdbc2;

import org.postgresql.test.TestUtil;
import junit.framework.TestCase;
import java.util.Arrays;
import java.io.*;
import java.sql.*;

/**
 * Test getting and setting data on a bytea field.
 *
 * @author Anders Hermansen <anders@yoyo.no>
 */
public class ByteaTest extends TestCase {
    /**
     * Database connection to use.
     */
    private Connection con;

    /**
     * Create a new ByteaTest.
     *
     * @param name The name of the test.
     */
    public ByteaTest(String name) {
        super(name);
    }

    /**
     * Set up the test case. Get database connection and create a test table.
     *
     * @throws Exception if something goes wrong.
     */
    protected void setUp() throws Exception {
        con = TestUtil.openDB();
        TestUtil.createTable(con, "testbytea", "id name, content bytea");
        con.setAutoCommit(false);
    }

    /**
     * Tear down the test case. Drop the test table and close the connection.
     *
     * @throws Exception if something goes wrong.
     */
    protected void tearDown() throws Exception {
        con.setAutoCommit(true);
        TestUtil.dropTable(con, "testbytea");
        TestUtil.closeDB(con);
    }

    /**
     * Test using setBinaryStream and getBinaryStream on a bytea field.
     *
     * @throws Exception if test fails.
     */
    public void testByteaBinaryStream() throws Exception {
        final String fileName = "build.xml";

        File file = new File(fileName);
        int length = (int) file.length();

        // Put the data into the database
        FileInputStream fis = new FileInputStream(file);
        PreparedStatement st1 = con.prepareStatement(
                "INSERT INTO testbytea (id, content) VALUES (?, ?)");
        st1.setString(1, fileName);
        st1.setBinaryStream(2, fis, length);
        st1.executeUpdate();
        con.commit();

        // Fetch the data from the database
        PreparedStatement st2 = con.prepareStatement(
                "SELECT content FROM testbytea WHERE id = ?");
        st2.setString(1, fileName);
        ResultSet rs = st2.executeQuery();
        assertTrue("No rows received", rs.next());

        // Load file bytes
        InputStream isFromFile = new FileInputStream(file);
        byte[] bytes1 = new byte[length];
        assertEquals("Byte count from file is not correct",
                length, isFromFile.read(bytes1));
        assertEquals("More bytes are available from file",
                0, isFromFile.available());

        // Load db bytes
        InputStream isFromDb = rs.getBinaryStream("content");
        byte[] bytes2 = new byte[length];
        assertEquals("Byte count from database is not correct",
                length, isFromDb.read(bytes2));
        assertEquals("More bytes are available from db",
                0, isFromDb.available());

        // Compare the results
        assertTrue("Data from database and file differs",
                Arrays.equals(bytes1, bytes2));
    }
}
