@antelopejs/postgres 0.2.2 → 0.2.3
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/README.md +6 -5
- package/dist/config.d.ts +1 -0
- package/dist/config.js +7 -3
- package/dist/config.js.map +1 -1
- package/dist/connect-failure.d.ts +1 -0
- package/dist/connect-failure.js +39 -0
- package/dist/connect-failure.js.map +1 -0
- package/dist/connection.d.ts +2 -1
- package/dist/connection.js +19 -2
- package/dist/connection.js.map +1 -1
- package/dist/implementations/catalog/index.js +3 -6
- package/dist/implementations/catalog/index.js.map +1 -1
- package/dist/implementations/database/coerce.js +20 -20
- package/dist/implementations/database/coerce.js.map +1 -1
- package/dist/implementations/database/context.d.ts +1 -0
- package/dist/implementations/database/context.js +4 -0
- package/dist/implementations/database/context.js.map +1 -1
- package/dist/implementations/database/convergence.d.ts +22 -0
- package/dist/implementations/database/convergence.js +183 -0
- package/dist/implementations/database/convergence.js.map +1 -0
- package/dist/implementations/database/cursors.js +3 -0
- package/dist/implementations/database/cursors.js.map +1 -1
- package/dist/implementations/database/ddl.d.ts +5 -26
- package/dist/implementations/database/ddl.js +15 -191
- package/dist/implementations/database/ddl.js.map +1 -1
- package/dist/implementations/database/external-column-profile.js +6 -1
- package/dist/implementations/database/external-column-profile.js.map +1 -1
- package/dist/implementations/database/external-discovery.js +5 -5
- package/dist/implementations/database/external-discovery.js.map +1 -1
- package/dist/implementations/database/external-measures.js.map +1 -1
- package/dist/implementations/database/external-payload.d.ts +2 -2
- package/dist/implementations/database/external-payload.js +23 -13
- package/dist/implementations/database/external-payload.js.map +1 -1
- package/dist/implementations/database/external-schema.d.ts +2 -2
- package/dist/implementations/database/external-schema.js +3 -3
- package/dist/implementations/database/external-schema.js.map +1 -1
- package/dist/implementations/database/external-types.js +23 -16
- package/dist/implementations/database/external-types.js.map +1 -1
- package/dist/implementations/database/external-writes.d.ts +7 -1
- package/dist/implementations/database/external-writes.js +22 -21
- package/dist/implementations/database/external-writes.js.map +1 -1
- package/dist/implementations/database/feed-pipeline.js +3 -2
- package/dist/implementations/database/feed-pipeline.js.map +1 -1
- package/dist/implementations/database/feeds.d.ts +1 -1
- package/dist/implementations/database/feeds.js +36 -45
- package/dist/implementations/database/feeds.js.map +1 -1
- package/dist/implementations/database/fields.d.ts +9 -13
- package/dist/implementations/database/fields.js +25 -21
- package/dist/implementations/database/fields.js.map +1 -1
- package/dist/implementations/database/guards.d.ts +5 -0
- package/dist/implementations/database/guards.js +23 -0
- package/dist/implementations/database/guards.js.map +1 -0
- package/dist/implementations/database/introspect.d.ts +1 -1
- package/dist/implementations/database/listener.js +9 -3
- package/dist/implementations/database/listener.js.map +1 -1
- package/dist/implementations/database/migrate.d.ts +2 -2
- package/dist/implementations/database/migrate.js +10 -10
- package/dist/implementations/database/migrate.js.map +1 -1
- package/dist/implementations/database/payload.d.ts +3 -3
- package/dist/implementations/database/payload.js +4 -4
- package/dist/implementations/database/pipeline.d.ts +6 -2
- package/dist/implementations/database/pipeline.js +4 -1
- package/dist/implementations/database/pipeline.js.map +1 -1
- package/dist/implementations/database/query.js +12 -7
- package/dist/implementations/database/query.js.map +1 -1
- package/dist/implementations/database/reaper.js +6 -4
- package/dist/implementations/database/reaper.js.map +1 -1
- package/dist/implementations/database/relation.d.ts +2 -12
- package/dist/implementations/database/relation.js +5 -141
- package/dist/implementations/database/relation.js.map +1 -1
- package/dist/implementations/database/render.d.ts +11 -0
- package/dist/implementations/database/render.js +147 -0
- package/dist/implementations/database/render.js.map +1 -0
- package/dist/implementations/database/result.d.ts +2 -2
- package/dist/implementations/database/result.js +18 -19
- package/dist/implementations/database/result.js.map +1 -1
- package/dist/implementations/database/row-source.d.ts +10 -10
- package/dist/implementations/database/row-source.js +22 -19
- package/dist/implementations/database/row-source.js.map +1 -1
- package/dist/implementations/database/schema.d.ts +2 -2
- package/dist/implementations/database/schema.js +19 -19
- package/dist/implementations/database/schema.js.map +1 -1
- package/dist/implementations/database/selection.js +13 -7
- package/dist/implementations/database/selection.js.map +1 -1
- package/dist/implementations/database/sql.d.ts +7 -3
- package/dist/implementations/database/sql.js.map +1 -1
- package/dist/implementations/database/stage.js +3 -2
- package/dist/implementations/database/stage.js.map +1 -1
- package/dist/implementations/database/stages-aggregate.js +7 -5
- package/dist/implementations/database/stages-aggregate.js.map +1 -1
- package/dist/implementations/database/stages-array.js.map +1 -1
- package/dist/implementations/database/stages-core.js +2 -1
- package/dist/implementations/database/stages-core.js.map +1 -1
- package/dist/implementations/database/stages-date.js +2 -1
- package/dist/implementations/database/stages-date.js.map +1 -1
- package/dist/implementations/database/stages-group.js +11 -6
- package/dist/implementations/database/stages-group.js.map +1 -1
- package/dist/implementations/database/stages-join.js +13 -11
- package/dist/implementations/database/stages-join.js.map +1 -1
- package/dist/implementations/database/stages-numeric.js.map +1 -1
- package/dist/implementations/database/stages-object.js +1 -1
- package/dist/implementations/database/stages-object.js.map +1 -1
- package/dist/implementations/database/stages-projection.js +9 -8
- package/dist/implementations/database/stages-projection.js.map +1 -1
- package/dist/implementations/database/stages-rows.js +10 -8
- package/dist/implementations/database/stages-rows.js.map +1 -1
- package/dist/implementations/database/stages-selection.js +6 -4
- package/dist/implementations/database/stages-selection.js.map +1 -1
- package/dist/implementations/database/stages-string.js +7 -6
- package/dist/implementations/database/stages-string.js.map +1 -1
- package/dist/implementations/database/subquery.d.ts +1 -1
- package/dist/implementations/database/subquery.js +7 -5
- package/dist/implementations/database/subquery.js.map +1 -1
- package/dist/implementations/database/types.d.ts +5 -5
- package/dist/implementations/database/types.js +11 -11
- package/dist/implementations/database/types.js.map +1 -1
- package/dist/implementations/database/utils.js +2 -1
- package/dist/implementations/database/utils.js.map +1 -1
- package/dist/implementations/database/value.d.ts +1 -1
- package/dist/implementations/database/value.js +34 -33
- package/dist/implementations/database/value.js.map +1 -1
- package/dist/implementations/database/writes-atomic.js +6 -5
- package/dist/implementations/database/writes-atomic.js.map +1 -1
- package/dist/implementations/database/writes-identity.js +18 -19
- package/dist/implementations/database/writes-identity.js.map +1 -1
- package/dist/implementations/database/writes-insert.js +16 -22
- package/dist/implementations/database/writes-insert.js.map +1 -1
- package/dist/implementations/database/writes-shared.d.ts +1 -1
- package/dist/implementations/database/writes-shared.js +11 -7
- package/dist/implementations/database/writes-shared.js.map +1 -1
- package/dist/implementations/database/writes.d.ts +22 -1
- package/dist/implementations/database/writes.js +6 -3
- package/dist/implementations/database/writes.js.map +1 -1
- package/dist/test/catalog-owned.test.js +2 -0
- package/dist/test/catalog-owned.test.js.map +1 -1
- package/dist/test/contention.test.js.map +1 -1
- package/dist/test/duplicate-key.test.js +13 -10
- package/dist/test/duplicate-key.test.js.map +1 -1
- package/dist/test/indexes.test.js +7 -7
- package/dist/test/indexes.test.js.map +1 -1
- package/dist/test/unit/coerce.spec.js +7 -7
- package/dist/test/unit/coerce.spec.js.map +1 -1
- package/dist/test/unit/config.spec.js +3 -1
- package/dist/test/unit/config.spec.js.map +1 -1
- package/dist/test/unit/connect-failure.spec.d.ts +1 -0
- package/dist/test/unit/connect-failure.spec.js +50 -0
- package/dist/test/unit/connect-failure.spec.js.map +1 -0
- package/dist/test/unit/connection.spec.js +16 -18
- package/dist/test/unit/connection.spec.js.map +1 -1
- package/dist/test/unit/convergence.spec.d.ts +1 -0
- package/dist/test/unit/convergence.spec.js +347 -0
- package/dist/test/unit/convergence.spec.js.map +1 -0
- package/dist/test/unit/cursors-fixture.d.ts +79 -0
- package/dist/test/unit/cursors-fixture.js +245 -0
- package/dist/test/unit/cursors-fixture.js.map +1 -0
- package/dist/test/unit/cursors.spec.js +138 -718
- package/dist/test/unit/cursors.spec.js.map +1 -1
- package/dist/test/unit/cursors.teardown.spec.d.ts +1 -0
- package/dist/test/unit/cursors.teardown.spec.js +322 -0
- package/dist/test/unit/cursors.teardown.spec.js.map +1 -0
- package/dist/test/unit/cursors.window.spec.d.ts +1 -0
- package/dist/test/unit/cursors.window.spec.js +78 -0
- package/dist/test/unit/cursors.window.spec.js.map +1 -0
- package/dist/test/unit/ddl-fixture.d.ts +5 -0
- package/dist/test/unit/ddl-fixture.js +19 -0
- package/dist/test/unit/ddl-fixture.js.map +1 -0
- package/dist/test/unit/ddl.spec.js +39 -380
- package/dist/test/unit/ddl.spec.js.map +1 -1
- package/dist/test/unit/expression-array-fixture.d.ts +17 -0
- package/dist/test/unit/expression-array-fixture.js +63 -0
- package/dist/test/unit/expression-array-fixture.js.map +1 -0
- package/dist/test/unit/expression-array-walk.spec.d.ts +1 -0
- package/dist/test/unit/expression-array-walk.spec.js +235 -0
- package/dist/test/unit/expression-array-walk.spec.js.map +1 -0
- package/dist/test/unit/expression-array.spec.js +48 -322
- package/dist/test/unit/expression-array.spec.js.map +1 -1
- package/dist/test/unit/expression-date.spec.js +4 -3
- package/dist/test/unit/expression-date.spec.js.map +1 -1
- package/dist/test/unit/expression-fixture.d.ts +15 -0
- package/dist/test/unit/expression-fixture.js +40 -0
- package/dist/test/unit/expression-fixture.js.map +1 -0
- package/dist/test/unit/expression-numeric.spec.js +10 -8
- package/dist/test/unit/expression-numeric.spec.js.map +1 -1
- package/dist/test/unit/expression-object.spec.js +3 -4
- package/dist/test/unit/expression-object.spec.js.map +1 -1
- package/dist/test/unit/expression-predicate.spec.d.ts +1 -0
- package/dist/test/unit/expression-predicate.spec.js +231 -0
- package/dist/test/unit/expression-predicate.spec.js.map +1 -0
- package/dist/test/unit/expression-stages.spec.js +0 -5
- package/dist/test/unit/expression-stages.spec.js.map +1 -1
- package/dist/test/unit/expression-string.spec.js +2 -5
- package/dist/test/unit/expression-string.spec.js.map +1 -1
- package/dist/test/unit/expression.spec.js +44 -292
- package/dist/test/unit/expression.spec.js.map +1 -1
- package/dist/test/unit/external-comparisons.spec.js +5 -5
- package/dist/test/unit/external-comparisons.spec.js.map +1 -1
- package/dist/test/unit/external-types.spec.js +2 -3
- package/dist/test/unit/external-types.spec.js.map +1 -1
- package/dist/test/unit/feeds.spec.js +40 -23
- package/dist/test/unit/feeds.spec.js.map +1 -1
- package/dist/test/unit/fields.spec.js +15 -9
- package/dist/test/unit/fields.spec.js.map +1 -1
- package/dist/test/unit/invalid-fixture.d.ts +3 -0
- package/dist/test/unit/invalid-fixture.js +11 -0
- package/dist/test/unit/invalid-fixture.js.map +1 -0
- package/dist/test/unit/payload.spec.js.map +1 -1
- package/dist/test/unit/pipeline-aggregate.spec.js +14 -14
- package/dist/test/unit/pipeline-aggregate.spec.js.map +1 -1
- package/dist/test/unit/pipeline-fixture.d.ts +25 -6
- package/dist/test/unit/pipeline-fixture.js +21 -11
- package/dist/test/unit/pipeline-fixture.js.map +1 -1
- package/dist/test/unit/pipeline-group-fixture.d.ts +2 -0
- package/dist/test/unit/pipeline-group-fixture.js +6 -0
- package/dist/test/unit/pipeline-group-fixture.js.map +1 -0
- package/dist/test/unit/pipeline-group.spec.js +15 -248
- package/dist/test/unit/pipeline-group.spec.js.map +1 -1
- package/dist/test/unit/pipeline-lookup.spec.js +13 -10
- package/dist/test/unit/pipeline-lookup.spec.js.map +1 -1
- package/dist/test/unit/pipeline-projection.spec.js +12 -13
- package/dist/test/unit/pipeline-projection.spec.js.map +1 -1
- package/dist/test/unit/pipeline-rows.spec.js +21 -18
- package/dist/test/unit/pipeline-rows.spec.js.map +1 -1
- package/dist/test/unit/pipeline-selection.spec.js +6 -4
- package/dist/test/unit/pipeline-selection.spec.js.map +1 -1
- package/dist/test/unit/pipeline-stages.spec.js +23 -35
- package/dist/test/unit/pipeline-stages.spec.js.map +1 -1
- package/dist/test/unit/pipeline-substream.spec.d.ts +1 -0
- package/dist/test/unit/pipeline-substream.spec.js +246 -0
- package/dist/test/unit/pipeline-substream.spec.js.map +1 -0
- package/dist/test/unit/pipeline.spec.js +1 -1
- package/dist/test/unit/query.spec.js +6 -2
- package/dist/test/unit/query.spec.js.map +1 -1
- package/dist/test/unit/reaper.spec.js +4 -3
- package/dist/test/unit/reaper.spec.js.map +1 -1
- package/dist/test/unit/relation.spec.js +37 -36
- package/dist/test/unit/relation.spec.js.map +1 -1
- package/dist/test/unit/result.spec.js +13 -11
- package/dist/test/unit/result.spec.js.map +1 -1
- package/dist/test/unit/row-source.spec.js +1 -1
- package/dist/test/unit/row-source.spec.js.map +1 -1
- package/dist/test/unit/schema.spec.js +5 -2
- package/dist/test/unit/schema.spec.js.map +1 -1
- package/dist/test/unit/selection.spec.js +7 -3
- package/dist/test/unit/selection.spec.js.map +1 -1
- package/dist/test/unit/types.spec.js +6 -6
- package/dist/test/unit/types.spec.js.map +1 -1
- package/dist/test/unit/writes-atomic.spec.js +2 -2
- package/dist/test/unit/writes-atomic.spec.js.map +1 -1
- package/dist/test/unit/writes-insert.spec.js +5 -4
- package/dist/test/unit/writes-insert.spec.js.map +1 -1
- package/dist/test/unit/writes-replace.spec.js +6 -6
- package/dist/test/unit/writes-replace.spec.js.map +1 -1
- package/dist/test/unit/writes-target.spec.js +3 -3
- package/dist/test/unit/writes-target.spec.js.map +1 -1
- package/dist/test/unit/writes-update-fixture.d.ts +9 -0
- package/dist/test/unit/writes-update-fixture.js +20 -0
- package/dist/test/unit/writes-update-fixture.js.map +1 -0
- package/dist/test/unit/writes-update-mapper.spec.d.ts +1 -0
- package/dist/test/unit/writes-update-mapper.spec.js +123 -0
- package/dist/test/unit/writes-update-mapper.spec.js.map +1 -0
- package/dist/test/unit/writes-update.spec.js +42 -171
- package/dist/test/unit/writes-update.spec.js.map +1 -1
- package/dist/test-external/catalog.test.js +11 -1
- package/dist/test-external/catalog.test.js.map +1 -1
- package/dist/test-external/native.test.js +8 -6
- package/dist/test-external/native.test.js.map +1 -1
- package/dist/test-external/reads.test.js +20 -22
- package/dist/test-external/reads.test.js.map +1 -1
- package/dist/test-external/refusals.test.js +45 -24
- package/dist/test-external/refusals.test.js.map +1 -1
- package/dist/test-external/registration.test.js +4 -2
- package/dist/test-external/registration.test.js.map +1 -1
- package/dist/test-external/sales.d.ts +9 -2
- package/dist/test-external/sales.js.map +1 -1
- package/dist/test-external/unreachable.test.d.ts +1 -0
- package/dist/test-external/unreachable.test.js +83 -0
- package/dist/test-external/unreachable.test.js.map +1 -0
- package/dist/test-external/writes.test.js +71 -37
- package/dist/test-external/writes.test.js.map +1 -1
- package/package.json +19 -6
|
@@ -5,15 +5,7 @@ const types_1 = require("../../implementations/database/types");
|
|
|
5
5
|
const fields_1 = require("../../implementations/database/fields");
|
|
6
6
|
const identifier_1 = require("../../implementations/database/identifier");
|
|
7
7
|
const ddl_1 = require("../../implementations/database/ddl");
|
|
8
|
-
const
|
|
9
|
-
fields: { car: "string", price: "number", tags: "string[]" },
|
|
10
|
-
indexes: {
|
|
11
|
-
price: {},
|
|
12
|
-
tags: { multi: true },
|
|
13
|
-
byCar: { fields: ["car", "price"] },
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
const VEHICLES_PLAN = (0, ddl_1.BuildTablePlan)("vehicles", vehicles, (0, fields_1.ParseTable)(vehicles, "s.vehicles"));
|
|
8
|
+
const ddl_fixture_1 = require("./ddl-fixture");
|
|
17
9
|
const TABLE_PREFIX = "t_";
|
|
18
10
|
const ESCAPED_LITERAL_PREFIX = "E'";
|
|
19
11
|
const COMMENT_PATTERN = /^COMMENT ON INDEX "shop"\."[^"]+" IS (E?'.*')$/;
|
|
@@ -24,11 +16,8 @@ function FindIndex(plan, name) {
|
|
|
24
16
|
}
|
|
25
17
|
return found;
|
|
26
18
|
}
|
|
27
|
-
function PlanFor(tableId, definition) {
|
|
28
|
-
return (0, ddl_1.BuildTablePlan)(tableId, definition, (0, fields_1.ParseTable)(definition, `s.${tableId}`));
|
|
29
|
-
}
|
|
30
19
|
function BuildOne(definition) {
|
|
31
|
-
return PlanFor("t", definition).indexes[0];
|
|
20
|
+
return (0, ddl_fixture_1.PlanFor)("t", definition).indexes[0];
|
|
32
21
|
}
|
|
33
22
|
function DecodeLiteral(literal) {
|
|
34
23
|
const isEscaped = literal.startsWith(ESCAPED_LITERAL_PREFIX);
|
|
@@ -38,7 +27,7 @@ function DecodeLiteral(literal) {
|
|
|
38
27
|
}
|
|
39
28
|
describe("BuildTablePlan", () => {
|
|
40
29
|
it("orders the reserved columns around the declared ones", () => {
|
|
41
|
-
(0, chai_1.expect)(VEHICLES_PLAN.columns.map((column) => column.name)).to.deep.equal([
|
|
30
|
+
(0, chai_1.expect)(ddl_fixture_1.VEHICLES_PLAN.columns.map((column) => column.name)).to.deep.equal([
|
|
42
31
|
"_id",
|
|
43
32
|
"_instance",
|
|
44
33
|
"car",
|
|
@@ -48,39 +37,39 @@ describe("BuildTablePlan", () => {
|
|
|
48
37
|
]);
|
|
49
38
|
});
|
|
50
39
|
it("maps declared fields to their physical types", () => {
|
|
51
|
-
(0, chai_1.expect)(VEHICLES_PLAN.columns[3]).to.deep.equal({
|
|
40
|
+
(0, chai_1.expect)(ddl_fixture_1.VEHICLES_PLAN.columns[3]).to.deep.equal({
|
|
52
41
|
name: "price",
|
|
53
42
|
type: "double precision",
|
|
54
43
|
declared: { field: "price", type: types_1.FLOAT },
|
|
55
44
|
});
|
|
56
45
|
});
|
|
57
46
|
it("leaves the reserved columns undeclared, since no field is stored in them", () => {
|
|
58
|
-
const reserved = [0, 1, VEHICLES_PLAN.columns.length - 1];
|
|
47
|
+
const reserved = [0, 1, ddl_fixture_1.VEHICLES_PLAN.columns.length - 1];
|
|
59
48
|
for (const at of reserved) {
|
|
60
|
-
(0, chai_1.expect)(VEHICLES_PLAN.columns[at].declared).to.equal(undefined);
|
|
49
|
+
(0, chai_1.expect)(ddl_fixture_1.VEHICLES_PLAN.columns[at].declared).to.equal(undefined);
|
|
61
50
|
}
|
|
62
51
|
});
|
|
63
52
|
it("gives the reserved columns their constraints", () => {
|
|
64
|
-
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(VEHICLES_PLAN.columns[1])).to.equal(`"_instance" text NOT NULL DEFAULT ''`);
|
|
65
|
-
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(VEHICLES_PLAN.columns[5])).to.equal(`"_extra" jsonb NOT NULL DEFAULT '{}'::jsonb`);
|
|
66
|
-
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(VEHICLES_PLAN.columns[3])).to.equal(`"price" double precision`);
|
|
53
|
+
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(ddl_fixture_1.VEHICLES_PLAN.columns[1])).to.equal(`"_instance" text NOT NULL DEFAULT ''`);
|
|
54
|
+
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(ddl_fixture_1.VEHICLES_PLAN.columns[5])).to.equal(`"_extra" jsonb NOT NULL DEFAULT '{}'::jsonb`);
|
|
55
|
+
(0, chai_1.expect)((0, ddl_1.ColumnDdl)(ddl_fixture_1.VEHICLES_PLAN.columns[3])).to.equal(`"price" double precision`);
|
|
67
56
|
});
|
|
68
57
|
it("leads a btree index with _instance", () => {
|
|
69
|
-
const index = FindIndex(VEHICLES_PLAN, "vehicles_price");
|
|
58
|
+
const index = FindIndex(ddl_fixture_1.VEHICLES_PLAN, "vehicles_price");
|
|
70
59
|
(0, chai_1.expect)(index.method).to.equal("btree");
|
|
71
60
|
(0, chai_1.expect)(index.keys).to.deep.equal([`"_instance"`, `"price"`]);
|
|
72
61
|
});
|
|
73
62
|
it("uses a bare gin index for a multi index over a jsonb field", () => {
|
|
74
|
-
const index = FindIndex(VEHICLES_PLAN, "vehicles_tags");
|
|
63
|
+
const index = FindIndex(ddl_fixture_1.VEHICLES_PLAN, "vehicles_tags");
|
|
75
64
|
(0, chai_1.expect)(index.method).to.equal("gin");
|
|
76
65
|
(0, chai_1.expect)(index.keys).to.deep.equal([`"tags"`]);
|
|
77
66
|
});
|
|
78
67
|
it("expands a compound index in declaration order", () => {
|
|
79
|
-
const index = FindIndex(VEHICLES_PLAN, "vehicles_byCar");
|
|
68
|
+
const index = FindIndex(ddl_fixture_1.VEHICLES_PLAN, "vehicles_byCar");
|
|
80
69
|
(0, chai_1.expect)(index.keys).to.deep.equal([`"_instance"`, `"car"`, `"price"`]);
|
|
81
70
|
});
|
|
82
71
|
it("indexes an undeclared field through _extra", () => {
|
|
83
|
-
const out = PlanFor("t", { fields: {}, indexes: { ref: {} } });
|
|
72
|
+
const out = (0, ddl_fixture_1.PlanFor)("t", { fields: {}, indexes: { ref: {} } });
|
|
84
73
|
(0, chai_1.expect)(out.indexes[0].keys).to.deep.equal([
|
|
85
74
|
`"_instance"`,
|
|
86
75
|
`("_extra" -> 'ref')`,
|
|
@@ -117,8 +106,10 @@ describe("BuildTablePlan", () => {
|
|
|
117
106
|
(0, chai_1.expect)(index.method).to.equal("btree");
|
|
118
107
|
(0, chai_1.expect)(index.keys).to.deep.equal([`"_instance"`, `("_extra" -> 'ref')`]);
|
|
119
108
|
});
|
|
109
|
+
});
|
|
110
|
+
describe("BuildTablePlan", () => {
|
|
120
111
|
it("adds an unprefixed __g twin to a crossInstance btree index", () => {
|
|
121
|
-
const plan = PlanFor("t", {
|
|
112
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
122
113
|
fields: { car: "string", price: "number" },
|
|
123
114
|
indexes: { byCar: { fields: ["car", "price"], crossInstance: true } },
|
|
124
115
|
});
|
|
@@ -133,7 +124,7 @@ describe("BuildTablePlan", () => {
|
|
|
133
124
|
(0, chai_1.expect)(unscoped.signature).to.not.equal(scoped.signature);
|
|
134
125
|
});
|
|
135
126
|
it("keeps a crossInstance gin index as one bare index", () => {
|
|
136
|
-
const plan = PlanFor("t", {
|
|
127
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
137
128
|
fields: { tags: "string[]" },
|
|
138
129
|
indexes: { tags: { multi: true, crossInstance: true } },
|
|
139
130
|
});
|
|
@@ -142,7 +133,7 @@ describe("BuildTablePlan", () => {
|
|
|
142
133
|
});
|
|
143
134
|
it("fits the __g name into the identifier limit", () => {
|
|
144
135
|
const longId = "x".repeat(70);
|
|
145
|
-
const plan = PlanFor("t", {
|
|
136
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
146
137
|
fields: {},
|
|
147
138
|
indexes: { [longId]: { crossInstance: true } },
|
|
148
139
|
});
|
|
@@ -152,35 +143,37 @@ describe("BuildTablePlan", () => {
|
|
|
152
143
|
(0, chai_1.expect)(Buffer.byteLength(names[1])).to.be.at.most(63);
|
|
153
144
|
});
|
|
154
145
|
it("signs an index with its method and keys", () => {
|
|
155
|
-
const index = FindIndex(VEHICLES_PLAN, "vehicles_price");
|
|
146
|
+
const index = FindIndex(ddl_fixture_1.VEHICLES_PLAN, "vehicles_price");
|
|
156
147
|
(0, chai_1.expect)(index.signature).to.equal(`antelopejs:1:btree:"_instance","price"`);
|
|
157
148
|
});
|
|
158
149
|
it("emits a create table statement with the composite primary key", () => {
|
|
159
|
-
const sql = (0, ddl_1.CreateTableSql)("shop", VEHICLES_PLAN);
|
|
150
|
+
const sql = (0, ddl_1.CreateTableSql)("shop", ddl_fixture_1.VEHICLES_PLAN);
|
|
160
151
|
(0, chai_1.expect)(sql).to.contain(`CREATE TABLE IF NOT EXISTS "shop"."vehicles" (`);
|
|
161
152
|
(0, chai_1.expect)(sql).to.contain(`PRIMARY KEY ("_instance", "_id")`);
|
|
162
153
|
});
|
|
163
154
|
it("emits a concurrent create index statement and its signature comment", () => {
|
|
164
|
-
const index = FindIndex(VEHICLES_PLAN, "vehicles_price");
|
|
165
|
-
(0, chai_1.expect)((0, ddl_1.CreateIndexSql)("shop", VEHICLES_PLAN, index)).to.deep.equal([
|
|
155
|
+
const index = FindIndex(ddl_fixture_1.VEHICLES_PLAN, "vehicles_price");
|
|
156
|
+
(0, chai_1.expect)((0, ddl_1.CreateIndexSql)("shop", ddl_fixture_1.VEHICLES_PLAN, index)).to.deep.equal([
|
|
166
157
|
`CREATE INDEX CONCURRENTLY "vehicles_price" ON "shop"."vehicles" USING btree ("_instance", "price")`,
|
|
167
158
|
`COMMENT ON INDEX "shop"."vehicles_price" IS 'antelopejs:1:btree:"_instance","price"'`,
|
|
168
159
|
]);
|
|
169
160
|
});
|
|
170
161
|
it("round-trips a signature over a hostile field name", () => {
|
|
171
162
|
const hostile = "it's\\bad";
|
|
172
|
-
const hostilePlan = PlanFor("t", {
|
|
163
|
+
const hostilePlan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
173
164
|
fields: {},
|
|
174
165
|
indexes: { [hostile]: {} },
|
|
175
166
|
});
|
|
176
167
|
const index = hostilePlan.indexes[0];
|
|
177
168
|
const comment = (0, ddl_1.CreateIndexSql)("shop", hostilePlan, index)[1];
|
|
178
169
|
const matched = COMMENT_PATTERN.exec(comment);
|
|
179
|
-
|
|
170
|
+
if (matched === null) {
|
|
171
|
+
chai_1.expect.fail(comment);
|
|
172
|
+
}
|
|
180
173
|
(0, chai_1.expect)(DecodeLiteral(matched[1])).to.equal(index.signature);
|
|
181
174
|
});
|
|
182
175
|
it("builds a unique index keyed by instance, with a marked signature", () => {
|
|
183
|
-
const plan = PlanFor("t", {
|
|
176
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
184
177
|
fields: { email: "string" },
|
|
185
178
|
indexes: { email: { unique: true } },
|
|
186
179
|
});
|
|
@@ -190,7 +183,7 @@ describe("BuildTablePlan", () => {
|
|
|
190
183
|
(0, chai_1.expect)((0, ddl_1.CreateIndexSql)("shop", plan, index)[0]).to.equal(`CREATE UNIQUE INDEX CONCURRENTLY "t_email" ON "shop"."t" USING btree ("_instance", "email")`);
|
|
191
184
|
});
|
|
192
185
|
it("keeps the __g twin of a unique index non-unique", () => {
|
|
193
|
-
const plan = PlanFor("t", {
|
|
186
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
194
187
|
fields: { email: "string" },
|
|
195
188
|
indexes: { email: { unique: true, crossInstance: true } },
|
|
196
189
|
});
|
|
@@ -208,15 +201,15 @@ describe("BuildTablePlan", () => {
|
|
|
208
201
|
});
|
|
209
202
|
});
|
|
210
203
|
describe("ServesCrossInstance", () => {
|
|
211
|
-
const
|
|
204
|
+
const model = (0, fields_1.ParseTable)(ddl_fixture_1.vehicles, "s.vehicles");
|
|
212
205
|
it("is true for a declared crossInstance index", () => {
|
|
213
|
-
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("price", { crossInstance: true },
|
|
206
|
+
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("price", { crossInstance: true }, model)).to.equal(true);
|
|
214
207
|
});
|
|
215
208
|
it("is false for a btree index that is not crossInstance", () => {
|
|
216
|
-
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("price", {},
|
|
209
|
+
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("price", {}, model)).to.equal(false);
|
|
217
210
|
});
|
|
218
211
|
it("is true for a gin index, which carries no instance prefix", () => {
|
|
219
|
-
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("tags", { multi: true },
|
|
212
|
+
(0, chai_1.expect)((0, ddl_1.ServesCrossInstance)("tags", { multi: true }, model)).to.equal(true);
|
|
220
213
|
});
|
|
221
214
|
});
|
|
222
215
|
describe("IsAdapterIndex", () => {
|
|
@@ -235,15 +228,15 @@ describe("IsAdapterIndex", () => {
|
|
|
235
228
|
describe("AssertDistinctNames", () => {
|
|
236
229
|
it("accepts a schema whose generated names are all distinct", () => {
|
|
237
230
|
const plans = [
|
|
238
|
-
VEHICLES_PLAN,
|
|
239
|
-
PlanFor("owners", { fields: { name: "string" }, indexes: { name: {} } }),
|
|
231
|
+
ddl_fixture_1.VEHICLES_PLAN,
|
|
232
|
+
(0, ddl_fixture_1.PlanFor)("owners", { fields: { name: "string" }, indexes: { name: {} } }),
|
|
240
233
|
];
|
|
241
234
|
(0, chai_1.expect)(() => (0, ddl_1.AssertDistinctNames)(plans)).to.not.throw();
|
|
242
235
|
});
|
|
243
236
|
it("rejects two indexes on one table that collide on one name", () => {
|
|
244
237
|
const long = "i".repeat(100);
|
|
245
238
|
const truncated = (0, identifier_1.PgIdentifier)(`${TABLE_PREFIX}${long}`).slice(TABLE_PREFIX.length);
|
|
246
|
-
const plan = PlanFor("t", {
|
|
239
|
+
const plan = (0, ddl_fixture_1.PlanFor)("t", {
|
|
247
240
|
fields: {},
|
|
248
241
|
indexes: { [long]: {}, [truncated]: {} },
|
|
249
242
|
});
|
|
@@ -254,8 +247,8 @@ describe("AssertDistinctNames", () => {
|
|
|
254
247
|
});
|
|
255
248
|
it("rejects two tables whose indexes map to one name", () => {
|
|
256
249
|
const plans = [
|
|
257
|
-
PlanFor("a", { fields: {}, indexes: { b_c: {} } }),
|
|
258
|
-
PlanFor("a_b", { fields: {}, indexes: { c: {} } }),
|
|
250
|
+
(0, ddl_fixture_1.PlanFor)("a", { fields: {}, indexes: { b_c: {} } }),
|
|
251
|
+
(0, ddl_fixture_1.PlanFor)("a_b", { fields: {}, indexes: { c: {} } }),
|
|
259
252
|
];
|
|
260
253
|
const check = () => (0, ddl_1.AssertDistinctNames)(plans);
|
|
261
254
|
(0, chai_1.expect)(check).to.throw("a_b_c");
|
|
@@ -264,8 +257,8 @@ describe("AssertDistinctNames", () => {
|
|
|
264
257
|
});
|
|
265
258
|
it("rejects an index that collides with a sibling table", () => {
|
|
266
259
|
const plans = [
|
|
267
|
-
VEHICLES_PLAN,
|
|
268
|
-
PlanFor("vehicles_price", { fields: {}, indexes: {} }),
|
|
260
|
+
ddl_fixture_1.VEHICLES_PLAN,
|
|
261
|
+
(0, ddl_fixture_1.PlanFor)("vehicles_price", { fields: {}, indexes: {} }),
|
|
269
262
|
];
|
|
270
263
|
const check = () => (0, ddl_1.AssertDistinctNames)(plans);
|
|
271
264
|
(0, chai_1.expect)(check).to.throw("vehicles_price");
|
|
@@ -273,338 +266,4 @@ describe("AssertDistinctNames", () => {
|
|
|
273
266
|
(0, chai_1.expect)(check).to.throw(/table 'vehicles_price'/);
|
|
274
267
|
});
|
|
275
268
|
});
|
|
276
|
-
const SAFE = "safe";
|
|
277
|
-
const DESTRUCTIVE = "destructive";
|
|
278
|
-
const SCHEMA = "shop";
|
|
279
|
-
const VEHICLES_TARGET = `"shop"."vehicles"`;
|
|
280
|
-
const DECLARED_INDEX_COUNT = 3;
|
|
281
|
-
const dated = {
|
|
282
|
-
fields: { manufactured: "date" },
|
|
283
|
-
indexes: {},
|
|
284
|
-
};
|
|
285
|
-
const everyType = {
|
|
286
|
-
fields: {
|
|
287
|
-
label: "string",
|
|
288
|
-
amount: "number",
|
|
289
|
-
active: "boolean",
|
|
290
|
-
at: "date",
|
|
291
|
-
payload: "object",
|
|
292
|
-
tags: "string[]",
|
|
293
|
-
},
|
|
294
|
-
indexes: {},
|
|
295
|
-
};
|
|
296
|
-
const CATALOG_TYPES = {
|
|
297
|
-
text: "text",
|
|
298
|
-
"double precision": "double precision",
|
|
299
|
-
boolean: "boolean",
|
|
300
|
-
timestamptz: "timestamp with time zone",
|
|
301
|
-
jsonb: "jsonb",
|
|
302
|
-
};
|
|
303
|
-
const EMPTY = { columns: [], indexes: [] };
|
|
304
|
-
const FULL_COLUMNS = [
|
|
305
|
-
{ name: "_id", type: "text" },
|
|
306
|
-
{ name: "_instance", type: "text" },
|
|
307
|
-
{ name: "car", type: "text" },
|
|
308
|
-
{ name: "price", type: "double precision" },
|
|
309
|
-
{ name: "tags", type: "jsonb" },
|
|
310
|
-
{ name: "_extra", type: "jsonb" },
|
|
311
|
-
];
|
|
312
|
-
const RETYPED_COLUMNS = FULL_COLUMNS.map((column) => column.name === "price" ? { name: column.name, type: "text" } : column);
|
|
313
|
-
const RETIRED_COLUMNS = [
|
|
314
|
-
...FULL_COLUMNS,
|
|
315
|
-
{ name: "retired", type: "text" },
|
|
316
|
-
];
|
|
317
|
-
const UNCASTABLE_COLUMNS = FULL_COLUMNS.map((column) => column.name === "price" ? { name: column.name, type: "boolean" } : column);
|
|
318
|
-
const DRIFTED_TAGS_INDEX = {
|
|
319
|
-
name: "vehicles_tags",
|
|
320
|
-
signature: `antelopejs:1:gin:"outdated"`,
|
|
321
|
-
valid: true,
|
|
322
|
-
};
|
|
323
|
-
const PRICE_SIGNATURE = `antelopejs:1:btree:"_instance","price"`;
|
|
324
|
-
const DRIFTED_PRICE_INDEX = {
|
|
325
|
-
name: "vehicles_price",
|
|
326
|
-
signature: `antelopejs:1:btree:"price"`,
|
|
327
|
-
valid: true,
|
|
328
|
-
};
|
|
329
|
-
const DROP_PRICE = `DROP INDEX CONCURRENTLY IF EXISTS "shop"."vehicles_price"`;
|
|
330
|
-
const DROP_PRICE_REPLACEMENT = `DROP INDEX CONCURRENTLY IF EXISTS "shop"."vehicles_price__next"`;
|
|
331
|
-
const CREATE_PRICE = `CREATE INDEX CONCURRENTLY "vehicles_price"`;
|
|
332
|
-
const CREATE_PRICE_REPLACEMENT = `CREATE INDEX CONCURRENTLY "vehicles_price__next"`;
|
|
333
|
-
const RENAME_PRICE_REPLACEMENT = `ALTER INDEX "shop"."vehicles_price__next" RENAME TO "vehicles_price"`;
|
|
334
|
-
function OtherIndexes(plan, name) {
|
|
335
|
-
return SignedIndexes(plan).filter((index) => index.name !== name);
|
|
336
|
-
}
|
|
337
|
-
function StartsAt(statements, prefix) {
|
|
338
|
-
return statements.findIndex((sql) => sql.startsWith(prefix));
|
|
339
|
-
}
|
|
340
|
-
function Existing(columns, indexes = []) {
|
|
341
|
-
return { columns, indexes };
|
|
342
|
-
}
|
|
343
|
-
function SignedIndexes(plan) {
|
|
344
|
-
return plan.indexes.map((index) => ({
|
|
345
|
-
name: index.name,
|
|
346
|
-
signature: index.signature,
|
|
347
|
-
valid: true,
|
|
348
|
-
}));
|
|
349
|
-
}
|
|
350
|
-
function CatalogType(type) {
|
|
351
|
-
if (!Object.hasOwn(CATALOG_TYPES, type)) {
|
|
352
|
-
throw new Error(`No catalog spelling recorded for physical type '${type}'`);
|
|
353
|
-
}
|
|
354
|
-
return CATALOG_TYPES[type];
|
|
355
|
-
}
|
|
356
|
-
function CatalogColumns(plan) {
|
|
357
|
-
return plan.columns.map((column) => ({
|
|
358
|
-
name: column.name,
|
|
359
|
-
type: CatalogType(column.type),
|
|
360
|
-
}));
|
|
361
|
-
}
|
|
362
|
-
const IsIndexDrop = (sql) => sql.startsWith("DROP INDEX");
|
|
363
|
-
const IsColumnChange = (sql) => sql.startsWith("ALTER TABLE");
|
|
364
|
-
function FirstAt(statements, matches) {
|
|
365
|
-
const position = statements.findIndex(matches);
|
|
366
|
-
if (position < 0) {
|
|
367
|
-
throw new Error(`No statement matched: ${statements.join(" | ")}`);
|
|
368
|
-
}
|
|
369
|
-
return position;
|
|
370
|
-
}
|
|
371
|
-
function LastAt(statements, matches) {
|
|
372
|
-
return statements.reduce((found, sql, position) => (matches(sql) ? position : found), FirstAt(statements, matches));
|
|
373
|
-
}
|
|
374
|
-
describe("PlanTable", () => {
|
|
375
|
-
it("creates everything when the table is absent", () => {
|
|
376
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, EMPTY, SAFE);
|
|
377
|
-
(0, chai_1.expect)(out.statements).to.have.lengthOf(1);
|
|
378
|
-
(0, chai_1.expect)(out.statements[0]).to.contain("CREATE TABLE IF NOT EXISTS");
|
|
379
|
-
(0, chai_1.expect)(out.indexStatements.filter((sql) => sql.startsWith("CREATE INDEX CONCURRENTLY"))).to.have.lengthOf(DECLARED_INDEX_COUNT);
|
|
380
|
-
(0, chai_1.expect)(out.warnings).to.deep.equal([]);
|
|
381
|
-
});
|
|
382
|
-
it("adds only the missing columns", () => {
|
|
383
|
-
const actual = Existing([
|
|
384
|
-
{ name: "_id", type: "text" },
|
|
385
|
-
{ name: "_instance", type: "text" },
|
|
386
|
-
{ name: "car", type: "text" },
|
|
387
|
-
{ name: "_extra", type: "jsonb" },
|
|
388
|
-
]);
|
|
389
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
390
|
-
const added = out.statements.filter((sql) => sql.includes("ADD COLUMN"));
|
|
391
|
-
(0, chai_1.expect)(added).to.deep.equal([
|
|
392
|
-
`ALTER TABLE ${VEHICLES_TARGET} ADD COLUMN IF NOT EXISTS "price" double precision`,
|
|
393
|
-
`ALTER TABLE ${VEHICLES_TARGET} ADD COLUMN IF NOT EXISTS "tags" jsonb`,
|
|
394
|
-
]);
|
|
395
|
-
});
|
|
396
|
-
it("moves each added column's field out of the overflow document, in the same transaction", () => {
|
|
397
|
-
const actual = Existing([
|
|
398
|
-
{ name: "_id", type: "text" },
|
|
399
|
-
{ name: "_instance", type: "text" },
|
|
400
|
-
{ name: "car", type: "text" },
|
|
401
|
-
{ name: "_extra", type: "jsonb" },
|
|
402
|
-
]);
|
|
403
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
404
|
-
const filled = out.statements.filter((sql) => sql.startsWith("UPDATE"));
|
|
405
|
-
(0, chai_1.expect)(filled).to.have.lengthOf(2);
|
|
406
|
-
(0, chai_1.expect)(filled[0]).to.contain(`UPDATE ${VEHICLES_TARGET} SET "price" =`);
|
|
407
|
-
(0, chai_1.expect)(filled[0]).to.contain(`"_extra" = "_extra" - 'price'`);
|
|
408
|
-
(0, chai_1.expect)(filled[0]).to.contain(`WHERE "price" IS NULL`);
|
|
409
|
-
const added = out.statements.indexOf(out.statements.filter((sql) => sql.includes(`"price"`))[0]);
|
|
410
|
-
(0, chai_1.expect)(out.statements[added + 1]).to.equal(filled[0]);
|
|
411
|
-
});
|
|
412
|
-
it("reads the stored value as the column's type, so a mistyped one stays put", () => {
|
|
413
|
-
const actual = Existing([
|
|
414
|
-
{ name: "_id", type: "text" },
|
|
415
|
-
{ name: "_instance", type: "text" },
|
|
416
|
-
{ name: "car", type: "text" },
|
|
417
|
-
{ name: "tags", type: "jsonb" },
|
|
418
|
-
{ name: "_extra", type: "jsonb" },
|
|
419
|
-
]);
|
|
420
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
421
|
-
const filled = out.statements.filter((sql) => sql.startsWith("UPDATE"));
|
|
422
|
-
(0, chai_1.expect)(filled).to.have.lengthOf(1);
|
|
423
|
-
(0, chai_1.expect)(filled[0]).to.contain("jsonb_typeof");
|
|
424
|
-
(0, chai_1.expect)(filled[0]).to.contain("IS NOT NULL");
|
|
425
|
-
(0, chai_1.expect)(filled[0]).to.contain("'null'::jsonb");
|
|
426
|
-
});
|
|
427
|
-
it("plans no backfill where nothing was added", () => {
|
|
428
|
-
const actual = Existing([
|
|
429
|
-
{ name: "_id", type: "text" },
|
|
430
|
-
{ name: "_instance", type: "text" },
|
|
431
|
-
{ name: "car", type: "text" },
|
|
432
|
-
{ name: "price", type: "double precision" },
|
|
433
|
-
{ name: "tags", type: "jsonb" },
|
|
434
|
-
{ name: "_extra", type: "jsonb" },
|
|
435
|
-
]);
|
|
436
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
437
|
-
(0, chai_1.expect)(out.statements.filter((sql) => sql.startsWith("UPDATE"))).to.deep.equal([]);
|
|
438
|
-
});
|
|
439
|
-
it("accepts the catalog spelling of a timestamp column", () => {
|
|
440
|
-
const plan = (0, ddl_1.BuildTablePlan)("v", dated, (0, fields_1.ParseTable)(dated, "s.v"));
|
|
441
|
-
const actual = Existing([
|
|
442
|
-
{ name: "_id", type: "text" },
|
|
443
|
-
{ name: "_instance", type: "text" },
|
|
444
|
-
{ name: "manufactured", type: "timestamp with time zone" },
|
|
445
|
-
{ name: "_extra", type: "jsonb" },
|
|
446
|
-
]);
|
|
447
|
-
(0, chai_1.expect)((0, ddl_1.PlanTable)(SCHEMA, plan, actual, SAFE).statements).to.deep.equal([]);
|
|
448
|
-
});
|
|
449
|
-
it("accepts the catalog spelling of every physical type", () => {
|
|
450
|
-
const plan = (0, ddl_1.BuildTablePlan)("v", everyType, (0, fields_1.ParseTable)(everyType, "s.v"));
|
|
451
|
-
const actual = Existing(CatalogColumns(plan));
|
|
452
|
-
(0, chai_1.expect)((0, ddl_1.PlanTable)(SCHEMA, plan, actual, SAFE).statements).to.deep.equal([]);
|
|
453
|
-
});
|
|
454
|
-
it("refuses a type change in safe mode, naming the field", () => {
|
|
455
|
-
const actual = Existing(RETYPED_COLUMNS);
|
|
456
|
-
const converge = () => (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
457
|
-
(0, chai_1.expect)(converge).to.throw(/price/);
|
|
458
|
-
(0, chai_1.expect)(converge).to.throw(/destructive/);
|
|
459
|
-
});
|
|
460
|
-
it("alters a changed type in destructive mode", () => {
|
|
461
|
-
const actual = Existing(RETYPED_COLUMNS);
|
|
462
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, DESTRUCTIVE);
|
|
463
|
-
(0, chai_1.expect)(out.statements).to.contain(`ALTER TABLE ${VEHICLES_TARGET} ALTER COLUMN "price" TYPE double precision USING ("price"::text::double precision)`);
|
|
464
|
-
});
|
|
465
|
-
it("routes the destructive cast through text when no direct cast exists", () => {
|
|
466
|
-
const actual = Existing(UNCASTABLE_COLUMNS);
|
|
467
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, DESTRUCTIVE);
|
|
468
|
-
(0, chai_1.expect)(out.statements).to.contain(`ALTER TABLE ${VEHICLES_TARGET} ALTER COLUMN "price" TYPE double precision USING ("price"::text::double precision)`);
|
|
469
|
-
});
|
|
470
|
-
it("refuses to add a not-null column with no default to a live table", () => {
|
|
471
|
-
const actual = Existing(FULL_COLUMNS.filter((column) => column.name !== "_id"));
|
|
472
|
-
const converge = () => (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, DESTRUCTIVE);
|
|
473
|
-
(0, chai_1.expect)(converge).to.throw(/_id/);
|
|
474
|
-
(0, chai_1.expect)(converge).to.throw(/not created by this adapter/);
|
|
475
|
-
});
|
|
476
|
-
it("warns about an undeclared column in safe mode and keeps it", () => {
|
|
477
|
-
const actual = Existing(RETIRED_COLUMNS, SignedIndexes(VEHICLES_PLAN));
|
|
478
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
479
|
-
(0, chai_1.expect)(out.statements).to.deep.equal([]);
|
|
480
|
-
(0, chai_1.expect)(out.warnings[0]).to.match(/retired/);
|
|
481
|
-
});
|
|
482
|
-
it("drops an undeclared column in destructive mode", () => {
|
|
483
|
-
const actual = Existing(RETIRED_COLUMNS, SignedIndexes(VEHICLES_PLAN));
|
|
484
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, DESTRUCTIVE);
|
|
485
|
-
(0, chai_1.expect)(out.statements).to.contain(`ALTER TABLE ${VEHICLES_TARGET} DROP COLUMN "retired"`);
|
|
486
|
-
});
|
|
487
|
-
it("leaves a matching index alone", () => {
|
|
488
|
-
const actual = Existing(FULL_COLUMNS, SignedIndexes(VEHICLES_PLAN));
|
|
489
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
490
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([]);
|
|
491
|
-
});
|
|
492
|
-
it("builds indexes outside the transaction", () => {
|
|
493
|
-
const actual = Existing(FULL_COLUMNS);
|
|
494
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
495
|
-
(0, chai_1.expect)(out.statements).to.deep.equal([]);
|
|
496
|
-
(0, chai_1.expect)(out.indexStatements).to.have.lengthOf(DECLARED_INDEX_COUNT * 2);
|
|
497
|
-
});
|
|
498
|
-
it("builds a drifted index's replacement before it drops the index", () => {
|
|
499
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
500
|
-
...OtherIndexes(VEHICLES_PLAN, "vehicles_price"),
|
|
501
|
-
DRIFTED_PRICE_INDEX,
|
|
502
|
-
]);
|
|
503
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
504
|
-
(0, chai_1.expect)(out.statements).to.deep.equal([]);
|
|
505
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([
|
|
506
|
-
`${CREATE_PRICE_REPLACEMENT} ON ${VEHICLES_TARGET} USING btree ("_instance", "price")`,
|
|
507
|
-
`COMMENT ON INDEX "shop"."vehicles_price__next" IS '${PRICE_SIGNATURE}'`,
|
|
508
|
-
DROP_PRICE,
|
|
509
|
-
RENAME_PRICE_REPLACEMENT,
|
|
510
|
-
]);
|
|
511
|
-
});
|
|
512
|
-
it("replaces an index we own but never signed", () => {
|
|
513
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
514
|
-
...OtherIndexes(VEHICLES_PLAN, "vehicles_price"),
|
|
515
|
-
{ name: "vehicles_price", valid: true },
|
|
516
|
-
]);
|
|
517
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
518
|
-
(0, chai_1.expect)(StartsAt(out.indexStatements, CREATE_PRICE_REPLACEMENT)).to.equal(0);
|
|
519
|
-
(0, chai_1.expect)(out.indexStatements).to.contain(RENAME_PRICE_REPLACEMENT);
|
|
520
|
-
});
|
|
521
|
-
it("drops and rebuilds an index a failed concurrent build left invalid", () => {
|
|
522
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
523
|
-
...OtherIndexes(VEHICLES_PLAN, "vehicles_price"),
|
|
524
|
-
{ name: "vehicles_price", signature: PRICE_SIGNATURE, valid: false },
|
|
525
|
-
]);
|
|
526
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
527
|
-
(0, chai_1.expect)(out.indexStatements[0]).to.equal(DROP_PRICE);
|
|
528
|
-
(0, chai_1.expect)(StartsAt(out.indexStatements, CREATE_PRICE)).to.equal(1);
|
|
529
|
-
});
|
|
530
|
-
it("clears a replacement a failed rebuild left behind", () => {
|
|
531
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
532
|
-
...SignedIndexes(VEHICLES_PLAN),
|
|
533
|
-
{ name: "vehicles_price__next", valid: false },
|
|
534
|
-
]);
|
|
535
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
536
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([DROP_PRICE_REPLACEMENT]);
|
|
537
|
-
});
|
|
538
|
-
it("swaps in a ready replacement when a crash left the index missing", () => {
|
|
539
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
540
|
-
...OtherIndexes(VEHICLES_PLAN, "vehicles_price"),
|
|
541
|
-
{ name: "vehicles_price__next", signature: PRICE_SIGNATURE, valid: true },
|
|
542
|
-
]);
|
|
543
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
544
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([RENAME_PRICE_REPLACEMENT]);
|
|
545
|
-
});
|
|
546
|
-
it("drops an adapter index whose declaration is gone, after every build", () => {
|
|
547
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
548
|
-
{
|
|
549
|
-
name: "vehicles_retired",
|
|
550
|
-
signature: `antelopejs:1:btree:"_instance","retired"`,
|
|
551
|
-
valid: true,
|
|
552
|
-
},
|
|
553
|
-
]);
|
|
554
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
555
|
-
(0, chai_1.expect)(out.indexStatements.at(-1)).to.equal(`DROP INDEX CONCURRENTLY IF EXISTS "shop"."vehicles_retired"`);
|
|
556
|
-
});
|
|
557
|
-
it("drops the __g twin once an index is no longer crossInstance", () => {
|
|
558
|
-
const shared = PlanFor("vehicles", {
|
|
559
|
-
fields: vehicles.fields,
|
|
560
|
-
indexes: { ...vehicles.indexes, price: { crossInstance: true } },
|
|
561
|
-
});
|
|
562
|
-
const actual = Existing(FULL_COLUMNS, SignedIndexes(shared));
|
|
563
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
564
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([
|
|
565
|
-
`DROP INDEX CONCURRENTLY IF EXISTS "shop"."vehicles_price__g"`,
|
|
566
|
-
]);
|
|
567
|
-
});
|
|
568
|
-
it("rebuilds an index whose unique flag was added, then removed", () => {
|
|
569
|
-
const unique = PlanFor("vehicles", {
|
|
570
|
-
fields: vehicles.fields,
|
|
571
|
-
indexes: { ...vehicles.indexes, price: { unique: true } },
|
|
572
|
-
});
|
|
573
|
-
const added = (0, ddl_1.PlanTable)(SCHEMA, unique, Existing(FULL_COLUMNS, SignedIndexes(VEHICLES_PLAN)), SAFE);
|
|
574
|
-
(0, chai_1.expect)(added.indexStatements[0]).to.equal(`CREATE UNIQUE INDEX CONCURRENTLY "vehicles_price__next" ON ${VEHICLES_TARGET} USING btree ("_instance", "price")`);
|
|
575
|
-
(0, chai_1.expect)(added.indexStatements).to.contain(RENAME_PRICE_REPLACEMENT);
|
|
576
|
-
const removed = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, Existing(FULL_COLUMNS, SignedIndexes(unique)), SAFE);
|
|
577
|
-
(0, chai_1.expect)(StartsAt(removed.indexStatements, CREATE_PRICE_REPLACEMENT)).to.equal(0);
|
|
578
|
-
(0, chai_1.expect)(removed.indexStatements).to.contain(RENAME_PRICE_REPLACEMENT);
|
|
579
|
-
});
|
|
580
|
-
it("leaves a hand-made index alone", () => {
|
|
581
|
-
const actual = Existing(FULL_COLUMNS, [
|
|
582
|
-
...SignedIndexes(VEHICLES_PLAN),
|
|
583
|
-
{ name: "operator_hunch", valid: true },
|
|
584
|
-
{ name: "operator_broken", valid: false },
|
|
585
|
-
]);
|
|
586
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE);
|
|
587
|
-
(0, chai_1.expect)(out.statements).to.deep.equal([]);
|
|
588
|
-
(0, chai_1.expect)(out.indexStatements).to.deep.equal([]);
|
|
589
|
-
});
|
|
590
|
-
it("drops obsolete indexes inside the transaction before a column retype", () => {
|
|
591
|
-
const actual = Existing(RETYPED_COLUMNS, [
|
|
592
|
-
...OtherIndexes(VEHICLES_PLAN, "vehicles_tags"),
|
|
593
|
-
DRIFTED_TAGS_INDEX,
|
|
594
|
-
]);
|
|
595
|
-
const out = (0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, DESTRUCTIVE);
|
|
596
|
-
(0, chai_1.expect)(LastAt(out.statements, IsIndexDrop)).to.be.lessThan(FirstAt(out.statements, IsColumnChange));
|
|
597
|
-
(0, chai_1.expect)(out.statements[0]).to.equal(`DROP INDEX IF EXISTS "shop"."vehicles_tags"`);
|
|
598
|
-
(0, chai_1.expect)(out.indexStatements).to.have.lengthOf(2);
|
|
599
|
-
(0, chai_1.expect)(out.indexStatements[0]).to.match(/^CREATE INDEX CONCURRENTLY "vehicles_tags"/);
|
|
600
|
-
});
|
|
601
|
-
it("emits nothing against the state its own creation produces", () => {
|
|
602
|
-
const actual = Existing(CatalogColumns(VEHICLES_PLAN), SignedIndexes(VEHICLES_PLAN));
|
|
603
|
-
(0, chai_1.expect)((0, ddl_1.PlanTable)(SCHEMA, VEHICLES_PLAN, actual, SAFE)).to.deep.equal({
|
|
604
|
-
statements: [],
|
|
605
|
-
indexStatements: [],
|
|
606
|
-
warnings: [],
|
|
607
|
-
});
|
|
608
|
-
});
|
|
609
|
-
});
|
|
610
269
|
//# sourceMappingURL=ddl.spec.js.map
|