package org.simpleflatmapper.jdbc.impl; import org.simpleflatmapper.jdbc.MultiIndexFieldMapper; import org.simpleflatmapper.jdbc.QueryBinder; import org.simpleflatmapper.jdbc.QueryPreparer; import org.simpleflatmapper.jdbc.SizeSupplier; import org.simpleflatmapper.jdbc.named.NamedSqlQuery; import org.simpleflatmapper.map.Mapper; import org.simpleflatmapper.util.Asserts; import org.simpleflatmapper.util.ErrorHelper; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class MultiIndexQueryPreparer<T> implements QueryPreparer<T> { private final NamedSqlQuery query; private final MultiIndexFieldMapper<T>[] multiIndexFieldMappers; private final String[] generatedKeys; public MultiIndexQueryPreparer(NamedSqlQuery query, MultiIndexFieldMapper<T>[] multiIndexFieldMappers, String[] generatedKeys) { this.query = query; this.multiIndexFieldMappers = multiIndexFieldMappers; this.generatedKeys = generatedKeys; } @Override public QueryBinder<T> prepare(Connection connection) throws SQLException { return new MultiIndexQueryBinder(connection); } @Override public PreparedStatement prepareStatement(Connection connection) throws SQLException { throw new UnsupportedOperationException(); } @Override public Mapper<T, PreparedStatement> mapper() { throw new UnsupportedOperationException(); } @Override public String toRewrittenSqlQuery(final T value) { return query.toSqlQuery(new SizeSupplier() { @Override public int getSize(int columnIndex) { return multiIndexFieldMappers[columnIndex].getSize(value); } }); } public class MultiIndexQueryBinder implements QueryBinder<T> { private final Connection connection; protected MultiIndexQueryBinder(Connection connection) { this.connection = connection; } @Override public PreparedStatement bind(T value) throws SQLException { PreparedStatement ps = createPreparedStatement(value); try { int columnIndex = 0; for (int i = 0; i < multiIndexFieldMappers.length; i++) { columnIndex += multiIndexFieldMappers[i].map(ps, value, columnIndex); } return ps; } catch (Exception e) { try { ps.close(); } catch (SQLException sqle) { // IGNORE } ErrorHelper.rethrow(e); return null; } } @Override public void bindTo(T value, PreparedStatement ps) throws SQLException { throw new UnsupportedOperationException(); } private PreparedStatement createPreparedStatement(final T value) throws SQLException { String sql = toRewrittenSqlQuery(value); if (generatedKeys != null && generatedKeys.length > 0) { return connection.prepareStatement(sql, generatedKeys); } else { return connection.prepareStatement(sql); } } } }