@intentius/sql-yodeler 0.0.0-stage → 0.2.0

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 (324) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +112 -2
  3. package/dist/bin.d.ts +2 -0
  4. package/dist/bin.js +29 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/chant/apply.d.ts +59 -0
  7. package/dist/chant/apply.js +116 -0
  8. package/dist/chant/apply.js.map +1 -0
  9. package/dist/chant/build.d.ts +34 -0
  10. package/dist/chant/build.js +48 -0
  11. package/dist/chant/build.js.map +1 -0
  12. package/dist/chant/drift.d.ts +112 -0
  13. package/dist/chant/drift.js +238 -0
  14. package/dist/chant/drift.js.map +1 -0
  15. package/dist/chant/plan.d.ts +45 -0
  16. package/dist/chant/plan.js +61 -0
  17. package/dist/chant/plan.js.map +1 -0
  18. package/dist/chant/process.d.ts +41 -0
  19. package/dist/chant/process.js +87 -0
  20. package/dist/chant/process.js.map +1 -0
  21. package/dist/chant/runnable.d.ts +19 -0
  22. package/dist/chant/runnable.js +47 -0
  23. package/dist/chant/runnable.js.map +1 -0
  24. package/dist/cli.d.ts +8 -0
  25. package/dist/cli.js +99 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/command.d.ts +23 -0
  28. package/dist/command.js +13 -0
  29. package/dist/command.js.map +1 -0
  30. package/dist/commands/apply.d.ts +3 -0
  31. package/dist/commands/apply.js +426 -0
  32. package/dist/commands/apply.js.map +1 -0
  33. package/dist/commands/approve.d.ts +5 -0
  34. package/dist/commands/approve.js +111 -0
  35. package/dist/commands/approve.js.map +1 -0
  36. package/dist/commands/drift.d.ts +14 -0
  37. package/dist/commands/drift.js +267 -0
  38. package/dist/commands/drift.js.map +1 -0
  39. package/dist/commands/index.d.ts +3 -0
  40. package/dist/commands/index.js +28 -0
  41. package/dist/commands/index.js.map +1 -0
  42. package/dist/commands/init.d.ts +6 -0
  43. package/dist/commands/init.js +139 -0
  44. package/dist/commands/init.js.map +1 -0
  45. package/dist/commands/lint.d.ts +3 -0
  46. package/dist/commands/lint.js +202 -0
  47. package/dist/commands/lint.js.map +1 -0
  48. package/dist/commands/mcp.d.ts +3 -0
  49. package/dist/commands/mcp.js +50 -0
  50. package/dist/commands/mcp.js.map +1 -0
  51. package/dist/commands/new.d.ts +5 -0
  52. package/dist/commands/new.js +292 -0
  53. package/dist/commands/new.js.map +1 -0
  54. package/dist/commands/override.d.ts +3 -0
  55. package/dist/commands/override.js +118 -0
  56. package/dist/commands/override.js.map +1 -0
  57. package/dist/commands/plan.d.ts +3 -0
  58. package/dist/commands/plan.js +183 -0
  59. package/dist/commands/plan.js.map +1 -0
  60. package/dist/commands/rebase.d.ts +3 -0
  61. package/dist/commands/rebase.js +167 -0
  62. package/dist/commands/rebase.js.map +1 -0
  63. package/dist/commands/repair.d.ts +14 -0
  64. package/dist/commands/repair.js +125 -0
  65. package/dist/commands/repair.js.map +1 -0
  66. package/dist/commands/status.d.ts +7 -0
  67. package/dist/commands/status.js +54 -0
  68. package/dist/commands/status.js.map +1 -0
  69. package/dist/config/define.d.ts +148 -0
  70. package/dist/config/define.js +20 -0
  71. package/dist/config/define.js.map +1 -0
  72. package/dist/config/index.d.ts +11 -0
  73. package/dist/config/index.js +12 -0
  74. package/dist/config/index.js.map +1 -0
  75. package/dist/config/load.d.ts +17 -0
  76. package/dist/config/load.js +162 -0
  77. package/dist/config/load.js.map +1 -0
  78. package/dist/config/settings.d.ts +53 -0
  79. package/dist/config/settings.js +116 -0
  80. package/dist/config/settings.js.map +1 -0
  81. package/dist/env-args.d.ts +24 -0
  82. package/dist/env-args.js +92 -0
  83. package/dist/env-args.js.map +1 -0
  84. package/dist/exit.d.ts +20 -0
  85. package/dist/exit.js +28 -0
  86. package/dist/exit.js.map +1 -0
  87. package/dist/history/client.d.ts +25 -0
  88. package/dist/history/client.js +42 -0
  89. package/dist/history/client.js.map +1 -0
  90. package/dist/history/ddl.d.ts +58 -0
  91. package/dist/history/ddl.js +100 -0
  92. package/dist/history/ddl.js.map +1 -0
  93. package/dist/history/index.d.ts +25 -0
  94. package/dist/history/index.js +26 -0
  95. package/dist/history/index.js.map +1 -0
  96. package/dist/history/lock.d.ts +104 -0
  97. package/dist/history/lock.js +230 -0
  98. package/dist/history/lock.js.map +1 -0
  99. package/dist/history/postgres/ddl.d.ts +22 -0
  100. package/dist/history/postgres/ddl.js +47 -0
  101. package/dist/history/postgres/ddl.js.map +1 -0
  102. package/dist/history/postgres/index.d.ts +12 -0
  103. package/dist/history/postgres/index.js +13 -0
  104. package/dist/history/postgres/index.js.map +1 -0
  105. package/dist/history/postgres/lock.d.ts +48 -0
  106. package/dist/history/postgres/lock.js +95 -0
  107. package/dist/history/postgres/lock.js.map +1 -0
  108. package/dist/history/postgres/store.d.ts +39 -0
  109. package/dist/history/postgres/store.js +68 -0
  110. package/dist/history/postgres/store.js.map +1 -0
  111. package/dist/history/rows.d.ts +96 -0
  112. package/dist/history/rows.js +73 -0
  113. package/dist/history/rows.js.map +1 -0
  114. package/dist/history/store.d.ts +72 -0
  115. package/dist/history/store.js +134 -0
  116. package/dist/history/store.js.map +1 -0
  117. package/dist/history/topology.d.ts +41 -0
  118. package/dist/history/topology.js +54 -0
  119. package/dist/history/topology.js.map +1 -0
  120. package/dist/index.d.ts +10 -0
  121. package/dist/index.js +10 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/init/adopt.d.ts +70 -0
  124. package/dist/init/adopt.js +143 -0
  125. package/dist/init/adopt.js.map +1 -0
  126. package/dist/init/baseline.d.ts +61 -0
  127. package/dist/init/baseline.js +88 -0
  128. package/dist/init/baseline.js.map +1 -0
  129. package/dist/init/files.d.ts +23 -0
  130. package/dist/init/files.js +77 -0
  131. package/dist/init/files.js.map +1 -0
  132. package/dist/init/index.d.ts +16 -0
  133. package/dist/init/index.js +17 -0
  134. package/dist/init/index.js.map +1 -0
  135. package/dist/init/live.d.ts +39 -0
  136. package/dist/init/live.js +68 -0
  137. package/dist/init/live.js.map +1 -0
  138. package/dist/lint/check.d.ts +88 -0
  139. package/dist/lint/check.js +227 -0
  140. package/dist/lint/check.js.map +1 -0
  141. package/dist/lint/config.d.ts +21 -0
  142. package/dist/lint/config.js +43 -0
  143. package/dist/lint/config.js.map +1 -0
  144. package/dist/lint/index.d.ts +31 -0
  145. package/dist/lint/index.js +43 -0
  146. package/dist/lint/index.js.map +1 -0
  147. package/dist/lint/project-rules.d.ts +19 -0
  148. package/dist/lint/project-rules.js +32 -0
  149. package/dist/lint/project-rules.js.map +1 -0
  150. package/dist/lint/report.d.ts +7 -0
  151. package/dist/lint/report.js +48 -0
  152. package/dist/lint/report.js.map +1 -0
  153. package/dist/lint/rules.d.ts +53 -0
  154. package/dist/lint/rules.js +42 -0
  155. package/dist/lint/rules.js.map +1 -0
  156. package/dist/lint/silences.d.ts +49 -0
  157. package/dist/lint/silences.js +91 -0
  158. package/dist/lint/silences.js.map +1 -0
  159. package/dist/lint/statements.d.ts +38 -0
  160. package/dist/lint/statements.js +120 -0
  161. package/dist/lint/statements.js.map +1 -0
  162. package/dist/mcp/server.d.ts +40 -0
  163. package/dist/mcp/server.js +106 -0
  164. package/dist/mcp/server.js.map +1 -0
  165. package/dist/mcp/tools.d.ts +72 -0
  166. package/dist/mcp/tools.js +178 -0
  167. package/dist/mcp/tools.js.map +1 -0
  168. package/dist/migrations/checks.d.ts +28 -0
  169. package/dist/migrations/checks.js +97 -0
  170. package/dist/migrations/checks.js.map +1 -0
  171. package/dist/migrations/checksum.d.ts +56 -0
  172. package/dist/migrations/checksum.js +72 -0
  173. package/dist/migrations/checksum.js.map +1 -0
  174. package/dist/migrations/create.d.ts +75 -0
  175. package/dist/migrations/create.js +120 -0
  176. package/dist/migrations/create.js.map +1 -0
  177. package/dist/migrations/directory.d.ts +119 -0
  178. package/dist/migrations/directory.js +229 -0
  179. package/dist/migrations/directory.js.map +1 -0
  180. package/dist/migrations/document.d.ts +106 -0
  181. package/dist/migrations/document.js +83 -0
  182. package/dist/migrations/document.js.map +1 -0
  183. package/dist/migrations/index.d.ts +21 -0
  184. package/dist/migrations/index.js +22 -0
  185. package/dist/migrations/index.js.map +1 -0
  186. package/dist/pr/comment.d.ts +32 -0
  187. package/dist/pr/comment.js +99 -0
  188. package/dist/pr/comment.js.map +1 -0
  189. package/dist/pr/forge.d.ts +54 -0
  190. package/dist/pr/forge.js +119 -0
  191. package/dist/pr/forge.js.map +1 -0
  192. package/dist/pr/issue.d.ts +68 -0
  193. package/dist/pr/issue.js +107 -0
  194. package/dist/pr/issue.js.map +1 -0
  195. package/dist/pr/model.d.ts +99 -0
  196. package/dist/pr/model.js +137 -0
  197. package/dist/pr/model.js.map +1 -0
  198. package/dist/pr/render.d.ts +29 -0
  199. package/dist/pr/render.js +279 -0
  200. package/dist/pr/render.js.map +1 -0
  201. package/dist/project.d.ts +62 -0
  202. package/dist/project.js +92 -0
  203. package/dist/project.js.map +1 -0
  204. package/dist/rebase/index.d.ts +121 -0
  205. package/dist/rebase/index.js +390 -0
  206. package/dist/rebase/index.js.map +1 -0
  207. package/dist/rebase/repair.d.ts +41 -0
  208. package/dist/rebase/repair.js +68 -0
  209. package/dist/rebase/repair.js.map +1 -0
  210. package/dist/replay/clickhouse.d.ts +33 -0
  211. package/dist/replay/clickhouse.js +106 -0
  212. package/dist/replay/clickhouse.js.map +1 -0
  213. package/dist/replay/index.d.ts +39 -0
  214. package/dist/replay/index.js +57 -0
  215. package/dist/replay/index.js.map +1 -0
  216. package/dist/replay/postgres.d.ts +31 -0
  217. package/dist/replay/postgres.js +140 -0
  218. package/dist/replay/postgres.js.map +1 -0
  219. package/dist/replay/replay.d.ts +114 -0
  220. package/dist/replay/replay.js +98 -0
  221. package/dist/replay/replay.js.map +1 -0
  222. package/dist/replay/report.d.ts +18 -0
  223. package/dist/replay/report.js +72 -0
  224. package/dist/replay/report.js.map +1 -0
  225. package/dist/replay/shared.d.ts +28 -0
  226. package/dist/replay/shared.js +77 -0
  227. package/dist/replay/shared.js.map +1 -0
  228. package/dist/schemas.d.ts +34 -0
  229. package/dist/schemas.js +38 -0
  230. package/dist/schemas.js.map +1 -0
  231. package/dist/server.d.ts +40 -0
  232. package/dist/server.js +87 -0
  233. package/dist/server.js.map +1 -0
  234. package/dist/steps/backfill.d.ts +132 -0
  235. package/dist/steps/backfill.js +307 -0
  236. package/dist/steps/backfill.js.map +1 -0
  237. package/dist/steps/index.d.ts +52 -0
  238. package/dist/steps/index.js +52 -0
  239. package/dist/steps/index.js.map +1 -0
  240. package/dist/steps/kinds.d.ts +101 -0
  241. package/dist/steps/kinds.js +143 -0
  242. package/dist/steps/kinds.js.map +1 -0
  243. package/dist/steps/postgres-migration.d.ts +95 -0
  244. package/dist/steps/postgres-migration.js +149 -0
  245. package/dist/steps/postgres-migration.js.map +1 -0
  246. package/dist/steps/rebuild.d.ts +97 -0
  247. package/dist/steps/rebuild.js +155 -0
  248. package/dist/steps/rebuild.js.map +1 -0
  249. package/dist/steps/run.d.ts +45 -0
  250. package/dist/steps/run.js +72 -0
  251. package/dist/steps/run.js.map +1 -0
  252. package/dist/topology/render.d.ts +17 -0
  253. package/dist/topology/render.js +17 -0
  254. package/dist/topology/render.js.map +1 -0
  255. package/dist/version.d.ts +2 -0
  256. package/dist/version.js +11 -0
  257. package/dist/version.js.map +1 -0
  258. package/dist/versioned/approval.d.ts +35 -0
  259. package/dist/versioned/approval.js +53 -0
  260. package/dist/versioned/approval.js.map +1 -0
  261. package/dist/versioned/checks.d.ts +29 -0
  262. package/dist/versioned/checks.js +54 -0
  263. package/dist/versioned/checks.js.map +1 -0
  264. package/dist/versioned/clickhouse.d.ts +24 -0
  265. package/dist/versioned/clickhouse.js +42 -0
  266. package/dist/versioned/clickhouse.js.map +1 -0
  267. package/dist/versioned/digest.d.ts +77 -0
  268. package/dist/versioned/digest.js +69 -0
  269. package/dist/versioned/digest.js.map +1 -0
  270. package/dist/versioned/driver.d.ts +51 -0
  271. package/dist/versioned/driver.js +13 -0
  272. package/dist/versioned/driver.js.map +1 -0
  273. package/dist/versioned/engine.d.ts +206 -0
  274. package/dist/versioned/engine.js +370 -0
  275. package/dist/versioned/engine.js.map +1 -0
  276. package/dist/versioned/explain.d.ts +123 -0
  277. package/dist/versioned/explain.js +294 -0
  278. package/dist/versioned/explain.js.map +1 -0
  279. package/dist/versioned/index.d.ts +46 -0
  280. package/dist/versioned/index.js +77 -0
  281. package/dist/versioned/index.js.map +1 -0
  282. package/dist/versioned/op.d.ts +72 -0
  283. package/dist/versioned/op.js +185 -0
  284. package/dist/versioned/op.js.map +1 -0
  285. package/dist/versioned/policy.d.ts +67 -0
  286. package/dist/versioned/policy.js +161 -0
  287. package/dist/versioned/policy.js.map +1 -0
  288. package/dist/versioned/postgres/catalog.d.ts +33 -0
  289. package/dist/versioned/postgres/catalog.js +34 -0
  290. package/dist/versioned/postgres/catalog.js.map +1 -0
  291. package/dist/versioned/postgres/driver.d.ts +71 -0
  292. package/dist/versioned/postgres/driver.js +140 -0
  293. package/dist/versioned/postgres/driver.js.map +1 -0
  294. package/dist/versioned/postgres/executor.d.ts +104 -0
  295. package/dist/versioned/postgres/executor.js +172 -0
  296. package/dist/versioned/postgres/executor.js.map +1 -0
  297. package/dist/versioned/postgres/index.d.ts +11 -0
  298. package/dist/versioned/postgres/index.js +12 -0
  299. package/dist/versioned/postgres/index.js.map +1 -0
  300. package/dist/versioned/postgres/waits.d.ts +46 -0
  301. package/dist/versioned/postgres/waits.js +78 -0
  302. package/dist/versioned/postgres/waits.js.map +1 -0
  303. package/dist/versioned/report.d.ts +25 -0
  304. package/dist/versioned/report.js +84 -0
  305. package/dist/versioned/report.js.map +1 -0
  306. package/dist/versioned/stand-down.d.ts +30 -0
  307. package/dist/versioned/stand-down.js +56 -0
  308. package/dist/versioned/stand-down.js.map +1 -0
  309. package/dist/versioned/state.d.ts +108 -0
  310. package/dist/versioned/state.js +153 -0
  311. package/dist/versioned/state.js.map +1 -0
  312. package/package.json +61 -4
  313. package/schemas/apply.schema.json +269 -0
  314. package/schemas/common.schema.json +213 -0
  315. package/schemas/drift.schema.json +36 -0
  316. package/schemas/init.schema.json +31 -0
  317. package/schemas/lint-rules.schema.json +54 -0
  318. package/schemas/lint.schema.json +290 -0
  319. package/schemas/mcp.schema.json +70 -0
  320. package/schemas/new.schema.json +71 -0
  321. package/schemas/plan.schema.json +371 -0
  322. package/schemas/rebase.schema.json +54 -0
  323. package/schemas/repair.schema.json +20 -0
  324. package/schemas/status.schema.json +310 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * What each step of a migration is to `yodel apply`, and the hash its
3
+ * history rows record.
4
+ *
5
+ * A migration's `steps` (in `migration.json`) are chant's: a `statement`
6
+ * apply sends as SQL, an `op` step naming the Op that makes a change no
7
+ * statement makes, or a `manual` step a person acts on. Apply runs two kinds
8
+ * of Op step itself, inside the migration and under its lock and gate:
9
+ *
10
+ * - `ClickHouseRebuildOp`, the step `yodel new` writes for a ClickHouse sort
11
+ * key, engine or key-column change (`./rebuild.ts`);
12
+ * - `backfill`, a data backfill the author writes as an Op of `effect()`
13
+ * steps in a module in the migration's directory (`./backfill.ts`);
14
+ * - `PostgresMigrationOp`, the step `yodel new` writes for a Postgres column
15
+ * rename or type change across kinds (`./postgres-migration.ts`, #13).
16
+ *
17
+ * Everything else (a manual step, a rebuild in app mode) is refused before
18
+ * anything runs, with exit 2.
19
+ */
20
+ import { createHash } from "node:crypto";
21
+ import { normalizeLineEndings, sortKeys } from "../migrations/document.js";
22
+ /** The `op` of a backfill step. */
23
+ export const BACKFILL_OP = "backfill";
24
+ /** The module a backfill step runs, in the migration's directory, unless its `options.file` names another. */
25
+ export const BACKFILL_FILE = "backfill.ts";
26
+ export const REBUILD_OP = "ClickHouseRebuildOp";
27
+ export const PG_MIGRATION_OP = "PostgresMigrationOp";
28
+ const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
29
+ /** The step as a backfill step, when it is one. */
30
+ export const asBackfill = (step) => step.kind === "op" && step.op === BACKFILL_OP ? step : undefined;
31
+ /** The file a backfill step names: relative to the migration's directory, `/`-separated, inside it. */
32
+ function backfillFile(options) {
33
+ const file = isRecord(options) ? options.file : undefined;
34
+ if (typeof file !== "string" || file === "")
35
+ return undefined;
36
+ const parts = file.split("/");
37
+ if (parts.some((p) => p === "" || p === "." || p === ".." || p.startsWith(".")) || file.includes("\\"))
38
+ return undefined;
39
+ return file;
40
+ }
41
+ /** How `yodel apply` treats one step. */
42
+ export function planStep(step) {
43
+ if (step.kind === "statement")
44
+ return { run: "statement" };
45
+ if (step.kind === "manual")
46
+ return { run: "refused", reason: `a manual step for ${step.object} (${step.name}): no statement and no Op makes it; ${step.detail}` };
47
+ const backfill = asBackfill(step);
48
+ if (backfill) {
49
+ const file = backfillFile(backfill.options);
50
+ return file ? { run: "backfill", file } : { run: "refused", reason: `a backfill step whose options.file is not a file in the migration's directory (${JSON.stringify(backfill.options)})` };
51
+ }
52
+ if (step.op === REBUILD_OP) {
53
+ const o = step.options;
54
+ const dw = isRecord(o.dualWrite) ? o.dualWrite : undefined;
55
+ if (typeof o.name !== "string" || typeof o.table !== "string" || !dw) {
56
+ return { run: "refused", reason: `${REBUILD_OP} for ${step.object} (${step.name}) without its name, table and dualWrite options` };
57
+ }
58
+ if (dw.mode === "app") {
59
+ return {
60
+ run: "refused",
61
+ reason: `${REBUILD_OP} for ${step.object} (${step.name}) in app mode: the application has to stop writing to ${o.table} while it is rebuilt, ` +
62
+ `which needs the Op's own writes gate; yodel apply runs materialized-view mode only. Run the Op with chant run (migration.json holds its declaration)`,
63
+ };
64
+ }
65
+ if (dw.mode !== "materialized-view" || typeof dw.cutoverColumn !== "string") {
66
+ return { run: "refused", reason: `${REBUILD_OP} for ${step.object} (${step.name}): dualWrite ${JSON.stringify(dw)} is not one yodel apply runs` };
67
+ }
68
+ return { run: "rebuild", options: { name: o.name, table: o.table, dualWrite: dw } };
69
+ }
70
+ if (step.op === PG_MIGRATION_OP)
71
+ return planPgMigration(step);
72
+ return { run: "refused", reason: `${step.op} for ${step.object} (${step.name}), not SQL: yodel apply does not run that Op` };
73
+ }
74
+ const optional = (o, key, ok) => {
75
+ const v = o[key];
76
+ if (v === undefined)
77
+ return undefined;
78
+ return ok(v) ? v : null;
79
+ };
80
+ const isString = (v) => typeof v === "string" && v !== "";
81
+ const isPositiveInt = (v) => typeof v === "number" && Number.isInteger(v) && v > 0;
82
+ const isLag = (v) => v === false || (isRecord(v) && Object.values(v).every((x) => typeof x === "string"));
83
+ function planPgMigration(step) {
84
+ const o = step.options;
85
+ const bad = (what) => ({ run: "refused", reason: `${PG_MIGRATION_OP} for ${step.object} (${step.name}): ${what}` });
86
+ if (!isString(o.name) || !isString(o.table) || !isString(o.column))
87
+ return bad("without its name, table and column options");
88
+ const using = optional(o, "using", isString);
89
+ const retain = optional(o, "retain", isString);
90
+ const batchSize = optional(o, "batchSize", isPositiveInt);
91
+ const lockTimeoutMs = optional(o, "lockTimeoutMs", isPositiveInt);
92
+ const statementTimeoutMs = optional(o, "statementTimeoutMs", isPositiveInt);
93
+ const replicationLag = optional(o, "replicationLag", isLag);
94
+ for (const [k, v] of Object.entries({ using, retain, batchSize, lockTimeoutMs, statementTimeoutMs, replicationLag })) {
95
+ if (v === null)
96
+ return bad(`options.${k} is ${JSON.stringify(o[k])}, which is not one it takes`);
97
+ }
98
+ return {
99
+ run: "pgMigration",
100
+ options: {
101
+ name: o.name,
102
+ table: o.table,
103
+ column: o.column,
104
+ ...(using ? { using } : {}),
105
+ ...(retain ? { retain } : {}),
106
+ ...(batchSize ? { batchSize } : {}),
107
+ ...(lockTimeoutMs ? { lockTimeoutMs } : {}),
108
+ ...(statementTimeoutMs ? { statementTimeoutMs } : {}),
109
+ ...(replicationLag !== undefined && replicationLag !== null ? { replicationLag } : {}),
110
+ },
111
+ };
112
+ }
113
+ /** One line naming a step, for logs and refusals. */
114
+ export function describeStep(step) {
115
+ if (step.kind === "statement")
116
+ return `${step.rule} ${step.class}, ${step.name}`;
117
+ if (step.kind === "manual")
118
+ return `manual step for ${step.object} (${step.name})`;
119
+ const backfill = asBackfill(step);
120
+ if (backfill)
121
+ return `backfill ${backfill.options.file}`;
122
+ return `${step.op} for ${step.object} (${step.name})`;
123
+ }
124
+ /**
125
+ * The hash a step's history rows record: for a statement, its SQL's (the
126
+ * history's `statementSha`); for an Op step, its canonical JSON and, for a
127
+ * backfill, the text of the module it runs. A step that ran and has since
128
+ * changed is how a part-way migration's edit is caught.
129
+ */
130
+ export function stepSha(step, files) {
131
+ const hash = createHash("sha256");
132
+ if (step.kind === "statement")
133
+ return `sha256:${hash.update(step.sql, "utf8").digest("hex")}`;
134
+ hash.update(JSON.stringify(sortKeys(step)), "utf8");
135
+ const backfill = asBackfill(step);
136
+ if (backfill) {
137
+ const file = backfill.options.file;
138
+ const text = files?.extra?.[file];
139
+ hash.update(`\n${file} ${text === undefined ? "missing" : String(Buffer.byteLength(normalizeLineEndings(text), "utf8"))}\n${normalizeLineEndings(text ?? "")}`, "utf8");
140
+ }
141
+ return `sha256:${hash.digest("hex")}`;
142
+ }
143
+ //# sourceMappingURL=kinds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinds.js","sourceRoot":"","sources":["../../src/steps/kinds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * A `PostgresMigrationOp` step: a Postgres column rename (SQLPG205) or type
3
+ * change across kinds (SQLPG208), which `yodel new` writes as a step since
4
+ * Postgres cannot make it in place without breaking readers, run inside the
5
+ * migration as chant's expand-and-contract Op.
6
+ *
7
+ * The Op is chant's own (`PostgresMigrationOp` from the sql lexicon), built
8
+ * from the step's options with the apply's environment, and run by chant's
9
+ * local executor with the lexicon's activities, as `ClickHouseRebuildOp` is
10
+ * (`./rebuild.ts`):
11
+ *
12
+ * Plan, Expand, Dual write, Backfill, Carry over, Verify, Switch, Retain, Contract
13
+ *
14
+ * What differs from `chant run` of the Op:
15
+ *
16
+ * - The declaration is the migration's recorded schema (`migration.json`'s
17
+ * `schema`), written to a temporary build file, not a fresh `chant build`.
18
+ * - Its two gates (before the switch, before the contract) are left out. The
19
+ * approval is the migration's: the step and its options are in the
20
+ * migration's checksum, so in the plan digest the migrations Op's gate
21
+ * approved. The verification still runs before the switch, and a
22
+ * difference (a row whose new column is not the expression over the old,
23
+ * a NULL where NOT NULL is declared) fails the step with nothing switched.
24
+ * - The old column's retention is the step's `options.retain` when it sets
25
+ * one, else none (`0s`): the contract drops the old column (and a rename's
26
+ * trigger) in the same run, right after the switch, as the migration's
27
+ * recorded schema says it is gone. A step that sets `retain` keeps the old
28
+ * column that long; the step succeeds with it kept, its note says until
29
+ * when, and dropping it after the date is `chant run` of the Op's
30
+ * declaration (in `migration.json`), whose contract is convergent.
31
+ * - Its onFailure (which drops what the expand added) is left out, so a step
32
+ * that failed or was stopped resumes on the next `yodel apply`. Every
33
+ * phase of the Op re-reads the server and does what is left of it: the
34
+ * expand finds the new column there and adds nothing, the dual write finds
35
+ * its trigger, the backfill skips every batch whose receipt is in
36
+ * `<schema>.__chant_receipts` (each receipt commits with its batch, so a
37
+ * batch is never filled twice), the carry over builds only the indexes and
38
+ * constraints not yet built (an INVALID one it left is built again), the
39
+ * verification runs again over every row, and a switch that already ran is
40
+ * not run again. To start over instead, drop the new column, its trigger
41
+ * and function (chant's working objects, named in their comments).
42
+ */
43
+ import type { OpConfig, PhaseDefinition } from "@intentius/chant/op/types";
44
+ import type { ActivityFn } from "@intentius/chant/op/activity-registry";
45
+ import type { StepRecord } from "@intentius/chant/op/local-executor";
46
+ import type { PgMigrationOptions } from "./kinds.js";
47
+ import { type RunOpOptions } from "./run.js";
48
+ /** The retention a step runs with when its options set none: the contract runs in the same apply. */
49
+ export declare const STEP_RETAIN = "0s";
50
+ /** `PostgresMigrationOp`'s phases as a step runs them: no gates, no onFailure. */
51
+ export declare function pgStepPhases(config: OpConfig): PhaseDefinition[];
52
+ /** The Op a step runs. `buildPath` is the recorded schema's file; `projectDir` holds chant.config.ts. */
53
+ export declare function pgMigrationOpConfig(options: PgMigrationOptions, ctx: {
54
+ environment: string;
55
+ projectDir: string;
56
+ buildPath: string;
57
+ lockTimeoutMs?: number | undefined;
58
+ }): Promise<OpConfig>;
59
+ export interface PgMigrationSummary {
60
+ op: "PostgresMigrationOp";
61
+ table: string;
62
+ column: string;
63
+ /** The Plan's state when the step began: `migrate`, or `switched` / `done` when an earlier run got that far. */
64
+ state?: string;
65
+ change?: string;
66
+ /** Backfill batches filled in this run, and skipped (their receipt was there). */
67
+ filled?: number;
68
+ skipped?: number;
69
+ backfilledRows?: number;
70
+ /** Indexes and constraints built on the new column in this run. */
71
+ carried?: number;
72
+ verifiedRows?: number;
73
+ switched?: boolean;
74
+ oldColumn?: string;
75
+ retainUntil?: string;
76
+ /** The contract dropped the old column. */
77
+ dropped?: boolean;
78
+ }
79
+ /** Folds one migration activity's result into the summary. */
80
+ export declare function summarizePg(summary: PgMigrationSummary, fn: string, result: unknown): void;
81
+ export interface RunPgMigrationOptions extends Omit<RunOpOptions, "activities" | "cwd"> {
82
+ projectDir: string;
83
+ /** The migration's recorded schema: the `chant build` output after it. */
84
+ schema: unknown;
85
+ /** The environment's lock timeout, used when the step's options set none. */
86
+ lockTimeoutMs?: number | undefined;
87
+ /** Activities to use in place of the lexicon's, for a test. */
88
+ activities?: Record<string, ActivityFn>;
89
+ log?: (line: string) => void;
90
+ }
91
+ /** Runs a `PostgresMigrationOp` step to the end. The summary fills in as the activities return, so a failure still says how far it got. */
92
+ export declare function runPgMigration(options: PgMigrationOptions, run: RunPgMigrationOptions, summary?: PgMigrationSummary): Promise<{
93
+ summary: PgMigrationSummary;
94
+ records: StepRecord[];
95
+ }>;
@@ -0,0 +1,149 @@
1
+ /**
2
+ * A `PostgresMigrationOp` step: a Postgres column rename (SQLPG205) or type
3
+ * change across kinds (SQLPG208), which `yodel new` writes as a step since
4
+ * Postgres cannot make it in place without breaking readers, run inside the
5
+ * migration as chant's expand-and-contract Op.
6
+ *
7
+ * The Op is chant's own (`PostgresMigrationOp` from the sql lexicon), built
8
+ * from the step's options with the apply's environment, and run by chant's
9
+ * local executor with the lexicon's activities, as `ClickHouseRebuildOp` is
10
+ * (`./rebuild.ts`):
11
+ *
12
+ * Plan, Expand, Dual write, Backfill, Carry over, Verify, Switch, Retain, Contract
13
+ *
14
+ * What differs from `chant run` of the Op:
15
+ *
16
+ * - The declaration is the migration's recorded schema (`migration.json`'s
17
+ * `schema`), written to a temporary build file, not a fresh `chant build`.
18
+ * - Its two gates (before the switch, before the contract) are left out. The
19
+ * approval is the migration's: the step and its options are in the
20
+ * migration's checksum, so in the plan digest the migrations Op's gate
21
+ * approved. The verification still runs before the switch, and a
22
+ * difference (a row whose new column is not the expression over the old,
23
+ * a NULL where NOT NULL is declared) fails the step with nothing switched.
24
+ * - The old column's retention is the step's `options.retain` when it sets
25
+ * one, else none (`0s`): the contract drops the old column (and a rename's
26
+ * trigger) in the same run, right after the switch, as the migration's
27
+ * recorded schema says it is gone. A step that sets `retain` keeps the old
28
+ * column that long; the step succeeds with it kept, its note says until
29
+ * when, and dropping it after the date is `chant run` of the Op's
30
+ * declaration (in `migration.json`), whose contract is convergent.
31
+ * - Its onFailure (which drops what the expand added) is left out, so a step
32
+ * that failed or was stopped resumes on the next `yodel apply`. Every
33
+ * phase of the Op re-reads the server and does what is left of it: the
34
+ * expand finds the new column there and adds nothing, the dual write finds
35
+ * its trigger, the backfill skips every batch whose receipt is in
36
+ * `<schema>.__chant_receipts` (each receipt commits with its batch, so a
37
+ * batch is never filled twice), the carry over builds only the indexes and
38
+ * constraints not yet built (an INVALID one it left is built again), the
39
+ * verification runs again over every row, and a switch that already ran is
40
+ * not run again. To start over instead, drop the new column, its trigger
41
+ * and function (chant's working objects, named in their comments).
42
+ */
43
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
44
+ import { tmpdir } from "node:os";
45
+ import { join } from "node:path";
46
+ import { runOp, StepOpFailed } from "./run.js";
47
+ /** The retention a step runs with when its options set none: the contract runs in the same apply. */
48
+ export const STEP_RETAIN = "0s";
49
+ /** `PostgresMigrationOp`'s phases as a step runs them: no gates, no onFailure. */
50
+ export function pgStepPhases(config) {
51
+ return config.phases.map((p) => ({ ...p, steps: p.steps.filter((s) => s.kind !== "gate") })).filter((p) => p.steps.length > 0);
52
+ }
53
+ /** The Op a step runs. `buildPath` is the recorded schema's file; `projectDir` holds chant.config.ts. */
54
+ export async function pgMigrationOpConfig(options, ctx) {
55
+ const { PostgresMigrationOp } = await import("@intentius/chant-lexicon-sql/postgres/migrate/op");
56
+ const lockTimeoutMs = options.lockTimeoutMs ?? ctx.lockTimeoutMs;
57
+ const { op } = PostgresMigrationOp({
58
+ name: options.name,
59
+ env: ctx.environment,
60
+ table: options.table,
61
+ column: options.column,
62
+ ...(options.using !== undefined ? { using: options.using } : {}),
63
+ retain: options.retain ?? STEP_RETAIN,
64
+ ...(options.batchSize !== undefined ? { batchSize: options.batchSize } : {}),
65
+ ...(options.replicationLag !== undefined ? { replicationLag: options.replicationLag } : {}),
66
+ ...(lockTimeoutMs !== undefined ? { lockTimeoutMs } : {}),
67
+ ...(options.statementTimeoutMs !== undefined ? { statementTimeoutMs: options.statementTimeoutMs } : {}),
68
+ build: false,
69
+ output: ctx.buildPath,
70
+ path: ctx.projectDir,
71
+ });
72
+ const full = op.props;
73
+ const rest = { ...full, phases: pgStepPhases(full) };
74
+ delete rest.onFailure;
75
+ return rest;
76
+ }
77
+ /** The migration activities whose results the history's summary keeps. */
78
+ const SUMMARIZED = ["postgresMigrationPlan", "postgresMigrationBackfill", "postgresMigrationCarry", "postgresMigrationVerify", "postgresMigrationSwitch", "postgresMigrationContract"];
79
+ const num = (v) => (typeof v === "number" ? v : undefined);
80
+ const str = (v) => (typeof v === "string" ? v : undefined);
81
+ /** Folds one migration activity's result into the summary. */
82
+ export function summarizePg(summary, fn, result) {
83
+ const r = (typeof result === "object" && result !== null ? result : {});
84
+ const put = (k, v) => {
85
+ if (v !== undefined)
86
+ summary[k] = v;
87
+ };
88
+ if (fn === "postgresMigrationPlan") {
89
+ put("state", str(r.state));
90
+ put("change", str(r.change));
91
+ }
92
+ if (fn === "postgresMigrationBackfill") {
93
+ put("filled", num(r.filled));
94
+ put("skipped", num(r.skipped));
95
+ put("backfilledRows", num(r.rows));
96
+ }
97
+ if (fn === "postgresMigrationCarry")
98
+ put("carried", num(r.built));
99
+ if (fn === "postgresMigrationVerify")
100
+ put("verifiedRows", num(r.rows));
101
+ if (fn === "postgresMigrationSwitch") {
102
+ put("switched", typeof r.switched === "boolean" ? r.switched : undefined);
103
+ put("oldColumn", str(r.oldColumn));
104
+ put("retainUntil", str(r.retainUntil));
105
+ }
106
+ if (fn === "postgresMigrationContract") {
107
+ put("dropped", typeof r.dropped === "boolean" ? r.dropped : undefined);
108
+ put("oldColumn", str(r.oldColumn));
109
+ put("retainUntil", str(r.retainUntil));
110
+ }
111
+ }
112
+ /** Runs a `PostgresMigrationOp` step to the end. The summary fills in as the activities return, so a failure still says how far it got. */
113
+ export async function runPgMigration(options, run, summary = { op: "PostgresMigrationOp", table: options.table, column: options.column }) {
114
+ const dir = mkdtempSync(join(tmpdir(), "yodel-pg-migration-"));
115
+ try {
116
+ const buildPath = join(dir, "schema.json");
117
+ writeFileSync(buildPath, JSON.stringify(run.schema));
118
+ const config = await pgMigrationOpConfig(options, { environment: run.environment, projectDir: run.projectDir, buildPath, lockTimeoutMs: run.lockTimeoutMs });
119
+ const lexicon = run.activities ?? (await import("@intentius/chant-lexicon-sql/op/activities"));
120
+ const wrapped = {};
121
+ for (const fn of SUMMARIZED) {
122
+ const inner = lexicon[fn];
123
+ if (!inner)
124
+ continue;
125
+ wrapped[fn] = async (args, signal) => {
126
+ const result = await inner(args, signal);
127
+ summarizePg(summary, fn, result);
128
+ return result;
129
+ };
130
+ }
131
+ const records = await runOp(config, {
132
+ cwd: run.projectDir,
133
+ environment: run.environment,
134
+ activities: { ...(run.activities ?? {}), ...wrapped },
135
+ ...(run.base ? { base: run.base } : {}),
136
+ ...(run.signal ? { signal: run.signal } : {}),
137
+ ...(run.onRecord ? { onRecord: run.onRecord } : {}),
138
+ }).catch((e) => {
139
+ if (e instanceof StepOpFailed)
140
+ e.summary = summary;
141
+ throw e;
142
+ });
143
+ return { summary, records };
144
+ }
145
+ finally {
146
+ rmSync(dir, { recursive: true, force: true });
147
+ }
148
+ }
149
+ //# sourceMappingURL=postgres-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-migration.js","sourceRoot":"","sources":["../../src/steps/postgres-migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * A `ClickHouseRebuildOp` step: the change ClickHouse cannot make with
3
+ * `ALTER` (a sort key, an engine, a key column's type or name), run inside
4
+ * the migration as chant's rebuild Op.
5
+ *
6
+ * The Op is chant's own (`ClickHouseRebuildOp` from the sql lexicon), built
7
+ * from the step's options with the apply's environment, and run by chant's
8
+ * local executor with the lexicon's rebuild activities:
9
+ *
10
+ * Plan, Create, Dual write (materialized-view mode), Backfill, Verify, Swap, Retain
11
+ *
12
+ * Three things differ from running the Op with `chant run`:
13
+ *
14
+ * - The declaration is the migration's recorded schema (`migration.json`'s
15
+ * `schema`), written to a temporary build file, not a fresh `chant build`:
16
+ * the table is rebuilt as this migration declares it, however far the
17
+ * declared schema has moved on since.
18
+ * - It is built with `gates: "outer"`: the swap gate's approval is the
19
+ * migration's (the step's options are in the migration's checksum, which
20
+ * is in the plan digest the migrations Op's gate approved), so the Op has
21
+ * no gate and no Drop phase. The verification still runs before the swap,
22
+ * and a difference fails the step with nothing swapped. The old table is
23
+ * kept, `<table>__chant_old`, until its retention date (7 days).
24
+ * - It is built with `onFailure: "keep"`, so a step that failed or was
25
+ * killed part way keeps `<table>__chant_new` and `<table>__chant_dual` and
26
+ * resumes from the backfill's receipts on the next `yodel apply`: every
27
+ * partition with a receipt is skipped. To start the rebuild over instead,
28
+ * drop those two tables (a refusal names them).
29
+ *
30
+ * The activities render their DDL for the topology chant resolves from
31
+ * `sql.profiles.<env>.topology`. When the environment's topology comes from
32
+ * elsewhere (`yodel.config.ts`, or `YODEL_TOPOLOGY`, #9), the step hands
33
+ * every rebuild activity chant's config with that topology set on the
34
+ * profile ({@link rebuildChantConfig}), so the rebuild renders for the same
35
+ * topology as the migration's statements. On a cluster of more than one
36
+ * shard the Op copies and verifies every shard; it needs the `{shard}` macro
37
+ * on each server, distinct per shard, and refuses the cluster without it.
38
+ */
39
+ import type { OpConfig } from "@intentius/chant/op/types";
40
+ import type { ActivityFn } from "@intentius/chant/op/activity-registry";
41
+ import type { StepRecord } from "@intentius/chant/op/local-executor";
42
+ import type { Topology } from "@intentius/chant-lexicon-sql/clickhouse/topology";
43
+ import type { RebuildOptions } from "./kinds.js";
44
+ import { type ProjectConfig } from "../project.js";
45
+ import { type RunOpOptions } from "./run.js";
46
+ /** `config` with `sql.profiles.<environment>.topology` set to `topology`. Pure; `config` is not changed. */
47
+ export declare function withProfileTopology(config: ProjectConfig, environment: string, topology: Topology): ProjectConfig;
48
+ /**
49
+ * The chant config a rebuild step's activities bind with: the project's,
50
+ * with the environment's resolved topology on its profile when chant would
51
+ * not find it there itself. `undefined` when chant's own resolution already
52
+ * gives the same topology (set in the profile, or no topology anywhere).
53
+ */
54
+ export declare function rebuildChantConfig(projectDir: string, environment: string, env?: NodeJS.ProcessEnv): Promise<ProjectConfig | undefined>;
55
+ /** The Op a rebuild step runs. `buildPath` is the recorded schema's file; `projectDir` holds chant.config.ts. */
56
+ export declare function rebuildOpConfig(options: RebuildOptions, ctx: {
57
+ environment: string;
58
+ projectDir: string;
59
+ buildPath: string;
60
+ }): Promise<OpConfig>;
61
+ export interface RebuildSummary {
62
+ op: "ClickHouseRebuildOp";
63
+ table: string;
64
+ /** The Plan's state when the step began: `rebuild`, or `swapped` / `done` when an earlier run got that far. */
65
+ state?: string;
66
+ partitions?: number;
67
+ /** Partitions copied in this run. */
68
+ copied?: number;
69
+ /** Partitions skipped: their receipt matched (copied by an earlier run). */
70
+ skipped?: number;
71
+ /** Partitions found partly copied and cleared before copying again. */
72
+ cleared?: number;
73
+ /** Rows copied by both the backfill and the dual-write view, deleted and copied again. */
74
+ repaired?: number;
75
+ /** Rows compared in the whole table, old against new. */
76
+ verifiedRows?: number;
77
+ swapped?: boolean;
78
+ oldTable?: string;
79
+ retainUntil?: string;
80
+ }
81
+ /** Folds one rebuild activity's result into the summary. */
82
+ export declare function summarize(summary: RebuildSummary, fn: string, result: unknown): void;
83
+ export interface RunRebuildOptions extends Omit<RunOpOptions, "activities" | "cwd"> {
84
+ projectDir: string;
85
+ /** The migration's recorded schema: the `chant build` output after it. */
86
+ schema: unknown;
87
+ /** Activities to use in place of the lexicon's, for a test. */
88
+ activities?: Record<string, ActivityFn>;
89
+ log?: (line: string) => void;
90
+ /** The chant config the rebuild activities bind with (see {@link rebuildChantConfig}). Default: they load chant.config.ts. */
91
+ config?: ProjectConfig | undefined;
92
+ }
93
+ /** Runs a rebuild step to the end. The summary is filled in as the activities return, so a failure still says how far it got. */
94
+ export declare function runRebuild(options: RebuildOptions, run: RunRebuildOptions, summary?: RebuildSummary): Promise<{
95
+ summary: RebuildSummary;
96
+ records: StepRecord[];
97
+ }>;