kioku-migrations 0.12.0.2 → 0.13.0.0
raw patch · 6 files changed
+160/−37 lines, 6 filesdep ~keiro-migrationsdep ~keiro-test-supportdep ~kioku-migrationsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: keiro-migrations, keiro-test-support, kioku-migrations, kiroku-store-migrations
API changes (from Hackage documentation)
Files
- CHANGELOG.md +11/−1
- kioku-migrations.cabal +10/−8
- test/Main.hs +112/−27
- test/fixtures/kiroku-0.7.1.0/README.md +1/−1
- test/fixtures/kiroku-0.7.2.0/0016.sql +13/−0
- test/fixtures/kiroku-0.7.2.0/README.md +13/−0
CHANGELOG.md view
@@ -1,6 +1,16 @@ # Changelog -## [Unreleased]+## 0.13.0.0 — 2026-11-08++### Changed++- Require mori://shinzui/keiro/packages/keiro-migrations and+ mori://shinzui/keiro/packages/keiro-test-support 0.24.0.0, and+ mori://shinzui/kiroku/packages/kiroku-store-migrations 0.7.3.0.+- Compose 64 entries (17 Kiroku, 32 Keiro, 15 Kioku); only `kiroku/0017`+ applies from a complete 0.12 database. Freeze the released 0.7.2 payload+ and prove data/checkpoint preservation, store identity creation and repeat+ no-op. Historical Kioku SQL/checksums remain unchanged; no ledger fixup. ## 0.12.0.2 — 2026-11-02
kioku-migrations.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: kioku-migrations-version: 0.12.0.2+version: 0.13.0.0 synopsis: Schema migrations for kioku description: Owns kioku schema evolution as a native pg-migrate component and composes@@ -34,6 +34,8 @@ test/fixtures/kiroku-0.7.1.0/*.sql test/fixtures/kiroku-0.7.1.0/README.md test/fixtures/kiroku-0.7.1.0/manifest+ test/fixtures/kiroku-0.7.2.0/*.sql+ test/fixtures/kiroku-0.7.2.0/README.md source-repository head type: git@@ -78,8 +80,8 @@ containers >=0.6 && <0.8, hasql >=1.10 && <1.11, hasql-transaction >=1.2 && <1.3,- keiro-migrations ^>=0.22.0.0,- kiroku-store-migrations ^>=0.7.2.0,+ keiro-migrations ^>=0.24.0.0,+ kiroku-store-migrations ^>=0.7.3.0, pg-migrate ^>=1.2.0.0, pg-migrate-embed ^>=1.2.0.0, pg-migrate-import-codd ^>=1.2.0.0,@@ -95,8 +97,8 @@ base >=4.18 && <5, directory >=1.3 && <1.4, ephemeral-pg >=0.3.1 && <0.4,- keiro-test-support ^>=0.22.0.0,- kioku-migrations ^>=0.12.0.2,+ keiro-test-support ^>=0.24.0.0,+ kioku-migrations ^>=0.13.0.0, text >=2.0 && <2.2, unix >=2.8 && <2.9, @@ -118,10 +120,10 @@ bytestring >=0.11 && <0.13, containers >=0.6 && <0.8, hasql >=1.6,- keiro-migrations ^>=0.22.0.0,- kioku-migrations ^>=0.12.0.2,+ keiro-migrations ^>=0.24.0.0,+ kioku-migrations ^>=0.13.0.0, kioku-migrations:test-support,- kiroku-store-migrations ^>=0.7.2.0,+ kiroku-store-migrations ^>=0.7.3.0, pg-migrate ^>=1.2.0.0, pg-migrate-embed ^>=1.2.0.0, pg-migrate-import-codd ^>=1.2.0.0,
test/Main.hs view
@@ -89,8 +89,9 @@ ], testCase "the full migration chain applies to a fresh database" testFreshDatabase, testCase "0.10.0.0 upgrades with one recency index and unchanged rows" testRecencyUpgrade,- testCase "the released previous cohort preserves data and checkpoints through 0013–0016" testPreviousCohortUpgrade,- testCase "the 62-entry Keiro 0.21 cohort adds only Kiroku 0016" testKeiro021Upgrade,+ testCase "the released previous cohort preserves data and checkpoints through 0013–0017" testPreviousCohortUpgrade,+ testCase "the 62-entry Keiro 0.21 cohort adds Kiroku 0016 and 0017" testKeiro021Upgrade,+ testCase "the 63-entry Keiro 0.22 cohort adds only Kiroku 0017" testKeiro022Upgrade, testCase "a changed previous checksum refuses before migration writes" testKeiro021ChecksumRefusal, testGroup "migration-session isolation"@@ -475,7 +476,7 @@ checkpointsBefore <- query connStr previousCheckpointSnapshot query connStr previousCohortIsLegacy >>= (@?= True) migrated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure- appliedNow migrated @?= [expectRight (migrationId "kiroku" n) | n <- ["0013", "0014", "0015", "0016"]]+ appliedNow migrated @?= [expectRight (migrationId "kiroku" n) | n <- ["0013", "0014", "0015", "0016", "0017"]] query connStr previousCohortSnapshot >>= (@?= before) query connStr previousCohortLedger >>= (@?= ledgerBefore) query connStr previousCheckpointSnapshot >>= (@?= checkpointsBefore)@@ -483,12 +484,12 @@ verification <- verifyMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure let VerificationReport {issues, appliedMigrations, pendingMigrations, unknownMigrations} = verification issues @?= []- length appliedMigrations @?= 63+ length appliedMigrations @?= 64 pendingMigrations @?= [] unknownMigrations @?= [] repeated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure let MigrationReport {results} = repeated- length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 63+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 64 appliedNow repeated @?= [] query connStr previousCohortSnapshot >>= (@?= before) query connStr previousCheckpointSnapshot >>= (@?= checkpointsBefore)@@ -547,7 +548,7 @@ """ SELECT jsonb_agg(to_jsonb(t) ORDER BY component, migration)::text FROM pgmigrate.migrations t- WHERE NOT (component = 'kiroku' AND migration IN ('0013', '0014', '0015', '0016'))+ WHERE NOT (component = 'kiroku' AND migration IN ('0013', '0014', '0015', '0016', '0017')) """ E.noParams (D.singleRow (D.column (D.nonNullable D.text)))@@ -625,10 +626,10 @@ "INSERT INTO kiroku.subscriptions (subscription_name,last_seen,consumer_group_member,consumer_group_size,target_kind,target_category) VALUES ('upgrade-exact',1,0,1,'category','kioku_memory'),('upgrade-all',1,0,1,'all',NULL),('upgrade-unbound',0,0,1,'unbound',NULL)" ) -ledgerWithout0016 :: Statement () Text-ledgerWithout0016 =+ledgerWithout0016And0017 :: Statement () Text+ledgerWithout0016And0017 = preparable- "SELECT jsonb_agg(to_jsonb(t) ORDER BY component,migration)::text FROM pgmigrate.migrations t WHERE NOT (component='kiroku' AND migration='0016')"+ "SELECT jsonb_agg(to_jsonb(t) ORDER BY component,migration)::text FROM pgmigrate.migrations t WHERE NOT (component='kiroku' AND migration IN ('0016','0017'))" E.noParams (D.singleRow (D.column (D.nonNullable D.text))) @@ -643,32 +644,115 @@ testKeiro021Upgrade = withBareDatabase $ \connStr -> do prepare021 connStr rows <- query connStr previousCohortSnapshot- ledger <- query connStr ledgerWithout0016+ ledger <- query connStr ledgerWithout0016And0017 bindings <- query connStr bindingsSnapshot checkpoints <- query connStr previousCheckpointSnapshot current <- either (assertFailure . show) pure kiokuMigrationPlan migrated <- runMigrationPlan defaultRunOptions (Settings.connectionString connStr) current >>= either (assertFailure . show) pure- appliedNow migrated @?= [expectRight (migrationId "kiroku" "0016")]+ appliedNow migrated @?= [expectRight (migrationId "kiroku" n) | n <- ["0016", "0017"]] query connStr previousCohortSnapshot >>= (@?= rows)- query connStr ledgerWithout0016 >>= (@?= ledger)+ query connStr ledgerWithout0016And0017 >>= (@?= ledger) query connStr bindingsSnapshot >>= (@?= bindings) query connStr previousCheckpointSnapshot >>= (@?= checkpoints) verification <- verifyMigrationPlan defaultRunOptions (Settings.connectionString connStr) current >>= either (assertFailure . show) pure let VerificationReport {issues, appliedMigrations, pendingMigrations, unknownMigrations} = verification issues @?= []- length appliedMigrations @?= 63+ length appliedMigrations @?= 64 pendingMigrations @?= [] unknownMigrations @?= [] beforeRepeat <- query connStr fullLedgerSnapshot repeated <- runMigrationPlan defaultRunOptions (Settings.connectionString connStr) current >>= either (assertFailure . show) pure appliedNow repeated @?= [] let MigrationReport {results} = repeated- length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 63+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 64 query connStr fullLedgerSnapshot >>= (@?= beforeRepeat) query connStr previousCohortSnapshot >>= (@?= rows) query connStr bindingsSnapshot >>= (@?= bindings) query connStr previousCheckpointSnapshot >>= (@?= checkpoints) +-- The 0.7.2 release retains the preceding fifteen payloads byte-for-byte.+-- Freeze only its appended payload and verify all sixteen checksums.+previous022Plan :: IO MigrationPlan+previous022Plan = do+ entries <- checkMigrationManifest "test/fixtures/kiroku-0.7.1.0/manifest" >>= either (assertFailure . show) pure+ namespaceSql <- ByteString.readFile "test/fixtures/kiroku-0.7.2.0/0016.sql"+ let frozen = entries <> (("0016.sql", namespaceSql) :| [])+ [(Text.dropEnd 4 (Text.pack name), checksumHex bytes) | (name, bytes) <- toList frozen]+ @?= previous021Checksums <> [("0016", "53b22f14e20af7af0f444877544217a2433939be6a9a245295485e2f87228ee4")]+ oldKiroku <- either (assertFailure . show) pure (migrationComponentFromEmbeddedSql "kiroku" Set.empty frozen)+ keiro <- either (assertFailure . show) pure KeiroMigrations.keiroMigrations+ kioku <- either (assertFailure . show) pure kiokuMigrations+ either (assertFailure . show) pure (migrationPlan (oldKiroku :| [keiro, kioku]))++testKeiro022Upgrade :: Assertion+testKeiro022Upgrade = withBareDatabase $ \connStr -> do+ prepare021 connStr+ let settings = Settings.connectionString connStr+ old <- previous022Plan+ installed <- runMigrationPlan defaultRunOptions settings old >>= either (assertFailure . show) pure+ appliedNow installed @?= [expectRight (migrationId "kiroku" "0016")]+ withConnection connStr $ \conn ->+ run conn (Session.script "INSERT INTO kiroku.subscriptions (subscription_name,last_seen,consumer_group_member,consumer_group_size,target_kind,target_category) VALUES ('upgrade-namespace',1,0,1,'category_namespace','kioku')")+ rows <- query connStr previousCohortSnapshot+ ledger <- query connStr ledgerWithout0017+ bindings <- query connStr bindingsSnapshot+ checkpoints <- query connStr previousCheckpointSnapshot+ current <- either (assertFailure . show) pure kiokuMigrationPlan+ before <- verifyMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+ let VerificationReport {appliedMigrations = previousApplied, pendingMigrations = pending} = before+ length previousApplied @?= 63+ pending @?= [expectRight (migrationId "kiroku" "0017")]+ migrated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+ appliedNow migrated @?= [expectRight (migrationId "kiroku" "0017")]+ query connStr previousCohortSnapshot >>= (@?= rows)+ query connStr ledgerWithout0017 >>= (@?= ledger)+ query connStr bindingsSnapshot >>= (@?= bindings)+ query connStr previousCheckpointSnapshot >>= (@?= checkpoints)+ query connStr compactionSchemaInstalled >>= (@?= True)+ identity <- query connStr storeIdentitySnapshot+ verification <- verifyMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+ let VerificationReport {issues, appliedMigrations, pendingMigrations, unknownMigrations} = verification+ issues @?= []+ length appliedMigrations @?= 64+ pendingMigrations @?= []+ unknownMigrations @?= []+ after <- query connStr fullLedgerSnapshot+ repeated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+ appliedNow repeated @?= []+ let MigrationReport {results} = repeated+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 64+ query connStr fullLedgerSnapshot >>= (@?= after)+ query connStr storeIdentitySnapshot >>= (@?= identity)+ query connStr previousCohortSnapshot >>= (@?= rows)+ query connStr bindingsSnapshot >>= (@?= bindings)+ query connStr previousCheckpointSnapshot >>= (@?= checkpoints)++ledgerWithout0017 :: Statement () Text+ledgerWithout0017 =+ preparable+ "SELECT jsonb_agg(to_jsonb(t) ORDER BY component,migration)::text FROM pgmigrate.migrations t WHERE NOT (component='kiroku' AND migration='0017')"+ E.noParams+ (D.singleRow (D.column (D.nonNullable D.text)))++storeIdentitySnapshot :: Statement () Text+storeIdentitySnapshot =+ preparable+ "SELECT to_jsonb(t)::text FROM kiroku.store_identity t WHERE singleton"+ E.noParams+ (D.singleRow (D.column (D.nonNullable D.text)))++compactionSchemaInstalled :: Statement () Bool+compactionSchemaInstalled =+ preparable+ """+ SELECT (SELECT count(*) = 1 FROM kiroku.store_identity WHERE singleton)+ AND (SELECT count(*) = 0 FROM kiroku.event_compactions)+ AND obj_description(to_regnamespace('kiroku'), 'pg_namespace') =+ 'Managed by pg-migrate component kiroku through 0017'+ """+ E.noParams+ (D.singleRow (D.column (D.nonNullable D.bool)))+ testKeiro021ChecksumRefusal :: Assertion testKeiro021ChecksumRefusal = withBareDatabase $ \connStr -> do prepare021 connStr@@ -706,7 +790,7 @@ runMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan >>= either (assertFailure . show) pure let MigrationReport {results = repeatedResults} = repeated- length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 63+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 64 length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0 verification <- verifyMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan@@ -825,10 +909,10 @@ plan <- either (fail . show) pure kiokuMigrationPlan let settings = Settings.connectionString connStr initial <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure- length (appliedNow initial) @?= 63+ length (appliedNow initial) @?= 64 baselineLedger <- query connStr fullLedgerSnapshot- fst baselineLedger @?= 63+ fst baselineLedger @?= 64 baselineSchema <- query connStr cohortSchemaSnapshotStatement fixup <- Text.IO.readFile ledgerFixupPath @@ -854,7 +938,7 @@ repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure let MigrationReport {results = repeatedResults} = repeated- length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 63+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 64 length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0 withConnection connStr \conn -> run conn (Session.script fixup)@@ -1319,12 +1403,12 @@ full <- either (fail . show) pure kiokuMigrationPlan kirokuReport <- runMigrationPlan defaultRunOptions settings kirokuOnly >>= either (assertFailure . show) pure- length (appliedNow kirokuReport) @?= 16+ length (appliedNow kirokuReport) @?= 17 ledgerBefore <- query connStr kirokuLedgerSnapshot adoption <- runMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure let MigrationReport {results = adoptionResults} = adoption- length [() | MigrationResult {outcome = AlreadyApplied} <- toList adoptionResults] @?= 16+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList adoptionResults] @?= 17 length [() | MigrationResult {outcome = AppliedNow} <- toList adoptionResults] @?= 47 -- Verified and skipped, never re-executed: the stored rows keep their checksums and their@@ -1338,7 +1422,7 @@ verification <- verifyMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure let VerificationReport {issues = adoptionIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification adoptionIssues @?= []- length appliedMigrations @?= 63+ length appliedMigrations @?= 64 pendingMigrations @?= [] unknownMigrations @?= [] @@ -1689,13 +1773,13 @@ verification <- verifyMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure let VerificationReport {issues = verificationIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification verificationIssues @?= []- length appliedMigrations @?= 63+ length appliedMigrations @?= 64 pendingMigrations @?= [] unknownMigrations @?= [] repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure let MigrationReport {results = repeatedResults} = repeated- length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 63+ length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 64 length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0 testSchemaConvergence :: Assertion@@ -1865,6 +1949,7 @@ migrationId "kiroku" "0014", migrationId "kiroku" "0015", migrationId "kiroku" "0016",+ migrationId "kiroku" "0017", migrationId "keiro" "0015-keiro-outbox-claim-order-index", migrationId "keiro" "0016-keiro-inbox-drop-received-idx", migrationId "keiro" "0017-schema-management-comment",@@ -1932,7 +2017,7 @@ (EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'kiroku' AND table_name = 'streams' AND column_name = 'truncate_before'))::int + (coalesce(obj_description(to_regnamespace('kiroku'), 'pg_namespace'), '') =- 'Managed by pg-migrate component kiroku through 0016')::int+ 'Managed by pg-migrate component kiroku through 0017')::int + (to_regclass('keiro.keiro_outbox_claim_order_idx') IS NOT NULL)::int + (to_regclass('keiro.keiro_inbox_received_idx') IS NULL)::int + (coalesce(obj_description(to_regnamespace('keiro'), 'pg_namespace'), '') =@@ -1965,8 +2050,8 @@ query :: Text -> Statement () a -> IO a query connStr statement = withConnection connStr \conn -> run conn (Session.statement () statement) --- The previous released manifest prefix is preserved byte-for-byte. Only the--- appended index runs when a data-bearing 0.10.0.0 database upgrades.+-- The previous released Kioku manifest prefix is preserved byte-for-byte. With+-- the current upstream schema already installed, only the appended index runs. testRecencyUpgrade :: Assertion testRecencyUpgrade = withBareDatabase $ \connStr -> do let settings = Settings.connectionString connStr@@ -1979,7 +2064,7 @@ old <- either (assertFailure . show) pure (migrationPlan (kiroku :| [keiro, oldKioku])) current <- either (assertFailure . show) pure kiokuMigrationPlan initial <- runMigrationPlan defaultRunOptions settings old >>= either (assertFailure . show) pure- length (appliedNow initial) @?= 62+ length (appliedNow initial) @?= 63 withConnection connStr $ \conn -> run conn
test/fixtures/kiroku-0.7.1.0/README.md view
@@ -5,4 +5,4 @@ SQL files match the retained prefix at release commit `22d103e4f424caab06c6a2b76ad92b408c262bc0`. Tests freeze their SHA-256s and require the current composed plan to verify the installed checksums before-applying only 0016. Never regenerate these from current SQL.+applying 0016 and 0017. Never regenerate these from current SQL.
+ test/fixtures/kiroku-0.7.2.0/0016.sql view
@@ -0,0 +1,13 @@+-- Allow category namespace subscription targets. Stop workers during cutover.+-- These are the generated constraint names from migration 0014 on PG 17/18.+-- Only subscription metadata changes; no event/stream index or append work.+ALTER TABLE kiroku.subscriptions+ DROP CONSTRAINT subscriptions_target_kind_check,+ DROP CONSTRAINT subscriptions_check,+ ADD CONSTRAINT subscriptions_target_kind_check+ CHECK (target_kind IN ('unbound', 'all', 'category', 'category_namespace')),+ ADD CONSTRAINT subscriptions_check+ CHECK ((target_kind IN ('category', 'category_namespace')) = (target_category IS NOT NULL));++COMMENT ON SCHEMA kiroku IS+ 'Managed by pg-migrate component kiroku through 0016';
+ test/fixtures/kiroku-0.7.2.0/README.md view
@@ -0,0 +1,13 @@+# Released Kiroku 0.7.2.0 migration payload++Frozen from the Hackage `kiroku-store-migrations-0.7.2.0.tar.gz` archive,+owned by mori://shinzui/kiroku/packages/kiroku-store-migrations, at release+commit `22d103e4f424caab06c6a2b76ad92b408c262bc0`.++Archive SHA-256: `b346415978147bcd24636be33313011cc5f1eb763272fa14c2f65dce042f4f71`.+`0016.sql` SHA-256: `53b22f14e20af7af0f444877544217a2433939be6a9a245295485e2f87228ee4`.++The preceding fifteen payloads match the adjacent `kiroku-0.7.1.0` fixtures+byte-for-byte; tests compose those bytes with this payload and verify every+checksum. This reconstructs the released 63-entry Kioku 0.12 plan without+slicing current migration SQL. Never regenerate these fixtures from current SQL.