uql-orm 0.66.0 → 0.67.1
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/browser/querier/httpQuerier.js +1 -8
- package/dist/browser/uql-browser.min.js.map +5 -5
- package/dist/bunSql/bunSql.util.d.ts +2 -6
- package/dist/bunSql/bunSql.util.js +2 -6
- package/dist/bunSql/bunSqlQuerier.d.ts +2 -5
- package/dist/bunSql/bunSqlQuerier.js +2 -5
- package/dist/cockroachdb/cockroachDialect.d.ts +4 -13
- package/dist/cockroachdb/cockroachDialect.js +4 -13
- package/dist/context/context.browser.js +2 -10
- package/dist/context/context.d.ts +4 -17
- package/dist/context/context.js +4 -17
- package/dist/dialect/abstractDialect.d.ts +4 -19
- package/dist/dialect/abstractDialect.js +2 -20
- package/dist/dialect/abstractSqlDialect.d.ts +47 -212
- package/dist/dialect/abstractSqlDialect.js +68 -222
- package/dist/dialect/aliases.d.ts +2 -12
- package/dist/dialect/aliases.js +4 -12
- package/dist/dialect/hydrateColumn.d.ts +2 -6
- package/dist/dialect/hydrateColumn.js +3 -13
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts +1 -7
- package/dist/dialect/jsonArrayElemMatchUtils.js +1 -7
- package/dist/dialect/jsonSql.d.ts +6 -27
- package/dist/dialect/jsonSql.js +6 -27
- package/dist/dialect/mergeSqlDialect.d.ts +4 -22
- package/dist/dialect/mergeSqlDialect.js +4 -22
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +11 -37
- package/dist/dialect/mysqlLikeSqlDialect.js +35 -51
- package/dist/dialect/pgLikeSqlDialect.d.ts +8 -22
- package/dist/dialect/pgLikeSqlDialect.js +36 -39
- package/dist/dialect/queryContext.d.ts +4 -22
- package/dist/dialect/queryContext.js +4 -22
- package/dist/dialect/queryJoins.d.ts +3 -12
- package/dist/dialect/queryJoins.js +3 -12
- package/dist/dialect/vectorCast.d.ts +2 -12
- package/dist/dialect/vectorCast.js +3 -19
- package/dist/dialect/vectorSqlDialect.d.ts +8 -38
- package/dist/dialect/vectorSqlDialect.js +7 -38
- package/dist/entity/decorator/bag.d.ts +6 -19
- package/dist/entity/decorator/bag.js +6 -22
- package/dist/entity/decorator/entity.d.ts +2 -7
- package/dist/entity/decorator/entity.js +2 -7
- package/dist/entity/decorator/members.d.ts +7 -30
- package/dist/entity/decorator/members.js +3 -12
- package/dist/entity/metadata/definition.d.ts +2 -18
- package/dist/entity/metadata/definition.js +6 -28
- package/dist/http/handler.d.ts +2 -14
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/libsql/libsqlDialect.d.ts +1 -8
- package/dist/libsql/libsqlDialect.js +1 -8
- package/dist/maria/mariaDialect.d.ts +3 -5
- package/dist/maria/mariaDialect.js +5 -5
- package/dist/maria/mariadbQuerier.js +2 -2
- package/dist/maria/mariadbQuerierPool.js +1 -6
- package/dist/migrate/builder/migrationBuilder.js +3 -19
- package/dist/migrate/builder/splitSqlStatements.d.ts +1 -14
- package/dist/migrate/builder/splitSqlStatements.js +2 -22
- package/dist/migrate/builder/types.d.ts +2 -15
- package/dist/migrate/cli-config.js +2 -11
- package/dist/migrate/cli.js +2 -7
- package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -15
- package/dist/migrate/codegen/entityCodeGenerator.js +15 -44
- package/dist/migrate/codegen/fieldOptionsSource.d.ts +1 -8
- package/dist/migrate/codegen/fieldOptionsSource.js +3 -22
- package/dist/migrate/ddl/indexDdl.d.ts +2 -5
- package/dist/migrate/ddl/indexDdl.js +2 -5
- package/dist/migrate/ddl/pgIndexDdl.d.ts +3 -13
- package/dist/migrate/ddl/pgIndexDdl.js +3 -13
- package/dist/migrate/generator/definitionToNode.d.ts +2 -9
- package/dist/migrate/generator/definitionToNode.js +3 -17
- package/dist/migrate/generator/indexNodeToSchema.d.ts +2 -3
- package/dist/migrate/generator/indexNodeToSchema.js +2 -3
- package/dist/migrate/generator/mongoCommand.d.ts +1 -8
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +1 -8
- package/dist/migrate/generator/mongoSchemaGenerator.js +1 -8
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +6 -26
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +9 -41
- package/dist/migrate/introspection/baseSqlIntrospector.js +0 -1
- package/dist/migrate/introspection/mongoIntrospector.d.ts +3 -1
- package/dist/migrate/introspection/mongoIntrospector.js +48 -46
- package/dist/migrate/introspection/mssqlIntrospector.d.ts +4 -4
- package/dist/migrate/introspection/mssqlIntrospector.js +18 -27
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +7 -2
- package/dist/migrate/introspection/mysqlIntrospector.js +16 -14
- package/dist/migrate/introspection/postgresIntrospector.d.ts +24 -9
- package/dist/migrate/introspection/postgresIntrospector.js +68 -59
- package/dist/migrate/introspection/sqliteIntrospector.d.ts +1 -1
- package/dist/migrate/introspection/sqliteIntrospector.js +8 -10
- package/dist/migrate/migrator.d.ts +9 -53
- package/dist/migrate/migrator.js +32 -65
- package/dist/migrate/schemaGenerator.d.ts +16 -66
- package/dist/migrate/schemaGenerator.js +21 -74
- package/dist/mongo/mongoDialect.d.ts +21 -53
- package/dist/mongo/mongoDialect.js +25 -70
- package/dist/mongo/mongodbQuerier.d.ts +5 -8
- package/dist/mongo/mongodbQuerier.js +31 -65
- package/dist/mssql/mssqlDialect.d.ts +8 -34
- package/dist/mssql/mssqlDialect.js +37 -51
- package/dist/mssql/mssqlQuerier.d.ts +37 -4
- package/dist/mssql/mssqlQuerier.js +2 -2
- package/dist/mssql/mssqlWireTypes.d.ts +2 -14
- package/dist/mssql/mssqlWireTypes.js +2 -14
- package/dist/nestjs/uqlModule.js +2 -7
- package/dist/pglite/pgliteQuerier.d.ts +1 -9
- package/dist/pglite/pgliteQuerierPool.d.ts +4 -26
- package/dist/pglite/pgliteQuerierPool.js +3 -18
- package/dist/postgres/abstractPgQuerierPool.d.ts +1 -8
- package/dist/postgres/abstractPgQuerierPool.js +1 -8
- package/dist/postgres/pgNumericTypes.d.ts +3 -26
- package/dist/postgres/pgNumericTypes.js +3 -26
- package/dist/postgres/postgresDialect.d.ts +4 -10
- package/dist/postgres/postgresDialect.js +4 -10
- package/dist/querier/abstractQuerier.d.ts +35 -103
- package/dist/querier/abstractQuerier.js +105 -201
- package/dist/querier/abstractSharedHandleQuerierPool.d.ts +3 -17
- package/dist/querier/abstractSharedHandleQuerierPool.js +3 -17
- package/dist/querier/abstractSqlQuerier.d.ts +15 -36
- package/dist/querier/abstractSqlQuerier.js +49 -131
- package/dist/schema/canonicalType.d.ts +3 -21
- package/dist/schema/canonicalType.js +22 -67
- package/dist/schema/dependencyGraph.d.ts +2 -8
- package/dist/schema/dependencyGraph.js +2 -32
- package/dist/schema/index.d.ts +1 -25
- package/dist/schema/index.js +0 -26
- package/dist/schema/indexColumns.d.ts +1 -8
- package/dist/schema/indexColumns.js +1 -8
- package/dist/schema/indexDifferences.d.ts +7 -40
- package/dist/schema/indexDifferences.js +6 -31
- package/dist/schema/schemaAST.d.ts +8 -175
- package/dist/schema/schemaAST.js +13 -365
- package/dist/schema/schemaASTBuilder.d.ts +2 -24
- package/dist/schema/schemaASTBuilder.js +2 -30
- package/dist/schema/schemaASTDiffer.d.ts +6 -46
- package/dist/schema/schemaASTDiffer.js +8 -56
- package/dist/schema/types.d.ts +5 -61
- package/dist/schema/types.js +3 -6
- package/dist/sqlite/abstractSqliteQuerier.d.ts +1 -8
- package/dist/sqlite/localSqliteQuerierPool.d.ts +1 -7
- package/dist/sqlite/localSqliteQuerierPool.js +1 -7
- package/dist/sqlite/nodeSqliteQuerierPool.d.ts +2 -7
- package/dist/sqlite/nodeSqliteQuerierPool.js +2 -7
- package/dist/sqlite/sqliteDialect.d.ts +5 -20
- package/dist/sqlite/sqliteDialect.js +29 -35
- package/dist/turso/tursoDialect.d.ts +4 -6
- package/dist/turso/tursoDialect.js +4 -6
- package/dist/turso/tursoLocalQuerierPool.d.ts +1 -7
- package/dist/turso/tursoLocalQuerierPool.js +1 -7
- package/dist/turso/tursoQuerierPool.d.ts +2 -6
- package/dist/turso/tursoQuerierPool.js +2 -6
- package/dist/turso/tursoSessionQuerier.d.ts +1 -7
- package/dist/turso/tursoSessionQuerier.js +1 -7
- package/dist/type/dialect.d.ts +42 -94
- package/dist/type/dialect.js +3 -13
- package/dist/type/entity.d.ts +163 -534
- package/dist/type/entity.js +26 -9
- package/dist/type/logger.d.ts +2 -14
- package/dist/type/migration.d.ts +9 -38
- package/dist/type/querier.d.ts +9 -28
- package/dist/type/querierPool.d.ts +4 -26
- package/dist/type/query.d.ts +19 -73
- package/dist/type/query.js +2 -7
- package/dist/type/queryAggregate.d.ts +18 -98
- package/dist/type/queryRaw.d.ts +1 -8
- package/dist/type/queryRaw.js +1 -8
- package/dist/type/queryWhere.d.ts +13 -61
- package/dist/type/universalQuerier.d.ts +18 -105
- package/dist/type/utility.d.ts +12 -24
- package/dist/type/vector.d.ts +8 -38
- package/dist/type/vector.js +1 -1
- package/dist/type/wire.d.ts +2 -5
- package/dist/util/dialect.util.d.ts +9 -27
- package/dist/util/dialect.util.js +10 -27
- package/dist/util/field.util.d.ts +2 -31
- package/dist/util/field.util.js +3 -43
- package/dist/util/fieldOption.util.d.ts +7 -15
- package/dist/util/fieldOption.util.js +1 -1
- package/dist/util/filters.util.d.ts +2 -5
- package/dist/util/filters.util.js +2 -5
- package/dist/util/logger.d.ts +2 -6
- package/dist/util/logger.js +2 -6
- package/dist/util/object.util.d.ts +2 -6
- package/dist/util/object.util.js +1 -5
- package/dist/util/raw.d.ts +3 -23
- package/dist/util/relationQuery.util.d.ts +3 -14
- package/dist/util/relationQuery.util.js +3 -14
- package/dist/util/rowKey.util.d.ts +2 -10
- package/dist/util/rowKey.util.js +2 -10
- package/dist/util/sql.util.d.ts +6 -37
- package/dist/util/sql.util.js +13 -73
- package/dist/util/sqlLiteral.d.ts +2 -13
- package/dist/util/sqlLiteral.js +8 -13
- package/dist/util/string.util.js +0 -2
- package/package.json +4 -4
|
@@ -3,20 +3,8 @@ type ColumnTypes = Record<string, {
|
|
|
3
3
|
readonly type: unknown;
|
|
4
4
|
}>;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* uql owes this to the caller because uql picks the column: `type: Number` maps to BIGINT (see
|
|
9
|
-
* `schema/canonicalType.ts`), and `tedious` hands that back as a string to protect the digits past
|
|
10
|
-
* 2^53 - so without this a field declared `number` reads back as `'9'`, including every generated
|
|
11
|
-
* primary key on every entity.
|
|
12
|
-
*
|
|
13
|
-
* At the wire, for the reason `pgNumericTypes` gives: everything crosses it exactly once - entity
|
|
14
|
-
* reads, the ids an `OUTPUT` reports, raw SQL, counts, aggregates - where the ORM's own hydration
|
|
15
|
-
* only ever sees entity reads.
|
|
16
|
-
*
|
|
17
|
-
* By the rule every driver here shares, `decodeWideNumber`: a number where one is exact, the driver's
|
|
18
|
-
* exact text past 2^53. The lighter escape hatch for a column that big is the declaration -
|
|
19
|
-
* `@Field({ type: String, columnType: 'bigint' })`.
|
|
6
|
+
* Decodes `BIGINT`, which `tedious` returns as text, by `decodeWideNumber`: `type: Number` maps to
|
|
7
|
+
* BIGINT, so otherwise every generated key reads back as a string. At the wire, which every result crosses.
|
|
20
8
|
*/
|
|
21
9
|
export declare function decodeWireTypes<T>(rows: T[] | undefined, columns: ColumnTypes | undefined): T[];
|
|
22
10
|
export {};
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* uql owes this to the caller because uql picks the column: `type: Number` maps to BIGINT (see
|
|
6
|
-
* `schema/canonicalType.ts`), and `tedious` hands that back as a string to protect the digits past
|
|
7
|
-
* 2^53 - so without this a field declared `number` reads back as `'9'`, including every generated
|
|
8
|
-
* primary key on every entity.
|
|
9
|
-
*
|
|
10
|
-
* At the wire, for the reason `pgNumericTypes` gives: everything crosses it exactly once - entity
|
|
11
|
-
* reads, the ids an `OUTPUT` reports, raw SQL, counts, aggregates - where the ORM's own hydration
|
|
12
|
-
* only ever sees entity reads.
|
|
13
|
-
*
|
|
14
|
-
* By the rule every driver here shares, `decodeWideNumber`: a number where one is exact, the driver's
|
|
15
|
-
* exact text past 2^53. The lighter escape hatch for a column that big is the declaration -
|
|
16
|
-
* `@Field({ type: String, columnType: 'bigint' })`.
|
|
3
|
+
* Decodes `BIGINT`, which `tedious` returns as text, by `decodeWideNumber`: `type: Number` maps to
|
|
4
|
+
* BIGINT, so otherwise every generated key reads back as a string. At the wire, which every result crosses.
|
|
17
5
|
*/
|
|
18
6
|
export function decodeWireTypes(rows, columns) {
|
|
19
7
|
if (!rows?.length || !columns) {
|
package/dist/nestjs/uqlModule.js
CHANGED
|
@@ -43,13 +43,8 @@ import { UqlContextInterceptor } from './uqlContextInterceptor.js';
|
|
|
43
43
|
*/
|
|
44
44
|
export const UQL_QUERIER_POOL = Symbol('UQL_QUERIER_POOL');
|
|
45
45
|
/**
|
|
46
|
-
* Ends the pool when Nest shuts down
|
|
47
|
-
*
|
|
48
|
-
* @remarks A provider rather than a hook on the module class, and built through `useFactory` with an
|
|
49
|
-
* `inject` list rather than constructor injection: Nest injects constructor parameters with a parameter
|
|
50
|
-
* decorator, and the TC39 decorator spec has none, so `@Inject()` cannot appear in a file compiled
|
|
51
|
-
* against it. Nest runs lifecycle hooks on providers too, so this keeps the pool that *this* module was
|
|
52
|
-
* configured with instead of reaching for the global default.
|
|
46
|
+
* Ends the pool this module was configured with when Nest shuts down: a provider built by `useFactory`,
|
|
47
|
+
* since TC39 decorators have no parameter decorator for `@Inject()`.
|
|
53
48
|
*/
|
|
54
49
|
class UqlPoolLifecycle {
|
|
55
50
|
pool;
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import type { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
2
2
|
import { AbstractSqlQuerier } from '../querier/index.js';
|
|
3
3
|
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Structural subset of the `@electric-sql/pglite` API actually used here, declared locally so this
|
|
6
|
-
* package does not couple its published types to a pre-1.0 dependency.
|
|
7
|
-
*
|
|
8
|
-
* @remarks This is what uql *consumes* from the driver, so it is two methods and stating them costs
|
|
9
|
-
* nothing. `PglitePoolOptions` is the opposite case and imports PGlite's own type: those options are
|
|
10
|
-
* the caller's input to the driver, so restating them would mean re-deriving its whole option surface
|
|
11
|
-
* and then casting at the `PGlite.create` call.
|
|
12
|
-
*/
|
|
4
|
+
/** The two methods uql uses of `@electric-sql/pglite`, stated so its published types do not depend on a pre-1.0 package. */
|
|
13
5
|
export type PgliteDatabase = {
|
|
14
6
|
query<T>(query: string, params?: unknown[]): Promise<{
|
|
15
7
|
rows: T[];
|
|
@@ -3,34 +3,12 @@ import { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
|
3
3
|
import { AbstractSharedHandleQuerierPool } from '../querier/abstractSharedHandleQuerierPool.js';
|
|
4
4
|
import type { ExtraOptions } from '../type/index.js';
|
|
5
5
|
import { type PgliteDatabase, PgliteQuerier } from './pgliteQuerier.js';
|
|
6
|
-
/**
|
|
7
|
-
* The driver's own options, minus the `dataDir` this pool takes as its first argument.
|
|
8
|
-
*
|
|
9
|
-
* @remarks Imported rather than restated so extensions and the filesystem hooks keep their real types:
|
|
10
|
-
* `extensions: { vector }` from `@electric-sql/pglite-pgvector` is how a vector column becomes usable,
|
|
11
|
-
* mirroring `LocalSqlitePoolOptions.extensions` for `sqlite-vec`. Type-only, like the `pg` imports in
|
|
12
|
-
* `abstractPgQuerierPool.ts`, so nothing here reaches a runtime without the peer installed.
|
|
13
|
-
*/
|
|
6
|
+
/** PGlite's own options but `dataDir`, the pool's first argument; `extensions: { vector }` enables pgvector. Type-only. */
|
|
14
7
|
export type PglitePoolOptions = Omit<PGliteOptions, 'dataDir'>;
|
|
15
8
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* Where PGlite differs from the two SQLite-family pools there is that it does not refuse a second
|
|
20
|
-
* `BEGIN`: a querier that opens a transaction while another already has one silently joins it, and that
|
|
21
|
-
* one's `ROLLBACK` then discards both queriers' writes. Nothing reports it, so a unit of work that needs
|
|
22
|
-
* a transaction of its own needs its own pool, and therefore its own database.
|
|
23
|
-
*
|
|
24
|
-
* @remarks Transactions are plain `BEGIN`/`COMMIT` statements rather than `db.transaction()`, whose
|
|
25
|
-
* callback holds PGlite's transaction mutex and would block every other querier's reads until commit.
|
|
26
|
-
* The cost is that PGlite cannot see the transaction, so it flushes to the filesystem after each
|
|
27
|
-
* statement within one: pass `relaxedDurability: true` on a persistent `dataDir` to skip waiting on
|
|
28
|
-
* those flushes.
|
|
29
|
-
*
|
|
30
|
-
* The dialect is plain `PostgresDialect`, `dialectName` included: PGlite *is* Postgres, so the
|
|
31
|
-
* introspector, schema generator and CLI resolve to Postgres's. Both driver capabilities hold as
|
|
32
|
-
* they are - PGlite serializes every built-in array type itself, and the `$n::jsonb` cast is what
|
|
33
|
-
* makes its `Describe` report JSONB and pick its JSON serializer; a bare `$n` binds `[object Object]`.
|
|
9
|
+
* A pool for PGlite, Postgres in WASM in this process, on one connection. A second `BEGIN` silently joins
|
|
10
|
+
* the open transaction, so a unit of work needing its own needs its own pool. Transactions are plain
|
|
11
|
+
* statements, so pass `relaxedDurability` on a persistent `dataDir` to skip a flush per statement.
|
|
34
12
|
*/
|
|
35
13
|
export declare class PgliteQuerierPool extends AbstractSharedHandleQuerierPool<PgliteDatabase, PgliteQuerier, PostgresDialect> {
|
|
36
14
|
readonly dataDir: string;
|
|
@@ -4,24 +4,9 @@ import { AbstractSharedHandleQuerierPool } from '../querier/abstractSharedHandle
|
|
|
4
4
|
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
5
5
|
import { PgliteQuerier } from './pgliteQuerier.js';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Where PGlite differs from the two SQLite-family pools there is that it does not refuse a second
|
|
11
|
-
* `BEGIN`: a querier that opens a transaction while another already has one silently joins it, and that
|
|
12
|
-
* one's `ROLLBACK` then discards both queriers' writes. Nothing reports it, so a unit of work that needs
|
|
13
|
-
* a transaction of its own needs its own pool, and therefore its own database.
|
|
14
|
-
*
|
|
15
|
-
* @remarks Transactions are plain `BEGIN`/`COMMIT` statements rather than `db.transaction()`, whose
|
|
16
|
-
* callback holds PGlite's transaction mutex and would block every other querier's reads until commit.
|
|
17
|
-
* The cost is that PGlite cannot see the transaction, so it flushes to the filesystem after each
|
|
18
|
-
* statement within one: pass `relaxedDurability: true` on a persistent `dataDir` to skip waiting on
|
|
19
|
-
* those flushes.
|
|
20
|
-
*
|
|
21
|
-
* The dialect is plain `PostgresDialect`, `dialectName` included: PGlite *is* Postgres, so the
|
|
22
|
-
* introspector, schema generator and CLI resolve to Postgres's. Both driver capabilities hold as
|
|
23
|
-
* they are - PGlite serializes every built-in array type itself, and the `$n::jsonb` cast is what
|
|
24
|
-
* makes its `Describe` report JSONB and pick its JSON serializer; a bare `$n` binds `[object Object]`.
|
|
7
|
+
* A pool for PGlite, Postgres in WASM in this process, on one connection. A second `BEGIN` silently joins
|
|
8
|
+
* the open transaction, so a unit of work needing its own needs its own pool. Transactions are plain
|
|
9
|
+
* statements, so pass `relaxedDurability` on a persistent `dataDir` to skip a flush per statement.
|
|
25
10
|
*/
|
|
26
11
|
export class PgliteQuerierPool extends AbstractSharedHandleQuerierPool {
|
|
27
12
|
dataDir;
|
|
@@ -7,14 +7,7 @@ export interface PgAnyPool<C extends PgAnyClient> extends ErrorEmittingPool {
|
|
|
7
7
|
connect: () => Promise<C>;
|
|
8
8
|
end: () => Promise<void>;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
* Shared base class for Postgres-compatible querier pools. Each hands out a {@link PgQuerier} over its
|
|
12
|
-
* driver's client, so a subclass supplies only the dialect and the driver's pool.
|
|
13
|
-
*
|
|
14
|
-
* Wires the crash-preventing error handler here, once, so a new pg-compatible pool subclass can't be
|
|
15
|
-
* added without it - the constructor takes the already constructed pool and attaches the handler
|
|
16
|
-
* unconditionally.
|
|
17
|
-
*/
|
|
10
|
+
/** A Postgres-wire pool of {@link PgQuerier}s, attaching the error handler that keeps a dropped connection from crashing the process. */
|
|
18
11
|
export declare abstract class AbstractPgQuerierPool<C extends PgAnyClient, D extends AbstractSqlDialect> extends AbstractSqlQuerierPool<PgQuerier<C>, D> {
|
|
19
12
|
readonly pool: PgAnyPool<C>;
|
|
20
13
|
constructor(dialect: D, pool: PgAnyPool<C>, extra?: ExtraOptions);
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
2
2
|
import { attachPoolErrorHandler } from '../util/index.js';
|
|
3
3
|
import { PgQuerier } from './pgQuerier.js';
|
|
4
|
-
/**
|
|
5
|
-
* Shared base class for Postgres-compatible querier pools. Each hands out a {@link PgQuerier} over its
|
|
6
|
-
* driver's client, so a subclass supplies only the dialect and the driver's pool.
|
|
7
|
-
*
|
|
8
|
-
* Wires the crash-preventing error handler here, once, so a new pg-compatible pool subclass can't be
|
|
9
|
-
* added without it - the constructor takes the already constructed pool and attaches the handler
|
|
10
|
-
* unconditionally.
|
|
11
|
-
*/
|
|
4
|
+
/** A Postgres-wire pool of {@link PgQuerier}s, attaching the error handler that keeps a dropped connection from crashing the process. */
|
|
12
5
|
export class AbstractPgQuerierPool extends AbstractSqlQuerierPool {
|
|
13
6
|
pool;
|
|
14
7
|
constructor(dialect, pool, extra) {
|
|
@@ -10,32 +10,9 @@ type PgTypes = {
|
|
|
10
10
|
getTypeParser(oid: number, format?: 'text' | 'binary'): (value: string) => unknown;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* uql owes this to the caller because uql picks the column: `type: Number` maps to BIGINT (see
|
|
17
|
-
* `schema/canonicalType.ts`), so without it a field declared `number` read back as `'9'` - including
|
|
18
|
-
* every auto-increment primary key, on every entity. `FLOAT8` is a float64, which is exactly what a
|
|
19
|
-
* JS number is, so decoding it loses nothing at all.
|
|
20
|
-
*
|
|
21
|
-
* At the driver because everything crosses the wire decoder exactly once - entity reads, `RETURNING
|
|
22
|
-
* id`, raw SQL, counts, aggregates - while the ORM's hydration only ever sees entity reads. Which
|
|
23
|
-
* types belong here and which need the entity's declaration is settled in `hydratableFields`.
|
|
24
|
-
*
|
|
25
|
-
* `NUMERIC` is deliberately absent, and decoded in hydration instead: `type: BigInt` also maps to
|
|
26
|
-
* BIGINT, so a blanket decode here is already as far as a driver can go without the declaration. That
|
|
27
|
-
* split also covers mysql2, which returns DECIMAL as text and has no equivalent hook.
|
|
28
|
-
*
|
|
29
|
-
* Per pool, never global, which is the whole reason this takes `types` as an argument. TypeORM does
|
|
30
|
-
* the same job by assigning `postgres.defaults.parseInt8`, a module-wide flag every pool in the
|
|
31
|
-
* process then shares; MikroORM passes a per-pool `TypeOverrides`, as here. Two globals of exactly
|
|
32
|
-
* that shape have already been deleted from this repo - `test/pgTypeParsers.util.ts` and the
|
|
33
|
-
* `types.setTypeParser` calls in `neon/neonQuerier.test.ts` - and both made the suite pass on
|
|
34
|
-
* behaviour the library never shipped. Do not reintroduce one.
|
|
35
|
-
*
|
|
36
|
-
* A caller's own `types` in the pool options are spread after this one and therefore win. For a
|
|
37
|
-
* decimal, the lighter escape hatch is the declaration itself: `@Field({ type: String, columnType:
|
|
38
|
-
* 'decimal' })` keeps the column DECIMAL while leaving the value as the exact text the driver returned.
|
|
13
|
+
* Decodes `INT8` by `decodeWideNumber` and `FLOAT8` as the float64 it is, since `type: Number` maps to
|
|
14
|
+
* BIGINT. At the wire, which every result crosses; `NUMERIC` is left to hydration, which knows the field.
|
|
15
|
+
* Per pool, never a global parser, and a caller's own `types` win.
|
|
39
16
|
*/
|
|
40
17
|
export declare function numericTypes(types: PgTypes): CustomTypesConfig;
|
|
41
18
|
export {};
|
|
@@ -1,31 +1,8 @@
|
|
|
1
1
|
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* uql owes this to the caller because uql picks the column: `type: Number` maps to BIGINT (see
|
|
7
|
-
* `schema/canonicalType.ts`), so without it a field declared `number` read back as `'9'` - including
|
|
8
|
-
* every auto-increment primary key, on every entity. `FLOAT8` is a float64, which is exactly what a
|
|
9
|
-
* JS number is, so decoding it loses nothing at all.
|
|
10
|
-
*
|
|
11
|
-
* At the driver because everything crosses the wire decoder exactly once - entity reads, `RETURNING
|
|
12
|
-
* id`, raw SQL, counts, aggregates - while the ORM's hydration only ever sees entity reads. Which
|
|
13
|
-
* types belong here and which need the entity's declaration is settled in `hydratableFields`.
|
|
14
|
-
*
|
|
15
|
-
* `NUMERIC` is deliberately absent, and decoded in hydration instead: `type: BigInt` also maps to
|
|
16
|
-
* BIGINT, so a blanket decode here is already as far as a driver can go without the declaration. That
|
|
17
|
-
* split also covers mysql2, which returns DECIMAL as text and has no equivalent hook.
|
|
18
|
-
*
|
|
19
|
-
* Per pool, never global, which is the whole reason this takes `types` as an argument. TypeORM does
|
|
20
|
-
* the same job by assigning `postgres.defaults.parseInt8`, a module-wide flag every pool in the
|
|
21
|
-
* process then shares; MikroORM passes a per-pool `TypeOverrides`, as here. Two globals of exactly
|
|
22
|
-
* that shape have already been deleted from this repo - `test/pgTypeParsers.util.ts` and the
|
|
23
|
-
* `types.setTypeParser` calls in `neon/neonQuerier.test.ts` - and both made the suite pass on
|
|
24
|
-
* behaviour the library never shipped. Do not reintroduce one.
|
|
25
|
-
*
|
|
26
|
-
* A caller's own `types` in the pool options are spread after this one and therefore win. For a
|
|
27
|
-
* decimal, the lighter escape hatch is the declaration itself: `@Field({ type: String, columnType:
|
|
28
|
-
* 'decimal' })` keeps the column DECIMAL while leaving the value as the exact text the driver returned.
|
|
3
|
+
* Decodes `INT8` by `decodeWideNumber` and `FLOAT8` as the float64 it is, since `type: Number` maps to
|
|
4
|
+
* BIGINT. At the wire, which every result crosses; `NUMERIC` is left to hydration, which knows the field.
|
|
5
|
+
* Per pool, never a global parser, and a caller's own `types` win.
|
|
29
6
|
*/
|
|
30
7
|
export function numericTypes(types) {
|
|
31
8
|
// Text only: in binary mode an INT8 arrives as an 8-byte Buffer, and `Number(buffer)` is `NaN`.
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { PgLikeSqlDialect } from '../dialect/pgLikeSqlDialect.js';
|
|
2
|
-
import type { QueryConflictPaths, QueryContext, SqlDialectName, Type } from '../type/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* PostgreSQL dialect, the same class under every Postgres driver - `pg`, Neon, PGlite, `bun:sql` -
|
|
5
|
-
* where a driver that binds differently passes `driverCapabilities` rather than subclassing it.
|
|
6
|
-
* Shared Postgres-wire AST/quoting/JSONB/full-text-search/vector-search logic (including BIGINT
|
|
7
|
-
* IDENTITY PKs) lives in {@link PgLikeSqlDialect}; this class adds what's Postgres-only: the `vector`
|
|
8
|
-
* extension requirement, pgvector's index syntax, and `xmax`-based upsert `created` detection.
|
|
9
|
-
*/
|
|
2
|
+
import type { QueryConflictPaths, QueryContext, SqlDialectFeatures, SqlDialectName, Type } from '../type/index.js';
|
|
3
|
+
/** PostgreSQL, under every driver: `pg`, Neon, PGlite, `bun:sql`. Adds pgvector and the `xmax` upsert `created`. */
|
|
10
4
|
export declare class PostgresDialect extends PgLikeSqlDialect {
|
|
11
5
|
readonly dialectName: SqlDialectName;
|
|
12
6
|
readonly vectorExtension: string | undefined;
|
|
13
|
-
/** pgvector is the only engine with `halfvec` and `sparsevec
|
|
14
|
-
|
|
7
|
+
/** pgvector is the only engine with `halfvec` and `sparsevec`. */
|
|
8
|
+
readonly features: SqlDialectFeatures;
|
|
15
9
|
upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[]): void;
|
|
16
10
|
/**
|
|
17
11
|
* `to_regclass` rather than a `::regclass` cast: it answers `NULL` for a table that does not exist
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { COUNT_ALIAS } from '../dialect/aliases.js';
|
|
2
|
-
import { PgLikeSqlDialect } from '../dialect/pgLikeSqlDialect.js';
|
|
2
|
+
import { PG_FEATURES, PgLikeSqlDialect } from '../dialect/pgLikeSqlDialect.js';
|
|
3
3
|
import { getMeta } from '../entity/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* PostgreSQL dialect, the same class under every Postgres driver - `pg`, Neon, PGlite, `bun:sql` -
|
|
6
|
-
* where a driver that binds differently passes `driverCapabilities` rather than subclassing it.
|
|
7
|
-
* Shared Postgres-wire AST/quoting/JSONB/full-text-search/vector-search logic (including BIGINT
|
|
8
|
-
* IDENTITY PKs) lives in {@link PgLikeSqlDialect}; this class adds what's Postgres-only: the `vector`
|
|
9
|
-
* extension requirement, pgvector's index syntax, and `xmax`-based upsert `created` detection.
|
|
10
|
-
*/
|
|
4
|
+
/** PostgreSQL, under every driver: `pg`, Neon, PGlite, `bun:sql`. Adds pgvector and the `xmax` upsert `created`. */
|
|
11
5
|
export class PostgresDialect extends PgLikeSqlDialect {
|
|
12
6
|
dialectName = 'postgres';
|
|
13
7
|
vectorExtension = 'vector';
|
|
14
|
-
/** pgvector is the only engine with `halfvec` and `sparsevec
|
|
15
|
-
|
|
8
|
+
/** pgvector is the only engine with `halfvec` and `sparsevec`. */
|
|
9
|
+
features = { ...PG_FEATURES, narrowVectorTypes: true };
|
|
16
10
|
upsert(ctx, entity, conflictPaths, payload) {
|
|
17
11
|
// The xmax system column is 0 for a newly inserted row and non-zero for an updated one (MVCC).
|
|
18
12
|
super.upsert(ctx, entity, conflictPaths, payload, `(xmax = 0) AS ${this.escapeId('_created')}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityData, EntityId, ExtraOptions, FieldKey,
|
|
1
|
+
import type { EntityData, EntityId, ExtraOptions, FieldKey, Querier, Query, QueryAggMap, QueryAggregate, QueryAggregateResult, QueryConflictPaths, QueryFilter, QueryFindResult, QueryGroupMap, QueryOneProjected, QueryOptions, QueryPage, QueryProjected, QuerySearch, PrimaryKey, QueryUpdateResult, QueryUpsertOneResult, QueryUpsertManyResult, RelationKey, TransactionOptions, Type, UpdatePayload, WrittenId } from '../type/index.js';
|
|
2
2
|
import { LoggerWrapper } from '../util/index.js';
|
|
3
3
|
/** Base class for all database queriers. */
|
|
4
4
|
export declare abstract class AbstractQuerier implements Querier {
|
|
@@ -18,28 +18,17 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
18
18
|
constructor(extra?: ExtraOptions | undefined);
|
|
19
19
|
protected validateProjectionQuery<E extends object>(entity: Type<E>, q: Query<E>): void;
|
|
20
20
|
private validateProjectionQueryRecursive;
|
|
21
|
-
/**
|
|
22
|
-
* Resolves `[entity, query, opts]` for the dual call pattern: `(entity, q, opts)` (entity argument)
|
|
23
|
-
* vs `(query, opts)` (entity via the query's `$entity` field). Generic in the query `Q` because it
|
|
24
|
-
* only ever reads `$entity`: pinning it to one statement's shape made every caller launder its own
|
|
25
|
-
* through a cast, which is how a read query's `$sort` used to reach a write's.
|
|
26
|
-
*/
|
|
21
|
+
/** `[entity, query, opts]` from either call form, `(entity, q, opts)` or `({ $entity, ...q }, opts)`. */
|
|
27
22
|
protected resolveEntityQuery<E extends object, Q extends object>(entityOrQuery: Type<E> | (Q & {
|
|
28
23
|
$entity: Type<E>;
|
|
29
24
|
}), maybeQueryOrOpts?: Q | QueryOptions, maybeOpts?: QueryOptions): [Type<E>, Q, QueryOptions | undefined];
|
|
30
25
|
findOneById<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(entity: Type<E>, id: EntityId<E>, q?: QueryOneProjected<E, S, V, X, P, C>, opts?: QueryOptions): Promise<QueryFindResult<E, S, V, X, P, C> | undefined>;
|
|
31
|
-
/**
|
|
32
|
-
* Find a single record matching the query.
|
|
33
|
-
* Supports both entity-as-argument and entity-as-field patterns.
|
|
34
|
-
*/
|
|
26
|
+
/** Find one record, the entity passed first or as the query's `$entity`. */
|
|
35
27
|
findOne<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(q: QueryOneProjected<E, S, V, X, P, C> & {
|
|
36
28
|
$entity: Type<E>;
|
|
37
29
|
}, opts?: QueryOptions): Promise<QueryFindResult<E, S, V, X, P, C> | undefined>;
|
|
38
30
|
findOne<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(entity: Type<E>, q: QueryOneProjected<E, S, V, X, P, C>, opts?: QueryOptions): Promise<QueryFindResult<E, S, V, X, P, C> | undefined>;
|
|
39
|
-
/**
|
|
40
|
-
* Find multiple records matching the query.
|
|
41
|
-
* Supports both entity-as-argument and entity-as-field patterns.
|
|
42
|
-
*/
|
|
31
|
+
/** Find many records, the entity passed first or as the query's `$entity`. */
|
|
43
32
|
findMany<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(q: QueryProjected<E, S, V, X, P, C> & {
|
|
44
33
|
$entity: Type<E>;
|
|
45
34
|
}, opts?: QueryOptions): Promise<QueryFindResult<E, S, V, X, P, C>[]>;
|
|
@@ -49,20 +38,13 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
49
38
|
* or pipeline. [The design](../../../../architecture/relations-in-one-statement.md).
|
|
50
39
|
*/
|
|
51
40
|
protected abstract internalFindMany<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): Promise<E[]>;
|
|
52
|
-
/**
|
|
53
|
-
* Stream records as an async iterable, in both the entity-as-argument and entity-as-field patterns.
|
|
54
|
-
* Each row streams with its populated relations and counts, read by the same statement or pipeline
|
|
55
|
-
* `findMany` runs. No `afterLoad` hooks on streamed rows.
|
|
56
|
-
*/
|
|
41
|
+
/** Stream records with the relations and counts `findMany` reads, the entity passed first or as `$entity`. No hooks fire. */
|
|
57
42
|
findManyStream<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(q: QueryProjected<E, S, V, X, P, C> & {
|
|
58
43
|
$entity: Type<E>;
|
|
59
44
|
}, opts?: QueryOptions): AsyncIterable<QueryFindResult<E, S, V, X, P, C>>;
|
|
60
45
|
findManyStream<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(entity: Type<E>, q: QueryProjected<E, S, V, X, P, C>, opts?: QueryOptions): AsyncIterable<QueryFindResult<E, S, V, X, P, C>>;
|
|
61
46
|
protected abstract internalFindManyStream<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): AsyncIterable<E>;
|
|
62
|
-
/**
|
|
63
|
-
* Find multiple records and return both the records and total count.
|
|
64
|
-
* Supports both entity-as-argument and entity-as-field patterns.
|
|
65
|
-
*/
|
|
47
|
+
/** Find many records and count every match, the entity passed first or as the query's `$entity`. */
|
|
66
48
|
findManyAndCount<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(q: QueryProjected<E, S, V, X, P, C> & {
|
|
67
49
|
$entity: Type<E>;
|
|
68
50
|
}, opts?: QueryOptions): Promise<[QueryFindResult<E, S, V, X, P, C>[], number]>;
|
|
@@ -72,20 +54,14 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
72
54
|
* backend with no way to answer both at once is left with; SQL overrides it to answer from one.
|
|
73
55
|
*/
|
|
74
56
|
protected internalFindManyAndCount<E extends object>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): Promise<[E[], number]>;
|
|
75
|
-
/**
|
|
76
|
-
* Count records matching the query, in both the entity-as-argument and entity-as-field patterns.
|
|
77
|
-
* A `$skip`/`$limit` settles the matching ids and counts those, rather than scanning every match;
|
|
78
|
-
* `$sort` never reaches that SELECT, since it changes which rows a page holds, never how many.
|
|
79
|
-
*/
|
|
57
|
+
/** Count records matching the query, the entity passed first or as the query's `$entity`. */
|
|
80
58
|
count<E extends object>(entity: Type<E>, q?: QueryPage<E>, opts?: QueryOptions): Promise<number>;
|
|
81
59
|
count<E extends object>(q: QueryPage<E> & {
|
|
82
60
|
$entity: Type<E>;
|
|
83
61
|
}, opts?: QueryOptions): Promise<number>;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* capped at one row, so the engine stops at the first match instead of scanning every other one.
|
|
88
|
-
*/
|
|
62
|
+
/** How many rows match, or how many of them a page takes: counted where they are, never read. */
|
|
63
|
+
protected abstract internalCount<E extends object>(entity: Type<E>, q: QueryPage<E>, opts?: QueryOptions): Promise<number>;
|
|
64
|
+
/** Whether anything matches, the entity passed first or as `$entity`: a count capped at one row. */
|
|
89
65
|
exists<E extends object>(entity: Type<E>, q?: QueryFilter<E>, opts?: QueryOptions): Promise<boolean>;
|
|
90
66
|
exists<E extends object>(q: QueryFilter<E> & {
|
|
91
67
|
$entity: Type<E>;
|
|
@@ -106,38 +82,30 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
106
82
|
/** Writes `rows`, and onto each one the key the database generated for it, where it can tell. */
|
|
107
83
|
protected abstract internalInsertMany<E extends object>(entity: Type<E>, rows: EntityData<E>[]): Promise<void>;
|
|
108
84
|
updateOneById<E extends object>(entity: Type<E>, id: EntityId<E>, payload: UpdatePayload<E>, opts?: QueryOptions): Promise<number>;
|
|
85
|
+
/** Settles the rows first where the update cascades, so a payload changing what `$where` reads still names them. */
|
|
109
86
|
updateMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): Promise<number>;
|
|
87
|
+
/** The UPDATE, skipped where the payload writes no column, reporting `unwritten` instead. */
|
|
88
|
+
private updateColumns;
|
|
89
|
+
/** Whether a write has to name the rows `q` matches by their ids: no engine pages or orders an update or delete. */
|
|
90
|
+
protected settlesWrite<E extends object>(_entity: Type<E>, q: QuerySearch<E>): boolean;
|
|
91
|
+
/** The ids `q` matches, in its own order and page. */
|
|
92
|
+
protected settleIds<E extends object>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<EntityId<E>[]>;
|
|
93
|
+
/** Runs one UPDATE over `q`, which names its rows by id wherever {@link updateMany} settled them. */
|
|
110
94
|
protected abstract internalUpdateMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): Promise<number>;
|
|
111
95
|
restoreOneById<E extends object>(entity: Type<E>, id: EntityId<E>): Promise<number>;
|
|
112
96
|
restoreMany<E extends object>(entity: Type<E>, q: QuerySearch<E>): Promise<number>;
|
|
113
|
-
/**
|
|
114
|
-
* `beforeUpsert`/`afterUpsert` rather than the insert's or the update's pair: the database decides
|
|
115
|
-
* which branch each row takes as the statement runs, so neither of those could be fired honestly -
|
|
116
|
-
* but the upsert itself is a fact known before and after, and a row written with no hook at all
|
|
117
|
-
* was how an `@Id({ onInsert })` or an audit trail silently skipped this path.
|
|
118
|
-
*/
|
|
97
|
+
/** Fires `beforeUpsert`/`afterUpsert`: which branch a row takes is the database's to decide, so neither the insert's nor the update's pair fits. */
|
|
119
98
|
upsertOne<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityData<E>): Promise<QueryUpsertOneResult<E>>;
|
|
120
99
|
upsertMany<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityData<E>[]): Promise<QueryUpsertManyResult<E>>;
|
|
121
100
|
protected abstract internalUpsertOne<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityData<E>): Promise<QueryUpdateResult>;
|
|
122
101
|
protected abstract internalUpsertMany<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityData<E>[]): Promise<QueryUpdateResult>;
|
|
123
102
|
deleteOneById<E extends object>(entity: Type<E>, id: EntityId<E>, opts?: QueryOptions): Promise<number>;
|
|
124
|
-
/**
|
|
125
|
-
* Delete records matching the query. Soft-deletes when the entity has a soft-delete field (unless
|
|
126
|
-
* `opts.hardDelete`), otherwise removes the rows. Supports both entity-as-argument and entity-as-field patterns.
|
|
127
|
-
*/
|
|
103
|
+
/** Delete records matching the query, the entity passed first or as `$entity`; soft-deletes unless `opts.hardDelete`. */
|
|
128
104
|
deleteMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<number>;
|
|
129
105
|
deleteMany<E extends object>(q: QuerySearch<E> & {
|
|
130
106
|
$entity: Type<E>;
|
|
131
107
|
}, opts?: QueryOptions): Promise<number>;
|
|
132
|
-
/**
|
|
133
|
-
* The rows a delete is about to take, loaded only when a hook or listener is there to receive
|
|
134
|
-
* them: the round trip is pure overhead for the (common) delete nobody is watching, and
|
|
135
|
-
* `internalDeleteMany` has its own fast path that never reads the rows at all.
|
|
136
|
-
*
|
|
137
|
-
* `undefined` means nobody was watching, which is not the same as the empty array meaning nothing
|
|
138
|
-
* matched - the caller deletes by `q` for the first and skips the statement entirely for the second.
|
|
139
|
-
*/
|
|
140
|
-
private findDoomed;
|
|
108
|
+
/** Runs one DELETE (or soft-delete stamp) over `q`, which names its rows by id wherever {@link deleteMany} settled them. */
|
|
141
109
|
protected abstract internalDeleteMany<E extends object>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<number>;
|
|
142
110
|
saveOne<E extends object>(entity: Type<E>, payload: EntityData<E>): Promise<WrittenId<E> | undefined>;
|
|
143
111
|
/**
|
|
@@ -146,39 +114,21 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
146
114
|
* inserts. A composite is always named. The hooks follow the statement: a named row fires the upsert pair.
|
|
147
115
|
*/
|
|
148
116
|
saveMany<E extends object>(entity: Type<E>, payload: EntityData<E>[]): Promise<(WrittenId<E> | undefined)[]>;
|
|
149
|
-
|
|
150
|
-
protected
|
|
117
|
+
/** Writes each inserted row's relations, one set of statements per relation whatever the number of rows. */
|
|
118
|
+
protected insertRelations<E extends object>(entity: Type<E>, rows: E[]): Promise<void>;
|
|
119
|
+
/** `EntityId` because a settled composite row is an object, which {@link childrenOf} reads each foreign key column out of. */
|
|
120
|
+
private deleteRelations;
|
|
151
121
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
122
|
+
* Writes each parent's value into one relation. The parent owns what it points at: an update replaces
|
|
123
|
+
* it, and a `null` only clears it.
|
|
154
124
|
*/
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Persists `relValue` against every id in `ids`, which an update hands the whole page of rows it
|
|
158
|
-
* settled: the value is the same for all of them, so the statements are per relation rather than per
|
|
159
|
-
* row wherever the cardinality allows it.
|
|
160
|
-
*/
|
|
161
|
-
protected saveRelation<E extends object>(entity: Type<E>, ids: IdValue<E>[], relValue: unknown, relKey: RelationKey<E>, isUpdate?: boolean): Promise<void>;
|
|
162
|
-
private saveToMany;
|
|
163
|
-
private saveOneToOne;
|
|
125
|
+
private saveRelation;
|
|
126
|
+
/** Each parent gets its own referenced row, and its own column pointing at it. */
|
|
164
127
|
private saveManyToOne;
|
|
165
128
|
abstract readonly hasOpenTransaction: boolean;
|
|
166
129
|
/**
|
|
167
|
-
* Runs `callback` in a transaction
|
|
168
|
-
*
|
|
169
|
-
* The single place that sequence is written; everything else delegates here, because both subtleties
|
|
170
|
-
* below were got wrong by code that hand-rolled it:
|
|
171
|
-
*
|
|
172
|
-
* - `beginTransaction` connects before it begins, so a refused connection lands in the catch with no
|
|
173
|
-
* transaction open. `rollbackTransaction` is a no-op there rather than an error, which is why a
|
|
174
|
-
* wrong password no longer surfaces as a transaction-state error.
|
|
175
|
-
* - A rollback that fails too is a consequence of the original failure, not news, so it must not
|
|
176
|
-
* replace it either.
|
|
177
|
-
*
|
|
178
|
-
* The connection is **not** released here: whoever took it from the pool gives it back, through
|
|
179
|
-
* {@link QuerierPool.transaction}, {@link QuerierPool.withQuerier} or `await using`. Releasing a
|
|
180
|
-
* connection this method never acquired is what forced every caller to know whether it still owned
|
|
181
|
-
* one afterwards.
|
|
130
|
+
* Runs `callback` in a transaction, joining one already open. A rollback that fails is logged, never
|
|
131
|
+
* thrown over the original error, and the connection stays with whoever acquired it.
|
|
182
132
|
*/
|
|
183
133
|
transaction<T>(callback: () => Promise<T>, opts?: TransactionOptions): Promise<T>;
|
|
184
134
|
/** Whether anything at all - a global listener or the entity itself - handles `event`. */
|
|
@@ -205,23 +155,9 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
205
155
|
private hooked;
|
|
206
156
|
/** Fires the global listeners first, then the entity's own hooks. */
|
|
207
157
|
private emitHook;
|
|
208
|
-
/**
|
|
209
|
-
* Runs `task` after everything already queued on this querier, one at a time.
|
|
210
|
-
*
|
|
211
|
-
* @remarks Not re-entrant: only one task runs at a time, so a serialized method awaited from inside
|
|
212
|
-
* another one would wait for a task queued behind itself. Callers below keep their `serialize` calls
|
|
213
|
-
* sequential rather than nested.
|
|
214
|
-
*/
|
|
158
|
+
/** Runs `task` after everything already queued, one at a time. Not re-entrant: never nest `serialize` calls. */
|
|
215
159
|
protected serialize<T>(task: () => Promise<T>): Promise<T>;
|
|
216
|
-
/**
|
|
217
|
-
* Runs `task`, logs `query` with how long it took, and tags any error it throws with that query.
|
|
218
|
-
*
|
|
219
|
-
* A method rather than the `@Log()` decorator it replaces. A standard-spec method decorator works by
|
|
220
|
-
* returning a replacement function, and a replacement cannot carry the original's type parameters, so
|
|
221
|
-
* decorating `internalFindMany<E extends Document>` made its signature unresolvable. Most of the query
|
|
222
|
-
* surface is generic like that, and wrapping at the call site costs one line while keeping the
|
|
223
|
-
* signature intact.
|
|
224
|
-
*/
|
|
160
|
+
/** Runs `task`, logs `query` with its duration, and tags a failure with it: a method, since a decorator would lose the generics. */
|
|
225
161
|
protected timed<T>(query: string, values: unknown[] | undefined, task: () => Promise<T>): Promise<T>;
|
|
226
162
|
abstract beginTransaction(opts?: TransactionOptions): Promise<void>;
|
|
227
163
|
/** Strict: this is the check that catches a forgotten `beginTransaction`. */
|
|
@@ -232,12 +168,8 @@ export declare abstract class AbstractQuerier implements Querier {
|
|
|
232
168
|
*/
|
|
233
169
|
abstract rollbackTransaction(): Promise<void>;
|
|
234
170
|
/**
|
|
235
|
-
* Rolls back an unfinished transaction, then hands the connection back
|
|
236
|
-
*
|
|
237
|
-
* @remarks Refusing to release was the opposite of safe: the throw came *before* the connection went
|
|
238
|
-
* back, so it destroyed the error that got here and cost the pool a connection with a live `BEGIN` on
|
|
239
|
-
* it. It is also the only option `await using` can reach, which calls `Symbol.asyncDispose` with no
|
|
240
|
-
* arguments and discards what it returns.
|
|
171
|
+
* Rolls back an unfinished transaction, then hands the connection back, discarding it if the rollback
|
|
172
|
+
* failed. Never throws first, since `await using` has no other way to release.
|
|
241
173
|
*/
|
|
242
174
|
release(): Promise<void>;
|
|
243
175
|
[Symbol.asyncDispose](): Promise<void>;
|