package com.intrbiz.bergamot.check.jdbc; import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.util.LinkedList; import java.util.List; import java.util.function.Function; public abstract class JDBCStatement { private final String sql; private List<Binder> bindings = new LinkedList<Binder>(); public JDBCStatement(String sql) { this.sql = sql; } public JDBCStatement bind(Object value) { bindings.add((s, i) -> s.setObject(i, value)); return this; } public JDBCStatement bindString(String value) { bindings.add((s, i) -> s.setString(i, value)); return this; } public JDBCStatement bindShort(short value) { bindings.add((s, i) -> s.setShort(i, value)); return this; } public JDBCStatement bindInt(int value) { bindings.add((s, i) -> s.setInt(i, value)); return this; } public JDBCStatement bindLong(long value) { bindings.add((s, i) -> s.setLong(i, value)); return this; } public JDBCStatement bindFloat(float value) { bindings.add((s, i) -> s.setFloat(i, value)); return this; } public JDBCStatement bindDouble(double value) { bindings.add((s, i) -> s.setDouble(i, value)); return this; } public JDBCStatement bindDate(Date value) { bindings.add((s, i) -> s.setDate(i, value)); return this; } public JDBCStatement bindTime(Time value) { bindings.add((s, i) -> s.setTime(i, value)); return this; } public JDBCStatement bindTimestamp(Timestamp value) { bindings.add((s, i) -> s.setTimestamp(i, value)); return this; } public JDBCStatement bindBytes(byte[] value) { bindings.add((s, i) -> s.setBytes(i, value)); return this; } public int execute() { try (PreparedStatement stmt = this.getConnection().prepareStatement(this.sql)) { // bind int i = 1; for (Binder binding : bindings) { binding.bind(stmt, i++); } // execute return stmt.executeUpdate(); } catch (SQLException e) { throw new JDBCException(e); } } public <T> T query(Function<JDBCResultSet, T> resultProcessor) { try (PreparedStatement stmt = this.getConnection().prepareStatement(this.sql)) { // bind int i = 1; for (Binder binding : bindings) { binding.bind(stmt, i++); } // execute try (ResultSet rs = stmt.executeQuery()) { return resultProcessor.apply(new JDBCResultSet(rs)); } } catch (SQLException e) { throw new JDBCException(e); } } protected abstract Connection getConnection(); private static interface Binder { void bind(PreparedStatement stmt, int index) throws SQLException; } }