From b940bf0eb1d7f259017a3b66f0f0681a9b284e9f Mon Sep 17 00:00:00 2001 From: zgw <13623675548@163.com> Date: Fri, 4 Sep 2026 11:47:01 +0800 Subject: [PATCH] fix: support database collation in shadow scripts --- .../resources/db/sqlserver/uninstall-shadow.sql | 4 ++-- .../db/sqlserver/upgrade-shadow-v2-to-v3.sql | 12 ++++++------ .../ShadowSqlServerMigrationScriptTest.java | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql index 21d0e02..8194ebf 100644 --- a/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall-shadow.sql @@ -7,8 +7,8 @@ DECLARE @expected_objects TABLE (object_name sysname NOT NULL PRIMARY KEY, objec INSERT INTO @expected_objects VALUES (N'shadow_package_manifest','U'),(N'warehouse_policy','U'),(N'project_policy','U'),(N'space_role','U'),(N'space_topology','U'),(N'inventory_item_snapshot','U'),(N'space_inventory_summary','U'),(N'lane_state','U'),(N'reservation','U'),(N'deep_workflow_lock','U'),(N'decision_log','U'),(N'shadow_snapshot_state','U'),(N'cargo_space_snapshot','U'),(N'active_job_snapshot','U'),(N'shadow_inbound_request_snapshot','U'),(N'shadow_outbound_request_snapshot','U'),(N'shadow_runtime_metric','U'),(N'shadow_instance_heartbeat','U'), (N'v_inventory_item','V'),(N'v_active_job','V'),(N'v_space_state','V'),(N'usp_rebuild_space_topology','P'),(N'usp_sync_inventory_snapshot','P'),(N'usp_compute_lane_semantic_fingerprint','P'),(N'usp_rebuild_lane_state','P'),(N'usp_refresh_dirty_lanes','P'),(N'usp_claim_shadow_instance','P'),(N'usp_refresh_shadow_snapshot','P'); -IF EXISTS (SELECT 1 FROM sys.objects object LEFT JOIN @expected_objects expected ON expected.object_name = object.name AND expected.object_type = object.type WHERE object.schema_id = SCHEMA_ID(N'alg') AND object.is_ms_shipped = 0 AND object.parent_object_id = 0 AND expected.object_name IS NULL) THROW 51013, 'FT546 shadow uninstall refused: unknown object exists in alg schema', 1; -IF EXISTS (SELECT 1 FROM @expected_objects expected LEFT JOIN sys.objects object ON object.schema_id=SCHEMA_ID(N'alg') AND object.name=expected.object_name AND object.type=expected.object_type WHERE object.object_id IS NULL) THROW 51014, 'FT546 shadow uninstall refused: expected object is missing or has wrong type', 1; +IF EXISTS (SELECT 1 FROM sys.objects object LEFT JOIN @expected_objects expected ON expected.object_name = object.name AND expected.object_type = object.type COLLATE DATABASE_DEFAULT WHERE object.schema_id = SCHEMA_ID(N'alg') AND object.is_ms_shipped = 0 AND object.parent_object_id = 0 AND expected.object_name IS NULL) THROW 51013, 'FT546 shadow uninstall refused: unknown object exists in alg schema', 1; +IF EXISTS (SELECT 1 FROM @expected_objects expected LEFT JOIN sys.objects object ON object.schema_id=SCHEMA_ID(N'alg') AND object.name=expected.object_name AND object.type COLLATE DATABASE_DEFAULT=expected.object_type WHERE object.object_id IS NULL) THROW 51014, 'FT546 shadow uninstall refused: expected object is missing or has wrong type', 1; BEGIN TRY BEGIN TRANSACTION; DROP PROCEDURE alg.usp_refresh_shadow_snapshot; DROP PROCEDURE alg.usp_claim_shadow_instance; DROP PROCEDURE alg.usp_refresh_dirty_lanes; DROP PROCEDURE alg.usp_rebuild_lane_state; DROP PROCEDURE alg.usp_compute_lane_semantic_fingerprint; DROP PROCEDURE alg.usp_sync_inventory_snapshot; DROP PROCEDURE alg.usp_rebuild_space_topology; diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql index 852cea7..07e63c1 100644 --- a/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql @@ -81,7 +81,7 @@ BEGIN FROM sys.objects object LEFT JOIN @expected_v3 expected ON expected.object_name = N'alg.' + object.name - AND expected.object_type = object.type + AND expected.object_type = object.type COLLATE DATABASE_DEFAULT WHERE object.schema_id = SCHEMA_ID(N'alg') AND object.is_ms_shipped = 0 AND object.parent_object_id = 0 @@ -95,7 +95,7 @@ BEGIN LEFT JOIN sys.objects object ON object.schema_id = SCHEMA_ID(N'alg') AND N'alg.' + object.name = expected.object_name - AND object.type = expected.object_type + AND object.type COLLATE DATABASE_DEFAULT = expected.object_type WHERE object.object_id IS NULL ) THROW 51033, 'FT546 shadow upgrade refused: expected object is missing or has wrong type', 1; @@ -114,7 +114,7 @@ IF EXISTS ( FROM sys.objects object LEFT JOIN @expected_v2 expected ON expected.object_name = N'alg.' + object.name - AND expected.object_type = object.type + AND expected.object_type = object.type COLLATE DATABASE_DEFAULT WHERE object.schema_id = SCHEMA_ID(N'alg') AND object.is_ms_shipped = 0 AND object.parent_object_id = 0 @@ -128,7 +128,7 @@ IF EXISTS ( LEFT JOIN sys.objects object ON object.schema_id = SCHEMA_ID(N'alg') AND N'alg.' + object.name = expected.object_name - AND object.type = expected.object_type + AND object.type COLLATE DATABASE_DEFAULT = expected.object_type WHERE object.object_id IS NULL ) THROW 51036, 'FT546 shadow upgrade refused: expected object is missing or has wrong type', 1; @@ -1332,7 +1332,7 @@ BEGIN TRY FROM sys.objects object LEFT JOIN @expected_v3_post expected ON expected.object_name = N'alg.' + object.name - AND expected.object_type = object.type + AND expected.object_type = object.type COLLATE DATABASE_DEFAULT WHERE object.schema_id = SCHEMA_ID(N'alg') AND object.is_ms_shipped = 0 AND object.parent_object_id = 0 @@ -1346,7 +1346,7 @@ BEGIN TRY LEFT JOIN sys.objects object ON object.schema_id = SCHEMA_ID(N'alg') AND N'alg.' + object.name = expected.object_name - AND object.type = expected.object_type + AND object.type COLLATE DATABASE_DEFAULT = expected.object_type WHERE object.object_id IS NULL ) THROW 51033, 'FT546 shadow upgrade refused: expected object is missing or has wrong type', 1; diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java index 9ecc6fc..4520290 100644 --- a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java @@ -175,6 +175,19 @@ class ShadowSqlServerMigrationScriptTest { "expected object is missing or has wrong type"); } + @Test + void metadataTypeAllowListsUseDatabaseCollationAcrossUpgradeAndUninstall() throws IOException { + String upgrade = normalize(resource("db/sqlserver/upgrade-shadow-v2-to-v3.sql")); + String uninstall = normalize(resource("db/sqlserver/uninstall-shadow.sql")); + + assertThat(matches(upgrade, "object\\.type\\s+collate\\s+database_default")) + .as("all six upgrade metadata type comparisons") + .isEqualTo(6); + assertThat(matches(uninstall, "object\\.type\\s+collate\\s+database_default")) + .as("both uninstall metadata type comparisons") + .isEqualTo(2); + } + @Test void refreshCopiesInputsChecksSourceStabilityAndPublishesInsideOneTransaction() throws IOException { String install = normalize(resource("db/sqlserver/install-shadow.sql")); @@ -350,6 +363,10 @@ class ShadowSqlServerMigrationScriptTest { return count; } + private long matches(String value, String regex) { + return Pattern.compile(regex).matcher(value).results().count(); + } + private Set objects(String sql, Pattern pattern) { Matcher matcher = pattern.matcher(sql); Set objects = new LinkedHashSet<>();