DIP/src/main/java/at/procon/ted/startup/OrganizationSchemaFixRunner...

105 lines
4.2 KiB
Java

package at.procon.ted.startup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
/**
* Startup runner that fixes the organization table schema if needed.
* This is a workaround for Flyway V2 migration not being applied automatically.
*
* Extends VARCHAR fields to handle long TED data.
*
* @author Martin.Schweitzer@procon.co.at and claude.ai
*/
@Component
@Order(1) // Run before other startup runners
@RequiredArgsConstructor
@Slf4j
public class OrganizationSchemaFixRunner implements ApplicationRunner {
private final JdbcTemplate jdbcTemplate;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("Checking organization table schema...");
try {
// Check if schema fix is needed by trying to query column types
String checkSql = """
SELECT column_name, character_maximum_length, data_type
FROM information_schema.columns
WHERE table_schema = 'ted'
AND table_name = 'organization'
AND column_name IN ('postal_code', 'company_id', 'name')
ORDER BY column_name
""";
var columnInfo = jdbcTemplate.queryForList(checkSql);
boolean needsFix = false;
for (var row : columnInfo) {
String columnName = (String) row.get("column_name");
Integer maxLength = (Integer) row.get("character_maximum_length");
String dataType = (String) row.get("data_type");
log.debug("Column {}: type={}, max_length={}", columnName, dataType, maxLength);
// Check if any field is still too small
if ("postal_code".equals(columnName) && maxLength != null && maxLength < 255) {
needsFix = true;
log.warn("Column postal_code is too small: {} chars, needs 255", maxLength);
}
if ("company_id".equals(columnName) && maxLength != null && maxLength < 255) {
needsFix = true;
log.warn("Column company_id is too small: {} chars, needs 255", maxLength);
}
}
if (needsFix) {
log.warn("Organization table schema needs fixing - applying migration...");
applySchemaFix();
log.info("Organization table schema fixed successfully!");
} else {
log.info("Organization table schema is up to date");
}
} catch (Exception e) {
log.error("Failed to check/fix organization table schema: {}", e.getMessage(), e);
throw e;
}
}
private void applySchemaFix() {
log.info("Applying schema fix to ted.organization table...");
// Apply all column type changes
// Use TEXT for fields that can be extremely long
String[] alterStatements = {
"ALTER TABLE ted.organization ALTER COLUMN postal_code TYPE TEXT",
"ALTER TABLE ted.organization ALTER COLUMN street_name TYPE TEXT",
"ALTER TABLE ted.organization ALTER COLUMN city TYPE TEXT", // Some cities have very long names
"ALTER TABLE ted.organization ALTER COLUMN phone TYPE VARCHAR(100)",
"ALTER TABLE ted.organization ALTER COLUMN org_reference TYPE VARCHAR(100)",
"ALTER TABLE ted.organization ALTER COLUMN role TYPE VARCHAR(100)",
"ALTER TABLE ted.organization ALTER COLUMN company_id TYPE TEXT", // Can be very long
"ALTER TABLE ted.organization ALTER COLUMN name TYPE TEXT"
};
for (String sql : alterStatements) {
try {
jdbcTemplate.execute(sql);
log.debug("Executed: {}", sql);
} catch (Exception e) {
log.warn("Failed to execute {}: {} (may already be applied)", sql, e.getMessage());
}
}
log.info("Schema fix applied successfully");
}
}