chore(deploy): synchronize phase3 unified database migration
This commit is contained in:
+70
@@ -50,4 +50,74 @@ class Phase3FinalUnifiedSqlContractTest {
|
||||
.contains("role.role_code IN ('PLATFORM_ADMIN','ORDER_OPERATOR')")
|
||||
.contains("角色授权未完整写入");
|
||||
}
|
||||
|
||||
@Test
|
||||
void phase3ModuleSqlBlocksAreContiguousAndSynchronised() throws Exception {
|
||||
String unified = normalise(Files.readString(resolveUnified()));
|
||||
assertBlock(unified, "-- 来源:order/src/main/resources/db/phase3-order-parent-child-schema.sql",
|
||||
"-- 来源:firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql",
|
||||
"order/src/main/resources/db/phase3-order-parent-child-schema.sql");
|
||||
assertBlock(unified, "-- 来源:firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql",
|
||||
"-- 来源:firstleg/src/main/resources/db/phase3-ocean-booking-schema.sql",
|
||||
"firstleg/src/main/resources/db/phase3-inbound-parent-child-schema.sql");
|
||||
assertBlock(unified, "-- 来源:firstleg/src/main/resources/db/phase3-carrier-schedule-query-schema.sql",
|
||||
"-- 来源:iam/src/main/resources/db/phase3-warehouse-roles.sql",
|
||||
"firstleg/src/main/resources/db/phase3-carrier-schedule-query-schema.sql");
|
||||
assertBlock(unified, "-- 来源:iam/src/main/resources/db/phase3-warehouse-roles.sql",
|
||||
"-- 二、三期对外统一使用 INBOUNDED;历史 WAIT_SPLIT 仅由查询适配为 INBOUNDED,统一迁移不改写主表或历史状态。",
|
||||
"iam/src/main/resources/db/phase3-warehouse-roles.sql");
|
||||
}
|
||||
|
||||
@Test
|
||||
void passIsUniqueAndOnlyTheFinalExecutableStatement() throws Exception {
|
||||
String sql = normalise(Files.readString(resolveUnified()));
|
||||
String pass = "SELECT 'PASS' AS migration_status";
|
||||
assertThat(count(sql, pass)).isEqualTo(1);
|
||||
int passIndex = sql.lastIndexOf(pass);
|
||||
assertThat(passIndex).isGreaterThan(sql.lastIndexOf("USE "))
|
||||
.isGreaterThan(sql.lastIndexOf("ALTER TABLE "))
|
||||
.isGreaterThan(sql.lastIndexOf("CREATE TABLE "))
|
||||
.isGreaterThan(sql.lastIndexOf("CALL "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void legacySplitIndexesAreOnlyDroppedAndNeverRecreated() throws Exception {
|
||||
String sql = normalise(Files.readString(resolveUnified()));
|
||||
assertThat(sql)
|
||||
.contains("DROP INDEX uk_inbound_one_child")
|
||||
.contains("DROP INDEX uk_inbound_one_secondary")
|
||||
.doesNotContain("UNIQUE KEY `uk_inbound_one_child`")
|
||||
.doesNotContain("UNIQUE KEY `uk_inbound_one_secondary`")
|
||||
.doesNotContain("UNIQUE KEY `uk_inbound_split_batch_source_item`");
|
||||
}
|
||||
|
||||
private static void assertBlock(String unified, String marker, String nextMarker, String modulePath)
|
||||
throws Exception {
|
||||
int start = unified.indexOf(marker);
|
||||
int next = unified.indexOf(nextMarker, start + marker.length());
|
||||
assertThat(start).as("missing marker %s", marker).isGreaterThanOrEqualTo(0);
|
||||
assertThat(next).as("missing next marker %s", nextMarker).isGreaterThan(start);
|
||||
String module = normalise(Files.readString(resolve(modulePath))).trim();
|
||||
String block = unified.substring(start + marker.length(), next).trim();
|
||||
assertThat(block).as("module block drift: %s", modulePath)
|
||||
.startsWith(module);
|
||||
}
|
||||
|
||||
private static Path resolveUnified() {
|
||||
return resolve("deploy/sql/头程数据库统一增量-MySQL8.sql");
|
||||
}
|
||||
|
||||
private static Path resolve(String path) {
|
||||
Path direct = Path.of(path);
|
||||
if (Files.exists(direct)) return direct;
|
||||
return Path.of("..", path).normalize();
|
||||
}
|
||||
|
||||
private static String normalise(String value) {
|
||||
return value.replace("\r\n", "\n").replace("\uFEFF", "");
|
||||
}
|
||||
|
||||
private static int count(String value, String token) {
|
||||
return value.split(java.util.regex.Pattern.quote(token), -1).length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user