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 PreparedStatement}. 011 */ 012public class SimplePreparedStatement implements AutoCloseable { 013 private final Context context; 014 private final DbDialect dialect; 015 private final PreparedStatement statement; 016 private final String sql; 017 018 SimplePreparedStatement(final Context context, final DbDialect dialect, final PreparedStatement statement, 019 final String sql) { 020 this.context = Objects.requireNonNull(context, "context"); 021 this.dialect = Objects.requireNonNull(dialect, "dialect"); 022 this.statement = Objects.requireNonNull(statement, "statement"); 023 this.sql = Objects.requireNonNull(sql, "sql"); 024 } 025 026 <T> SimpleResultSet<T> executeQuery(final ContextRowMapper<T> rowMapper) { 027 final ResultSet resultSet = doExecuteQuery(); 028 final ResultSet convertingResultSet = ConvertingResultSet.create(dialect, resultSet); 029 return new SimpleResultSet<>(context, convertingResultSet, rowMapper, this); 030 } 031 032 private ResultSet doExecuteQuery() { 033 try { 034 return statement.executeQuery(); 035 } catch (final SQLException e) { 036 throw new UncheckedSQLException("Error executing query '" + sql + "'", e); 037 } 038 } 039 040 /** 041 * @see PreparedStatement#executeUpdate() 042 */ 043 int executeUpdate() { 044 try { 045 return statement.executeUpdate(); 046 } catch (final SQLException e) { 047 throw new UncheckedSQLException("Error executing statement '" + sql + "'", e); 048 } 049 } 050 051 @Override 052 public void close() { 053 try { 054 statement.close(); 055 } catch (final SQLException e) { 056 throw new UncheckedSQLException("Error closing statement", e); 057 } 058 } 059 060 /** 061 * Set the values for the prepared statement. 062 * 063 * @param preparedStatementSetter prepared statement setter 064 */ 065 public void setValues(final PreparedStatementSetter preparedStatementSetter) { 066 try { 067 preparedStatementSetter.setValues(statement); 068 } catch (final SQLException e) { 069 throw new UncheckedSQLException("Error setting values for prepared statement", e); 070 } 071 } 072 073 /** 074 * Execute the batch statement. 075 * 076 * @return array of update counts 077 * @see Statement#executeBatch() 078 */ 079 public int[] executeBatch() { 080 try { 081 return statement.executeBatch(); 082 } catch (final SQLException e) { 083 throw new UncheckedSQLException("Error executing batch sql '" + sql + "'", e); 084 } 085 } 086 087 /** 088 * Add the current set of parameters to the batch. 089 * 090 * @see PreparedStatement#addBatch() 091 */ 092 public void addBatch() { 093 try { 094 this.statement.addBatch(); 095 } catch (final SQLException e) { 096 throw new UncheckedSQLException("Error adding batch", e); 097 } 098 } 099 100 SimpleParameterMetaData getParameterMetadata() { 101 try { 102 return SimpleParameterMetaData.create(statement.getParameterMetaData()); 103 } catch (final SQLException e) { 104 throw new UncheckedSQLException("Error getting parameter metadata", e); 105 } 106 } 107 108 /** 109 * Get the underlying {@link PreparedStatement}. 110 * 111 * @return the underlying {@link PreparedStatement} 112 */ 113 public PreparedStatement getStatement() { 114 return statement; 115 } 116}