import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; /** * One-off migration: adds b_i18n varchar(150) null to dbo.s_power * (i18n resource key for permission point names, see FMS新系统核心表结构设计.md 14.1). * Idempotent: skips the ALTER TABLE when the column already exists. */ public final class AddSPowerI18nColumn { public static void main(String[] args) throws Exception { Path apiRoot = Path.of("").toAbsolutePath().normalize(); Path configPath = apiRoot.resolve("config/dbconfigs/g3hd.properties").normalize(); Properties properties = new Properties(); try (InputStream input = Files.newInputStream(configPath)) { properties.load(input); } try (Connection connection = DriverManager.getConnection( required(properties, "url"), required(properties, "username"), required(properties, "password"))) { if (!"FMS".equalsIgnoreCase(connection.getCatalog())) { throw new IllegalStateException("Refusing to alter database: " + connection.getCatalog()); } try (Statement statement = connection.createStatement()) { boolean exists; try (ResultSet rows = statement.executeQuery( "SELECT CASE WHEN COL_LENGTH(N'dbo.s_power', N'b_i18n') IS NULL THEN 0 ELSE 1 END")) { rows.next(); exists = rows.getInt(1) == 1; } if (exists) { System.out.println("SKIP|dbo.s_power.b_i18n already exists"); } else { statement.executeUpdate("ALTER TABLE dbo.s_power ADD b_i18n varchar(150) NULL"); System.out.println("APPLIED|ALTER TABLE dbo.s_power ADD b_i18n varchar(150) NULL"); } try (ResultSet rows = statement.executeQuery( "SELECT c.name, t.name, c.max_length, c.is_nullable " + "FROM sys.columns c JOIN sys.types t ON t.user_type_id = c.user_type_id " + "WHERE c.object_id = OBJECT_ID(N'dbo.s_power') AND c.name = N'b_i18n'")) { if (!rows.next()) throw new IllegalStateException("Column b_i18n not found after migration"); System.out.println("VERIFY|" + rows.getString(1) + "|" + rows.getString(2) + "(" + rows.getInt(3) + ")|nullable=" + rows.getInt(4)); } } } } private static String required(Properties properties, String key) { String value = properties.getProperty(key); if (value == null || value.isBlank()) throw new IllegalStateException("Missing property: " + key); return value; } }