@atscript/db-mongo 0.1.146 → 0.1.148
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 +126 -18
- package/dist/agg.d.cts +40 -5
- package/dist/agg.d.mts +40 -5
- package/dist/agg.mjs +123 -19
- package/dist/index.cjs +599 -194
- package/dist/index.d.cts +118 -23
- package/dist/index.d.mts +118 -23
- package/dist/index.mjs +597 -197
- package/dist/mongo-accumulator-BKMdRf3s.cjs +611 -0
- package/dist/mongo-accumulator-BvJNCVoc.mjs +534 -0
- package/dist/mongo-filter-CGd9ryOD.d.cts +123 -0
- package/dist/mongo-filter-CGd9ryOD.d.mts +123 -0
- package/package.json +9 -9
- package/dist/mongo-accumulator-BalE9LkU.cjs +0 -265
- package/dist/mongo-accumulator-Dc0w4t0l.mjs +0 -236
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { a as buildMongoFilter, c as mongoFilterStages, i as TMongoFilterPlan, l as planStages, n as TMongoFieldCollation, o as buildMongoQuery, r as TMongoFilterOptions, s as collationOfAdapter, t as REL_FILTER_TEMP_PREFIX } from "./mongo-filter-CGd9ryOD.cjs";
|
|
2
|
+
import { BaseDbAdapter, DbQuery, DbSpace, FilterExpr, TColumnDiff, TDbCollation, TDbDeleteResult, TDbFieldMeta, TDbForeignKey, TDbInsertIgnoreSlot, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbRelation, TDbUpdateResult, TExistingTableOption, TFieldOps, TMetadataOverrides, TPrimaryKeyChange, TSearchIndexInfo, TSyncColumnResult, TTableResolver, TViewCapability, TableMetadata, WithRelation, getKeyProps } from "@atscript/db";
|
|
3
|
+
import { AggregateOptions, AggregationCursor, ClientSession, Collection, Db, Document, Filter, MongoClient, ObjectId, UpdateFilter, UpdateOptions } from "mongodb";
|
|
3
4
|
import { TAtscriptAnnotatedType, TMetadataMap, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
4
5
|
import { AggregateFn, BucketUnit } from "@uniqu/core";
|
|
5
6
|
|
|
@@ -277,6 +278,12 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
277
278
|
private get _client();
|
|
278
279
|
/** Every adapter over this client (or database handle) shares one session (since 0.1.128). */
|
|
279
280
|
protected _transactionOwner(): unknown;
|
|
281
|
+
/**
|
|
282
|
+
* Same store = same client (or database handle) AND the same database: a
|
|
283
|
+
* `$lookup` only reads collections of the pipeline's own database, and one
|
|
284
|
+
* client may serve several (since 0.1.147).
|
|
285
|
+
*/
|
|
286
|
+
sharesStoreWith(other: BaseDbAdapter): boolean;
|
|
280
287
|
/**
|
|
281
288
|
* Per-client cache: whether transactions are unavailable (standalone MongoDB).
|
|
282
289
|
* Shared across all adapter instances for the same client so topology is probed once.
|
|
@@ -296,7 +303,7 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
296
303
|
session: ClientSession;
|
|
297
304
|
} | Record<string, never>;
|
|
298
305
|
get collection(): Collection<any>;
|
|
299
|
-
aggregatePipeline(pipeline: Document[]): AggregationCursor;
|
|
306
|
+
aggregatePipeline(pipeline: Document[], options?: AggregateOptions): AggregationCursor;
|
|
300
307
|
aggregate(query: DbQuery): Promise<Array<Record<string, unknown>>>;
|
|
301
308
|
get idType(): "string" | "number" | "objectId";
|
|
302
309
|
prepareId(id: unknown, _fieldType: unknown): unknown;
|
|
@@ -307,10 +314,14 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
307
314
|
prepareIdFromIdType<D = string | number | ObjectId>(id: string | number | ObjectId): D;
|
|
308
315
|
supportsNestedObjects(): boolean;
|
|
309
316
|
supportsNativePatch(): boolean;
|
|
310
|
-
/**
|
|
317
|
+
/** Every unit, over MongoDB's bundled time zone database (see `agg.ts` `bucketExpression`). */
|
|
311
318
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
312
|
-
/** Every aggregate function
|
|
319
|
+
/** Every aggregate function: `countDistinct`, `first` and `last` included. */
|
|
313
320
|
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
321
|
+
/** Arithmetic in an aggregate `$select` (`{ $expr }`, `{ $fn, $expr }`). */
|
|
322
|
+
supportsAggregateExpressions(): boolean;
|
|
323
|
+
/** Computed view columns and first-row joins. */
|
|
324
|
+
viewCapabilities(): ReadonlySet<TViewCapability>;
|
|
314
325
|
/**
|
|
315
326
|
* See BaseDbAdapter.viewRenderRevision. 2 = 0.1.137 (null-guarded field filters, nested document paths).
|
|
316
327
|
* BUMP whenever `buildViewPipeline` output changes for an unchanged view definition.
|
|
@@ -348,6 +359,46 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
348
359
|
} | undefined;
|
|
349
360
|
getAdapterTableName(_type: unknown): string | undefined;
|
|
350
361
|
supportsNativeRelations(): boolean;
|
|
362
|
+
/**
|
|
363
|
+
* Relational predicates (`{ nav: { $some | $none: … } }`) render as
|
|
364
|
+
* correlated `$lookup` stages, so a read whose filter holds one runs as an
|
|
365
|
+
* aggregation pipeline (find / count / findManyWithCount / grouped
|
|
366
|
+
* aggregate / search / geo); predicate-free reads keep their plain
|
|
367
|
+
* `find` / `countDocuments` path.
|
|
368
|
+
*
|
|
369
|
+
* Writes (`updateMany` / `replaceMany` / `deleteMany` and the single-row
|
|
370
|
+
* variants, whose scope may carry a predicate) first resolve the matching
|
|
371
|
+
* `_id`s through that pipeline, then write by `_id` in batches of
|
|
372
|
+
* {@link REL_WRITE_BATCH} — re-checking the predicate-free part of the
|
|
373
|
+
* filter. Inside an active transaction both steps share its session and
|
|
374
|
+
* are atomic; without one there is a window between resolving and writing
|
|
375
|
+
* in which a related document can change, so a written document may no
|
|
376
|
+
* longer satisfy the predicate (or a newly matching one is missed).
|
|
377
|
+
*
|
|
378
|
+
* Collation: such a pipeline runs without an operation-wide `collation`
|
|
379
|
+
* (it would govern the join keys and every related field too); each
|
|
380
|
+
* table's `'nocase'` fields are compared case-insensitively explicitly
|
|
381
|
+
* ({@link TMongoFilterOptions.collation}) — on reads and on these writes.
|
|
382
|
+
*
|
|
383
|
+
* @since 0.1.147
|
|
384
|
+
*/
|
|
385
|
+
supportsRelationFilters(_mode: "read" | "write"): boolean;
|
|
386
|
+
/**
|
|
387
|
+
* The `@db.column.collate` of a field (physical or logical path), or
|
|
388
|
+
* `undefined` for a byte-wise one — how predicate pipelines render this
|
|
389
|
+
* table's `'nocase'` comparisons ({@link TMongoFilterOptions.collation}).
|
|
390
|
+
*
|
|
391
|
+
* @since 0.1.147
|
|
392
|
+
*/
|
|
393
|
+
fieldCollation(field: string): TDbCollation | undefined;
|
|
394
|
+
/** Filter-rendering options of a pipeline with relational predicates on this table. */
|
|
395
|
+
private get _predicateFilterOpts();
|
|
396
|
+
/**
|
|
397
|
+
* Operation options of a read: the request collation for a predicate-free
|
|
398
|
+
* filter ({@link _getCollationOpts}); none with relational predicates —
|
|
399
|
+
* those pipelines render collation per field ({@link _predicateFilterOpts}).
|
|
400
|
+
*/
|
|
401
|
+
private _readOpts;
|
|
351
402
|
loadRelations(rows: Array<Record<string, unknown>>, withRelations: WithRelation[], relations: ReadonlyMap<string, TDbRelation>, foreignKeys: ReadonlyMap<string, TDbForeignKey>, tableResolver?: TTableResolver): Promise<void>;
|
|
352
403
|
/** Returns the context object used by CollectionPatcher. */
|
|
353
404
|
getPatcherContext(): TCollectionPatcherContext;
|
|
@@ -394,6 +445,37 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
394
445
|
* rather than silently dropping the CAS predicate.
|
|
395
446
|
*/
|
|
396
447
|
private _buildCasFilter;
|
|
448
|
+
/**
|
|
449
|
+
* The id-resolving pipeline of a write filter holding relational
|
|
450
|
+
* predicates: the matching `_id`s (in the active transaction's session,
|
|
451
|
+
* if any), each table's `'nocase'` fields compared like on reads
|
|
452
|
+
* ({@link _predicateFilterOpts}). `pre` is the predicate-free part, which
|
|
453
|
+
* every `_id`-based write re-checks — so a document that stopped matching
|
|
454
|
+
* it in between is not written.
|
|
455
|
+
*/
|
|
456
|
+
private _predicateWritePlan;
|
|
457
|
+
/** A write filter's `_id` filter (re-checking `pre`). */
|
|
458
|
+
private static _byIds;
|
|
459
|
+
/** Single-document write over a predicate filter: the first match's `_id` filter (`undefined`: none). */
|
|
460
|
+
private _predicateWriteFilterOne;
|
|
461
|
+
/**
|
|
462
|
+
* Multi-document write over `filter`: a predicate-free filter is written
|
|
463
|
+
* as is; one with predicates calls `write` with one `_id`-based filter per
|
|
464
|
+
* batch of {@link REL_WRITE_BATCH} matching ids, streamed from the cursor
|
|
465
|
+
* (never all ids in memory at once).
|
|
466
|
+
*
|
|
467
|
+
* The ids come sorted by `_id`, so writes made while the cursor is open
|
|
468
|
+
* can never feed back into it (otherwise a document an update moves within
|
|
469
|
+
* the index the cursor scans could be returned — and written — twice):
|
|
470
|
+
* after the `$lookup`s that `$sort` consumes every match before the first
|
|
471
|
+
* batch returns, and an `_id` order read from the `_id` index is stable
|
|
472
|
+
* (`_id` never changes).
|
|
473
|
+
*/
|
|
474
|
+
private _forEachMatching;
|
|
475
|
+
/** Runs an update-shaped write over `filter` ({@link _forEachMatching}), counts summed. */
|
|
476
|
+
private _updateMatching;
|
|
477
|
+
/** The filter of a single-document write — its predicates resolved to one `_id`. */
|
|
478
|
+
private _writeFilterOne;
|
|
397
479
|
/**
|
|
398
480
|
* Wraps an async operation to catch MongoDB duplicate key errors
|
|
399
481
|
* (code 11000) and rethrow as structured `DbError` — every write path
|
|
@@ -401,10 +483,35 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
401
483
|
* so a unique-index violation is a `CONFLICT` whichever statement hit it.
|
|
402
484
|
*/
|
|
403
485
|
private _wrapDuplicateKeyError;
|
|
486
|
+
/** Rethrows a duplicate-key (11000) server error as `CONFLICT`, anything else as is. */
|
|
487
|
+
private _mapConstraintError;
|
|
404
488
|
/** An update-shaped write under {@link _wrapDuplicateKeyError}, reduced to `TDbUpdateResult`. */
|
|
405
489
|
private _wrapUpdate;
|
|
406
490
|
insertOne(data: Record<string, unknown>): Promise<TDbInsertResult>;
|
|
407
491
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
492
|
+
supportsInsertIgnore(): boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Conflict-ignoring batch insert (the core already removed in-batch duplicates).
|
|
495
|
+
*
|
|
496
|
+
* Outside a transaction: `insertMany(…, { ordered: false })`; duplicate-key
|
|
497
|
+
* write errors (11000) mark the skipped rows, every other write error
|
|
498
|
+
* rethrows after the batch (rows already written stay — as for a plain
|
|
499
|
+
* non-transactional `insertMany`).
|
|
500
|
+
*
|
|
501
|
+
* Inside a transaction a duplicate key would abort the transaction even with
|
|
502
|
+
* `ordered: false`, so the stored keys are looked up first (inside the
|
|
503
|
+
* session), the matches are skipped and the rest is inserted ordered. A
|
|
504
|
+
* residual 11000 (e.g. a collation-equal value) throws `CONFLICT`.
|
|
505
|
+
*/
|
|
506
|
+
insertManyIgnore(data: Array<Record<string, unknown>>): Promise<TDbInsertIgnoreSlot[]>;
|
|
507
|
+
/**
|
|
508
|
+
* Indices of `data` rows whose primary (`_id`) or unique-index key tuple is
|
|
509
|
+
* already stored (rows with a null / missing key component never collide).
|
|
510
|
+
* One `$or` query per chunk covers every key set.
|
|
511
|
+
*/
|
|
512
|
+
private _findStoredKeyConflicts;
|
|
513
|
+
/** Version default + `@db.default.increment` allocation shared by every batch insert. */
|
|
514
|
+
private _prepareInsertBatch;
|
|
408
515
|
findOne(query: DbQuery): Promise<Record<string, unknown> | null>;
|
|
409
516
|
findMany(query: DbQuery): Promise<Array<Record<string, unknown>>>;
|
|
410
517
|
count(query: DbQuery): Promise<number>;
|
|
@@ -452,11 +559,16 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
452
559
|
private _getCurrentFieldMax;
|
|
453
560
|
/** Allocates increment values for a batch of items, assigning in order. */
|
|
454
561
|
private _assignBatchIncrements;
|
|
562
|
+
/** A find whose filter holds relational predicates, as an aggregation pipeline. */
|
|
563
|
+
private _aggregateFind;
|
|
455
564
|
private _buildFindOptions;
|
|
456
565
|
/**
|
|
457
566
|
* Returns MongoDB collation options if any filter field has a non-binary collation.
|
|
458
567
|
* Uses pre-computed insights when available, falls back to computing them on demand.
|
|
459
568
|
* Maps: nocase → strength 2 (case-insensitive), unicode → strength 1 (case+accent-insensitive).
|
|
569
|
+
* Predicate-free filters only — a filter with relational predicates never gets an
|
|
570
|
+
* operation-wide collation ({@link _readOpts}), so insights are never computed over
|
|
571
|
+
* resolved predicate operands.
|
|
460
572
|
*/
|
|
461
573
|
private _getCollationOpts;
|
|
462
574
|
protected _addMongoIndexField(type: TPlainIndex["type"], name: string, field: string, weight?: number): void;
|
|
@@ -484,27 +596,10 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
484
596
|
private _descendSearchNode;
|
|
485
597
|
}
|
|
486
598
|
//#endregion
|
|
487
|
-
//#region src/lib/mongo-filter.d.ts
|
|
488
|
-
/**
|
|
489
|
-
* Translates a generic {@link FilterExpr} into a MongoDB-compatible
|
|
490
|
-
* {@link Filter} document.
|
|
491
|
-
*
|
|
492
|
-
* MongoDB's query language is nearly identical to the `FilterExpr` structure,
|
|
493
|
-
* so this is largely a structural pass-through via the `walkFilter` visitor.
|
|
494
|
-
* `fieldOperands` (view predicates only — `translateQueryTree` output) turns
|
|
495
|
-
* `{ $field: path }` operands into field-to-field `$expr` comparisons; a
|
|
496
|
-
* request filter never gets that reading.
|
|
497
|
-
*/
|
|
498
|
-
declare function buildMongoFilter(filter: FilterExpr, {
|
|
499
|
-
fieldOperands
|
|
500
|
-
}?: {
|
|
501
|
-
fieldOperands?: boolean;
|
|
502
|
-
}): Filter<any>;
|
|
503
|
-
//#endregion
|
|
504
599
|
//#region src/lib/validate-plugins.d.ts
|
|
505
600
|
declare const validateMongoIdPlugin: TValidatorPlugin;
|
|
506
601
|
//#endregion
|
|
507
602
|
//#region src/lib/index.d.ts
|
|
508
603
|
declare function createAdapter(connection: string, _options?: Record<string, unknown>): DbSpace;
|
|
509
604
|
//#endregion
|
|
510
|
-
export { CollectionPatcher, INDEX_PREFIX, MongoAdapter, TCollectionPatcherContext, type TMongoIndex, type TMongoSearchIndexDefinition, type TPlainIndex, type TSearchIndex, buildMongoFilter, createAdapter, mongoIndexKey, validateMongoIdPlugin };
|
|
605
|
+
export { CollectionPatcher, INDEX_PREFIX, MongoAdapter, REL_FILTER_TEMP_PREFIX, TCollectionPatcherContext, TMongoFieldCollation, TMongoFilterOptions, TMongoFilterPlan, type TMongoIndex, type TMongoSearchIndexDefinition, type TPlainIndex, type TSearchIndex, buildMongoFilter, buildMongoQuery, collationOfAdapter, createAdapter, mongoFilterStages, mongoIndexKey, planStages, validateMongoIdPlugin };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { a as buildMongoFilter, c as mongoFilterStages, i as TMongoFilterPlan, l as planStages, n as TMongoFieldCollation, o as buildMongoQuery, r as TMongoFilterOptions, s as collationOfAdapter, t as REL_FILTER_TEMP_PREFIX } from "./mongo-filter-CGd9ryOD.mjs";
|
|
2
|
+
import { BaseDbAdapter, DbQuery, DbSpace, FilterExpr, TColumnDiff, TDbCollation, TDbDeleteResult, TDbFieldMeta, TDbForeignKey, TDbInsertIgnoreSlot, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbRelation, TDbUpdateResult, TExistingTableOption, TFieldOps, TMetadataOverrides, TPrimaryKeyChange, TSearchIndexInfo, TSyncColumnResult, TTableResolver, TViewCapability, TableMetadata, WithRelation, getKeyProps } from "@atscript/db";
|
|
3
|
+
import { AggregateOptions, AggregationCursor, ClientSession, Collection, Db, Document, Filter, MongoClient, ObjectId, UpdateFilter, UpdateOptions } from "mongodb";
|
|
3
4
|
import { AggregateFn, BucketUnit } from "@uniqu/core";
|
|
4
5
|
import { TAtscriptAnnotatedType, TMetadataMap, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
5
6
|
|
|
@@ -277,6 +278,12 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
277
278
|
private get _client();
|
|
278
279
|
/** Every adapter over this client (or database handle) shares one session (since 0.1.128). */
|
|
279
280
|
protected _transactionOwner(): unknown;
|
|
281
|
+
/**
|
|
282
|
+
* Same store = same client (or database handle) AND the same database: a
|
|
283
|
+
* `$lookup` only reads collections of the pipeline's own database, and one
|
|
284
|
+
* client may serve several (since 0.1.147).
|
|
285
|
+
*/
|
|
286
|
+
sharesStoreWith(other: BaseDbAdapter): boolean;
|
|
280
287
|
/**
|
|
281
288
|
* Per-client cache: whether transactions are unavailable (standalone MongoDB).
|
|
282
289
|
* Shared across all adapter instances for the same client so topology is probed once.
|
|
@@ -296,7 +303,7 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
296
303
|
session: ClientSession;
|
|
297
304
|
} | Record<string, never>;
|
|
298
305
|
get collection(): Collection<any>;
|
|
299
|
-
aggregatePipeline(pipeline: Document[]): AggregationCursor;
|
|
306
|
+
aggregatePipeline(pipeline: Document[], options?: AggregateOptions): AggregationCursor;
|
|
300
307
|
aggregate(query: DbQuery): Promise<Array<Record<string, unknown>>>;
|
|
301
308
|
get idType(): "string" | "number" | "objectId";
|
|
302
309
|
prepareId(id: unknown, _fieldType: unknown): unknown;
|
|
@@ -307,10 +314,14 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
307
314
|
prepareIdFromIdType<D = string | number | ObjectId>(id: string | number | ObjectId): D;
|
|
308
315
|
supportsNestedObjects(): boolean;
|
|
309
316
|
supportsNativePatch(): boolean;
|
|
310
|
-
/**
|
|
317
|
+
/** Every unit, over MongoDB's bundled time zone database (see `agg.ts` `bucketExpression`). */
|
|
311
318
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
312
|
-
/** Every aggregate function
|
|
319
|
+
/** Every aggregate function: `countDistinct`, `first` and `last` included. */
|
|
313
320
|
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
321
|
+
/** Arithmetic in an aggregate `$select` (`{ $expr }`, `{ $fn, $expr }`). */
|
|
322
|
+
supportsAggregateExpressions(): boolean;
|
|
323
|
+
/** Computed view columns and first-row joins. */
|
|
324
|
+
viewCapabilities(): ReadonlySet<TViewCapability>;
|
|
314
325
|
/**
|
|
315
326
|
* See BaseDbAdapter.viewRenderRevision. 2 = 0.1.137 (null-guarded field filters, nested document paths).
|
|
316
327
|
* BUMP whenever `buildViewPipeline` output changes for an unchanged view definition.
|
|
@@ -348,6 +359,46 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
348
359
|
} | undefined;
|
|
349
360
|
getAdapterTableName(_type: unknown): string | undefined;
|
|
350
361
|
supportsNativeRelations(): boolean;
|
|
362
|
+
/**
|
|
363
|
+
* Relational predicates (`{ nav: { $some | $none: … } }`) render as
|
|
364
|
+
* correlated `$lookup` stages, so a read whose filter holds one runs as an
|
|
365
|
+
* aggregation pipeline (find / count / findManyWithCount / grouped
|
|
366
|
+
* aggregate / search / geo); predicate-free reads keep their plain
|
|
367
|
+
* `find` / `countDocuments` path.
|
|
368
|
+
*
|
|
369
|
+
* Writes (`updateMany` / `replaceMany` / `deleteMany` and the single-row
|
|
370
|
+
* variants, whose scope may carry a predicate) first resolve the matching
|
|
371
|
+
* `_id`s through that pipeline, then write by `_id` in batches of
|
|
372
|
+
* {@link REL_WRITE_BATCH} — re-checking the predicate-free part of the
|
|
373
|
+
* filter. Inside an active transaction both steps share its session and
|
|
374
|
+
* are atomic; without one there is a window between resolving and writing
|
|
375
|
+
* in which a related document can change, so a written document may no
|
|
376
|
+
* longer satisfy the predicate (or a newly matching one is missed).
|
|
377
|
+
*
|
|
378
|
+
* Collation: such a pipeline runs without an operation-wide `collation`
|
|
379
|
+
* (it would govern the join keys and every related field too); each
|
|
380
|
+
* table's `'nocase'` fields are compared case-insensitively explicitly
|
|
381
|
+
* ({@link TMongoFilterOptions.collation}) — on reads and on these writes.
|
|
382
|
+
*
|
|
383
|
+
* @since 0.1.147
|
|
384
|
+
*/
|
|
385
|
+
supportsRelationFilters(_mode: "read" | "write"): boolean;
|
|
386
|
+
/**
|
|
387
|
+
* The `@db.column.collate` of a field (physical or logical path), or
|
|
388
|
+
* `undefined` for a byte-wise one — how predicate pipelines render this
|
|
389
|
+
* table's `'nocase'` comparisons ({@link TMongoFilterOptions.collation}).
|
|
390
|
+
*
|
|
391
|
+
* @since 0.1.147
|
|
392
|
+
*/
|
|
393
|
+
fieldCollation(field: string): TDbCollation | undefined;
|
|
394
|
+
/** Filter-rendering options of a pipeline with relational predicates on this table. */
|
|
395
|
+
private get _predicateFilterOpts();
|
|
396
|
+
/**
|
|
397
|
+
* Operation options of a read: the request collation for a predicate-free
|
|
398
|
+
* filter ({@link _getCollationOpts}); none with relational predicates —
|
|
399
|
+
* those pipelines render collation per field ({@link _predicateFilterOpts}).
|
|
400
|
+
*/
|
|
401
|
+
private _readOpts;
|
|
351
402
|
loadRelations(rows: Array<Record<string, unknown>>, withRelations: WithRelation[], relations: ReadonlyMap<string, TDbRelation>, foreignKeys: ReadonlyMap<string, TDbForeignKey>, tableResolver?: TTableResolver): Promise<void>;
|
|
352
403
|
/** Returns the context object used by CollectionPatcher. */
|
|
353
404
|
getPatcherContext(): TCollectionPatcherContext;
|
|
@@ -394,6 +445,37 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
394
445
|
* rather than silently dropping the CAS predicate.
|
|
395
446
|
*/
|
|
396
447
|
private _buildCasFilter;
|
|
448
|
+
/**
|
|
449
|
+
* The id-resolving pipeline of a write filter holding relational
|
|
450
|
+
* predicates: the matching `_id`s (in the active transaction's session,
|
|
451
|
+
* if any), each table's `'nocase'` fields compared like on reads
|
|
452
|
+
* ({@link _predicateFilterOpts}). `pre` is the predicate-free part, which
|
|
453
|
+
* every `_id`-based write re-checks — so a document that stopped matching
|
|
454
|
+
* it in between is not written.
|
|
455
|
+
*/
|
|
456
|
+
private _predicateWritePlan;
|
|
457
|
+
/** A write filter's `_id` filter (re-checking `pre`). */
|
|
458
|
+
private static _byIds;
|
|
459
|
+
/** Single-document write over a predicate filter: the first match's `_id` filter (`undefined`: none). */
|
|
460
|
+
private _predicateWriteFilterOne;
|
|
461
|
+
/**
|
|
462
|
+
* Multi-document write over `filter`: a predicate-free filter is written
|
|
463
|
+
* as is; one with predicates calls `write` with one `_id`-based filter per
|
|
464
|
+
* batch of {@link REL_WRITE_BATCH} matching ids, streamed from the cursor
|
|
465
|
+
* (never all ids in memory at once).
|
|
466
|
+
*
|
|
467
|
+
* The ids come sorted by `_id`, so writes made while the cursor is open
|
|
468
|
+
* can never feed back into it (otherwise a document an update moves within
|
|
469
|
+
* the index the cursor scans could be returned — and written — twice):
|
|
470
|
+
* after the `$lookup`s that `$sort` consumes every match before the first
|
|
471
|
+
* batch returns, and an `_id` order read from the `_id` index is stable
|
|
472
|
+
* (`_id` never changes).
|
|
473
|
+
*/
|
|
474
|
+
private _forEachMatching;
|
|
475
|
+
/** Runs an update-shaped write over `filter` ({@link _forEachMatching}), counts summed. */
|
|
476
|
+
private _updateMatching;
|
|
477
|
+
/** The filter of a single-document write — its predicates resolved to one `_id`. */
|
|
478
|
+
private _writeFilterOne;
|
|
397
479
|
/**
|
|
398
480
|
* Wraps an async operation to catch MongoDB duplicate key errors
|
|
399
481
|
* (code 11000) and rethrow as structured `DbError` — every write path
|
|
@@ -401,10 +483,35 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
401
483
|
* so a unique-index violation is a `CONFLICT` whichever statement hit it.
|
|
402
484
|
*/
|
|
403
485
|
private _wrapDuplicateKeyError;
|
|
486
|
+
/** Rethrows a duplicate-key (11000) server error as `CONFLICT`, anything else as is. */
|
|
487
|
+
private _mapConstraintError;
|
|
404
488
|
/** An update-shaped write under {@link _wrapDuplicateKeyError}, reduced to `TDbUpdateResult`. */
|
|
405
489
|
private _wrapUpdate;
|
|
406
490
|
insertOne(data: Record<string, unknown>): Promise<TDbInsertResult>;
|
|
407
491
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
492
|
+
supportsInsertIgnore(): boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Conflict-ignoring batch insert (the core already removed in-batch duplicates).
|
|
495
|
+
*
|
|
496
|
+
* Outside a transaction: `insertMany(…, { ordered: false })`; duplicate-key
|
|
497
|
+
* write errors (11000) mark the skipped rows, every other write error
|
|
498
|
+
* rethrows after the batch (rows already written stay — as for a plain
|
|
499
|
+
* non-transactional `insertMany`).
|
|
500
|
+
*
|
|
501
|
+
* Inside a transaction a duplicate key would abort the transaction even with
|
|
502
|
+
* `ordered: false`, so the stored keys are looked up first (inside the
|
|
503
|
+
* session), the matches are skipped and the rest is inserted ordered. A
|
|
504
|
+
* residual 11000 (e.g. a collation-equal value) throws `CONFLICT`.
|
|
505
|
+
*/
|
|
506
|
+
insertManyIgnore(data: Array<Record<string, unknown>>): Promise<TDbInsertIgnoreSlot[]>;
|
|
507
|
+
/**
|
|
508
|
+
* Indices of `data` rows whose primary (`_id`) or unique-index key tuple is
|
|
509
|
+
* already stored (rows with a null / missing key component never collide).
|
|
510
|
+
* One `$or` query per chunk covers every key set.
|
|
511
|
+
*/
|
|
512
|
+
private _findStoredKeyConflicts;
|
|
513
|
+
/** Version default + `@db.default.increment` allocation shared by every batch insert. */
|
|
514
|
+
private _prepareInsertBatch;
|
|
408
515
|
findOne(query: DbQuery): Promise<Record<string, unknown> | null>;
|
|
409
516
|
findMany(query: DbQuery): Promise<Array<Record<string, unknown>>>;
|
|
410
517
|
count(query: DbQuery): Promise<number>;
|
|
@@ -452,11 +559,16 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
452
559
|
private _getCurrentFieldMax;
|
|
453
560
|
/** Allocates increment values for a batch of items, assigning in order. */
|
|
454
561
|
private _assignBatchIncrements;
|
|
562
|
+
/** A find whose filter holds relational predicates, as an aggregation pipeline. */
|
|
563
|
+
private _aggregateFind;
|
|
455
564
|
private _buildFindOptions;
|
|
456
565
|
/**
|
|
457
566
|
* Returns MongoDB collation options if any filter field has a non-binary collation.
|
|
458
567
|
* Uses pre-computed insights when available, falls back to computing them on demand.
|
|
459
568
|
* Maps: nocase → strength 2 (case-insensitive), unicode → strength 1 (case+accent-insensitive).
|
|
569
|
+
* Predicate-free filters only — a filter with relational predicates never gets an
|
|
570
|
+
* operation-wide collation ({@link _readOpts}), so insights are never computed over
|
|
571
|
+
* resolved predicate operands.
|
|
460
572
|
*/
|
|
461
573
|
private _getCollationOpts;
|
|
462
574
|
protected _addMongoIndexField(type: TPlainIndex["type"], name: string, field: string, weight?: number): void;
|
|
@@ -484,27 +596,10 @@ declare class MongoAdapter extends BaseDbAdapter {
|
|
|
484
596
|
private _descendSearchNode;
|
|
485
597
|
}
|
|
486
598
|
//#endregion
|
|
487
|
-
//#region src/lib/mongo-filter.d.ts
|
|
488
|
-
/**
|
|
489
|
-
* Translates a generic {@link FilterExpr} into a MongoDB-compatible
|
|
490
|
-
* {@link Filter} document.
|
|
491
|
-
*
|
|
492
|
-
* MongoDB's query language is nearly identical to the `FilterExpr` structure,
|
|
493
|
-
* so this is largely a structural pass-through via the `walkFilter` visitor.
|
|
494
|
-
* `fieldOperands` (view predicates only — `translateQueryTree` output) turns
|
|
495
|
-
* `{ $field: path }` operands into field-to-field `$expr` comparisons; a
|
|
496
|
-
* request filter never gets that reading.
|
|
497
|
-
*/
|
|
498
|
-
declare function buildMongoFilter(filter: FilterExpr, {
|
|
499
|
-
fieldOperands
|
|
500
|
-
}?: {
|
|
501
|
-
fieldOperands?: boolean;
|
|
502
|
-
}): Filter<any>;
|
|
503
|
-
//#endregion
|
|
504
599
|
//#region src/lib/validate-plugins.d.ts
|
|
505
600
|
declare const validateMongoIdPlugin: TValidatorPlugin;
|
|
506
601
|
//#endregion
|
|
507
602
|
//#region src/lib/index.d.ts
|
|
508
603
|
declare function createAdapter(connection: string, _options?: Record<string, unknown>): DbSpace;
|
|
509
604
|
//#endregion
|
|
510
|
-
export { CollectionPatcher, INDEX_PREFIX, MongoAdapter, TCollectionPatcherContext, type TMongoIndex, type TMongoSearchIndexDefinition, type TPlainIndex, type TSearchIndex, buildMongoFilter, createAdapter, mongoIndexKey, validateMongoIdPlugin };
|
|
605
|
+
export { CollectionPatcher, INDEX_PREFIX, MongoAdapter, REL_FILTER_TEMP_PREFIX, TCollectionPatcherContext, TMongoFieldCollation, TMongoFilterOptions, TMongoFilterPlan, type TMongoIndex, type TMongoSearchIndexDefinition, type TPlainIndex, type TSearchIndex, buildMongoFilter, buildMongoQuery, collationOfAdapter, createAdapter, mongoFilterStages, mongoIndexKey, planStages, validateMongoIdPlugin };
|