@supabase/pg-delta 1.0.0-alpha.2 → 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.
Files changed (464) hide show
  1. package/README.md +22 -0
  2. package/dist/cli/bin/cli.js +0 -0
  3. package/dist/cli/commands/plan.js +21 -0
  4. package/dist/cli/utils.d.ts +2 -0
  5. package/dist/cli/utils.js +1 -1
  6. package/dist/core/integrations/supabase.js +2 -0
  7. package/dist/core/objects/table/table.model.d.ts +4 -2
  8. package/dist/core/objects/table/table.model.js +3 -0
  9. package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
  10. package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
  11. package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
  12. package/dist/core/objects/trigger/trigger.model.js +3 -0
  13. package/dist/core/plan/apply.js +3 -3
  14. package/dist/core/plan/create.js +34 -15
  15. package/dist/core/plan/sql-format/constants.d.ts +2 -0
  16. package/dist/core/plan/sql-format/constants.js +11 -0
  17. package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
  18. package/dist/core/plan/sql-format/fixtures.js +2449 -0
  19. package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
  20. package/dist/core/plan/sql-format/format-utils.js +274 -0
  21. package/dist/core/plan/sql-format/formatters.d.ts +20 -0
  22. package/dist/core/plan/sql-format/formatters.js +737 -0
  23. package/dist/core/plan/sql-format/index.d.ts +2 -0
  24. package/dist/core/plan/sql-format/index.js +98 -0
  25. package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
  26. package/dist/core/plan/sql-format/keyword-case.js +868 -0
  27. package/dist/core/plan/sql-format/protect.d.ts +3 -0
  28. package/dist/core/plan/sql-format/protect.js +269 -0
  29. package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
  30. package/dist/core/plan/sql-format/sql-scanner.js +202 -0
  31. package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
  32. package/dist/core/plan/sql-format/tokenizer.js +118 -0
  33. package/dist/core/plan/sql-format/types.d.ts +28 -0
  34. package/dist/core/plan/sql-format/types.js +1 -0
  35. package/dist/core/plan/sql-format/wrap.d.ts +2 -0
  36. package/dist/core/plan/sql-format/wrap.js +165 -0
  37. package/dist/core/plan/sql-format.d.ts +2 -0
  38. package/dist/core/plan/sql-format.js +1 -0
  39. package/dist/core/plan/statements.d.ts +2 -1
  40. package/dist/core/plan/statements.js +6 -2
  41. package/dist/core/postgres-config.d.ts +15 -0
  42. package/dist/core/postgres-config.js +30 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +1 -0
  45. package/package.json +37 -22
  46. package/src/cli/app.ts +28 -0
  47. package/src/cli/bin/cli.ts +9 -0
  48. package/src/cli/commands/apply.ts +101 -0
  49. package/src/cli/commands/plan.ts +195 -0
  50. package/src/cli/commands/sync.ts +185 -0
  51. package/src/cli/formatters/index.ts +5 -0
  52. package/src/cli/formatters/tree/tree-builder.ts +380 -0
  53. package/src/cli/formatters/tree/tree-renderer.ts +372 -0
  54. package/src/cli/formatters/tree/tree.ts +237 -0
  55. package/src/cli/utils/integrations.ts +42 -0
  56. package/src/cli/utils.ts +231 -0
  57. package/src/core/catalog.diff.ts +246 -0
  58. package/src/core/catalog.model.ts +384 -0
  59. package/src/core/change.types.ts +44 -0
  60. package/src/core/context.ts +26 -0
  61. package/src/core/depend.ts +1870 -0
  62. package/src/core/expand-replace-dependencies.ts +380 -0
  63. package/src/core/fingerprint.ts +204 -0
  64. package/src/core/integrations/filter/dsl.ts +204 -0
  65. package/src/core/integrations/filter/extractors.ts +145 -0
  66. package/src/core/integrations/filter/filter.types.ts +3 -0
  67. package/src/core/integrations/integration-dsl.ts +24 -0
  68. package/src/core/integrations/integration.types.ts +7 -0
  69. package/src/core/integrations/serialize/dsl.ts +77 -0
  70. package/src/core/integrations/serialize/serialize.types.ts +3 -0
  71. package/src/core/integrations/supabase.ts +121 -0
  72. package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
  73. package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
  74. package/src/core/objects/aggregate/aggregate.model.ts +317 -0
  75. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
  76. package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
  77. package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
  78. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
  79. package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
  80. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
  81. package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
  82. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
  83. package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
  84. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
  85. package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
  86. package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
  87. package/src/core/objects/base.change.ts +62 -0
  88. package/src/core/objects/base.default-privileges.ts +204 -0
  89. package/src/core/objects/base.diff.ts +20 -0
  90. package/src/core/objects/base.model.ts +82 -0
  91. package/src/core/objects/base.privilege-diff.ts +299 -0
  92. package/src/core/objects/base.privilege.ts +184 -0
  93. package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
  94. package/src/core/objects/collation/changes/collation.alter.ts +79 -0
  95. package/src/core/objects/collation/changes/collation.base.ts +20 -0
  96. package/src/core/objects/collation/changes/collation.comment.ts +68 -0
  97. package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
  98. package/src/core/objects/collation/changes/collation.create.ts +106 -0
  99. package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
  100. package/src/core/objects/collation/changes/collation.drop.ts +37 -0
  101. package/src/core/objects/collation/changes/collation.types.ts +10 -0
  102. package/src/core/objects/collation/collation.diff.test.ts +100 -0
  103. package/src/core/objects/collation/collation.diff.ts +126 -0
  104. package/src/core/objects/collation/collation.model.ts +224 -0
  105. package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
  106. package/src/core/objects/domain/changes/domain.alter.ts +286 -0
  107. package/src/core/objects/domain/changes/domain.base.ts +20 -0
  108. package/src/core/objects/domain/changes/domain.comment.ts +59 -0
  109. package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
  110. package/src/core/objects/domain/changes/domain.create.ts +118 -0
  111. package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
  112. package/src/core/objects/domain/changes/domain.drop.ts +34 -0
  113. package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
  114. package/src/core/objects/domain/changes/domain.types.ts +12 -0
  115. package/src/core/objects/domain/domain.diff.test.ts +284 -0
  116. package/src/core/objects/domain/domain.diff.ts +358 -0
  117. package/src/core/objects/domain/domain.model.ts +190 -0
  118. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
  119. package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
  120. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
  121. package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
  122. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
  123. package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
  124. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
  125. package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
  126. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
  127. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
  128. package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
  129. package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
  130. package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
  131. package/src/core/objects/extension/changes/extension.alter.ts +78 -0
  132. package/src/core/objects/extension/changes/extension.base.ts +20 -0
  133. package/src/core/objects/extension/changes/extension.comment.ts +64 -0
  134. package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
  135. package/src/core/objects/extension/changes/extension.create.ts +63 -0
  136. package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
  137. package/src/core/objects/extension/changes/extension.drop.ts +34 -0
  138. package/src/core/objects/extension/changes/extension.types.ts +10 -0
  139. package/src/core/objects/extension/extension.diff.test.ts +42 -0
  140. package/src/core/objects/extension/extension.diff.ts +90 -0
  141. package/src/core/objects/extension/extension.model.ts +280 -0
  142. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
  143. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
  144. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
  146. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
  148. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
  149. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
  150. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
  151. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
  152. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
  153. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
  154. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
  155. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
  156. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
  157. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
  158. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
  159. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
  160. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
  161. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
  162. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
  163. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
  164. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
  165. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
  166. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
  167. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
  168. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
  169. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
  170. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
  171. package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
  172. package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
  173. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
  174. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
  175. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
  176. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
  177. package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
  178. package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
  179. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
  180. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
  181. package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
  182. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
  183. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
  184. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
  185. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
  186. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
  187. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
  188. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
  189. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
  190. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
  191. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
  192. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
  193. package/src/core/objects/index/changes/index.alter.test.ts +200 -0
  194. package/src/core/objects/index/changes/index.alter.ts +144 -0
  195. package/src/core/objects/index/changes/index.base.ts +20 -0
  196. package/src/core/objects/index/changes/index.comment.ts +63 -0
  197. package/src/core/objects/index/changes/index.create.test.ts +66 -0
  198. package/src/core/objects/index/changes/index.create.ts +68 -0
  199. package/src/core/objects/index/changes/index.drop.test.ts +44 -0
  200. package/src/core/objects/index/changes/index.drop.ts +34 -0
  201. package/src/core/objects/index/changes/index.types.ts +6 -0
  202. package/src/core/objects/index/changes/utils.ts +16 -0
  203. package/src/core/objects/index/index.diff.test.ts +153 -0
  204. package/src/core/objects/index/index.diff.ts +243 -0
  205. package/src/core/objects/index/index.model.ts +370 -0
  206. package/src/core/objects/language/changes/language.alter.test.ts +33 -0
  207. package/src/core/objects/language/changes/language.alter.ts +53 -0
  208. package/src/core/objects/language/changes/language.base.ts +20 -0
  209. package/src/core/objects/language/changes/language.comment.ts +58 -0
  210. package/src/core/objects/language/changes/language.create.test.ts +27 -0
  211. package/src/core/objects/language/changes/language.create.ts +104 -0
  212. package/src/core/objects/language/changes/language.drop.test.ts +25 -0
  213. package/src/core/objects/language/changes/language.drop.ts +39 -0
  214. package/src/core/objects/language/changes/language.privilege.ts +172 -0
  215. package/src/core/objects/language/changes/language.types.ts +12 -0
  216. package/src/core/objects/language/language.diff.test.ts +53 -0
  217. package/src/core/objects/language/language.diff.ts +176 -0
  218. package/src/core/objects/language/language.model.ts +150 -0
  219. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
  220. package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
  221. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
  222. package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
  223. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
  224. package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
  225. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
  226. package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
  227. package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
  228. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
  229. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
  230. package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
  231. package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
  232. package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
  233. package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
  234. package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
  235. package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
  236. package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
  237. package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
  238. package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
  239. package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
  240. package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
  241. package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
  242. package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
  243. package/src/core/objects/procedure/procedure.diff.ts +404 -0
  244. package/src/core/objects/procedure/procedure.model.ts +264 -0
  245. package/src/core/objects/procedure/utils.ts +58 -0
  246. package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
  247. package/src/core/objects/publication/changes/publication.alter.ts +243 -0
  248. package/src/core/objects/publication/changes/publication.base.ts +20 -0
  249. package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
  250. package/src/core/objects/publication/changes/publication.comment.ts +64 -0
  251. package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
  252. package/src/core/objects/publication/changes/publication.create.ts +82 -0
  253. package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
  254. package/src/core/objects/publication/changes/publication.drop.ts +29 -0
  255. package/src/core/objects/publication/changes/publication.types.ts +26 -0
  256. package/src/core/objects/publication/publication.diff.test.ts +292 -0
  257. package/src/core/objects/publication/publication.diff.ts +253 -0
  258. package/src/core/objects/publication/publication.model.ts +206 -0
  259. package/src/core/objects/publication/utils.ts +55 -0
  260. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
  261. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
  262. package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
  263. package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
  264. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
  265. package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
  266. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
  267. package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
  268. package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
  269. package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
  270. package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
  271. package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
  272. package/src/core/objects/role/changes/role.alter.test.ts +346 -0
  273. package/src/core/objects/role/changes/role.alter.ts +110 -0
  274. package/src/core/objects/role/changes/role.base.ts +24 -0
  275. package/src/core/objects/role/changes/role.comment.ts +55 -0
  276. package/src/core/objects/role/changes/role.create.test.ts +52 -0
  277. package/src/core/objects/role/changes/role.create.ts +102 -0
  278. package/src/core/objects/role/changes/role.drop.test.ts +29 -0
  279. package/src/core/objects/role/changes/role.drop.ts +34 -0
  280. package/src/core/objects/role/changes/role.privilege.ts +376 -0
  281. package/src/core/objects/role/changes/role.types.ts +12 -0
  282. package/src/core/objects/role/role.diff.test.ts +44 -0
  283. package/src/core/objects/role/role.diff.ts +479 -0
  284. package/src/core/objects/role/role.model.ts +344 -0
  285. package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
  286. package/src/core/objects/rule/changes/rule.alter.ts +72 -0
  287. package/src/core/objects/rule/changes/rule.base.ts +20 -0
  288. package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
  289. package/src/core/objects/rule/changes/rule.comment.ts +62 -0
  290. package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
  291. package/src/core/objects/rule/changes/rule.create.ts +42 -0
  292. package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
  293. package/src/core/objects/rule/changes/rule.drop.ts +29 -0
  294. package/src/core/objects/rule/changes/rule.types.ts +12 -0
  295. package/src/core/objects/rule/rule.diff.test.ts +132 -0
  296. package/src/core/objects/rule/rule.diff.ts +79 -0
  297. package/src/core/objects/rule/rule.model.ts +173 -0
  298. package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
  299. package/src/core/objects/schema/changes/schema.alter.ts +45 -0
  300. package/src/core/objects/schema/changes/schema.base.ts +20 -0
  301. package/src/core/objects/schema/changes/schema.comment.ts +56 -0
  302. package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
  303. package/src/core/objects/schema/changes/schema.create.ts +47 -0
  304. package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
  305. package/src/core/objects/schema/changes/schema.drop.ts +34 -0
  306. package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
  307. package/src/core/objects/schema/changes/schema.types.ts +12 -0
  308. package/src/core/objects/schema/schema.diff.test.ts +42 -0
  309. package/src/core/objects/schema/schema.diff.ts +209 -0
  310. package/src/core/objects/schema/schema.model.ts +107 -0
  311. package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
  312. package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
  313. package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
  314. package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
  315. package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
  316. package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
  317. package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
  318. package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
  319. package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
  320. package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
  321. package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
  322. package/src/core/objects/sequence/sequence.diff.ts +359 -0
  323. package/src/core/objects/sequence/sequence.model.ts +185 -0
  324. package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
  325. package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
  326. package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
  327. package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
  328. package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
  329. package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
  330. package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
  331. package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
  332. package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
  333. package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
  334. package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
  335. package/src/core/objects/subscription/subscription.diff.ts +241 -0
  336. package/src/core/objects/subscription/subscription.model.ts +190 -0
  337. package/src/core/objects/subscription/utils.ts +156 -0
  338. package/src/core/objects/table/changes/table.alter.test.ts +823 -0
  339. package/src/core/objects/table/changes/table.alter.ts +806 -0
  340. package/src/core/objects/table/changes/table.base.ts +20 -0
  341. package/src/core/objects/table/changes/table.comment.ts +266 -0
  342. package/src/core/objects/table/changes/table.create.test.ts +150 -0
  343. package/src/core/objects/table/changes/table.create.ts +188 -0
  344. package/src/core/objects/table/changes/table.drop.test.ts +34 -0
  345. package/src/core/objects/table/changes/table.drop.ts +45 -0
  346. package/src/core/objects/table/changes/table.privilege.ts +200 -0
  347. package/src/core/objects/table/changes/table.types.ts +12 -0
  348. package/src/core/objects/table/table.diff.test.ts +711 -0
  349. package/src/core/objects/table/table.diff.ts +953 -0
  350. package/src/core/objects/table/table.model.ts +460 -0
  351. package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
  352. package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
  353. package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
  354. package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
  355. package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
  356. package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
  357. package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
  358. package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
  359. package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
  360. package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
  361. package/src/core/objects/trigger/trigger.diff.ts +116 -0
  362. package/src/core/objects/trigger/trigger.model.ts +252 -0
  363. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
  364. package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
  365. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
  366. package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
  367. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
  368. package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
  369. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
  370. package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
  371. package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
  372. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
  373. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
  374. package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
  375. package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
  376. package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
  377. package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
  378. package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
  379. package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
  380. package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
  381. package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
  382. package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
  383. package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
  384. package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
  385. package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
  386. package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
  387. package/src/core/objects/type/enum/enum.diff.ts +396 -0
  388. package/src/core/objects/type/enum/enum.model.ts +194 -0
  389. package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
  390. package/src/core/objects/type/range/changes/range.alter.ts +51 -0
  391. package/src/core/objects/type/range/changes/range.base.ts +20 -0
  392. package/src/core/objects/type/range/changes/range.comment.ts +64 -0
  393. package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
  394. package/src/core/objects/type/range/changes/range.create.ts +151 -0
  395. package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
  396. package/src/core/objects/type/range/changes/range.drop.ts +34 -0
  397. package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
  398. package/src/core/objects/type/range/changes/range.types.ts +12 -0
  399. package/src/core/objects/type/range/range.diff.test.ts +70 -0
  400. package/src/core/objects/type/range/range.diff.ts +259 -0
  401. package/src/core/objects/type/range/range.model.ts +187 -0
  402. package/src/core/objects/type/type.types.ts +5 -0
  403. package/src/core/objects/utils.ts +171 -0
  404. package/src/core/objects/view/changes/view.alter.test.ts +110 -0
  405. package/src/core/objects/view/changes/view.alter.ts +112 -0
  406. package/src/core/objects/view/changes/view.base.ts +20 -0
  407. package/src/core/objects/view/changes/view.comment.ts +59 -0
  408. package/src/core/objects/view/changes/view.create.test.ts +65 -0
  409. package/src/core/objects/view/changes/view.create.ts +73 -0
  410. package/src/core/objects/view/changes/view.drop.test.ts +34 -0
  411. package/src/core/objects/view/changes/view.drop.ts +40 -0
  412. package/src/core/objects/view/changes/view.privilege.ts +200 -0
  413. package/src/core/objects/view/changes/view.types.ts +12 -0
  414. package/src/core/objects/view/view.diff.test.ts +91 -0
  415. package/src/core/objects/view/view.diff.ts +365 -0
  416. package/src/core/objects/view/view.model.ts +276 -0
  417. package/src/core/plan/apply.ts +190 -0
  418. package/src/core/plan/create.ts +432 -0
  419. package/src/core/plan/hierarchy.ts +574 -0
  420. package/src/core/plan/index.ts +29 -0
  421. package/src/core/plan/io.ts +20 -0
  422. package/src/core/plan/risk.ts +48 -0
  423. package/src/core/plan/serialize.ts +195 -0
  424. package/src/core/plan/sql-format/constants.ts +13 -0
  425. package/src/core/plan/sql-format/fixtures.ts +2806 -0
  426. package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
  427. package/src/core/plan/sql-format/format-functions.test.ts +127 -0
  428. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
  429. package/src/core/plan/sql-format/format-off.test.ts +809 -0
  430. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
  431. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
  432. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
  433. package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
  434. package/src/core/plan/sql-format/format-stress.test.ts +616 -0
  435. package/src/core/plan/sql-format/format-utils.test.ts +91 -0
  436. package/src/core/plan/sql-format/format-utils.ts +391 -0
  437. package/src/core/plan/sql-format/formatters.ts +921 -0
  438. package/src/core/plan/sql-format/index.ts +149 -0
  439. package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
  440. package/src/core/plan/sql-format/keyword-case.ts +1085 -0
  441. package/src/core/plan/sql-format/protect.test.ts +127 -0
  442. package/src/core/plan/sql-format/protect.ts +337 -0
  443. package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
  444. package/src/core/plan/sql-format/sql-scanner.ts +252 -0
  445. package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
  446. package/src/core/plan/sql-format/tokenizer.ts +152 -0
  447. package/src/core/plan/sql-format/types.ts +31 -0
  448. package/src/core/plan/sql-format/wrap.test.ts +119 -0
  449. package/src/core/plan/sql-format/wrap.ts +196 -0
  450. package/src/core/plan/sql-format.ts +2 -0
  451. package/src/core/plan/statements.ts +22 -0
  452. package/src/core/plan/types.ts +165 -0
  453. package/src/core/postgres-config.ts +169 -0
  454. package/src/core/sort/custom-constraints.ts +161 -0
  455. package/src/core/sort/debug-visualization.ts +239 -0
  456. package/src/core/sort/dependency-filter.ts +224 -0
  457. package/src/core/sort/graph-builder.ts +223 -0
  458. package/src/core/sort/graph-utils.ts +51 -0
  459. package/src/core/sort/logical-sort.ts +590 -0
  460. package/src/core/sort/sort-changes.ts +234 -0
  461. package/src/core/sort/topological-sort.ts +184 -0
  462. package/src/core/sort/types.ts +112 -0
  463. package/src/core/sort/utils.ts +69 -0
  464. package/src/index.ts +14 -0
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Format function arguments for CREATE/DROP FUNCTION statements.
3
+ *
4
+ * @param argNames - Array of argument names (can be null)
5
+ * @param argTypes - Array of argument types (required)
6
+ * @param argModes - Array of argument modes (can be null)
7
+ * @returns Formatted argument string
8
+ */
9
+ export function formatFunctionArguments(
10
+ argNames: string[] | null,
11
+ argTypes: string[] | null,
12
+ argModes: string[] | null,
13
+ ): string {
14
+ const names = argNames ?? [];
15
+ const types = argTypes ?? [];
16
+ const modes = argModes ?? [];
17
+
18
+ if (types.length === 0) {
19
+ return "";
20
+ }
21
+
22
+ const modeMap: Record<string, string> = {
23
+ i: "IN",
24
+ o: "OUT",
25
+ b: "INOUT",
26
+ v: "VARIADIC",
27
+ t: "TABLE",
28
+ };
29
+
30
+ return types
31
+ .map((type, i) => {
32
+ const name = names[i] ?? ""; // already quoted in model, if present
33
+ const mode = modes[i] ? modeMap[modes[i]] : "";
34
+
35
+ const parts: string[] = [];
36
+ if (mode) parts.push(mode);
37
+ if (name) parts.push(name);
38
+ parts.push(type);
39
+
40
+ return parts.join(" ");
41
+ })
42
+ .join(", ");
43
+ }
44
+
45
+ /**
46
+ * Format a GUC value for SET ... TO ... in function/procedure definitions.
47
+ * Applies quoting rules consistent with PostgreSQL docs and psql style.
48
+ */
49
+ export function formatConfigValue(key: string, rawValue: string): string {
50
+ const value = rawValue.trim();
51
+ if (value.length === 0) return value;
52
+ const lowerKey = key.toLowerCase();
53
+ if (value.startsWith("'") && value.endsWith("'")) return value;
54
+ if (/^(true|false|on|off)$/i.test(value)) return value.toLowerCase();
55
+ if (/^-?\d+(?:\.\d+)?$/.test(value)) return value;
56
+ if (lowerKey === "search_path" || value.includes(",")) return value;
57
+ return `'${value.replace(/'/g, "''")}'`;
58
+ }
@@ -0,0 +1,223 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { stableId } from "../../utils.ts";
3
+ import type { PublicationTableProps } from "../publication.model.ts";
4
+ import { Publication } from "../publication.model.ts";
5
+ import {
6
+ AlterPublicationAddSchemas,
7
+ AlterPublicationAddTables,
8
+ AlterPublicationDropSchemas,
9
+ AlterPublicationDropTables,
10
+ AlterPublicationSetForAllTables,
11
+ AlterPublicationSetList,
12
+ AlterPublicationSetOptions,
13
+ AlterPublicationSetOwner,
14
+ } from "./publication.alter.ts";
15
+
16
+ type PublicationProps = ConstructorParameters<typeof Publication>[0];
17
+
18
+ const base: PublicationProps = {
19
+ name: "pub_base",
20
+ owner: "owner1",
21
+ comment: null,
22
+ all_tables: true,
23
+ publish_insert: true,
24
+ publish_update: true,
25
+ publish_delete: true,
26
+ publish_truncate: true,
27
+ publish_via_partition_root: false,
28
+ tables: [],
29
+ schemas: [],
30
+ };
31
+
32
+ const cloneTables = (tables: PublicationProps["tables"]) =>
33
+ tables.map((table) => ({
34
+ ...table,
35
+ columns: table.columns ? [...table.columns] : null,
36
+ }));
37
+
38
+ const makePublication = (override: Partial<PublicationProps> = {}) =>
39
+ new Publication({
40
+ ...base,
41
+ ...override,
42
+ tables: override.tables
43
+ ? cloneTables(override.tables)
44
+ : cloneTables(base.tables),
45
+ schemas: override.schemas ? [...override.schemas] : [...base.schemas],
46
+ });
47
+
48
+ describe("publication.alter", () => {
49
+ test("set options serializes assignments and requires publication", () => {
50
+ const publication = makePublication({
51
+ name: "pub_options",
52
+ publish_delete: false,
53
+ publish_truncate: false,
54
+ publish_via_partition_root: true,
55
+ });
56
+ const change = new AlterPublicationSetOptions({
57
+ publication,
58
+ setPublish: true,
59
+ setPublishViaPartitionRoot: true,
60
+ });
61
+
62
+ expect(change.requires).toEqual([publication.stableId]);
63
+ expect(change.serialize()).toBe(
64
+ "ALTER PUBLICATION pub_options SET (publish = 'insert, update', publish_via_partition_root = true)",
65
+ );
66
+ });
67
+
68
+ test("set for all tables serializes and requires publication", () => {
69
+ const publication = makePublication({
70
+ name: "pub_all",
71
+ all_tables: false,
72
+ });
73
+ const change = new AlterPublicationSetForAllTables({ publication });
74
+
75
+ expect(change.requires).toEqual([publication.stableId]);
76
+ expect(change.serialize()).toBe(
77
+ "ALTER PUBLICATION pub_all SET FOR ALL TABLES",
78
+ );
79
+ });
80
+
81
+ test("set list serializes object selection and tracks dependencies", () => {
82
+ const publication = makePublication({
83
+ name: "pub_set_list",
84
+ all_tables: false,
85
+ tables: [
86
+ {
87
+ schema: "public",
88
+ name: "authors",
89
+ columns: ["name", "id"],
90
+ row_filter: null,
91
+ },
92
+ {
93
+ schema: "public",
94
+ name: "articles",
95
+ columns: null,
96
+ row_filter: " published = true ",
97
+ },
98
+ ],
99
+ schemas: ["analytics"],
100
+ });
101
+ const change = new AlterPublicationSetList({ publication });
102
+
103
+ expect(change.requires).toEqual([
104
+ publication.stableId,
105
+ stableId.table("public", "articles"),
106
+ stableId.table("public", "authors"),
107
+ stableId.column("public", "authors", "id"),
108
+ stableId.column("public", "authors", "name"),
109
+ stableId.schema("analytics"),
110
+ ]);
111
+ expect(change.serialize()).toBe(
112
+ "ALTER PUBLICATION pub_set_list SET TABLE public.articles WHERE (published = true), TABLE public.authors (id, name), TABLES IN SCHEMA analytics",
113
+ );
114
+ });
115
+
116
+ test("add tables serializes new tables and tracks dependencies", () => {
117
+ const publication = makePublication({ name: "pub_add_tables" });
118
+ const tables: PublicationTableProps[] = [
119
+ {
120
+ schema: "public",
121
+ name: "logs",
122
+ columns: null,
123
+ row_filter: null,
124
+ },
125
+ {
126
+ schema: "audit",
127
+ name: "events",
128
+ columns: ["created_at", "id"],
129
+ row_filter: null,
130
+ },
131
+ ];
132
+ const change = new AlterPublicationAddTables({ publication, tables });
133
+
134
+ expect(change.requires).toEqual([
135
+ publication.stableId,
136
+ stableId.table("public", "logs"),
137
+ stableId.table("audit", "events"),
138
+ stableId.column("audit", "events", "created_at"),
139
+ stableId.column("audit", "events", "id"),
140
+ ]);
141
+ expect(change.serialize()).toBe(
142
+ "ALTER PUBLICATION pub_add_tables ADD TABLE public.logs, TABLE audit.events (created_at, id)",
143
+ );
144
+ });
145
+
146
+ test("drop tables serializes target list and tracks dependencies", () => {
147
+ const publication = makePublication({ name: "pub_drop_tables" });
148
+ const tables: PublicationTableProps[] = [
149
+ {
150
+ schema: "public",
151
+ name: "logs",
152
+ columns: null,
153
+ row_filter: null,
154
+ },
155
+ {
156
+ schema: "audit",
157
+ name: "events",
158
+ columns: ["id"],
159
+ row_filter: null,
160
+ },
161
+ ];
162
+ const change = new AlterPublicationDropTables({ publication, tables });
163
+
164
+ expect(change.requires).toEqual([
165
+ publication.stableId,
166
+ stableId.table("public", "logs"),
167
+ stableId.table("audit", "events"),
168
+ ]);
169
+ expect(change.serialize()).toBe(
170
+ "ALTER PUBLICATION pub_drop_tables DROP TABLE public.logs, audit.events",
171
+ );
172
+ });
173
+
174
+ test("add schemas serializes and tracks dependencies", () => {
175
+ const publication = makePublication({ name: "pub_add_schemas" });
176
+ const change = new AlterPublicationAddSchemas({
177
+ publication,
178
+ schemas: ["analytics", "sales"],
179
+ });
180
+
181
+ expect(change.requires).toEqual([
182
+ publication.stableId,
183
+ stableId.schema("analytics"),
184
+ stableId.schema("sales"),
185
+ ]);
186
+ expect(change.serialize()).toBe(
187
+ "ALTER PUBLICATION pub_add_schemas ADD TABLES IN SCHEMA analytics, TABLES IN SCHEMA sales",
188
+ );
189
+ });
190
+
191
+ test("drop schemas serializes and tracks dependencies", () => {
192
+ const publication = makePublication({ name: "pub_drop_schemas" });
193
+ const change = new AlterPublicationDropSchemas({
194
+ publication,
195
+ schemas: ["analytics", "sales"],
196
+ });
197
+
198
+ expect(change.requires).toEqual([
199
+ publication.stableId,
200
+ stableId.schema("analytics"),
201
+ stableId.schema("sales"),
202
+ ]);
203
+ expect(change.serialize()).toBe(
204
+ "ALTER PUBLICATION pub_drop_schemas DROP TABLES IN SCHEMA analytics, TABLES IN SCHEMA sales",
205
+ );
206
+ });
207
+
208
+ test("set owner serializes and tracks dependencies", () => {
209
+ const publication = makePublication({ name: "pub_owner" });
210
+ const change = new AlterPublicationSetOwner({
211
+ publication,
212
+ owner: "owner2",
213
+ });
214
+
215
+ expect(change.requires).toEqual([
216
+ publication.stableId,
217
+ stableId.role("owner2"),
218
+ ]);
219
+ expect(change.serialize()).toBe(
220
+ "ALTER PUBLICATION pub_owner OWNER TO owner2",
221
+ );
222
+ });
223
+ });
@@ -0,0 +1,243 @@
1
+ import { stableId } from "../../utils.ts";
2
+ import type {
3
+ Publication,
4
+ PublicationTableProps,
5
+ } from "../publication.model.ts";
6
+ import {
7
+ formatPublicationObjects,
8
+ formatPublicationTable,
9
+ getPublicationOperations,
10
+ } from "../utils.ts";
11
+ import { AlterPublicationChange } from "./publication.base.ts";
12
+
13
+ export class AlterPublicationSetOptions extends AlterPublicationChange {
14
+ public readonly publication: Publication;
15
+ public readonly scope = "object" as const;
16
+ private readonly setPublish: boolean;
17
+ private readonly setPublishViaPartitionRoot: boolean;
18
+
19
+ constructor(props: {
20
+ publication: Publication;
21
+ setPublish: boolean;
22
+ setPublishViaPartitionRoot: boolean;
23
+ }) {
24
+ super();
25
+ this.publication = props.publication;
26
+ this.setPublish = props.setPublish;
27
+ this.setPublishViaPartitionRoot = props.setPublishViaPartitionRoot;
28
+ }
29
+
30
+ get requires() {
31
+ return [this.publication.stableId];
32
+ }
33
+
34
+ serialize(): string {
35
+ const assignments: string[] = [];
36
+
37
+ if (this.setPublish) {
38
+ const operations = getPublicationOperations(this.publication);
39
+ assignments.push(`publish = '${operations.join(", ")}'`);
40
+ }
41
+
42
+ if (this.setPublishViaPartitionRoot) {
43
+ assignments.push(
44
+ `publish_via_partition_root = ${this.publication.publish_via_partition_root ? "true" : "false"}`,
45
+ );
46
+ }
47
+
48
+ return `ALTER PUBLICATION ${this.publication.name} SET (${assignments.join(", ")})`;
49
+ }
50
+ }
51
+
52
+ export class AlterPublicationSetForAllTables extends AlterPublicationChange {
53
+ public readonly publication: Publication;
54
+ public readonly scope = "object" as const;
55
+
56
+ constructor(props: { publication: Publication }) {
57
+ super();
58
+ this.publication = props.publication;
59
+ }
60
+
61
+ get requires() {
62
+ return [this.publication.stableId];
63
+ }
64
+
65
+ serialize(): string {
66
+ return `ALTER PUBLICATION ${this.publication.name} SET FOR ALL TABLES`;
67
+ }
68
+ }
69
+
70
+ export class AlterPublicationSetList extends AlterPublicationChange {
71
+ public readonly publication: Publication;
72
+ public readonly scope = "object" as const;
73
+
74
+ constructor(props: { publication: Publication }) {
75
+ super();
76
+ this.publication = props.publication;
77
+ }
78
+
79
+ get requires() {
80
+ const dependencies = new Set<string>();
81
+
82
+ dependencies.add(this.publication.stableId);
83
+
84
+ for (const table of this.publication.tables) {
85
+ dependencies.add(stableId.table(table.schema, table.name));
86
+ if (table.columns) {
87
+ for (const column of table.columns) {
88
+ dependencies.add(stableId.column(table.schema, table.name, column));
89
+ }
90
+ }
91
+ }
92
+
93
+ for (const schema of this.publication.schemas) {
94
+ dependencies.add(stableId.schema(schema));
95
+ }
96
+
97
+ return Array.from(dependencies);
98
+ }
99
+
100
+ serialize(): string {
101
+ const clauses = formatPublicationObjects(
102
+ this.publication.tables,
103
+ this.publication.schemas,
104
+ );
105
+ return `ALTER PUBLICATION ${this.publication.name} SET ${clauses.join(", ")}`;
106
+ }
107
+ }
108
+
109
+ export class AlterPublicationAddTables extends AlterPublicationChange {
110
+ public readonly publication: Publication;
111
+ public readonly scope = "object" as const;
112
+ private readonly tables: PublicationTableProps[];
113
+
114
+ constructor(props: {
115
+ publication: Publication;
116
+ tables: PublicationTableProps[];
117
+ }) {
118
+ super();
119
+ this.publication = props.publication;
120
+ this.tables = props.tables;
121
+ }
122
+
123
+ get requires() {
124
+ const dependencies = new Set<string>();
125
+
126
+ dependencies.add(this.publication.stableId);
127
+
128
+ for (const table of this.tables) {
129
+ dependencies.add(stableId.table(table.schema, table.name));
130
+ if (table.columns) {
131
+ for (const column of table.columns) {
132
+ dependencies.add(stableId.column(table.schema, table.name, column));
133
+ }
134
+ }
135
+ }
136
+ return Array.from(dependencies);
137
+ }
138
+
139
+ serialize(): string {
140
+ const clauses = this.tables.map((table) => formatPublicationTable(table));
141
+ return `ALTER PUBLICATION ${this.publication.name} ADD ${clauses.join(", ")}`;
142
+ }
143
+ }
144
+
145
+ export class AlterPublicationDropTables extends AlterPublicationChange {
146
+ public readonly publication: Publication;
147
+ public readonly scope = "object" as const;
148
+ private readonly tables: PublicationTableProps[];
149
+
150
+ constructor(props: {
151
+ publication: Publication;
152
+ tables: PublicationTableProps[];
153
+ }) {
154
+ super();
155
+ this.publication = props.publication;
156
+ this.tables = props.tables;
157
+ }
158
+
159
+ get requires() {
160
+ const dependencies = new Set<string>();
161
+
162
+ dependencies.add(this.publication.stableId);
163
+
164
+ for (const table of this.tables) {
165
+ dependencies.add(stableId.table(table.schema, table.name));
166
+ }
167
+
168
+ return Array.from(dependencies);
169
+ }
170
+
171
+ serialize(): string {
172
+ const targets = this.tables.map((table) => `${table.schema}.${table.name}`);
173
+ return `ALTER PUBLICATION ${this.publication.name} DROP TABLE ${targets.join(", ")}`;
174
+ }
175
+ }
176
+
177
+ export class AlterPublicationAddSchemas extends AlterPublicationChange {
178
+ public readonly publication: Publication;
179
+ public readonly scope = "object" as const;
180
+ private readonly schemas: string[];
181
+
182
+ constructor(props: { publication: Publication; schemas: string[] }) {
183
+ super();
184
+ this.publication = props.publication;
185
+ this.schemas = props.schemas;
186
+ }
187
+
188
+ get requires() {
189
+ return [
190
+ this.publication.stableId,
191
+ ...this.schemas.map((schema) => stableId.schema(schema)),
192
+ ];
193
+ }
194
+
195
+ serialize(): string {
196
+ const clauses = this.schemas.map((schema) => `TABLES IN SCHEMA ${schema}`);
197
+ return `ALTER PUBLICATION ${this.publication.name} ADD ${clauses.join(", ")}`;
198
+ }
199
+ }
200
+
201
+ export class AlterPublicationDropSchemas extends AlterPublicationChange {
202
+ public readonly publication: Publication;
203
+ public readonly scope = "object" as const;
204
+ private readonly schemas: string[];
205
+
206
+ constructor(props: { publication: Publication; schemas: string[] }) {
207
+ super();
208
+ this.publication = props.publication;
209
+ this.schemas = props.schemas;
210
+ }
211
+
212
+ get requires() {
213
+ return [
214
+ this.publication.stableId,
215
+ ...this.schemas.map((schema) => stableId.schema(schema)),
216
+ ];
217
+ }
218
+
219
+ serialize(): string {
220
+ const clauses = this.schemas.map((schema) => `TABLES IN SCHEMA ${schema}`);
221
+ return `ALTER PUBLICATION ${this.publication.name} DROP ${clauses.join(", ")}`;
222
+ }
223
+ }
224
+
225
+ export class AlterPublicationSetOwner extends AlterPublicationChange {
226
+ public readonly publication: Publication;
227
+ public readonly scope = "object" as const;
228
+ private readonly owner: string;
229
+
230
+ constructor(props: { publication: Publication; owner: string }) {
231
+ super();
232
+ this.publication = props.publication;
233
+ this.owner = props.owner;
234
+ }
235
+
236
+ get requires() {
237
+ return [this.publication.stableId, stableId.role(this.owner)];
238
+ }
239
+
240
+ serialize(): string {
241
+ return `ALTER PUBLICATION ${this.publication.name} OWNER TO ${this.owner}`;
242
+ }
243
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseChange } from "../../base.change.ts";
2
+ import type { Publication } from "../publication.model.ts";
3
+
4
+ abstract class BasePublicationChange extends BaseChange {
5
+ abstract readonly publication: Publication;
6
+ abstract readonly scope: "object" | "comment";
7
+ readonly objectType = "publication" as const;
8
+ }
9
+
10
+ export abstract class CreatePublicationChange extends BasePublicationChange {
11
+ readonly operation = "create" as const;
12
+ }
13
+
14
+ export abstract class AlterPublicationChange extends BasePublicationChange {
15
+ readonly operation = "alter" as const;
16
+ }
17
+
18
+ export abstract class DropPublicationChange extends BasePublicationChange {
19
+ readonly operation = "drop" as const;
20
+ }
@@ -0,0 +1,70 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { stableId } from "../../utils.ts";
3
+ import { Publication } from "../publication.model.ts";
4
+ import {
5
+ CreateCommentOnPublication,
6
+ DropCommentOnPublication,
7
+ } from "./publication.comment.ts";
8
+
9
+ type PublicationProps = ConstructorParameters<typeof Publication>[0];
10
+
11
+ const base: PublicationProps = {
12
+ name: "pub_comment",
13
+ owner: "owner1",
14
+ comment: null,
15
+ all_tables: true,
16
+ publish_insert: true,
17
+ publish_update: true,
18
+ publish_delete: true,
19
+ publish_truncate: true,
20
+ publish_via_partition_root: false,
21
+ tables: [],
22
+ schemas: [],
23
+ };
24
+
25
+ const cloneTables = (tables: PublicationProps["tables"]) =>
26
+ tables.map((table) => ({
27
+ ...table,
28
+ columns: table.columns ? [...table.columns] : null,
29
+ }));
30
+
31
+ const makePublication = (override: Partial<PublicationProps> = {}) =>
32
+ new Publication({
33
+ ...base,
34
+ ...override,
35
+ tables: override.tables
36
+ ? cloneTables(override.tables)
37
+ : cloneTables(base.tables),
38
+ schemas: override.schemas ? [...override.schemas] : [...base.schemas],
39
+ });
40
+
41
+ describe("publication.comment", () => {
42
+ test("create comment serializes and tracks dependencies", () => {
43
+ const publication = makePublication({
44
+ comment: "publication's overview",
45
+ });
46
+ const change = new CreateCommentOnPublication({ publication });
47
+
48
+ expect(change.creates).toEqual([stableId.comment(publication.stableId)]);
49
+ expect(change.requires).toEqual([publication.stableId]);
50
+ expect(change.serialize()).toBe(
51
+ "COMMENT ON PUBLICATION pub_comment IS 'publication''s overview'",
52
+ );
53
+ });
54
+
55
+ test("drop comment serializes and tracks dependencies", () => {
56
+ const publication = makePublication({
57
+ comment: "some comment",
58
+ });
59
+ const change = new DropCommentOnPublication({ publication });
60
+
61
+ expect(change.drops).toEqual([stableId.comment(publication.stableId)]);
62
+ expect(change.requires).toEqual([
63
+ stableId.comment(publication.stableId),
64
+ publication.stableId,
65
+ ]);
66
+ expect(change.serialize()).toBe(
67
+ "COMMENT ON PUBLICATION pub_comment IS NULL",
68
+ );
69
+ });
70
+ });
@@ -0,0 +1,64 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import { stableId } from "../../utils.ts";
3
+ import type { Publication } from "../publication.model.ts";
4
+ import {
5
+ CreatePublicationChange,
6
+ DropPublicationChange,
7
+ } from "./publication.base.ts";
8
+
9
+ export type CommentPublication =
10
+ | CreateCommentOnPublication
11
+ | DropCommentOnPublication;
12
+
13
+ export class CreateCommentOnPublication extends CreatePublicationChange {
14
+ public readonly publication: Publication;
15
+ public readonly scope = "comment" as const;
16
+
17
+ constructor(props: { publication: Publication }) {
18
+ super();
19
+ this.publication = props.publication;
20
+ }
21
+
22
+ get creates() {
23
+ return [stableId.comment(this.publication.stableId)];
24
+ }
25
+
26
+ get requires() {
27
+ return [this.publication.stableId];
28
+ }
29
+
30
+ serialize(): string {
31
+ return [
32
+ "COMMENT ON PUBLICATION",
33
+ this.publication.name,
34
+ "IS",
35
+ // biome-ignore lint/style/noNonNullAssertion: comment ensured non-null by caller
36
+ quoteLiteral(this.publication.comment!),
37
+ ].join(" ");
38
+ }
39
+ }
40
+
41
+ export class DropCommentOnPublication extends DropPublicationChange {
42
+ public readonly publication: Publication;
43
+ public readonly scope = "comment" as const;
44
+
45
+ constructor(props: { publication: Publication }) {
46
+ super();
47
+ this.publication = props.publication;
48
+ }
49
+
50
+ get drops() {
51
+ return [stableId.comment(this.publication.stableId)];
52
+ }
53
+
54
+ get requires() {
55
+ return [
56
+ stableId.comment(this.publication.stableId),
57
+ this.publication.stableId,
58
+ ];
59
+ }
60
+
61
+ serialize(): string {
62
+ return `COMMENT ON PUBLICATION ${this.publication.name} IS NULL`;
63
+ }
64
+ }