@intentius/sql-yodeler 0.3.0 → 0.4.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 (201) hide show
  1. package/README.md +1 -1
  2. package/dist/apply-steps/index.d.ts +65 -0
  3. package/dist/apply-steps/index.js +106 -0
  4. package/dist/apply-steps/index.js.map +1 -0
  5. package/dist/approval-mode/index.d.ts +78 -0
  6. package/dist/approval-mode/index.js +105 -0
  7. package/dist/approval-mode/index.js.map +1 -0
  8. package/dist/chant/access.d.ts +87 -0
  9. package/dist/chant/access.js +169 -0
  10. package/dist/chant/access.js.map +1 -0
  11. package/dist/chant/drift.d.ts +17 -1
  12. package/dist/chant/drift.js +55 -2
  13. package/dist/chant/drift.js.map +1 -1
  14. package/dist/chant/plan.d.ts +18 -2
  15. package/dist/chant/plan.js +21 -3
  16. package/dist/chant/plan.js.map +1 -1
  17. package/dist/ci/render.d.ts +54 -10
  18. package/dist/ci/render.js +249 -52
  19. package/dist/ci/render.js.map +1 -1
  20. package/dist/cleanup/index.d.ts +86 -0
  21. package/dist/cleanup/index.js +207 -0
  22. package/dist/cleanup/index.js.map +1 -0
  23. package/dist/commands/apply.js +153 -20
  24. package/dist/commands/apply.js.map +1 -1
  25. package/dist/commands/approve.d.ts +13 -0
  26. package/dist/commands/approve.js +206 -24
  27. package/dist/commands/approve.js.map +1 -1
  28. package/dist/commands/ci.js +12 -0
  29. package/dist/commands/ci.js.map +1 -1
  30. package/dist/commands/cleanup.d.ts +13 -0
  31. package/dist/commands/cleanup.js +138 -0
  32. package/dist/commands/cleanup.js.map +1 -0
  33. package/dist/commands/config.d.ts +3 -0
  34. package/dist/commands/config.js +136 -0
  35. package/dist/commands/config.js.map +1 -0
  36. package/dist/commands/drift.js +34 -3
  37. package/dist/commands/drift.js.map +1 -1
  38. package/dist/commands/index.js +6 -0
  39. package/dist/commands/index.js.map +1 -1
  40. package/dist/commands/lint.js +30 -6
  41. package/dist/commands/lint.js.map +1 -1
  42. package/dist/commands/new.js +133 -34
  43. package/dist/commands/new.js.map +1 -1
  44. package/dist/commands/plan.js +42 -5
  45. package/dist/commands/plan.js.map +1 -1
  46. package/dist/commands/test.d.ts +3 -0
  47. package/dist/commands/test.js +164 -0
  48. package/dist/commands/test.js.map +1 -0
  49. package/dist/config/define.d.ts +117 -2
  50. package/dist/config/define.js +2 -0
  51. package/dist/config/define.js.map +1 -1
  52. package/dist/config/load.js +74 -10
  53. package/dist/config/load.js.map +1 -1
  54. package/dist/config/settings.d.ts +18 -0
  55. package/dist/config/settings.js +26 -0
  56. package/dist/config/settings.js.map +1 -1
  57. package/dist/credentials.d.ts +119 -0
  58. package/dist/credentials.js +119 -0
  59. package/dist/credentials.js.map +1 -0
  60. package/dist/exit.js +1 -1
  61. package/dist/exit.js.map +1 -1
  62. package/dist/index.d.ts +5 -1
  63. package/dist/index.js +2 -0
  64. package/dist/index.js.map +1 -1
  65. package/dist/init/adopt.js +1 -1
  66. package/dist/init/adopt.js.map +1 -1
  67. package/dist/init/clickhouse-access.d.ts +64 -0
  68. package/dist/init/clickhouse-access.js +211 -0
  69. package/dist/init/clickhouse-access.js.map +1 -0
  70. package/dist/init/live.d.ts +4 -0
  71. package/dist/init/live.js +16 -0
  72. package/dist/init/live.js.map +1 -1
  73. package/dist/lint/access.d.ts +18 -0
  74. package/dist/lint/access.js +34 -0
  75. package/dist/lint/access.js.map +1 -0
  76. package/dist/lint/check.js +23 -6
  77. package/dist/lint/check.js.map +1 -1
  78. package/dist/lint/config.d.ts +7 -1
  79. package/dist/lint/config.js +11 -5
  80. package/dist/lint/config.js.map +1 -1
  81. package/dist/lint/index.d.ts +2 -0
  82. package/dist/lint/index.js +2 -0
  83. package/dist/lint/index.js.map +1 -1
  84. package/dist/lint/naming.d.ts +62 -0
  85. package/dist/lint/naming.js +138 -0
  86. package/dist/lint/naming.js.map +1 -0
  87. package/dist/lint/rules.d.ts +37 -4
  88. package/dist/lint/rules.js +16 -4
  89. package/dist/lint/rules.js.map +1 -1
  90. package/dist/lint/schema-checks.d.ts +63 -0
  91. package/dist/lint/schema-checks.js +128 -0
  92. package/dist/lint/schema-checks.js.map +1 -0
  93. package/dist/lint/statements.d.ts +22 -1
  94. package/dist/lint/statements.js +40 -1
  95. package/dist/lint/statements.js.map +1 -1
  96. package/dist/mcp/tools.d.ts +1 -1
  97. package/dist/mcp/tools.js +1 -1
  98. package/dist/mcp/tools.js.map +1 -1
  99. package/dist/migrations/checkpoint.js +0 -2
  100. package/dist/migrations/checkpoint.js.map +1 -1
  101. package/dist/migrations/checks.d.ts +19 -1
  102. package/dist/migrations/checks.js +15 -0
  103. package/dist/migrations/checks.js.map +1 -1
  104. package/dist/migrations/create.d.ts +13 -4
  105. package/dist/migrations/create.js +24 -9
  106. package/dist/migrations/create.js.map +1 -1
  107. package/dist/migrations/routines.d.ts +5 -15
  108. package/dist/migrations/routines.js +5 -30
  109. package/dist/migrations/routines.js.map +1 -1
  110. package/dist/pr/model.d.ts +4 -1
  111. package/dist/pr/model.js +13 -5
  112. package/dist/pr/model.js.map +1 -1
  113. package/dist/pr/render.d.ts +4 -1
  114. package/dist/pr/render.js +22 -8
  115. package/dist/pr/render.js.map +1 -1
  116. package/dist/pr/tenants.d.ts +37 -0
  117. package/dist/pr/tenants.js +138 -0
  118. package/dist/pr/tenants.js.map +1 -0
  119. package/dist/probe.d.ts +27 -0
  120. package/dist/probe.js +106 -0
  121. package/dist/probe.js.map +1 -0
  122. package/dist/project.d.ts +16 -0
  123. package/dist/project.js +29 -1
  124. package/dist/project.js.map +1 -1
  125. package/dist/replay/clickhouse.d.ts +31 -0
  126. package/dist/replay/clickhouse.js +103 -6
  127. package/dist/replay/clickhouse.js.map +1 -1
  128. package/dist/replay/replay.d.ts +5 -2
  129. package/dist/replay/replay.js.map +1 -1
  130. package/dist/report/audit.d.ts +1 -1
  131. package/dist/report/audit.js +20 -3
  132. package/dist/report/audit.js.map +1 -1
  133. package/dist/schemas.d.ts +3 -1
  134. package/dist/schemas.js +2 -0
  135. package/dist/schemas.js.map +1 -1
  136. package/dist/sources/ddl.d.ts +15 -20
  137. package/dist/sources/ddl.js +34 -328
  138. package/dist/sources/ddl.js.map +1 -1
  139. package/dist/sources/index.js +2 -2
  140. package/dist/sources/index.js.map +1 -1
  141. package/dist/steps/backfill.d.ts +40 -5
  142. package/dist/steps/backfill.js +128 -8
  143. package/dist/steps/backfill.js.map +1 -1
  144. package/dist/steps/index.d.ts +19 -1
  145. package/dist/steps/index.js +34 -7
  146. package/dist/steps/index.js.map +1 -1
  147. package/dist/steps/kinds.d.ts +42 -4
  148. package/dist/steps/kinds.js +88 -14
  149. package/dist/steps/kinds.js.map +1 -1
  150. package/dist/steps/postgres-migration.d.ts +3 -0
  151. package/dist/steps/postgres-migration.js +7 -3
  152. package/dist/steps/postgres-migration.js.map +1 -1
  153. package/dist/steps/rebuild.d.ts +15 -6
  154. package/dist/steps/rebuild.js +12 -9
  155. package/dist/steps/rebuild.js.map +1 -1
  156. package/dist/tenants/index.d.ts +2 -1
  157. package/dist/tenants/index.js +3 -4
  158. package/dist/tenants/index.js.map +1 -1
  159. package/dist/tenants/wave.d.ts +128 -0
  160. package/dist/tenants/wave.js +254 -0
  161. package/dist/tenants/wave.js.map +1 -0
  162. package/dist/testing/define.d.ts +62 -0
  163. package/dist/testing/define.js +32 -0
  164. package/dist/testing/define.js.map +1 -0
  165. package/dist/testing/files.d.ts +5 -0
  166. package/dist/testing/files.js +18 -0
  167. package/dist/testing/files.js.map +1 -0
  168. package/dist/testing/report.d.ts +14 -0
  169. package/dist/testing/report.js +83 -0
  170. package/dist/testing/report.js.map +1 -0
  171. package/dist/testing/run.d.ts +104 -0
  172. package/dist/testing/run.js +328 -0
  173. package/dist/testing/run.js.map +1 -0
  174. package/dist/versioned/approval.d.ts +6 -0
  175. package/dist/versioned/approval.js +11 -5
  176. package/dist/versioned/approval.js.map +1 -1
  177. package/dist/versioned/checks.d.ts +8 -2
  178. package/dist/versioned/checks.js +34 -13
  179. package/dist/versioned/checks.js.map +1 -1
  180. package/dist/versioned/driver.d.ts +2 -2
  181. package/dist/versioned/engine.d.ts +10 -0
  182. package/dist/versioned/engine.js +8 -4
  183. package/dist/versioned/engine.js.map +1 -1
  184. package/dist/versioned/explain.d.ts +2 -0
  185. package/dist/versioned/explain.js +3 -1
  186. package/dist/versioned/explain.js.map +1 -1
  187. package/dist/versioned/state.js +1 -1
  188. package/dist/versioned/state.js.map +1 -1
  189. package/dist/waves/index.d.ts +58 -13
  190. package/dist/waves/index.js +109 -24
  191. package/dist/waves/index.js.map +1 -1
  192. package/dist/waves/record.d.ts +10 -0
  193. package/dist/waves/record.js.map +1 -1
  194. package/package.json +7 -7
  195. package/schemas/apply.schema.json +1 -1
  196. package/schemas/cleanup.schema.json +40 -0
  197. package/schemas/lint-rules.schema.json +4 -0
  198. package/schemas/new.schema.json +41 -3
  199. package/schemas/plan.schema.json +39 -0
  200. package/schemas/report.schema.json +1 -1
  201. package/schemas/test.schema.json +41 -0
@@ -2,7 +2,16 @@
2
2
  * A backfill step: a data migration the author writes, run inside the
3
3
  * migration between the statements around it, resumable from receipts.
4
4
  *
5
- * The step names a module in the migration's directory (`backfill.ts` by
5
+ * The common case is a form, the step's options in `migration.json`
6
+ * ({@link BackfillForm}): a table, an integer key and a batch size (or a
7
+ * list of batches), and the SQL of one batch with `{from}` and `{to}` (or
8
+ * `{batch}`) in it. `yodel new <name> --backfill` writes it from
9
+ * `backfills/<name>.json`. When the step runs, yodel builds the Op below
10
+ * from it ({@link formOp}): one `effect()` per batch, the batches read from
11
+ * the table's smallest and largest key at that moment, aligned to the
12
+ * batch size so a rerun sees the same ranges.
13
+ *
14
+ * The advanced case: the step names a module in the migration's directory (`backfill.ts` by
6
15
  * default) that exports a chant Op as `op` (or as its default export). Each
7
16
  * step of its phases is an `effect()` step: one batch of the backfill, with
8
17
  * its own receipt. The nested steps run SQL on the environment's server with
@@ -59,7 +68,7 @@ import { join } from "node:path";
59
68
  import { pathToFileURL } from "node:url";
60
69
  import { YodelError } from "../project.js";
61
70
  import { gatesOf, runOp, StepOpFailed } from "./run.js";
62
- import { BACKFILL_FILE, BACKFILL_OP } from "./kinds.js";
71
+ import { BACKFILL_FILE, BACKFILL_OP, describeForm, formPlaceholders } from "./kinds.js";
63
72
  /** The activity a backfill's steps run SQL with: `activity("yodelSql", { sql, settings? })`. */
64
73
  export const SQL_ACTIVITY = "yodelSql";
65
74
  /** The step `yodel new --backfill` adds to a migration. */
@@ -77,6 +86,32 @@ export function backfillStep(migrationName, file = BACKFILL_FILE) {
77
86
  detail: `a data backfill: the effect() steps of the Op in ${file}, each a batch with its own receipt; yodel apply runs it after the statements before it and resumes it from its receipts`,
78
87
  };
79
88
  }
89
+ /** The default place `yodel new <name> --backfill` reads a form from (and writes its template at), in the project directory. */
90
+ export const formPath = (name) => `backfills/${name}.json`;
91
+ /** What one batch of a form runs, as the plan shows it. */
92
+ export function describeFormSql(form) {
93
+ return (typeof form.sql === "string" ? [form.sql] : form.sql).map((s) => `${s.trim().replace(/;\s*$/, "")};`).join("\n");
94
+ }
95
+ /** The step `yodel new --backfill` adds for a form: the form is the step's options, so it is in the checksum and the plan shows it. */
96
+ export function backfillFormStep(migrationName, form) {
97
+ const batches = form.key !== undefined
98
+ ? `each range of ${form.key} ${String(form.batchSize)} wide, {from} inclusive to {to} exclusive, from the table's smallest key to its largest when the step runs, is one batch`
99
+ : `each of the ${String(form.batches?.length ?? 0)} batches listed, {batch} in the SQL, is one batch`;
100
+ return {
101
+ kind: "op",
102
+ object: "backfill",
103
+ type: "Yodel::Backfill",
104
+ name: migrationName,
105
+ op: BACKFILL_OP,
106
+ importPath: "@intentius/sql-yodeler",
107
+ options: form,
108
+ declaration: JSON.stringify(form, null, 2),
109
+ changes: [],
110
+ detail: `a data backfill of ${describeForm(form)}: ${batches}, with its own receipt. ` +
111
+ `yodel apply runs the batches in order after the statements before this step, and a rerun after a failure resumes at the first batch without a receipt. Each batch runs:\n` +
112
+ describeFormSql(form),
113
+ };
114
+ }
80
115
  /** Text only the template holds: a backfill still carrying it has not been written. */
81
116
  export const TEMPLATE_MARK = "write the backfill of";
82
117
  /** What `yodel new --backfill <file>` writes at `<file>` when there is none yet. */
@@ -118,6 +153,24 @@ export const op = Op({
118
153
  });
119
154
  `;
120
155
  }
156
+ /** What `yodel new <name> --backfill` writes at `backfills/<name>.json` when there is none yet: a form to fill in. */
157
+ export function formTemplate(name, dialect = "clickhouse") {
158
+ const form = dialect === "postgres"
159
+ ? {
160
+ table: "<schema>.<table>",
161
+ key: "id",
162
+ batchSize: 10000,
163
+ sql: `${TEMPLATE_MARK} ${name}: UPDATE <schema>.<table> SET <column> = <expression> WHERE id >= {from} AND id < {to}`,
164
+ }
165
+ : {
166
+ table: "<database>.<table>",
167
+ key: "id",
168
+ batchSize: 100000,
169
+ settings: { mutations_sync: "2" },
170
+ sql: `${TEMPLATE_MARK} ${name}: ALTER TABLE <database>.<table> UPDATE <column> = <expression> WHERE id >= {from} AND id < {to}`,
171
+ };
172
+ return `${JSON.stringify(form, null, 2)}\n`;
173
+ }
121
174
  const isRecord = (v) => typeof v === "object" && v !== null;
122
175
  /** The Op config a module exports as `op` or as its default export. */
123
176
  export function exportedOp(mod) {
@@ -190,6 +243,7 @@ export async function serverReceipts(server, environment) {
190
243
  }
191
244
  function clickhouseBatches(port) {
192
245
  return {
246
+ read: (sql) => port.query(sql),
193
247
  next: () => Promise.resolve(),
194
248
  sql: async (sql, settings) => (await port.query(sql, settings ? { settings } : {})).length,
195
249
  done: () => Promise.resolve(),
@@ -209,6 +263,10 @@ function postgresBatches(server) {
209
263
  await client.query("ROLLBACK").catch(() => undefined);
210
264
  };
211
265
  return {
266
+ async read(sql) {
267
+ await rollback();
268
+ return client.query(sql);
269
+ },
212
270
  async next() {
213
271
  await rollback();
214
272
  lost = undefined;
@@ -242,13 +300,74 @@ function postgresBatches(server) {
242
300
  abandon: rollback,
243
301
  };
244
302
  }
245
- /** Runs a backfill step to the end, counting batches as they skip or finish. */
246
- export async function runBackfill(file, run) {
247
- const config = await loadBackfill(join(run.dir, file), run.text);
248
- const summary = { op: "backfill", file, name: config.name, effects: config.phases.reduce((n, p) => n + p.steps.length, 0), skipped: 0, ran: 0 };
303
+ /** Floor division of bigints. */
304
+ const floorDiv = (a, b) => (a % b === 0n || a >= 0n ? a / b : a / b - 1n);
305
+ /** The ranges `[from, to)` of width `size`, aligned to multiples of it, that cover `lo` to `hi`. */
306
+ export function keyRanges(lo, hi, size) {
307
+ const width = BigInt(size);
308
+ const out = [];
309
+ for (let from = floorDiv(lo, width) * width; from <= hi; from += width) {
310
+ const to = from + width;
311
+ out.push({ id: `${String(from)}-${String(to)}`, values: { "{from}": String(from), "{to}": String(to) } });
312
+ }
313
+ return out;
314
+ }
315
+ /** A form's batches: its list, or the ranges of its key over the table's rows now (none when the table is empty). */
316
+ export async function formBatches(form, read, dialect) {
317
+ if (form.key === undefined)
318
+ return (form.batches ?? []).map((b) => ({ id: String(b), values: { "{batch}": String(b) } }));
319
+ const sql = dialect === "clickhouse"
320
+ ? `SELECT count() AS n, toString(min(${form.key})) AS lo, toString(max(${form.key})) AS hi FROM ${form.table}`
321
+ : `SELECT count(*)::text AS n, min(${form.key})::text AS lo, max(${form.key})::text AS hi FROM ${form.table}`;
322
+ const [row] = await read(sql);
323
+ if (!row || Number(row.n) === 0)
324
+ return [];
325
+ let lo, hi;
326
+ try {
327
+ lo = BigInt(String(row.lo));
328
+ hi = BigInt(String(row.hi));
329
+ }
330
+ catch {
331
+ throw new YodelError(`the backfill's key ${form.key} of ${form.table} is not an integer (its values run from ${String(row.lo)} to ${String(row.hi)}); list the batches with "batches" instead`);
332
+ }
333
+ return keyRanges(lo, hi, form.batchSize ?? 1);
334
+ }
335
+ /** The SQL of one batch: each placeholder replaced by its value. */
336
+ export function batchSql(form, batch) {
337
+ const statements = typeof form.sql === "string" ? [form.sql] : form.sql;
338
+ return statements.map((s) => formPlaceholders(form).reduce((out, p) => out.split(p).join(batch.values[p] ?? p), s));
339
+ }
340
+ /** The Op a form runs: one effect() per batch, each running its statements with `yodelSql` and writing its receipt last. */
341
+ export async function formOp(name, form, batches) {
342
+ const { EffectReceipt } = await import("@intentius/chant");
343
+ const { Op, activity, effect, phase } = await import("@intentius/chant/op");
344
+ const kind = form.key !== undefined ? "range" : "batch";
345
+ const steps = batches.map((b) => effect(EffectReceipt(`${name}-${b.id}`, { effect: `${kind}/${b.id}`, flavor: "existence" }), batchSql(form, b).map((sql) => activity(SQL_ACTIVITY, { sql, ...(form.settings ? { settings: form.settings } : {}) }, "atMostOnce"))));
346
+ const op = Op({ name: `backfill-${name}`, overview: `Backfill of ${describeForm(form)}`, phases: [phase("Backfill", steps)] });
347
+ return op.props;
348
+ }
349
+ /** Runs a backfill step to the end, counting batches as they skip or finish. `source` is the module's file, or the step's form. */
350
+ export async function runBackfill(source, run) {
249
351
  const session = run.postgres ? postgresBatches(run.postgres) : run.port ? clickhouseBatches(run.port) : undefined;
250
352
  if (!session)
251
353
  throw new YodelError("a backfill step needs the environment's server to run its SQL on, and has none");
354
+ let config;
355
+ let summary;
356
+ if (typeof source === "string") {
357
+ config = await loadBackfill(join(run.dir, source), run.text);
358
+ summary = { op: "backfill", file: source, name: config.name, effects: config.phases.reduce((n, p) => n + p.steps.length, 0), skipped: 0, ran: 0 };
359
+ }
360
+ else {
361
+ const name = run.migrationId.slice(run.migrationId.indexOf("-") + 1);
362
+ const batches = await formBatches(source, (sql) => session.read(sql), run.postgres ? "postgres" : "clickhouse");
363
+ config = await formOp(name, source, batches);
364
+ summary = { op: "backfill", table: source.table, name: config.name, effects: batches.length, skipped: 0, ran: 0 };
365
+ if (batches.length === 0) {
366
+ run.log?.(` ${source.table} has no rows: no batch to run`);
367
+ await session.abandon();
368
+ return { summary, records: [] };
369
+ }
370
+ }
252
371
  const { receiptActivities } = await import("@intentius/chant/op/receipt-store");
253
372
  const store = receiptActivities(prefixedStore(run.receipts, `${run.migrationId}/`));
254
373
  const activities = {
@@ -275,9 +394,10 @@ export async function runBackfill(file, run) {
275
394
  },
276
395
  receiptStaleness: (args) => store.receiptStaleness(args),
277
396
  [SQL_ACTIVITY]: async (args) => {
278
- const sql = args.sql;
279
- if (typeof sql !== "string" || sql.trim() === "")
397
+ const written = args.sql;
398
+ if (typeof written !== "string" || written.trim() === "")
280
399
  throw new Error(`${SQL_ACTIVITY}: needs { sql: "<statement>" }`);
400
+ const sql = run.rename ? run.rename(written) : written;
281
401
  const settings = isRecord(args.settings) ? Object.fromEntries(Object.entries(args.settings).map(([k, v]) => [k, String(v)])) : undefined;
282
402
  run.log?.(` ${sql.split("\n")[0] ?? ""}`);
283
403
  return { rows: await session.sql(sql, settings) };
@@ -1 +1 @@
1
- {"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/steps/backfill.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/steps/backfill.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * planStep(step) statement, rebuild, backfill, or refused (with why)
5
5
  * stepSha(step, files) the hash a step's history rows record
6
6
  * runRebuild(...) a ClickHouseRebuildOp step (./rebuild.ts)
7
- * runBackfill(...) a backfill step, an Op of effect() batches (./backfill.ts)
7
+ * runBackfill(...) a backfill step, a form or an Op of effect() batches (./backfill.ts)
8
8
  * runPgMigration(...) a PostgresMigrationOp step (./postgres-migration.ts)
9
9
  * defaultStepRunner what the versioned apply calls for an Op step
10
10
  */
@@ -12,8 +12,10 @@ import type { ReceiptStore } from "@intentius/chant/op/receipt-store";
12
12
  import type { ClickHouseEndpoint } from "@intentius/chant-lexicon-sql/clickhouse/http";
13
13
  import type { ClickHousePort } from "../history/index.js";
14
14
  import type { Migration } from "../migrations/index.js";
15
+ import { type ProjectConfig, type TenantOf } from "../project.js";
15
16
  import { type PgBackfillServer } from "./backfill.js";
16
17
  import type { StepPlan } from "./kinds.js";
18
+ import { type RebuildReceiptStore } from "./rebuild.js";
17
19
  export * from "./kinds.js";
18
20
  export * from "./run.js";
19
21
  export * from "./rebuild.js";
@@ -44,7 +46,23 @@ export interface StepContext {
44
46
  log: (line: string) => void;
45
47
  /** A backfill's receipt store; default the sql lexicon's on the server. */
46
48
  receipts?: ReceiptStore | undefined;
49
+ /** A rebuild's partition receipts; default the sql lexicon's on the server (`chant_receipts.receipts`). `yodel test` keeps each case's apart (#112). */
50
+ rebuildReceipts?: RebuildReceiptStore | undefined;
51
+ /** The tenant the step runs on (#56): what the step names in the template is renamed to the tenant. */
52
+ tenant?: TenantOf | undefined;
47
53
  }
54
+ /** `value` with the template renamed in every string it holds (#56), as statements are. */
55
+ export declare function renameDeep(value: unknown, rename: (s: string) => string): unknown;
56
+ /**
57
+ * What an Op step runs with on a tenant (#56): its options and the recorded
58
+ * schema with the template renamed to the tenant, and the project's chant
59
+ * config with the tenant's profile in it, which the Op's activities bind
60
+ * with in place of chant.config.ts.
61
+ */
62
+ export declare function tenantStep(projectDir: string, environment: string, tenant: TenantOf): Promise<{
63
+ rename: (s: string) => string;
64
+ config: ProjectConfig;
65
+ }>;
48
66
  /** Runs one Op step to the end and returns the summary its history row records. Throws `StepOpFailed` when it stops part way. */
49
67
  export type StepRunner = (ctx: StepContext) => Promise<{
50
68
  summary: unknown;
@@ -4,11 +4,12 @@
4
4
  * planStep(step) statement, rebuild, backfill, or refused (with why)
5
5
  * stepSha(step, files) the hash a step's history rows record
6
6
  * runRebuild(...) a ClickHouseRebuildOp step (./rebuild.ts)
7
- * runBackfill(...) a backfill step, an Op of effect() batches (./backfill.ts)
7
+ * runBackfill(...) a backfill step, a form or an Op of effect() batches (./backfill.ts)
8
8
  * runPgMigration(...) a PostgresMigrationOp step (./postgres-migration.ts)
9
9
  * defaultStepRunner what the versioned apply calls for an Op step
10
10
  */
11
- import { YodelError } from "../project.js";
11
+ import { loadProject, resolveEnvironment, YodelError } from "../project.js";
12
+ import { renameIdentifier } from "../tenants/target.js";
12
13
  import { runBackfill, serverReceipts } from "./backfill.js";
13
14
  import { rebuildChantConfig, runRebuild } from "./rebuild.js";
14
15
  import { runPgMigration } from "./postgres-migration.js";
@@ -17,14 +18,39 @@ export * from "./run.js";
17
18
  export * from "./rebuild.js";
18
19
  export * from "./backfill.js";
19
20
  export * from "./postgres-migration.js";
21
+ /** `value` with the template renamed in every string it holds (#56), as statements are. */
22
+ export function renameDeep(value, rename) {
23
+ if (typeof value === "string")
24
+ return rename(value);
25
+ if (Array.isArray(value))
26
+ return value.map((v) => renameDeep(v, rename));
27
+ if (typeof value === "object" && value !== null)
28
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, renameDeep(v, rename)]));
29
+ return value;
30
+ }
31
+ /**
32
+ * What an Op step runs with on a tenant (#56): its options and the recorded
33
+ * schema with the template renamed to the tenant, and the project's chant
34
+ * config with the tenant's profile in it, which the Op's activities bind
35
+ * with in place of chant.config.ts.
36
+ */
37
+ export async function tenantStep(projectDir, environment, tenant) {
38
+ const project = await loadProject(projectDir);
39
+ resolveEnvironment(project, environment);
40
+ return { rename: (s) => renameIdentifier(s, tenant.template, tenant.name), config: project.config };
41
+ }
20
42
  export const defaultStepRunner = async (ctx) => {
43
+ const tenant = ctx.tenant ? await tenantStep(ctx.projectDir, ctx.environment, ctx.tenant) : undefined;
44
+ const schema = tenant ? renameDeep(ctx.migration.document.schema, tenant.rename) : ctx.migration.document.schema;
21
45
  if (ctx.plan.run === "rebuild") {
22
- const config = await rebuildChantConfig(ctx.projectDir, ctx.environment);
23
- const { summary } = await runRebuild(ctx.plan.options, { environment: ctx.environment, projectDir: ctx.projectDir, schema: ctx.migration.document.schema, log: ctx.log, config });
46
+ const options = tenant ? { ...ctx.plan.options, table: tenant.rename(ctx.plan.options.table) } : ctx.plan.options;
47
+ const config = await rebuildChantConfig(ctx.projectDir, ctx.environment, process.env, tenant?.config);
48
+ const { summary } = await runRebuild(options, { environment: ctx.environment, projectDir: ctx.projectDir, schema, log: ctx.log, config, ...(ctx.rebuildReceipts ? { receipts: ctx.rebuildReceipts } : {}) });
24
49
  return { summary };
25
50
  }
26
51
  if (ctx.plan.run === "pgMigration") {
27
- const { summary } = await runPgMigration(ctx.plan.options, { environment: ctx.environment, projectDir: ctx.projectDir, schema: ctx.migration.document.schema, lockTimeoutMs: ctx.lockTimeoutMs, log: ctx.log });
52
+ const options = tenant ? { ...ctx.plan.options, table: tenant.rename(ctx.plan.options.table) } : ctx.plan.options;
53
+ const { summary } = await runPgMigration(options, { environment: ctx.environment, projectDir: ctx.projectDir, schema, lockTimeoutMs: ctx.lockTimeoutMs, log: ctx.log, config: tenant?.config });
28
54
  return { summary };
29
55
  }
30
56
  if (!ctx.port && !ctx.postgres)
@@ -37,15 +63,16 @@ export const defaultStepRunner = async (ctx) => {
37
63
  : undefined);
38
64
  if (!receipts)
39
65
  throw new YodelError("a backfill step needs a receipt store, and this environment has no server endpoint for one");
40
- const { summary } = await runBackfill(ctx.plan.file, {
66
+ const { summary } = await runBackfill(ctx.plan.form ?? ctx.plan.file, {
41
67
  environment: ctx.environment,
42
68
  projectDir: ctx.projectDir,
43
69
  migrationId: ctx.migration.id,
44
70
  dir: ctx.migration.dir,
45
- text: ctx.migration.files.extra?.[ctx.plan.file],
71
+ text: ctx.plan.file === undefined ? undefined : ctx.migration.files.extra?.[ctx.plan.file],
46
72
  ...(ctx.postgres ? { postgres: { client: ctx.postgres.client, timeouts: ctx.postgres.timeouts } } : { port: ctx.port }),
47
73
  receipts,
48
74
  log: ctx.log,
75
+ ...(tenant ? { rename: tenant.rename } : {}),
49
76
  });
50
77
  return { summary };
51
78
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/steps/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/steps/index.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,10 @@
9
9
  *
10
10
  * - `ClickHouseRebuildOp`, the step `yodel new` writes for a ClickHouse sort
11
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`);
12
+ * - `backfill`, a data backfill: written as a form in the step's options
13
+ * (a table, a key and a batch size, or a list of batches, and the SQL of
14
+ * one batch), or as an Op of `effect()` steps in a module in the
15
+ * migration's directory (`./backfill.ts`);
14
16
  * - `PostgresMigrationOp`, the step `yodel new` writes for a Postgres column
15
17
  * rename or type change across kinds (`./postgres-migration.ts`, #13).
16
18
  *
@@ -28,9 +30,30 @@ export declare const PG_MIGRATION_OP = "PostgresMigrationOp";
28
30
  type OpStep = Extract<MigrationStep, {
29
31
  kind: "op";
30
32
  }>;
33
+ /**
34
+ * A backfill written as a form, yodel's own terms for the common case: the
35
+ * step's options in `migration.json`, which yodel turns into an Op of
36
+ * `effect()` batches, one receipt each.
37
+ *
38
+ * Batches are either ranges of an integer `key` of `table`, `batchSize`
39
+ * wide (`{from}` and `{to}` in the SQL, from inclusive, to exclusive, read
40
+ * from the table's smallest and largest key when the step runs), or the
41
+ * values `batches` lists (`{batch}` in the SQL). `sql` is one statement, or
42
+ * several run in order, for one batch.
43
+ */
44
+ export interface BackfillForm {
45
+ table: string;
46
+ key?: string;
47
+ batchSize?: number;
48
+ batches?: Array<string | number>;
49
+ sql: string | string[];
50
+ /** Settings for each statement: ClickHouse query settings (`mutations_sync`), Postgres `set_config` for the batch's transaction. */
51
+ settings?: Record<string, string>;
52
+ }
31
53
  /**
32
54
  * A backfill step in `migration.json`. chant's `OpStep` shape, so every
33
- * reader of steps sees an Op step:
55
+ * reader of steps sees an Op step. Its options are a {@link BackfillForm},
56
+ * or name the module that exports the Op:
34
57
  *
35
58
  * { "kind": "op", "object": "backfill", "type": "Yodel::Backfill", "name": "<migration name>",
36
59
  * "op": "backfill", "importPath": "./backfill.ts", "options": { "file": "backfill.ts" },
@@ -40,7 +63,7 @@ export interface BackfillStep extends Omit<OpStep, "op" | "options"> {
40
63
  op: typeof BACKFILL_OP;
41
64
  options: {
42
65
  file: string;
43
- };
66
+ } | BackfillForm;
44
67
  }
45
68
  export type DualWrite = {
46
69
  mode: "materialized-view";
@@ -53,6 +76,8 @@ export interface RebuildOptions {
53
76
  name: string;
54
77
  table: string;
55
78
  dualWrite: DualWrite;
79
+ /** How long the old table is kept after the swap; default chant's (7 days). */
80
+ retain?: string;
56
81
  }
57
82
  /** A `PostgresMigrationOp` step's options: chant's `{ name, env, table, column }`, and what the author may add (`using`, `retain`, ...). */
58
83
  export interface PgMigrationOptions {
@@ -81,12 +106,25 @@ export type StepPlan = {
81
106
  } | {
82
107
  run: "backfill";
83
108
  file: string;
109
+ form?: undefined;
110
+ } | {
111
+ run: "backfill";
112
+ form: BackfillForm;
113
+ file?: undefined;
84
114
  } | {
85
115
  run: "refused";
86
116
  reason: string;
87
117
  };
88
118
  /** The step as a backfill step, when it is one. */
89
119
  export declare const asBackfill: (step: MigrationStep | BackfillStep) => BackfillStep | undefined;
120
+ /** The placeholders a form's SQL takes: `{from}` and `{to}` with a key, `{batch}` with a list. */
121
+ export declare const formPlaceholders: (form: Pick<BackfillForm, "key">) => string[];
122
+ /** What is wrong with a backfill form, if anything. */
123
+ export declare function formProblems(options: unknown): string[];
124
+ /** The step's options as a form, when they are one (no `file`). */
125
+ export declare function asForm(options: unknown): BackfillForm | undefined;
126
+ /** One line saying how a form batches: `shop.orders by id, 10000 a batch` or `shop.orders, 3 batches`. */
127
+ export declare function describeForm(form: BackfillForm): string;
90
128
  /** How `yodel apply` treats one step. */
91
129
  export declare function planStep(step: MigrationStep | BackfillStep): StepPlan;
92
130
  /** One line naming a step, for logs and refusals. */
@@ -9,8 +9,10 @@
9
9
  *
10
10
  * - `ClickHouseRebuildOp`, the step `yodel new` writes for a ClickHouse sort
11
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`);
12
+ * - `backfill`, a data backfill: written as a form in the step's options
13
+ * (a table, a key and a batch size, or a list of batches, and the SQL of
14
+ * one batch), or as an Op of `effect()` steps in a module in the
15
+ * migration's directory (`./backfill.ts`);
14
16
  * - `PostgresMigrationOp`, the step `yodel new` writes for a Postgres column
15
17
  * rename or type change across kinds (`./postgres-migration.ts`, #13).
16
18
  *
@@ -26,6 +28,14 @@ export const BACKFILL_FILE = "backfill.ts";
26
28
  export const REBUILD_OP = "ClickHouseRebuildOp";
27
29
  export const PG_MIGRATION_OP = "PostgresMigrationOp";
28
30
  const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
31
+ const optional = (o, key, ok) => {
32
+ const v = o[key];
33
+ if (v === undefined)
34
+ return undefined;
35
+ return ok(v) ? v : null;
36
+ };
37
+ const isString = (v) => typeof v === "string" && v !== "";
38
+ const isPositiveInt = (v) => typeof v === "number" && Number.isInteger(v) && v > 0;
29
39
  /** The step as a backfill step, when it is one. */
30
40
  export const asBackfill = (step) => step.kind === "op" && step.op === BACKFILL_OP ? step : undefined;
31
41
  /** The file a backfill step names: relative to the migration's directory, `/`-separated, inside it. */
@@ -38,6 +48,69 @@ function backfillFile(options) {
38
48
  return undefined;
39
49
  return file;
40
50
  }
51
+ /** The placeholders a form's SQL takes: `{from}` and `{to}` with a key, `{batch}` with a list. */
52
+ export const formPlaceholders = (form) => (form.key !== undefined ? ["{from}", "{to}"] : ["{batch}"]);
53
+ /** What is wrong with a backfill form, if anything. */
54
+ export function formProblems(options) {
55
+ if (!isRecord(options))
56
+ return ["a backfill form is an object"];
57
+ const o = options;
58
+ const problems = [];
59
+ const known = new Set(["table", "key", "batchSize", "batches", "sql", "settings"]);
60
+ for (const k of Object.keys(o))
61
+ if (!known.has(k))
62
+ problems.push(`"${k}" is not a field of a backfill (${[...known].join(", ")})`);
63
+ if (!isString(o.table))
64
+ problems.push(`"table" names the table the backfill fills, for example "shop.orders"`);
65
+ const sql = typeof o.sql === "string" ? [o.sql] : Array.isArray(o.sql) ? o.sql : undefined;
66
+ if (!sql || sql.length === 0 || !sql.every((x) => typeof x === "string" && x.trim() !== ""))
67
+ problems.push(`"sql" is the SQL of one batch: a statement, or a list of them`);
68
+ const byKey = o.key !== undefined || o.batchSize !== undefined;
69
+ if (byKey && o.batches !== undefined)
70
+ problems.push(`give "key" and "batchSize", or "batches", not both`);
71
+ else if (byKey) {
72
+ if (!isString(o.key))
73
+ problems.push(`"key" is an integer column of the table, the batches are ranges of it`);
74
+ if (!isPositiveInt(o.batchSize))
75
+ problems.push(`"batchSize" is how wide each range of the key is, a positive integer`);
76
+ }
77
+ else if (o.batches !== undefined) {
78
+ if (!Array.isArray(o.batches) || o.batches.length === 0 || !o.batches.every((b) => typeof b === "string" || (typeof b === "number" && Number.isFinite(b)))) {
79
+ problems.push(`"batches" lists the batches, strings or numbers, for example ["202601", "202602"]`);
80
+ }
81
+ else if (new Set(o.batches.map(String)).size !== o.batches.length)
82
+ problems.push(`"batches" lists a batch twice`);
83
+ }
84
+ else
85
+ problems.push(`give "key" and "batchSize" (ranges of an integer key), or "batches" (a list)`);
86
+ if (o.settings !== undefined && !(isRecord(o.settings) && Object.values(o.settings).every((v) => typeof v === "string" || typeof v === "number")))
87
+ problems.push(`"settings" maps a setting's name to its value`);
88
+ if (sql && problems.length === 0) {
89
+ const want = formPlaceholders(o);
90
+ const text = sql.join("\n");
91
+ if (!want.some((p) => text.includes(p)))
92
+ problems.push(`"sql" uses none of ${want.join(" and ")}, so every batch would run the same statement`);
93
+ }
94
+ return problems;
95
+ }
96
+ /** The step's options as a form, when they are one (no `file`). */
97
+ export function asForm(options) {
98
+ if (!isRecord(options) || "file" in options)
99
+ return undefined;
100
+ if (formProblems(options).length > 0)
101
+ return undefined;
102
+ const o = options;
103
+ return {
104
+ table: o.table,
105
+ ...(o.key !== undefined ? { key: o.key, batchSize: o.batchSize } : { batches: o.batches }),
106
+ sql: o.sql,
107
+ ...(o.settings ? { settings: Object.fromEntries(Object.entries(o.settings).map(([k, v]) => [k, String(v)])) } : {}),
108
+ };
109
+ }
110
+ /** One line saying how a form batches: `shop.orders by id, 10000 a batch` or `shop.orders, 3 batches`. */
111
+ export function describeForm(form) {
112
+ return form.key !== undefined ? `${form.table} by ${form.key}, ${String(form.batchSize)} a batch` : `${form.table}, ${String(form.batches?.length ?? 0)} batch${form.batches?.length === 1 ? "" : "es"} (${(form.batches ?? []).join(", ")})`;
113
+ }
41
114
  /** How `yodel apply` treats one step. */
42
115
  export function planStep(step) {
43
116
  if (step.kind === "statement")
@@ -46,6 +119,10 @@ export function planStep(step) {
46
119
  return { run: "refused", reason: `a manual step for ${step.object} (${step.name}): no statement and no Op makes it; ${step.detail}` };
47
120
  const backfill = asBackfill(step);
48
121
  if (backfill) {
122
+ if (isRecord(backfill.options) && !("file" in backfill.options)) {
123
+ const form = asForm(backfill.options);
124
+ return form ? { run: "backfill", form } : { run: "refused", reason: `a backfill step whose form is not one yodel runs: ${formProblems(backfill.options).join("; ")}` };
125
+ }
49
126
  const file = backfillFile(backfill.options);
50
127
  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
128
  }
@@ -65,20 +142,15 @@ export function planStep(step) {
65
142
  if (dw.mode !== "materialized-view" || typeof dw.cutoverColumn !== "string") {
66
143
  return { run: "refused", reason: `${REBUILD_OP} for ${step.object} (${step.name}): dualWrite ${JSON.stringify(dw)} is not one yodel apply runs` };
67
144
  }
68
- return { run: "rebuild", options: { name: o.name, table: o.table, dualWrite: dw } };
145
+ const retain = optional(o, "retain", isString);
146
+ if (retain === null)
147
+ return { run: "refused", reason: `${REBUILD_OP} for ${step.object} (${step.name}): options.retain is ${JSON.stringify(o.retain)}, which is not a duration` };
148
+ return { run: "rebuild", options: { name: o.name, table: o.table, dualWrite: dw, ...(retain ? { retain } : {}) } };
69
149
  }
70
150
  if (step.op === PG_MIGRATION_OP)
71
151
  return planPgMigration(step);
72
152
  return { run: "refused", reason: `${step.op} for ${step.object} (${step.name}), not SQL: yodel apply does not run that Op` };
73
153
  }
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
154
  const isLag = (v) => v === false || (isRecord(v) && Object.values(v).every((x) => typeof x === "string"));
83
155
  function planPgMigration(step) {
84
156
  const o = step.options;
@@ -117,8 +189,10 @@ export function describeStep(step) {
117
189
  if (step.kind === "manual")
118
190
  return `manual step for ${step.object} (${step.name})`;
119
191
  const backfill = asBackfill(step);
120
- if (backfill)
121
- return `backfill ${backfill.options.file}`;
192
+ if (backfill) {
193
+ const form = asForm(backfill.options);
194
+ return form ? `backfill of ${describeForm(form)}` : `backfill ${"file" in backfill.options ? backfill.options.file : "(a form yodel does not run)"}`;
195
+ }
122
196
  return `${step.op} for ${step.object} (${step.name})`;
123
197
  }
124
198
  /**
@@ -133,7 +207,7 @@ export function stepSha(step, files) {
133
207
  return `sha256:${hash.update(step.sql, "utf8").digest("hex")}`;
134
208
  hash.update(JSON.stringify(sortKeys(step)), "utf8");
135
209
  const backfill = asBackfill(step);
136
- if (backfill) {
210
+ if (backfill && "file" in backfill.options) {
137
211
  const file = backfill.options.file;
138
212
  const text = files?.extra?.[file];
139
213
  hash.update(`\n${file} ${text === undefined ? "missing" : String(Buffer.byteLength(normalizeLineEndings(text), "utf8"))}\n${normalizeLineEndings(text ?? "")}`, "utf8");