import java.sql.*;
import java.util.Random;

public class InsertSlowdown
{
    public static void main(String[] args) throws Exception
    {
        Driver driver = (Driver) Class.forName("org.postgresql.Driver").newInstance();
        new InsertSlowdown().run();
    }

    private void run() throws SQLException
    {
        connection = newConnection(false);
        execute(connection, ddl);
        load();
    }

    private void load() throws SQLException
    {
        PreparedStatement insert =
            connection.prepareStatement("insert into test values(?)");
        long txnStart = System.currentTimeMillis();
        long loadStart = txnStart;
        for (int i = 0; i < N; i++) {
            int key = key();
            insert.setLong(1, key);
            insert.executeUpdate();
            if (((i + 1) % COMMIT_FREQUENCY) == 0) {
                connection.commit();
                long stop = System.currentTimeMillis();
                System.out.println(i + 1 + ", " + (stop - loadStart) + ", " + (stop - txnStart));
                txnStart = System.currentTimeMillis();
            }
        }
        insert.close();
    }

    private static Connection newConnection(boolean autoCommit) throws SQLException
    {
        Connection connection = DriverManager.getConnection("jdbc:postgresql:test", "jao", "jao");
        connection.setAutoCommit(autoCommit);
        return connection;
    }

    private void execute(Connection connection, String[] sql)
    {
        for (int i = 0; i < sql.length; i++) {
            String statement = sql[i];
            execute(connection, statement);
        }
    }

    private void execute(Connection connection, String sql)
    {
        System.out.println(sql);
        try {
            Statement statement = connection.createStatement();
            statement.execute(sql);
            statement.close();
            commit(connection);
        } catch (SQLException e) {
            try {
                rollback(connection);
            } catch (SQLException e1) {
            }
            System.out.println("    "+e.getMessage());
        }
    }

    private void commit(Connection connection) throws SQLException
    {
        connection.commit();
        connection.clearWarnings();
    }

    private void rollback(Connection connection) throws SQLException
    {
        connection.rollback();
        connection.clearWarnings();
    }

    private int key()
    {
        return random.nextInt(1000000000);
    }

    private static final int N = 1000000;
    private static final int COMMIT_FREQUENCY = 1000;
    private final Random random = new Random();
    private int counter = 0;

    private static final String[] ddl = {
        "drop table test",
        "create table test(id int)",
        "create index idx_test on test(id)"
    };

    private Connection connection;
}
