@lossless.org/client 1.12.0 → 1.14.0
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/nosqldb/classes.db.d.ts +1 -1
- package/dist_ts/nosqldb/classes.db.js +1 -1
- package/dist_ts/nosqldb/classes.doc.d.ts +7 -0
- package/dist_ts/nosqldb/classes.doc.js +23 -1
- package/dist_ts/nosqldb/classes.persistence.d.ts +6 -0
- package/dist_ts/nosqldb/classes.persistence.js +8 -1
- package/dist_ts/nosqldb/classes.queryplaninspection.d.ts +65 -0
- package/dist_ts/nosqldb/classes.queryplaninspection.js +148 -0
- package/dist_ts/nosqldb/classes.session.d.ts +29 -0
- package/dist_ts/nosqldb/classes.session.js +114 -32
- package/dist_ts/nosqldb/index.d.ts +1 -0
- package/dist_ts/nosqldb/index.js +1 -1
- package/package.json +4 -4
- package/readme.md +10 -7
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/nosqldb/classes.db.ts +5 -1
- package/ts/nosqldb/classes.doc.ts +30 -0
- package/ts/nosqldb/classes.persistence.ts +9 -0
- package/ts/nosqldb/classes.queryplaninspection.ts +220 -0
- package/ts/nosqldb/classes.session.ts +161 -45
- package/ts/nosqldb/index.ts +3 -0
|
@@ -25,6 +25,12 @@ export declare const isMongoDeadlineError: (errorArg: unknown) => boolean;
|
|
|
25
25
|
/** Maps an expired driver deadline to `timeout`; every other error passes through unchanged. */
|
|
26
26
|
export declare const normalizeDeadlineError: (errorArg: unknown) => unknown;
|
|
27
27
|
export declare const isMongoTransactionRetryError: (errorArg: unknown) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The server or the driver stated that the transaction was aborted and may be
|
|
30
|
+
* run again from its start, so nothing of it was committed. A timeout the
|
|
31
|
+
* driver raises in place of such an error copies its labels.
|
|
32
|
+
*/
|
|
33
|
+
export declare const isMongoTransientTransactionError: (errorArg: unknown) => boolean;
|
|
28
34
|
export declare const isMongoDuplicateKeyError: (errorArg: unknown) => errorArg is plugins.mongodb.MongoServerError;
|
|
29
35
|
/**
|
|
30
36
|
* MongoDB refuses an index whose key or name collides with an existing one:
|
|
@@ -34,6 +34,13 @@ export const normalizeDeadlineError = (errorArg) => isMongoDeadlineError(errorAr
|
|
|
34
34
|
export const isMongoTransactionRetryError = (errorArg) => errorArg instanceof plugins.mongodb.MongoServerError &&
|
|
35
35
|
(errorArg.hasErrorLabel('TransientTransactionError') ||
|
|
36
36
|
errorArg.hasErrorLabel('UnknownTransactionCommitResult'));
|
|
37
|
+
/**
|
|
38
|
+
* The server or the driver stated that the transaction was aborted and may be
|
|
39
|
+
* run again from its start, so nothing of it was committed. A timeout the
|
|
40
|
+
* driver raises in place of such an error copies its labels.
|
|
41
|
+
*/
|
|
42
|
+
export const isMongoTransientTransactionError = (errorArg) => errorArg instanceof plugins.mongodb.MongoError
|
|
43
|
+
&& errorArg.hasErrorLabel(plugins.mongodb.MongoErrorLabel.TransientTransactionError);
|
|
37
44
|
export const isMongoDuplicateKeyError = (errorArg) => {
|
|
38
45
|
return (errorArg instanceof plugins.mongodb.MongoServerError &&
|
|
39
46
|
(errorArg.code === 11000 || errorArg.codeName === 'DuplicateKey'));
|
|
@@ -62,4 +69,4 @@ export const normalizeOrdinaryPersistenceError = (errorArg, messageArg) => {
|
|
|
62
69
|
}
|
|
63
70
|
throw errorArg;
|
|
64
71
|
};
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wZXJzaXN0ZW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL25vc3FsZGIvY2xhc3Nlcy5wZXJzaXN0ZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQVd4Qzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLHlCQUEwQixTQUFRLEtBQUs7SUFDbEMsSUFBSSxDQUFpQztJQUVyRCxZQUNFLE9BQXVDLEVBQ3ZDLFVBQWtCLEVBQ2xCLFVBQXlCO1FBRXpCLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLElBQUksR0FBRywyQkFBMkIsQ0FBQztRQUN4QyxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztJQUN0QixDQUFDO0NBQ0Y7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLENBQ3pDLFVBQWtCLEVBQ2xCLFFBQWtCLEVBQ1MsRUFBRSxDQUM3QixJQUFJLHlCQUF5QixDQUMzQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFFBQVEsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQ3pELENBQUM7QUFFSjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxRQUFpQixFQUFXLEVBQUUsQ0FDakUsUUFBUSxZQUFZLE9BQU8sQ0FBQyxPQUFPLENBQUMsMEJBQTBCO09BQzNELENBQ0QsUUFBUSxZQUFZLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUJBQW1CO1dBQ3BELFFBQVEsQ0FBQyxhQUFhLFlBQVksT0FBTyxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsQ0FDaEYsQ0FBQztBQUVKLGdHQUFnRztBQUNoRyxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFFBQWlCLEVBQVcsRUFBRSxDQUNuRSxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7SUFDNUIsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLG1EQUFtRCxFQUFFLFFBQVEsQ0FBQztJQUM1RixDQUFDLENBQUMsUUFBUSxDQUFDO0FBRWYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxRQUFpQixFQUFXLEVBQUUsQ0FDekUsUUFBUSxZQUFZLE9BQU8sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCO0lBQ3BELENBQ0UsUUFBUSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsQ0FBQztRQUNuRCxRQUFRLENBQUMsYUFBYSxDQUFDLGdDQUFnQyxDQUFDLENBQ3pELENBQUM7QUFFSjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsQ0FBQyxRQUFpQixFQUFXLEVBQUUsQ0FDN0UsUUFBUSxZQUFZLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVTtPQUMzQyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLHlCQUF5QixDQUFDLENBQUM7QUFFdkYsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FDdEMsUUFBaUIsRUFDNkIsRUFBRTtJQUNoRCxPQUFPLENBQ0wsUUFBUSxZQUFZLE9BQU8sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCO1FBQ3BELENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxLQUFLLElBQUksUUFBUSxDQUFDLFFBQVEsS0FBSyxjQUFjLENBQUMsQ0FDbEUsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxDQUN2QyxRQUFpQixFQUM2QixFQUFFO0lBQ2hELE9BQU8sQ0FDTCxRQUFRLFlBQVksT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0I7UUFDcEQsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLEVBQUU7WUFDbkIsUUFBUSxDQUFDLElBQUksS0FBSyxFQUFFO1lBQ3BCLFFBQVEsQ0FBQyxRQUFRLEtBQUssc0JBQXNCO1lBQzVDLFFBQVEsQ0FBQyxRQUFRLEtBQUssdUJBQXVCLENBQUMsQ0FDakQsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFHLENBQy9DLFFBQWlCLEVBQ2pCLFVBQWtCLEVBQ1gsRUFBRTtJQUNULElBQ0UsUUFBUSxZQUFZLHlCQUF5QjtRQUM3Qyw0QkFBNEIsQ0FBQyxRQUFRLENBQUMsRUFDdEMsQ0FBQztRQUNELE1BQU0sUUFBUSxDQUFDO0lBQ2pCLENBQUM7SUFDRCxJQUFJLHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDdkMsTUFBTSxJQUFJLHlCQUF5QixDQUFDLGlCQUFpQixFQUFFLFVBQVUsRUFBRTtZQUNqRSxLQUFLLEVBQUUsUUFBUTtTQUNoQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsTUFBTSxRQUFRLENBQUM7QUFDakIsQ0FBQyxDQUFDIn0=
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import type { SmartdataDb } from './classes.db.js';
|
|
3
|
+
import type { MongoFilter, TSmartdataProjection, TSmartdataSort } from './classes.doc.js';
|
|
4
|
+
export interface ISmartdataQueryPlanOptions<T> {
|
|
5
|
+
/** Validated exactly like the filter of the model's ordinary reads. */
|
|
6
|
+
filter: MongoFilter<T>;
|
|
7
|
+
/** Declared paths or `_id`, each 1 or -1, as for `getCursor()` and `getOffsetPage()`. */
|
|
8
|
+
sort?: TSmartdataSort<T>;
|
|
9
|
+
/** Declared paths or `_id`, 0 or 1, as for `getCursor()` and `getOffsetPage()`. */
|
|
10
|
+
projection?: TSmartdataProjection<T>;
|
|
11
|
+
/** 1..10000. Without it the plan executes over every match. */
|
|
12
|
+
limit?: number;
|
|
13
|
+
/** Client deadline for the explained execution. Default 5000ms, maximum 120000ms. */
|
|
14
|
+
timeoutMS?: number;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
/** One stage of the winning plan, in depth-first order from the root. */
|
|
18
|
+
export interface ISmartdataQueryPlanStage {
|
|
19
|
+
/** The engine's stage name, such as `IXSCAN`, `COLLSCAN`, `FETCH`, `SORT` or `LIMIT`. */
|
|
20
|
+
readonly stage: string;
|
|
21
|
+
/** 0 for the root; a stage's inputs follow it at one level deeper. */
|
|
22
|
+
readonly depth: number;
|
|
23
|
+
/** The index the stage reads, when the engine names one. */
|
|
24
|
+
readonly indexName?: string;
|
|
25
|
+
/** The scan direction, when the engine states one. */
|
|
26
|
+
readonly direction?: 'forward' | 'backward';
|
|
27
|
+
}
|
|
28
|
+
export interface ISmartdataQueryPlan {
|
|
29
|
+
/** The winning plan's stage tree, flattened depth-first. */
|
|
30
|
+
readonly stages: readonly ISmartdataQueryPlanStage[];
|
|
31
|
+
readonly nReturned: number;
|
|
32
|
+
readonly totalKeysExamined: number;
|
|
33
|
+
readonly totalDocsExamined: number;
|
|
34
|
+
/** Present when the engine reports it. */
|
|
35
|
+
readonly executionTimeMillis?: number;
|
|
36
|
+
}
|
|
37
|
+
/** @internal The query-plan options after their bounds are checked. */
|
|
38
|
+
export interface IValidatedQueryPlanOptions<T> {
|
|
39
|
+
readonly filter: MongoFilter<T>;
|
|
40
|
+
readonly sort: TSmartdataSort<T> | undefined;
|
|
41
|
+
readonly projection: TSmartdataProjection<T> | undefined;
|
|
42
|
+
readonly limit: number | undefined;
|
|
43
|
+
readonly timeoutMS: number;
|
|
44
|
+
readonly signal: AbortSignal | undefined;
|
|
45
|
+
}
|
|
46
|
+
/** @internal The normalized query one inspection explains. */
|
|
47
|
+
export interface IQueryPlanRequest {
|
|
48
|
+
readonly collectionName: string;
|
|
49
|
+
readonly filter: plugins.mongodb.Filter<plugins.mongodb.Document>;
|
|
50
|
+
readonly sort: plugins.mongodb.Sort | undefined;
|
|
51
|
+
readonly projection: plugins.mongodb.Document | undefined;
|
|
52
|
+
readonly limit: number | undefined;
|
|
53
|
+
readonly timeoutMS: number;
|
|
54
|
+
readonly signal: AbortSignal | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** @internal Refuses every option shape the query-plan inspection does not define. */
|
|
57
|
+
export declare const requireQueryPlanOptions: <T>(optionsArg: ISmartdataQueryPlanOptions<T>) => IValidatedQueryPlanOptions<T>;
|
|
58
|
+
/** @internal Reduces an `executionStats` explanation to the stable summary; exported for its unit test. */
|
|
59
|
+
export declare const summarizeQueryPlanExplanation: (explanationArg: plugins.mongodb.Document) => ISmartdataQueryPlan;
|
|
60
|
+
/**
|
|
61
|
+
* @internal Explains one model query with `executionStats` on the given
|
|
62
|
+
* database. Nothing is created, bound or hydrated; the raw explanation never
|
|
63
|
+
* leaves this module.
|
|
64
|
+
*/
|
|
65
|
+
export declare const inspectQueryPlan: (dbArg: SmartdataDb, requestArg: IQueryPlanRequest) => Promise<ISmartdataQueryPlan>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { SmartdataPersistenceError, createSmartdataTimeoutError, isMongoDeadlineError } from './classes.persistence.js';
|
|
3
|
+
import { requireOperationSignal, requireOperationTimeoutMS } from './classes.operationdeadline.js';
|
|
4
|
+
import { runCursorOperation } from './classes.cursoroperation.js';
|
|
5
|
+
import { collectionTopologyDbInspectionSymbol } from './classes.collectiontopology.js';
|
|
6
|
+
const queryPlanOptionKeys = ['filter', 'sort', 'projection', 'limit', 'timeoutMS', 'signal'];
|
|
7
|
+
const maximumPlanStages = 256;
|
|
8
|
+
const maximumPlanDepth = 64;
|
|
9
|
+
const maximumPlanStringLength = 1024;
|
|
10
|
+
/** MongoDB's `CommandNotFound`, the answer of an engine that implements no `explain`. */
|
|
11
|
+
const commandNotFoundCode = 59;
|
|
12
|
+
const isRecord = (valueArg) => typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg);
|
|
13
|
+
const isPlainRecord = (valueArg) => {
|
|
14
|
+
if (!isRecord(valueArg))
|
|
15
|
+
return false;
|
|
16
|
+
const prototype = Object.getPrototypeOf(valueArg);
|
|
17
|
+
return prototype === Object.prototype || prototype === null;
|
|
18
|
+
};
|
|
19
|
+
/** @internal Refuses every option shape the query-plan inspection does not define. */
|
|
20
|
+
export const requireQueryPlanOptions = (optionsArg) => {
|
|
21
|
+
const options = optionsArg;
|
|
22
|
+
if (!isPlainRecord(options) || Reflect.ownKeys(options).some((keyArg) => typeof keyArg !== 'string' || !queryPlanOptionKeys.includes(keyArg) ||
|
|
23
|
+
!('value' in Object.getOwnPropertyDescriptor(options, keyArg)))) {
|
|
24
|
+
throw new SmartdataPersistenceError('invalid_argument', 'Invalid query plan inspection options.');
|
|
25
|
+
}
|
|
26
|
+
if (!isPlainRecord(optionsArg.filter)) {
|
|
27
|
+
throw new SmartdataPersistenceError('invalid_argument', 'Query plan inspection requires a plain filter object.');
|
|
28
|
+
}
|
|
29
|
+
const limit = optionsArg.limit;
|
|
30
|
+
if (limit !== undefined &&
|
|
31
|
+
(typeof limit !== 'number' || !Number.isSafeInteger(limit) || limit < 1 || limit > 10_000)) {
|
|
32
|
+
throw new SmartdataPersistenceError('invalid_argument', 'limit must be an integer from 1 through 10000.');
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
filter: optionsArg.filter,
|
|
36
|
+
sort: optionsArg.sort,
|
|
37
|
+
projection: optionsArg.projection,
|
|
38
|
+
limit,
|
|
39
|
+
timeoutMS: requireOperationTimeoutMS(optionsArg.timeoutMS, 'timeoutMS') ?? 5_000,
|
|
40
|
+
signal: requireOperationSignal(optionsArg.signal, 'signal'),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const unreadablePlan = () => new SmartdataPersistenceError('unsupported_operation', 'The engine returned an unreadable query plan.');
|
|
44
|
+
const readCount = (valueArg) => {
|
|
45
|
+
if (typeof valueArg !== 'number' || !Number.isSafeInteger(valueArg) || valueArg < 0) {
|
|
46
|
+
throw unreadablePlan();
|
|
47
|
+
}
|
|
48
|
+
return valueArg;
|
|
49
|
+
};
|
|
50
|
+
const readPlanString = (valueArg) => {
|
|
51
|
+
if (typeof valueArg !== 'string' || valueArg.length === 0 || valueArg.length > maximumPlanStringLength) {
|
|
52
|
+
throw unreadablePlan();
|
|
53
|
+
}
|
|
54
|
+
return valueArg;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Flattens the winning plan depth-first. MongoDB's slot-based engine wraps the
|
|
58
|
+
* classic tree as `queryPlan`; every other field of a stage stays behind.
|
|
59
|
+
*/
|
|
60
|
+
const flattenWinningPlan = (winningPlanArg) => {
|
|
61
|
+
const root = isRecord(winningPlanArg) && winningPlanArg.stage === undefined && isRecord(winningPlanArg.queryPlan)
|
|
62
|
+
? winningPlanArg.queryPlan
|
|
63
|
+
: winningPlanArg;
|
|
64
|
+
const stages = [];
|
|
65
|
+
const visit = (nodeArg, depthArg) => {
|
|
66
|
+
if (!isRecord(nodeArg) || depthArg >= maximumPlanDepth || stages.length === maximumPlanStages) {
|
|
67
|
+
throw unreadablePlan();
|
|
68
|
+
}
|
|
69
|
+
const direction = nodeArg.direction === 'forward' || nodeArg.direction === 'backward'
|
|
70
|
+
? nodeArg.direction
|
|
71
|
+
: undefined;
|
|
72
|
+
stages.push(Object.freeze({
|
|
73
|
+
stage: readPlanString(nodeArg.stage),
|
|
74
|
+
depth: depthArg,
|
|
75
|
+
...(nodeArg.indexName === undefined ? {} : { indexName: readPlanString(nodeArg.indexName) }),
|
|
76
|
+
...(direction === undefined ? {} : { direction }),
|
|
77
|
+
}));
|
|
78
|
+
const inputs = nodeArg.inputStages === undefined ? [] : nodeArg.inputStages;
|
|
79
|
+
if (!Array.isArray(inputs))
|
|
80
|
+
throw unreadablePlan();
|
|
81
|
+
if (nodeArg.inputStage !== undefined)
|
|
82
|
+
visit(nodeArg.inputStage, depthArg + 1);
|
|
83
|
+
for (const input of inputs)
|
|
84
|
+
visit(input, depthArg + 1);
|
|
85
|
+
};
|
|
86
|
+
visit(root, 0);
|
|
87
|
+
return stages;
|
|
88
|
+
};
|
|
89
|
+
/** @internal Reduces an `executionStats` explanation to the stable summary; exported for its unit test. */
|
|
90
|
+
export const summarizeQueryPlanExplanation = (explanationArg) => {
|
|
91
|
+
const queryPlanner = explanationArg.queryPlanner;
|
|
92
|
+
const executionStats = explanationArg.executionStats;
|
|
93
|
+
if (!isRecord(queryPlanner) || !isRecord(executionStats) || executionStats.executionSuccess === false) {
|
|
94
|
+
throw unreadablePlan();
|
|
95
|
+
}
|
|
96
|
+
const stages = flattenWinningPlan(queryPlanner.winningPlan);
|
|
97
|
+
const executionTimeMillis = executionStats.executionTimeMillis === undefined
|
|
98
|
+
? undefined
|
|
99
|
+
: readCount(executionStats.executionTimeMillis);
|
|
100
|
+
return Object.freeze({
|
|
101
|
+
stages: Object.freeze(stages),
|
|
102
|
+
nReturned: readCount(executionStats.nReturned),
|
|
103
|
+
totalKeysExamined: readCount(executionStats.totalKeysExamined),
|
|
104
|
+
totalDocsExamined: readCount(executionStats.totalDocsExamined),
|
|
105
|
+
...(executionTimeMillis === undefined ? {} : { executionTimeMillis }),
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* @internal Explains one model query with `executionStats` on the given
|
|
110
|
+
* database. Nothing is created, bound or hydrated; the raw explanation never
|
|
111
|
+
* leaves this module.
|
|
112
|
+
*/
|
|
113
|
+
export const inspectQueryPlan = async (dbArg, requestArg) => {
|
|
114
|
+
const { signal } = requestArg;
|
|
115
|
+
signal?.throwIfAborted();
|
|
116
|
+
let failure;
|
|
117
|
+
let explanation;
|
|
118
|
+
try {
|
|
119
|
+
explanation = await dbArg[collectionTopologyDbInspectionSymbol](async (mongoDbArg) => {
|
|
120
|
+
const cursor = mongoDbArg.collection(requestArg.collectionName).find(requestArg.filter, {
|
|
121
|
+
...(requestArg.sort === undefined ? {} : { sort: requestArg.sort }),
|
|
122
|
+
...(requestArg.projection === undefined ? {} : { projection: requestArg.projection }),
|
|
123
|
+
...(requestArg.limit === undefined ? {} : { limit: requestArg.limit }),
|
|
124
|
+
...(signal === undefined ? {} : { signal }),
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
return await runCursorOperation(cursor, (cursorArg) => cursorArg.explain('executionStats', { timeoutMS: requestArg.timeoutMS }), signal);
|
|
128
|
+
}
|
|
129
|
+
catch (errorArg) {
|
|
130
|
+
failure = { error: errorArg };
|
|
131
|
+
throw errorArg;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (errorArg) {
|
|
136
|
+
signal?.throwIfAborted();
|
|
137
|
+
if (failure !== undefined && isMongoDeadlineError(failure.error)) {
|
|
138
|
+
throw createSmartdataTimeoutError('Query plan inspection exceeded its client deadline.', failure.error);
|
|
139
|
+
}
|
|
140
|
+
if (failure !== undefined && failure.error instanceof plugins.mongodb.MongoServerError &&
|
|
141
|
+
failure.error.code === commandNotFoundCode) {
|
|
142
|
+
throw new SmartdataPersistenceError('unsupported_operation', 'The connected engine does not explain queries.');
|
|
143
|
+
}
|
|
144
|
+
throw errorArg;
|
|
145
|
+
}
|
|
146
|
+
return summarizeQueryPlanExplanation(explanation);
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5xdWVyeXBsYW5pbnNwZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvbm9zcWxkYi9jbGFzc2VzLnF1ZXJ5cGxhbmluc3BlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFHeEMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDeEgsT0FBTyxFQUFFLHNCQUFzQixFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG9DQUFvQyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUEyRHZGLE1BQU0sbUJBQW1CLEdBQXNCLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNoSCxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUM5QixNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztBQUM1QixNQUFNLHVCQUF1QixHQUFHLElBQUksQ0FBQztBQUNyQyx5RkFBeUY7QUFDekYsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFFL0IsTUFBTSxRQUFRLEdBQUcsQ0FBQyxRQUFpQixFQUF1QyxFQUFFLENBQzFFLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVoRixNQUFNLGFBQWEsR0FBRyxDQUFDLFFBQWlCLEVBQXVDLEVBQUU7SUFDL0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUN0QyxNQUFNLFNBQVMsR0FBRyxN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
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import type { SmartdataDb } from './classes.db.js';
|
|
3
3
|
import { SmartdataOperationDeadline } from './classes.operationdeadline.js';
|
|
4
|
+
/**
|
|
5
|
+
* Whether a transaction that `SmartdataSession.withTransaction()` rejected
|
|
6
|
+
* could have committed:
|
|
7
|
+
*
|
|
8
|
+
* - `not_committed`: nothing of the transaction was committed. The call failed
|
|
9
|
+
* before the driver sent a commit, or the database answered the commit with
|
|
10
|
+
* an error that states the transaction was aborted.
|
|
11
|
+
* - `unknown`: a commit was sent and its outcome was never confirmed; it may
|
|
12
|
+
* have applied.
|
|
13
|
+
*/
|
|
14
|
+
export type TSmartdataTransactionCommitOutcome = 'not_committed' | 'unknown';
|
|
4
15
|
interface ISmartdataSessionAcquireOptions {
|
|
5
16
|
ordinaryWrite?: boolean;
|
|
6
17
|
}
|
|
@@ -32,6 +43,20 @@ export interface ISmartdataTransactionOptions {
|
|
|
32
43
|
signal?: AbortSignal;
|
|
33
44
|
}
|
|
34
45
|
export declare class SmartdataSession {
|
|
46
|
+
/**
|
|
47
|
+
* Whether the transaction whose `withTransaction()` call rejected with
|
|
48
|
+
* `errorArg` could have committed: `not_committed` when nothing of it was
|
|
49
|
+
* committed, `unknown` when a commit was sent and never confirmed, so it may
|
|
50
|
+
* have applied. Every rejection of `withTransaction()` carries one, whatever
|
|
51
|
+
* it is: the client's own errors, the callback's error, the abort reason or
|
|
52
|
+
* a driver error, which all keep their identity. A value several calls
|
|
53
|
+
* rejected with reads `unknown` once any of them may have committed.
|
|
54
|
+
*
|
|
55
|
+
* Returns `undefined` for any other value, and for a primitive rejection —
|
|
56
|
+
* a callback that throws a string, or a string abort reason — which cannot
|
|
57
|
+
* carry the outcome; treat `undefined` as `unknown`.
|
|
58
|
+
*/
|
|
59
|
+
static getCommitOutcome(errorArg: unknown): TSmartdataTransactionCommitOutcome | undefined;
|
|
35
60
|
/**
|
|
36
61
|
* Runs `callbackArg` in a transaction, retrying it as the driver decides.
|
|
37
62
|
*
|
|
@@ -63,6 +88,10 @@ export declare class SmartdataSession {
|
|
|
63
88
|
* `unsupported_operation`: before the callback returned nothing was
|
|
64
89
|
* committed, afterwards the commit outcome is unknown. The callback's
|
|
65
90
|
* error, if it threw, is the `cause`.
|
|
91
|
+
*
|
|
92
|
+
* Every rejection states whether the transaction could have committed:
|
|
93
|
+
* `SmartdataSession.getCommitOutcome(error)` returns `not_committed` or
|
|
94
|
+
* `unknown` for the value the call rejected with.
|
|
66
95
|
*/
|
|
67
96
|
withTransaction<TResult>(callbackArg: (sessionArg: SmartdataSession) => Promise<TResult>, optionsArg?: ISmartdataTransactionOptions): Promise<TResult | undefined>;
|
|
68
97
|
close(): Promise<void>;
|