@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,123 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import {
3
+ MaterializedView,
4
+ type MaterializedViewProps,
5
+ } from "../materialized-view.model.ts";
6
+ import {
7
+ AlterMaterializedViewChangeOwner,
8
+ AlterMaterializedViewSetStorageParams,
9
+ } from "./materialized-view.alter.ts";
10
+
11
+ describe.concurrent("materialized-view", () => {
12
+ describe("alter", () => {
13
+ test("change owner", () => {
14
+ const props: Omit<MaterializedViewProps, "owner"> = {
15
+ schema: "public",
16
+ name: "test_mv",
17
+ definition: "SELECT * FROM test_table",
18
+ row_security: false,
19
+ force_row_security: false,
20
+ has_indexes: false,
21
+ has_rules: false,
22
+ has_triggers: false,
23
+ has_subclasses: false,
24
+ is_populated: true,
25
+ replica_identity: "d",
26
+ is_partition: false,
27
+ options: null,
28
+ partition_bound: null,
29
+ comment: null,
30
+ columns: [],
31
+ privileges: [],
32
+ };
33
+ const materializedView = new MaterializedView({
34
+ ...props,
35
+ owner: "old_owner",
36
+ });
37
+
38
+ const change = new AlterMaterializedViewChangeOwner({
39
+ materializedView,
40
+ owner: "new_owner",
41
+ });
42
+
43
+ expect(change.serialize()).toBe(
44
+ "ALTER MATERIALIZED VIEW public.test_mv OWNER TO new_owner",
45
+ );
46
+ });
47
+
48
+ test("set storage params", () => {
49
+ const props: Omit<MaterializedViewProps, "options"> = {
50
+ schema: "public",
51
+ name: "test_mv",
52
+ definition: "SELECT * FROM test_table",
53
+ row_security: false,
54
+ force_row_security: false,
55
+ has_indexes: false,
56
+ has_rules: false,
57
+ has_triggers: false,
58
+ has_subclasses: false,
59
+ is_populated: true,
60
+ replica_identity: "d",
61
+ is_partition: false,
62
+ partition_bound: null,
63
+ owner: "test",
64
+ comment: null,
65
+ columns: [],
66
+ privileges: [],
67
+ };
68
+ const materializedView = new MaterializedView({
69
+ ...props,
70
+ options: [],
71
+ });
72
+
73
+ const change = new AlterMaterializedViewSetStorageParams({
74
+ materializedView,
75
+ paramsToSet: ["fillfactor=90"],
76
+ keysToReset: [],
77
+ });
78
+
79
+ expect(change.serialize()).toBe(
80
+ "ALTER MATERIALIZED VIEW public.test_mv SET (fillfactor=90)",
81
+ );
82
+ });
83
+
84
+ test("reset and set storage params", () => {
85
+ const props: Omit<MaterializedViewProps, "options"> = {
86
+ schema: "public",
87
+ name: "test_mv",
88
+ definition: "SELECT * FROM test_table",
89
+ row_security: false,
90
+ force_row_security: false,
91
+ has_indexes: false,
92
+ has_rules: false,
93
+ has_triggers: false,
94
+ has_subclasses: false,
95
+ is_populated: true,
96
+ replica_identity: "d",
97
+ is_partition: false,
98
+ partition_bound: null,
99
+ owner: "test",
100
+ comment: null,
101
+ columns: [],
102
+ privileges: [],
103
+ };
104
+ const materializedView = new MaterializedView({
105
+ ...props,
106
+ options: ["fillfactor=70", "autovacuum_enabled=false"],
107
+ });
108
+
109
+ const change = new AlterMaterializedViewSetStorageParams({
110
+ materializedView,
111
+ paramsToSet: ["fillfactor=90", "user_catalog_table=true"],
112
+ keysToReset: ["autovacuum_enabled"],
113
+ });
114
+
115
+ expect(change.serialize()).toBe(
116
+ [
117
+ "ALTER MATERIALIZED VIEW public.test_mv RESET (autovacuum_enabled)",
118
+ "ALTER MATERIALIZED VIEW public.test_mv SET (fillfactor=90, user_catalog_table=true)",
119
+ ].join(";\n"),
120
+ );
121
+ });
122
+ });
123
+ });
@@ -0,0 +1,113 @@
1
+ import type { MaterializedView } from "../materialized-view.model.ts";
2
+ import { AlterMaterializedViewChange } from "./materialized-view.base.ts";
3
+
4
+ /**
5
+ * Alter a materialized view.
6
+ *
7
+ * @see https://www.postgresql.org/docs/17/sql-altermaterializedview.html
8
+ *
9
+ * Synopsis
10
+ * ```sql
11
+ * ALTER MATERIALIZED VIEW [ IF EXISTS ] name
12
+ * action [, ... ]
13
+ * where action is one of:
14
+ * ALTER [ COLUMN ] column_name SET STATISTICS integer
15
+ * ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] )
16
+ * ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] )
17
+ * ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
18
+ * CLUSTER ON index_name
19
+ * SET WITHOUT CLUSTER
20
+ * SET ( storage_parameter [= value] [, ... ] )
21
+ * RESET ( storage_parameter [, ... ] )
22
+ * OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
23
+ * RENAME TO new_name
24
+ * SET SCHEMA new_schema
25
+ * ```
26
+ *
27
+ * Notes for diff-based generation:
28
+ * - We currently only emit OWNER TO when owner differs.
29
+ * - Name/schema changes are treated as identity changes; handled as drop/create by the diff engine.
30
+ * - Column attribute changes, CLUSTER are not modeled and thus not emitted.
31
+ * - Changes to definition, options, and other non-alterable properties trigger a replace (drop + create).
32
+ */
33
+
34
+ export type AlterMaterializedView =
35
+ | AlterMaterializedViewChangeOwner
36
+ | AlterMaterializedViewSetStorageParams;
37
+
38
+ /**
39
+ * ALTER MATERIALIZED VIEW ... OWNER TO ...
40
+ */
41
+ export class AlterMaterializedViewChangeOwner extends AlterMaterializedViewChange {
42
+ public readonly materializedView: MaterializedView;
43
+ public readonly owner: string;
44
+ public readonly scope = "object" as const;
45
+
46
+ constructor(props: { materializedView: MaterializedView; owner: string }) {
47
+ super();
48
+ this.materializedView = props.materializedView;
49
+ this.owner = props.owner;
50
+ }
51
+
52
+ get requires() {
53
+ return [this.materializedView.stableId];
54
+ }
55
+
56
+ serialize(): string {
57
+ return [
58
+ "ALTER MATERIALIZED VIEW",
59
+ `${this.materializedView.schema}.${this.materializedView.name}`,
60
+ "OWNER TO",
61
+ this.owner,
62
+ ].join(" ");
63
+ }
64
+ }
65
+
66
+ /**
67
+ * ALTER MATERIALIZED VIEW ... SET/RESET ( storage_parameter ... )
68
+ * Accepts main and branch, computes differences, and emits RESET then SET statements.
69
+ */
70
+ export class AlterMaterializedViewSetStorageParams extends AlterMaterializedViewChange {
71
+ public readonly materializedView: MaterializedView;
72
+ public readonly paramsToSet: string[];
73
+ public readonly keysToReset: string[];
74
+ public readonly scope = "object" as const;
75
+
76
+ constructor(props: {
77
+ materializedView: MaterializedView;
78
+ paramsToSet: string[];
79
+ keysToReset: string[];
80
+ }) {
81
+ super();
82
+ this.materializedView = props.materializedView;
83
+ this.paramsToSet = props.paramsToSet;
84
+ this.keysToReset = props.keysToReset;
85
+ }
86
+
87
+ get requires() {
88
+ return [this.materializedView.stableId];
89
+ }
90
+
91
+ serialize(): string {
92
+ const head = [
93
+ "ALTER MATERIALIZED VIEW",
94
+ `${this.materializedView.schema}.${this.materializedView.name}`,
95
+ ].join(" ");
96
+
97
+ const statements: string[] = [];
98
+ if (this.keysToReset.length > 0) {
99
+ statements.push(`${head} RESET (${this.keysToReset.join(", ")})`);
100
+ }
101
+ if (this.paramsToSet.length > 0) {
102
+ statements.push(`${head} SET (${this.paramsToSet.join(", ")})`);
103
+ }
104
+
105
+ return statements.join(";\n");
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Replace a materialized view by dropping and recreating it.
111
+ * This is used when properties that cannot be altered via ALTER MATERIALIZED VIEW change.
112
+ */
113
+ // NOTE: ReplaceMaterializedView removed. Non-alterable changes are emitted as Drop + Create in materialized-view.diff.ts.
@@ -0,0 +1,20 @@
1
+ import { BaseChange } from "../../base.change.ts";
2
+ import type { MaterializedView } from "../materialized-view.model.ts";
3
+
4
+ abstract class BaseMaterializedViewChange extends BaseChange {
5
+ abstract readonly materializedView: MaterializedView;
6
+ abstract readonly scope: "object" | "comment" | "privilege";
7
+ readonly objectType: "materialized_view" = "materialized_view";
8
+ }
9
+
10
+ export abstract class CreateMaterializedViewChange extends BaseMaterializedViewChange {
11
+ readonly operation = "create" as const;
12
+ }
13
+
14
+ export abstract class AlterMaterializedViewChange extends BaseMaterializedViewChange {
15
+ readonly operation = "alter" as const;
16
+ }
17
+
18
+ export abstract class DropMaterializedViewChange extends BaseMaterializedViewChange {
19
+ readonly operation = "drop" as const;
20
+ }
@@ -0,0 +1,176 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { ColumnProps } from "../../base.model.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { MaterializedView } from "../materialized-view.model.ts";
5
+ import {
6
+ CreateMaterializedViewChange,
7
+ DropMaterializedViewChange,
8
+ } from "./materialized-view.base.ts";
9
+
10
+ export type CommentMaterializedView =
11
+ | CreateCommentOnMaterializedView
12
+ | CreateCommentOnMaterializedViewColumn
13
+ | DropCommentOnMaterializedView
14
+ | DropCommentOnMaterializedViewColumn;
15
+
16
+ /**
17
+ * Create/drop comments on materialized view columns.
18
+ *
19
+ * @see https://www.postgresql.org/docs/17/sql-comment.html
20
+ */
21
+
22
+ export class CreateCommentOnMaterializedView extends CreateMaterializedViewChange {
23
+ public readonly materializedView: MaterializedView;
24
+ public readonly scope = "comment" as const;
25
+
26
+ constructor(props: { materializedView: MaterializedView }) {
27
+ super();
28
+ this.materializedView = props.materializedView;
29
+ }
30
+
31
+ get creates() {
32
+ return [stableId.comment(this.materializedView.stableId)];
33
+ }
34
+
35
+ get requires() {
36
+ return [this.materializedView.stableId];
37
+ }
38
+
39
+ serialize(): string {
40
+ return [
41
+ "COMMENT ON MATERIALIZED VIEW",
42
+ `${this.materializedView.schema}.${this.materializedView.name}`,
43
+ "IS",
44
+ // biome-ignore lint/style/noNonNullAssertion: mv comment is not nullable in this case
45
+ quoteLiteral(this.materializedView.comment!),
46
+ ].join(" ");
47
+ }
48
+ }
49
+
50
+ export class DropCommentOnMaterializedView extends DropMaterializedViewChange {
51
+ public readonly materializedView: MaterializedView;
52
+ public readonly scope = "comment" as const;
53
+
54
+ constructor(props: { materializedView: MaterializedView }) {
55
+ super();
56
+ this.materializedView = props.materializedView;
57
+ }
58
+
59
+ get drops() {
60
+ return [stableId.comment(this.materializedView.stableId)];
61
+ }
62
+
63
+ get requires() {
64
+ return [
65
+ stableId.comment(this.materializedView.stableId),
66
+ this.materializedView.stableId,
67
+ ];
68
+ }
69
+
70
+ serialize(): string {
71
+ return [
72
+ "COMMENT ON MATERIALIZED VIEW",
73
+ `${this.materializedView.schema}.${this.materializedView.name}`,
74
+ "IS NULL",
75
+ ].join(" ");
76
+ }
77
+ }
78
+
79
+ export class CreateCommentOnMaterializedViewColumn extends CreateMaterializedViewChange {
80
+ public readonly materializedView: MaterializedView;
81
+ public readonly column: ColumnProps;
82
+ public readonly scope = "comment" as const;
83
+
84
+ constructor(props: {
85
+ materializedView: MaterializedView;
86
+ column: ColumnProps;
87
+ }) {
88
+ super();
89
+ this.materializedView = props.materializedView;
90
+ this.column = props.column;
91
+ }
92
+
93
+ get creates() {
94
+ return [
95
+ stableId.comment(
96
+ stableId.column(
97
+ this.materializedView.schema,
98
+ this.materializedView.name,
99
+ this.column.name,
100
+ ),
101
+ ),
102
+ ];
103
+ }
104
+
105
+ get requires() {
106
+ return [
107
+ stableId.column(
108
+ this.materializedView.schema,
109
+ this.materializedView.name,
110
+ this.column.name,
111
+ ),
112
+ ];
113
+ }
114
+
115
+ serialize(): string {
116
+ return [
117
+ "COMMENT ON COLUMN",
118
+ `${this.materializedView.schema}.${this.materializedView.name}.${this.column.name}`,
119
+ "IS",
120
+ // biome-ignore lint/style/noNonNullAssertion: column comment is not nullable in this case
121
+ quoteLiteral(this.column.comment!),
122
+ ].join(" ");
123
+ }
124
+ }
125
+
126
+ export class DropCommentOnMaterializedViewColumn extends DropMaterializedViewChange {
127
+ public readonly materializedView: MaterializedView;
128
+ public readonly column: ColumnProps;
129
+ public readonly scope = "comment" as const;
130
+
131
+ constructor(props: {
132
+ materializedView: MaterializedView;
133
+ column: ColumnProps;
134
+ }) {
135
+ super();
136
+ this.materializedView = props.materializedView;
137
+ this.column = props.column;
138
+ }
139
+
140
+ get drops() {
141
+ return [
142
+ stableId.comment(
143
+ stableId.column(
144
+ this.materializedView.schema,
145
+ this.materializedView.name,
146
+ this.column.name,
147
+ ),
148
+ ),
149
+ ];
150
+ }
151
+
152
+ get requires() {
153
+ return [
154
+ stableId.comment(
155
+ stableId.column(
156
+ this.materializedView.schema,
157
+ this.materializedView.name,
158
+ this.column.name,
159
+ ),
160
+ ),
161
+ stableId.column(
162
+ this.materializedView.schema,
163
+ this.materializedView.name,
164
+ this.column.name,
165
+ ),
166
+ ];
167
+ }
168
+
169
+ serialize(): string {
170
+ return [
171
+ "COMMENT ON COLUMN",
172
+ `${this.materializedView.schema}.${this.materializedView.name}.${this.column.name}`,
173
+ "IS NULL",
174
+ ].join(" ");
175
+ }
176
+ }
@@ -0,0 +1,64 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { MaterializedView } from "../materialized-view.model.ts";
3
+ import { CreateMaterializedView } from "./materialized-view.create.ts";
4
+
5
+ describe("materialized-view", () => {
6
+ test("create minimal", () => {
7
+ const mv = new MaterializedView({
8
+ schema: "public",
9
+ name: "test_mv",
10
+ definition: "SELECT * FROM test_table",
11
+ row_security: false,
12
+ force_row_security: false,
13
+ has_indexes: false,
14
+ has_rules: false,
15
+ has_triggers: false,
16
+ has_subclasses: false,
17
+ // Default is WITH NO DATA -> omitted
18
+ is_populated: false,
19
+ replica_identity: "d",
20
+ is_partition: false,
21
+ options: null,
22
+ partition_bound: null,
23
+ owner: "test",
24
+ columns: [],
25
+ comment: null,
26
+ privileges: [],
27
+ });
28
+
29
+ const change = new CreateMaterializedView({ materializedView: mv });
30
+
31
+ expect(change.serialize()).toBe(
32
+ "CREATE MATERIALIZED VIEW public.test_mv AS SELECT * FROM test_table WITH NO DATA",
33
+ );
34
+ });
35
+
36
+ test("create with all options", () => {
37
+ const mv = new MaterializedView({
38
+ schema: "public",
39
+ name: "test_mv",
40
+ definition: "SELECT * FROM test_table",
41
+ row_security: false,
42
+ force_row_security: false,
43
+ has_indexes: false,
44
+ has_rules: false,
45
+ has_triggers: false,
46
+ has_subclasses: false,
47
+ is_populated: true,
48
+ replica_identity: "d",
49
+ is_partition: false,
50
+ options: ["fillfactor=90", "autovacuum_enabled=false"],
51
+ partition_bound: null,
52
+ owner: "test",
53
+ columns: [],
54
+ comment: null,
55
+ privileges: [],
56
+ });
57
+
58
+ const change = new CreateMaterializedView({ materializedView: mv });
59
+
60
+ expect(change.serialize()).toBe(
61
+ "CREATE MATERIALIZED VIEW public.test_mv WITH (fillfactor=90, autovacuum_enabled=false) AS SELECT * FROM test_table WITH DATA",
62
+ );
63
+ });
64
+ });
@@ -0,0 +1,93 @@
1
+ import { stableId } from "../../utils.ts";
2
+ import type { MaterializedView } from "../materialized-view.model.ts";
3
+ import { CreateMaterializedViewChange } from "./materialized-view.base.ts";
4
+
5
+ /**
6
+ * Create a materialized view.
7
+ *
8
+ * @see https://www.postgresql.org/docs/17/sql-creatematerializedview.html
9
+ *
10
+ * Synopsis
11
+ * ```sql
12
+ * CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name
13
+ * [ (column_name [, ...] ) ]
14
+ * [ WITH ( storage_parameter [= value] [, ... ] ) ]
15
+ * [ TABLESPACE tablespace_name ]
16
+ * AS query
17
+ * [ WITH [ NO ] DATA ]
18
+ * ```
19
+ *
20
+ * Notes for diff-based generation:
21
+ * - IF NOT EXISTS is omitted: diffs are deterministic and explicit.
22
+ * - (column_name, ...) list is derived from the SELECT query; we don't emit it.
23
+ * - TABLESPACE is not currently modeled/extracted and is not emitted.
24
+ * - WITH (options) is emitted only when non-empty.
25
+ * - WITH NO DATA is always emitted when is_populated is false to ensure correct state.
26
+ * - WITH DATA is emitted when is_populated is true.
27
+ */
28
+ export class CreateMaterializedView extends CreateMaterializedViewChange {
29
+ public readonly materializedView: MaterializedView;
30
+ public readonly scope = "object" as const;
31
+
32
+ constructor(props: { materializedView: MaterializedView }) {
33
+ super();
34
+ this.materializedView = props.materializedView;
35
+ }
36
+
37
+ get creates() {
38
+ return [
39
+ this.materializedView.stableId,
40
+ ...this.materializedView.columns.map((column) =>
41
+ stableId.column(
42
+ this.materializedView.schema,
43
+ this.materializedView.name,
44
+ column.name,
45
+ ),
46
+ ),
47
+ ];
48
+ }
49
+
50
+ get requires() {
51
+ const dependencies = new Set<string>();
52
+
53
+ // Schema dependency
54
+ dependencies.add(stableId.schema(this.materializedView.schema));
55
+
56
+ // Owner dependency
57
+ dependencies.add(stableId.role(this.materializedView.owner));
58
+
59
+ // Note: Materialized view definition dependencies are handled via pg_depend
60
+ // for existing objects. For new objects, parsing the SQL definition would be complex.
61
+
62
+ return Array.from(dependencies);
63
+ }
64
+
65
+ serialize(): string {
66
+ const parts: string[] = ["CREATE MATERIALIZED VIEW"];
67
+
68
+ // Add schema and name
69
+ parts.push(`${this.materializedView.schema}.${this.materializedView.name}`);
70
+
71
+ // Add storage parameters if specified
72
+ if (
73
+ this.materializedView.options &&
74
+ this.materializedView.options.length > 0
75
+ ) {
76
+ parts.push("WITH", `(${this.materializedView.options.join(", ")})`);
77
+ }
78
+
79
+ // Add AS query (definition is required)
80
+ parts.push("AS", this.materializedView.definition.trim());
81
+
82
+ // Add population clause to match the desired state
83
+ // PostgreSQL defaults to WITH NO DATA, but we need to be explicit to ensure
84
+ // the created view matches the expected is_populated state
85
+ if (this.materializedView.is_populated) {
86
+ parts.push("WITH DATA");
87
+ } else {
88
+ parts.push("WITH NO DATA");
89
+ }
90
+
91
+ return parts.join(" ");
92
+ }
93
+ }
@@ -0,0 +1,34 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { MaterializedView } from "../materialized-view.model.ts";
3
+ import { DropMaterializedView } from "./materialized-view.drop.ts";
4
+
5
+ describe("materialized-view", () => {
6
+ test("drop", () => {
7
+ const materializedView = new MaterializedView({
8
+ schema: "public",
9
+ name: "test_mv",
10
+ definition: "SELECT * FROM test_table",
11
+ row_security: false,
12
+ force_row_security: false,
13
+ has_indexes: false,
14
+ has_rules: false,
15
+ has_triggers: false,
16
+ has_subclasses: false,
17
+ is_populated: true,
18
+ replica_identity: "d",
19
+ is_partition: false,
20
+ options: null,
21
+ partition_bound: null,
22
+ owner: "test",
23
+ comment: null,
24
+ columns: [],
25
+ privileges: [],
26
+ });
27
+
28
+ const change = new DropMaterializedView({
29
+ materializedView,
30
+ });
31
+
32
+ expect(change.serialize()).toBe("DROP MATERIALIZED VIEW public.test_mv");
33
+ });
34
+ });
@@ -0,0 +1,60 @@
1
+ import { stableId } from "../../utils.ts";
2
+ import type { MaterializedView } from "../materialized-view.model.ts";
3
+ import { DropMaterializedViewChange } from "./materialized-view.base.ts";
4
+
5
+ /**
6
+ * Drop a materialized view.
7
+ *
8
+ * @see https://www.postgresql.org/docs/17/sql-dropmaterializedview.html
9
+ *
10
+ * Synopsis
11
+ * ```sql
12
+ * DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
13
+ * ```
14
+ *
15
+ * Notes for diff-based generation:
16
+ * - IF EXISTS is omitted for deterministic diffs; the object must exist in the source.
17
+ * - We do not emit CASCADE; dependency ordering ensures safe drops, and RESTRICT is default.
18
+ */
19
+ export class DropMaterializedView extends DropMaterializedViewChange {
20
+ public readonly materializedView: MaterializedView;
21
+ public readonly scope = "object" as const;
22
+
23
+ constructor(props: { materializedView: MaterializedView }) {
24
+ super();
25
+ this.materializedView = props.materializedView;
26
+ }
27
+
28
+ get drops() {
29
+ return [
30
+ this.materializedView.stableId,
31
+ ...this.materializedView.columns.map((column) =>
32
+ stableId.column(
33
+ this.materializedView.schema,
34
+ this.materializedView.name,
35
+ column.name,
36
+ ),
37
+ ),
38
+ ];
39
+ }
40
+
41
+ get requires() {
42
+ return [
43
+ this.materializedView.stableId,
44
+ ...this.materializedView.columns.map((column) =>
45
+ stableId.column(
46
+ this.materializedView.schema,
47
+ this.materializedView.name,
48
+ column.name,
49
+ ),
50
+ ),
51
+ ];
52
+ }
53
+
54
+ serialize(): string {
55
+ return [
56
+ "DROP MATERIALIZED VIEW",
57
+ `${this.materializedView.schema}.${this.materializedView.name}`,
58
+ ].join(" ");
59
+ }
60
+ }