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.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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 org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,16 +23,15 @@ import java.util.stream.Collectors;
|
|||||||
* <p>
|
* <p>
|
||||||
* The ClickHouse container's {@code CLICKHOUSE_DB} env var creates the database;
|
* The ClickHouse container's {@code CLICKHOUSE_DB} env var creates the database;
|
||||||
* this class creates the tables within it.
|
* 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
|
@Configuration
|
||||||
public class ClickHouseConfig {
|
public class ClickHouseConfig {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ClickHouseConfig.class);
|
private static final Logger log = LoggerFactory.getLogger(ClickHouseConfig.class);
|
||||||
private static final String[] SCHEMA_FILES = {
|
private static final String MIGRATION_PATTERN = "classpath:clickhouse/*.sql";
|
||||||
"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 final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
|
||||||
@@ -45,25 +47,34 @@ public class ClickHouseConfig {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
void initSchema() {
|
void initSchema() {
|
||||||
var jdbc = new JdbcTemplate(dataSource);
|
var jdbc = new JdbcTemplate(dataSource);
|
||||||
for (String schemaFile : SCHEMA_FILES) {
|
try {
|
||||||
try {
|
Resource[] resources = new PathMatchingResourcePatternResolver()
|
||||||
String sql = new ClassPathResource(schemaFile).getContentAsString(StandardCharsets.UTF_8);
|
.getResources(MIGRATION_PATTERN);
|
||||||
// Strip comment lines before splitting — a statement preceded by
|
Arrays.sort(resources, Comparator.comparing(Resource::getFilename));
|
||||||
// comment lines would otherwise be skipped entirely.
|
|
||||||
String stripped = sql.lines()
|
for (Resource resource : resources) {
|
||||||
.filter(line -> !line.trim().startsWith("--"))
|
String filename = resource.getFilename();
|
||||||
.collect(Collectors.joining("\n"));
|
try {
|
||||||
for (String statement : stripped.split(";")) {
|
String sql = resource.getContentAsString(StandardCharsets.UTF_8);
|
||||||
String trimmed = statement.trim();
|
String stripped = sql.lines()
|
||||||
if (!trimmed.isEmpty()) {
|
.filter(line -> !line.trim().startsWith("--"))
|
||||||
jdbc.execute(trimmed);
|
.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