001package org.itsallcode.jdbc;
002
003import java.sql.*;
004import java.util.Objects;
005
006import org.itsallcode.jdbc.dialect.DbDialect;
007import org.itsallcode.jdbc.resultset.*;
008
009/**
010 * Simple wrapper for a JDBC {@link Statement}.
011 */
012public class SimpleStatement implements AutoCloseable {
013    private final Context context;
014    private final DbDialect dialect;
015    private final Statement statement;
016
017    SimpleStatement(final Context context, final DbDialect dialect, final Statement statement) {
018        this.context = Objects.requireNonNull(context, "context");
019        this.dialect = Objects.requireNonNull(dialect, "dialect");
020        this.statement = Objects.requireNonNull(statement, "statement");
021    }
022
023    <T> SimpleResultSet<T> executeQuery(final String sql, final ContextRowMapper<T> rowMapper) {
024        final ResultSet resultSet = doExecuteQuery(sql);
025        final ResultSet convertingResultSet = ConvertingResultSet.create(dialect, resultSet);
026        return new SimpleResultSet<>(context, convertingResultSet, rowMapper, this);
027    }
028
029    private ResultSet doExecuteQuery(final String sql) {
030        try {
031            return statement.executeQuery(sql);
032        } catch (final SQLException e) {
033            throw new UncheckedSQLException("Error executing query '" + sql + "'", e);
034        }
035    }
036
037    int executeUpdate(final String sql) {
038        try {
039            return statement.executeUpdate(sql);
040        } catch (final SQLException e) {
041            throw new UncheckedSQLException("Error executing statement '" + sql + "'", e);
042        }
043    }
044
045    /**
046     * Execute the batch statement.
047     * 
048     * @return array of update counts
049     * @see Statement#executeBatch()
050     */
051    public int[] executeBatch() {
052        try {
053            return statement.executeBatch();
054        } catch (final SQLException e) {
055            throw new UncheckedSQLException("Error executing batch", e);
056        }
057    }
058
059    /**
060     * Add the SQL statement to the batch.
061     * 
062     * @param sql SQL statement
063     * @see Statement#addBatch(String)
064     */
065    public void addBatch(final String sql) {
066        try {
067            this.statement.addBatch(sql);
068        } catch (final SQLException e) {
069            throw new UncheckedSQLException("Error adding batch", e);
070        }
071    }
072
073    /**
074     * Get the underlying {@link Statement}.
075     * 
076     * @return the underlying {@link Statement}
077     */
078    public Statement getStatement() {
079        return statement;
080    }
081
082    @Override
083    public void close() {
084        try {
085            statement.close();
086        } catch (final SQLException e) {
087            throw new UncheckedSQLException("Error closing statement", e);
088        }
089    }
090}