@supabase/pg-delta 1.0.0-alpha.3 → 1.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/cli/bin/cli.js +0 -0
- package/dist/cli/commands/plan.js +21 -0
- package/dist/cli/utils.d.ts +2 -0
- package/dist/cli/utils.js +1 -1
- package/dist/core/objects/table/table.model.d.ts +4 -2
- package/dist/core/objects/table/table.model.js +3 -0
- package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
- package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
- package/dist/core/objects/trigger/trigger.model.js +3 -0
- package/dist/core/plan/apply.js +3 -3
- package/dist/core/plan/create.js +34 -15
- package/dist/core/plan/sql-format/constants.d.ts +2 -0
- package/dist/core/plan/sql-format/constants.js +11 -0
- package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
- package/dist/core/plan/sql-format/fixtures.js +2449 -0
- package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
- package/dist/core/plan/sql-format/format-utils.js +274 -0
- package/dist/core/plan/sql-format/formatters.d.ts +20 -0
- package/dist/core/plan/sql-format/formatters.js +737 -0
- package/dist/core/plan/sql-format/index.d.ts +2 -0
- package/dist/core/plan/sql-format/index.js +98 -0
- package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
- package/dist/core/plan/sql-format/keyword-case.js +868 -0
- package/dist/core/plan/sql-format/protect.d.ts +3 -0
- package/dist/core/plan/sql-format/protect.js +269 -0
- package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
- package/dist/core/plan/sql-format/sql-scanner.js +202 -0
- package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
- package/dist/core/plan/sql-format/tokenizer.js +118 -0
- package/dist/core/plan/sql-format/types.d.ts +28 -0
- package/dist/core/plan/sql-format/types.js +1 -0
- package/dist/core/plan/sql-format/wrap.d.ts +2 -0
- package/dist/core/plan/sql-format/wrap.js +165 -0
- package/dist/core/plan/sql-format.d.ts +2 -0
- package/dist/core/plan/sql-format.js +1 -0
- package/dist/core/plan/statements.d.ts +2 -1
- package/dist/core/plan/statements.js +6 -2
- package/dist/core/postgres-config.d.ts +15 -0
- package/dist/core/postgres-config.js +30 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +37 -22
- package/src/cli/app.ts +28 -0
- package/src/cli/bin/cli.ts +9 -0
- package/src/cli/commands/apply.ts +101 -0
- package/src/cli/commands/plan.ts +195 -0
- package/src/cli/commands/sync.ts +185 -0
- package/src/cli/formatters/index.ts +5 -0
- package/src/cli/formatters/tree/tree-builder.ts +380 -0
- package/src/cli/formatters/tree/tree-renderer.ts +372 -0
- package/src/cli/formatters/tree/tree.ts +237 -0
- package/src/cli/utils/integrations.ts +42 -0
- package/src/cli/utils.ts +231 -0
- package/src/core/catalog.diff.ts +246 -0
- package/src/core/catalog.model.ts +384 -0
- package/src/core/change.types.ts +44 -0
- package/src/core/context.ts +26 -0
- package/src/core/depend.ts +1870 -0
- package/src/core/expand-replace-dependencies.ts +380 -0
- package/src/core/fingerprint.ts +204 -0
- package/src/core/integrations/filter/dsl.ts +204 -0
- package/src/core/integrations/filter/extractors.ts +145 -0
- package/src/core/integrations/filter/filter.types.ts +3 -0
- package/src/core/integrations/integration-dsl.ts +24 -0
- package/src/core/integrations/integration.types.ts +7 -0
- package/src/core/integrations/serialize/dsl.ts +77 -0
- package/src/core/integrations/serialize/serialize.types.ts +3 -0
- package/src/core/integrations/supabase.ts +121 -0
- package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
- package/src/core/objects/aggregate/aggregate.model.ts +317 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
- package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
- package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
- package/src/core/objects/base.change.ts +62 -0
- package/src/core/objects/base.default-privileges.ts +204 -0
- package/src/core/objects/base.diff.ts +20 -0
- package/src/core/objects/base.model.ts +82 -0
- package/src/core/objects/base.privilege-diff.ts +299 -0
- package/src/core/objects/base.privilege.ts +184 -0
- package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
- package/src/core/objects/collation/changes/collation.alter.ts +79 -0
- package/src/core/objects/collation/changes/collation.base.ts +20 -0
- package/src/core/objects/collation/changes/collation.comment.ts +68 -0
- package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
- package/src/core/objects/collation/changes/collation.create.ts +106 -0
- package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
- package/src/core/objects/collation/changes/collation.drop.ts +37 -0
- package/src/core/objects/collation/changes/collation.types.ts +10 -0
- package/src/core/objects/collation/collation.diff.test.ts +100 -0
- package/src/core/objects/collation/collation.diff.ts +126 -0
- package/src/core/objects/collation/collation.model.ts +224 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
- package/src/core/objects/domain/changes/domain.alter.ts +286 -0
- package/src/core/objects/domain/changes/domain.base.ts +20 -0
- package/src/core/objects/domain/changes/domain.comment.ts +59 -0
- package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
- package/src/core/objects/domain/changes/domain.create.ts +118 -0
- package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
- package/src/core/objects/domain/changes/domain.drop.ts +34 -0
- package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
- package/src/core/objects/domain/changes/domain.types.ts +12 -0
- package/src/core/objects/domain/domain.diff.test.ts +284 -0
- package/src/core/objects/domain/domain.diff.ts +358 -0
- package/src/core/objects/domain/domain.model.ts +190 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
- package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
- package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
- package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
- package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
- package/src/core/objects/extension/changes/extension.alter.ts +78 -0
- package/src/core/objects/extension/changes/extension.base.ts +20 -0
- package/src/core/objects/extension/changes/extension.comment.ts +64 -0
- package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
- package/src/core/objects/extension/changes/extension.create.ts +63 -0
- package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
- package/src/core/objects/extension/changes/extension.drop.ts +34 -0
- package/src/core/objects/extension/changes/extension.types.ts +10 -0
- package/src/core/objects/extension/extension.diff.test.ts +42 -0
- package/src/core/objects/extension/extension.diff.ts +90 -0
- package/src/core/objects/extension/extension.model.ts +280 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
- package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
- package/src/core/objects/index/changes/index.alter.test.ts +200 -0
- package/src/core/objects/index/changes/index.alter.ts +144 -0
- package/src/core/objects/index/changes/index.base.ts +20 -0
- package/src/core/objects/index/changes/index.comment.ts +63 -0
- package/src/core/objects/index/changes/index.create.test.ts +66 -0
- package/src/core/objects/index/changes/index.create.ts +68 -0
- package/src/core/objects/index/changes/index.drop.test.ts +44 -0
- package/src/core/objects/index/changes/index.drop.ts +34 -0
- package/src/core/objects/index/changes/index.types.ts +6 -0
- package/src/core/objects/index/changes/utils.ts +16 -0
- package/src/core/objects/index/index.diff.test.ts +153 -0
- package/src/core/objects/index/index.diff.ts +243 -0
- package/src/core/objects/index/index.model.ts +370 -0
- package/src/core/objects/language/changes/language.alter.test.ts +33 -0
- package/src/core/objects/language/changes/language.alter.ts +53 -0
- package/src/core/objects/language/changes/language.base.ts +20 -0
- package/src/core/objects/language/changes/language.comment.ts +58 -0
- package/src/core/objects/language/changes/language.create.test.ts +27 -0
- package/src/core/objects/language/changes/language.create.ts +104 -0
- package/src/core/objects/language/changes/language.drop.test.ts +25 -0
- package/src/core/objects/language/changes/language.drop.ts +39 -0
- package/src/core/objects/language/changes/language.privilege.ts +172 -0
- package/src/core/objects/language/changes/language.types.ts +12 -0
- package/src/core/objects/language/language.diff.test.ts +53 -0
- package/src/core/objects/language/language.diff.ts +176 -0
- package/src/core/objects/language/language.model.ts +150 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
- package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
- package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
- package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
- package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
- package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
- package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
- package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
- package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
- package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
- package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
- package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
- package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
- package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
- package/src/core/objects/procedure/procedure.diff.ts +404 -0
- package/src/core/objects/procedure/procedure.model.ts +264 -0
- package/src/core/objects/procedure/utils.ts +58 -0
- package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
- package/src/core/objects/publication/changes/publication.alter.ts +243 -0
- package/src/core/objects/publication/changes/publication.base.ts +20 -0
- package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
- package/src/core/objects/publication/changes/publication.comment.ts +64 -0
- package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
- package/src/core/objects/publication/changes/publication.create.ts +82 -0
- package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
- package/src/core/objects/publication/changes/publication.drop.ts +29 -0
- package/src/core/objects/publication/changes/publication.types.ts +26 -0
- package/src/core/objects/publication/publication.diff.test.ts +292 -0
- package/src/core/objects/publication/publication.diff.ts +253 -0
- package/src/core/objects/publication/publication.model.ts +206 -0
- package/src/core/objects/publication/utils.ts +55 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
- package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
- package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
- package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
- package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
- package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
- package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
- package/src/core/objects/role/changes/role.alter.test.ts +346 -0
- package/src/core/objects/role/changes/role.alter.ts +110 -0
- package/src/core/objects/role/changes/role.base.ts +24 -0
- package/src/core/objects/role/changes/role.comment.ts +55 -0
- package/src/core/objects/role/changes/role.create.test.ts +52 -0
- package/src/core/objects/role/changes/role.create.ts +102 -0
- package/src/core/objects/role/changes/role.drop.test.ts +29 -0
- package/src/core/objects/role/changes/role.drop.ts +34 -0
- package/src/core/objects/role/changes/role.privilege.ts +376 -0
- package/src/core/objects/role/changes/role.types.ts +12 -0
- package/src/core/objects/role/role.diff.test.ts +44 -0
- package/src/core/objects/role/role.diff.ts +479 -0
- package/src/core/objects/role/role.model.ts +344 -0
- package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
- package/src/core/objects/rule/changes/rule.alter.ts +72 -0
- package/src/core/objects/rule/changes/rule.base.ts +20 -0
- package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
- package/src/core/objects/rule/changes/rule.comment.ts +62 -0
- package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
- package/src/core/objects/rule/changes/rule.create.ts +42 -0
- package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
- package/src/core/objects/rule/changes/rule.drop.ts +29 -0
- package/src/core/objects/rule/changes/rule.types.ts +12 -0
- package/src/core/objects/rule/rule.diff.test.ts +132 -0
- package/src/core/objects/rule/rule.diff.ts +79 -0
- package/src/core/objects/rule/rule.model.ts +173 -0
- package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
- package/src/core/objects/schema/changes/schema.alter.ts +45 -0
- package/src/core/objects/schema/changes/schema.base.ts +20 -0
- package/src/core/objects/schema/changes/schema.comment.ts +56 -0
- package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
- package/src/core/objects/schema/changes/schema.create.ts +47 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
- package/src/core/objects/schema/changes/schema.drop.ts +34 -0
- package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
- package/src/core/objects/schema/changes/schema.types.ts +12 -0
- package/src/core/objects/schema/schema.diff.test.ts +42 -0
- package/src/core/objects/schema/schema.diff.ts +209 -0
- package/src/core/objects/schema/schema.model.ts +107 -0
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
- package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
- package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
- package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
- package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
- package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
- package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
- package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
- package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
- package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
- package/src/core/objects/sequence/sequence.diff.ts +359 -0
- package/src/core/objects/sequence/sequence.model.ts +185 -0
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
- package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
- package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
- package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
- package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
- package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
- package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
- package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
- package/src/core/objects/subscription/subscription.diff.ts +241 -0
- package/src/core/objects/subscription/subscription.model.ts +190 -0
- package/src/core/objects/subscription/utils.ts +156 -0
- package/src/core/objects/table/changes/table.alter.test.ts +823 -0
- package/src/core/objects/table/changes/table.alter.ts +806 -0
- package/src/core/objects/table/changes/table.base.ts +20 -0
- package/src/core/objects/table/changes/table.comment.ts +266 -0
- package/src/core/objects/table/changes/table.create.test.ts +150 -0
- package/src/core/objects/table/changes/table.create.ts +188 -0
- package/src/core/objects/table/changes/table.drop.test.ts +34 -0
- package/src/core/objects/table/changes/table.drop.ts +45 -0
- package/src/core/objects/table/changes/table.privilege.ts +200 -0
- package/src/core/objects/table/changes/table.types.ts +12 -0
- package/src/core/objects/table/table.diff.test.ts +711 -0
- package/src/core/objects/table/table.diff.ts +953 -0
- package/src/core/objects/table/table.model.ts +460 -0
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
- package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
- package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
- package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
- package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
- package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
- package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
- package/src/core/objects/trigger/trigger.diff.ts +116 -0
- package/src/core/objects/trigger/trigger.model.ts +252 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
- package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
- package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
- package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
- package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
- package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
- package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
- package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
- package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
- package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
- package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
- package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
- package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
- package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
- package/src/core/objects/type/enum/enum.diff.ts +396 -0
- package/src/core/objects/type/enum/enum.model.ts +194 -0
- package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
- package/src/core/objects/type/range/changes/range.alter.ts +51 -0
- package/src/core/objects/type/range/changes/range.base.ts +20 -0
- package/src/core/objects/type/range/changes/range.comment.ts +64 -0
- package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
- package/src/core/objects/type/range/changes/range.create.ts +151 -0
- package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
- package/src/core/objects/type/range/changes/range.drop.ts +34 -0
- package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
- package/src/core/objects/type/range/changes/range.types.ts +12 -0
- package/src/core/objects/type/range/range.diff.test.ts +70 -0
- package/src/core/objects/type/range/range.diff.ts +259 -0
- package/src/core/objects/type/range/range.model.ts +187 -0
- package/src/core/objects/type/type.types.ts +5 -0
- package/src/core/objects/utils.ts +171 -0
- package/src/core/objects/view/changes/view.alter.test.ts +110 -0
- package/src/core/objects/view/changes/view.alter.ts +112 -0
- package/src/core/objects/view/changes/view.base.ts +20 -0
- package/src/core/objects/view/changes/view.comment.ts +59 -0
- package/src/core/objects/view/changes/view.create.test.ts +65 -0
- package/src/core/objects/view/changes/view.create.ts +73 -0
- package/src/core/objects/view/changes/view.drop.test.ts +34 -0
- package/src/core/objects/view/changes/view.drop.ts +40 -0
- package/src/core/objects/view/changes/view.privilege.ts +200 -0
- package/src/core/objects/view/changes/view.types.ts +12 -0
- package/src/core/objects/view/view.diff.test.ts +91 -0
- package/src/core/objects/view/view.diff.ts +365 -0
- package/src/core/objects/view/view.model.ts +276 -0
- package/src/core/plan/apply.ts +190 -0
- package/src/core/plan/create.ts +432 -0
- package/src/core/plan/hierarchy.ts +574 -0
- package/src/core/plan/index.ts +29 -0
- package/src/core/plan/io.ts +20 -0
- package/src/core/plan/risk.ts +48 -0
- package/src/core/plan/serialize.ts +195 -0
- package/src/core/plan/sql-format/constants.ts +13 -0
- package/src/core/plan/sql-format/fixtures.ts +2806 -0
- package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
- package/src/core/plan/sql-format/format-functions.test.ts +127 -0
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
- package/src/core/plan/sql-format/format-off.test.ts +809 -0
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
- package/src/core/plan/sql-format/format-stress.test.ts +616 -0
- package/src/core/plan/sql-format/format-utils.test.ts +91 -0
- package/src/core/plan/sql-format/format-utils.ts +391 -0
- package/src/core/plan/sql-format/formatters.ts +921 -0
- package/src/core/plan/sql-format/index.ts +149 -0
- package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
- package/src/core/plan/sql-format/keyword-case.ts +1085 -0
- package/src/core/plan/sql-format/protect.test.ts +127 -0
- package/src/core/plan/sql-format/protect.ts +337 -0
- package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
- package/src/core/plan/sql-format/sql-scanner.ts +252 -0
- package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
- package/src/core/plan/sql-format/tokenizer.ts +152 -0
- package/src/core/plan/sql-format/types.ts +31 -0
- package/src/core/plan/sql-format/wrap.test.ts +119 -0
- package/src/core/plan/sql-format/wrap.ts +196 -0
- package/src/core/plan/sql-format.ts +2 -0
- package/src/core/plan/statements.ts +22 -0
- package/src/core/plan/types.ts +165 -0
- package/src/core/postgres-config.ts +169 -0
- package/src/core/sort/custom-constraints.ts +161 -0
- package/src/core/sort/debug-visualization.ts +239 -0
- package/src/core/sort/dependency-filter.ts +224 -0
- package/src/core/sort/graph-builder.ts +223 -0
- package/src/core/sort/graph-utils.ts +51 -0
- package/src/core/sort/logical-sort.ts +590 -0
- package/src/core/sort/sort-changes.ts +234 -0
- package/src/core/sort/topological-sort.ts +184 -0
- package/src/core/sort/types.ts +112 -0
- package/src/core/sort/utils.ts +69 -0
- package/src/index.ts +14 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
|
|
2
|
+
import { diffObjects } from "../base.diff.ts";
|
|
3
|
+
import {
|
|
4
|
+
diffPrivileges,
|
|
5
|
+
filterPublicBuiltInDefaults,
|
|
6
|
+
groupPrivilegesByGrantable,
|
|
7
|
+
} from "../base.privilege-diff.ts";
|
|
8
|
+
import type { Role } from "../role/role.model.ts";
|
|
9
|
+
import {
|
|
10
|
+
AlterDomainAddConstraint,
|
|
11
|
+
AlterDomainChangeOwner,
|
|
12
|
+
AlterDomainDropConstraint,
|
|
13
|
+
AlterDomainDropDefault,
|
|
14
|
+
AlterDomainDropNotNull,
|
|
15
|
+
AlterDomainSetDefault,
|
|
16
|
+
AlterDomainSetNotNull,
|
|
17
|
+
AlterDomainValidateConstraint,
|
|
18
|
+
} from "./changes/domain.alter.ts";
|
|
19
|
+
import {
|
|
20
|
+
CreateCommentOnDomain,
|
|
21
|
+
DropCommentOnDomain,
|
|
22
|
+
} from "./changes/domain.comment.ts";
|
|
23
|
+
import { CreateDomain } from "./changes/domain.create.ts";
|
|
24
|
+
import { DropDomain } from "./changes/domain.drop.ts";
|
|
25
|
+
import {
|
|
26
|
+
GrantDomainPrivileges,
|
|
27
|
+
RevokeDomainPrivileges,
|
|
28
|
+
RevokeGrantOptionDomainPrivileges,
|
|
29
|
+
} from "./changes/domain.privilege.ts";
|
|
30
|
+
import type { DomainChange } from "./changes/domain.types.ts";
|
|
31
|
+
import type { Domain } from "./domain.model.ts";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Diff two sets of domains from main and branch catalogs.
|
|
35
|
+
*
|
|
36
|
+
* @param ctx - Context containing version, currentUser, and defaultPrivilegeState
|
|
37
|
+
* @param main - The domains in the main catalog.
|
|
38
|
+
* @param branch - The domains in the branch catalog.
|
|
39
|
+
* @returns A list of changes to apply to main to make it match branch.
|
|
40
|
+
*/
|
|
41
|
+
export function diffDomains(
|
|
42
|
+
ctx: {
|
|
43
|
+
version: number;
|
|
44
|
+
currentUser: string;
|
|
45
|
+
defaultPrivilegeState: DefaultPrivilegeState;
|
|
46
|
+
mainRoles: Record<string, Role>;
|
|
47
|
+
},
|
|
48
|
+
main: Record<string, Domain>,
|
|
49
|
+
branch: Record<string, Domain>,
|
|
50
|
+
): DomainChange[] {
|
|
51
|
+
const { created, dropped, altered } = diffObjects(main, branch);
|
|
52
|
+
|
|
53
|
+
const changes: DomainChange[] = [];
|
|
54
|
+
|
|
55
|
+
for (const domainId of created) {
|
|
56
|
+
const newDomain = branch[domainId];
|
|
57
|
+
changes.push(new CreateDomain({ domain: newDomain }));
|
|
58
|
+
|
|
59
|
+
// OWNER: If the domain should be owned by someone other than the current user,
|
|
60
|
+
// emit ALTER DOMAIN ... OWNER TO after creation
|
|
61
|
+
if (newDomain.owner !== ctx.currentUser) {
|
|
62
|
+
changes.push(
|
|
63
|
+
new AlterDomainChangeOwner({
|
|
64
|
+
domain: newDomain,
|
|
65
|
+
owner: newDomain.owner,
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (newDomain.comment !== null) {
|
|
71
|
+
changes.push(new CreateCommentOnDomain({ domain: newDomain }));
|
|
72
|
+
}
|
|
73
|
+
// For unvalidated constraints, CREATE DOMAIN cannot specify NOT VALID.
|
|
74
|
+
// Add them after creation and validate to match branch state semantics.
|
|
75
|
+
// For already validated constraints, they are emitted inline in CREATE DOMAIN.
|
|
76
|
+
if (newDomain.constraints && newDomain.constraints.length > 0) {
|
|
77
|
+
for (const c of newDomain.constraints) {
|
|
78
|
+
if (c.validated === false) {
|
|
79
|
+
changes.push(
|
|
80
|
+
new AlterDomainAddConstraint({ domain: newDomain, constraint: c }),
|
|
81
|
+
);
|
|
82
|
+
changes.push(
|
|
83
|
+
new AlterDomainValidateConstraint({
|
|
84
|
+
domain: newDomain,
|
|
85
|
+
constraint: c,
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// PRIVILEGES: For created objects, compare against default privileges state
|
|
93
|
+
// The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
|
|
94
|
+
// so objects are created with the default privileges state in effect.
|
|
95
|
+
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
96
|
+
// needed to reach the final desired state.
|
|
97
|
+
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(
|
|
98
|
+
ctx.currentUser,
|
|
99
|
+
"domain",
|
|
100
|
+
newDomain.schema ?? "",
|
|
101
|
+
);
|
|
102
|
+
// Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
|
|
103
|
+
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
104
|
+
// This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
|
|
105
|
+
const desiredPrivileges = filterPublicBuiltInDefaults(
|
|
106
|
+
"domain",
|
|
107
|
+
newDomain.privileges,
|
|
108
|
+
);
|
|
109
|
+
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
110
|
+
// and shouldn't be compared. Use the domain owner as the reference.
|
|
111
|
+
const privilegeResults = diffPrivileges(
|
|
112
|
+
effectiveDefaults,
|
|
113
|
+
desiredPrivileges,
|
|
114
|
+
newDomain.owner,
|
|
115
|
+
ctx.mainRoles,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Generate grant changes
|
|
119
|
+
for (const [grantee, result] of privilegeResults) {
|
|
120
|
+
if (result.grants.length > 0) {
|
|
121
|
+
const grantGroups = groupPrivilegesByGrantable(result.grants);
|
|
122
|
+
for (const [grantable, list] of grantGroups) {
|
|
123
|
+
void grantable;
|
|
124
|
+
changes.push(
|
|
125
|
+
new GrantDomainPrivileges({
|
|
126
|
+
domain: newDomain,
|
|
127
|
+
grantee,
|
|
128
|
+
privileges: list,
|
|
129
|
+
version: ctx.version,
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Generate revoke changes
|
|
136
|
+
if (result.revokes.length > 0) {
|
|
137
|
+
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
138
|
+
for (const [grantable, list] of revokeGroups) {
|
|
139
|
+
void grantable;
|
|
140
|
+
changes.push(
|
|
141
|
+
new RevokeDomainPrivileges({
|
|
142
|
+
domain: newDomain,
|
|
143
|
+
grantee,
|
|
144
|
+
privileges: list,
|
|
145
|
+
version: ctx.version,
|
|
146
|
+
}),
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Generate revoke grant option changes
|
|
152
|
+
if (result.revokeGrantOption.length > 0) {
|
|
153
|
+
changes.push(
|
|
154
|
+
new RevokeGrantOptionDomainPrivileges({
|
|
155
|
+
domain: newDomain,
|
|
156
|
+
grantee,
|
|
157
|
+
privilegeNames: result.revokeGrantOption,
|
|
158
|
+
version: ctx.version,
|
|
159
|
+
}),
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (const domainId of dropped) {
|
|
166
|
+
changes.push(new DropDomain({ domain: main[domainId] }));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for (const domainId of altered) {
|
|
170
|
+
const mainDomain = main[domainId];
|
|
171
|
+
const branchDomain = branch[domainId];
|
|
172
|
+
|
|
173
|
+
// DEFAULT
|
|
174
|
+
if (mainDomain.default_value !== branchDomain.default_value) {
|
|
175
|
+
if (branchDomain.default_value === null) {
|
|
176
|
+
changes.push(new AlterDomainDropDefault({ domain: mainDomain }));
|
|
177
|
+
} else {
|
|
178
|
+
changes.push(
|
|
179
|
+
new AlterDomainSetDefault({
|
|
180
|
+
domain: mainDomain,
|
|
181
|
+
defaultValue: branchDomain.default_value,
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// NOT NULL
|
|
188
|
+
if (mainDomain.not_null !== branchDomain.not_null) {
|
|
189
|
+
if (branchDomain.not_null) {
|
|
190
|
+
changes.push(new AlterDomainSetNotNull({ domain: mainDomain }));
|
|
191
|
+
} else {
|
|
192
|
+
changes.push(new AlterDomainDropNotNull({ domain: mainDomain }));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// DOMAIN CONSTRAINTS
|
|
197
|
+
const mainByName = new Map(mainDomain.constraints.map((c) => [c.name, c]));
|
|
198
|
+
const branchByName = new Map(
|
|
199
|
+
branchDomain.constraints.map((c) => [c.name, c]),
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Note: Constraint renames are modeled as drop+add because name is part
|
|
203
|
+
// of the identity we diff on. No dedicated rename class is generated here.
|
|
204
|
+
|
|
205
|
+
// Created
|
|
206
|
+
for (const [name, c] of branchByName) {
|
|
207
|
+
if (!mainByName.has(name)) {
|
|
208
|
+
changes.push(
|
|
209
|
+
new AlterDomainAddConstraint({
|
|
210
|
+
domain: branchDomain,
|
|
211
|
+
constraint: c,
|
|
212
|
+
}),
|
|
213
|
+
);
|
|
214
|
+
if (!c.validated) {
|
|
215
|
+
changes.push(
|
|
216
|
+
new AlterDomainValidateConstraint({
|
|
217
|
+
domain: branchDomain,
|
|
218
|
+
constraint: c,
|
|
219
|
+
}),
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Dropped
|
|
226
|
+
for (const [name, c] of mainByName) {
|
|
227
|
+
if (!branchByName.has(name)) {
|
|
228
|
+
changes.push(
|
|
229
|
+
new AlterDomainDropConstraint({
|
|
230
|
+
domain: mainDomain,
|
|
231
|
+
constraint: c,
|
|
232
|
+
}),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Altered (drop + add for now)
|
|
238
|
+
for (const [name, mainC] of mainByName) {
|
|
239
|
+
const branchC = branchByName.get(name);
|
|
240
|
+
if (!branchC) continue;
|
|
241
|
+
const changed =
|
|
242
|
+
mainC.validated !== branchC.validated ||
|
|
243
|
+
mainC.is_local !== branchC.is_local ||
|
|
244
|
+
mainC.no_inherit !== branchC.no_inherit ||
|
|
245
|
+
mainC.check_expression !== branchC.check_expression;
|
|
246
|
+
if (changed) {
|
|
247
|
+
changes.push(
|
|
248
|
+
new AlterDomainDropConstraint({
|
|
249
|
+
domain: mainDomain,
|
|
250
|
+
constraint: mainC,
|
|
251
|
+
}),
|
|
252
|
+
);
|
|
253
|
+
changes.push(
|
|
254
|
+
new AlterDomainAddConstraint({
|
|
255
|
+
domain: branchDomain,
|
|
256
|
+
constraint: branchC,
|
|
257
|
+
}),
|
|
258
|
+
);
|
|
259
|
+
if (!branchC.validated) {
|
|
260
|
+
changes.push(
|
|
261
|
+
new AlterDomainValidateConstraint({
|
|
262
|
+
domain: branchDomain,
|
|
263
|
+
constraint: branchC,
|
|
264
|
+
}),
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// OWNER
|
|
271
|
+
if (mainDomain.owner !== branchDomain.owner) {
|
|
272
|
+
changes.push(
|
|
273
|
+
new AlterDomainChangeOwner({
|
|
274
|
+
domain: mainDomain,
|
|
275
|
+
owner: branchDomain.owner,
|
|
276
|
+
}),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// COMMENT
|
|
281
|
+
if (mainDomain.comment !== branchDomain.comment) {
|
|
282
|
+
if (branchDomain.comment === null) {
|
|
283
|
+
changes.push(new DropCommentOnDomain({ domain: mainDomain }));
|
|
284
|
+
} else {
|
|
285
|
+
changes.push(new CreateCommentOnDomain({ domain: branchDomain }));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// PRIVILEGES
|
|
290
|
+
// Filter out PUBLIC's built-in default USAGE privilege from main catalog
|
|
291
|
+
// (PostgreSQL grants it automatically, so we shouldn't compare it)
|
|
292
|
+
const mainPrivilegesFiltered = filterPublicBuiltInDefaults(
|
|
293
|
+
"domain",
|
|
294
|
+
mainDomain.privileges,
|
|
295
|
+
);
|
|
296
|
+
// Filter out PUBLIC's built-in default USAGE privilege from branch catalog
|
|
297
|
+
const branchPrivilegesFiltered = filterPublicBuiltInDefaults(
|
|
298
|
+
"domain",
|
|
299
|
+
branchDomain.privileges,
|
|
300
|
+
);
|
|
301
|
+
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
302
|
+
// and shouldn't be compared. Use branch owner as the reference.
|
|
303
|
+
const privilegeResults = diffPrivileges(
|
|
304
|
+
mainPrivilegesFiltered,
|
|
305
|
+
branchPrivilegesFiltered,
|
|
306
|
+
branchDomain.owner,
|
|
307
|
+
ctx.mainRoles,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
for (const [grantee, result] of privilegeResults) {
|
|
311
|
+
// Generate grant changes
|
|
312
|
+
if (result.grants.length > 0) {
|
|
313
|
+
const grantGroups = groupPrivilegesByGrantable(result.grants);
|
|
314
|
+
for (const [grantable, list] of grantGroups) {
|
|
315
|
+
void grantable;
|
|
316
|
+
changes.push(
|
|
317
|
+
new GrantDomainPrivileges({
|
|
318
|
+
domain: branchDomain,
|
|
319
|
+
grantee,
|
|
320
|
+
privileges: list,
|
|
321
|
+
version: ctx.version,
|
|
322
|
+
}),
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Generate revoke changes
|
|
328
|
+
if (result.revokes.length > 0) {
|
|
329
|
+
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
330
|
+
for (const [grantable, list] of revokeGroups) {
|
|
331
|
+
void grantable;
|
|
332
|
+
changes.push(
|
|
333
|
+
new RevokeDomainPrivileges({
|
|
334
|
+
domain: mainDomain,
|
|
335
|
+
grantee,
|
|
336
|
+
privileges: list,
|
|
337
|
+
version: ctx.version,
|
|
338
|
+
}),
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Generate revoke grant option changes
|
|
344
|
+
if (result.revokeGrantOption.length > 0) {
|
|
345
|
+
changes.push(
|
|
346
|
+
new RevokeGrantOptionDomainPrivileges({
|
|
347
|
+
domain: mainDomain,
|
|
348
|
+
grantee,
|
|
349
|
+
privilegeNames: result.revokeGrantOption,
|
|
350
|
+
version: ctx.version,
|
|
351
|
+
}),
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return changes;
|
|
358
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { sql } from "@ts-safeql/sql-tag";
|
|
2
|
+
import type { Pool } from "pg";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
import { BasePgModel } from "../base.model.ts";
|
|
5
|
+
import {
|
|
6
|
+
type PrivilegeProps,
|
|
7
|
+
privilegePropsSchema,
|
|
8
|
+
} from "../base.privilege-diff.ts";
|
|
9
|
+
|
|
10
|
+
const domainConstraintPropsSchema = z.object({
|
|
11
|
+
name: z.string(),
|
|
12
|
+
validated: z.boolean(),
|
|
13
|
+
is_local: z.boolean(),
|
|
14
|
+
no_inherit: z.boolean(),
|
|
15
|
+
check_expression: z.string().nullable(),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const domainPropsSchema = z.object({
|
|
19
|
+
schema: z.string(),
|
|
20
|
+
name: z.string(),
|
|
21
|
+
base_type: z.string(),
|
|
22
|
+
base_type_schema: z.string(),
|
|
23
|
+
base_type_str: z.string().optional(),
|
|
24
|
+
not_null: z.boolean(),
|
|
25
|
+
type_modifier: z.number().nullable(),
|
|
26
|
+
array_dimensions: z.number().nullable(),
|
|
27
|
+
collation: z.string().nullable(),
|
|
28
|
+
default_bin: z.string().nullable(),
|
|
29
|
+
default_value: z.string().nullable(),
|
|
30
|
+
owner: z.string(),
|
|
31
|
+
comment: z.string().nullable(),
|
|
32
|
+
constraints: z.array(domainConstraintPropsSchema),
|
|
33
|
+
privileges: z.array(privilegePropsSchema),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export type DomainConstraintProps = z.infer<typeof domainConstraintPropsSchema>;
|
|
37
|
+
type DomainPrivilegeProps = PrivilegeProps;
|
|
38
|
+
export type DomainProps = z.infer<typeof domainPropsSchema>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A domain is a user-defined data type that is based on another underlying type.
|
|
42
|
+
*
|
|
43
|
+
* @see https://www.postgresql.org/docs/17/domains.html
|
|
44
|
+
*/
|
|
45
|
+
export class Domain extends BasePgModel {
|
|
46
|
+
public readonly schema: DomainProps["schema"];
|
|
47
|
+
public readonly name: DomainProps["name"];
|
|
48
|
+
public readonly base_type: DomainProps["base_type"];
|
|
49
|
+
public readonly base_type_schema: DomainProps["base_type_schema"];
|
|
50
|
+
public readonly base_type_str?: DomainProps["base_type_str"];
|
|
51
|
+
public readonly not_null: DomainProps["not_null"];
|
|
52
|
+
public readonly type_modifier: DomainProps["type_modifier"];
|
|
53
|
+
public readonly array_dimensions: DomainProps["array_dimensions"];
|
|
54
|
+
public readonly collation: DomainProps["collation"];
|
|
55
|
+
public readonly default_bin: DomainProps["default_bin"];
|
|
56
|
+
public readonly default_value: DomainProps["default_value"];
|
|
57
|
+
public readonly owner: DomainProps["owner"];
|
|
58
|
+
public readonly comment: DomainProps["comment"];
|
|
59
|
+
public readonly constraints: DomainConstraintProps[];
|
|
60
|
+
public readonly privileges: DomainPrivilegeProps[];
|
|
61
|
+
|
|
62
|
+
constructor(props: DomainProps) {
|
|
63
|
+
super();
|
|
64
|
+
|
|
65
|
+
// Identity fields
|
|
66
|
+
this.schema = props.schema;
|
|
67
|
+
this.name = props.name;
|
|
68
|
+
|
|
69
|
+
// Data fields
|
|
70
|
+
this.base_type = props.base_type;
|
|
71
|
+
this.base_type_schema = props.base_type_schema;
|
|
72
|
+
this.base_type_str = props.base_type_str;
|
|
73
|
+
this.not_null = props.not_null;
|
|
74
|
+
this.type_modifier = props.type_modifier;
|
|
75
|
+
this.array_dimensions = props.array_dimensions;
|
|
76
|
+
this.collation = props.collation;
|
|
77
|
+
this.default_bin = props.default_bin;
|
|
78
|
+
this.default_value = props.default_value;
|
|
79
|
+
this.owner = props.owner;
|
|
80
|
+
this.comment = props.comment;
|
|
81
|
+
this.constraints = props.constraints;
|
|
82
|
+
this.privileges = props.privileges;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get stableId(): `domain:${string}` {
|
|
86
|
+
return `domain:${this.schema}.${this.name}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get identityFields() {
|
|
90
|
+
return {
|
|
91
|
+
schema: this.schema,
|
|
92
|
+
name: this.name,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get dataFields() {
|
|
97
|
+
return {
|
|
98
|
+
base_type: this.base_type,
|
|
99
|
+
base_type_schema: this.base_type_schema,
|
|
100
|
+
not_null: this.not_null,
|
|
101
|
+
type_modifier: this.type_modifier,
|
|
102
|
+
array_dimensions: this.array_dimensions,
|
|
103
|
+
collation: this.collation,
|
|
104
|
+
default_bin: this.default_bin,
|
|
105
|
+
default_value: this.default_value,
|
|
106
|
+
owner: this.owner,
|
|
107
|
+
comment: this.comment,
|
|
108
|
+
constraints: this.constraints,
|
|
109
|
+
privileges: this.privileges,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Extract all domains from the database.
|
|
116
|
+
*
|
|
117
|
+
* @param sql - The SQL client.
|
|
118
|
+
* @returns A list of domains.
|
|
119
|
+
*/
|
|
120
|
+
export async function extractDomains(pool: Pool): Promise<Domain[]> {
|
|
121
|
+
const { rows: domainRows } = await pool.query<DomainProps>(sql`
|
|
122
|
+
with extension_oids as (
|
|
123
|
+
select
|
|
124
|
+
objid
|
|
125
|
+
from
|
|
126
|
+
pg_depend d
|
|
127
|
+
where
|
|
128
|
+
d.refclassid = 'pg_extension'::regclass
|
|
129
|
+
and d.classid = 'pg_type'::regclass
|
|
130
|
+
)
|
|
131
|
+
select
|
|
132
|
+
t.typnamespace::regnamespace::text as schema,
|
|
133
|
+
quote_ident(t.typname) as name,
|
|
134
|
+
bt.typname as base_type,
|
|
135
|
+
bt.typnamespace::regnamespace::text as base_type_schema,
|
|
136
|
+
format_type(t.typbasetype, t.typtypmod) as base_type_str,
|
|
137
|
+
t.typnotnull as not_null,
|
|
138
|
+
t.typtypmod as type_modifier,
|
|
139
|
+
t.typndims as array_dimensions,
|
|
140
|
+
case when t.typcollation <> bt.typcollation then quote_ident(c.collname) else null end as collation,
|
|
141
|
+
pg_get_expr(t.typdefaultbin, 0) as default_bin,
|
|
142
|
+
t.typdefault as default_value,
|
|
143
|
+
t.typowner::regrole::text as owner,
|
|
144
|
+
obj_description(t.oid, 'pg_type') as comment,
|
|
145
|
+
coalesce(
|
|
146
|
+
(
|
|
147
|
+
select json_agg(
|
|
148
|
+
json_build_object(
|
|
149
|
+
'name', quote_ident(con.conname),
|
|
150
|
+
'validated', con.convalidated,
|
|
151
|
+
'is_local', con.conislocal,
|
|
152
|
+
'no_inherit', con.connoinherit,
|
|
153
|
+
'check_expression', pg_get_expr(con.conbin, 0)
|
|
154
|
+
)
|
|
155
|
+
order by con.conname
|
|
156
|
+
)
|
|
157
|
+
from pg_catalog.pg_constraint con
|
|
158
|
+
where con.contypid = t.oid
|
|
159
|
+
), '[]'
|
|
160
|
+
) as constraints,
|
|
161
|
+
coalesce(
|
|
162
|
+
(
|
|
163
|
+
select json_agg(
|
|
164
|
+
json_build_object(
|
|
165
|
+
'grantee', case when x.grantee = 0 then 'PUBLIC' else x.grantee::regrole::text end,
|
|
166
|
+
'privilege', x.privilege_type,
|
|
167
|
+
'grantable', x.is_grantable
|
|
168
|
+
)
|
|
169
|
+
order by x.grantee, x.privilege_type
|
|
170
|
+
)
|
|
171
|
+
from lateral aclexplode(t.typacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
172
|
+
), '[]'
|
|
173
|
+
) as privileges
|
|
174
|
+
from
|
|
175
|
+
pg_catalog.pg_type t
|
|
176
|
+
inner join pg_catalog.pg_type bt on bt.oid = t.typbasetype
|
|
177
|
+
left join pg_catalog.pg_collation c on c.oid = t.typcollation
|
|
178
|
+
left outer join extension_oids e on t.oid = e.objid
|
|
179
|
+
where not t.typnamespace::regnamespace::text like any(array['pg\\_%', 'information\\_schema'])
|
|
180
|
+
and e.objid is null
|
|
181
|
+
and t.typtype = 'd'
|
|
182
|
+
order by
|
|
183
|
+
1, 2
|
|
184
|
+
`);
|
|
185
|
+
// Validate and parse each row using the Zod schema
|
|
186
|
+
const validatedRows = domainRows.map((row: unknown) =>
|
|
187
|
+
domainPropsSchema.parse(row),
|
|
188
|
+
);
|
|
189
|
+
return validatedRows.map((row: DomainProps) => new Domain(row));
|
|
190
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { EventTrigger } from "../event-trigger.model.ts";
|
|
3
|
+
import {
|
|
4
|
+
AlterEventTriggerChangeOwner,
|
|
5
|
+
AlterEventTriggerSetEnabled,
|
|
6
|
+
} from "./event-trigger.alter.ts";
|
|
7
|
+
|
|
8
|
+
describe("event trigger alter change", () => {
|
|
9
|
+
const baseEventTrigger = new EventTrigger({
|
|
10
|
+
name: "ddl_logger",
|
|
11
|
+
event: "ddl_command_start",
|
|
12
|
+
function_schema: "public",
|
|
13
|
+
function_name: "log_ddl",
|
|
14
|
+
enabled: "O",
|
|
15
|
+
tags: null,
|
|
16
|
+
owner: "postgres",
|
|
17
|
+
comment: null,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("serialize owner change", () => {
|
|
21
|
+
const change = new AlterEventTriggerChangeOwner({
|
|
22
|
+
eventTrigger: baseEventTrigger,
|
|
23
|
+
owner: "new_owner",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(change.serialize()).toBe(
|
|
27
|
+
"ALTER EVENT TRIGGER ddl_logger OWNER TO new_owner",
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("serialize disable", () => {
|
|
32
|
+
const change = new AlterEventTriggerSetEnabled({
|
|
33
|
+
eventTrigger: baseEventTrigger,
|
|
34
|
+
enabled: "D",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(change.serialize()).toBe("ALTER EVENT TRIGGER ddl_logger DISABLE");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("serialize enable always", () => {
|
|
41
|
+
const change = new AlterEventTriggerSetEnabled({
|
|
42
|
+
eventTrigger: baseEventTrigger,
|
|
43
|
+
enabled: "A",
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(change.serialize()).toBe(
|
|
47
|
+
"ALTER EVENT TRIGGER ddl_logger ENABLE ALWAYS",
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { EventTrigger } from "../event-trigger.model.ts";
|
|
2
|
+
import { AlterEventTriggerChange } from "./event-trigger.base.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Alter an event trigger.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.postgresql.org/docs/17/sql-altereventtrigger.html
|
|
8
|
+
*
|
|
9
|
+
* Synopsis
|
|
10
|
+
* ```sql
|
|
11
|
+
* ALTER EVENT TRIGGER name DISABLE
|
|
12
|
+
* ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
|
|
13
|
+
* ALTER EVENT TRIGGER name OWNER TO { newowner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
|
|
14
|
+
* ALTER EVENT TRIGGER name RENAME TO newname
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export type AlterEventTrigger =
|
|
19
|
+
| AlterEventTriggerChangeOwner
|
|
20
|
+
| AlterEventTriggerSetEnabled;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* ALTER EVENT TRIGGER ... OWNER TO ...
|
|
24
|
+
*/
|
|
25
|
+
export class AlterEventTriggerChangeOwner extends AlterEventTriggerChange {
|
|
26
|
+
public readonly eventTrigger: EventTrigger;
|
|
27
|
+
public readonly owner: string;
|
|
28
|
+
public readonly scope = "object" as const;
|
|
29
|
+
|
|
30
|
+
constructor(props: { eventTrigger: EventTrigger; owner: string }) {
|
|
31
|
+
super();
|
|
32
|
+
this.eventTrigger = props.eventTrigger;
|
|
33
|
+
this.owner = props.owner;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get requires() {
|
|
37
|
+
return [this.eventTrigger.stableId];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
serialize(): string {
|
|
41
|
+
return [
|
|
42
|
+
"ALTER EVENT TRIGGER",
|
|
43
|
+
this.eventTrigger.name,
|
|
44
|
+
"OWNER TO",
|
|
45
|
+
this.owner,
|
|
46
|
+
].join(" ");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const ENABLED_SQL = {
|
|
51
|
+
O: "ENABLE",
|
|
52
|
+
D: "DISABLE",
|
|
53
|
+
R: "ENABLE REPLICA",
|
|
54
|
+
A: "ENABLE ALWAYS",
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* ALTER EVENT TRIGGER ... ENABLE/DISABLE ...
|
|
59
|
+
*/
|
|
60
|
+
export class AlterEventTriggerSetEnabled extends AlterEventTriggerChange {
|
|
61
|
+
public readonly eventTrigger: EventTrigger;
|
|
62
|
+
public readonly enabled: EventTrigger["enabled"];
|
|
63
|
+
public readonly scope = "object" as const;
|
|
64
|
+
|
|
65
|
+
constructor(props: {
|
|
66
|
+
eventTrigger: EventTrigger;
|
|
67
|
+
enabled: EventTrigger["enabled"];
|
|
68
|
+
}) {
|
|
69
|
+
super();
|
|
70
|
+
this.eventTrigger = props.eventTrigger;
|
|
71
|
+
this.enabled = props.enabled;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get requires() {
|
|
75
|
+
return [this.eventTrigger.stableId];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
serialize(): string {
|
|
79
|
+
const clause = ENABLED_SQL[this.enabled];
|
|
80
|
+
return ["ALTER EVENT TRIGGER", this.eventTrigger.name, clause].join(" ");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseChange } from "../../base.change.ts";
|
|
2
|
+
import type { EventTrigger } from "../event-trigger.model.ts";
|
|
3
|
+
|
|
4
|
+
abstract class BaseEventTriggerChange extends BaseChange {
|
|
5
|
+
abstract readonly eventTrigger: EventTrigger;
|
|
6
|
+
abstract readonly scope: "object" | "comment";
|
|
7
|
+
readonly objectType = "event_trigger" as const;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export abstract class CreateEventTriggerChange extends BaseEventTriggerChange {
|
|
11
|
+
readonly operation = "create" as const;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export abstract class AlterEventTriggerChange extends BaseEventTriggerChange {
|
|
15
|
+
readonly operation = "alter" as const;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export abstract class DropEventTriggerChange extends BaseEventTriggerChange {
|
|
19
|
+
readonly operation = "drop" as const;
|
|
20
|
+
}
|