@intentius/chant-lexicon-sql 0.124.31 → 0.124.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/change-set.js +250 -0
- package/dist/clickhouse/access.js +722 -0
- package/dist/clickhouse/apply/apply.js +243 -0
- package/dist/clickhouse/apply/mutations.js +66 -0
- package/dist/clickhouse/apply/statements.js +545 -0
- package/dist/clickhouse/catalog-types.js +7 -0
- package/dist/clickhouse/container.js +152 -0
- package/dist/clickhouse/engine-syntax.js +159 -0
- package/dist/clickhouse/entities.js +593 -0
- package/dist/clickhouse/expressions.js +107 -0
- package/dist/clickhouse/http.js +55 -0
- package/dist/clickhouse/import/generator.js +192 -0
- package/dist/clickhouse/import/inlined.js +207 -0
- package/dist/clickhouse/import/ir.js +160 -0
- package/dist/clickhouse/import/live-export.js +131 -0
- package/dist/clickhouse/import/parser.js +17 -0
- package/dist/clickhouse/live/bind.js +116 -0
- package/dist/clickhouse/live/catalog.js +223 -0
- package/dist/clickhouse/live/describe-resources.js +91 -0
- package/dist/clickhouse/live/undeclarable.js +59 -0
- package/dist/clickhouse/overlays/codecs.js +57 -0
- package/dist/clickhouse/overlays/engines.js +101 -0
- package/dist/clickhouse/overlays/kinds.js +1 -0
- package/dist/clickhouse/overlays/projections.js +26 -0
- package/dist/clickhouse/overlays/skip-indexes.js +40 -0
- package/dist/clickhouse/overlays/ttl.js +34 -0
- package/dist/clickhouse/overlays/types.js +59 -0
- package/dist/clickhouse/ownership.js +83 -0
- package/dist/clickhouse/parser.js +674 -0
- package/dist/clickhouse/plan/commands.js +159 -0
- package/dist/clickhouse/plan/deep.js +345 -0
- package/dist/clickhouse/plan/diff.js +312 -0
- package/dist/clickhouse/plan/disruption.js +73 -0
- package/dist/clickhouse/plan/normalize.js +545 -0
- package/dist/clickhouse/plan/rebuild-handoff.js +57 -0
- package/dist/clickhouse/plan/report.js +26 -0
- package/dist/clickhouse/plan/rules.js +72 -0
- package/dist/clickhouse/plan/schema.js +67 -0
- package/dist/clickhouse/plan/server-format.js +35 -0
- package/dist/clickhouse/rebuild/backfill.js +265 -0
- package/dist/clickhouse/rebuild/engines.js +146 -0
- package/dist/clickhouse/rebuild/observe.js +260 -0
- package/dist/clickhouse/rebuild/op.js +152 -0
- package/dist/clickhouse/rebuild/partitions.js +65 -0
- package/dist/clickhouse/rebuild/receipts.js +120 -0
- package/dist/clickhouse/rebuild/replicas.js +121 -0
- package/dist/clickhouse/rebuild/shards.js +76 -0
- package/dist/clickhouse/rebuild/steps.js +383 -0
- package/dist/clickhouse/rebuild/verify.js +279 -0
- package/dist/clickhouse/row-types.js +151 -0
- package/dist/clickhouse/testing/fake-server.js +47 -0
- package/dist/clickhouse/testing/roundtrip-schema.js +25 -0
- package/dist/clickhouse/testing/writable-server.js +123 -0
- package/dist/clickhouse/tokens.js +23 -0
- package/dist/clickhouse/topology.js +463 -0
- package/dist/clickhouse/type-syntax.js +73 -0
- package/dist/clickhouse.js +25 -0
- package/dist/codegen/classifier-page.js +93 -0
- package/dist/codegen/clickhouse-module.js +249 -0
- package/dist/codegen/coverage-page.js +70 -0
- package/dist/codegen/docs-cli.js +3 -0
- package/dist/codegen/docs.js +222 -0
- package/dist/codegen/generate-cli.js +13 -0
- package/dist/codegen/generate.js +97 -0
- package/dist/codegen/package.js +28 -0
- package/dist/codegen/postgres-classifier-page.js +95 -0
- package/dist/codegen/postgres-module.js +418 -0
- package/dist/codegen/registry.js +52 -0
- package/dist/composites/audit-log-table.js +35 -0
- package/dist/composites/catalog.js +524 -0
- package/dist/composites/cdc-mirror.js +32 -0
- package/dist/composites/clickhouse.js +6 -0
- package/dist/composites/events-table.js +26 -0
- package/dist/composites/index.js +8 -0
- package/dist/composites/join-table.js +25 -0
- package/dist/composites/postgres.js +6 -0
- package/dist/composites/refreshed-view.js +24 -0
- package/dist/composites/replacing-table.js +28 -0
- package/dist/composites/rollup-view.js +29 -0
- package/dist/composites/sharded-table.js +27 -0
- package/dist/composites/soft-delete-table.js +34 -0
- package/dist/composites/tenant-table.js +26 -0
- package/dist/composites/typed.js +8 -0
- package/dist/config.js +206 -0
- package/dist/core/apply.js +93 -0
- package/dist/core/classifier.js +115 -0
- package/dist/core/container.js +69 -0
- package/dist/core/cursor.js +261 -0
- package/dist/core/diff.js +48 -0
- package/dist/core/entity.js +58 -0
- package/dist/core/find-templates.js +118 -0
- package/dist/core/foreign-tables.js +27 -0
- package/dist/core/handoff.js +32 -0
- package/dist/core/index.js +64 -0
- package/dist/core/interpolation.js +191 -0
- package/dist/core/normalize.js +43 -0
- package/dist/core/ownership.js +119 -0
- package/dist/core/receipts.js +22 -0
- package/dist/core/references.js +61 -0
- package/dist/core/statements.js +42 -0
- package/dist/core/template.js +79 -0
- package/dist/core/testing/http-stub.js +21 -0
- package/dist/core/tokens.js +202 -0
- package/dist/core/typed.js +40 -0
- package/dist/core/undeclarable.js +46 -0
- package/dist/coverage.js +161 -0
- package/dist/detect.js +32 -0
- package/dist/dialects.js +18 -0
- package/dist/files/build-root.js +72 -0
- package/dist/files/clickhouse.js +138 -0
- package/dist/files/common.js +58 -0
- package/dist/files/postgres.js +389 -0
- package/dist/generated/clickhouse-types.js +5 -0
- package/dist/generated/clickhouse.js +4361 -0
- package/dist/generated/postgres-types.js +227 -0
- package/dist/generated/postgres.js +3667 -0
- package/dist/import-generator.js +14 -0
- package/dist/import-parser.js +71 -0
- package/dist/index.js +24 -0
- package/dist/init-templates.js +290 -0
- package/dist/integrity.json +2 -2
- package/dist/lint/audit-catalog.js +31 -0
- package/dist/lint/audit-lineage.js +22 -0
- package/dist/lint/post-synth/audit-entries.js +34 -0
- package/dist/lint/post-synth/clickhouse-helpers.js +79 -0
- package/dist/lint/post-synth/clickhouse-type-check.js +162 -0
- package/dist/lint/post-synth/index.js +112 -0
- package/dist/lint/post-synth/postgres-audit-entries.js +35 -0
- package/dist/lint/post-synth/postgres-helpers.js +65 -0
- package/dist/lint/post-synth/postgres-names.js +507 -0
- package/dist/lint/post-synth/sql-helpers.js +23 -0
- package/dist/lint/post-synth/sql101.js +59 -0
- package/dist/lint/post-synth/sql102.js +34 -0
- package/dist/lint/post-synth/sqlch101.js +34 -0
- package/dist/lint/post-synth/sqlch102.js +23 -0
- package/dist/lint/post-synth/sqlch103.js +45 -0
- package/dist/lint/post-synth/sqlch104.js +41 -0
- package/dist/lint/post-synth/sqlch105.js +36 -0
- package/dist/lint/post-synth/sqlch106.js +27 -0
- package/dist/lint/post-synth/sqlch107.js +39 -0
- package/dist/lint/post-synth/sqlch108.js +28 -0
- package/dist/lint/post-synth/sqlch109.js +21 -0
- package/dist/lint/post-synth/sqlch110.js +31 -0
- package/dist/lint/post-synth/sqlch111.js +41 -0
- package/dist/lint/post-synth/sqlch112.js +28 -0
- package/dist/lint/post-synth/sqlch113.js +19 -0
- package/dist/lint/post-synth/sqlch114.js +26 -0
- package/dist/lint/post-synth/sqlch115.js +30 -0
- package/dist/lint/post-synth/sqlch116.js +22 -0
- package/dist/lint/post-synth/sqlch117.js +26 -0
- package/dist/lint/post-synth/sqlch118.js +27 -0
- package/dist/lint/post-synth/sqlch119.js +32 -0
- package/dist/lint/post-synth/sqlch120.js +20 -0
- package/dist/lint/post-synth/sqlch121.js +11 -0
- package/dist/lint/post-synth/sqlch122.js +11 -0
- package/dist/lint/post-synth/sqlch123.js +10 -0
- package/dist/lint/post-synth/sqlch124.js +21 -0
- package/dist/lint/post-synth/sqlch125.js +55 -0
- package/dist/lint/post-synth/sqlch126.js +62 -0
- package/dist/lint/post-synth/sqlch127.js +132 -0
- package/dist/lint/post-synth/sqlpg101.js +25 -0
- package/dist/lint/post-synth/sqlpg102.js +35 -0
- package/dist/lint/post-synth/sqlpg103.js +23 -0
- package/dist/lint/post-synth/sqlpg104.js +23 -0
- package/dist/lint/post-synth/sqlpg105.js +22 -0
- package/dist/lint/post-synth/sqlpg106.js +22 -0
- package/dist/lint/post-synth/sqlpg107.js +22 -0
- package/dist/lint/post-synth/sqlpg108.js +28 -0
- package/dist/lint/post-synth/sqlpg109.js +39 -0
- package/dist/lint/post-synth/sqlpg110.js +38 -0
- package/dist/lint/post-synth/sqlpg111.js +23 -0
- package/dist/lint/post-synth/sqlpg112.js +25 -0
- package/dist/lint/post-synth/sqlpg113.js +29 -0
- package/dist/lint/post-synth/sqlpg114.js +39 -0
- package/dist/lint/post-synth/sqlpg115.js +48 -0
- package/dist/lint/post-synth/sqlpg116.js +26 -0
- package/dist/lint/post-synth/sqlpg117.js +24 -0
- package/dist/lint/post-synth/sqlpg118.js +22 -0
- package/dist/lint/post-synth/sqlpg119.js +41 -0
- package/dist/lint/post-synth/sqlpg120.js +83 -0
- package/dist/lint/post-synth/sqlpg121.js +33 -0
- package/dist/lint/post-synth/sqlpg122.js +27 -0
- package/dist/lint/post-synth/sqlpg123.js +69 -0
- package/dist/lint/post-synth/sqlpg124.js +50 -0
- package/dist/lint/post-synth/sqlpg125.js +41 -0
- package/dist/lint/post-synth/sqlpg126.js +38 -0
- package/dist/lint/rules/index.js +12 -0
- package/dist/lint/rules/postgres-templates.js +27 -0
- package/dist/lint/rules/sqlch001.js +79 -0
- package/dist/lint/rules/sqlch002.js +124 -0
- package/dist/lint/rules/sqlch003.js +69 -0
- package/dist/lint/rules/sqlch004.js +83 -0
- package/dist/lint/rules/sqlpg001.js +68 -0
- package/dist/lint/rules/sqlpg002.js +69 -0
- package/dist/lint/rules/sqlpg003.js +58 -0
- package/dist/lint/rules/sqlpg004.js +77 -0
- package/dist/lint/rules/sqlpg005.js +86 -0
- package/dist/lint/rules/templates.js +25 -0
- package/dist/lint/rules/typed-names.js +132 -0
- package/dist/live-dialect.js +32 -0
- package/dist/lsp/catalog.js +44 -0
- package/dist/lsp/completions.js +136 -0
- package/dist/lsp/hover.js +115 -0
- package/dist/lsp/postgres-catalog.js +176 -0
- package/dist/lsp/postgres-template.js +171 -0
- package/dist/lsp/postgres.js +266 -0
- package/dist/lsp/refs.js +60 -0
- package/dist/lsp/registry.d.ts.map +1 -1
- package/dist/lsp/registry.js +19 -0
- package/dist/lsp/template.js +143 -0
- package/dist/manifest.json +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +293 -0
- package/dist/mcp/postgres.js +117 -0
- package/dist/migration-statements.js +243 -0
- package/dist/op/activities/clickhouse-apply.js +83 -0
- package/dist/op/activities/clickhouse-emulator.js +53 -0
- package/dist/op/activities/clickhouse-rebuild.js +119 -0
- package/dist/op/activities/index.js +26 -0
- package/dist/op/activities/postgres-apply.js +126 -0
- package/dist/op/activities/postgres-emulator.js +70 -0
- package/dist/op/activities/postgres-migration.js +156 -0
- package/dist/op/activities/sql-exec.js +57 -0
- package/dist/op/activity-contracts.js +103 -0
- package/dist/package-cli.js +14 -0
- package/dist/plugin.js +259 -0
- package/dist/postgres/access/acl.js +344 -0
- package/dist/postgres/access/changes.js +30 -0
- package/dist/postgres/access/import.js +61 -0
- package/dist/postgres/access/live.js +96 -0
- package/dist/postgres/apply/apply.js +557 -0
- package/dist/postgres/apply/statements.js +882 -0
- package/dist/postgres/catalog-types.js +18 -0
- package/dist/postgres/container.js +58 -0
- package/dist/postgres/entities.js +1390 -0
- package/dist/postgres/entity-types.js +28 -0
- package/dist/postgres/import/generator.js +283 -0
- package/dist/postgres/import/ir.js +53 -0
- package/dist/postgres/import/live-export.js +83 -0
- package/dist/postgres/keywords.js +32 -0
- package/dist/postgres/live/bind.js +130 -0
- package/dist/postgres/live/catalog-kinds.js +301 -0
- package/dist/postgres/live/catalog.js +644 -0
- package/dist/postgres/live/client.js +151 -0
- package/dist/postgres/live/describe-resources.js +135 -0
- package/dist/postgres/live/undeclarable.js +111 -0
- package/dist/postgres/migrate/backfill.js +170 -0
- package/dist/postgres/migrate/batches.js +122 -0
- package/dist/postgres/migrate/carry.js +518 -0
- package/dist/postgres/migrate/handoff.js +59 -0
- package/dist/postgres/migrate/names.js +61 -0
- package/dist/postgres/migrate/observe.js +360 -0
- package/dist/postgres/migrate/op.js +178 -0
- package/dist/postgres/migrate/receipts.js +117 -0
- package/dist/postgres/migrate/replication.js +106 -0
- package/dist/postgres/migrate/steps.js +514 -0
- package/dist/postgres/overlays/columns.js +31 -0
- package/dist/postgres/overlays/constraints.js +52 -0
- package/dist/postgres/overlays/extension-objects.js +88 -0
- package/dist/postgres/overlays/indexes.js +25 -0
- package/dist/postgres/overlays/kinds.js +2 -0
- package/dist/postgres/overlays/partitioning.js +23 -0
- package/dist/postgres/overlays/relations.js +25 -0
- package/dist/postgres/overlays/storage.js +65 -0
- package/dist/postgres/overlays/type-ddl.js +36 -0
- package/dist/postgres/overlays/types.js +74 -0
- package/dist/postgres/parser.js +1824 -0
- package/dist/postgres/plan/commands.js +137 -0
- package/dist/postgres/plan/deep.js +324 -0
- package/dist/postgres/plan/diff.js +499 -0
- package/dist/postgres/plan/disruption.js +64 -0
- package/dist/postgres/plan/normalize.js +889 -0
- package/dist/postgres/plan/report.js +21 -0
- package/dist/postgres/plan/rules.js +115 -0
- package/dist/postgres/plan/schema.js +105 -0
- package/dist/postgres/plan/server-normalize.js +166 -0
- package/dist/postgres/providers/aurora.js +44 -0
- package/dist/postgres/providers/azure.js +53 -0
- package/dist/postgres/providers/cloud-sql.js +41 -0
- package/dist/postgres/providers/index.js +73 -0
- package/dist/postgres/providers/neon.js +44 -0
- package/dist/postgres/providers/rds.js +47 -0
- package/dist/postgres/providers/supabase.js +45 -0
- package/dist/postgres/providers/types.js +21 -0
- package/dist/postgres/row-types.js +107 -0
- package/dist/postgres/testing/fake-client.js +34 -0
- package/dist/postgres/testing/migration.js +48 -0
- package/dist/postgres/testing/roundtrip-schema.js +64 -0
- package/dist/postgres/testing/server.js +47 -0
- package/dist/postgres/testing/writable-server.js +160 -0
- package/dist/postgres/tokens.js +41 -0
- package/dist/postgres.js +15 -0
- package/dist/read/clickhouse.js +82 -0
- package/dist/read/objects.js +44 -0
- package/dist/read/postgres.js +104 -0
- package/dist/read.js +52 -0
- package/dist/receipts.js +207 -0
- package/dist/serializer.js +172 -0
- package/dist/skill-defs.js +93 -0
- package/dist/spec/catalog.js +191 -0
- package/dist/spec/fetch.d.ts.map +1 -1
- package/dist/spec/fetch.js +90 -0
- package/dist/spec/pin.js +42 -0
- package/dist/spec/postgres-catalog.js +171 -0
- package/dist/spec/postgres-fetch.js +91 -0
- package/dist/spec/postgres-pin.js +82 -0
- package/dist/sql-files.js +206 -0
- package/dist/sql-types-command.js +97 -0
- package/dist/sql-types.js +323 -0
- package/dist/token-source.js +156 -0
- package/dist/validate-cli.js +5 -0
- package/dist/validate.js +151 -0
- package/dist/workspace-outputs.js +191 -0
- package/package.json +7 -7
- package/src/codegen/package.ts +2 -2
- package/src/lint/rules/typescript-7.test.ts +2 -1
- package/src/lsp/catalog.ts +2 -2
- package/src/lsp/postgres-catalog.ts +2 -2
- package/src/lsp/registry.ts +2 -1
- package/src/mcp/index.ts +4 -2
- package/src/spec/fetch.ts +2 -2
- package/src/spec/postgres-fetch.ts +2 -2
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sql lexicon's Postgres emulator capability (#3280): the official
|
|
3
|
+
* `postgres` image at the newest pin, by tag and digest (../../spec/postgres-pin.ts),
|
|
4
|
+
* the same server generation and the live tests run, so `chant emulator up`
|
|
5
|
+
* boots a real Postgres rather than a stand-in.
|
|
6
|
+
*
|
|
7
|
+
* Postgres has no HTTP health endpoint, so readiness is `pg_isready` run in
|
|
8
|
+
* the container against 127.0.0.1: the image's first, initdb-time server
|
|
9
|
+
* listens on its socket only, so the TCP check answers once the real server
|
|
10
|
+
* is up. The endpoint is a `postgres://` URL, which `POSTGRES_URL` carries;
|
|
11
|
+
* the user and password are `POSTGRES_USER` and `POSTGRES_PASSWORD`, the
|
|
12
|
+
* variables binding reads with it.
|
|
13
|
+
*
|
|
14
|
+
* `upstream` is left off: the pins move per major through the lexicon's
|
|
15
|
+
* `upstreamPins`, not the emulator freshness check.
|
|
16
|
+
*/
|
|
17
|
+
import { emulatorLifecycle } from "@intentius/chant/op";
|
|
18
|
+
import { POSTGRES_LATEST_MAJOR, postgresImage } from "../../spec/postgres-pin.js";
|
|
19
|
+
import { connectPostgres } from "../../postgres/live/client.js";
|
|
20
|
+
/** The local server's password. It is a throwaway server on localhost. */
|
|
21
|
+
export const POSTGRES_EMULATOR_PASSWORD = "chant";
|
|
22
|
+
/** How long `chant emulator status` waits for the server behind the endpoint. */
|
|
23
|
+
const PROBE_TIMEOUT_MS = 5000;
|
|
24
|
+
/**
|
|
25
|
+
* The cluster's system identifier, unique per `initdb` (#3673): read in the
|
|
26
|
+
* container over its socket, and through the endpoint `status` prints. A
|
|
27
|
+
* native Postgres holding 127.0.0.1:5432 answers with its own, or refuses
|
|
28
|
+
* the emulator's sign-in.
|
|
29
|
+
*/
|
|
30
|
+
export const POSTGRES_EMULATOR_IDENTITY = {
|
|
31
|
+
server: "Postgres",
|
|
32
|
+
command: ["psql", "-U", "postgres", "-tAc", "select system_identifier from pg_control_system()"],
|
|
33
|
+
async probe(endpoint) {
|
|
34
|
+
const client = await withTimeout(connectPostgres({ url: endpoint, user: "postgres", password: POSTGRES_EMULATOR_PASSWORD }, { applicationName: "chant emulator status" }));
|
|
35
|
+
try {
|
|
36
|
+
const [row] = await withTimeout(client.query("SELECT system_identifier::text AS id, pg_catalog.current_setting('server_version') AS version FROM pg_catalog.pg_control_system()"));
|
|
37
|
+
return { id: row?.id ?? "", label: `PostgreSQL ${row?.version ?? "(unknown version)"}` };
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await client.end();
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
function withTimeout(promise) {
|
|
45
|
+
let timer;
|
|
46
|
+
const timeout = new Promise((_, reject) => {
|
|
47
|
+
timer = setTimeout(() => reject(new Error(`no answer within ${PROBE_TIMEOUT_MS / 1000}s`)), PROBE_TIMEOUT_MS);
|
|
48
|
+
});
|
|
49
|
+
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
50
|
+
}
|
|
51
|
+
export const POSTGRES_EMULATOR_SPEC = {
|
|
52
|
+
name: "chant-postgres",
|
|
53
|
+
image: postgresImage(POSTGRES_LATEST_MAJOR),
|
|
54
|
+
containerPort: 5432,
|
|
55
|
+
readyCommand: ["pg_isready", "-h", "127.0.0.1", "-U", "postgres"],
|
|
56
|
+
endpoint: (port) => `postgres://localhost:${port}/postgres`,
|
|
57
|
+
runArgs: ["-e", `POSTGRES_PASSWORD=${POSTGRES_EMULATOR_PASSWORD}`],
|
|
58
|
+
identity: POSTGRES_EMULATOR_IDENTITY,
|
|
59
|
+
credentials: `user postgres, password ${POSTGRES_EMULATOR_PASSWORD}`,
|
|
60
|
+
};
|
|
61
|
+
/** `POSTGRES_URL` is the variable binding reads when no `sql.profiles.<env>` names a server. */
|
|
62
|
+
export const POSTGRES_EMULATOR = {
|
|
63
|
+
spec: POSTGRES_EMULATOR_SPEC,
|
|
64
|
+
env: (endpoint) => ({ POSTGRES_URL: endpoint, POSTGRES_USER: "postgres", POSTGRES_PASSWORD: POSTGRES_EMULATOR_PASSWORD }),
|
|
65
|
+
};
|
|
66
|
+
const lifecycle = emulatorLifecycle(POSTGRES_EMULATOR_SPEC);
|
|
67
|
+
/** Boot the pinned Postgres server in Docker and return its endpoint. */
|
|
68
|
+
export const postgresUp = (args = {}, signal) => lifecycle.up(args, signal);
|
|
69
|
+
/** Stop and remove it (a no-op when it is gone). */
|
|
70
|
+
export const postgresDown = (args = {}, signal) => lifecycle.down(args, signal);
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The expand-and-contract migration's activities (#3281), one per step of
|
|
3
|
+
* `PostgresMigrationOp` (`../../postgres/migrate/op.ts`). Each takes the same
|
|
4
|
+
* arguments, reads the build's declaration of the table and binds the
|
|
5
|
+
* environment's server the way the applier does (`./postgres-apply.ts`),
|
|
6
|
+
* opens one connection with node-postgres (loaded only now), runs its step
|
|
7
|
+
* (`../../postgres/migrate/`), which re-reads the server, and closes the
|
|
8
|
+
* connection.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { resolve } from "node:path";
|
|
12
|
+
import { currentOpRun, parseDuration } from "@intentius/chant/op";
|
|
13
|
+
import { resolveOwnershipMarker } from "../../core/apply.js";
|
|
14
|
+
import { resolveBoundTarget } from "../../postgres/live/bind.js";
|
|
15
|
+
import { connectPostgres } from "../../postgres/live/client.js";
|
|
16
|
+
import { DEFAULT_POSTGRES_APPLY_TIMEOUTS, declaredObjects } from "../../postgres/apply/apply.js";
|
|
17
|
+
import { PG_CLASSIFIER_RULES } from "../../postgres/plan/rules.js";
|
|
18
|
+
import { declaredTable, migrationPlanDigest, MigrationRefusal, observeMigration } from "../../postgres/migrate/observe.js";
|
|
19
|
+
import { backfill, MigrationVerificationError, verifyMigration } from "../../postgres/migrate/backfill.js";
|
|
20
|
+
import { carryOver, compensate, contract, expand, retainPlan, startDualWrite, switchColumns, } from "../../postgres/migrate/steps.js";
|
|
21
|
+
import { DEFAULT_REPLICATION_LAG } from "../../postgres/migrate/replication.js";
|
|
22
|
+
import { buildMajor } from "./postgres-apply.js";
|
|
23
|
+
import { statementChange } from "../../core/statements.js";
|
|
24
|
+
import { postgresMigrationPart } from "../../change-set.js";
|
|
25
|
+
async function loadConfig(cwd) {
|
|
26
|
+
try {
|
|
27
|
+
const { loadChantConfig } = await import("@intentius/chant/config");
|
|
28
|
+
return (await loadChantConfig(cwd)).config;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* With `onFailure: "keep"` (#3687) no onFailure drops what the expand added,
|
|
36
|
+
* so a step that fails says what a person does instead: a refusal or a
|
|
37
|
+
* failed verification would otherwise fail every run after it the same way.
|
|
38
|
+
*/
|
|
39
|
+
const ON_FAILURE_DROPS = "onFailure drops what the expand added, and the next run starts again.";
|
|
40
|
+
function noting(args, err) {
|
|
41
|
+
if (args.keepOnFailure && (err instanceof MigrationRefusal || err instanceof MigrationVerificationError)) {
|
|
42
|
+
const kept = `This migration keeps what the expand added on failure (onFailure: "keep"), so nothing drops it: ` +
|
|
43
|
+
`to start again from a new column, run the Op once with onFailure: "drop" (the default), whose onFailure drops it when this step fails again.`;
|
|
44
|
+
err.message = err.message.includes(ON_FAILURE_DROPS) ? err.message.replace(ON_FAILURE_DROPS, kept) : `${err.message.replace(/\.?$/, ".")} ${kept}`;
|
|
45
|
+
}
|
|
46
|
+
return err;
|
|
47
|
+
}
|
|
48
|
+
/** Bind the server, connect and read the declaration, run `body` with it, then close the connection. */
|
|
49
|
+
async function withRun(args, signal, deps, body) {
|
|
50
|
+
try {
|
|
51
|
+
return await bound(args, signal, deps, body);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw noting(args, err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function bound(args, signal, deps, body) {
|
|
58
|
+
const cwd = args.cwd ?? process.cwd();
|
|
59
|
+
const config = deps.config ?? (await loadConfig(cwd));
|
|
60
|
+
const marker = resolveOwnershipMarker(args, config, "PostgresMigrationOp");
|
|
61
|
+
const target = await resolveBoundTarget({ ...(args.environment !== undefined ? { environment: args.environment } : {}), config: config ?? {}, ...(deps.env ? { env: deps.env } : {}) });
|
|
62
|
+
const json = readFileSync(resolve(cwd, args.buildPath), "utf8");
|
|
63
|
+
const objects = declaredObjects(json, target.defaultSchema);
|
|
64
|
+
const declared = declaredTable(objects, args.table);
|
|
65
|
+
const major = buildMajor(json) ?? config?.sql?.postgresMajor;
|
|
66
|
+
const lag = args.replicationLag;
|
|
67
|
+
const client = await (deps.connect ?? ((e) => connectPostgres(e, { applicationName: "chant migration" })))(target.endpoint);
|
|
68
|
+
const runId = currentOpRun()?.runId;
|
|
69
|
+
try {
|
|
70
|
+
return await body({
|
|
71
|
+
client,
|
|
72
|
+
target,
|
|
73
|
+
declared,
|
|
74
|
+
objects,
|
|
75
|
+
column: args.column,
|
|
76
|
+
...(args.using !== undefined ? { using: args.using } : {}),
|
|
77
|
+
...(marker ? { marker } : {}),
|
|
78
|
+
...(major !== undefined ? { major } : {}),
|
|
79
|
+
batchSize: args.batchSize ?? 1000,
|
|
80
|
+
retainMs: parseDuration(args.retain ?? "7d"),
|
|
81
|
+
replicationLag: lag === false
|
|
82
|
+
? false
|
|
83
|
+
: {
|
|
84
|
+
maxLagMs: lag?.max !== undefined ? parseDuration(lag.max) : DEFAULT_REPLICATION_LAG.maxLagMs,
|
|
85
|
+
waitMs: lag?.wait !== undefined ? parseDuration(lag.wait) : DEFAULT_REPLICATION_LAG.waitMs,
|
|
86
|
+
},
|
|
87
|
+
lockTimeoutMs: args.lockTimeoutMs ?? target.timeouts?.lockTimeoutMs ?? DEFAULT_POSTGRES_APPLY_TIMEOUTS.lockTimeoutMs,
|
|
88
|
+
statementTimeoutMs: args.statementTimeoutMs ?? target.timeouts?.statementTimeoutMs ?? DEFAULT_POSTGRES_APPLY_TIMEOUTS.statementTimeoutMs,
|
|
89
|
+
log: deps.log ?? ((line) => console.log(line)),
|
|
90
|
+
...(signal ? { signal } : {}),
|
|
91
|
+
...(runId ? { runId } : {}),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await client.end();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Plan: classify the column's change against the server and say how far the migration has got. */
|
|
99
|
+
export async function postgresMigrationPlan(args, signal, deps = {}) {
|
|
100
|
+
return withRun(args, signal, deps, async (run) => {
|
|
101
|
+
const o = await observeMigration({
|
|
102
|
+
client: run.client,
|
|
103
|
+
target: run.target,
|
|
104
|
+
declared: run.declared,
|
|
105
|
+
...(run.objects ? { objects: run.objects } : {}),
|
|
106
|
+
column: run.column,
|
|
107
|
+
...(run.marker ? { marker: run.marker } : {}),
|
|
108
|
+
...(run.using !== undefined ? { using: run.using } : {}),
|
|
109
|
+
...(run.major !== undefined ? { major: run.major } : {}),
|
|
110
|
+
});
|
|
111
|
+
const n = o.names;
|
|
112
|
+
const changes = o.changes.map((c) => `${c.rule} ${c.field}${c.before !== undefined || c.after !== undefined ? `: ${c.before ?? "none"} -> ${c.after ?? "none"}` : ""}`);
|
|
113
|
+
const made = o.changes.filter((c) => c.rule === "SQLPG205" || c.rule === "SQLPG207" || c.rule === "SQLPG208").map((c) => `${c.rule} ${PG_CLASSIFIER_RULES[c.rule].title}`);
|
|
114
|
+
const summary = o.state === "migrate"
|
|
115
|
+
? `${n.key} needs expand and contract (${made.join("; ")}): ${n.change === "rename" ? `${n.source} renamed to ${n.column}` : `${n.column} as ${o.column.type}, computed as ${o.expression}`}, batched by ${o.batchKey}${o.newColumn ? `; ${n.newColumn} already added` : ""}`
|
|
116
|
+
: o.state === "switched"
|
|
117
|
+
? `${n.key} has been switched; the old column is kept as ${n.oldColumn}`
|
|
118
|
+
: `${n.key} holds its declaration; nothing to migrate`;
|
|
119
|
+
run.log(`-- ${summary}`);
|
|
120
|
+
for (const c of changes)
|
|
121
|
+
run.log(`-- ${c}`);
|
|
122
|
+
const classified = o.changes.map(statementChange);
|
|
123
|
+
const result = { state: o.state, migration: n.key, change: n.change, ...(o.state === "migrate" ? { planDigest: migrationPlanDigest(o) } : {}), changes, classified };
|
|
124
|
+
const part = postgresMigrationPart({ member: n.key, plan: result, ...(args.environment !== undefined ? { environment: args.environment } : {}) });
|
|
125
|
+
return { ...result, part, summary };
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
export async function postgresMigrationExpand(args, signal, deps = {}) {
|
|
129
|
+
return withRun(args, signal, deps, expand);
|
|
130
|
+
}
|
|
131
|
+
export async function postgresMigrationDualWrite(args, signal, deps = {}) {
|
|
132
|
+
return withRun(args, signal, deps, startDualWrite);
|
|
133
|
+
}
|
|
134
|
+
export async function postgresMigrationBackfill(args, signal, deps = {}) {
|
|
135
|
+
return withRun(args, signal, deps, (run) => backfill(run, deps.backfill));
|
|
136
|
+
}
|
|
137
|
+
/** Carry over: the indexes and constraints on the old column, made again on the new one. */
|
|
138
|
+
export async function postgresMigrationCarry(args, signal, deps = {}) {
|
|
139
|
+
return withRun(args, signal, deps, carryOver);
|
|
140
|
+
}
|
|
141
|
+
export async function postgresMigrationVerify(args, signal, deps = {}) {
|
|
142
|
+
return withRun(args, signal, deps, verifyMigration);
|
|
143
|
+
}
|
|
144
|
+
export async function postgresMigrationSwitch(args, signal, deps = {}) {
|
|
145
|
+
return withRun(args, signal, deps, switchColumns);
|
|
146
|
+
}
|
|
147
|
+
export async function postgresMigrationRetain(args, signal, deps = {}) {
|
|
148
|
+
return withRun(args, signal, deps, retainPlan);
|
|
149
|
+
}
|
|
150
|
+
export async function postgresMigrationContract(args, signal, deps = {}) {
|
|
151
|
+
return withRun(args, signal, deps, contract);
|
|
152
|
+
}
|
|
153
|
+
/** onFailure: drop what the expand added. */
|
|
154
|
+
export async function postgresMigrationCompensate(args, signal, deps = {}) {
|
|
155
|
+
return withRun(args, signal, deps, compensate);
|
|
156
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sqlExec` (#3657): run SQL on the environment's database server, the step
|
|
3
|
+
* an `effect()` batch of a sql project is made of.
|
|
4
|
+
*
|
|
5
|
+
* effect(EffectReceipt("country-202601", { effect: "country/202601", flavor: "existence" }), [
|
|
6
|
+
* activity("sqlExec", { sql: "ALTER TABLE shop.orders UPDATE country = 'NL' WHERE toYYYYMM(ts) = 202601" }, "atMostOnce"),
|
|
7
|
+
* ])
|
|
8
|
+
*
|
|
9
|
+
* The server is the one `effect()`'s receipts are kept on
|
|
10
|
+
* (`../../receipts.ts`): `sql.profiles.<env>` for the environment
|
|
11
|
+
* `chant run --env` sets, else `CLICKHOUSE_URL` or `POSTGRES_URL`. `environment`
|
|
12
|
+
* in the arguments names another. On Postgres the SQL runs on a connection of
|
|
13
|
+
* its own with the role's default `search_path`, as one implicit transaction;
|
|
14
|
+
* on ClickHouse, `settings` are sent with the query.
|
|
15
|
+
*/
|
|
16
|
+
import { clickhouseQuery } from "../../clickhouse/http.js";
|
|
17
|
+
import { bindClickHouse } from "../../clickhouse/live/bind.js";
|
|
18
|
+
import { resolveBoundTarget } from "../../postgres/live/bind.js";
|
|
19
|
+
import { connectPostgres } from "../../postgres/live/client.js";
|
|
20
|
+
import { environmentOf, receiptDialect } from "../../receipts.js";
|
|
21
|
+
async function loadConfig(cwd) {
|
|
22
|
+
try {
|
|
23
|
+
const { loadChantConfig } = await import("@intentius/chant/config");
|
|
24
|
+
return (await loadChantConfig(cwd)).config;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function sqlExec(args, signal, deps = {}) {
|
|
31
|
+
if (typeof args?.sql !== "string" || args.sql.trim() === "")
|
|
32
|
+
throw new Error('sqlExec: needs { sql: "<statement>" }');
|
|
33
|
+
signal?.throwIfAborted();
|
|
34
|
+
const env = deps.env ?? process.env;
|
|
35
|
+
const config = deps.config ?? (await loadConfig(args.cwd ?? process.cwd()));
|
|
36
|
+
const environment = environmentOf(args, config, env);
|
|
37
|
+
const log = deps.log ?? ((line) => console.log(line));
|
|
38
|
+
const where = environment !== undefined ? { environment } : {};
|
|
39
|
+
log(args.sql);
|
|
40
|
+
if (receiptDialect(config, environment, env) === "postgres") {
|
|
41
|
+
const target = await resolveBoundTarget({ ...where, config: config ?? {}, env });
|
|
42
|
+
const client = await connectPostgres(target.endpoint, { applicationName: "chant sqlExec" });
|
|
43
|
+
try {
|
|
44
|
+
// The catalog reader's empty search_path is not what a hand-written statement expects.
|
|
45
|
+
await client.query("RESET search_path");
|
|
46
|
+
const rows = await client.query(args.sql);
|
|
47
|
+
return { dialect: "postgres", source: target.source, rows: Array.isArray(rows) ? rows.length : 0 };
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await client.end();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const target = await bindClickHouse({ ...where, config: config ?? {}, env });
|
|
54
|
+
const settings = args.settings ? Object.fromEntries(Object.entries(args.settings).map(([k, v]) => [k, String(v)])) : undefined;
|
|
55
|
+
const rows = await clickhouseQuery(target.endpoint, args.sql, { ...(settings ? { settings } : {}), ...(signal ? { signal } : {}) });
|
|
56
|
+
return { dialect: "clickhouse", source: target.source, rows: rows.length };
|
|
57
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity contracts for the sql lexicon's own `op/activities` (chant #2101):
|
|
3
|
+
* the ClickHouse rebuild migration's steps (#3198) and the Postgres
|
|
4
|
+
* expand-and-contract migration's (#3281).
|
|
5
|
+
*
|
|
6
|
+
* `loadActivityContracts` imports this module at
|
|
7
|
+
* `@intentius/chant-lexicon-sql/op/activity-contracts` for every project that
|
|
8
|
+
* lists the sql lexicon, and core's OPS012 and OPS013 check every
|
|
9
|
+
* `ClickHouseRebuildOp` and `PostgresMigrationOp` step against it at
|
|
10
|
+
* `chant build`: the arguments, and the two references each Op makes into a
|
|
11
|
+
* step's return value, the verification's `planDigest` (the swap or switch
|
|
12
|
+
* gate) and the retention's `dropDigest` or `contractDigest` (the drop or
|
|
13
|
+
* contract gate). Arguments are `z.strictObject`, so a
|
|
14
|
+
* misspelled key fails the build instead of vanishing.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { activityContract } from "@intentius/chant/op";
|
|
18
|
+
const dualWrite = z.discriminatedUnion("mode", [
|
|
19
|
+
z.strictObject({ mode: z.literal("materialized-view"), cutoverColumn: z.string(), cutoverDelay: z.string().optional() }),
|
|
20
|
+
z.strictObject({ mode: z.literal("app") }),
|
|
21
|
+
]);
|
|
22
|
+
/** `ClickHouseRebuildArgs` (`../clickhouse/rebuild/op.ts`): the same for every step. */
|
|
23
|
+
const rebuildArgs = z.strictObject({
|
|
24
|
+
table: z.string(),
|
|
25
|
+
buildPath: z.string(),
|
|
26
|
+
environment: z.string().optional(),
|
|
27
|
+
dualWrite,
|
|
28
|
+
retain: z.string().optional(),
|
|
29
|
+
mutationTimeout: z.string().optional(),
|
|
30
|
+
replicaTimeout: z.string().optional(),
|
|
31
|
+
cutoverTimeout: z.string().optional(),
|
|
32
|
+
stack: z.string().optional(),
|
|
33
|
+
ownershipEnv: z.string().optional(),
|
|
34
|
+
cwd: z.string().optional(),
|
|
35
|
+
keepOnFailure: z.boolean().optional(),
|
|
36
|
+
});
|
|
37
|
+
const state = z.enum(["rebuild", "swapped", "done"]);
|
|
38
|
+
/** A plan step's structured changes and its change-set part (#3767), as `../change-set.ts` makes it. */
|
|
39
|
+
const classified = z.array(z.object({ rule: z.string(), class: z.string(), field: z.string() }).passthrough());
|
|
40
|
+
const part = z.object({ member: z.object({ member: z.string(), planner: z.literal("sql"), planDigest: z.string().nullable() }).passthrough(), entries: z.array(z.unknown()) });
|
|
41
|
+
const tableEntity = { entities: ["table"] };
|
|
42
|
+
export const clickhouseRebuildPlanContract = activityContract("clickhouseRebuildPlan", rebuildArgs, z.object({ state, table: z.string(), planDigest: z.string().optional(), changes: z.array(z.string()), classified, part, summary: z.string() }), tableEntity);
|
|
43
|
+
export const clickhouseRebuildCreateContract = activityContract("clickhouseRebuildCreate", rebuildArgs, z.object({ state, table: z.string(), created: z.boolean() }), tableEntity);
|
|
44
|
+
export const clickhouseRebuildDualWriteContract = activityContract("clickhouseRebuildDualWrite", rebuildArgs, z.object({ state, mode: z.enum(["materialized-view", "app"]), cutover: z.string().optional(), created: z.boolean() }), tableEntity);
|
|
45
|
+
export const clickhouseRebuildBackfillContract = activityContract("clickhouseRebuildBackfill", rebuildArgs, z.object({ state, partitions: z.number(), copied: z.number(), skipped: z.number(), cleared: z.number() }), tableEntity);
|
|
46
|
+
export const clickhouseRebuildVerifyContract = activityContract("clickhouseRebuildVerify", rebuildArgs, z.object({
|
|
47
|
+
state,
|
|
48
|
+
planDigest: z.string().optional(),
|
|
49
|
+
partitions: z.number(),
|
|
50
|
+
rows: z.number(),
|
|
51
|
+
summary: z.string(),
|
|
52
|
+
verification: z.array(z.object({ partition: z.string(), rows: z.number(), checksum: z.string() })),
|
|
53
|
+
}), tableEntity);
|
|
54
|
+
export const clickhouseRebuildSwapContract = activityContract("clickhouseRebuildSwap", rebuildArgs, z.object({ state, swapped: z.boolean(), dependents: z.array(z.string()), oldTable: z.string().optional(), retainUntil: z.string().optional() }), tableEntity);
|
|
55
|
+
export const clickhouseRebuildRetainContract = activityContract("clickhouseRebuildRetain", rebuildArgs, z.object({ state, oldTable: z.string().optional(), retainUntil: z.string().optional(), due: z.boolean(), dropDigest: z.string().optional() }), tableEntity);
|
|
56
|
+
export const clickhouseRebuildDropContract = activityContract("clickhouseRebuildDrop", rebuildArgs, z.object({ state, dropped: z.boolean(), oldTable: z.string().optional(), retainUntil: z.string().optional() }), tableEntity);
|
|
57
|
+
export const clickhouseRebuildCompensateContract = activityContract("clickhouseRebuildCompensate", rebuildArgs, z.object({ dropped: z.array(z.string()) }), tableEntity);
|
|
58
|
+
// ── PostgresMigrationOp (#3281) ────────────────────────────────────────
|
|
59
|
+
/** `PostgresMigrationArgs` (`../postgres/migrate/op.ts`): the same for every step. */
|
|
60
|
+
const migrationArgs = z.strictObject({
|
|
61
|
+
table: z.string(),
|
|
62
|
+
column: z.string(),
|
|
63
|
+
buildPath: z.string(),
|
|
64
|
+
environment: z.string().optional(),
|
|
65
|
+
using: z.string().optional(),
|
|
66
|
+
retain: z.string().optional(),
|
|
67
|
+
batchSize: z.number().int().positive().optional(),
|
|
68
|
+
replicationLag: z.union([z.literal(false), z.strictObject({ max: z.string().optional(), wait: z.string().optional() })]).optional(),
|
|
69
|
+
lockTimeoutMs: z.number().int().nonnegative().optional(),
|
|
70
|
+
statementTimeoutMs: z.number().int().nonnegative().optional(),
|
|
71
|
+
stack: z.string().optional(),
|
|
72
|
+
ownershipEnv: z.string().optional(),
|
|
73
|
+
cwd: z.string().optional(),
|
|
74
|
+
keepOnFailure: z.boolean().optional(),
|
|
75
|
+
});
|
|
76
|
+
const migrationState = z.enum(["migrate", "switched", "done"]);
|
|
77
|
+
export const postgresMigrationPlanContract = activityContract("postgresMigrationPlan", migrationArgs, z.object({ state: migrationState, migration: z.string(), change: z.enum(["rename", "type"]), planDigest: z.string().optional(), changes: z.array(z.string()), classified, part, summary: z.string() }), tableEntity);
|
|
78
|
+
export const postgresMigrationExpandContract = activityContract("postgresMigrationExpand", migrationArgs, z.object({ state: migrationState, column: z.string(), added: z.boolean() }), tableEntity);
|
|
79
|
+
export const postgresMigrationDualWriteContract = activityContract("postgresMigrationDualWrite", migrationArgs, z.object({ state: migrationState, trigger: z.string(), created: z.boolean() }), tableEntity);
|
|
80
|
+
export const postgresMigrationBackfillContract = activityContract("postgresMigrationBackfill", migrationArgs, z.object({ state: migrationState, batches: z.number(), filled: z.number(), skipped: z.number(), rows: z.number(), pausedMs: z.number() }), tableEntity);
|
|
81
|
+
export const postgresMigrationCarryContract = activityContract("postgresMigrationCarry", migrationArgs, z.object({ state: migrationState, built: z.number(), ready: z.number(), views: z.number(), carried: z.array(z.string()) }), tableEntity);
|
|
82
|
+
export const postgresMigrationVerifyContract = activityContract("postgresMigrationVerify", migrationArgs, z.object({
|
|
83
|
+
state: migrationState,
|
|
84
|
+
planDigest: z.string().optional(),
|
|
85
|
+
rows: z.number(),
|
|
86
|
+
mismatched: z.number(),
|
|
87
|
+
nulls: z.number(),
|
|
88
|
+
checksum: z.string(),
|
|
89
|
+
expected: z.string(),
|
|
90
|
+
summary: z.string(),
|
|
91
|
+
}), tableEntity);
|
|
92
|
+
export const postgresMigrationSwitchContract = activityContract("postgresMigrationSwitch", migrationArgs, z.object({ state: migrationState, switched: z.boolean(), oldColumn: z.string().optional(), retainUntil: z.string().optional() }), tableEntity);
|
|
93
|
+
export const postgresMigrationRetainContract = activityContract("postgresMigrationRetain", migrationArgs, z.object({ state: migrationState, oldColumn: z.string().optional(), retainUntil: z.string().optional(), due: z.boolean(), contractDigest: z.string().optional() }), tableEntity);
|
|
94
|
+
export const postgresMigrationContractContract = activityContract("postgresMigrationContract", migrationArgs, z.object({ state: migrationState, dropped: z.boolean(), oldColumn: z.string().optional(), retainUntil: z.string().optional() }), tableEntity);
|
|
95
|
+
export const postgresMigrationCompensateContract = activityContract("postgresMigrationCompensate", migrationArgs, z.object({ dropped: z.array(z.string()) }), tableEntity);
|
|
96
|
+
// ── effect() batches (#3657) ───────────────────────────────────────────
|
|
97
|
+
/** `SqlExecArgs` (`./activities/sql-exec.ts`): one batch's SQL on the environment's server. */
|
|
98
|
+
export const sqlExecContract = activityContract("sqlExec", z.strictObject({
|
|
99
|
+
sql: z.string().min(1),
|
|
100
|
+
environment: z.string().optional(),
|
|
101
|
+
settings: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
|
102
|
+
cwd: z.string().optional(),
|
|
103
|
+
}), z.object({ dialect: z.enum(["clickhouse", "postgres"]), source: z.string(), rows: z.number() }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Thin entry point for `npm run bundle` in lexicon-sql.
|
|
4
|
+
*/
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { writeBundleSpec } from "@intentius/chant/codegen/package";
|
|
8
|
+
import { generate, writeGeneratedFiles } from "./codegen/generate.js";
|
|
9
|
+
import { packageLexicon } from "./codegen/package.js";
|
|
10
|
+
const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
11
|
+
writeGeneratedFiles(await generate({ verbose: true }));
|
|
12
|
+
const { spec, stats } = await packageLexicon({ verbose: true });
|
|
13
|
+
writeBundleSpec(spec, join(pkgDir, "dist"));
|
|
14
|
+
console.error(`Packaged ${stats.ruleCount} rules, ${stats.skillCount} skills`);
|