@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { r as DbError } from "./db-error-B_DRL1E9.cjs";
|
|
1
2
|
import { f as TFieldOps } from "./ops-AqhV7s9o.cjs";
|
|
2
3
|
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, NullsPlacement, NullsPlacement as NullsPlacement$1, RelationOp, ResolvedBucket, ResolvedRowOrderKey, ResolvedSelectExpr, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
3
4
|
import { AtscriptExprNode, AtscriptExprNode as AtscriptExprNode$1, AtscriptOrderItem, AtscriptQueryComparison, AtscriptQueryFieldRef, AtscriptQueryFieldRef as AtscriptQueryFieldRef$1, AtscriptQueryNode, AtscriptQueryNode as AtscriptQueryNode$1, AtscriptRef, 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";
|
|
@@ -761,6 +762,14 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
761
762
|
* @internal Adapter-facing surface; not part of the consumer API.
|
|
762
763
|
*/
|
|
763
764
|
get versionColumnPhysical(): string | undefined;
|
|
765
|
+
/**
|
|
766
|
+
* Physical column names of the `@db.onUpdate.inc` fields (since 0.1.162):
|
|
767
|
+
* adapters add `col = col + 1` to every replace. Empty when there are none.
|
|
768
|
+
*
|
|
769
|
+
* @internal Adapter-facing surface; not part of the consumer API.
|
|
770
|
+
*/
|
|
771
|
+
get onUpdateIncPhysical(): readonly string[];
|
|
772
|
+
private _onUpdateIncPhysical?;
|
|
764
773
|
/**
|
|
765
774
|
* Logical paths of the `@db.column.version.exempt` fields, including objects
|
|
766
775
|
* whose direct children are all exempt. A patch that writes only these (and
|
|
@@ -860,7 +869,7 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
860
869
|
* `query` with {@link _withPkTieBreak} applied and its `$nulls` resolved
|
|
861
870
|
* ({@link NullsSource.resolveSort}) — a copy when either changes.
|
|
862
871
|
*/
|
|
863
|
-
|
|
872
|
+
protected _withStableSort(query: Uniquery): Uniquery;
|
|
864
873
|
private _nullsCache?;
|
|
865
874
|
/** NULL-placement resolution for this table (`$nulls`, `@db.sort.nulls`; since 0.1.153). */
|
|
866
875
|
private get _nulls();
|
|
@@ -949,18 +958,43 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
949
958
|
* Creates a new validator with custom options.
|
|
950
959
|
*/
|
|
951
960
|
createValidator(opts?: Partial<TValidatorOptions>): Validator<T, DataType>;
|
|
961
|
+
/**
|
|
962
|
+
* The row lock a `findOne` / `findMany` asked for (`opts.lock`, since
|
|
963
|
+
* 0.1.162), validated — `undefined` when none was asked for.
|
|
964
|
+
*
|
|
965
|
+
* @throws DbError `INVALID_QUERY` — bad `lock` / `wait` value, a view, a
|
|
966
|
+
* grouped / aggregate / `$count` read, or no `withTransaction` scope of
|
|
967
|
+
* this table's adapter; `LOCK_NOT_SUPPORTED` — the adapter cannot lock.
|
|
968
|
+
*/
|
|
969
|
+
private _readLock;
|
|
952
970
|
/**
|
|
953
971
|
* Finds a single record matching the query.
|
|
954
972
|
* The return type automatically excludes nav props unless they are
|
|
955
973
|
* explicitly requested via `$with`.
|
|
974
|
+
*
|
|
975
|
+
* `opts.lock` (since 0.1.162) makes it a locking read — see
|
|
976
|
+
* {@link TReadLockOptions}:
|
|
977
|
+
*
|
|
978
|
+
* ```typescript
|
|
979
|
+
* await adapter.withTransaction(async () => {
|
|
980
|
+
* const order = await orders.findOne({ filter: { id }, controls: {} }, { lock: 'update' })
|
|
981
|
+
* // … the row stays locked until the transaction ends
|
|
982
|
+
* })
|
|
983
|
+
* ```
|
|
956
984
|
*/
|
|
957
|
-
findOne<Q extends Uniquery<OwnProps, NavType>>(query: Q): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
985
|
+
findOne<Q extends Uniquery<OwnProps, NavType>>(query: Q, opts?: TReadLockOptions): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
986
|
+
/** {@link findOne} of a guarded query with an already validated lock. */
|
|
987
|
+
private _findOne;
|
|
958
988
|
/**
|
|
959
989
|
* Finds all records matching the query.
|
|
960
990
|
* The return type automatically excludes nav props unless they are
|
|
961
991
|
* explicitly requested via `$with`.
|
|
992
|
+
*
|
|
993
|
+
* `opts.lock` (since 0.1.162) makes it a locking read — see
|
|
994
|
+
* {@link TReadLockOptions}. Sort by the primary key when locking several
|
|
995
|
+
* rows, so concurrent transactions take the locks in the same order.
|
|
962
996
|
*/
|
|
963
|
-
findMany<Q extends Uniquery<OwnProps, NavType>>(query: Q): Promise<Array<DbResponse<DataType, NavType, Q>>>;
|
|
997
|
+
findMany<Q extends Uniquery<OwnProps, NavType>>(query: Q, opts?: TReadLockOptions): Promise<Array<DbResponse<DataType, NavType, Q>>>;
|
|
964
998
|
/**
|
|
965
999
|
* `findMany` for the generic `$with` loader. With `partitionBy` (logical
|
|
966
1000
|
* fields), `$skip` / `$limit` apply per group of rows sharing those fields'
|
|
@@ -1118,11 +1152,14 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
1118
1152
|
*
|
|
1119
1153
|
* // With relations — only requested nav props appear
|
|
1120
1154
|
* const user = await table.findById('123', { controls: { $with: [{ name: 'posts' }] } })
|
|
1155
|
+
*
|
|
1156
|
+
* // Locking read inside a transaction (since 0.1.162) — see TReadLockOptions
|
|
1157
|
+
* const user = await table.findById('123', { lock: 'update' })
|
|
1121
1158
|
* ```
|
|
1122
1159
|
*/
|
|
1123
1160
|
findById<Q extends {
|
|
1124
1161
|
controls?: UniqueryControls<OwnProps, NavType>;
|
|
1125
|
-
} = Record<string, never>>(id: IdType, query?: Q): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
1162
|
+
} = Record<string, never>>(id: IdType, query?: Q & TReadLockOptions): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
1126
1163
|
/**
|
|
1127
1164
|
* Reads the ONE row an id addresses — resolved exactly like
|
|
1128
1165
|
* {@link resolveRowFilter} (primary key first, `opts.scope` /
|
|
@@ -1132,11 +1169,18 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
1132
1169
|
* must also match `opts.scope` (an out-of-scope row answers `null` like a
|
|
1133
1170
|
* missing one).
|
|
1134
1171
|
*
|
|
1172
|
+
* `opts.lock` / `opts.wait` (since 0.1.162) lock the row found — see
|
|
1173
|
+
* {@link TReadLockOptions}. The id is then resolved to its one row first
|
|
1174
|
+
* (an unlocked read, exactly like {@link resolveRowFilter}) and that row is
|
|
1175
|
+
* read with the lock: with `wait: 'skipLocked'` a row another transaction
|
|
1176
|
+
* holds answers `null` — never a lower-precedence identification naming a
|
|
1177
|
+
* different row.
|
|
1178
|
+
*
|
|
1135
1179
|
* @since 0.1.143
|
|
1136
1180
|
*/
|
|
1137
1181
|
findOneByRow<Q extends {
|
|
1138
1182
|
controls?: UniqueryControls<OwnProps, NavType>;
|
|
1139
|
-
} = Record<string, never>>(id: unknown, opts?: TRowResolveOptions & Q): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
1183
|
+
} = Record<string, never>>(id: unknown, opts?: TRowResolveOptions & TReadLockOptions & Q): Promise<DbResponse<DataType, NavType, Q> | null>;
|
|
1140
1184
|
/**
|
|
1141
1185
|
* Resolve an id value (scalar or object) into a {@link FilterExpr} using the
|
|
1142
1186
|
* same identifications as {@link findById}. Public so callers can
|
|
@@ -1424,9 +1468,77 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
|
|
|
1424
1468
|
* calling the guard.
|
|
1425
1469
|
*/
|
|
1426
1470
|
deleteOne(id: IdType, opts?: TDeleteOptions<DataType>): Promise<TDbDeleteResult>;
|
|
1427
|
-
|
|
1471
|
+
/**
|
|
1472
|
+
* Patches every row matching `filter` with `data` (own fields only — no
|
|
1473
|
+
* relations, no `$cas`). Since 0.1.162 the payload is validated in `patch`
|
|
1474
|
+
* mode, exactly like {@link updateOne}: a type mismatch, `null` on a
|
|
1475
|
+
* non-nullable field, `@meta.required` or `@expect.*` failures throw a
|
|
1476
|
+
* `ValidatorError` before any statement runs.
|
|
1477
|
+
*
|
|
1478
|
+
* `opts.limit` (since 0.1.162) bounds the write to the first `limit` matching
|
|
1479
|
+
* rows in `opts.sort` order (default: primary key ascending; the primary key
|
|
1480
|
+
* always breaks ties). Loop until `matchedCount === 0` to process every
|
|
1481
|
+
* match in batches. Not exposed over HTTP.
|
|
1482
|
+
*/
|
|
1483
|
+
updateMany(filter: FilterExpr<FlatType>, data: DbPatch<DataType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbUpdateResult>;
|
|
1484
|
+
/**
|
|
1485
|
+
* Replaces the own fields of every row matching `filter` with `data`. The
|
|
1486
|
+
* payload is validated in `replace` mode (since 0.1.162) — every required
|
|
1487
|
+
* field must be present — except the primary key, which the filter
|
|
1488
|
+
* replaces as a row picker.
|
|
1489
|
+
*/
|
|
1428
1490
|
replaceMany(filter: FilterExpr<FlatType>, data: DbRow<DataType>): Promise<TDbUpdateResult>;
|
|
1429
|
-
|
|
1491
|
+
/**
|
|
1492
|
+
* Deletes every row matching `filter` (application-level cascades run first
|
|
1493
|
+
* where the adapter has no native foreign keys).
|
|
1494
|
+
*
|
|
1495
|
+
* `opts.limit` (since 0.1.162) bounds the delete to the first `limit`
|
|
1496
|
+
* matching rows in `opts.sort` order (default: primary key ascending; the
|
|
1497
|
+
* primary key always breaks ties) — for retention sweeps that keep each
|
|
1498
|
+
* statement small. Loop until `deletedCount === 0`, not until it is below
|
|
1499
|
+
* `limit`: a concurrent writer can make one round delete fewer rows while
|
|
1500
|
+
* matches remain. Not exposed over HTTP.
|
|
1501
|
+
*/
|
|
1502
|
+
deleteMany(filter: FilterExpr<FlatType>, opts?: TBulkWriteOptions<FlatType>): Promise<TDbDeleteResult>;
|
|
1503
|
+
/**
|
|
1504
|
+
* Runs a bounded write. `native` (default: `supportsWriteLimit()`) hands
|
|
1505
|
+
* `write` the physical filter and the bound; otherwise the primary keys of
|
|
1506
|
+
* the picked rows are read first and `write` gets `filter AND keys` per
|
|
1507
|
+
* key batch (no bound) — a pick that finds nothing writes nothing.
|
|
1508
|
+
*
|
|
1509
|
+
* When the write affected no rows although a row still matches — a
|
|
1510
|
+
* concurrent transaction deleted or changed the picked rows between the
|
|
1511
|
+
* pick and the write — it runs again, at most
|
|
1512
|
+
* {@link BOUNDED_WRITE_RETRIES} more times; an emulated write's next pick
|
|
1513
|
+
* is that check. Rows still matching after the last attempt throw a
|
|
1514
|
+
* retryable `SERIALIZATION_FAILURE`. So `0` means nothing matched (a loop
|
|
1515
|
+
* until `0` cannot stop early); fewer than `limit` stays possible.
|
|
1516
|
+
* A native write whose adapter reports `writeLimitIsAtomic()` is never
|
|
1517
|
+
* re-checked.
|
|
1518
|
+
*/
|
|
1519
|
+
private _runBounded;
|
|
1520
|
+
/** Whether any row still matches a bounded write's filter (a one-row key read). */
|
|
1521
|
+
private _boundStillMatches;
|
|
1522
|
+
/**
|
|
1523
|
+
* Application-level cascade, then the delete. `translate` maps `filter` to
|
|
1524
|
+
* the adapter's physical filter (identity for an already-physical one).
|
|
1525
|
+
*/
|
|
1526
|
+
private _cascadeDelete;
|
|
1527
|
+
/**
|
|
1528
|
+
* Validates `opts` of a bounded `updateMany` / `deleteMany` and returns the
|
|
1529
|
+
* translated read of the rows it picks (filter, order with the primary-key
|
|
1530
|
+
* tie-breaker, `limit`, primary-key projection), or `undefined` when the
|
|
1531
|
+
* write is unbounded.
|
|
1532
|
+
*/
|
|
1533
|
+
private _writeBound;
|
|
1534
|
+
/** `updateMany` / `replaceMany` write the table's own fields only. */
|
|
1535
|
+
private _rejectNavWrite;
|
|
1536
|
+
/**
|
|
1537
|
+
* A logical patch → the adapter's physical `{ update, ops }`: nested
|
|
1538
|
+
* merge-strategy objects decomposed into dot-paths (so nested field ops are
|
|
1539
|
+
* caught), field ops separated, keys translated.
|
|
1540
|
+
*/
|
|
1541
|
+
private _translatePatch;
|
|
1430
1542
|
/**
|
|
1431
1543
|
* Synchronizes indexes between Atscript definitions and the database.
|
|
1432
1544
|
*/
|
|
@@ -1566,7 +1678,11 @@ declare class AtscriptDbTable<T extends TAtscriptAnnotatedType = TAtscriptAnnota
|
|
|
1566
1678
|
* them once the patch is known to write something.
|
|
1567
1679
|
*/
|
|
1568
1680
|
private _stampOnUpdate;
|
|
1569
|
-
/**
|
|
1681
|
+
/**
|
|
1682
|
+
* Sets the top-level `@db.onUpdate.now` columns of a non-empty patch to
|
|
1683
|
+
* `now` and increments its `@db.onUpdate.inc` counters (`$inc: 1`).
|
|
1684
|
+
* `force`: stamp an empty patch too (a touch writes the row).
|
|
1685
|
+
*/
|
|
1570
1686
|
private _stampTopLevel;
|
|
1571
1687
|
/** {@link _nestedDefaultFillable} per nested default path. */
|
|
1572
1688
|
private _fillableDefaults?;
|
|
@@ -1738,6 +1854,13 @@ interface TViewSource {
|
|
|
1738
1854
|
designType: string;
|
|
1739
1855
|
/** Set for a relational object stored as one column per leaf. */
|
|
1740
1856
|
flattened?: true;
|
|
1857
|
+
/**
|
|
1858
|
+
* Set when the path is itself a JSON-stored column (relational) — a
|
|
1859
|
+
* `@db.json` field, an array or a structured mixed union — so
|
|
1860
|
+
* {@link column} holds its JSON text, not the typed value.
|
|
1861
|
+
* @since 0.1.162
|
|
1862
|
+
*/
|
|
1863
|
+
jsonColumn?: true;
|
|
1741
1864
|
/**
|
|
1742
1865
|
* `true` when the value may be absent: the path or an ancestor segment is
|
|
1743
1866
|
* optional, or it reads inside a JSON-stored value.
|
|
@@ -1797,6 +1920,9 @@ interface TViewColumnMapping {
|
|
|
1797
1920
|
/**
|
|
1798
1921
|
* Set when the source is a primitive leaf inside a JSON column
|
|
1799
1922
|
* ({@link sourceColumn}): the path within it and the leaf's declared type.
|
|
1923
|
+
* Since 0.1.162 also set, with an empty `path` (the JSON root), when the
|
|
1924
|
+
* source is itself a primitive `@db.json` column — the view reads its typed
|
|
1925
|
+
* value, not the JSON text.
|
|
1800
1926
|
* @since 0.1.136
|
|
1801
1927
|
*/
|
|
1802
1928
|
json?: {
|
|
@@ -2140,8 +2266,74 @@ declare const ALL_BUCKET_UNITS: ReadonlySet<BucketUnit>;
|
|
|
2140
2266
|
* @since 0.1.147
|
|
2141
2267
|
*/
|
|
2142
2268
|
type TViewCapability = "compute" | "firstJoin";
|
|
2269
|
+
/**
|
|
2270
|
+
* Every isolation level, weakest first — what an adapter that provides them
|
|
2271
|
+
* all returns from `isolationLevels()`. @since 0.1.162
|
|
2272
|
+
*/
|
|
2273
|
+
declare const ALL_ISOLATION_LEVELS: ReadonlySet<TDbIsolationLevel>;
|
|
2143
2274
|
/** Every view capability — what the bundled adapters return from `viewCapabilities()`. @since 0.1.147 */
|
|
2144
2275
|
declare const ALL_VIEW_CAPABILITIES: ReadonlySet<TViewCapability>;
|
|
2276
|
+
/**
|
|
2277
|
+
* What an adapter hands `BaseDbAdapter.syncIndexesWithDiff`: the three
|
|
2278
|
+
* DB-specific primitives plus how to compare and skip.
|
|
2279
|
+
* @since 0.1.162 (inline before)
|
|
2280
|
+
*/
|
|
2281
|
+
interface TIndexDiffOptions {
|
|
2282
|
+
/**
|
|
2283
|
+
* Existing indexes. When `columns` is provided (ordered column names),
|
|
2284
|
+
* plain/unique indexes whose definition no longer matches the model are
|
|
2285
|
+
* dropped and recreated — a name match alone is not enough (e.g. a
|
|
2286
|
+
* composite index that gained or lost a member keeps its name).
|
|
2287
|
+
*/
|
|
2288
|
+
listExisting(): Promise<Array<{
|
|
2289
|
+
name: string;
|
|
2290
|
+
columns?: string[];
|
|
2291
|
+
}>>;
|
|
2292
|
+
createIndex(index: TDbIndex): Promise<void>;
|
|
2293
|
+
dropIndex(name: string): Promise<void>;
|
|
2294
|
+
prefix?: string;
|
|
2295
|
+
/**
|
|
2296
|
+
* Renders one desired key part for the drift comparison, so adapters whose
|
|
2297
|
+
* `listExisting` reports more than a bare column name (e.g. MySQL's
|
|
2298
|
+
* `col(255)` key-length prefix) can render the model side identically.
|
|
2299
|
+
* Default: the column name.
|
|
2300
|
+
* @since 0.1.128
|
|
2301
|
+
*/
|
|
2302
|
+
renderDesiredColumn?(index: TDbIndex, field: TDbIndex["fields"][number]): string;
|
|
2303
|
+
/**
|
|
2304
|
+
* An index this diff does not build: a string — the warning to log (e.g. a
|
|
2305
|
+
* geo index without PostGIS); `null` — skipped silently (e.g. an index type
|
|
2306
|
+
* the adapter maintains itself); `undefined` — built. A skipped index is not
|
|
2307
|
+
* desired — never reported as work to do, and a stale one is dropped.
|
|
2308
|
+
* @since 0.1.162
|
|
2309
|
+
*/
|
|
2310
|
+
skipIndex?(index: TDbIndex): string | null | undefined;
|
|
2311
|
+
/**
|
|
2312
|
+
* Prefixed indexes the adapter manages itself, outside the model's
|
|
2313
|
+
* `indexes` (e.g. PostgreSQL's pgvector HNSW indexes) — never dropped as
|
|
2314
|
+
* stale here.
|
|
2315
|
+
* @since 0.1.162
|
|
2316
|
+
*/
|
|
2317
|
+
isUnmanaged?(name: string): boolean;
|
|
2318
|
+
/**
|
|
2319
|
+
* Compute the changes only — no DDL (`planIndexes`).
|
|
2320
|
+
* @since 0.1.162
|
|
2321
|
+
*/
|
|
2322
|
+
dryRun?: boolean;
|
|
2323
|
+
}
|
|
2324
|
+
/**
|
|
2325
|
+
* What an adapter hands `BaseDbAdapter.syncForeignKeysWithDiff`: its
|
|
2326
|
+
* foreign-key constraint primitives.
|
|
2327
|
+
* @since 0.1.162
|
|
2328
|
+
*/
|
|
2329
|
+
interface TForeignKeyDiffOptions {
|
|
2330
|
+
/** The live table's foreign-key constraints: constraint name → local column names. */
|
|
2331
|
+
listExisting(): Promise<ReadonlyMap<string, string[]>>;
|
|
2332
|
+
dropConstraint(name: string): Promise<void>;
|
|
2333
|
+
addConstraint(fk: TDbForeignKey): Promise<void>;
|
|
2334
|
+
/** Compute the changes only — no DDL (`planForeignKeys`). */
|
|
2335
|
+
dryRun?: boolean;
|
|
2336
|
+
}
|
|
2145
2337
|
/**
|
|
2146
2338
|
* Abstract base class for database adapters.
|
|
2147
2339
|
*
|
|
@@ -2228,6 +2420,31 @@ declare abstract class BaseDbAdapter {
|
|
|
2228
2420
|
* `expectedVersion`; a violation throws).
|
|
2229
2421
|
*/
|
|
2230
2422
|
protected _versionColumnFor(opts?: TDbUpdateOptions, expectedVersion?: number): string | undefined;
|
|
2423
|
+
/**
|
|
2424
|
+
* `@db.onUpdate.inc` columns (physical names, since 0.1.162) as a field-op
|
|
2425
|
+
* increment by one, or `undefined` when the table declares none. A replace
|
|
2426
|
+
* path renders it next to the replacement data (the core leaves these
|
|
2427
|
+
* columns out of the payload); the patch paths get the `$inc` from the core.
|
|
2428
|
+
*/
|
|
2429
|
+
protected _onUpdateIncOps(): TFieldOps | undefined;
|
|
2430
|
+
/**
|
|
2431
|
+
* Whether `updateMany` / `deleteMany` render a row bound
|
|
2432
|
+
* ({@link TDbWriteLimit}) natively in one statement (since 0.1.162). When
|
|
2433
|
+
* `false` (the default) the core emulates a bounded write: it reads the
|
|
2434
|
+
* primary keys of the first `limit` matching rows in order, then writes the
|
|
2435
|
+
* rows matching the filter AND those keys.
|
|
2436
|
+
*/
|
|
2437
|
+
supportsWriteLimit(): boolean;
|
|
2438
|
+
/**
|
|
2439
|
+
* Whether a native bounded write ({@link supportsWriteLimit}) picks and
|
|
2440
|
+
* writes its rows atomically — a row a concurrent transaction deletes or
|
|
2441
|
+
* moves out of the filter is passed over and the next match taken, so `0`
|
|
2442
|
+
* affected rows always means nothing matched (MySQL's
|
|
2443
|
+
* `UPDATE/DELETE … ORDER BY … LIMIT`). When `false` (the default) the core
|
|
2444
|
+
* probes for a remaining match after a bounded write that affected no rows
|
|
2445
|
+
* and retries it a few times (since 0.1.162).
|
|
2446
|
+
*/
|
|
2447
|
+
writeLimitIsAtomic(): boolean;
|
|
2231
2448
|
/**
|
|
2232
2449
|
* Logs a debug message if verbose mode is enabled.
|
|
2233
2450
|
* Adapters call this to log DB operations with zero overhead when disabled.
|
|
@@ -2242,8 +2459,58 @@ declare abstract class BaseDbAdapter {
|
|
|
2242
2459
|
* The generic layer handles nesting detection via `AsyncLocalStorage`.
|
|
2243
2460
|
* Adapters override `_beginTransaction`, `_commitTransaction`, and
|
|
2244
2461
|
* `_rollbackTransaction` to provide raw DB-specific transaction primitives.
|
|
2462
|
+
*
|
|
2463
|
+
* `opts.isolation` (since 0.1.162) sets the isolation level of the
|
|
2464
|
+
* transaction this call opens — "at least this level". An adapter whose
|
|
2465
|
+
* {@link isolationLevels} lacks it throws `ISOLATION_NOT_SUPPORTED`. A
|
|
2466
|
+
* nested call joins the open transaction; it may request a level only when
|
|
2467
|
+
* that transaction was opened with the same or a stricter one, else it
|
|
2468
|
+
* throws `INVALID_QUERY` (the level of a running transaction cannot change).
|
|
2469
|
+
*/
|
|
2470
|
+
withTransaction<T>(fn: () => Promise<T>, opts?: TTransactionOptions): Promise<T>;
|
|
2471
|
+
/**
|
|
2472
|
+
* The isolation levels {@link withTransaction} can open a transaction at
|
|
2473
|
+
* (since 0.1.162). Default: none — a requested level throws
|
|
2474
|
+
* `ISOLATION_NOT_SUPPORTED`. Override and apply the level in
|
|
2475
|
+
* {@link _beginTransaction} (`opts.isolation`).
|
|
2476
|
+
*/
|
|
2477
|
+
isolationLevels(): ReadonlySet<TDbIsolationLevel>;
|
|
2478
|
+
/**
|
|
2479
|
+
* The level every transaction of this adapter runs at regardless of the
|
|
2480
|
+
* request (since 0.1.162) — SQLite's `BEGIN IMMEDIATE` is always
|
|
2481
|
+
* serializable. A nested `withTransaction` asking for any level then joins
|
|
2482
|
+
* without error. Default `undefined` (the engine default / what was asked).
|
|
2245
2483
|
*/
|
|
2246
|
-
|
|
2484
|
+
protected _inherentIsolation(): TDbIsolationLevel | undefined;
|
|
2485
|
+
/**
|
|
2486
|
+
* Validates a `withTransaction` isolation request against
|
|
2487
|
+
* {@link isolationLevels} — the requested level, or `undefined`.
|
|
2488
|
+
* @throws DbError `INVALID_QUERY` (unknown level) / `ISOLATION_NOT_SUPPORTED`.
|
|
2489
|
+
*/
|
|
2490
|
+
protected _checkIsolation(opts: TTransactionOptions | undefined): TDbIsolationLevel | undefined;
|
|
2491
|
+
/** The `ISOLATION_NOT_SUPPORTED` error of a `withTransaction` isolation request. */
|
|
2492
|
+
protected _isolationNotSupported(message: string): DbError;
|
|
2493
|
+
/**
|
|
2494
|
+
* A nested `withTransaction` asked for `requested` while a transaction
|
|
2495
|
+
* opened at `open` runs: fine when `open` is at least as strict.
|
|
2496
|
+
* @throws DbError `INVALID_QUERY` otherwise.
|
|
2497
|
+
*/
|
|
2498
|
+
protected _assertJoinIsolation(open: TDbIsolationLevel | undefined, requested: TDbIsolationLevel): void;
|
|
2499
|
+
/**
|
|
2500
|
+
* Whether the readable layer may pass a row lock on `DbQuery.lock` to
|
|
2501
|
+
* `findOne` / `findMany` (since 0.1.162). Default `false` — a locking read
|
|
2502
|
+
* throws `LOCK_NOT_SUPPORTED`. An adapter whose transaction already
|
|
2503
|
+
* serialises writers may return `true` and ignore the lock.
|
|
2504
|
+
*/
|
|
2505
|
+
supportsReadLocks(): boolean;
|
|
2506
|
+
/**
|
|
2507
|
+
* `true` inside a `withTransaction` scope of this adapter's owner — a real
|
|
2508
|
+
* transaction or a pass-through one (adapters without transaction
|
|
2509
|
+
* primitives, such as the in-memory one). Unlike {@link isInTransaction} a
|
|
2510
|
+
* pass-through scope counts. Used to require a scope for locking reads.
|
|
2511
|
+
* @since 0.1.162
|
|
2512
|
+
*/
|
|
2513
|
+
inTransactionScope(): boolean;
|
|
2247
2514
|
/**
|
|
2248
2515
|
* The object a transaction state is branded with (since 0.1.128). Every
|
|
2249
2516
|
* adapter instance that returns the same owner shares one transaction —
|
|
@@ -2277,9 +2544,10 @@ declare abstract class BaseDbAdapter {
|
|
|
2277
2544
|
protected _runInTransactionContext<T>(state: unknown, fn: () => Promise<T>): Promise<T>;
|
|
2278
2545
|
/**
|
|
2279
2546
|
* Starts a raw transaction. Returns opaque state stored in the async context.
|
|
2280
|
-
* Override in adapters that support transactions.
|
|
2547
|
+
* Override in adapters that support transactions. `opts.isolation` (since
|
|
2548
|
+
* 0.1.162) is set only to a level of {@link isolationLevels}.
|
|
2281
2549
|
*/
|
|
2282
|
-
protected _beginTransaction(): Promise<unknown>;
|
|
2550
|
+
protected _beginTransaction(_opts?: TTransactionOptions): Promise<unknown>;
|
|
2283
2551
|
/** Commits the raw transaction. Override in adapters that support transactions. */
|
|
2284
2552
|
protected _commitTransaction(_state: unknown): Promise<void>;
|
|
2285
2553
|
/** Rolls back the raw transaction. Override in adapters that support transactions. */
|
|
@@ -2334,6 +2602,16 @@ declare abstract class BaseDbAdapter {
|
|
|
2334
2602
|
* to generate the value client-side or leave it for the DB.
|
|
2335
2603
|
*/
|
|
2336
2604
|
nativeDefaultFns(): ReadonlySet<TDbDefaultFn>;
|
|
2605
|
+
/**
|
|
2606
|
+
* How this engine's introspection (`getExistingColumns`) reports the
|
|
2607
|
+
* model default `desired` (`serializeDefaultValue` form) of `field` when
|
|
2608
|
+
* it cannot report it exactly — e.g. MySQL reports a 4-byte character of a
|
|
2609
|
+
* literal default as `?` while the column stores it intact. Schema sync
|
|
2610
|
+
* treats a live default equal to this as unchanged. Optional — omit when
|
|
2611
|
+
* introspection reports defaults faithfully.
|
|
2612
|
+
* @since 0.1.162
|
|
2613
|
+
*/
|
|
2614
|
+
reportedDefault?(desired: string, field: TDbFieldMeta): string;
|
|
2337
2615
|
/**
|
|
2338
2616
|
* Calendar-bucket units (`{ $bucket, $field }` in an aggregate `$select`)
|
|
2339
2617
|
* this adapter can group by, over IANA time zones. Empty (the default) =
|
|
@@ -2584,48 +2862,27 @@ declare abstract class BaseDbAdapter {
|
|
|
2584
2862
|
*
|
|
2585
2863
|
* @example
|
|
2586
2864
|
* ```typescript
|
|
2587
|
-
*
|
|
2588
|
-
*
|
|
2865
|
+
* protected override _syncIndexes(dryRun: boolean) {
|
|
2866
|
+
* return this.syncIndexesWithDiff({
|
|
2867
|
+
* dryRun,
|
|
2589
2868
|
* listExisting: async () => this.driver.all('PRAGMA index_list(...)'),
|
|
2590
2869
|
* createIndex: async (index) => this.driver.exec('CREATE INDEX ...'),
|
|
2591
2870
|
* dropIndex: async (name) => this.driver.exec('DROP INDEX ...'),
|
|
2592
|
-
*
|
|
2871
|
+
* skipIndex: (index) => (index.type === 'fulltext' ? null : undefined),
|
|
2593
2872
|
* })
|
|
2594
2873
|
* }
|
|
2595
2874
|
* ```
|
|
2596
2875
|
*/
|
|
2597
|
-
protected syncIndexesWithDiff(opts:
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
}>>;
|
|
2608
|
-
createIndex(index: TDbIndex): Promise<void>;
|
|
2609
|
-
dropIndex(name: string): Promise<void>;
|
|
2610
|
-
prefix?: string;
|
|
2611
|
-
shouldSkipType?(type: TDbIndex["type"]): boolean;
|
|
2612
|
-
/**
|
|
2613
|
-
* Renders one desired key part for the drift comparison, so adapters whose
|
|
2614
|
-
* `listExisting` reports more than a bare column name (e.g. MySQL's
|
|
2615
|
-
* `col(255)` key-length prefix) can render the model side identically.
|
|
2616
|
-
* Default: the column name.
|
|
2617
|
-
* @since 0.1.128
|
|
2618
|
-
*/
|
|
2619
|
-
renderDesiredColumn?(index: TDbIndex, field: TDbIndex["fields"][number]): string;
|
|
2620
|
-
/**
|
|
2621
|
-
* Index types declared on the model but not supported by this adapter —
|
|
2622
|
-
* warns and skips (models stay portable; sync never errors on these).
|
|
2623
|
-
*/
|
|
2624
|
-
warnUnsupportedTypes?: {
|
|
2625
|
-
adapter: string;
|
|
2626
|
-
types: ReadonlyArray<TDbIndex["type"]>;
|
|
2627
|
-
};
|
|
2628
|
-
}): Promise<void>;
|
|
2876
|
+
protected syncIndexesWithDiff(opts: TIndexDiffOptions): Promise<TIndexChange[]>;
|
|
2877
|
+
/**
|
|
2878
|
+
* Template method for foreign-key constraint synchronization: drops the
|
|
2879
|
+
* live constraints the model does not declare and adds the declared ones
|
|
2880
|
+
* the live table lacks — matched by their sorted local columns
|
|
2881
|
+
* ({@link fkKey}). A failing statement throws. Returns the changes (made,
|
|
2882
|
+
* or with `dryRun` only computed).
|
|
2883
|
+
* @since 0.1.162
|
|
2884
|
+
*/
|
|
2885
|
+
protected syncForeignKeysWithDiff(opts: TForeignKeyDiffOptions): Promise<TForeignKeyChange[]>;
|
|
2629
2886
|
/**
|
|
2630
2887
|
* Returns available search indexes for this adapter.
|
|
2631
2888
|
* UI uses this to show index picker. Override in adapters that support search.
|
|
@@ -2800,15 +3057,33 @@ declare abstract class BaseDbAdapter {
|
|
|
2800
3057
|
/** `opts.keepVersion` — skip the version bump; see {@link TDbUpdateOptions}. */
|
|
2801
3058
|
abstract updateMany(filter: FilterExpr, data: Record<string, unknown>, ops?: TFieldOps, opts?: TDbUpdateOptions): Promise<TDbUpdateResult>;
|
|
2802
3059
|
abstract replaceMany(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
|
|
2803
|
-
|
|
3060
|
+
/** `opts.limit` — bounded delete, sent only when {@link supportsWriteLimit} (since 0.1.162). */
|
|
3061
|
+
abstract deleteMany(filter: FilterExpr, opts?: TDbDeleteManyOptions): Promise<TDbDeleteResult>;
|
|
2804
3062
|
/**
|
|
2805
3063
|
* Synchronizes indexes between the Atscript definitions and the database.
|
|
2806
|
-
* Uses `this._table.indexes` for the full index definitions.
|
|
3064
|
+
* Uses `this._table.indexes` for the full index definitions. Returns the
|
|
3065
|
+
* changes it made (since 0.1.162) — schema sync reports them on the run
|
|
3066
|
+
* entry; `void` reports none. Schema sync
|
|
2807
3067
|
* passes `opts` when safe mode skipped work the indexes depend on (see
|
|
2808
3068
|
* {@link TSyncIndexesOptions}); an adapter whose indexes do not depend on it
|
|
2809
|
-
* ignores them.
|
|
3069
|
+
* ignores them. Default: {@link _syncIndexes} without `dryRun`.
|
|
3070
|
+
*/
|
|
3071
|
+
syncIndexes(opts?: TSyncIndexesOptions): Promise<void | TIndexChange[]>;
|
|
3072
|
+
/**
|
|
3073
|
+
* The index changes {@link syncIndexes} would make now — no DDL. Schema
|
|
3074
|
+
* sync's plan reports them (`entry.indexChanges`) and marks the entry
|
|
3075
|
+
* `alter`; a run reports what `syncIndexes` returns.
|
|
3076
|
+
* @since 0.1.162
|
|
3077
|
+
*/
|
|
3078
|
+
planIndexes(opts?: TSyncIndexesOptions): Promise<TIndexChange[]>;
|
|
3079
|
+
/**
|
|
3080
|
+
* The one index pass behind {@link syncIndexes} (`dryRun: false`) and
|
|
3081
|
+
* {@link planIndexes} (`dryRun: true` — compute the changes, no DDL).
|
|
3082
|
+
* Adapters implement this (usually over {@link syncIndexesWithDiff}). An
|
|
3083
|
+
* adapter that overrides `syncIndexes` instead plans no index work.
|
|
3084
|
+
* @since 0.1.162
|
|
2810
3085
|
*/
|
|
2811
|
-
|
|
3086
|
+
protected _syncIndexes(dryRun: boolean, _opts?: TSyncIndexesOptions): Promise<TIndexChange[]>;
|
|
2812
3087
|
/**
|
|
2813
3088
|
* Ensures the table exists in the database, creating it if needed.
|
|
2814
3089
|
* Uses `this._table.tableName`, `this._table.schema`, etc.
|
|
@@ -2820,11 +3095,6 @@ declare abstract class BaseDbAdapter {
|
|
|
2820
3095
|
* order. Adapters without inline constraints ignore the parameter.
|
|
2821
3096
|
*/
|
|
2822
3097
|
abstract ensureTable(opts?: TEnsureTableOptions): Promise<void>;
|
|
2823
|
-
/**
|
|
2824
|
-
* Synchronizes foreign key constraints between Atscript definitions and the database.
|
|
2825
|
-
* Uses `this._table.foreignKeys` for the full FK definitions.
|
|
2826
|
-
* Optional — only relational adapters need to implement this.
|
|
2827
|
-
*/
|
|
2828
3098
|
/**
|
|
2829
3099
|
* Post-sync hook called after all table operations (columns, indexes, FKs)
|
|
2830
3100
|
* are complete. Adapters can use this for finalization work such as
|
|
@@ -2832,7 +3102,22 @@ declare abstract class BaseDbAdapter {
|
|
|
2832
3102
|
* Optional — most adapters don't need this.
|
|
2833
3103
|
*/
|
|
2834
3104
|
afterSyncTable?(): Promise<void>;
|
|
2835
|
-
|
|
3105
|
+
/**
|
|
3106
|
+
* Synchronizes foreign key constraints between Atscript definitions and
|
|
3107
|
+
* the live table — adds the missing ones, drops the ones the model does
|
|
3108
|
+
* not declare (matched by their local columns). Returns what it changed
|
|
3109
|
+
* (since 0.1.162); schema sync reports it on the run entry. Optional —
|
|
3110
|
+
* only relational adapters implement it (usually over
|
|
3111
|
+
* {@link syncForeignKeysWithDiff}); without it, schema sync recreates the
|
|
3112
|
+
* table to change its foreign keys (when the adapter can).
|
|
3113
|
+
*/
|
|
3114
|
+
syncForeignKeys?(): Promise<void | TForeignKeyChange[]>;
|
|
3115
|
+
/**
|
|
3116
|
+
* The changes {@link syncForeignKeys} would make now — no DDL. Schema
|
|
3117
|
+
* sync's plan reports them with the snapshot-based FK diff.
|
|
3118
|
+
* @since 0.1.162
|
|
3119
|
+
*/
|
|
3120
|
+
planForeignKeys?(): Promise<TForeignKeyChange[]>;
|
|
2836
3121
|
/**
|
|
2837
3122
|
* Drops FK constraints identified by their canonical local column key.
|
|
2838
3123
|
* Called by the sync executor before column operations to remove stale FKs
|
|
@@ -3140,6 +3425,12 @@ declare class TableMetadata {
|
|
|
3140
3425
|
* @since 0.1.156
|
|
3141
3426
|
*/
|
|
3142
3427
|
onUpdateNow: Set<string>;
|
|
3428
|
+
/**
|
|
3429
|
+
* Top-level fields annotated with `@db.onUpdate.inc`: `0` on insert, `+1` in
|
|
3430
|
+
* the same statement on every update and replace.
|
|
3431
|
+
* @since 0.1.162
|
|
3432
|
+
*/
|
|
3433
|
+
onUpdateInc: Set<string>;
|
|
3143
3434
|
/** Logical path → `@db.column` override (top-level keys only on document storage). */
|
|
3144
3435
|
columnMap: Map<string, string>;
|
|
3145
3436
|
dimensions: string[];
|
|
@@ -3429,6 +3720,67 @@ interface DbQuery {
|
|
|
3429
3720
|
controls: DbControls;
|
|
3430
3721
|
/** Pre-computed query insights (field → operators). Adapters may use this to apply query-time behaviour (e.g. collation). */
|
|
3431
3722
|
insights?: UniqueryInsights;
|
|
3723
|
+
/**
|
|
3724
|
+
* Row lock the read takes (`findOne` / `findMany` with `{ lock }`; since
|
|
3725
|
+
* 0.1.162). Only ever set on a table read inside a transaction of the
|
|
3726
|
+
* adapter's owner, and only when `supportsReadLocks()` is true. SQL
|
|
3727
|
+
* adapters render `FOR UPDATE` / `FOR SHARE` [`NOWAIT` / `SKIP LOCKED`];
|
|
3728
|
+
* an adapter whose transaction already serialises writers may ignore it.
|
|
3729
|
+
*/
|
|
3730
|
+
lock?: TDbReadLock;
|
|
3731
|
+
}
|
|
3732
|
+
/** Lock strength of a locking read: exclusive (`update`) or shared (`share`). */
|
|
3733
|
+
type TDbLockMode = "update" | "share";
|
|
3734
|
+
/**
|
|
3735
|
+
* What a locking read does when a row is locked by another transaction:
|
|
3736
|
+
* `block` (default) waits for it; `nowait` fails at once with a retryable
|
|
3737
|
+
* `DbError("LOCK_TIMEOUT")`; `skipLocked` leaves the locked rows out of the
|
|
3738
|
+
* result.
|
|
3739
|
+
*/
|
|
3740
|
+
type TDbLockWait = "block" | "nowait" | "skipLocked";
|
|
3741
|
+
/** The resolved row lock handed to the adapter on {@link DbQuery.lock}. */
|
|
3742
|
+
interface TDbReadLock {
|
|
3743
|
+
mode: TDbLockMode;
|
|
3744
|
+
wait: TDbLockWait;
|
|
3745
|
+
}
|
|
3746
|
+
/**
|
|
3747
|
+
* Second argument of `findOne` / `findMany` (and part of the `findById` /
|
|
3748
|
+
* `findOneByRow` options): a locking read. Server-side only — it is never a
|
|
3749
|
+
* query control, so it cannot arrive over HTTP.
|
|
3750
|
+
*
|
|
3751
|
+
* A lock requires a `withTransaction` scope of the table's adapter and a
|
|
3752
|
+
* table (not a view); `$groupBy` / aggregate `$select` / `$count` reads are
|
|
3753
|
+
* rejected. Only the root rows are locked — `$with` relations load with
|
|
3754
|
+
* plain reads. The locks are held until the outermost transaction commits
|
|
3755
|
+
* or rolls back.
|
|
3756
|
+
*
|
|
3757
|
+
* @since 0.1.162
|
|
3758
|
+
*/
|
|
3759
|
+
interface TReadLockOptions {
|
|
3760
|
+
/** `'update'` — exclusive row lock (`FOR UPDATE`); `'share'` — shared lock (`FOR SHARE`). */
|
|
3761
|
+
lock?: TDbLockMode;
|
|
3762
|
+
/** Behaviour on a row locked by another transaction (default `'block'`); requires `lock`. */
|
|
3763
|
+
wait?: TDbLockWait;
|
|
3764
|
+
}
|
|
3765
|
+
/**
|
|
3766
|
+
* Transaction isolation level. Semantics are "at least this level": an
|
|
3767
|
+
* engine that always runs stricter (SQLite) satisfies every level.
|
|
3768
|
+
* @since 0.1.162
|
|
3769
|
+
*/
|
|
3770
|
+
type TDbIsolationLevel = "read committed" | "repeatable read" | "serializable";
|
|
3771
|
+
/**
|
|
3772
|
+
* Options of `withTransaction(fn, opts)` (since 0.1.162). Apply to the
|
|
3773
|
+
* outermost call only — a nested call joins the open transaction and may
|
|
3774
|
+
* request an isolation level only when the open transaction was started with
|
|
3775
|
+
* the same or a stricter one (otherwise `INVALID_QUERY`).
|
|
3776
|
+
*/
|
|
3777
|
+
interface TTransactionOptions {
|
|
3778
|
+
/**
|
|
3779
|
+
* Isolation level of the transaction. An adapter that cannot provide it
|
|
3780
|
+
* throws `DbError("ISOLATION_NOT_SUPPORTED")`. Omitted: the engine default
|
|
3781
|
+
* (PostgreSQL READ COMMITTED, MySQL REPEATABLE READ).
|
|
3782
|
+
*/
|
|
3783
|
+
isolation?: TDbIsolationLevel;
|
|
3432
3784
|
}
|
|
3433
3785
|
/** Describes an available search index exposed by a database adapter. */
|
|
3434
3786
|
interface TSearchIndexInfo {
|
|
@@ -3846,6 +4198,48 @@ interface TDbUpdateOptions {
|
|
|
3846
4198
|
* the option keeps bumping (the pre-0.1.150 behaviour).
|
|
3847
4199
|
*/
|
|
3848
4200
|
keepVersion?: boolean;
|
|
4201
|
+
/**
|
|
4202
|
+
* Bounded update (`updateMany(filter, data, { limit })`, since 0.1.162):
|
|
4203
|
+
* write at most `limit.limit` rows, the first ones in `limit.sort` order.
|
|
4204
|
+
* Sent only to an adapter whose {@link BaseDbAdapter.supportsWriteLimit}
|
|
4205
|
+
* is `true`; the core emulates it for the others.
|
|
4206
|
+
*/
|
|
4207
|
+
limit?: TDbWriteLimit;
|
|
4208
|
+
}
|
|
4209
|
+
/**
|
|
4210
|
+
* The row bound of a bounded `updateMany` / `deleteMany` as the adapter
|
|
4211
|
+
* receives it (since 0.1.162): physical column names, the primary key always
|
|
4212
|
+
* included in `sort` as the final tie-breaker so the order is total.
|
|
4213
|
+
*/
|
|
4214
|
+
interface TDbWriteLimit {
|
|
4215
|
+
/** Positive integer — the most rows the statement may touch. */
|
|
4216
|
+
limit: number;
|
|
4217
|
+
/** Physical column → direction. Never empty. */
|
|
4218
|
+
sort: Record<string, 1 | -1>;
|
|
4219
|
+
/** Resolved NULL placement per `sort` key (see `DbControls.$nulls`). */
|
|
4220
|
+
nulls?: DbControls["$nulls"];
|
|
4221
|
+
}
|
|
4222
|
+
/** Per-call options of an adapter `deleteMany` (since 0.1.162). */
|
|
4223
|
+
interface TDbDeleteManyOptions {
|
|
4224
|
+
/** Bounded delete — see {@link TDbWriteLimit}. Sent only when `supportsWriteLimit()`. */
|
|
4225
|
+
limit?: TDbWriteLimit;
|
|
4226
|
+
}
|
|
4227
|
+
/**
|
|
4228
|
+
* Options of `AtscriptDbTable.updateMany` / `deleteMany` (since 0.1.162).
|
|
4229
|
+
* Not exposed over HTTP.
|
|
4230
|
+
*/
|
|
4231
|
+
interface TBulkWriteOptions<FlatType = Record<string, unknown>> {
|
|
4232
|
+
/**
|
|
4233
|
+
* Touch at most this many matching rows (a positive integer). Loop until a
|
|
4234
|
+
* call reports `0` to process every match in batches.
|
|
4235
|
+
*/
|
|
4236
|
+
limit?: number;
|
|
4237
|
+
/**
|
|
4238
|
+
* The order in which a bounded write picks rows (`$sort` shape). Defaults
|
|
4239
|
+
* to the primary key ascending; the primary key is always appended as the
|
|
4240
|
+
* final tie-breaker. Needs `limit`.
|
|
4241
|
+
*/
|
|
4242
|
+
sort?: Partial<Record<keyof FlatType & string, 1 | -1>>;
|
|
3849
4243
|
}
|
|
3850
4244
|
interface TDbDeleteResult {
|
|
3851
4245
|
deletedCount: number;
|
|
@@ -4225,6 +4619,30 @@ interface TSyncIndexesOptions {
|
|
|
4225
4619
|
*/
|
|
4226
4620
|
keepColumns?: readonly string[];
|
|
4227
4621
|
}
|
|
4622
|
+
/**
|
|
4623
|
+
* One managed index `syncIndexes` creates (`add`), drops (`drop`) or drops
|
|
4624
|
+
* and recreates because its definition drifted (`rebuild`) — returned by
|
|
4625
|
+
* `BaseDbAdapter.syncIndexes` / `planIndexes` and reported on schema-sync
|
|
4626
|
+
* entries (`entry.indexChanges`). `name` is the physical index name (or the
|
|
4627
|
+
* adapter's artifact for it, e.g. SQLite's FTS5 table).
|
|
4628
|
+
* @since 0.1.162
|
|
4629
|
+
*/
|
|
4630
|
+
interface TIndexChange {
|
|
4631
|
+
name: string;
|
|
4632
|
+
action: "add" | "drop" | "rebuild";
|
|
4633
|
+
}
|
|
4634
|
+
/**
|
|
4635
|
+
* One foreign key `syncForeignKeys` adds to the live table (missing there,
|
|
4636
|
+
* e.g. dropped by hand) or drops from it (not in the model) — matched by
|
|
4637
|
+
* the sorted local columns. `targetTable` is set for an added constraint;
|
|
4638
|
+
* a dropped one may leave it out.
|
|
4639
|
+
* @since 0.1.162
|
|
4640
|
+
*/
|
|
4641
|
+
interface TForeignKeyChange {
|
|
4642
|
+
fields: string[];
|
|
4643
|
+
targetTable?: string;
|
|
4644
|
+
action: "add" | "drop";
|
|
4645
|
+
}
|
|
4228
4646
|
/** Result of applying column diff to the database. */
|
|
4229
4647
|
interface TSyncColumnResult {
|
|
4230
4648
|
added: string[];
|
|
@@ -4725,4 +5143,4 @@ declare function isJsonValueField(fd: TDbFieldMeta): boolean;
|
|
|
4725
5143
|
*/
|
|
4726
5144
|
declare function jsonValueAncestor(path: string, jsonValueParents: ReadonlySet<string>): string | undefined;
|
|
4727
5145
|
//#endregion
|
|
4728
|
-
export {
|
|
5146
|
+
export { TDbInsertManyIgnoreResult as $, hasRelationOp as $n, TWriteOptions as $t, TCascadeTarget as A, AtscriptRef as An, TForeignKeyChange as At, TDbCollation as B, AtscriptDbReadable as Bn, TReadLockOptions as Bt, NavPropsOf$1 as C, TViewReadPlan as Cn, TEnsureTableOptions as Ct, PrimaryKeyOf$1 as D, AtscriptQueryComparison as Dn, TFieldMeta as Dt, OwnPropsOf$1 as E, AtscriptOrderItem as En, TExistingTableOption as Et, TDbActionIntent as F, translateQueryTree as Fn, TInsertOptions as Ft, TDbFieldMeta as G, ResolvedRelationFilter as Gn, TSyncColumnResult as Gt, TDbDefaultValue as H, resolveDesignType as Hn, TRelationInfo as Ht, TDbActionLevel as I, AtscriptDbTable as In, TJsonCopyTarget as It, TDbIndexField as J, TRelationFilterTable as Jn, TTableResolver as Jt, TDbForeignKey as K, TRelGuardState as Kn, TSyncIndexesOptions as Kt, TDbActionProcessor as L, IntegrityStrategy as Ln, TMetaResponse as Lt, TCrudOp as M, TViewPlan as Mn, TIdResolveOptions as Mt, TCrudPermissions as N, evaluateExpr as Nn, TIdentification as Nt, TBulkWriteOptions as O, AtscriptQueryFieldRef$1 as On, TFkLookupResolver as Ot, TDbActionInfo as P, isFieldRef as Pn, TIndexChange as Pt, TDbInsertIgnoreSlot as Q, forEachResolvedRelation as Qn, TViewJsonType as Qt, TDbActionTargetSummary as R, NativeIntegrity as Rn, TMetadataOverrides as Rt, FlatOf$1 as S, isViewType as Sn, TDerivedColumn as St, NullsPlacement$1 as T, AtscriptExprNode$1 as Tn, TExistingForeignKey as Tt, TDbDeleteManyOptions as U, REL_FILTER_MAX_DEPTH as Un, TRowResolveOptions as Ut, TDbDefaultFn as V, DbResponse as Vn, TReferencingForeignKey as Vt, TDbDeleteResult as W, REL_FILTER_MAX_NODES as Wn, TSearchIndexInfo as Wt, TDbInsertIgnoreOptions as X, andFilters as Xn, TTransactionOptions as Xt, TDbIndexType as Y, TRelationStaticFilter as Yn, TTouchManyOptions as Yt, TDbInsertIgnoreResult as Z, containsRelationFilter as Zn, TValueFormatterPair as Zt, DbPatch as _, TAdapterFactory as _n, TDbWriteGuard as _t, isJsonValueField as a, TableMetadata as an, FieldMappingStrategy as ar, TDbObjectKind as at, FieldOpsFor as b, TViewColumnMapping as bn, TDeleteOptions as bt, resolveCalendarBuckets as c, TPathPresence as cn, TGenericLogger as cr, TDbRelation as ct, AggregateFn$1 as d, ALL_VIEW_CAPABILITIES as dn, TRowOrderKey as dr, TDbStorageType as dt, TWriteTableResolver as en, isResolvedRelationFilter as er, TDbInsertManyResult as et, AggregateQuery$1 as f, BaseDbAdapter as fn, UniquSelect as fr, TDbUpdateOptions as ft, DbControls as g, DbSpace as gn, TDbWriteCheckContext as gt, AtscriptDbWritable as h, TViewCapability as hn, TDbWriteCheck as ht, isBucketableField as i, WithRelation$1 as in, DocumentFieldMapper as ir, TDbLockWait as it, TColumnDiff as j, TViewJoin as jn, TIdDescriptor as jt, TCascadeResolver as k, AtscriptQueryNode$1 as kn, TFkLookupTarget as kt, AggregateControls as l, ALL_BUCKET_UNITS as ln, TExprAggregate as lr, TDbRemoveGuard as lt, AtscriptDbTableLike as m, TIndexDiffOptions as mn, TDbWriteAction as mt, TComputedSelect as n, Uniquery$1 as nn, DbEncryption as nr, TDbIsolationLevel as nt, jsonValueAncestor as o, isGeoIndexableType as on, TReadControls as or, TDbReadLock as ot, AggregateResult as p, TForeignKeyDiffOptions as pn, TDbUpdateResult as pt, TDbIndex as q, TRelationFilterJunction as qn, TTableOptionDiff as qt, TResolvedBucket as r, UniqueryControls$1 as rn, TDbEncryptionOptions as rr, TDbLockMode as rt, normalizeComputedSelect as s, isGeoPointType as sn, NoopLogger as sr, TDbReferentialAction as st, TBucketFieldSource as t, TypedWithRelation as tn, relationStaticFilter as tr, TDbInsertResult as tt, AggregateExpr$1 as u, ALL_ISOLATION_LEVELS as un, TFirstLast as ur, TDbRemoveGuardContext as ut, DbQuery as v, TDbSpaceOptions as vn, TDbWriteGuardContext as vt, NullableOptional as w, aliasTargetOf as wn, TExistingColumn as wt, FilterExpr$1 as x, isAtscriptDbView as xn, TDerivedChangeReason as xt, DbRow as y, AtscriptDbView as yn, TDbWriteLimit as yt, TDbAvailableActions as z, TCascadePin as zn, TPrimaryKeyChange as zt };
|