Skip to content

Commit

Permalink
Add converting prepared statement
Browse files Browse the repository at this point in the history
  • Loading branch information
kaklakariada committed Oct 20, 2024
1 parent af390eb commit 4e21c42
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private BatchInsertBuilder<NameRow> testee() {
final PreparedStatement stmt = createNoopPreparedStatement();
when(connectionMock.prepareStatement(anyString()))
.thenReturn(new SimplePreparedStatement(null, null, stmt, "sql"));
return new BatchInsertBuilder<NameRow>(connectionMock::prepareStatement, Context.builder().build());
return new BatchInsertBuilder<NameRow>(connectionMock::prepareStatement);
}

private PreparedStatement createNoopPreparedStatement() {
Expand Down
16 changes: 16 additions & 0 deletions src/integrationTest/java/org/itsallcode/jdbc/ExasolTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.JDBCType;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Stream;

import org.itsallcode.jdbc.resultset.SimpleResultSet;
Expand Down Expand Up @@ -172,6 +174,20 @@ private static Arguments typeTest(final String value, final String type, final O

record TypeTest(String value, String type, Object expectedValue, JDBCType expectedType, String expectedTypeName,
String expectedClassName) {
}

@Test
void batchInsert() {
final LocalDate date = LocalDate.parse("2024-10-20");
try (final SimpleConnection connection = connect()) {
connection.executeStatement("create schema test");
connection.executeStatement("create table tab(col date)");
connection.batchInsert(LocalDate.class).into("TAB", List.of("COL"))
.mapping((row, stmt) -> stmt.setObject(1, row)).rows(Stream.of(date)).start();
try (SimpleResultSet<LocalDate> resultSet = connection.query("select * from tab",
(rs, rowNum) -> rs.getObject(1, LocalDate.class))) {
assertEquals(date, resultSet.toList().get(0));
}
}
}
}
7 changes: 2 additions & 5 deletions src/main/java/org/itsallcode/jdbc/BatchInsertBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ public class BatchInsertBuilder<T> {
private static final Logger LOG = Logger.getLogger(BatchInsertBuilder.class.getName());
private static final int DEFAULT_MAX_BATCH_SIZE = 200_000;
private final Function<String, SimplePreparedStatement> statementFactory;
private final Context context;
private String sql;
private RowPreparedStatementSetter<T> mapper;
private Iterator<T> rows;
private int maxBatchSize = DEFAULT_MAX_BATCH_SIZE;

BatchInsertBuilder(final Function<String, SimplePreparedStatement> statementFactory, final Context context) {
BatchInsertBuilder(final Function<String, SimplePreparedStatement> statementFactory) {
this.statementFactory = statementFactory;
this.context = context;
}

/**
Expand Down Expand Up @@ -86,8 +84,7 @@ public BatchInsertBuilder<T> rows(final Iterator<T> rows) {
* @return {@code this} for fluent programming
*/
public BatchInsertBuilder<T> mapping(final ParamConverter<T> rowMapper) {
final RowPreparedStatementSetter<Object[]> setter = new ObjectArrayPreparedStatementSetter(
context.getParameterMapper());
final RowPreparedStatementSetter<Object[]> setter = new ObjectArrayPreparedStatementSetter();
return mapping(
(final T row, final PreparedStatement preparedStatement) -> setter.setValues(rowMapper.map(row),
preparedStatement));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@
import java.sql.SQLException;

class ObjectArrayPreparedStatementSetter implements RowPreparedStatementSetter<Object[]> {
private final ParameterMapper mapper;

ObjectArrayPreparedStatementSetter(final ParameterMapper mapper) {
this.mapper = mapper;
}

public void setValues(final Object[] row, final PreparedStatement preparedStatement) throws SQLException {
int parameterIndex = 1;
for (final Object arg : row) {
preparedStatement.setObject(parameterIndex, mapper.map(arg));
preparedStatement.setObject(parameterIndex, arg);
parameterIndex++;
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/org/itsallcode/jdbc/SimpleConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.itsallcode.jdbc.dialect.DbDialect;
import org.itsallcode.jdbc.resultset.*;
import org.itsallcode.jdbc.resultset.generic.Row;
import org.itsallcode.jdbc.statement.ConvertingPreparedStatement;

/**
* A simplified version of a JDBC {@link Connection}. Create new connections
Expand Down Expand Up @@ -97,7 +98,11 @@ public <T> SimpleResultSet<T> query(final String sql, final PreparedStatementSet
}

SimplePreparedStatement prepareStatement(final String sql) {
return new SimplePreparedStatement(context, dialect, prepare(sql), sql);
return new SimplePreparedStatement(context, dialect, wrap(prepare(sql)), sql);
}

private PreparedStatement wrap(final PreparedStatement preparedStatement) {
return new ConvertingPreparedStatement(preparedStatement, context.getParameterMapper());
}

/**
Expand All @@ -108,7 +113,7 @@ SimplePreparedStatement prepareStatement(final String sql) {
* @return batch insert builder
*/
public <T> BatchInsertBuilder<T> batchInsert(final Class<T> rowType) {
return new BatchInsertBuilder<>(this::prepareStatement, context);
return new BatchInsertBuilder<>(this::prepareStatement);
}

private PreparedStatement prepare(final String sql) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.itsallcode.jdbc.statement;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.itsallcode.jdbc.ParameterMapper;

public class ConvertingPreparedStatement extends DelegatingPreparedStatement {

private final ParameterMapper parameterMapper;

public ConvertingPreparedStatement(final PreparedStatement delegate, final ParameterMapper parameterMapper) {
super(delegate);
this.parameterMapper = parameterMapper;
}

@Override
public void setObject(final int parameterIndex, final Object x) throws SQLException {
super.setObject(parameterIndex, convert(x));
}

private Object convert(final Object object) {
return parameterMapper.map(object);
}
}

0 comments on commit 4e21c42

Please sign in to comment.