diff --git a/.github/workflows/liquibase-upgrade.yml b/.github/workflows/liquibase-upgrade.yml index 72f96bb..ee90c12 100644 --- a/.github/workflows/liquibase-upgrade.yml +++ b/.github/workflows/liquibase-upgrade.yml @@ -9,6 +9,7 @@ on: - 'tools/tests/test_liquibase_1.2.7_to_head_upgrade.sh' - 'tools/tests/test_liquibase_codelist_auth_mode_swap.sh' - 'tools/tests/test_prepare_extracted_liquibase.py' + - 'tools/tests/test_service_check_observed_rebuild_order.py' - 'tools/bin/prepare_extracted_liquibase.py' - '.github/workflows/liquibase-upgrade.yml' workflow_dispatch: @@ -29,6 +30,9 @@ jobs: - name: Extracted-tree helper unit tests run: python3 tools/tests/test_prepare_extracted_liquibase.py + - name: Service-check observed rebuild order + run: python3 tools/tests/test_service_check_observed_rebuild_order.py + postgres-1-2-7-to-head: runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/CHANGELOG.md b/CHANGELOG.md index e40f96b..e5e89e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), #### Profile-level - **Liquibase**: Development changelog 89, and PostgreSQL and Oracle changelog 33, alter `STM_SERVICE_CHECK.SEC_OBSERVED` and `STM_SERVICE_CHECK_SAMPLE.SCS_OBSERVED` to `TIMESTAMP(6) WITH TIME ZONE` on Oracle ([sitmun-admin-app#516](https://github.com/sitmun/sitmun-admin-app/issues/516)). +- **Liquibase**: Development changelog 91, and PostgreSQL and Oracle changelog 35, copy populated `SEC_OBSERVED` and `SCS_OBSERVED` values as UTC before that `ALTER`. The `ALTER` changesets are unchanged ([#135](https://github.com/sitmun/sitmun-application-stack/issues/135)). ### Security diff --git a/back/backend/sitmun-backend-core b/back/backend/sitmun-backend-core index a9ba615..747461c 160000 --- a/back/backend/sitmun-backend-core +++ b/back/backend/sitmun-backend-core @@ -1 +1 @@ -Subproject commit a9ba615be04b2cb1e17e9d587a39658754d82b9f +Subproject commit 747461c4c481ffe3b1e418f010bc984285717399 diff --git a/profiles/development/backend/liquibase/changelog/91_service_check_observed_timestamptz_rebuild.sql b/profiles/development/backend/liquibase/changelog/91_service_check_observed_timestamptz_rebuild.sql new file mode 100644 index 0000000..b60a42d --- /dev/null +++ b/profiles/development/backend/liquibase/changelog/91_service_check_observed_timestamptz_rebuild.sql @@ -0,0 +1,103 @@ +--liquibase formatted sql + +-- Oracle raises ORA-01439 when ALTER MODIFY changes TIMESTAMP to +-- TIMESTAMP WITH TIME ZONE and the column already has values. +-- Copy each value onto a new column as UTC. The backend stores these +-- instants with hibernate.jdbc.time_zone set to UTC. +-- The later ALTER changeset sees TIMESTAMP(6) WITH TIME ZONE and is skipped. + +--changeset sitmun:91-service-check-sec-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED_TZ'; + END IF; + ELSE + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK ADD (SEC_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK SET SEC_OBSERVED_TZ = FROM_TZ(SEC_OBSERVED, ''UTC'') WHERE SEC_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK RENAME COLUMN SEC_OBSERVED_TZ TO SEC_OBSERVED'; + END IF; +END; +/ + +--changeset sitmun:91-service-check-scs-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_idx NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED_TZ'; + END IF; + ELSE + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 1 THEN + EXECUTE IMMEDIATE 'DROP INDEX STM_SCS_IX_SER_OBS'; + END IF; + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE ADD (SCS_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK_SAMPLE SET SCS_OBSERVED_TZ = FROM_TZ(SCS_OBSERVED, ''UTC'') WHERE SCS_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE RENAME COLUMN SCS_OBSERVED_TZ TO SCS_OBSERVED'; + END IF; + + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 0 THEN + EXECUTE IMMEDIATE 'CREATE INDEX STM_SCS_IX_SER_OBS ON STM_SERVICE_CHECK_SAMPLE (SCS_SERID, SCS_OBSERVED)'; + END IF; +END; +/ diff --git a/profiles/development/backend/liquibase/master.xml b/profiles/development/backend/liquibase/master.xml index f75d145..f84e17f 100644 --- a/profiles/development/backend/liquibase/master.xml +++ b/profiles/development/backend/liquibase/master.xml @@ -95,6 +95,8 @@ + + diff --git a/profiles/oracle/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql b/profiles/oracle/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql new file mode 100644 index 0000000..bfd6a86 --- /dev/null +++ b/profiles/oracle/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql @@ -0,0 +1,103 @@ +--liquibase formatted sql + +-- Oracle raises ORA-01439 when ALTER MODIFY changes TIMESTAMP to +-- TIMESTAMP WITH TIME ZONE and the column already has values. +-- Copy each value onto a new column as UTC. The backend stores these +-- instants with hibernate.jdbc.time_zone set to UTC. +-- The later ALTER changeset sees TIMESTAMP(6) WITH TIME ZONE and is skipped. + +--changeset sitmun:35-service-check-sec-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED_TZ'; + END IF; + ELSE + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK ADD (SEC_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK SET SEC_OBSERVED_TZ = FROM_TZ(SEC_OBSERVED, ''UTC'') WHERE SEC_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK RENAME COLUMN SEC_OBSERVED_TZ TO SEC_OBSERVED'; + END IF; +END; +/ + +--changeset sitmun:35-service-check-scs-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_idx NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED_TZ'; + END IF; + ELSE + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 1 THEN + EXECUTE IMMEDIATE 'DROP INDEX STM_SCS_IX_SER_OBS'; + END IF; + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE ADD (SCS_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK_SAMPLE SET SCS_OBSERVED_TZ = FROM_TZ(SCS_OBSERVED, ''UTC'') WHERE SCS_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE RENAME COLUMN SCS_OBSERVED_TZ TO SCS_OBSERVED'; + END IF; + + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 0 THEN + EXECUTE IMMEDIATE 'CREATE INDEX STM_SCS_IX_SER_OBS ON STM_SERVICE_CHECK_SAMPLE (SCS_SERID, SCS_OBSERVED)'; + END IF; +END; +/ diff --git a/profiles/oracle/liquibase/master.xml b/profiles/oracle/liquibase/master.xml index 6d0ee84..68c5d53 100644 --- a/profiles/oracle/liquibase/master.xml +++ b/profiles/oracle/liquibase/master.xml @@ -37,6 +37,8 @@ + + diff --git a/profiles/postgres/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql b/profiles/postgres/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql new file mode 100644 index 0000000..bfd6a86 --- /dev/null +++ b/profiles/postgres/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql @@ -0,0 +1,103 @@ +--liquibase formatted sql + +-- Oracle raises ORA-01439 when ALTER MODIFY changes TIMESTAMP to +-- TIMESTAMP WITH TIME ZONE and the column already has values. +-- Copy each value onto a new column as UTC. The backend stores these +-- instants with hibernate.jdbc.time_zone set to UTC. +-- The later ALTER changeset sees TIMESTAMP(6) WITH TIME ZONE and is skipped. + +--changeset sitmun:35-service-check-sec-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK' AND column_name = 'SEC_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED_TZ'; + END IF; + ELSE + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK ADD (SEC_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK SET SEC_OBSERVED_TZ = FROM_TZ(SEC_OBSERVED, ''UTC'') WHERE SEC_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK DROP COLUMN SEC_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK RENAME COLUMN SEC_OBSERVED_TZ TO SEC_OBSERVED'; + END IF; +END; +/ + +--changeset sitmun:35-service-check-scs-observed-rebuild-oracle dbms:oracle splitStatements:false endDelimiter:/ +DECLARE + l_type VARCHAR2(128); + l_tz NUMBER; + l_idx NUMBER; + l_nullable VARCHAR2(1); +BEGIN + BEGIN + SELECT data_type, nullable INTO l_type, l_nullable + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + l_type := NULL; + l_nullable := NULL; + END; + + SELECT COUNT(*) INTO l_tz + FROM user_tab_columns + WHERE table_name = 'STM_SERVICE_CHECK_SAMPLE' AND column_name = 'SCS_OBSERVED_TZ'; + + IF l_type LIKE '%WITH TIME ZONE' THEN + IF l_nullable = 'Y' THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED NOT NULL)'; + END IF; + IF l_tz = 1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED_TZ'; + END IF; + ELSE + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 1 THEN + EXECUTE IMMEDIATE 'DROP INDEX STM_SCS_IX_SER_OBS'; + END IF; + IF l_tz = 0 THEN + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE ADD (SCS_OBSERVED_TZ TIMESTAMP(6) WITH TIME ZONE)'; + END IF; + IF l_type IS NOT NULL THEN + EXECUTE IMMEDIATE 'UPDATE STM_SERVICE_CHECK_SAMPLE SET SCS_OBSERVED_TZ = FROM_TZ(SCS_OBSERVED, ''UTC'') WHERE SCS_OBSERVED_TZ IS NULL'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE DROP COLUMN SCS_OBSERVED'; + ELSE + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE MODIFY (SCS_OBSERVED_TZ NOT NULL)'; + END IF; + EXECUTE IMMEDIATE 'ALTER TABLE STM_SERVICE_CHECK_SAMPLE RENAME COLUMN SCS_OBSERVED_TZ TO SCS_OBSERVED'; + END IF; + + SELECT COUNT(*) INTO l_idx FROM user_indexes WHERE index_name = 'STM_SCS_IX_SER_OBS'; + IF l_idx = 0 THEN + EXECUTE IMMEDIATE 'CREATE INDEX STM_SCS_IX_SER_OBS ON STM_SERVICE_CHECK_SAMPLE (SCS_SERID, SCS_OBSERVED)'; + END IF; +END; +/ diff --git a/profiles/postgres/liquibase/master.xml b/profiles/postgres/liquibase/master.xml index e4d8f6f..e951da9 100644 --- a/profiles/postgres/liquibase/master.xml +++ b/profiles/postgres/liquibase/master.xml @@ -35,6 +35,8 @@ + + diff --git a/tools/tests/test_service_check_observed_rebuild_order.py b/tools/tests/test_service_check_observed_rebuild_order.py new file mode 100644 index 0000000..159bd74 --- /dev/null +++ b/tools/tests/test_service_check_observed_rebuild_order.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Oracle service-check timestamptz rebuild runs before the empty-column ALTER.""" + +from __future__ import annotations + +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] + +TREES = ( + ( + "profiles/oracle/liquibase/master.xml", + "35_service_check_observed_timestamptz_rebuild.sql", + "33_service_check_observed_timestamptz.yaml", + "profiles/oracle/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql", + ), + ( + "profiles/postgres/liquibase/master.xml", + "35_service_check_observed_timestamptz_rebuild.sql", + "33_service_check_observed_timestamptz.yaml", + "profiles/postgres/liquibase/changelog/35_service_check_observed_timestamptz_rebuild.sql", + ), + ( + "profiles/development/backend/liquibase/master.xml", + "91_service_check_observed_timestamptz_rebuild.sql", + "89_service_check_observed_timestamptz.yaml", + "profiles/development/backend/liquibase/changelog/91_service_check_observed_timestamptz_rebuild.sql", + ), +) + + +class ServiceCheckObservedRebuildOrderTest(unittest.TestCase): + def test_rebuild_is_included_before_empty_column_alter(self) -> None: + for master_rel, rebuild_name, alter_name, rebuild_rel in TREES: + master = (ROOT / master_rel).read_text(encoding="utf-8") + rebuild_at = master.find(rebuild_name) + alter_at = master.find(alter_name) + self.assertGreaterEqual(rebuild_at, 0, master_rel) + self.assertGreaterEqual(alter_at, 0, master_rel) + self.assertLess(rebuild_at, alter_at, master_rel) + + rebuild = (ROOT / rebuild_rel).read_text(encoding="utf-8") + self.assertIn( + "UPDATE STM_SERVICE_CHECK SET SEC_OBSERVED_TZ = FROM_TZ(SEC_OBSERVED, ''UTC'')", + rebuild, + ) + self.assertIn( + "UPDATE STM_SERVICE_CHECK_SAMPLE SET SCS_OBSERVED_TZ = FROM_TZ(SCS_OBSERVED, ''UTC'')", + rebuild, + ) + self.assertNotIn("DELETE FROM STM_SERVICE_CHECK", rebuild) + self.assertIn("dbms:oracle", rebuild) + + alter = (ROOT / master_rel).parent.joinpath("changelog", alter_name).read_text( + encoding="utf-8" + ) + self.assertIn( + "ALTER TABLE STM_SERVICE_CHECK MODIFY (SEC_OBSERVED TIMESTAMP(6) WITH TIME ZONE)", + alter, + ) + + +if __name__ == "__main__": + unittest.main()