uql-orm 0.22.0 → 0.24.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/README.md +4 -4
- package/dist/browser/uql-browser.min.js.map +3 -3
- package/dist/dialect/abstractSqlDialect.d.ts +14 -1
- package/dist/dialect/abstractSqlDialect.js +21 -14
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +11 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +25 -0
- package/dist/dialect/pgLikeSqlDialect.d.ts +4 -7
- package/dist/dialect/pgLikeSqlDialect.js +7 -12
- package/dist/entity/decorator/bag.d.ts +35 -0
- package/dist/entity/decorator/bag.js +54 -0
- package/dist/entity/decorator/entity.d.ts +28 -2
- package/dist/entity/decorator/entity.js +40 -2
- package/dist/entity/decorator/members.d.ts +51 -0
- package/dist/entity/decorator/members.js +51 -0
- package/dist/entity/index.d.ts +3 -1
- package/dist/entity/index.js +3 -1
- package/dist/entity/metadata/definition.d.ts +23 -9
- package/dist/entity/metadata/definition.js +55 -100
- package/dist/http/contract.js +1 -2
- package/dist/http/handler.js +5 -26
- package/dist/http/query.js +1 -1
- package/dist/migrate/acquireQuerierForMigrations.d.ts +13 -1
- package/dist/migrate/acquireQuerierForMigrations.js +28 -0
- package/dist/migrate/cli-config.js +24 -8
- package/dist/migrate/cli.js +5 -1
- package/dist/migrate/codegen/entityCodeGenerator.js +3 -4
- package/dist/migrate/codegen/index.d.ts +0 -1
- package/dist/migrate/codegen/index.js +0 -2
- package/dist/migrate/drift/driftDetector.d.ts +10 -1
- package/dist/migrate/drift/driftDetector.js +22 -5
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +5 -1
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +17 -27
- package/dist/migrate/introspection/mongoIntrospector.js +7 -13
- package/dist/migrate/migrator.js +44 -81
- package/dist/migrate/storage/databaseStorage.d.ts +2 -0
- package/dist/migrate/storage/databaseStorage.js +8 -23
- package/dist/mongo/mongodbQuerier.js +171 -229
- package/dist/nestjs/uqlContextInterceptor.js +58 -22
- package/dist/nestjs/uqlModule.d.ts +2 -11
- package/dist/nestjs/uqlModule.js +93 -44
- package/dist/postgres/postgresDialect.js +2 -2
- package/dist/querier/abstractQuerier.d.ts +28 -0
- package/dist/querier/abstractQuerier.js +47 -22
- package/dist/querier/abstractQuerierPool.d.ts +21 -1
- package/dist/querier/abstractQuerierPool.js +113 -3
- package/dist/querier/abstractSqlQuerier.d.ts +1 -3
- package/dist/querier/abstractSqlQuerier.js +51 -96
- package/dist/querier/index.d.ts +3 -1
- package/dist/querier/index.js +3 -1
- package/dist/querier/querierContext.browser.d.ts +12 -0
- package/dist/querier/querierContext.browser.js +18 -0
- package/dist/querier/querierContext.d.ts +22 -0
- package/dist/querier/querierContext.js +42 -0
- package/dist/querier/queryError.d.ts +22 -0
- package/dist/querier/queryError.js +20 -0
- package/dist/querier/transactional.d.ts +26 -0
- package/dist/querier/transactional.js +43 -0
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/schemaASTBuilder.d.ts +1 -1
- package/dist/schema/schemaASTBuilder.js +2 -2
- package/dist/schema/types.d.ts +0 -21
- package/dist/sqlite/abstractSqliteQuerier.d.ts +9 -2
- package/dist/sqlite/hranaQuerier.js +20 -42
- package/dist/sqlite/index.d.ts +1 -0
- package/dist/sqlite/index.js +1 -0
- package/dist/sqlite/localSqliteQuerierPool.d.ts +31 -0
- package/dist/sqlite/localSqliteQuerierPool.js +34 -0
- package/dist/sqlite/nodeSqliteAdapter.d.ts +35 -0
- package/dist/sqlite/nodeSqliteAdapter.js +28 -0
- package/dist/sqlite/nodeSqliteQuerierPool.d.ts +28 -0
- package/dist/sqlite/nodeSqliteQuerierPool.js +29 -0
- package/dist/sqlite/sqliteDialect.d.ts +1 -2
- package/dist/sqlite/sqliteDialect.js +0 -13
- package/dist/sqlite/sqliteQuerierPool.d.ts +10 -23
- package/dist/sqlite/sqliteQuerierPool.js +9 -28
- package/dist/type/entity.d.ts +95 -28
- package/dist/type/querier.d.ts +8 -35
- package/dist/type/querierPool.d.ts +13 -12
- package/dist/type/universalQuerier.d.ts +23 -7
- package/dist/util/hook.util.js +1 -1
- package/package.json +7 -16
- package/dist/entity/decorator/field.d.ts +0 -2
- package/dist/entity/decorator/field.js +0 -7
- package/dist/entity/decorator/filter.d.ts +0 -7
- package/dist/entity/decorator/filter.js +0 -11
- package/dist/entity/decorator/hook.d.ts +0 -7
- package/dist/entity/decorator/hook.js +0 -14
- package/dist/entity/decorator/id.d.ts +0 -2
- package/dist/entity/decorator/id.js +0 -7
- package/dist/entity/decorator/index-decorator.d.ts +0 -22
- package/dist/entity/decorator/index-decorator.js +0 -26
- package/dist/entity/decorator/index.d.ts +0 -8
- package/dist/entity/decorator/index.js +0 -8
- package/dist/entity/decorator/relation.d.ts +0 -8
- package/dist/entity/decorator/relation.js +0 -19
- package/dist/migrate/codegen/smartRelationDetector.d.ts +0 -47
- package/dist/migrate/codegen/smartRelationDetector.js +0 -134
- package/dist/querier/decorator/index.d.ts +0 -4
- package/dist/querier/decorator/index.js +0 -4
- package/dist/querier/decorator/injectQuerier.d.ts +0 -3
- package/dist/querier/decorator/injectQuerier.js +0 -33
- package/dist/querier/decorator/log.d.ts +0 -32
- package/dist/querier/decorator/log.js +0 -52
- package/dist/querier/decorator/serialized.d.ts +0 -6
- package/dist/querier/decorator/serialized.js +0 -13
- package/dist/querier/decorator/transactional.d.ts +0 -6
- package/dist/querier/decorator/transactional.js +0 -48
package/dist/nestjs/uqlModule.js
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
9
27
|
};
|
|
10
|
-
var
|
|
11
|
-
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
12
34
|
};
|
|
13
|
-
|
|
14
|
-
import { Inject, Module, } from '@nestjs/common';
|
|
35
|
+
import { Module, } from '@nestjs/common';
|
|
15
36
|
import { APP_INTERCEPTOR } from '@nestjs/core';
|
|
16
37
|
import { setQuerierPool } from '../options.js';
|
|
17
38
|
import { UqlContextInterceptor } from './uqlContextInterceptor.js';
|
|
@@ -28,7 +49,16 @@ export const UQL_QUERIER_POOL = Symbol('UQL_QUERIER_POOL');
|
|
|
28
49
|
* optionally scopes every request to a {@link UqlContext} (multi-tenancy), and ends the pool on
|
|
29
50
|
* application shutdown.
|
|
30
51
|
*/
|
|
31
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Ends the pool when Nest shuts down.
|
|
54
|
+
*
|
|
55
|
+
* @remarks A provider rather than a hook on the module class, and built through `useFactory` with an
|
|
56
|
+
* `inject` list rather than constructor injection: Nest injects constructor parameters with a parameter
|
|
57
|
+
* decorator, and the TC39 decorator spec has none, so `@Inject()` cannot appear in a file compiled
|
|
58
|
+
* against it. Nest runs lifecycle hooks on providers too, so this keeps the pool that *this* module was
|
|
59
|
+
* configured with instead of reaching for the global default.
|
|
60
|
+
*/
|
|
61
|
+
class UqlPoolLifecycle {
|
|
32
62
|
pool;
|
|
33
63
|
constructor(pool) {
|
|
34
64
|
this.pool = pool;
|
|
@@ -36,36 +66,55 @@ let UqlModule = UqlModule_1 = class UqlModule {
|
|
|
36
66
|
onApplicationShutdown() {
|
|
37
67
|
return this.pool.end();
|
|
38
68
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
inject,
|
|
54
|
-
};
|
|
55
|
-
return UqlModule_1.build(global, poolProvider, getContext, imports);
|
|
56
|
-
}
|
|
57
|
-
static build(global, poolProvider, getContext, imports) {
|
|
58
|
-
const providers = [poolProvider];
|
|
59
|
-
if (getContext) {
|
|
60
|
-
// Scope every request to its context so multi-tenancy / security filters apply automatically.
|
|
61
|
-
providers.push({ provide: APP_INTERCEPTOR, useValue: new UqlContextInterceptor(getContext) });
|
|
69
|
+
}
|
|
70
|
+
let UqlModule = (() => {
|
|
71
|
+
let _classDecorators = [Module({})];
|
|
72
|
+
let _classDescriptor;
|
|
73
|
+
let _classExtraInitializers = [];
|
|
74
|
+
let _classThis;
|
|
75
|
+
var UqlModule = class {
|
|
76
|
+
static { _classThis = this; }
|
|
77
|
+
static {
|
|
78
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
79
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
80
|
+
UqlModule = _classThis = _classDescriptor.value;
|
|
81
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
82
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
62
83
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
UqlModule
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
/** Configure with an already-built pool. */
|
|
85
|
+
static forRoot({ pool, global = true, getContext }) {
|
|
86
|
+
setQuerierPool(pool);
|
|
87
|
+
return UqlModule.build(global, { provide: UQL_QUERIER_POOL, useValue: pool }, getContext);
|
|
88
|
+
}
|
|
89
|
+
/** Configure with a pool built asynchronously from injected providers (e.g. `ConfigService`). */
|
|
90
|
+
static forRootAsync({ imports, useFactory, inject = [], global = true, getContext, }) {
|
|
91
|
+
const poolProvider = {
|
|
92
|
+
provide: UQL_QUERIER_POOL,
|
|
93
|
+
useFactory: async (...args) => {
|
|
94
|
+
const pool = await useFactory(...args);
|
|
95
|
+
setQuerierPool(pool); // register as UQL's default once the pool is resolved
|
|
96
|
+
return pool;
|
|
97
|
+
},
|
|
98
|
+
inject,
|
|
99
|
+
};
|
|
100
|
+
return UqlModule.build(global, poolProvider, getContext, imports);
|
|
101
|
+
}
|
|
102
|
+
static build(global, poolProvider, getContext, imports) {
|
|
103
|
+
const providers = [
|
|
104
|
+
poolProvider,
|
|
105
|
+
{
|
|
106
|
+
provide: UqlPoolLifecycle,
|
|
107
|
+
useFactory: (pool) => new UqlPoolLifecycle(pool),
|
|
108
|
+
inject: [UQL_QUERIER_POOL],
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
if (getContext) {
|
|
112
|
+
// Scope every request to its context so multi-tenancy / security filters apply automatically.
|
|
113
|
+
providers.push({ provide: APP_INTERCEPTOR, useValue: new UqlContextInterceptor(getContext) });
|
|
114
|
+
}
|
|
115
|
+
return { module: UqlModule, global, imports, providers, exports: [UQL_QUERIER_POOL] };
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
return UqlModule = _classThis;
|
|
119
|
+
})();
|
|
71
120
|
export { UqlModule };
|
|
@@ -10,7 +10,7 @@ export class PostgresDialect extends PgLikeSqlDialect {
|
|
|
10
10
|
dialectName = 'postgres';
|
|
11
11
|
vectorExtension = 'vector';
|
|
12
12
|
upsert(ctx, entity, conflictPaths, payload) {
|
|
13
|
-
// xmax system column is 0 for newly inserted
|
|
14
|
-
|
|
13
|
+
// The xmax system column is 0 for a newly inserted row and non-zero for an updated one (MVCC).
|
|
14
|
+
super.upsert(ctx, entity, conflictPaths, payload, `, (xmax = 0) AS ${this.escapeId('_created')}`);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -117,6 +117,23 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
117
117
|
private saveOneToOne;
|
|
118
118
|
private saveManyToOne;
|
|
119
119
|
abstract readonly hasOpenTransaction: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Runs `callback` in a transaction: begin, commit on success, roll back on failure.
|
|
122
|
+
*
|
|
123
|
+
* The single place that sequence is written; everything else delegates here, because both subtleties
|
|
124
|
+
* below were got wrong by code that hand-rolled it:
|
|
125
|
+
*
|
|
126
|
+
* - `beginTransaction` connects before it begins, so a refused connection lands in the catch with no
|
|
127
|
+
* transaction open. Rolling back regardless threw `not a pending transaction`, and that replaced the
|
|
128
|
+
* real cause: a wrong password surfaced as a transaction-state error.
|
|
129
|
+
* - A rollback that fails too is a consequence of the original failure, not news, so it must not
|
|
130
|
+
* replace it either.
|
|
131
|
+
*
|
|
132
|
+
* The connection is **not** released here: whoever took it from the pool gives it back, through
|
|
133
|
+
* {@link QuerierPool.transaction}, {@link QuerierPool.withQuerier} or `await using`. Releasing a
|
|
134
|
+
* connection this method never acquired is what forced every caller to know whether it still owned
|
|
135
|
+
* one afterwards.
|
|
136
|
+
*/
|
|
120
137
|
transaction<T>(callback: () => Promise<T>, opts?: TransactionOptions): Promise<T>;
|
|
121
138
|
/**
|
|
122
139
|
* Emit a lifecycle hook event for the given entity.
|
|
@@ -132,9 +149,20 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
132
149
|
* @returns A promise that resolves with the task's result.
|
|
133
150
|
*/
|
|
134
151
|
protected serialize<T>(task: () => Promise<T>): Promise<T>;
|
|
152
|
+
/**
|
|
153
|
+
* Runs `task`, logs `query` with how long it took, and tags any error it throws with that query.
|
|
154
|
+
*
|
|
155
|
+
* A method rather than the `@Log()` decorator it replaces. A standard-spec method decorator works by
|
|
156
|
+
* returning a replacement function, and a replacement cannot carry the original's type parameters, so
|
|
157
|
+
* decorating `internalFindMany<E extends Document>` made its signature unresolvable. Most of the query
|
|
158
|
+
* surface is generic like that, and wrapping at the call site costs one line while keeping the
|
|
159
|
+
* signature intact.
|
|
160
|
+
*/
|
|
161
|
+
protected timed<T>(query: string, values: unknown[] | undefined, task: () => Promise<T>): Promise<T>;
|
|
135
162
|
abstract beginTransaction(opts?: TransactionOptions): Promise<void>;
|
|
136
163
|
abstract commitTransaction(): Promise<void>;
|
|
137
164
|
abstract rollbackTransaction(): Promise<void>;
|
|
138
165
|
protected abstract internalRelease(): Promise<void>;
|
|
139
166
|
release(): Promise<void>;
|
|
167
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
140
168
|
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
-
};
|
|
10
|
-
import { getMeta } from '../entity/decorator/index.js';
|
|
1
|
+
import { getMeta } from '../entity/index.js';
|
|
11
2
|
import { asSelectMap, augmentWhere, clone, filterPersistableRelationKeys, forEachRequestedRelation, getKeys, getRelationRequestSummary, LoggerWrapper, parseRelationAtKey, parseRelationQueryValue, runHooks, } from '../util/index.js';
|
|
12
|
-
import {
|
|
3
|
+
import { enrichError } from './queryError.js';
|
|
13
4
|
/**
|
|
14
5
|
* Base class for all database queriers.
|
|
15
6
|
* It provides a standardized way to execute tasks serially to prevent race conditions on database connections.
|
|
@@ -366,6 +357,23 @@ export class AbstractQuerier {
|
|
|
366
357
|
const referenceId = await this.insertOne(relEntity, relPayload);
|
|
367
358
|
await this.updateOneById(entity, id, { [localField]: referenceId });
|
|
368
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Runs `callback` in a transaction: begin, commit on success, roll back on failure.
|
|
362
|
+
*
|
|
363
|
+
* The single place that sequence is written; everything else delegates here, because both subtleties
|
|
364
|
+
* below were got wrong by code that hand-rolled it:
|
|
365
|
+
*
|
|
366
|
+
* - `beginTransaction` connects before it begins, so a refused connection lands in the catch with no
|
|
367
|
+
* transaction open. Rolling back regardless threw `not a pending transaction`, and that replaced the
|
|
368
|
+
* real cause: a wrong password surfaced as a transaction-state error.
|
|
369
|
+
* - A rollback that fails too is a consequence of the original failure, not news, so it must not
|
|
370
|
+
* replace it either.
|
|
371
|
+
*
|
|
372
|
+
* The connection is **not** released here: whoever took it from the pool gives it back, through
|
|
373
|
+
* {@link QuerierPool.transaction}, {@link QuerierPool.withQuerier} or `await using`. Releasing a
|
|
374
|
+
* connection this method never acquired is what forced every caller to know whether it still owned
|
|
375
|
+
* one afterwards.
|
|
376
|
+
*/
|
|
369
377
|
async transaction(callback, opts) {
|
|
370
378
|
if (this.hasOpenTransaction) {
|
|
371
379
|
return callback();
|
|
@@ -377,12 +385,11 @@ export class AbstractQuerier {
|
|
|
377
385
|
return res;
|
|
378
386
|
}
|
|
379
387
|
catch (err) {
|
|
380
|
-
|
|
388
|
+
if (this.hasOpenTransaction) {
|
|
389
|
+
await this.rollbackTransaction().catch(() => { });
|
|
390
|
+
}
|
|
381
391
|
throw err;
|
|
382
392
|
}
|
|
383
|
-
finally {
|
|
384
|
-
await this.release();
|
|
385
|
-
}
|
|
386
393
|
}
|
|
387
394
|
/**
|
|
388
395
|
* Emit a lifecycle hook event for the given entity.
|
|
@@ -428,13 +435,31 @@ export class AbstractQuerier {
|
|
|
428
435
|
this.taskQueue = res.catch(() => { });
|
|
429
436
|
return res;
|
|
430
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* Runs `task`, logs `query` with how long it took, and tags any error it throws with that query.
|
|
440
|
+
*
|
|
441
|
+
* A method rather than the `@Log()` decorator it replaces. A standard-spec method decorator works by
|
|
442
|
+
* returning a replacement function, and a replacement cannot carry the original's type parameters, so
|
|
443
|
+
* decorating `internalFindMany<E extends Document>` made its signature unresolvable. Most of the query
|
|
444
|
+
* surface is generic like that, and wrapping at the call site costs one line while keeping the
|
|
445
|
+
* signature intact.
|
|
446
|
+
*/
|
|
447
|
+
async timed(query, values, task) {
|
|
448
|
+
const startTime = performance.now();
|
|
449
|
+
try {
|
|
450
|
+
return await task();
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
throw enrichError(err, this.logger, query, values);
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
this.logger.logQuery(query, values, Math.round(performance.now() - startTime));
|
|
457
|
+
}
|
|
458
|
+
}
|
|
431
459
|
async release() {
|
|
432
|
-
return this.internalRelease();
|
|
460
|
+
return this.serialize(() => this.internalRelease());
|
|
461
|
+
}
|
|
462
|
+
async [Symbol.asyncDispose]() {
|
|
463
|
+
return this.release();
|
|
433
464
|
}
|
|
434
465
|
}
|
|
435
|
-
__decorate([
|
|
436
|
-
Serialized(),
|
|
437
|
-
__metadata("design:type", Function),
|
|
438
|
-
__metadata("design:paramtypes", []),
|
|
439
|
-
__metadata("design:returntype", Promise)
|
|
440
|
-
], AbstractQuerier.prototype, "release", null);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AbstractDialect } from '../dialect/index.js';
|
|
2
|
-
import type { ExtraOptions, IdValue, PoolRunOptions, Querier, QuerierPool, Query, QueryAggMap, QueryAggregate, QueryAggregateResult, QueryGroupMap, QueryOne, QueryOptions, QuerySearch, TransactionOptions, Type } from '../type/index.js';
|
|
2
|
+
import type { ExtraOptions, IdValue, PoolRunOptions, Querier, QuerierPool, Query, QueryAggMap, QueryAggregate, QueryAggregateResult, QueryConflictPaths, QueryGroupMap, QueryOne, QueryOptions, QuerySearch, QueryUpdateResult, TransactionOptions, Type, UpdatePayload } from '../type/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Base pool: dialect id and behavior come only from the `dialect` instance (see {@link QuerierPool}).
|
|
5
5
|
*/
|
|
@@ -13,6 +13,9 @@ export declare abstract class AbstractQuerierPool<Q extends Querier, D extends A
|
|
|
13
13
|
abstract getQuerier(): Promise<Q>;
|
|
14
14
|
/**
|
|
15
15
|
* get a querier from the pool and run the given callback inside a transaction.
|
|
16
|
+
*
|
|
17
|
+
* The pool acquired the connection, so the pool releases it: `withQuerier` owns that half and
|
|
18
|
+
* `querier.transaction` owns begin/commit/rollback. Neither knows about the other's job.
|
|
16
19
|
*/
|
|
17
20
|
transaction<T>(callback: (querier: Q) => Promise<T>, opts?: TransactionOptions & PoolRunOptions): Promise<T>;
|
|
18
21
|
/**
|
|
@@ -24,9 +27,26 @@ export declare abstract class AbstractQuerierPool<Q extends Querier, D extends A
|
|
|
24
27
|
findOneById<E extends object>(entity: Type<E>, id: IdValue<E>, q?: QueryOne<E>, opts?: QueryOptions): Promise<E | undefined>;
|
|
25
28
|
findOne<E extends object>(entity: Type<E>, q: QueryOne<E>, opts?: QueryOptions): Promise<E | undefined>;
|
|
26
29
|
findMany<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): Promise<E[]>;
|
|
30
|
+
/**
|
|
31
|
+
* The connection outlives the call here: it is held until the iterator is drained or closed by a
|
|
32
|
+
* `break`/`throw`. Abandoning the iterator instead leaks it until GC, so consume it in a `for await`.
|
|
33
|
+
*/
|
|
34
|
+
findManyStream<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): AsyncGenerator<E>;
|
|
27
35
|
findManyAndCount<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): Promise<[E[], number]>;
|
|
28
36
|
count<E extends object>(entity: Type<E>, q?: QuerySearch<E>, opts?: QueryOptions): Promise<number>;
|
|
29
37
|
aggregate<E extends object, const G extends QueryGroupMap<E>, const A extends QueryAggMap<E>>(entity: Type<E>, q: QueryAggregate<E, G, A>, opts?: QueryOptions): Promise<QueryAggregateResult<E, G, A>[]>;
|
|
38
|
+
insertOne<E extends object>(entity: Type<E>, payload: E): Promise<IdValue<E> | undefined>;
|
|
39
|
+
insertMany<E extends object>(entity: Type<E>, payload: E[]): Promise<IdValue<E>[]>;
|
|
40
|
+
updateOneById<E extends object>(entity: Type<E>, id: IdValue<E>, payload: UpdatePayload<E>, opts?: QueryOptions): Promise<number>;
|
|
41
|
+
updateMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): Promise<number>;
|
|
42
|
+
upsertOne<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): Promise<QueryUpdateResult>;
|
|
43
|
+
upsertMany<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E[]): Promise<QueryUpdateResult>;
|
|
44
|
+
saveOne<E extends object>(entity: Type<E>, payload: E): Promise<IdValue<E>>;
|
|
45
|
+
saveMany<E extends object>(entity: Type<E>, payload: E[]): Promise<IdValue<E>[]>;
|
|
46
|
+
deleteOneById<E extends object>(entity: Type<E>, id: IdValue<E>, opts?: QueryOptions): Promise<number>;
|
|
47
|
+
deleteMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<number>;
|
|
48
|
+
restoreOneById<E extends object>(entity: Type<E>, id: IdValue<E>): Promise<number>;
|
|
49
|
+
restoreMany<E extends object>(entity: Type<E>, q: QuerySearch<E>): Promise<number>;
|
|
30
50
|
/**
|
|
31
51
|
* end the pool.
|
|
32
52
|
*/
|
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
import { withContext } from '../context/context.js';
|
|
2
54
|
/**
|
|
3
55
|
* Base pool: dialect id and behavior come only from the `dialect` instance (see {@link QuerierPool}).
|
|
@@ -11,10 +63,12 @@ export class AbstractQuerierPool {
|
|
|
11
63
|
}
|
|
12
64
|
/**
|
|
13
65
|
* get a querier from the pool and run the given callback inside a transaction.
|
|
66
|
+
*
|
|
67
|
+
* The pool acquired the connection, so the pool releases it: `withQuerier` owns that half and
|
|
68
|
+
* `querier.transaction` owns begin/commit/rollback. Neither knows about the other's job.
|
|
14
69
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return this.runScoped(opts?.context, () => querier.transaction(() => callback(querier), opts));
|
|
70
|
+
transaction(callback, opts) {
|
|
71
|
+
return this.withQuerier((querier) => querier.transaction(() => callback(querier), opts), opts);
|
|
18
72
|
}
|
|
19
73
|
/**
|
|
20
74
|
* get a querier from the pool, run the given callback, and release the querier.
|
|
@@ -41,6 +95,26 @@ export class AbstractQuerierPool {
|
|
|
41
95
|
findMany(entity, q, opts) {
|
|
42
96
|
return this.withQuerier((querier) => querier.findMany(entity, q, opts));
|
|
43
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* The connection outlives the call here: it is held until the iterator is drained or closed by a
|
|
100
|
+
* `break`/`throw`. Abandoning the iterator instead leaks it until GC, so consume it in a `for await`.
|
|
101
|
+
*/
|
|
102
|
+
async *findManyStream(entity, q, opts) {
|
|
103
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
104
|
+
try {
|
|
105
|
+
const querier = __addDisposableResource(env_1, await this.getQuerier(), true);
|
|
106
|
+
yield* querier.findManyStream(entity, q, opts);
|
|
107
|
+
}
|
|
108
|
+
catch (e_1) {
|
|
109
|
+
env_1.error = e_1;
|
|
110
|
+
env_1.hasError = true;
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
const result_1 = __disposeResources(env_1);
|
|
114
|
+
if (result_1)
|
|
115
|
+
await result_1;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
44
118
|
findManyAndCount(entity, q, opts) {
|
|
45
119
|
return this.withQuerier((querier) => querier.findManyAndCount(entity, q, opts));
|
|
46
120
|
}
|
|
@@ -50,4 +124,40 @@ export class AbstractQuerierPool {
|
|
|
50
124
|
aggregate(entity, q, opts) {
|
|
51
125
|
return this.withQuerier((querier) => querier.aggregate(entity, q, opts));
|
|
52
126
|
}
|
|
127
|
+
insertOne(entity, payload) {
|
|
128
|
+
return this.withQuerier((querier) => querier.insertOne(entity, payload));
|
|
129
|
+
}
|
|
130
|
+
insertMany(entity, payload) {
|
|
131
|
+
return this.withQuerier((querier) => querier.insertMany(entity, payload));
|
|
132
|
+
}
|
|
133
|
+
updateOneById(entity, id, payload, opts) {
|
|
134
|
+
return this.withQuerier((querier) => querier.updateOneById(entity, id, payload, opts));
|
|
135
|
+
}
|
|
136
|
+
updateMany(entity, q, payload, opts) {
|
|
137
|
+
return this.withQuerier((querier) => querier.updateMany(entity, q, payload, opts));
|
|
138
|
+
}
|
|
139
|
+
upsertOne(entity, conflictPaths, payload) {
|
|
140
|
+
return this.withQuerier((querier) => querier.upsertOne(entity, conflictPaths, payload));
|
|
141
|
+
}
|
|
142
|
+
upsertMany(entity, conflictPaths, payload) {
|
|
143
|
+
return this.withQuerier((querier) => querier.upsertMany(entity, conflictPaths, payload));
|
|
144
|
+
}
|
|
145
|
+
saveOne(entity, payload) {
|
|
146
|
+
return this.withQuerier((querier) => querier.saveOne(entity, payload));
|
|
147
|
+
}
|
|
148
|
+
saveMany(entity, payload) {
|
|
149
|
+
return this.withQuerier((querier) => querier.saveMany(entity, payload));
|
|
150
|
+
}
|
|
151
|
+
deleteOneById(entity, id, opts) {
|
|
152
|
+
return this.withQuerier((querier) => querier.deleteOneById(entity, id, opts));
|
|
153
|
+
}
|
|
154
|
+
deleteMany(entity, q, opts) {
|
|
155
|
+
return this.withQuerier((querier) => querier.deleteMany(entity, q, opts));
|
|
156
|
+
}
|
|
157
|
+
restoreOneById(entity, id) {
|
|
158
|
+
return this.withQuerier((querier) => querier.restoreOneById(entity, id));
|
|
159
|
+
}
|
|
160
|
+
restoreMany(entity, q) {
|
|
161
|
+
return this.withQuerier((querier) => querier.restoreMany(entity, q));
|
|
162
|
+
}
|
|
53
163
|
}
|
|
@@ -28,13 +28,11 @@ export declare abstract class AbstractSqlQuerier extends AbstractQuerier impleme
|
|
|
28
28
|
protected loadInsertIdIncrement(): Promise<number>;
|
|
29
29
|
/**
|
|
30
30
|
* Hook for subclasses (e.g. pool queriers) to establish a connection.
|
|
31
|
-
* Called before every query but outside the
|
|
31
|
+
* Called before every query but outside the timing window.
|
|
32
32
|
*/
|
|
33
33
|
protected lazyConnect(): Promise<void>;
|
|
34
34
|
all<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
35
|
-
private timedAll;
|
|
36
35
|
run(query: string, values?: unknown[]): Promise<QueryUpdateResult>;
|
|
37
|
-
private timedRun;
|
|
38
36
|
protected internalFindMany<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): Promise<E[]>;
|
|
39
37
|
protected internalFindManyStream<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): AsyncGenerator<Awaited<E>, void, unknown>;
|
|
40
38
|
/**
|