fix(update): repair baselined plugin schema

这个提交包含在:
XuqmGroup 2026-07-29 00:40:25 +08:00
父节点 0e962d6214
当前提交 63cc21d812
共有 2 个文件被更改,包括 158 次插入0 次删除

查看文件

@ -0,0 +1,126 @@
-- 部分早期私有化库将 Flyway baseline 直接设置为 V3,但没有执行 V3 的表结构变更。
-- 本迁移按实际字段状态补齐终态契约;已正确执行 V3 的数据库重复运行时不会改坏结构。
DELIMITER //
CREATE PROCEDURE repair_baselined_rn_bundle_contract()
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'md5'
) THEN
ALTER TABLE update_rn_bundle DROP COLUMN md5;
END IF;
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'min_common_version'
) THEN
ALTER TABLE update_rn_bundle DROP COLUMN min_common_version;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'module_type'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN module_type VARCHAR(16) NULL AFTER module_id;
END IF;
ALTER TABLE update_rn_bundle MODIFY COLUMN version VARCHAR(64) NOT NULL;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'app_version_range'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN app_version_range VARCHAR(128) NULL AFTER version;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'built_against_native_baseline_id'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN built_against_native_baseline_id VARCHAR(128) NULL AFTER app_version_range;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'build_id'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN build_id VARCHAR(128) NULL AFTER built_against_native_baseline_id;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'bundle_format'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN bundle_format VARCHAR(32) NULL AFTER build_id;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'common_version_range'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN common_version_range VARCHAR(128) NULL AFTER bundle_format;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'min_native_api_level'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN min_native_api_level INT NULL AFTER common_version_range;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'bundle_sha256'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN bundle_sha256 VARCHAR(64) NULL AFTER min_native_api_level;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'archive_sha256'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN archive_sha256 VARCHAR(64) NULL AFTER bundle_sha256;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'signed_manifest'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN signed_manifest TEXT NULL AFTER bundle_url;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'signing_key_id'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN signing_key_id VARCHAR(64) NULL AFTER signed_manifest;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle' AND column_name = 'signature'
) THEN
ALTER TABLE update_rn_bundle ADD COLUMN signature VARCHAR(256) NULL AFTER signing_key_id;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.statistics
WHERE table_schema = DATABASE() AND table_name = 'update_rn_bundle'
AND index_name = 'idx_rn_release_candidates'
) THEN
ALTER TABLE update_rn_bundle
ADD INDEX idx_rn_release_candidates
(app_key, platform, module_id, publish_status, created_at);
END IF;
-- 旧包没有不可变清单、归档摘要和平台签名,不得成为客户端候选版本。
UPDATE update_rn_bundle
SET publish_status = 'DEPRECATED'
WHERE archive_sha256 IS NULL OR signed_manifest IS NULL OR signature IS NULL;
END//
CALL repair_baselined_rn_bundle_contract()//
DROP PROCEDURE repair_baselined_rn_bundle_contract//
DELIMITER ;

查看文件

@ -29,6 +29,38 @@ class MigrationSchemaContractTest {
); );
} }
@Test
void baselinedPrivateDatabaseRepairContainsTerminalBundleIdentity() throws IOException {
var resource = getClass().getResourceAsStream(
"/db/migration/V7__repair_baselined_rn_bundle_contract.sql"
);
assertTrue(resource != null, "V7 repair migration must be packaged");
String sql;
try (resource) {
sql = new String(resource.readAllBytes(), StandardCharsets.UTF_8);
}
for (String column : new String[] {
"module_type",
"app_version_range",
"built_against_native_baseline_id",
"build_id",
"bundle_format",
"common_version_range",
"min_native_api_level",
"bundle_sha256",
"archive_sha256",
"signed_manifest",
"signing_key_id",
"signature"
}) {
assertTrue(sql.contains("column_name = '" + column + "'"), column + " must be repaired");
}
assertTrue(sql.contains("publish_status = 'DEPRECATED'"));
assertTrue(sql.contains("idx_rn_release_candidates"));
}
private static int occurrences(String value, String token) { private static int occurrences(String value, String token) {
int count = 0; int count = 0;
int offset = 0; int offset = 0;