Auto-discover ClickHouse migration files instead of hardcoded list
Replace the static SCHEMA_FILES array with classpath pattern matching (classpath:clickhouse/*.sql). Migration files are discovered and sorted by filename, so adding a new numbered .sql file is all that's needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,12 +4,15 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -20,16 +23,15 @@ import java.util.stream.Collectors;
|
||||
* <p>
|
||||
* The ClickHouse container's {@code CLICKHOUSE_DB} env var creates the database;
|
||||
* this class creates the tables within it.
|
||||
* <p>
|
||||
* Migration files are discovered automatically from {@code classpath:clickhouse/*.sql}
|
||||
* and executed in filename order (numeric prefix sort).
|
||||
*/
|
||||
@Configuration
|
||||
public class ClickHouseConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClickHouseConfig.class);
|
||||
private static final String[] SCHEMA_FILES = {
|
||||
"clickhouse/01-schema.sql", "clickhouse/02-search-columns.sql",
|
||||
"clickhouse/03-users.sql", "clickhouse/04-oidc-config.sql",
|
||||
"clickhouse/05-oidc-auto-signup.sql", "clickhouse/06-oidc-display-name-claim.sql"
|
||||
};
|
||||
private static final String MIGRATION_PATTERN = "classpath:clickhouse/*.sql";
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
@@ -45,25 +47,34 @@ public class ClickHouseConfig {
|
||||
@PostConstruct
|
||||
void initSchema() {
|
||||
var jdbc = new JdbcTemplate(dataSource);
|
||||
for (String schemaFile : SCHEMA_FILES) {
|
||||
try {
|
||||
String sql = new ClassPathResource(schemaFile).getContentAsString(StandardCharsets.UTF_8);
|
||||
// Strip comment lines before splitting — a statement preceded by
|
||||
// comment lines would otherwise be skipped entirely.
|
||||
String stripped = sql.lines()
|
||||
.filter(line -> !line.trim().startsWith("--"))
|
||||
.collect(Collectors.joining("\n"));
|
||||
for (String statement : stripped.split(";")) {
|
||||
String trimmed = statement.trim();
|
||||
if (!trimmed.isEmpty()) {
|
||||
jdbc.execute(trimmed);
|
||||
try {
|
||||
Resource[] resources = new PathMatchingResourcePatternResolver()
|
||||
.getResources(MIGRATION_PATTERN);
|
||||
Arrays.sort(resources, Comparator.comparing(Resource::getFilename));
|
||||
|
||||
for (Resource resource : resources) {
|
||||
String filename = resource.getFilename();
|
||||
try {
|
||||
String sql = resource.getContentAsString(StandardCharsets.UTF_8);
|
||||
String stripped = sql.lines()
|
||||
.filter(line -> !line.trim().startsWith("--"))
|
||||
.collect(Collectors.joining("\n"));
|
||||
for (String statement : stripped.split(";")) {
|
||||
String trimmed = statement.trim();
|
||||
if (!trimmed.isEmpty()) {
|
||||
jdbc.execute(trimmed);
|
||||
}
|
||||
}
|
||||
log.info("Applied schema: {}", filename);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to apply schema: {}", filename, e);
|
||||
throw new RuntimeException("Schema initialization failed: " + filename, e);
|
||||
}
|
||||
log.info("Applied schema: {}", schemaFile);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to apply schema: {}", schemaFile, e);
|
||||
throw new RuntimeException("Schema initialization failed: " + schemaFile, e);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to discover migration files", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user