@atscript/db 0.1.127 → 0.1.129
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/{db-error-DXwEzmYJ.cjs → db-error-C4JuLcvb.cjs} +27 -0
- package/dist/{db-error-BHPXOKzc.mjs → db-error-COrO58t5.mjs} +22 -1
- package/dist/{db-readable-BkAGccv9.d.mts → db-readable-B7eYWS5q.d.cts} +299 -17
- package/dist/{db-readable-C0nDKX8A.d.cts → db-readable-Bn1bV_eC.d.mts} +299 -17
- package/dist/{db-space-B_ASuDaR.d.mts → db-space-C2UCnGHd.d.cts} +108 -30
- package/dist/{db-space-CSntT6yS.d.cts → db-space-DdIPYD0Q.d.mts} +108 -30
- package/dist/{db-view-BP0Qbeux.cjs → db-view-CRBgkEp0.cjs} +786 -100
- package/dist/{db-view-C8rZM5_N.mjs → db-view-Dl0aDTiT.mjs} +733 -101
- package/dist/index.cjs +48 -3
- package/dist/index.d.cts +162 -37
- package/dist/index.d.mts +162 -37
- package/dist/index.mjs +37 -5
- package/dist/{nested-writer-DI-HeTky.mjs → nested-writer-CkDo-ZfH.mjs} +1 -1
- package/dist/{nested-writer-DoDhl3X3.cjs → nested-writer-DxPhmWFz.cjs} +1 -1
- package/dist/{ops-DJRnNTVo.d.cts → ops-AqhV7s9o.d.cts} +24 -1
- package/dist/{ops-DJRnNTVo.d.mts → ops-AqhV7s9o.d.mts} +24 -1
- package/dist/ops.cjs +44 -1
- package/dist/ops.d.cts +2 -2
- package/dist/ops.d.mts +2 -2
- package/dist/ops.mjs +44 -2
- package/dist/plugin.cjs +12 -5
- package/dist/plugin.mjs +12 -5
- package/dist/rel.cjs +2 -2
- package/dist/rel.d.cts +1 -1
- package/dist/rel.d.mts +1 -1
- package/dist/rel.mjs +2 -2
- package/dist/{relation-loader-BnUgJsUG.cjs → relation-loader-C8GOpNYJ.cjs} +1 -1
- package/dist/{relation-loader-BmeOMj0b.mjs → relation-loader-CUGcxJ18.mjs} +1 -1
- package/dist/sync.cjs +1270 -398
- package/dist/sync.d.cts +255 -18
- package/dist/sync.d.mts +255 -18
- package/dist/sync.mjs +1269 -399
- package/dist/{validator-0vRXN51D.mjs → validator-CeD_fqyW.mjs} +21 -4
- package/dist/{validator-CSGug4vg.cjs → validator-lkCJKuoo.cjs} +32 -3
- package/dist/{validator-BcBtg8yW.d.cts → validator-wBARmD68.d.cts} +57 -1
- package/dist/{validator-BcBtg8yW.d.mts → validator-wBARmD68.d.mts} +57 -1
- package/dist/validator.cjs +7 -1
- package/dist/validator.d.cts +3 -3
- package/dist/validator.d.mts +3 -3
- package/dist/validator.mjs +4 -3
- package/package.json +8 -8
|
@@ -50,6 +50,27 @@ var CasExhaustedError = class extends DbError {
|
|
|
50
50
|
this.lastSeenVersion = lastSeenVersion;
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Thrown by `AtscriptDbTable.touchMany` (`require: 'all'`, the default) when
|
|
55
|
+
* fewer rows than keys matched their expected version — at least one row is
|
|
56
|
+
* stale or missing. Nothing was written (the pre-count refused before the
|
|
57
|
+
* first statement, or the SQL transaction rolled every bump back). Surfaced
|
|
58
|
+
* as HTTP 409 by moost-db.
|
|
59
|
+
*/
|
|
60
|
+
var CasMismatchError = class extends DbError {
|
|
61
|
+
matched;
|
|
62
|
+
expected;
|
|
63
|
+
name = "CasMismatchError";
|
|
64
|
+
constructor(matched, expected) {
|
|
65
|
+
const message = `touchMany: ${matched} of ${expected} rows matched — stale or missing rows`;
|
|
66
|
+
super("CAS_MISMATCH", [{
|
|
67
|
+
path: "$cas",
|
|
68
|
+
message
|
|
69
|
+
}], message);
|
|
70
|
+
this.matched = matched;
|
|
71
|
+
this.expected = expected;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
53
74
|
//#endregion
|
|
54
75
|
Object.defineProperty(exports, "CasExhaustedError", {
|
|
55
76
|
enumerable: true,
|
|
@@ -57,6 +78,12 @@ Object.defineProperty(exports, "CasExhaustedError", {
|
|
|
57
78
|
return CasExhaustedError;
|
|
58
79
|
}
|
|
59
80
|
});
|
|
81
|
+
Object.defineProperty(exports, "CasMismatchError", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function() {
|
|
84
|
+
return CasMismatchError;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
60
87
|
Object.defineProperty(exports, "DbError", {
|
|
61
88
|
enumerable: true,
|
|
62
89
|
get: function() {
|
|
@@ -50,5 +50,26 @@ var CasExhaustedError = class extends DbError {
|
|
|
50
50
|
this.lastSeenVersion = lastSeenVersion;
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Thrown by `AtscriptDbTable.touchMany` (`require: 'all'`, the default) when
|
|
55
|
+
* fewer rows than keys matched their expected version — at least one row is
|
|
56
|
+
* stale or missing. Nothing was written (the pre-count refused before the
|
|
57
|
+
* first statement, or the SQL transaction rolled every bump back). Surfaced
|
|
58
|
+
* as HTTP 409 by moost-db.
|
|
59
|
+
*/
|
|
60
|
+
var CasMismatchError = class extends DbError {
|
|
61
|
+
matched;
|
|
62
|
+
expected;
|
|
63
|
+
name = "CasMismatchError";
|
|
64
|
+
constructor(matched, expected) {
|
|
65
|
+
const message = `touchMany: ${matched} of ${expected} rows matched — stale or missing rows`;
|
|
66
|
+
super("CAS_MISMATCH", [{
|
|
67
|
+
path: "$cas",
|
|
68
|
+
message
|
|
69
|
+
}], message);
|
|
70
|
+
this.matched = matched;
|
|
71
|
+
this.expected = expected;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
53
74
|
//#endregion
|
|
54
|
-
export {
|
|
75
|
+
export { DepthLimitExceededError as i, CasMismatchError as n, DbError as r, CasExhaustedError as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { f as TFieldOps } from "./ops-
|
|
2
|
-
import { FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
1
|
+
import { f as TFieldOps } from "./ops-AqhV7s9o.cjs";
|
|
3
2
|
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
3
|
+
import { FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/query/uniqu-select.d.ts
|
|
6
6
|
/**
|
|
@@ -55,6 +55,12 @@ interface TGenericLogger {
|
|
|
55
55
|
declare const NoopLogger: TGenericLogger;
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region src/table/table-metadata.d.ts
|
|
58
|
+
/**
|
|
59
|
+
* Finds the nearest ancestor of `path` that belongs to `set`.
|
|
60
|
+
* Used by both the build pipeline (in `_classifyFields`) and
|
|
61
|
+
* runtime reconstruction on the Readable.
|
|
62
|
+
*/
|
|
63
|
+
declare function findAncestorInSet(path: string, set: ReadonlySet<string>): string | undefined;
|
|
58
64
|
/** Returns true if the annotated type IS the `db.geoPoint` primitive (tag-based). */
|
|
59
65
|
declare function isGeoPointType(fieldType: TAtscriptAnnotatedType): boolean;
|
|
60
66
|
/**
|
|
@@ -118,6 +124,22 @@ declare class TableMetadata {
|
|
|
118
124
|
leafByPhysical: Map<string, TDbFieldMeta>;
|
|
119
125
|
/** Leaf field descriptors indexed by logical path (write/patch/filter paths). */
|
|
120
126
|
leafByLogical: Map<string, TDbFieldMeta>;
|
|
127
|
+
/**
|
|
128
|
+
* Non-ignored field descriptors keyed by logical path, excluding navigation
|
|
129
|
+
* relations and their descendants. Unlike `leafByLogical` (relational
|
|
130
|
+
* adapters only) this is built for every adapter, so the core path guard
|
|
131
|
+
* (`guardPaths`) can answer "does this path have physical storage here?"
|
|
132
|
+
* on nested-object adapters too.
|
|
133
|
+
*/
|
|
134
|
+
descriptorByPath: Map<string, TDbFieldMeta>;
|
|
135
|
+
/**
|
|
136
|
+
* Logical paths stored as a single JSON column (`storage === 'json'`,
|
|
137
|
+
* non-ignored descriptors). Retained after build — unlike the build-time
|
|
138
|
+
* `jsonFields` set — so the path guard can classify JSON descendants on
|
|
139
|
+
* relational adapters. Empty on nested-object adapters (they keep native
|
|
140
|
+
* dotted paths as descriptors).
|
|
141
|
+
*/
|
|
142
|
+
jsonParents: ReadonlySet<string>;
|
|
121
143
|
private _built;
|
|
122
144
|
private _identifications?;
|
|
123
145
|
private _collateMap;
|
|
@@ -166,6 +188,14 @@ declare class TableMetadata {
|
|
|
166
188
|
private _classifyFields;
|
|
167
189
|
/** Returns the `__`-separated parent prefix for a dot-separated path, or empty string for top-level paths. */
|
|
168
190
|
private _flattenedPrefix;
|
|
191
|
+
/** Nearest `@db.encrypted` ancestor of `path` (exclusive), or `undefined`. */
|
|
192
|
+
/**
|
|
193
|
+
* Indexes non-ignored descriptors by logical path and retains the JSON-parent
|
|
194
|
+
* set. Navigation relations and their descendants are skipped even when the
|
|
195
|
+
* adapter keeps them as descriptors (nested-object adapters do) — they are
|
|
196
|
+
* loaded with `$with`, never addressed as columns of this table.
|
|
197
|
+
*/
|
|
198
|
+
private _buildGuardIndexes;
|
|
169
199
|
/**
|
|
170
200
|
* Indexes `fieldDescriptors` into two lookup maps for unified
|
|
171
201
|
* read/write field classification in the RelationalFieldMapper.
|
|
@@ -244,6 +274,13 @@ interface TFieldMeta {
|
|
|
244
274
|
* present in read responses. UIs render it as a set-only input.
|
|
245
275
|
*/
|
|
246
276
|
writeOnly?: boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Present (true) when the field is index-backed (explicit `@db.index*`,
|
|
279
|
+
* primary key or unique field). Advisory only — a hint for UIs that want to
|
|
280
|
+
* steer users toward cheap sort keys; it never affects whether a `$sort`
|
|
281
|
+
* is accepted (`sortable` does). Since 0.1.128.
|
|
282
|
+
*/
|
|
283
|
+
indexed?: boolean;
|
|
247
284
|
}
|
|
248
285
|
/** Built-in CRUD operation names; map 1:1 to public method names. */
|
|
249
286
|
type TCrudOp = "query" | "pages" | "one" | "geo" | "insert" | "update" | "replace" | "remove";
|
|
@@ -543,6 +580,57 @@ interface TColumnDiff {
|
|
|
543
580
|
oldName: string;
|
|
544
581
|
conflictsWith: string;
|
|
545
582
|
}>;
|
|
583
|
+
/**
|
|
584
|
+
* The primary-key FIELD SET differs between the live table and the model
|
|
585
|
+
* (set semantics — a composite-key reorder is not a change, consistent with
|
|
586
|
+
* the schema hash). Column names are physical; a renamed PK column is
|
|
587
|
+
* compared under its new name. Only reported when the table exists.
|
|
588
|
+
* @since 0.1.128
|
|
589
|
+
*/
|
|
590
|
+
primaryKeyChanged?: TPrimaryKeyChange;
|
|
591
|
+
}
|
|
592
|
+
/** Old and new primary-key column sets of a table whose key definition moved. */
|
|
593
|
+
interface TPrimaryKeyChange {
|
|
594
|
+
/** Physical PK columns currently in the database (after rename mapping). */
|
|
595
|
+
from: string[];
|
|
596
|
+
/** Physical PK columns the model declares. */
|
|
597
|
+
to: string[];
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* A live foreign-key constraint as introspected from the database
|
|
601
|
+
* (outbound: declared on the table that owns it).
|
|
602
|
+
*/
|
|
603
|
+
interface TExistingForeignKey {
|
|
604
|
+
/** Local (referencing) columns, in constraint order. */
|
|
605
|
+
fields: string[];
|
|
606
|
+
/** Referenced table name. */
|
|
607
|
+
targetTable: string;
|
|
608
|
+
/** Referenced columns, in constraint order. */
|
|
609
|
+
targetFields: string[];
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* A live foreign key that REFERENCES a given table (inbound edge), as returned
|
|
613
|
+
* by `BaseDbAdapter.getReferencingForeignKeys(tableName)`.
|
|
614
|
+
*/
|
|
615
|
+
interface TReferencingForeignKey {
|
|
616
|
+
/** The referencing (child) table. */
|
|
617
|
+
table: string;
|
|
618
|
+
/** Referencing columns on `table`, in constraint order. */
|
|
619
|
+
fields: string[];
|
|
620
|
+
/** Referenced columns on the queried table, in constraint order. */
|
|
621
|
+
targetFields: string[];
|
|
622
|
+
}
|
|
623
|
+
/** Kind of a physical database object, as returned by `BaseDbAdapter.getObjectKind`. */
|
|
624
|
+
type TDbObjectKind = "table" | "view" | "materialized";
|
|
625
|
+
/** Options accepted by `BaseDbAdapter.ensureTable`. */
|
|
626
|
+
interface TEnsureTableOptions {
|
|
627
|
+
/**
|
|
628
|
+
* Table names whose inline FOREIGN KEY constraints must be omitted from
|
|
629
|
+
* CREATE TABLE — the constraints are added afterwards by `syncForeignKeys()`.
|
|
630
|
+
* Schema sync passes the members of a foreign-key cycle so they can be
|
|
631
|
+
* created in any order.
|
|
632
|
+
*/
|
|
633
|
+
deferForeignKeysTo?: ReadonlySet<string>;
|
|
546
634
|
}
|
|
547
635
|
/** Result of applying column diff to the database. */
|
|
548
636
|
interface TSyncColumnResult {
|
|
@@ -684,6 +772,102 @@ interface TDbRelation {
|
|
|
684
772
|
/** Junction type reference for 'via' (M:N) relations. */
|
|
685
773
|
viaType?: () => TAtscriptAnnotatedType;
|
|
686
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* Write payload for insert / patch paths: every key optional, and optional
|
|
777
|
+
* columns additionally accept `null` (an explicit NULL — `undefined` means
|
|
778
|
+
* "absent" and is dropped before the row reaches defaults or validation).
|
|
779
|
+
*/
|
|
780
|
+
type DbPatch<D> = { [K in keyof D]?: undefined extends D[K] ? D[K] | null : D[K] } & Record<string, unknown>;
|
|
781
|
+
/**
|
|
782
|
+
* Write payload for full-row replace paths: required keys stay required,
|
|
783
|
+
* optional columns additionally accept `null` (explicit NULL).
|
|
784
|
+
*/
|
|
785
|
+
type DbRow<D> = { [K in keyof D]: undefined extends D[K] ? D[K] | null : D[K] } & Record<string, unknown>;
|
|
786
|
+
/** Built-in write actions a moost-db `AsDbController` endpoint performs. */
|
|
787
|
+
type TDbWriteAction = "insert" | "insertMany" | "replace" | "replaceMany" | "update" | "updateMany";
|
|
788
|
+
/**
|
|
789
|
+
* Context handed to a write {@link TWriteOptions.guard} (since 0.1.128) — and
|
|
790
|
+
* through it to `AsDbController.guardWrite()`. The table invokes the guard
|
|
791
|
+
* exactly once, inside its own transaction, after `undefined`-pruning,
|
|
792
|
+
* defaults and validation and before encryption / nested-relation phases.
|
|
793
|
+
*/
|
|
794
|
+
interface TDbWriteGuardContext<Row = Record<string, unknown>> {
|
|
795
|
+
/** The table method the guard runs for (`insertOne` → `insert`, `insertMany` → `insertMany`, …). */
|
|
796
|
+
readonly action: TDbWriteAction;
|
|
797
|
+
/**
|
|
798
|
+
* insert/replace: validated rows with SDK-side defaults applied (plaintext,
|
|
799
|
+
* nav data still attached); update: validated patches with the identifying
|
|
800
|
+
* PK/unique fields present and `$cas` removed. Mutate in place to enrich —
|
|
801
|
+
* the table re-validates the rows after the guard.
|
|
802
|
+
*/
|
|
803
|
+
readonly rows: Row[];
|
|
804
|
+
/** Parallel to `rows`: expected version lifted from `$cas`, or `undefined`. */
|
|
805
|
+
readonly expectedVersions: ReadonlyArray<number | undefined>;
|
|
806
|
+
/**
|
|
807
|
+
* Lazy, memoised pre-image of `rows[i]` by its identifying filter, read
|
|
808
|
+
* inside the transaction. `null` when the row is missing OR when it carries
|
|
809
|
+
* no identifying key yet (e.g. auto-increment inserts) — never throws.
|
|
810
|
+
*/
|
|
811
|
+
current(i: number): Promise<Row | null>;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Context handed to a delete {@link TDeleteOptions.guard} (since 0.1.128) —
|
|
815
|
+
* and through it to `AsDbController.guardRemove()`. Runs inside the table's
|
|
816
|
+
* transaction; an id that resolves to no filter never reaches the guard
|
|
817
|
+
* (`deleteOne` answers `{ deletedCount: 0 }`).
|
|
818
|
+
*/
|
|
819
|
+
interface TDbRemoveGuardContext<Row = Record<string, unknown>> {
|
|
820
|
+
/** The id `deleteOne` was called with. */
|
|
821
|
+
readonly id: unknown;
|
|
822
|
+
/** `table.resolveIdFilter(id)` — never null here. */
|
|
823
|
+
readonly filter: FilterExpr;
|
|
824
|
+
/** Lazy, memoised pre-image of the row about to be deleted (`null` when missing). */
|
|
825
|
+
current(): Promise<Row | null>;
|
|
826
|
+
}
|
|
827
|
+
/** A validated-stage write guard — see {@link TWriteOptions.guard}. */
|
|
828
|
+
type TDbWriteGuard<Row = Record<string, unknown>> = (ctx: TDbWriteGuardContext<Row>) => void | Promise<void>;
|
|
829
|
+
/** A validated-stage delete guard — see {@link TDeleteOptions.guard}. */
|
|
830
|
+
type TDbRemoveGuard<Row = Record<string, unknown>> = (ctx: TDbRemoveGuardContext<Row>) => void | Promise<void>;
|
|
831
|
+
/** Options of `AtscriptDbTable.touchMany` (since 0.1.129). */
|
|
832
|
+
interface TTouchManyOptions {
|
|
833
|
+
/**
|
|
834
|
+
* `'all'` (default): every key must match its stored version — a stale or
|
|
835
|
+
* missing row throws `DbError("CAS_MISMATCH")` and no version moves.
|
|
836
|
+
* `'any'`: bump whatever matches and report the honest counts.
|
|
837
|
+
*/
|
|
838
|
+
require?: "all" | "any";
|
|
839
|
+
}
|
|
840
|
+
/** Options of `insertOne/Many`, `replaceOne` / `bulkReplace`, `updateOne` / `bulkUpdate`. */
|
|
841
|
+
interface TWriteOptions<Row = Record<string, unknown>> {
|
|
842
|
+
/** Nested-relation write recursion limit (default 3). */
|
|
843
|
+
maxDepth?: number;
|
|
844
|
+
/**
|
|
845
|
+
* Validated-stage guard (since 0.1.128): invoked exactly once inside the
|
|
846
|
+
* table's transaction, after defaults + validation and before encryption
|
|
847
|
+
* and nested-relation phases, with the rows the table is about to write.
|
|
848
|
+
* Rows may be enriched in place — they are validated again afterwards. A
|
|
849
|
+
* throw rolls the transaction back and propagates unchanged. Never runs
|
|
850
|
+
* for the nested re-entries a deep write performs on related tables.
|
|
851
|
+
*/
|
|
852
|
+
guard?: TDbWriteGuard<Row>;
|
|
853
|
+
}
|
|
854
|
+
/** Options of `deleteOne`. */
|
|
855
|
+
interface TDeleteOptions<Row = Record<string, unknown>> {
|
|
856
|
+
/**
|
|
857
|
+
* Validated-stage guard (since 0.1.128): invoked inside the table's
|
|
858
|
+
* transaction after the id resolved to a filter and before cascade /
|
|
859
|
+
* delete. A throw rolls the transaction back and propagates unchanged.
|
|
860
|
+
*/
|
|
861
|
+
guard?: TDbRemoveGuard<Row>;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Adds `null` to every optional property of `O`. Optional columns store SQL
|
|
865
|
+
* NULL / Mongo null, and the runtime validator accepts `null` for optional
|
|
866
|
+
* props — so filter shapes (`{ note: null }`, `{ note: { $ne: null } }`) and
|
|
867
|
+
* row shapes must admit it at the type level too. Homomorphic: keys and
|
|
868
|
+
* required properties are unchanged; applying it twice is a no-op.
|
|
869
|
+
*/
|
|
870
|
+
type NullableOptional<O> = { [K in keyof O]: undefined extends O[K] ? O[K] | null : O[K] };
|
|
687
871
|
//#endregion
|
|
688
872
|
//#region src/base-adapter.d.ts
|
|
689
873
|
/**
|
|
@@ -710,6 +894,15 @@ interface TDbRelation {
|
|
|
710
894
|
* - `this._table.isView` — whether this is a view (vs a table)
|
|
711
895
|
*/
|
|
712
896
|
declare abstract class BaseDbAdapter {
|
|
897
|
+
/**
|
|
898
|
+
* The readable this adapter serves. UNSET on an administrative adapter:
|
|
899
|
+
* `DbSpace` creates one from the factory without a readable for the
|
|
900
|
+
* name-taking schema-sync primitives (`dropTableByName`, `dropViewByName`,
|
|
901
|
+
* `dropTablesByName`, `getReferencingForeignKeys`, `getObjectKind`,
|
|
902
|
+
* `getExistingColumnsForTable`, `hasRows(tableName)`), so those must derive
|
|
903
|
+
* everything — the schema included — from the driver/connection, never from
|
|
904
|
+
* `this._table`.
|
|
905
|
+
*/
|
|
713
906
|
protected _table: AtscriptDbReadable<any, any, any, any, any, any, any>;
|
|
714
907
|
/**
|
|
715
908
|
* Resolves the correct insertedId: prefers the user-supplied PK value
|
|
@@ -738,7 +931,9 @@ declare abstract class BaseDbAdapter {
|
|
|
738
931
|
protected _log(...args: unknown[]): void;
|
|
739
932
|
/**
|
|
740
933
|
* Runs `fn` inside a database transaction. Nested calls (from related tables
|
|
741
|
-
* within the same async chain) reuse the existing transaction automatically
|
|
934
|
+
* within the same async chain) reuse the existing transaction automatically
|
|
935
|
+
* — "existing" meaning a transaction of the same {@link _transactionOwner};
|
|
936
|
+
* inside another adapter family's transaction this opens its own.
|
|
742
937
|
*
|
|
743
938
|
* The generic layer handles nesting detection via `AsyncLocalStorage`.
|
|
744
939
|
* Adapters override `_beginTransaction`, `_commitTransaction`, and
|
|
@@ -746,7 +941,17 @@ declare abstract class BaseDbAdapter {
|
|
|
746
941
|
*/
|
|
747
942
|
withTransaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
748
943
|
/**
|
|
749
|
-
*
|
|
944
|
+
* The object a transaction state is branded with (since 0.1.128). Every
|
|
945
|
+
* adapter instance that returns the same owner shares one transaction —
|
|
946
|
+
* override to return the driver / pool / client the adapter was constructed
|
|
947
|
+
* with, so all tables of a space join it. The default (the adapter class)
|
|
948
|
+
* suits adapters without a connection object (in-memory, mocks).
|
|
949
|
+
*/
|
|
950
|
+
protected _transactionOwner(): unknown;
|
|
951
|
+
/**
|
|
952
|
+
* Returns the opaque transaction state of THIS adapter's owner from the
|
|
953
|
+
* current async context — `undefined` when no transaction is open or only
|
|
954
|
+
* another adapter family's transaction is (its state is never handed out).
|
|
750
955
|
* Adapters use this to retrieve DB-specific state (e.g., MongoDB `ClientSession`).
|
|
751
956
|
*/
|
|
752
957
|
protected _getTransactionState(): unknown;
|
|
@@ -755,7 +960,7 @@ declare abstract class BaseDbAdapter {
|
|
|
755
960
|
* Adapters that override `withTransaction` (e.g., to use MongoDB's
|
|
756
961
|
* `session.withTransaction()` Convenient API) use this to set up the
|
|
757
962
|
* shared context so that nested adapters see the same session.
|
|
758
|
-
* If a context already exists (nesting), it's reused.
|
|
963
|
+
* If a context of the same owner already exists (nesting), it's reused.
|
|
759
964
|
*/
|
|
760
965
|
protected _runInTransactionContext<T>(state: unknown, fn: () => Promise<T>): Promise<T>;
|
|
761
966
|
/**
|
|
@@ -797,11 +1002,14 @@ declare abstract class BaseDbAdapter {
|
|
|
797
1002
|
*/
|
|
798
1003
|
supportsNestedObjects(): boolean;
|
|
799
1004
|
/**
|
|
800
|
-
* Whether the DB engine
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
1005
|
+
* Whether the DB engine carries static `@db.default "value"` defaults in
|
|
1006
|
+
* its DDL (`DEFAULT` clauses in `CREATE TABLE`).
|
|
1007
|
+
*
|
|
1008
|
+
* @deprecated since 0.1.128 — no longer consulted: the table layer fills
|
|
1009
|
+
* static value defaults SDK-side on every adapter before validation, and the
|
|
1010
|
+
* SQL adapters emit their DDL `DEFAULT` clauses regardless of this flag.
|
|
1011
|
+
* Kept as a capability hint for tooling; nothing in the generic layer
|
|
1012
|
+
* branches on it.
|
|
805
1013
|
*/
|
|
806
1014
|
supportsNativeValueDefaults(): boolean;
|
|
807
1015
|
/**
|
|
@@ -838,9 +1046,12 @@ declare abstract class BaseDbAdapter {
|
|
|
838
1046
|
canFilterField(fd: TDbFieldMeta): boolean;
|
|
839
1047
|
/**
|
|
840
1048
|
* Whether this adapter can sort by a given field.
|
|
841
|
-
* Default: scalar columns yes
|
|
842
|
-
* (min/max element) is a footgun for generic
|
|
843
|
-
* stays conservative even for adapters that
|
|
1049
|
+
* Default: scalar columns yes; JSON-stored columns, `@db.json` objects and
|
|
1050
|
+
* arrays no. Mongo's array sort (min/max element) is a footgun for generic
|
|
1051
|
+
* UI sort headers, so the default stays conservative even for adapters that
|
|
1052
|
+
* technically support it — the veto keys on `designType` as well as
|
|
1053
|
+
* `storage` because nested-object adapters keep arrays / `@db.json` values
|
|
1054
|
+
* inline as `storage: 'column'` (since 0.1.128).
|
|
844
1055
|
*/
|
|
845
1056
|
canSortField(fd: TDbFieldMeta): boolean;
|
|
846
1057
|
/**
|
|
@@ -961,6 +1172,14 @@ declare abstract class BaseDbAdapter {
|
|
|
961
1172
|
dropIndex(name: string): Promise<void>;
|
|
962
1173
|
prefix?: string;
|
|
963
1174
|
shouldSkipType?(type: TDbIndex["type"]): boolean;
|
|
1175
|
+
/**
|
|
1176
|
+
* Renders one desired key part for the drift comparison, so adapters whose
|
|
1177
|
+
* `listExisting` reports more than a bare column name (e.g. MySQL's
|
|
1178
|
+
* `col(255)` key-length prefix) can render the model side identically.
|
|
1179
|
+
* Default: the column name.
|
|
1180
|
+
* @since 0.1.128
|
|
1181
|
+
*/
|
|
1182
|
+
renderDesiredColumn?(index: TDbIndex, field: TDbIndex["fields"][number]): string;
|
|
964
1183
|
/**
|
|
965
1184
|
* Index types declared on the model but not supported by this adapter —
|
|
966
1185
|
* warns and skips (models stay portable; sync never errors on these).
|
|
@@ -1090,8 +1309,14 @@ declare abstract class BaseDbAdapter {
|
|
|
1090
1309
|
/**
|
|
1091
1310
|
* Ensures the table exists in the database, creating it if needed.
|
|
1092
1311
|
* Uses `this._table.tableName`, `this._table.schema`, etc.
|
|
1312
|
+
*
|
|
1313
|
+
* @param opts - Optional (since 0.1.128). Relational adapters that emit
|
|
1314
|
+
* inline FOREIGN KEY constraints must omit those whose target is in
|
|
1315
|
+
* `opts.deferForeignKeysTo` — schema sync adds them afterwards through
|
|
1316
|
+
* {@link syncForeignKeys} so a foreign-key cycle can be created in any
|
|
1317
|
+
* order. Adapters without inline constraints ignore the parameter.
|
|
1093
1318
|
*/
|
|
1094
|
-
abstract ensureTable(): Promise<void>;
|
|
1319
|
+
abstract ensureTable(opts?: TEnsureTableOptions): Promise<void>;
|
|
1095
1320
|
/**
|
|
1096
1321
|
* Synchronizes foreign key constraints between Atscript definitions and the database.
|
|
1097
1322
|
* Uses `this._table.foreignKeys` for the full FK definitions.
|
|
@@ -1128,8 +1353,13 @@ declare abstract class BaseDbAdapter {
|
|
|
1128
1353
|
*
|
|
1129
1354
|
* Returns undefined if the adapter cannot introspect table options.
|
|
1130
1355
|
* In that case, schema sync falls back to stored snapshot.
|
|
1356
|
+
*
|
|
1357
|
+
* @param tableName - Introspect this table instead of the adapter's own
|
|
1358
|
+
* (schema sync passes the OLD name of a table that is about to be
|
|
1359
|
+
* renamed, as for `getExistingColumnsForTable`). Defaults to the bound
|
|
1360
|
+
* table.
|
|
1131
1361
|
*/
|
|
1132
|
-
getExistingTableOptions?(): Promise<TExistingTableOption[]>;
|
|
1362
|
+
getExistingTableOptions?(tableName?: string): Promise<TExistingTableOption[]>;
|
|
1133
1363
|
/**
|
|
1134
1364
|
* Applies non-destructive table option changes (e.g., MySQL ALTER TABLE ENGINE=X).
|
|
1135
1365
|
* Called for each non-destructive change in the diff.
|
|
@@ -1205,6 +1435,58 @@ declare abstract class BaseDbAdapter {
|
|
|
1205
1435
|
* Optional — only relational adapters implement this.
|
|
1206
1436
|
*/
|
|
1207
1437
|
dropViewByName?(viewName: string): Promise<void>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Drops several tables that reference each other (a foreign-key cycle) as
|
|
1440
|
+
* one operation. Schema sync only calls this for cycles whose members are
|
|
1441
|
+
* ALL being removed. Default: {@link dropTableByName} in the given order —
|
|
1442
|
+
* enough for engines that tolerate it (SQLite with FK checks off, MySQL with
|
|
1443
|
+
* FOREIGN_KEY_CHECKS=0); PostgreSQL overrides it with one multi-table
|
|
1444
|
+
* `DROP TABLE a, b` statement.
|
|
1445
|
+
* @since 0.1.128
|
|
1446
|
+
*/
|
|
1447
|
+
dropTablesByName(tableNames: string[]): Promise<void>;
|
|
1448
|
+
/**
|
|
1449
|
+
* Whether the table has at least one row. Schema sync uses it in the
|
|
1450
|
+
* pre-flight phase to refuse a primary-key change on a populated table.
|
|
1451
|
+
* Override with an EXISTS/LIMIT 1 probe — this default is `count() > 0`,
|
|
1452
|
+
* a full scan on some engines, and it can only answer for the adapter's
|
|
1453
|
+
* OWN table: for another `tableName` (or on an administrative adapter
|
|
1454
|
+
* without a readable) it returns `undefined` ("cannot tell"), which schema
|
|
1455
|
+
* sync treats as a refusal.
|
|
1456
|
+
*
|
|
1457
|
+
* @param tableName - Check this table instead of the adapter's own (schema
|
|
1458
|
+
* sync passes the OLD name of a table that is about to be renamed).
|
|
1459
|
+
* @returns `true`/`false`, or `undefined` when the adapter cannot tell.
|
|
1460
|
+
* @since 0.1.128
|
|
1461
|
+
*/
|
|
1462
|
+
hasRows(tableName?: string): Promise<boolean | undefined>;
|
|
1463
|
+
/**
|
|
1464
|
+
* Live foreign keys that REFERENCE `tableName` (inbound edges), from any
|
|
1465
|
+
* table in the database — including tables whose models are no longer in
|
|
1466
|
+
* the sync inventory. Schema sync uses it to order drops (children before
|
|
1467
|
+
* parents), to refuse dropping a table that an unmanaged table still
|
|
1468
|
+
* references, and to refuse a primary-key change that a live FK depends on.
|
|
1469
|
+
* Optional — engines without physical foreign keys omit it.
|
|
1470
|
+
* @since 0.1.128
|
|
1471
|
+
*/
|
|
1472
|
+
getReferencingForeignKeys?(tableName: string): Promise<TReferencingForeignKey[]>;
|
|
1473
|
+
/**
|
|
1474
|
+
* Kind of the physical object stored under `name`, or `undefined` when
|
|
1475
|
+
* nothing exists. Schema sync refuses a run when a physical table sits
|
|
1476
|
+
* where a managed view is declared (or a view where a table is declared)
|
|
1477
|
+
* instead of silently creating/skipping over it.
|
|
1478
|
+
* Optional — adapters without the method skip the check.
|
|
1479
|
+
* @since 0.1.128
|
|
1480
|
+
*/
|
|
1481
|
+
getObjectKind?(name: string): Promise<TDbObjectKind | undefined>;
|
|
1482
|
+
/**
|
|
1483
|
+
* Rewrites the table's primary key from `change.from` to `change.to`.
|
|
1484
|
+
* Called only on an EMPTY table (schema sync refuses populated ones) after
|
|
1485
|
+
* new columns were added and before stale columns are dropped, so both
|
|
1486
|
+
* column sets exist. Adapters without it fall back to {@link recreateTable}.
|
|
1487
|
+
* @since 0.1.128
|
|
1488
|
+
*/
|
|
1489
|
+
rebuildPrimaryKey?(change: TPrimaryKeyChange): Promise<void>;
|
|
1208
1490
|
/**
|
|
1209
1491
|
* Renames a table/collection from `oldName` to the adapter's current table name.
|
|
1210
1492
|
* Used by schema sync when `@db.table.renamed` is present.
|
|
@@ -1422,7 +1704,7 @@ declare function resolveDesignType(fieldType: TAtscriptAnnotatedType): string;
|
|
|
1422
1704
|
* {@link AtscriptDbTable} (adds write operations) and {@link AtscriptDbView}
|
|
1423
1705
|
* (adds view plan/DDL).
|
|
1424
1706
|
*/
|
|
1425
|
-
declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>, _FlatType = FlatOf<T
|
|
1707
|
+
declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = TAtscriptDataType<T>, _FlatType = NullableOptional<FlatOf<T>>, A extends BaseDbAdapter = BaseDbAdapter, IdType = PrimaryKeyOf<T>, OwnProps = NullableOptional<OwnPropsOf<T>>, NavType extends Record<string, unknown> = NavPropsOf<T>> {
|
|
1426
1708
|
protected readonly _type: T;
|
|
1427
1709
|
protected readonly adapter: A;
|
|
1428
1710
|
protected readonly logger: TGenericLogger;
|
|
@@ -1733,4 +2015,4 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
1733
2015
|
}, thisTableName: string, alias?: string): TDbForeignKey | undefined;
|
|
1734
2016
|
}
|
|
1735
2017
|
//#endregion
|
|
1736
|
-
export {
|
|
2018
|
+
export { TDbWriteAction as $, TCrudPermissions as A, findAncestorInSet as At, TDbForeignKey as B, NullableOptional as C, TWriteOptions as Ct, TCascadeTarget as D, UniqueryControls$1 as Dt, TCascadeResolver as E, Uniquery$1 as Et, TDbCollation as F, UniquSelect as Ft, TDbInsertResult as G, TDbIndexField as H, TDbDefaultFn as I, TDbRelation as J, TDbObjectKind as K, TDbDefaultValue as L, TDbActionIntent as M, isGeoPointType as Mt, TDbActionLevel as N, NoopLogger as Nt, TColumnDiff as O, WithRelation$1 as Ot, TDbActionProcessor as P, TGenericLogger as Pt, TDbUpdateResult as Q, TDbDeleteResult as R, NavPropsOf$1 as S, TValueFormatterPair as St, PrimaryKeyOf$1 as T, TypedWithRelation as Tt, TDbIndexType as U, TDbIndex as V, TDbInsertManyResult as W, TDbRemoveGuardContext as X, TDbRemoveGuard as Y, TDbStorageType as Z, DbQuery as _, TSearchIndexInfo as _t, TDbEncryptionOptions as a, TExistingForeignKey as at, FilterExpr$1 as b, TTableResolver as bt, BaseDbAdapter as c, TFkLookupResolver as ct, AggregateFn as d, TIdentification as dt, TDbWriteGuard as et, AggregateQuery$1 as f, TMetaResponse as ft, DbPatch as g, TRelationInfo as gt, DbControls as h, TReferencingForeignKey as ht, DbEncryption as i, TExistingColumn as it, TDbActionInfo as j, isGeoIndexableType as jt, TCrudOp as k, TableMetadata as kt, AggregateControls as l, TFkLookupTarget as lt, AtscriptDbWritable as m, TPrimaryKeyChange as mt, DbResponse as n, TDeleteOptions as nt, DocumentFieldMapper as o, TExistingTableOption as ot, AggregateResult as p, TMetadataOverrides as pt, TDbReferentialAction as q, resolveDesignType as r, TEnsureTableOptions as rt, FieldMappingStrategy as s, TFieldMeta as st, AtscriptDbReadable as t, TDbWriteGuardContext as tt, AggregateExpr$1 as u, TIdDescriptor as ut, DbRow as v, TSyncColumnResult as vt, OwnPropsOf$1 as w, TWriteTableResolver as wt, FlatOf$1 as x, TTouchManyOptions as xt, FieldOpsFor as y, TTableOptionDiff as yt, TDbFieldMeta as z };
|