
import java.sql.*;

/**
 * Testcase for MySQL Connector/J 5.1.7 bug report.
 *
 * I think the bug is in UpdatableResultSet.deleteRow(), where the binary data is being corrupted
 * because it is going through a String (with some character encoding), rather than being treated
 * as raw binary data.  Compare to com.mysql.jdbc.PreparedStatement.setBytes(), which seems to work
 * correctly.
 */
public class TestDeleteRowBinaryColumn {

    public static void main(String[] args) throws SQLException {
        String databaseUrl = "jdbc:mysql://gandalf/chris?autoGenerateTestcaseScript=true";
        String databaseUser = "webapp";
        String databasePassword = "v1cut";
        Connection conn = DriverManager.getConnection(databaseUrl, databaseUser, databasePassword);

        // create the table
        Statement createStmt = conn.createStatement();
        createStmt.executeUpdate("DROP TABLE IF EXISTS testtable_bincolumn");
        createStmt.close();
        createStmt = conn.createStatement();
        createStmt.executeUpdate("CREATE TABLE testtable_bincolumn (" +
                "bincolumn binary(8) NOT NULL, " +
                "PRIMARY KEY (bincolumn)" +
                ") ENGINE=InnoDB");
        createStmt.close();

        String pkValue1 = "0123456789ABCD90";
        String pkValue2 = "0123456789ABCD00";
        // put some data in it
        createStmt = conn.createStatement();
        createStmt.executeUpdate("INSERT INTO testtable_bincolumn (bincolumn) " +
                "VALUES (unhex('"+pkValue1+"')), (unhex('"+pkValue2+"'))");
        createStmt.close();

        // cause the bug
        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"+pkValue1+"')");
        if (rs.next()) {
            System.out.println("We got a row for "+pkValue1+", about to delete it ...");
            rs.deleteRow();
        }
        rs.close();
        stmt.close();

        // At this point the row with pkValue1 should be deleted.  We'll select it back to see.
        // If the row comes back, the testcase has failed.

        stmt = conn.createStatement();
        rs = stmt.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"+pkValue1+"')");
        if (rs.next()) {
            System.out.println("Testcase #1 FAILED, the row was not deleted by deleteRow()");
        } else {
            System.out.println("Testcase #1 PASSED, the row was deleted by deleteRow()");
        }

        rs.close();
        stmt.close();

        // Now, show a case where it happens to work, because the binary data is different
        stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
        rs = stmt.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"+pkValue2+"')");
        if (rs.next()) {
            System.out.println("We got a row for "+pkValue2+", about to delete it ...");
            rs.deleteRow();
        }
        rs.close();
        stmt.close();

        stmt = conn.createStatement();
        rs = stmt.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"+pkValue2+"')");
        if (rs.next()) {
            System.out.println("Testcase #2 FAILED, the row was not deleted by deleteRow()");
        } else {
            System.out.println("Testcase #2 PASSED, the row was deleted by deleteRow()");
        }

        rs.close();
        stmt.close();
        conn.close();
    }
}
