/** * Returns a comma separated list of tracked domain event column names to select from an event entry. * * @return comma separated tracked domain event column names. */ protected String trackedEventFields() { return schema.globalIndexColumn() + ", " + domainEventFields(); }
GapAwareTrackingToken previousToken = (GapAwareTrackingToken) lastToken; String sql = "SELECT " + trackedEventFields() + " FROM " + schema.domainEventTable() + " WHERE (" + schema.globalIndexColumn() + " > ? AND " + schema.globalIndexColumn() + " <= ?) "; List<Long> gaps; if (previousToken != null) { gaps = new ArrayList<>(previousToken.getGaps()); if (!gaps.isEmpty()) { sql += " OR " + schema.globalIndexColumn() + " IN (" + String.join(",", Collections.nCopies(gaps.size(), "?")) + ") "; gaps = Collections.emptyList(); sql += "ORDER BY " + schema.globalIndexColumn() + " ASC"; PreparedStatement preparedStatement = connection.prepareStatement(sql); long globalIndex = previousToken == null ? -1 : previousToken.getIndex();
@Override public TrackingToken createTailToken() { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get tail token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
@Override public TrackingToken createHeadToken() { String sql = "SELECT max(" + schema.globalIndexColumn() + ") FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get head token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
PreparedStatement statement = conn.prepareStatement(format("SELECT %s, %s FROM %s WHERE %s >= ? AND %s <= ?", schema.globalIndexColumn(), schema.timestampColumn(), schema.domainEventTable(), schema.globalIndexColumn(), schema.globalIndexColumn())); statement.setLong(1, gaps.first()); statement.setLong(2, gaps.last() + 1L); while (resultSet.next()) { try { long sequenceNumber = resultSet.getLong(schema.globalIndexColumn()); Instant timestamp = DateTimeUtils.parseInstant(readTimeStamp(resultSet, schema.timestampColumn()).toString());
@Override public TrackingToken createTokenAt(Instant dateTime) { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable() + " WHERE " + schema.timestampColumn() + " >= ?"; Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> { PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, formatInstant(dateTime)); return stmt; }, resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException(format("Failed to get token at [%s]", dateTime), e))); if (index == null) { return null; } return GapAwareTrackingToken.newInstance(index, Collections.emptySet()); }
PreparedStatement stat = connection.prepareStatement( format("SELECT min(%s) FROM %s WHERE %s > ?", schema.globalIndexColumn(), schema.domainEventTable(), schema.globalIndexColumn())); stat.setLong(1, index); return stat;
long globalSequence = resultSet.getLong(schema.globalIndexColumn());
@Override public PreparedStatement createDomainEventTable(Connection connection, EventSchema schema) throws SQLException { String sql = "CREATE TABLE " + schema.domainEventTable() + " (\n" + schema.globalIndexColumn() + " NUMBER(19) NOT NULL,\n" + schema.aggregateIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.sequenceNumberColumn() + " NUMBER(19) NOT NULL,\n" + schema.typeColumn() + " VARCHAR(255),\n" + schema.eventIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.metaDataColumn() + " " + payloadType() + ",\n" + schema.payloadColumn() + " " + payloadType() + " NOT NULL,\n" + schema.payloadRevisionColumn() + " VARCHAR(255),\n" + schema.payloadTypeColumn() + " VARCHAR(255) NOT NULL,\n" + schema.timestampColumn() + " VARCHAR(255) NOT NULL,\n" + "PRIMARY KEY (" + schema.globalIndexColumn() + "),\n" + "UNIQUE (" + schema.aggregateIdentifierColumn() + ", " + schema.sequenceNumberColumn() + "),\n" + "UNIQUE (" + schema.eventIdentifierColumn() + ")\n" + ")"; try (PreparedStatement pst = connection.prepareStatement(sql)) { pst.execute(); } Oracle11Utils.simulateAutoIncrement(connection, schema.domainEventTable(), schema.globalIndexColumn()); return Oracle11Utils.createNullStatement(connection); }
@Override public PreparedStatement createDomainEventTable(Connection connection, EventSchema schema) throws SQLException { String sql = "CREATE TABLE IF NOT EXISTS " + schema.domainEventTable() + " (\n" + schema.globalIndexColumn() + " " + idColumnType() + " NOT NULL,\n" + schema.aggregateIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.sequenceNumberColumn() + " BIGINT NOT NULL,\n" + schema.typeColumn() + " VARCHAR(255),\n" + schema.eventIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.metaDataColumn() + " " + payloadType() + ",\n" + schema.payloadColumn() + " " + payloadType() + " NOT NULL,\n" + schema.payloadRevisionColumn() + " VARCHAR(255),\n" + schema.payloadTypeColumn() + " VARCHAR(255) NOT NULL,\n" + schema.timestampColumn() + " VARCHAR(255) NOT NULL,\n" + "PRIMARY KEY (" + schema.globalIndexColumn() + "),\n" + "UNIQUE (" + schema.aggregateIdentifierColumn() + ", " + schema.sequenceNumberColumn() + "),\n" + "UNIQUE (" + schema.eventIdentifierColumn() + ")\n" + ")"; return connection.prepareStatement(sql); }
/** * Returns a comma separated list of tracked domain event column names to select from an event entry. * * @return comma separated tracked domain event column names. */ protected String trackedEventFields() { return schema.globalIndexColumn() + ", " + domainEventFields(); }
/** * Returns a comma separated list of tracked domain event column names to select from an event entry. * * @return comma separated tracked domain event column names. */ protected String trackedEventFields() { return schema.globalIndexColumn() + ", " + domainEventFields(); }
@Override public TrackingToken createHeadToken() { String sql = "SELECT max(" + schema.globalIndexColumn() + ") FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get head token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
@Override public TrackingToken createTailToken() { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get tail token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
@Override public TrackingToken createTailToken() { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get tail token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
@Override public TrackingToken createHeadToken() { String sql = "SELECT max(" + schema.globalIndexColumn() + ") FROM " + schema.domainEventTable(); Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> connection.prepareStatement(sql), resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException("Failed to get head token", e))); return Optional.ofNullable(index) .map(seq -> GapAwareTrackingToken.newInstance(seq, Collections.emptySet())) .orElse(null); }
@Override public TrackingToken createTokenAt(Instant dateTime) { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable() + " WHERE " + schema.timestampColumn() + " >= ?"; Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> { PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, formatInstant(dateTime)); return stmt; }, resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException(format("Failed to get token at [%s]", dateTime), e))); if (index == null) { return null; } return GapAwareTrackingToken.newInstance(index, Collections.emptySet()); }
@Override public TrackingToken createTokenAt(Instant dateTime) { String sql = "SELECT min(" + schema.globalIndexColumn() + ") - 1 FROM " + schema.domainEventTable() + " WHERE " + schema.timestampColumn() + " >= ?"; Long index = transactionManager.fetchInTransaction( () -> executeQuery(getConnection(), connection -> { PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, formatInstant(dateTime)); return stmt; }, resultSet -> nextAndExtract(resultSet, 1, Long.class), e -> new EventStoreException(format("Failed to get token at [%s]", dateTime), e))); if (index == null) { return null; } return GapAwareTrackingToken.newInstance(index, Collections.emptySet()); }
@Override public PreparedStatement createDomainEventTable(Connection connection, EventSchema schema) throws SQLException { String sql = "CREATE TABLE IF NOT EXISTS " + schema.domainEventTable() + " (\n" + schema.globalIndexColumn() + " " + idColumnType() + " NOT NULL,\n" + schema.aggregateIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.sequenceNumberColumn() + " BIGINT NOT NULL,\n" + schema.typeColumn() + " VARCHAR(255),\n" + schema.eventIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.metaDataColumn() + " " + payloadType() + ",\n" + schema.payloadColumn() + " " + payloadType() + " NOT NULL,\n" + schema.payloadRevisionColumn() + " VARCHAR(255),\n" + schema.payloadTypeColumn() + " VARCHAR(255) NOT NULL,\n" + schema.timestampColumn() + " VARCHAR(255) NOT NULL,\n" + "PRIMARY KEY (" + schema.globalIndexColumn() + "),\n" + "UNIQUE (" + schema.aggregateIdentifierColumn() + ", " + schema.sequenceNumberColumn() + "),\n" + "UNIQUE (" + schema.eventIdentifierColumn() + ")\n" + ")"; return connection.prepareStatement(sql); }
@Override public PreparedStatement createDomainEventTable(Connection connection, EventSchema schema) throws SQLException { String sql = "CREATE TABLE IF NOT EXISTS " + schema.domainEventTable() + " (\n" + schema.globalIndexColumn() + " " + idColumnType() + " NOT NULL,\n" + schema.aggregateIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.sequenceNumberColumn() + " BIGINT NOT NULL,\n" + schema.typeColumn() + " VARCHAR(255),\n" + schema.eventIdentifierColumn() + " VARCHAR(255) NOT NULL,\n" + schema.metaDataColumn() + " " + payloadType() + ",\n" + schema.payloadColumn() + " " + payloadType() + " NOT NULL,\n" + schema.payloadRevisionColumn() + " VARCHAR(255),\n" + schema.payloadTypeColumn() + " VARCHAR(255) NOT NULL,\n" + schema.timestampColumn() + " VARCHAR(255) NOT NULL,\n" + "PRIMARY KEY (" + schema.globalIndexColumn() + "),\n" + "UNIQUE (" + schema.aggregateIdentifierColumn() + ", " + schema.sequenceNumberColumn()+ "),\n" + "UNIQUE (" + schema.eventIdentifierColumn() + ")\n" + ")"; return connection.prepareStatement(sql); }