uql-orm 0.65.1 → 0.67.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/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 +5 -10
- package/dist/entity/decorator/entity.js +2 -7
- package/dist/entity/decorator/members.d.ts +10 -31
- package/dist/entity/decorator/members.js +3 -12
- package/dist/entity/metadata/definition.d.ts +5 -21
- package/dist/entity/metadata/definition.js +69 -91
- package/dist/http/handler.d.ts +2 -14
- package/dist/index.d.ts +3 -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 +20 -66
- package/dist/migrate/schemaGenerator.js +32 -93
- 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 +6 -41
- 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 +189 -551
- 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 +28 -78
- 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 +5 -37
- package/dist/util/field.util.js +7 -50
- 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
|
@@ -10,34 +10,39 @@ import { parseQueryLock } from '../type/index.js';
|
|
|
10
10
|
import { isAutoIncrement } from '../util/field.util.js';
|
|
11
11
|
import { assertNonNegativeInteger } from '../util/index.js';
|
|
12
12
|
import { escapeSingleQuotes } from '../util/sqlLiteral.js';
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
/** What SQL Server has. */
|
|
14
|
+
const MSSQL_FEATURES = {
|
|
15
|
+
// Neither object takes an `IF NOT EXISTS`; both need a `sys` catalogue lookup around them, which
|
|
16
|
+
// the generator does not emit.
|
|
17
|
+
ifNotExists: false,
|
|
18
|
+
indexIfNotExists: false,
|
|
19
|
+
schemas: true,
|
|
20
|
+
dropTableCascade: false,
|
|
21
|
+
foreignKeyAlter: true,
|
|
22
|
+
primaryKeyAlter: true,
|
|
23
|
+
generatedColumnAdd: true,
|
|
24
|
+
// Extended properties are out-of-band metadata with their own procedures, not comments.
|
|
25
|
+
commentSyntax: 'none',
|
|
26
|
+
vectorIndexRequiresNotNull: false,
|
|
27
|
+
vectorSupportsLength: true,
|
|
28
|
+
supportsTimestamptz: false,
|
|
29
|
+
stringSizing: 'varchar',
|
|
30
|
+
supportsUnsigned: false,
|
|
31
|
+
serverSideCursors: false,
|
|
32
|
+
rowLocks: true,
|
|
33
|
+
rowLockWithWindow: true,
|
|
34
|
+
rowLockOf: true,
|
|
35
|
+
orderedUpsertReturning: false,
|
|
36
|
+
orderedJsonAggregates: true,
|
|
37
|
+
partialJsonContainment: false,
|
|
38
|
+
typedJsonElements: false,
|
|
39
|
+
narrowVectorTypes: false,
|
|
40
|
+
vectorTuningNeedsTransaction: false,
|
|
41
|
+
serialDeclaresPrimaryKey: false,
|
|
42
|
+
};
|
|
43
|
+
/** Microsoft SQL Server 2017 and up. Identifiers are `"`-quoted, the ANSI spelling `tedious` enables. */
|
|
21
44
|
export class MsSqlDialect extends MergeSqlDialect {
|
|
22
|
-
|
|
23
|
-
// Neither object takes an `IF NOT EXISTS`; both need a `sys` catalogue lookup around them, which
|
|
24
|
-
// the generator does not emit.
|
|
25
|
-
ifNotExists: false,
|
|
26
|
-
indexIfNotExists: false,
|
|
27
|
-
schemas: true,
|
|
28
|
-
dropTableCascade: false,
|
|
29
|
-
foreignKeyAlter: true,
|
|
30
|
-
primaryKeyAlter: true,
|
|
31
|
-
generatedColumnAdd: true,
|
|
32
|
-
// Extended properties are out-of-band metadata with their own procedures, not comments.
|
|
33
|
-
commentSyntax: 'none',
|
|
34
|
-
vectorIndexRequiresNotNull: false,
|
|
35
|
-
vectorSupportsLength: true,
|
|
36
|
-
supportsTimestamptz: false,
|
|
37
|
-
stringSizing: 'varchar',
|
|
38
|
-
supportsUnsigned: false,
|
|
39
|
-
serverSideCursors: false,
|
|
40
|
-
};
|
|
45
|
+
features = MSSQL_FEATURES;
|
|
41
46
|
dialectName = 'mssql';
|
|
42
47
|
/** `OPENJSON`'s own output columns, which every JSON operator below reads through. */
|
|
43
48
|
#elem = {
|
|
@@ -61,8 +66,6 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
61
66
|
maxBindValues = 2100;
|
|
62
67
|
/** `OUTPUT` has no trailing form: it sits between the column list and `VALUES`. */
|
|
63
68
|
returningPosition = 'after-target';
|
|
64
|
-
/** Microsoft documents no row order for a `MERGE ... OUTPUT`. */
|
|
65
|
-
upsertReturningOrdered = false;
|
|
66
69
|
insertIdSource = 'returning';
|
|
67
70
|
/** Holds the update key lock across the insert; without it two concurrent upserts of one key race. */
|
|
68
71
|
mergeTargetHint = ' WITH (HOLDLOCK)';
|
|
@@ -86,12 +89,8 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
86
89
|
super.pager(ctx, opts, sorted);
|
|
87
90
|
}
|
|
88
91
|
/**
|
|
89
|
-
* `SET IDENTITY_INSERT` around
|
|
90
|
-
*
|
|
91
|
-
* column ... when IDENTITY_INSERT is set to OFF") rather than ignored.
|
|
92
|
-
*
|
|
93
|
-
* Emitted only for that case, because the setting is per-session and only one table may hold it at
|
|
94
|
-
* a time, so it is turned back off in the same batch it was turned on.
|
|
92
|
+
* `SET IDENTITY_INSERT` around an insert that states a key the engine would generate, which it otherwise
|
|
93
|
+
* refuses; turned off in the same batch, since one table per session may hold it.
|
|
95
94
|
*/
|
|
96
95
|
insert(ctx, entity, payload, opts) {
|
|
97
96
|
const table = this.identityInsertTarget(entity, payload);
|
|
@@ -115,13 +114,7 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
115
114
|
const stated = records.some((record) => record[idKey] !== undefined);
|
|
116
115
|
return stated ? this.escapedTableName(meta) : undefined;
|
|
117
116
|
}
|
|
118
|
-
/**
|
|
119
|
-
* A `DECIMAL` read back as the exact text it was written as, where the entity declared the field a
|
|
120
|
-
* `String`. `tedious` decodes the type to a JS number before anything here can see it, so the
|
|
121
|
-
* digits past 2^53 are gone at the wire unless the column is converted before it crosses - the same
|
|
122
|
-
* reason MariaDB reads a vector column through `VEC_ToText`. 41 characters covers `DECIMAL(38, s)`
|
|
123
|
-
* with room for the sign and the point.
|
|
124
|
-
*/
|
|
117
|
+
/** A `DECIMAL` declared `String`, converted before it crosses the wire, where `tedious` would round it. */
|
|
125
118
|
selectFieldExpr(escapedColumn, field) {
|
|
126
119
|
const exactDecimal = field.type === String && fieldOptionsToCanonical(field).category === 'decimal';
|
|
127
120
|
return exactDecimal ? `CONVERT(NVARCHAR(41), ${escapedColumn})` : escapedColumn;
|
|
@@ -261,13 +254,8 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
261
254
|
return this.getJsonPathScalarExpr(escapedColumn, jsonPathStr);
|
|
262
255
|
}
|
|
263
256
|
/**
|
|
264
|
-
* A value
|
|
265
|
-
* `'true'
|
|
266
|
-
* string already binds as the text it will be compared with.
|
|
267
|
-
*
|
|
268
|
-
* There is no "parse this text as JSON" cast to bind through the way `CAST(? AS JSON)` and
|
|
269
|
-
* `json(?)` serve the other families - `JSON_QUERY` marks text as JSON but answers NULL for a
|
|
270
|
-
* scalar - which is why reading and writing need the two different binders here.
|
|
257
|
+
* A value compared against a JSON path, which reads back as text, so only a boolean needs spelling as
|
|
258
|
+
* `'true'`; SQL Server has no cast that parses text as JSON.
|
|
271
259
|
*/
|
|
272
260
|
jsonScalarParam(ctx, value) {
|
|
273
261
|
return (this.#jsonCompound(ctx, value) ?? this.addValue(ctx, typeof value === 'boolean' ? JSON.stringify(value) : value));
|
|
@@ -298,8 +286,6 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
298
286
|
}
|
|
299
287
|
return `JSON_QUERY(${this.addValue(ctx, JSON.stringify(value))})`;
|
|
300
288
|
}
|
|
301
|
-
/** An exploded element compares as text here, so `$elemMatch` always expands per field. */
|
|
302
|
-
jsonContainmentIsPartial = false;
|
|
303
289
|
jsonElemFrom(jsonField, _fields, alias) {
|
|
304
290
|
return `OPENJSON(${jsonField}) ${alias}`;
|
|
305
291
|
}
|
|
@@ -1,12 +1,44 @@
|
|
|
1
|
-
import type { ConnectionPool } from 'mssql';
|
|
2
1
|
import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
|
|
3
|
-
import type { QueryUpdateResult, TransactionOptions } from '../type/index.js';
|
|
2
|
+
import type { QueryUpdateResult, RawRow, TransactionOptions } from '../type/index.js';
|
|
3
|
+
/** What `tedious` hands back for one statement, whichever shape it took. */
|
|
4
|
+
type MsSqlResult = {
|
|
5
|
+
recordset?: RawRow[] & {
|
|
6
|
+
columns?: Record<string, {
|
|
7
|
+
type: unknown;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
rowsAffected: number[];
|
|
11
|
+
};
|
|
12
|
+
/** The part of the `Readable` a request streams into that a querier drives. */
|
|
13
|
+
type MsSqlRowStream = AsyncIterable<unknown> & {
|
|
14
|
+
destroy(error: Error): unknown;
|
|
15
|
+
on(event: 'error', listener: (error: Error) => void): unknown;
|
|
16
|
+
};
|
|
17
|
+
/** The part of an `mssql` `Request` a querier drives. */
|
|
18
|
+
type MsSqlRequest = {
|
|
19
|
+
input(name: string, value: unknown): unknown;
|
|
20
|
+
query(command: string): Promise<MsSqlResult>;
|
|
21
|
+
toReadableStream(): MsSqlRowStream;
|
|
22
|
+
cancel(): unknown;
|
|
23
|
+
};
|
|
24
|
+
/** The part of an `mssql` `Transaction` a querier drives. */
|
|
25
|
+
type MsSqlTransaction = {
|
|
26
|
+
begin(isolationLevel?: number): Promise<unknown>;
|
|
27
|
+
commit(): Promise<unknown>;
|
|
28
|
+
rollback(): Promise<unknown>;
|
|
29
|
+
request(): MsSqlRequest;
|
|
30
|
+
};
|
|
31
|
+
/** The part of an `mssql` `ConnectionPool` a querier drives. */
|
|
32
|
+
export type MsSqlConnection = {
|
|
33
|
+
request(): MsSqlRequest;
|
|
34
|
+
transaction(): MsSqlTransaction;
|
|
35
|
+
};
|
|
4
36
|
/**
|
|
5
37
|
* A connection is a `ConnectionPool` handle here rather than a checked-out socket: `mssql` owns its
|
|
6
38
|
* own pool and hands out `Request`s, so what UQL holds is the pool plus, once a transaction opens,
|
|
7
39
|
* the `Transaction` every later request has to be bound to.
|
|
8
40
|
*/
|
|
9
|
-
export declare class MsSqlQuerier extends AbstractPoolQuerier<
|
|
41
|
+
export declare class MsSqlQuerier extends AbstractPoolQuerier<MsSqlConnection> {
|
|
10
42
|
#private;
|
|
11
43
|
internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
12
44
|
internalRun(query: string, values?: unknown[]): Promise<QueryUpdateResult>;
|
|
@@ -26,5 +58,6 @@ export declare class MsSqlQuerier extends AbstractPoolQuerier<ConnectionPool> {
|
|
|
26
58
|
protected internalCommit(): Promise<void>;
|
|
27
59
|
protected internalRollback(): Promise<void>;
|
|
28
60
|
/** The pool owns the socket; releasing a querier only drops this one's claim on it. */
|
|
29
|
-
protected releaseConn(_conn:
|
|
61
|
+
protected releaseConn(_conn: MsSqlConnection, _discard: boolean): Promise<void>;
|
|
30
62
|
}
|
|
63
|
+
export {};
|
|
@@ -19,11 +19,11 @@ export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
|
19
19
|
return request;
|
|
20
20
|
}
|
|
21
21
|
async internalAll(query, values) {
|
|
22
|
-
const res =
|
|
22
|
+
const res = await this.#request(values).query(query);
|
|
23
23
|
return decodeWireTypes(res.recordset, res.recordset?.columns);
|
|
24
24
|
}
|
|
25
25
|
async internalRun(query, values) {
|
|
26
|
-
const res =
|
|
26
|
+
const res = await this.#request(values).query(query);
|
|
27
27
|
return this.buildUpdateResult({
|
|
28
28
|
// `rowsAffected` carries one entry per statement, and a `MERGE` upsert emits its `OUTPUT`
|
|
29
29
|
// alongside the write, so the counts are summed rather than read at [0].
|
|
@@ -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')}`);
|