package uk.co.acuminous.julez.event.source; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import uk.co.acuminous.julez.event.Event; import uk.co.acuminous.julez.event.repository.BaseEventRepository; import uk.co.acuminous.julez.jdbc.DefaultEventSql; import uk.co.acuminous.julez.jdbc.SqlStatementProvider; import uk.co.acuminous.julez.mapper.TwoWayMapper; public class JdbcEventRepository extends BaseEventRepository { private final JdbcTemplate jdbcTemplate; private final TwoWayMapper columnMapper; private final SqlStatementProvider sql; public JdbcEventRepository(DataSource dataSource, TwoWayMapper columnMapper) { this(dataSource, columnMapper, new DefaultEventSql(columnMapper.getValues())); } public JdbcEventRepository(DataSource dataSource, TwoWayMapper columnMapper, SqlStatementProvider sql) { this.jdbcTemplate = new JdbcTemplate(dataSource); this.columnMapper = columnMapper; this.sql = sql; } @Override public void onEvent(Event event) { List<String> columnNames = sql.getColumnNames(); List<Object> params = new ArrayList<Object>(sql.getColumnNames().size()); for (String columnName : columnNames) { String propertyName = columnMapper.getKey(columnName); params.add(event.get(propertyName)); } jdbcTemplate.update(sql.getInsertStatement(), params.toArray()); } @Override public void raise() { jdbcTemplate.query(sql.getSelectStatement(), new EventRaisingRowMapper()); } private class EventRaisingRowMapper implements RowMapper<Event> { private EventRowMapper underlyingMapper = new EventRowMapper(); @Override public Event mapRow(ResultSet rs, int rowNum) throws SQLException { Event event = underlyingMapper.mapRow(rs, rowNum); handler.onEvent(event); return null; } } private class EventRowMapper implements RowMapper<Event> { @Override public Event mapRow(ResultSet rs, int rowNum) throws SQLException { try { Map<String, String> eventData = new HashMap<String, String>(); for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { String columnName = rs.getMetaData().getColumnName(i); String key = columnMapper.getKey(columnName); String value = rs.getString(i); if (key != null && value != null) { eventData.put(key, value); } } return new Event(eventData); } catch (Exception e) { throw new RuntimeException(e); } } } // TODO this is a hack for now. // There's no reason other than my laziness that this should load everything in one go @Override public Iterator<Event> iterator() { return jdbcTemplate.query(sql.getSelectStatement(), new EventRowMapper()).iterator(); } }