@pgpmjs/transform 0.17.0 → 0.18.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.
- package/esm/semantic-diff-driver.js +45 -13
- package/package.json +2 -2
- package/semantic-diff-driver.d.ts +7 -4
- package/semantic-diff-driver.js +44 -12
|
@@ -16,15 +16,18 @@
|
|
|
16
16
|
* modified objects routed through the granularity pipeline
|
|
17
17
|
* (`restructureChanges`), so names come from the naming spec and `requires`
|
|
18
18
|
* from the statement graph — the same derivation every other projection uses.
|
|
19
|
-
* Every emitted change carries a full deploy/revert/verify triple:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* Every emitted change carries a full deploy/revert/verify triple: inverses
|
|
20
|
+
* and existence checks are composed at the AST level via `@pgsql/scripts`'
|
|
21
|
+
* node-level API (`invertStatement`/`existenceCheck`) — never hand-templated
|
|
22
|
+
* and never round-tripped through deparsed text — deparsing only once at the
|
|
23
|
+
* end. Statements the node layer cannot derive fall back to the text layer
|
|
24
|
+
* (`revertFor`/`verifyFor`) solely to surface its not-derivable comment and
|
|
25
|
+
* warning.
|
|
23
26
|
*
|
|
24
27
|
* Requires `loadModule()` from `plpgsql-parser` before use.
|
|
25
28
|
*/
|
|
26
29
|
import { pathFor } from '@pgpmjs/naming-spec';
|
|
27
|
-
import { revertFor, verifyFor } from '@pgsql/scripts';
|
|
30
|
+
import { existenceCheck, invertStatement, revertFor, verifyFor } from '@pgsql/scripts';
|
|
28
31
|
import { buildStatementGraph, classifyStatements, cleanTree, identityOf } from '@pgsql/transform';
|
|
29
32
|
import { Deparser, parseSync } from 'plpgsql-parser';
|
|
30
33
|
import { restructureChanges } from './granularity-driver';
|
|
@@ -252,17 +255,46 @@ export function diffSchemas(from, to, options = {}) {
|
|
|
252
255
|
const forwardSql = [];
|
|
253
256
|
const modifiedChanges = [];
|
|
254
257
|
const dropUnits = [];
|
|
255
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* `@pgsql/scripts` inverse of a deploy script (drops in reverse topo
|
|
260
|
+
* order), composed at the AST level via `invertStatement` and deparsed
|
|
261
|
+
* once. Underivable statements fall back to `revertFor` on the single
|
|
262
|
+
* statement to surface its not-derivable comment and warning.
|
|
263
|
+
*/
|
|
256
264
|
const inverseOf = (deploy, context) => {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
265
|
+
const facts = classifyStatements(deploy);
|
|
266
|
+
const graph = buildStatementGraph(facts);
|
|
267
|
+
const pieces = [];
|
|
268
|
+
for (const i of [...graph.order].reverse()) {
|
|
269
|
+
const nodes = invertStatement(facts[i]);
|
|
270
|
+
if (nodes === null) {
|
|
271
|
+
const { sql, warnings: w } = revertFor([facts[i]]);
|
|
272
|
+
warnings.push(...w.map(x => `${context}: ${x}`));
|
|
273
|
+
if (sql.trim())
|
|
274
|
+
pieces.push(sql);
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
pieces.push(...nodes.map(n => deparseStmt(n)));
|
|
278
|
+
}
|
|
279
|
+
return pieces.join('\n');
|
|
260
280
|
};
|
|
261
|
-
/**
|
|
281
|
+
/**
|
|
282
|
+
* `@pgsql/scripts` existence checks for a deploy script, composed from
|
|
283
|
+
* `existenceCheck`'s SelectStmt nodes and deparsed once. Underivable
|
|
284
|
+
* statements fall back to `verifyFor` to surface the warning.
|
|
285
|
+
*/
|
|
262
286
|
const verifyOf = (deploy, context) => {
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
287
|
+
const pieces = [];
|
|
288
|
+
for (const fact of classifyStatements(deploy)) {
|
|
289
|
+
const nodes = existenceCheck(fact);
|
|
290
|
+
if (nodes === null) {
|
|
291
|
+
const { warnings: w } = verifyFor([fact]);
|
|
292
|
+
warnings.push(...w.map(x => `${context}: ${x}`));
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
pieces.push(...nodes.map(n => deparseStmt(n)));
|
|
296
|
+
}
|
|
297
|
+
return pieces.join('\n\n');
|
|
266
298
|
};
|
|
267
299
|
for (const key of b.order) {
|
|
268
300
|
const unit = b.units.get(key);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgpmjs/transform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Change-aware SQL transformation for PGPM — superset of @pgsql/transform plus change categorization, fixture closure, and bundle transpile/apply drivers",
|
|
6
6
|
"main": "index.js",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"@pgsql/transform": "^18.11.0",
|
|
49
49
|
"plpgsql-parser": "^18.2.3"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "6d3e25dc5c9f93421dba49ddedf93239f87213a8"
|
|
52
52
|
}
|
|
@@ -16,10 +16,13 @@
|
|
|
16
16
|
* modified objects routed through the granularity pipeline
|
|
17
17
|
* (`restructureChanges`), so names come from the naming spec and `requires`
|
|
18
18
|
* from the statement graph — the same derivation every other projection uses.
|
|
19
|
-
* Every emitted change carries a full deploy/revert/verify triple:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* Every emitted change carries a full deploy/revert/verify triple: inverses
|
|
20
|
+
* and existence checks are composed at the AST level via `@pgsql/scripts`'
|
|
21
|
+
* node-level API (`invertStatement`/`existenceCheck`) — never hand-templated
|
|
22
|
+
* and never round-tripped through deparsed text — deparsing only once at the
|
|
23
|
+
* end. Statements the node layer cannot derive fall back to the text layer
|
|
24
|
+
* (`revertFor`/`verifyFor`) solely to surface its not-derivable comment and
|
|
25
|
+
* warning.
|
|
23
26
|
*
|
|
24
27
|
* Requires `loadModule()` from `plpgsql-parser` before use.
|
|
25
28
|
*/
|
package/semantic-diff-driver.js
CHANGED
|
@@ -20,10 +20,13 @@ exports.diffChangeSets = diffChangeSets;
|
|
|
20
20
|
* modified objects routed through the granularity pipeline
|
|
21
21
|
* (`restructureChanges`), so names come from the naming spec and `requires`
|
|
22
22
|
* from the statement graph — the same derivation every other projection uses.
|
|
23
|
-
* Every emitted change carries a full deploy/revert/verify triple:
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* Every emitted change carries a full deploy/revert/verify triple: inverses
|
|
24
|
+
* and existence checks are composed at the AST level via `@pgsql/scripts`'
|
|
25
|
+
* node-level API (`invertStatement`/`existenceCheck`) — never hand-templated
|
|
26
|
+
* and never round-tripped through deparsed text — deparsing only once at the
|
|
27
|
+
* end. Statements the node layer cannot derive fall back to the text layer
|
|
28
|
+
* (`revertFor`/`verifyFor`) solely to surface its not-derivable comment and
|
|
29
|
+
* warning.
|
|
27
30
|
*
|
|
28
31
|
* Requires `loadModule()` from `plpgsql-parser` before use.
|
|
29
32
|
*/
|
|
@@ -256,17 +259,46 @@ function diffSchemas(from, to, options = {}) {
|
|
|
256
259
|
const forwardSql = [];
|
|
257
260
|
const modifiedChanges = [];
|
|
258
261
|
const dropUnits = [];
|
|
259
|
-
/**
|
|
262
|
+
/**
|
|
263
|
+
* `@pgsql/scripts` inverse of a deploy script (drops in reverse topo
|
|
264
|
+
* order), composed at the AST level via `invertStatement` and deparsed
|
|
265
|
+
* once. Underivable statements fall back to `revertFor` on the single
|
|
266
|
+
* statement to surface its not-derivable comment and warning.
|
|
267
|
+
*/
|
|
260
268
|
const inverseOf = (deploy, context) => {
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
const facts = (0, transform_1.classifyStatements)(deploy);
|
|
270
|
+
const graph = (0, transform_1.buildStatementGraph)(facts);
|
|
271
|
+
const pieces = [];
|
|
272
|
+
for (const i of [...graph.order].reverse()) {
|
|
273
|
+
const nodes = (0, scripts_1.invertStatement)(facts[i]);
|
|
274
|
+
if (nodes === null) {
|
|
275
|
+
const { sql, warnings: w } = (0, scripts_1.revertFor)([facts[i]]);
|
|
276
|
+
warnings.push(...w.map(x => `${context}: ${x}`));
|
|
277
|
+
if (sql.trim())
|
|
278
|
+
pieces.push(sql);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
pieces.push(...nodes.map(n => deparseStmt(n)));
|
|
282
|
+
}
|
|
283
|
+
return pieces.join('\n');
|
|
264
284
|
};
|
|
265
|
-
/**
|
|
285
|
+
/**
|
|
286
|
+
* `@pgsql/scripts` existence checks for a deploy script, composed from
|
|
287
|
+
* `existenceCheck`'s SelectStmt nodes and deparsed once. Underivable
|
|
288
|
+
* statements fall back to `verifyFor` to surface the warning.
|
|
289
|
+
*/
|
|
266
290
|
const verifyOf = (deploy, context) => {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
291
|
+
const pieces = [];
|
|
292
|
+
for (const fact of (0, transform_1.classifyStatements)(deploy)) {
|
|
293
|
+
const nodes = (0, scripts_1.existenceCheck)(fact);
|
|
294
|
+
if (nodes === null) {
|
|
295
|
+
const { warnings: w } = (0, scripts_1.verifyFor)([fact]);
|
|
296
|
+
warnings.push(...w.map(x => `${context}: ${x}`));
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
pieces.push(...nodes.map(n => deparseStmt(n)));
|
|
300
|
+
}
|
|
301
|
+
return pieces.join('\n\n');
|
|
270
302
|
};
|
|
271
303
|
for (const key of b.order) {
|
|
272
304
|
const unit = b.units.get(key);
|