@atscript/db 0.1.161 → 0.1.162
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/agg.cjs +1 -1
- package/dist/agg.d.cts +1 -1
- package/dist/agg.d.mts +1 -1
- package/dist/agg.mjs +1 -1
- package/dist/{aggregate-fns-B_sgl4mB.mjs → aggregate-fns-DsS9UQVB.mjs} +1 -1
- package/dist/{aggregate-fns-DFtKAv7Q.cjs → aggregate-fns-DupYzFD7.cjs} +1 -1
- package/dist/{buckets-8mG67Mtw.d.mts → buckets-DUTcrT4Z.d.mts} +475 -57
- package/dist/{buckets-B4T_alUe.d.cts → buckets-_iZV39Z3.d.cts} +475 -57
- package/dist/{column-diff-DpeUbhEI.cjs → column-diff-CZsMGQ_w.cjs} +846 -232
- package/dist/{column-diff-DR1glykD.mjs → column-diff-pdn53AIj.mjs} +829 -233
- package/dist/{validator-B3xlbrWf.d.cts → db-error-B_DRL1E9.d.cts} +18 -89
- package/dist/{validator-B3xlbrWf.d.mts → db-error-B_DRL1E9.d.mts} +18 -89
- package/dist/{db-error-JcfJqqpk.cjs → db-error-DmF1_xrz.cjs} +13 -0
- package/dist/{db-error-eSsQX7rt.mjs → db-error-hraC12B9.mjs} +8 -1
- package/dist/{db-validator-plugin-BWy60OvG.d.cts → db-validator-plugin-wRqMYNBI.d.cts} +6 -0
- package/dist/{db-validator-plugin-BWy60OvG.d.mts → db-validator-plugin-wRqMYNBI.d.mts} +6 -0
- package/dist/{fk-diff-5gX42hBt.d.mts → fk-diff-B5jW68T3.d.cts} +34 -10
- package/dist/{fk-diff-BWdQ7kRZ.d.cts → fk-diff-PhVBYohc.d.mts} +34 -10
- package/dist/index.cjs +12 -11
- package/dist/index.d.cts +24 -21
- package/dist/index.d.mts +24 -21
- package/dist/index.mjs +9 -12
- package/dist/{nested-writer-BOj_c_lI.mjs → nested-writer-ClUX0DB0.mjs} +16 -22
- package/dist/{nested-writer-Bl1SZS7x.cjs → nested-writer-yCy6wGuN.cjs} +16 -22
- package/dist/{object-CtPYTIvy.d.cts → object-Czia_qD4.d.cts} +7 -1
- package/dist/{object-CtPYTIvy.d.mts → object-Czia_qD4.d.mts} +7 -1
- package/dist/{object-Djg28csK.cjs → object-GjsuPNqo.cjs} +19 -0
- package/dist/{object-TkiJQ-Dp.mjs → object-PQ1J8jri.mjs} +14 -1
- package/dist/ops.cjs +6 -21
- package/dist/ops.mjs +6 -21
- package/dist/plugin.cjs +263 -323
- package/dist/plugin.mjs +163 -223
- package/dist/rel.cjs +2 -2
- package/dist/rel.d.cts +3 -3
- package/dist/rel.d.mts +3 -3
- package/dist/rel.mjs +2 -2
- package/dist/{relation-helpers-17_2f5hX.d.mts → relation-helpers-BAEkP4bH.d.cts} +1 -1
- package/dist/{relation-helpers-BLBrLQYi.d.cts → relation-helpers-BSYwxOSA.d.mts} +1 -1
- package/dist/{relation-loader-DeulLrAw.cjs → relation-loader-DujL_Mh9.cjs} +1 -1
- package/dist/{relation-loader-CNBMPfRr.mjs → relation-loader-Qv3LrQ42.mjs} +1 -1
- package/dist/{search-fields-CE8cmj9X.mjs → search-fields-0U0FAFGj.mjs} +47 -1
- package/dist/{search-fields-CT_UZ9fg.cjs → search-fields-Bi1n-pB1.cjs} +64 -0
- package/dist/search-fields-CHqqcC3W.d.cts +30 -0
- package/dist/search-fields-CHqqcC3W.d.mts +30 -0
- package/dist/shared.cjs +42 -26
- package/dist/shared.d.cts +98 -4
- package/dist/shared.d.mts +98 -4
- package/dist/shared.mjs +4 -2
- package/dist/sync.cjs +228 -65
- package/dist/sync.d.cts +41 -5
- package/dist/sync.d.mts +41 -5
- package/dist/sync.mjs +228 -66
- package/dist/validator-BcBtg8yW.d.cts +88 -0
- package/dist/validator-BcBtg8yW.d.mts +88 -0
- package/dist/{validator-B4YDLUkj.cjs → validator-DK9Ijpo7.cjs} +3 -2
- package/dist/{validator-B3fPJjS1.mjs → validator-DuDWsIdQ.mjs} +3 -2
- package/dist/validator.cjs +3 -3
- package/dist/validator.d.cts +4 -3
- package/dist/validator.d.mts +4 -3
- package/dist/validator.mjs +3 -3
- package/dist/{validation-utils-CtLNlBtB.cjs → view-validation-D50KWU7O.cjs} +452 -18
- package/dist/{validation-utils-BGjqc2jU.mjs → view-validation-QbqqXEAM.mjs} +364 -20
- package/package.json +6 -6
package/dist/sync.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_db_error = require("./db-error-
|
|
3
|
-
const require_column_diff = require("./column-diff-
|
|
4
|
-
const require_validator = require("./validator-
|
|
2
|
+
const require_db_error = require("./db-error-DmF1_xrz.cjs");
|
|
3
|
+
const require_column_diff = require("./column-diff-CZsMGQ_w.cjs");
|
|
4
|
+
const require_validator = require("./validator-DK9Ijpo7.cjs");
|
|
5
5
|
//#region src/schema/json-column-copy.ts
|
|
6
6
|
const NONE = {
|
|
7
7
|
copies: [],
|
|
@@ -506,6 +506,24 @@ async function readStoredSnapshot(space, tableName, _asView) {
|
|
|
506
506
|
}
|
|
507
507
|
//#endregion
|
|
508
508
|
//#region src/schema/sync-entry.ts
|
|
509
|
+
/** How each index change prints: its mark, color and past-tense word. */
|
|
510
|
+
const INDEX_CHANGE_STYLE = {
|
|
511
|
+
add: {
|
|
512
|
+
mark: "+",
|
|
513
|
+
color: "green",
|
|
514
|
+
done: "added"
|
|
515
|
+
},
|
|
516
|
+
drop: {
|
|
517
|
+
mark: "-",
|
|
518
|
+
color: "red",
|
|
519
|
+
done: "dropped"
|
|
520
|
+
},
|
|
521
|
+
rebuild: {
|
|
522
|
+
mark: "~",
|
|
523
|
+
color: "yellow",
|
|
524
|
+
done: "rebuilt"
|
|
525
|
+
}
|
|
526
|
+
};
|
|
509
527
|
const noColor = {
|
|
510
528
|
green: (s) => s,
|
|
511
529
|
red: (s) => s,
|
|
@@ -560,6 +578,10 @@ var SyncEntry = class SyncEntry {
|
|
|
560
578
|
refused;
|
|
561
579
|
/** @since 0.1.141 — see {@link TSyncEntryInit.cascadeFrom}. */
|
|
562
580
|
cascadeFrom;
|
|
581
|
+
/** @since 0.1.162 — see {@link TSyncEntryInit.definitionChanged}. */
|
|
582
|
+
definitionChanged;
|
|
583
|
+
/** @since 0.1.162 — see {@link TSyncEntryInit.indexChanges}. */
|
|
584
|
+
indexChanges;
|
|
563
585
|
constructor(init) {
|
|
564
586
|
this.name = init.name;
|
|
565
587
|
this.viewType = init.viewType;
|
|
@@ -590,6 +612,8 @@ var SyncEntry = class SyncEntry {
|
|
|
590
612
|
this.dropGroup = init.dropGroup;
|
|
591
613
|
this.refused = init.refused ?? false;
|
|
592
614
|
this.cascadeFrom = init.cascadeFrom ?? [];
|
|
615
|
+
this.definitionChanged = init.definitionChanged ?? false;
|
|
616
|
+
this.indexChanges = init.indexChanges ?? [];
|
|
593
617
|
}
|
|
594
618
|
/**
|
|
595
619
|
* The init object this entry was built from — lets callers derive a
|
|
@@ -660,11 +684,13 @@ var SyncEntry = class SyncEntry {
|
|
|
660
684
|
return mode === "plan" ? [` ${c.red(`! ${cols} — rebuild (${pk.populated ? "rows satisfy the new key" : "table is empty"})`)}`] : [` ${c.yellow(`~ ${cols} — rebuilt`)}`];
|
|
661
685
|
}
|
|
662
686
|
/**
|
|
663
|
-
* `! col: t1 → t2 — drop` (plan),
|
|
664
|
-
* mode)` in plan and result when
|
|
687
|
+
* `! col: t1 → t2 — drop` (plan), `~ col: t1 → t2 — type changed` (result),
|
|
688
|
+
* or `! type col (t1 → t2) — skipped (safe mode)` in plan and result when
|
|
689
|
+
* the `'drop'` recreate was skipped.
|
|
665
690
|
*/
|
|
666
|
-
printTypeChanges(c) {
|
|
691
|
+
printTypeChanges(c, mode) {
|
|
667
692
|
if (this.skipped.includes("recreate")) return this.typeChanges.map((tc) => ` ${c.yellow(`! type ${tc.column} (${tc.fromType} → ${tc.toType}) — skipped (safe mode)`)}`);
|
|
693
|
+
if (mode === "result") return this.typeChanges.map((tc) => ` ${c.yellow(`~ ${tc.column}: ${tc.fromType} → ${tc.toType} — type changed`)}`);
|
|
668
694
|
return this.typeChanges.map((tc) => {
|
|
669
695
|
const action = this.syncMethod ? ` — ${this.syncMethod}` : " — requires migration";
|
|
670
696
|
return ` ${c.red(`! ${tc.column}: ${tc.fromType} → ${tc.toType}${action}`)}`;
|
|
@@ -708,6 +734,26 @@ var SyncEntry = class SyncEntry {
|
|
|
708
734
|
return ` ${tag} ${c.cyan(`option ${oc.key}`)}: ${oc.oldValue} → ${oc.newValue}${action}`;
|
|
709
735
|
});
|
|
710
736
|
}
|
|
737
|
+
/** `+ FK(a) → t — add` / `- … — remove` / `~ … — details` (plan); `added` / `removed` (result). */
|
|
738
|
+
printForeignKeys(c, mode) {
|
|
739
|
+
const [add, remove] = mode === "plan" ? ["add", "remove"] : ["added", "removed"];
|
|
740
|
+
return [
|
|
741
|
+
...this.fkAdded.map((fk) => ` ${c.green(`+ FK(${fk.fields.join(",")}) → ${fk.targetTable} — ${add}`)}`),
|
|
742
|
+
...this.fkRemoved.map((fk) => ` ${c.red(`- FK(${fk.fields.join(",")})${fk.targetTable ? ` → ${fk.targetTable}` : ""} — ${remove}`)}`),
|
|
743
|
+
...this.fkChanged.map((fk) => ` ${c.yellow(`~ FK(${fk.fields.join(",")}) → ${fk.targetTable} — ${fk.details}`)}`)
|
|
744
|
+
];
|
|
745
|
+
}
|
|
746
|
+
/** `+ index name — add` / `- … — drop` / `~ … — rebuild` (plan); `added` / `dropped` / `rebuilt` (result). */
|
|
747
|
+
printIndexChanges(c, mode) {
|
|
748
|
+
return this.indexChanges.map((ic) => {
|
|
749
|
+
const { mark, color, done } = INDEX_CHANGE_STYLE[ic.action];
|
|
750
|
+
return ` ${c[color](`${mark} index ${ic.name} — ${mode === "plan" ? ic.action : done}`)}`;
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
/** `· definition changed` — why a managed view is recreated. */
|
|
754
|
+
printDefinitionChanged(c) {
|
|
755
|
+
return this.definitionChanged ? [` ${c.dim("· definition changed")}`] : [];
|
|
756
|
+
}
|
|
711
757
|
/** `· after: a, b` (plan only — the executor already runs in this order). */
|
|
712
758
|
printDependsOn(c) {
|
|
713
759
|
if (this.dependsOn.length === 0) return [];
|
|
@@ -746,15 +792,15 @@ var SyncEntry = class SyncEntry {
|
|
|
746
792
|
...this.columnsToAdd.map((col) => ` ${c.green(`+ ${col.physicalName} (${col.designType})${col.derived ? " derived" : ""} — add`)}`),
|
|
747
793
|
...this.columnsToRename.map((r) => ` ${c.yellow(`~ ${r.from} → ${r.to} — rename`)}`),
|
|
748
794
|
...this.printJsonMigration(c, "plan"),
|
|
749
|
-
...this.printTypeChanges(c),
|
|
795
|
+
...this.printTypeChanges(c, "plan"),
|
|
750
796
|
...this.printNullableDefaults(c),
|
|
751
797
|
...this.printDerivedChanges(c, "plan"),
|
|
752
798
|
...this.printPkChange(c, "plan"),
|
|
753
799
|
...this.columnsToDrop.map((col) => ` ${c.red(`- ${col} — drop`)}`),
|
|
754
800
|
...this.printOptionChanges(c, "plan"),
|
|
755
|
-
...this.
|
|
756
|
-
...this.
|
|
757
|
-
...this.
|
|
801
|
+
...this.printForeignKeys(c, "plan"),
|
|
802
|
+
...this.printIndexChanges(c, "plan"),
|
|
803
|
+
...this.printDefinitionChanged(c),
|
|
758
804
|
...this.printCascade(c),
|
|
759
805
|
...this.printDependsOn(c),
|
|
760
806
|
""
|
|
@@ -774,7 +820,7 @@ var SyncEntry = class SyncEntry {
|
|
|
774
820
|
...this.columnsAdded.map((col) => ` ${c.green(`+ ${col} — added`)}`),
|
|
775
821
|
""
|
|
776
822
|
];
|
|
777
|
-
if (this.columnsAdded.length > 0 || this.columnsRenamed.length > 0 || this.columnsDropped.length > 0 || this.optionChanges.length > 0 || this.pkChange !== void 0 || this.derivedChanges.length > 0 || this.jsonCopies.length > 0 || this.jsonified.length > 0 || this.skipped.length > 0 || this.recreated || this.renamedFrom) {
|
|
823
|
+
if (this.columnsAdded.length > 0 || this.columnsRenamed.length > 0 || this.columnsDropped.length > 0 || this.optionChanges.length > 0 || this.pkChange !== void 0 || this.derivedChanges.length > 0 || this.jsonCopies.length > 0 || this.jsonified.length > 0 || this.typeChanges.length > 0 || this.nullableChanges.length > 0 || this.defaultChanges.length > 0 || this.fkAdded.length > 0 || this.fkRemoved.length > 0 || this.fkChanged.length > 0 || this.indexChanges.length > 0 || this.skipped.length > 0 || this.recreated || this.renamedFrom || this.status === "alter") {
|
|
778
824
|
const rlabel = this.recreated ? "recreated" : "altered";
|
|
779
825
|
const renameInfo = this.renamedFrom ? ` ${c.yellow(`(renamed from ${this.renamedFrom})`)}` : "";
|
|
780
826
|
return [
|
|
@@ -783,11 +829,14 @@ var SyncEntry = class SyncEntry {
|
|
|
783
829
|
...this.columnsRenamed.map((col) => ` ${c.yellow(`~ ${col} — renamed`)}`),
|
|
784
830
|
...this.printJsonMigration(c, "result"),
|
|
785
831
|
...this.printPkChange(c, "result"),
|
|
786
|
-
...this.printTypeChanges(c),
|
|
832
|
+
...this.printTypeChanges(c, "result"),
|
|
787
833
|
...this.printNullableDefaults(c),
|
|
788
834
|
...this.printDerivedChanges(c, "result"),
|
|
789
835
|
...this.columnsDropped.map((col) => ` ${c.red(`- ${col} — dropped`)}`),
|
|
790
836
|
...this.printOptionChanges(c, "result"),
|
|
837
|
+
...this.printForeignKeys(c, "result"),
|
|
838
|
+
...this.printIndexChanges(c, "result"),
|
|
839
|
+
...this.printDefinitionChanged(c),
|
|
791
840
|
...this.printCascade(c),
|
|
792
841
|
""
|
|
793
842
|
];
|
|
@@ -921,10 +970,7 @@ async function executeSyncTable(facts, safe, deps, exec) {
|
|
|
921
970
|
await adapter.ensureTable(ensureOpts);
|
|
922
971
|
init.status = "create";
|
|
923
972
|
} else if (existing.length > 0) {
|
|
924
|
-
let diff = facts.diff ?? require_column_diff.computeColumnDiff(readable.columnDescriptors, existing, adapter.typeMapper?.bind(adapter),
|
|
925
|
-
snapshot: storedSnapshot,
|
|
926
|
-
nativeDefaultFns: adapter.nativeDefaultFns()
|
|
927
|
-
});
|
|
973
|
+
let diff = facts.diff ?? require_column_diff.computeColumnDiff(readable.columnDescriptors, existing, adapter.typeMapper?.bind(adapter), columnDiffOptions(adapter, storedSnapshot));
|
|
928
974
|
const migration = facts.jsonMigration ?? planJsonColumnMigration(readable, diff, storedSnapshot);
|
|
929
975
|
if (migration.errors.length > 0) throw new Error(migration.errors.join(" "));
|
|
930
976
|
if (migration.copies.length > 0 || migration.jsonify.length > 0) {
|
|
@@ -961,10 +1007,7 @@ async function executeSyncTable(facts, safe, deps, exec) {
|
|
|
961
1007
|
const existed = adapter.tableExists ? await adapter.tableExists() : false;
|
|
962
1008
|
await adapter.ensureTable(ensureOpts);
|
|
963
1009
|
if (!existed) init.status = "create";
|
|
964
|
-
} else await applyColumnDiff(adapter, readable, facts.diff ?? require_column_diff.computeColumnDiff(readable.columnDescriptors, require_column_diff.snapshotToExistingColumns(storedSnapshot, readable), deps.resolveTypeMapper(adapter),
|
|
965
|
-
snapshot: storedSnapshot,
|
|
966
|
-
nativeDefaultFns: adapter.nativeDefaultFns()
|
|
967
|
-
}), init, safe, deps.logger, ensureOpts);
|
|
1010
|
+
} else await applyColumnDiff(adapter, readable, facts.diff ?? require_column_diff.computeColumnDiff(readable.columnDescriptors, require_column_diff.snapshotToExistingColumns(storedSnapshot, readable), deps.resolveTypeMapper(adapter), columnDiffOptions(adapter, storedSnapshot)), init, safe, deps.logger, ensureOpts);
|
|
968
1011
|
else {
|
|
969
1012
|
const existed = adapter.tableExists ? await adapter.tableExists() : true;
|
|
970
1013
|
if (!init.recreated) {
|
|
@@ -972,6 +1015,10 @@ async function executeSyncTable(facts, safe, deps, exec) {
|
|
|
972
1015
|
if (!existed) init.status = "create";
|
|
973
1016
|
}
|
|
974
1017
|
}
|
|
1018
|
+
if (hasFkChanges && fkDiff && init.status !== "create" && init.status !== "error") {
|
|
1019
|
+
Object.assign(init, describeForeignKeyChanges(fkDiff));
|
|
1020
|
+
init.status = "alter";
|
|
1021
|
+
}
|
|
975
1022
|
phase = "Table option sync";
|
|
976
1023
|
const optionDiff = facts.optionDiff;
|
|
977
1024
|
if (init.status !== "create" && !init.recreated && init.status !== "error" && optionDiff && optionDiff.changed.length > 0) {
|
|
@@ -1006,8 +1053,15 @@ async function executeSyncTable(facts, safe, deps, exec) {
|
|
|
1006
1053
|
if (init.pkChange && facts.populated === true) init.pkChange.populated = true;
|
|
1007
1054
|
if (init.status === "error") return new SyncEntry(init);
|
|
1008
1055
|
phase = "Index/FK sync";
|
|
1009
|
-
await adapter.syncIndexes(keptIndexes(init));
|
|
1010
|
-
if (
|
|
1056
|
+
const indexChanges = await adapter.syncIndexes(keptIndexes(init));
|
|
1057
|
+
if (Array.isArray(indexChanges) && indexChanges.length > 0 && init.status !== "create" && !init.recreated) {
|
|
1058
|
+
init.indexChanges = indexChanges;
|
|
1059
|
+
init.status = "alter";
|
|
1060
|
+
}
|
|
1061
|
+
if (adapter.syncForeignKeys && !exec.deferForeignKeysTo) {
|
|
1062
|
+
const fkChanges = await adapter.syncForeignKeys();
|
|
1063
|
+
if (init.status !== "create" && !init.recreated && mergeLiveForeignKeyChanges(init, fkChanges)) init.status = "alter";
|
|
1064
|
+
}
|
|
1011
1065
|
if (adapter.afterSyncTable) await adapter.afterSyncTable();
|
|
1012
1066
|
} catch (error) {
|
|
1013
1067
|
const dropped = droppedFks.length > 0 ? ` Dropped foreign keys before the failure: ${droppedFks.join(", ")} — the ones still in the model are re-added by the next run's syncForeignKeys.` : "";
|
|
@@ -1036,8 +1090,13 @@ async function executeDeferredForeignKeys(readable, entry, deps) {
|
|
|
1036
1090
|
const adapter = readable.dbAdapter;
|
|
1037
1091
|
if (!adapter.syncForeignKeys || entry.status === "error") return entry;
|
|
1038
1092
|
try {
|
|
1039
|
-
await adapter.syncForeignKeys();
|
|
1040
|
-
return entry;
|
|
1093
|
+
const fkChanges = await adapter.syncForeignKeys();
|
|
1094
|
+
if (entry.status === "create" || entry.recreated) return entry;
|
|
1095
|
+
const init = entry.toInit();
|
|
1096
|
+
return mergeLiveForeignKeyChanges(init, fkChanges) ? new SyncEntry({
|
|
1097
|
+
...init,
|
|
1098
|
+
status: "alter"
|
|
1099
|
+
}) : entry;
|
|
1041
1100
|
} catch (error) {
|
|
1042
1101
|
const msg = `FK sync failed on ${readable.tableName}: ${error.message}`;
|
|
1043
1102
|
deps.logger.error?.(`[schema-sync] ${msg}`);
|
|
@@ -1083,6 +1142,14 @@ function describeDerivedChanges(diff) {
|
|
|
1083
1142
|
derived: dc.field.derived !== void 0
|
|
1084
1143
|
}));
|
|
1085
1144
|
}
|
|
1145
|
+
/** The {@link computeColumnDiff} options for a table of `adapter`. */
|
|
1146
|
+
function columnDiffOptions(adapter, snapshot) {
|
|
1147
|
+
return {
|
|
1148
|
+
snapshot,
|
|
1149
|
+
nativeDefaultFns: adapter.nativeDefaultFns(),
|
|
1150
|
+
reportedDefault: adapter.reportedDefault?.bind(adapter)
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1086
1153
|
/** The plan-shaped summary of a diff's type changes (`entry.typeChanges`). */
|
|
1087
1154
|
function describeTypeChanges(diff) {
|
|
1088
1155
|
return diff.typeChanged.map((tc) => ({
|
|
@@ -1121,6 +1188,28 @@ function markSkipped(init, kind) {
|
|
|
1121
1188
|
init.skipped = [...init.skipped ?? [], kind];
|
|
1122
1189
|
}
|
|
1123
1190
|
/**
|
|
1191
|
+
* Whether the run (without safe mode) recreates this existing table — an FK
|
|
1192
|
+
* change on an adapter without `syncForeignKeys`, a `'drop'` / `'recreate'`
|
|
1193
|
+
* type change, nullable / default DDL through `recreateTable`, or a key
|
|
1194
|
+
* rebuild without `rebuildPrimaryKey`. The plan predicts no index work for
|
|
1195
|
+
* such a table: the recreate rebuilds every index.
|
|
1196
|
+
*/
|
|
1197
|
+
function runRecreatesTable(facts, safe = false) {
|
|
1198
|
+
const { readable, fkDiff } = facts;
|
|
1199
|
+
const adapter = readable.dbAdapter;
|
|
1200
|
+
if (!adapter.recreateTable) return false;
|
|
1201
|
+
if (fkDiff && require_column_diff.hasForeignKeyChanges(fkDiff) && !adapter.syncForeignKeys) return true;
|
|
1202
|
+
const diff = facts.diff;
|
|
1203
|
+
if (!diff) return false;
|
|
1204
|
+
if (diff.typeChanged.length > 0) {
|
|
1205
|
+
const strategy = typeChangeStrategy(readable, diff);
|
|
1206
|
+
if (strategy === "recreate" || strategy === "drop" && !safe) return true;
|
|
1207
|
+
}
|
|
1208
|
+
if (safe) return false;
|
|
1209
|
+
if ((diff.nullableChanged.length > 0 || diff.defaultChanged.length > 0) && !adapter.supportsColumnModify && !!adapter.getExistingColumns) return true;
|
|
1210
|
+
return !!diff.primaryKeyChanged && !adapter.rebuildPrimaryKey;
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1124
1213
|
* Whether nullable/default changes need DDL on this adapter: in-place modify,
|
|
1125
1214
|
* or a recreate on a live-introspected one (SQLite). Snapshot-based adapters
|
|
1126
1215
|
* (MongoDB) have no column constraint to change — they only update the
|
|
@@ -1130,6 +1219,20 @@ function needsDdlForNullableDefaults(adapter) {
|
|
|
1130
1219
|
return !!adapter.supportsColumnModify && !!adapter.syncColumns || !!adapter.recreateTable && !!adapter.getExistingColumns;
|
|
1131
1220
|
}
|
|
1132
1221
|
/**
|
|
1222
|
+
* The `syncIndexes` options the run will pass for this table — what the plan
|
|
1223
|
+
* passes `planIndexes`, so both report the same index work.
|
|
1224
|
+
*/
|
|
1225
|
+
function plannedIndexOptions(facts, safe) {
|
|
1226
|
+
if (!safe) return;
|
|
1227
|
+
const diff = afterJsonCopy(facts);
|
|
1228
|
+
return keptIndexes({
|
|
1229
|
+
name: facts.name,
|
|
1230
|
+
status: "alter",
|
|
1231
|
+
skipped: safeModeSkips(facts),
|
|
1232
|
+
typeChanges: diff ? describeTypeChanges(diff) : []
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1133
1236
|
* The indexes `syncIndexes` keeps as they are because safe mode skipped
|
|
1134
1237
|
* the change they depend on — a skipped key rebuild, the columns of a
|
|
1135
1238
|
* skipped type-change recreate (see `TSyncIndexesOptions`).
|
|
@@ -1178,6 +1281,68 @@ function describeJsonMigration(migration) {
|
|
|
1178
1281
|
jsonified: migration.jsonify.length > 0 ? migration.jsonify : void 0
|
|
1179
1282
|
};
|
|
1180
1283
|
}
|
|
1284
|
+
/** Builds a human-readable description of what changed in an FK constraint. */
|
|
1285
|
+
function buildFkChangeDetails(desired, existing) {
|
|
1286
|
+
const parts = [];
|
|
1287
|
+
if (existing.targetTable !== desired.targetTable) parts.push(`retarget ${existing.targetTable} → ${desired.targetTable}`);
|
|
1288
|
+
if ([...existing.targetFields].toSorted().join(",") !== [...desired.targetFields].toSorted().join(",")) parts.push(`fields ${existing.targetFields.join(",")} → ${desired.targetFields.join(",")}`);
|
|
1289
|
+
if ((existing.onDelete ?? void 0) !== (desired.onDelete ?? void 0)) parts.push(`onDelete ${existing.onDelete ?? "noAction"} → ${desired.onDelete ?? "noAction"}`);
|
|
1290
|
+
if ((existing.onUpdate ?? void 0) !== (desired.onUpdate ?? void 0)) parts.push(`onUpdate ${existing.onUpdate ?? "noAction"} → ${desired.onUpdate ?? "noAction"}`);
|
|
1291
|
+
return parts.join(", ");
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* The plan-shaped summaries of a foreign-key diff (`entry.fkAdded` /
|
|
1295
|
+
* `fkRemoved` / `fkChanged`) — on plan entries and on the run entries that
|
|
1296
|
+
* applied them.
|
|
1297
|
+
*/
|
|
1298
|
+
function describeForeignKeyChanges(fkDiff) {
|
|
1299
|
+
return {
|
|
1300
|
+
fkAdded: fkDiff.added.map((fk) => ({
|
|
1301
|
+
fields: require_column_diff.fkColumns(fk).fields,
|
|
1302
|
+
targetTable: fk.targetTable
|
|
1303
|
+
})),
|
|
1304
|
+
fkRemoved: fkDiff.removed.map((fk) => ({
|
|
1305
|
+
fields: fk.fields,
|
|
1306
|
+
targetTable: fk.targetTable
|
|
1307
|
+
})),
|
|
1308
|
+
fkChanged: fkDiff.changed.map((fk) => ({
|
|
1309
|
+
fields: require_column_diff.fkColumns(fk.desired).fields,
|
|
1310
|
+
targetTable: fk.desired.targetTable,
|
|
1311
|
+
details: buildFkChangeDetails({
|
|
1312
|
+
...fk.desired,
|
|
1313
|
+
targetFields: require_column_diff.fkColumns(fk.desired).targetFields
|
|
1314
|
+
}, fk.existing)
|
|
1315
|
+
}))
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Folds the live FK changes `syncForeignKeys` / `planForeignKeys` report
|
|
1320
|
+
* into the entry: those the snapshot-based FK diff did not already name
|
|
1321
|
+
* (a constraint dropped or added by hand) join `fkAdded` / `fkRemoved`.
|
|
1322
|
+
* `true` when any was added.
|
|
1323
|
+
*/
|
|
1324
|
+
function mergeLiveForeignKeyChanges(init, changes) {
|
|
1325
|
+
if (!changes || changes.length === 0) return false;
|
|
1326
|
+
const known = new Set([
|
|
1327
|
+
...init.fkAdded ?? [],
|
|
1328
|
+
...init.fkRemoved ?? [],
|
|
1329
|
+
...init.fkChanged ?? []
|
|
1330
|
+
].map((fk) => require_column_diff.fkKey(fk.fields)));
|
|
1331
|
+
let merged = false;
|
|
1332
|
+
for (const change of changes) {
|
|
1333
|
+
const key = require_column_diff.fkKey(change.fields);
|
|
1334
|
+
if (known.has(key)) continue;
|
|
1335
|
+
known.add(key);
|
|
1336
|
+
const fk = {
|
|
1337
|
+
fields: change.fields,
|
|
1338
|
+
targetTable: change.targetTable ?? ""
|
|
1339
|
+
};
|
|
1340
|
+
if (change.action === "add") init.fkAdded = [...init.fkAdded ?? [], fk];
|
|
1341
|
+
else init.fkRemoved = [...init.fkRemoved ?? [], fk];
|
|
1342
|
+
merged = true;
|
|
1343
|
+
}
|
|
1344
|
+
return merged;
|
|
1345
|
+
}
|
|
1181
1346
|
/** The plan-shaped nullable / default change summaries of a diff. */
|
|
1182
1347
|
function describeNullableDefaults(diff) {
|
|
1183
1348
|
return {
|
|
@@ -1242,11 +1407,12 @@ async function applyColumnDiff(adapter, readable, diff, init, safe, logger, ensu
|
|
|
1242
1407
|
let needsSyncColumns = false;
|
|
1243
1408
|
if (diff.typeChanged.length > 0 && init.status !== "error") {
|
|
1244
1409
|
const strategy = typeChangeStrategy(readable, diff);
|
|
1410
|
+
const typeChanges = describeTypeChanges(diff);
|
|
1411
|
+
if (strategy !== "none") init.typeChanges = typeChanges;
|
|
1245
1412
|
if (strategy === "drop") if (safe) {
|
|
1246
|
-
init.typeChanges = describeTypeChanges(diff);
|
|
1247
1413
|
markSkipped(init, "recreate");
|
|
1248
1414
|
init.status = "alter";
|
|
1249
|
-
const cols =
|
|
1415
|
+
const cols = typeChanges.map((tc) => `${tc.column}: ${tc.fromType} → ${tc.toType}`).join(", ");
|
|
1250
1416
|
logger.warn?.(`[schema-sync] Type change on "${name}" (${cols}) — drop-and-recreate skipped (safe mode)`);
|
|
1251
1417
|
} else await dropAndRecreate(adapter, init, name, ensureOpts);
|
|
1252
1418
|
else if (strategy === "recreate") await recreateKeepingRenames(adapter, diff, init);
|
|
@@ -1261,12 +1427,15 @@ async function applyColumnDiff(adapter, readable, diff, init, safe, logger, ensu
|
|
|
1261
1427
|
}
|
|
1262
1428
|
}
|
|
1263
1429
|
if (diff.nullableChanged.length > 0 || diff.defaultChanged.length > 0) {
|
|
1264
|
-
if (!safe && !init.recreated && init.status !== "error")
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1430
|
+
if (!safe && !init.recreated && init.status !== "error") {
|
|
1431
|
+
if (adapter.supportsColumnModify && adapter.syncColumns) {
|
|
1432
|
+
needsSyncColumns = true;
|
|
1433
|
+
init.status = "alter";
|
|
1434
|
+
} else if (needsDdlForNullableDefaults(adapter)) await recreateKeepingRenames(adapter, diff, init);
|
|
1435
|
+
else init.status = "alter";
|
|
1436
|
+
Object.assign(init, describeNullableDefaults(diff));
|
|
1437
|
+
} else if (init.status !== "error") {
|
|
1438
|
+
if (!safe || !needsDdlForNullableDefaults(adapter) || init.recreated) Object.assign(init, describeNullableDefaults(diff));
|
|
1270
1439
|
if (safe && !init.recreated && needsDdlForNullableDefaults(adapter)) {
|
|
1271
1440
|
Object.assign(init, describeNullableDefaults(diff));
|
|
1272
1441
|
markSkipped(init, "nullable-defaults");
|
|
@@ -1361,15 +1530,6 @@ async function applyColumnDiff(adapter, readable, diff, init, safe, logger, ensu
|
|
|
1361
1530
|
function retain(group, ctx) {
|
|
1362
1531
|
ctx.retained.push(...group.map((name) => ctx.d.removedByName.get(name)));
|
|
1363
1532
|
}
|
|
1364
|
-
/** Builds a human-readable description of what changed in an FK constraint. */
|
|
1365
|
-
function buildFkChangeDetails(desired, existing) {
|
|
1366
|
-
const parts = [];
|
|
1367
|
-
if (existing.targetTable !== desired.targetTable) parts.push(`retarget ${existing.targetTable} → ${desired.targetTable}`);
|
|
1368
|
-
if ([...existing.targetFields].toSorted().join(",") !== [...desired.targetFields].toSorted().join(",")) parts.push(`fields ${existing.targetFields.join(",")} → ${desired.targetFields.join(",")}`);
|
|
1369
|
-
if ((existing.onDelete ?? void 0) !== (desired.onDelete ?? void 0)) parts.push(`onDelete ${existing.onDelete ?? "noAction"} → ${desired.onDelete ?? "noAction"}`);
|
|
1370
|
-
if ((existing.onUpdate ?? void 0) !== (desired.onUpdate ?? void 0)) parts.push(`onUpdate ${existing.onUpdate ?? "noAction"} → ${desired.onUpdate ?? "noAction"}`);
|
|
1371
|
-
return parts.join(", ");
|
|
1372
|
-
}
|
|
1373
1533
|
function sortedUnique(names) {
|
|
1374
1534
|
return [...new Set(names)].toSorted();
|
|
1375
1535
|
}
|
|
@@ -1641,6 +1801,7 @@ var SchemaSync = class {
|
|
|
1641
1801
|
this.assertLockHeld(heartbeat.getAbortReason);
|
|
1642
1802
|
const refusals = this.preflight(d, safe);
|
|
1643
1803
|
if (refusals.size > 0) {
|
|
1804
|
+
await this.planLiveWork(d, safe);
|
|
1644
1805
|
const result = {
|
|
1645
1806
|
status: "refused",
|
|
1646
1807
|
schemaHash: hash,
|
|
@@ -1705,6 +1866,7 @@ var SchemaSync = class {
|
|
|
1705
1866
|
renamedFrom: plan.isRenamed ? view.renamedFrom : void 0,
|
|
1706
1867
|
recreated: viewRecreated(plan) || void 0,
|
|
1707
1868
|
cascadeFrom: plan.upstreamRecreated,
|
|
1869
|
+
definitionChanged: plan.definitionChanged || void 0,
|
|
1708
1870
|
dependsOn: viewSources.get(view.tableName).filter((n) => tableNames.has(n) || viewNames.has(n) || externalViewNames.has(n))
|
|
1709
1871
|
}));
|
|
1710
1872
|
}
|
|
@@ -1842,10 +2004,7 @@ var SchemaSync = class {
|
|
|
1842
2004
|
init.columnsToAdd = [...readable.columnDescriptors];
|
|
1843
2005
|
} else if (facts.existing && facts.existing.length > 0) {
|
|
1844
2006
|
const typeMapper = adapter.typeMapper?.bind(adapter);
|
|
1845
|
-
facts.diff = require_column_diff.computeColumnDiff(readable.columnDescriptors, facts.existing, typeMapper,
|
|
1846
|
-
snapshot: storedSnapshot,
|
|
1847
|
-
nativeDefaultFns: adapter.nativeDefaultFns()
|
|
1848
|
-
});
|
|
2007
|
+
facts.diff = require_column_diff.computeColumnDiff(readable.columnDescriptors, facts.existing, typeMapper, columnDiffOptions(adapter, storedSnapshot));
|
|
1849
2008
|
this.populatePlanFromDiff(facts.diff, init, readable, safe);
|
|
1850
2009
|
const migration = planJsonColumnMigration(readable, facts.diff, storedSnapshot);
|
|
1851
2010
|
facts.jsonMigration = migration;
|
|
@@ -1864,10 +2023,7 @@ var SchemaSync = class {
|
|
|
1864
2023
|
}
|
|
1865
2024
|
} else {
|
|
1866
2025
|
const existing = require_column_diff.snapshotToExistingColumns(storedSnapshot, readable);
|
|
1867
|
-
facts.diff = require_column_diff.computeColumnDiff(readable.columnDescriptors, existing, this.resolveTypeMapper(adapter),
|
|
1868
|
-
snapshot: storedSnapshot,
|
|
1869
|
-
nativeDefaultFns: adapter.nativeDefaultFns()
|
|
1870
|
-
});
|
|
2026
|
+
facts.diff = require_column_diff.computeColumnDiff(readable.columnDescriptors, existing, this.resolveTypeMapper(adapter), columnDiffOptions(adapter, storedSnapshot));
|
|
1871
2027
|
this.populatePlanFromDiff(facts.diff, init, readable, safe);
|
|
1872
2028
|
}
|
|
1873
2029
|
else if (adapter.tableExists) {
|
|
@@ -1885,22 +2041,7 @@ var SchemaSync = class {
|
|
|
1885
2041
|
if (init.status !== "create" && init.status !== "error" && facts.fkDiff && require_column_diff.hasForeignKeyChanges(facts.fkDiff)) {
|
|
1886
2042
|
const fkDiff = facts.fkDiff;
|
|
1887
2043
|
init.status = "alter";
|
|
1888
|
-
init
|
|
1889
|
-
fields: require_column_diff.fkColumns(fk).fields,
|
|
1890
|
-
targetTable: fk.targetTable
|
|
1891
|
-
}));
|
|
1892
|
-
init.fkRemoved = fkDiff.removed.map((fk) => ({
|
|
1893
|
-
fields: fk.fields,
|
|
1894
|
-
targetTable: fk.targetTable
|
|
1895
|
-
}));
|
|
1896
|
-
init.fkChanged = fkDiff.changed.map((fk) => ({
|
|
1897
|
-
fields: require_column_diff.fkColumns(fk.desired).fields,
|
|
1898
|
-
targetTable: fk.desired.targetTable,
|
|
1899
|
-
details: buildFkChangeDetails({
|
|
1900
|
-
...fk.desired,
|
|
1901
|
-
targetFields: require_column_diff.fkColumns(fk.desired).targetFields
|
|
1902
|
-
}, fk.existing)
|
|
1903
|
-
}));
|
|
2044
|
+
Object.assign(init, describeForeignKeyChanges(fkDiff));
|
|
1904
2045
|
}
|
|
1905
2046
|
if (facts.diff?.primaryKeyChanged) {
|
|
1906
2047
|
const tableName = pendingRename ? dbName : void 0;
|
|
@@ -1918,6 +2059,26 @@ var SchemaSync = class {
|
|
|
1918
2059
|
return facts;
|
|
1919
2060
|
}
|
|
1920
2061
|
/**
|
|
2062
|
+
* Folds the index / foreign-key work on each live table as it is now
|
|
2063
|
+
* (`planIndexes` / `planForeignKeys`) into its plan entry. Read only when
|
|
2064
|
+
* plan entries are reported (`plan()`, a refused run) — a run reports what
|
|
2065
|
+
* `syncIndexes` / `syncForeignKeys` did.
|
|
2066
|
+
*/
|
|
2067
|
+
async planLiveWork(d, safe) {
|
|
2068
|
+
await Promise.all(d.tables.map((t) => this.planTableLiveWork(t, safe)));
|
|
2069
|
+
}
|
|
2070
|
+
async planTableLiveWork(facts, safe) {
|
|
2071
|
+
const adapter = facts.readable.dbAdapter;
|
|
2072
|
+
const init = facts.planEntry;
|
|
2073
|
+
if (!(init.status !== "create" && init.status !== "error" && (safe || !init.recreated) && !facts.pendingRename && !runRecreatesTable(facts, safe))) return;
|
|
2074
|
+
const indexChanges = await adapter.planIndexes(plannedIndexOptions(facts, safe));
|
|
2075
|
+
if (indexChanges.length > 0) {
|
|
2076
|
+
init.indexChanges = indexChanges;
|
|
2077
|
+
init.status = "alter";
|
|
2078
|
+
}
|
|
2079
|
+
if (adapter.planForeignKeys && mergeLiveForeignKeyChanges(init, await adapter.planForeignKeys())) init.status = "alter";
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
1921
2082
|
* Pure validation over the discovery facts. Every refusal is a change that
|
|
1922
2083
|
* no order of DDL can apply safely; the messages are user-facing.
|
|
1923
2084
|
*/
|
|
@@ -2283,6 +2444,7 @@ var SchemaSync = class {
|
|
|
2283
2444
|
await this.store.ensureControlTable();
|
|
2284
2445
|
const d = await this.discover(resolved, safe);
|
|
2285
2446
|
const refusals = this.preflight(d, safe);
|
|
2447
|
+
await this.planLiveWork(d, safe);
|
|
2286
2448
|
const entries = this.buildPlanEntries(d, safe, refusals);
|
|
2287
2449
|
if (!force) {
|
|
2288
2450
|
if (await this.store.readHash() === hash) return {
|
|
@@ -2435,6 +2597,7 @@ exports.fkKey = require_column_diff.fkKey;
|
|
|
2435
2597
|
exports.hasForeignKeyChanges = require_column_diff.hasForeignKeyChanges;
|
|
2436
2598
|
exports.planSchema = planSchema;
|
|
2437
2599
|
exports.readStoredSnapshot = readStoredSnapshot;
|
|
2600
|
+
exports.sameDefaultValue = require_column_diff.sameDefaultValue;
|
|
2438
2601
|
exports.snapshotToExistingColumns = require_column_diff.snapshotToExistingColumns;
|
|
2439
2602
|
exports.snapshotToExistingTableOptions = require_column_diff.snapshotToExistingTableOptions;
|
|
2440
2603
|
exports.syncSchema = syncSchema;
|
package/dist/sync.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Ct as TEnsureTableOptions, Et as TExistingTableOption, G as TDbFieldMeta, Pt as TIndexChange, Tt as TExistingForeignKey, Vt as TReferencingForeignKey, at as TDbObjectKind, cr as TGenericLogger, gn as DbSpace, qt as TTableOptionDiff, xt as TDerivedChangeReason, zt as TPrimaryKeyChange } from "./buckets-_iZV39Z3.cjs";
|
|
2
|
+
import { S as snapshotToExistingTableOptions, _ as computeSchemaHash, a as hasForeignKeyChanges, b as computeViewSnapshot, d as TForeignKeySnapshot, f as TTableSnapshot, g as canonicalizeQueryNode, h as TViewSnapshot, i as fkKey, l as sameDefaultValue, m as TViewJoinSnapshot, n as computeForeignKeyDiff, o as TColumnDiffOptions, p as TViewColumnSnapshot, s as computeColumnDiff, t as TForeignKeyDiff, u as TFieldSnapshot, v as computeTableHash, x as snapshotToExistingColumns, y as computeTableSnapshot } from "./fk-diff-B5jW68T3.cjs";
|
|
3
3
|
import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/schema/sync-entry.d.ts
|
|
@@ -150,6 +150,23 @@ interface TSyncEntryInit {
|
|
|
150
150
|
* @since 0.1.141
|
|
151
151
|
*/
|
|
152
152
|
cascadeFrom?: string[];
|
|
153
|
+
/**
|
|
154
|
+
* `true` on a managed view whose own definition changed since the last
|
|
155
|
+
* sync — the reason it is dropped and recreated. Printed as
|
|
156
|
+
* `· definition changed`.
|
|
157
|
+
* @since 0.1.162
|
|
158
|
+
*/
|
|
159
|
+
definitionChanged?: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Managed indexes created, dropped or rebuilt (definition drift). On a
|
|
162
|
+
* plan entry: what the run's index sync would do to the live table as it
|
|
163
|
+
* is now (before the entry's column changes; not planned for a table the
|
|
164
|
+
* run creates, recreates or renames). On a run entry: what it did — not
|
|
165
|
+
* reported for a created or recreated table. Either marks the entry
|
|
166
|
+
* `alter`.
|
|
167
|
+
* @since 0.1.162
|
|
168
|
+
*/
|
|
169
|
+
indexChanges?: TIndexChange[];
|
|
153
170
|
}
|
|
154
171
|
declare class SyncEntry {
|
|
155
172
|
readonly name: string;
|
|
@@ -223,6 +240,10 @@ declare class SyncEntry {
|
|
|
223
240
|
readonly refused: boolean;
|
|
224
241
|
/** @since 0.1.141 — see {@link TSyncEntryInit.cascadeFrom}. */
|
|
225
242
|
readonly cascadeFrom: string[];
|
|
243
|
+
/** @since 0.1.162 — see {@link TSyncEntryInit.definitionChanged}. */
|
|
244
|
+
readonly definitionChanged: boolean;
|
|
245
|
+
/** @since 0.1.162 — see {@link TSyncEntryInit.indexChanges}. */
|
|
246
|
+
readonly indexChanges: TIndexChange[];
|
|
226
247
|
constructor(init: TSyncEntryInit);
|
|
227
248
|
/**
|
|
228
249
|
* The init object this entry was built from — lets callers derive a
|
|
@@ -259,8 +280,9 @@ declare class SyncEntry {
|
|
|
259
280
|
/** `! PK (id) → (code) — rebuild (table is empty)` / `— rebuild (rows satisfy the new key)` / `— skipped (safe mode)` */
|
|
260
281
|
private printPkChange;
|
|
261
282
|
/**
|
|
262
|
-
* `! col: t1 → t2 — drop` (plan),
|
|
263
|
-
* mode)` in plan and result when
|
|
283
|
+
* `! col: t1 → t2 — drop` (plan), `~ col: t1 → t2 — type changed` (result),
|
|
284
|
+
* or `! type col (t1 → t2) — skipped (safe mode)` in plan and result when
|
|
285
|
+
* the `'drop'` recreate was skipped.
|
|
264
286
|
*/
|
|
265
287
|
private printTypeChanges;
|
|
266
288
|
/**
|
|
@@ -278,6 +300,12 @@ declare class SyncEntry {
|
|
|
278
300
|
* change. Both: `! option k: a → b — skipped (safe mode)` when pending.
|
|
279
301
|
*/
|
|
280
302
|
private printOptionChanges;
|
|
303
|
+
/** `+ FK(a) → t — add` / `- … — remove` / `~ … — details` (plan); `added` / `removed` (result). */
|
|
304
|
+
private printForeignKeys;
|
|
305
|
+
/** `+ index name — add` / `- … — drop` / `~ … — rebuild` (plan); `added` / `dropped` / `rebuilt` (result). */
|
|
306
|
+
private printIndexChanges;
|
|
307
|
+
/** `· definition changed` — why a managed view is recreated. */
|
|
308
|
+
private printDefinitionChanged;
|
|
281
309
|
/** `· after: a, b` (plan only — the executor already runs in this order). */
|
|
282
310
|
private printDependsOn;
|
|
283
311
|
/** `· upstream view "x" recreated` — why an unchanged view is recreated. */
|
|
@@ -423,6 +451,14 @@ declare class SchemaSync {
|
|
|
423
451
|
* `safe` — safe mode skips the key rebuild, so its plan rule does not apply.
|
|
424
452
|
*/
|
|
425
453
|
private discoverTable;
|
|
454
|
+
/**
|
|
455
|
+
* Folds the index / foreign-key work on each live table as it is now
|
|
456
|
+
* (`planIndexes` / `planForeignKeys`) into its plan entry. Read only when
|
|
457
|
+
* plan entries are reported (`plan()`, a refused run) — a run reports what
|
|
458
|
+
* `syncIndexes` / `syncForeignKeys` did.
|
|
459
|
+
*/
|
|
460
|
+
private planLiveWork;
|
|
461
|
+
private planTableLiveWork;
|
|
426
462
|
/**
|
|
427
463
|
* Pure validation over the discovery facts. Every refusal is a change that
|
|
428
464
|
* no order of DDL can apply safely; the messages are user-facing.
|
|
@@ -566,4 +602,4 @@ declare function syncSchema(space: DbSpace, types: readonly TAtscriptAnnotatedTy
|
|
|
566
602
|
*/
|
|
567
603
|
declare function planSchema(space: DbSpace, types: readonly TAtscriptAnnotatedType[], opts?: Pick<TSyncOptions, "force" | "safe">): Promise<TSyncPlan>;
|
|
568
604
|
//#endregion
|
|
569
|
-
export { SchemaSync, SyncEntry, type TDbObjectKind, type TDependencyEdge, type TEnsureTableOptions, type TExistingForeignKey, type TFieldSnapshot, type TForeignKeyDiff, type TForeignKeySnapshot, type TPrimaryKeyChange, type TReferencingForeignKey, type TSyncColors, type TSyncDerivedChange, type TSyncEntryInit, type TSyncEntryStatus, type TSyncOptions, type TSyncPlan, type TSyncResult, type TSyncSkippedWork, type TTableSnapshot, type TViewColumnSnapshot, type TViewJoinSnapshot, type TViewSnapshot, canonicalizeQueryNode, computeColumnDiff, computeForeignKeyDiff, computeSchemaHash, computeTableHash, computeTableOptionDiff, computeTableSnapshot, computeViewSnapshot, fkKey, hasForeignKeyChanges, planSchema, readStoredSnapshot, snapshotToExistingColumns, snapshotToExistingTableOptions, syncSchema, topoOrder };
|
|
605
|
+
export { SchemaSync, SyncEntry, type TColumnDiffOptions, type TDbObjectKind, type TDependencyEdge, type TEnsureTableOptions, type TExistingForeignKey, type TFieldSnapshot, type TForeignKeyDiff, type TForeignKeySnapshot, type TPrimaryKeyChange, type TReferencingForeignKey, type TSyncColors, type TSyncDerivedChange, type TSyncEntryInit, type TSyncEntryStatus, type TSyncOptions, type TSyncPlan, type TSyncResult, type TSyncSkippedWork, type TTableSnapshot, type TViewColumnSnapshot, type TViewJoinSnapshot, type TViewSnapshot, canonicalizeQueryNode, computeColumnDiff, computeForeignKeyDiff, computeSchemaHash, computeTableHash, computeTableOptionDiff, computeTableSnapshot, computeViewSnapshot, fkKey, hasForeignKeyChanges, planSchema, readStoredSnapshot, sameDefaultValue, snapshotToExistingColumns, snapshotToExistingTableOptions, syncSchema, topoOrder };
|