uql-orm 0.54.0 → 0.55.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 +2 -2
- package/dist/browser/uql-browser.min.js.map +1 -1
- package/dist/bunSql/bunSql.util.d.ts +3 -14
- package/dist/bunSql/bunSql.util.js +33 -56
- package/dist/bunSql/bunSqlQuerier.d.ts +3 -6
- package/dist/bunSql/bunSqlQuerier.js +7 -13
- package/dist/bunSql/bunSqlQuerierPool.d.ts +10 -5
- package/dist/bunSql/bunSqlQuerierPool.js +25 -10
- package/dist/cockroachdb/crdbQuerierPool.d.ts +1 -3
- package/dist/cockroachdb/crdbQuerierPool.js +0 -4
- package/dist/cockroachdb/index.d.ts +0 -1
- package/dist/cockroachdb/index.js +0 -1
- package/dist/d1/d1SqliteDialect.d.ts +5 -0
- package/dist/d1/d1SqliteDialect.js +7 -0
- package/dist/dialect/abstractSqlDialect.d.ts +9 -9
- package/dist/dialect/abstractSqlDialect.js +38 -51
- package/dist/dialect/hydrateColumn.js +2 -2
- package/dist/dialect/mergeSqlDialect.d.ts +2 -2
- package/dist/dialect/mergeSqlDialect.js +0 -4
- package/dist/dialect/pgLikeSqlDialect.d.ts +5 -0
- package/dist/dialect/pgLikeSqlDialect.js +12 -2
- package/dist/entity/index.d.ts +1 -1
- package/dist/entity/index.js +1 -1
- package/dist/entity/metadata/definition.d.ts +3 -1
- package/dist/entity/metadata/definition.js +8 -0
- package/dist/libsql/index.d.ts +0 -1
- package/dist/libsql/index.js +0 -1
- package/dist/libsql/libsqlQuerierPool.d.ts +3 -5
- package/dist/libsql/libsqlQuerierPool.js +2 -5
- package/dist/maria/mariadbQuerier.d.ts +0 -3
- package/dist/maria/mariadbQuerier.js +6 -7
- package/dist/maria/mariadbQuerierPool.js +4 -7
- package/dist/migrate/ddl/index.d.ts +3 -3
- package/dist/migrate/ddl/index.js +3 -3
- package/dist/mongo/index.d.ts +0 -1
- package/dist/mongo/index.js +0 -1
- package/dist/mongo/mongoDialect.d.ts +0 -1
- package/dist/mongo/mongoDialect.js +3 -14
- package/dist/mongo/mongodbQuerier.js +6 -5
- package/dist/mongo/mongodbQuerierPool.d.ts +2 -2
- package/dist/mongo/mongodbQuerierPool.js +2 -2
- package/dist/mssql/mssqlDialect.d.ts +3 -5
- package/dist/mssql/mssqlDialect.js +9 -8
- package/dist/mssql/mssqlQuerier.d.ts +13 -6
- package/dist/mssql/mssqlQuerier.js +30 -75
- package/dist/mssql/mssqlQuerierPool.js +2 -0
- package/dist/mssql/mssqlWireTypes.d.ts +3 -4
- package/dist/mssql/mssqlWireTypes.js +5 -8
- package/dist/mysql/index.d.ts +0 -1
- package/dist/mysql/index.js +0 -1
- package/dist/mysql/mysql2Querier.d.ts +1 -4
- package/dist/mysql/mysql2Querier.js +0 -3
- package/dist/mysql/mysql2QuerierPool.d.ts +2 -2
- package/dist/mysql/mysql2QuerierPool.js +5 -3
- package/dist/neon/index.d.ts +0 -2
- package/dist/neon/index.js +0 -2
- package/dist/neon/neonQuerierPool.d.ts +2 -4
- package/dist/neon/neonQuerierPool.js +2 -6
- package/dist/pglite/index.d.ts +0 -1
- package/dist/pglite/index.js +0 -1
- package/dist/pglite/pgliteQuerier.d.ts +3 -3
- package/dist/pglite/pgliteQuerier.js +1 -1
- package/dist/pglite/pgliteQuerierPool.d.ts +7 -2
- package/dist/pglite/pgliteQuerierPool.js +16 -6
- package/dist/postgres/abstractPgQuerierPool.d.ts +8 -12
- package/dist/postgres/abstractPgQuerierPool.js +8 -6
- package/dist/postgres/index.d.ts +0 -1
- package/dist/postgres/index.js +0 -1
- package/dist/postgres/pgNumericTypes.d.ts +5 -5
- package/dist/postgres/pgNumericTypes.js +11 -7
- package/dist/postgres/pgQuerier.d.ts +22 -4
- package/dist/postgres/pgQuerier.js +29 -2
- package/dist/postgres/pgQuerierPool.d.ts +2 -4
- package/dist/postgres/pgQuerierPool.js +2 -6
- package/dist/postgres/postgresDialect.d.ts +5 -5
- package/dist/postgres/postgresDialect.js +5 -5
- package/dist/postgres/postgresWireDriverCapabilities.d.ts +2 -2
- package/dist/postgres/postgresWireDriverCapabilities.js +2 -2
- package/dist/querier/abstractPoolQuerier.d.ts +1 -1
- package/dist/querier/abstractPoolQuerier.js +1 -1
- package/dist/querier/abstractSqlQuerier.d.ts +11 -4
- package/dist/querier/abstractSqlQuerier.js +28 -16
- package/dist/sqlite/hranaQuerier.d.ts +6 -8
- package/dist/sqlite/hranaQuerier.js +13 -30
- package/dist/sqlite/hranaQuerierPool.d.ts +3 -4
- package/dist/sqlite/hranaQuerierPool.js +2 -1
- package/dist/sqlite/localSqliteQuerierPool.d.ts +3 -3
- package/dist/sqlite/localSqliteQuerierPool.js +4 -2
- package/dist/sqlite/nodeSqliteAdapter.d.ts +0 -1
- package/dist/sqlite/nodeSqliteQuerierPool.js +0 -2
- package/dist/sqlite/sqlitePragmas.d.ts +12 -0
- package/dist/sqlite/sqlitePragmas.js +15 -0
- package/dist/sqlite/sqliteQuerierPool.d.ts +0 -5
- package/dist/sqlite/sqliteQuerierPool.js +2 -13
- package/dist/turso/index.d.ts +0 -1
- package/dist/turso/index.js +0 -1
- package/dist/turso/tursoLocalQuerier.d.ts +0 -1
- package/dist/turso/tursoLocalQuerierPool.js +2 -2
- package/dist/turso/tursoQuerierPool.d.ts +1 -3
- package/dist/turso/tursoQuerierPool.js +0 -4
- package/dist/type/dialect.d.ts +1 -1
- package/dist/util/dialect.util.d.ts +1 -1
- package/dist/util/dialect.util.js +1 -1
- package/dist/util/logger.d.ts +7 -8
- package/dist/util/logger.js +18 -11
- package/dist/util/raw.js +3 -3
- package/dist/util/sqlLiteral.js +3 -8
- package/dist/util/string.util.js +2 -6
- package/dist/util/wideNumber.d.ts +14 -0
- package/dist/util/wideNumber.js +24 -0
- package/package.json +1 -1
- package/dist/cockroachdb/crdbQuerier.d.ts +0 -8
- package/dist/cockroachdb/crdbQuerier.js +0 -6
- package/dist/libsql/libsqlQuerier.d.ts +0 -10
- package/dist/libsql/libsqlQuerier.js +0 -10
- package/dist/mongo/mongodbNativeDialect.d.ts +0 -9
- package/dist/mongo/mongodbNativeDialect.js +0 -9
- package/dist/mysql/mysql2Dialect.d.ts +0 -9
- package/dist/mysql/mysql2Dialect.js +0 -9
- package/dist/neon/neonDialect.d.ts +0 -10
- package/dist/neon/neonDialect.js +0 -10
- package/dist/neon/neonQuerier.d.ts +0 -5
- package/dist/neon/neonQuerier.js +0 -3
- package/dist/pglite/pgliteDialect.d.ts +0 -14
- package/dist/pglite/pgliteDialect.js +0 -14
- package/dist/postgres/abstractPgQuerier.d.ts +0 -24
- package/dist/postgres/abstractPgQuerier.js +0 -32
- package/dist/postgres/pgDialect.d.ts +0 -10
- package/dist/postgres/pgDialect.js +0 -10
- package/dist/turso/tursoQuerier.d.ts +0 -10
- package/dist/turso/tursoQuerier.js +0 -10
|
@@ -52,12 +52,10 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
52
52
|
commitTransactionCommand = 'COMMIT TRANSACTION';
|
|
53
53
|
rollbackTransactionCommand = 'ROLLBACK TRANSACTION';
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* the transaction opens on, and would then stick to that connection for unrelated later queries.
|
|
58
|
-
* `MsSqlQuerier` reads the level back off this command and hands it to the driver.
|
|
55
|
+
* T-SQL has no inline form, so the level is set before the `BEGIN`. What a driver that sends these
|
|
56
|
+
* as statements would run; `MsSqlQuerier` opens its transactions through the driver instead.
|
|
59
57
|
*/
|
|
60
|
-
isolationLevelStrategy = '
|
|
58
|
+
isolationLevelStrategy = 'set-before';
|
|
61
59
|
dropIndexSyntax = 'on-table';
|
|
62
60
|
booleanLiteral = 'integer';
|
|
63
61
|
/** [The hard server limit](https://github.com/yiisoft/yii2/issues/10371), not a driver preference. */
|
|
@@ -270,11 +268,14 @@ export class MsSqlDialect extends MergeSqlDialect {
|
|
|
270
268
|
return typeof value === 'boolean' ? `CAST(${placeholder} AS BIT)` : placeholder;
|
|
271
269
|
}
|
|
272
270
|
/**
|
|
273
|
-
* An object or array bound as JSON, which is the half both binders
|
|
274
|
-
* `undefined` for a scalar - where they diverge.
|
|
271
|
+
* An object or array bound as JSON, or a `raw()` rendered in place, which is the half both binders
|
|
272
|
+
* spell the same way; `undefined` for a scalar - where they diverge.
|
|
275
273
|
*/
|
|
276
274
|
#jsonCompound(ctx, value) {
|
|
277
|
-
if (value
|
|
275
|
+
if (value instanceof QueryRaw) {
|
|
276
|
+
return this.rawFragment(ctx, value);
|
|
277
|
+
}
|
|
278
|
+
if (value === null || typeof value !== 'object') {
|
|
278
279
|
return undefined;
|
|
279
280
|
}
|
|
280
281
|
ctx.pushValue(JSON.stringify(value));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ConnectionPool } from 'mssql';
|
|
2
2
|
import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type { MsSqlDialect } from './mssqlDialect.js';
|
|
3
|
+
import type { QueryUpdateResult, TransactionOptions } from '../type/index.js';
|
|
5
4
|
/**
|
|
6
5
|
* A connection is a `ConnectionPool` handle here rather than a checked-out socket: `mssql` owns its
|
|
7
6
|
* own pool and hands out `Request`s, so what UQL holds is the pool plus, once a transaction opens,
|
|
@@ -9,15 +8,23 @@ import type { MsSqlDialect } from './mssqlDialect.js';
|
|
|
9
8
|
*/
|
|
10
9
|
export declare class MsSqlQuerier extends AbstractPoolQuerier<ConnectionPool> {
|
|
11
10
|
#private;
|
|
12
|
-
constructor(connect: () => Promise<ConnectionPool>, dialect: MsSqlDialect, extra?: ExtraOptions);
|
|
13
11
|
internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
14
12
|
internalRun(query: string, values?: unknown[]): Promise<QueryUpdateResult>;
|
|
15
13
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* The driver's own stream over the request, which pauses the request while the loop is behind, so
|
|
15
|
+
* rows arrive only as fast as they are read. A failure the driver reports through the promise alone
|
|
16
|
+
* would leave the loop waiting for rows, so it ends the stream instead.
|
|
19
17
|
*/
|
|
20
18
|
internalStream<T>(query: string, values?: unknown[]): AsyncGenerator<Awaited<T>, void, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* `mssql` owns its pool and hands out a `Request` per call, so a `BEGIN TRANSACTION` sent as text
|
|
21
|
+
* would open one on a connection the next call may not be given. Its `Transaction` object is the
|
|
22
|
+
* only thing that pins them together, so the transaction is that object rather than statements, and
|
|
23
|
+
* the level goes to its `begin`: sent as a statement it would land on whichever connection served it.
|
|
24
|
+
*/
|
|
25
|
+
protected internalBegin(opts?: TransactionOptions): Promise<void>;
|
|
26
|
+
protected internalCommit(): Promise<void>;
|
|
27
|
+
protected internalRollback(): Promise<void>;
|
|
21
28
|
/** The pool owns the socket; releasing a querier only drops this one's claim on it. */
|
|
22
29
|
protected releaseConn(_conn: ConnectionPool, _discard: boolean): Promise<void>;
|
|
23
30
|
}
|
|
@@ -8,9 +8,6 @@ import { decodeWireTypes } from './mssqlWireTypes.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
10
10
|
#transaction;
|
|
11
|
-
constructor(connect, dialect, extra) {
|
|
12
|
-
super(dialect, connect, extra);
|
|
13
|
-
}
|
|
14
11
|
/**
|
|
15
12
|
* Values bind by name, `@p1` upward, matching {@link MsSqlDialect.placeholder}. `tedious` infers
|
|
16
13
|
* a type from the JS value, which is why a `Date` and a `Uint8Array` reach it unconverted - the
|
|
@@ -26,9 +23,6 @@ export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
|
26
23
|
return decodeWireTypes(res.recordset, res.recordset?.columns);
|
|
27
24
|
}
|
|
28
25
|
async internalRun(query, values) {
|
|
29
|
-
if (await this.#driveTransaction(query)) {
|
|
30
|
-
return { changes: 0 };
|
|
31
|
-
}
|
|
32
26
|
const res = (await this.#request(values).query(query));
|
|
33
27
|
return this.buildUpdateResult({
|
|
34
28
|
// `rowsAffected` carries one entry per statement, and a `MERGE` upsert emits its `OUTPUT`
|
|
@@ -38,57 +32,24 @@ export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
|
38
32
|
});
|
|
39
33
|
}
|
|
40
34
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
35
|
+
* The driver's own stream over the request, which pauses the request while the loop is behind, so
|
|
36
|
+
* rows arrive only as fast as they are read. A failure the driver reports through the promise alone
|
|
37
|
+
* would leave the loop waiting for rows, so it ends the stream instead.
|
|
44
38
|
*/
|
|
45
39
|
async *internalStream(query, values) {
|
|
46
40
|
const request = this.#request(values);
|
|
47
|
-
|
|
48
|
-
let pending = [];
|
|
49
|
-
let done = false;
|
|
50
|
-
let failure;
|
|
51
|
-
let wake;
|
|
52
|
-
const arrived = () => {
|
|
53
|
-
wake?.();
|
|
54
|
-
wake = undefined;
|
|
55
|
-
};
|
|
56
|
-
request.on('row', (row) => {
|
|
57
|
-
pending.push(row);
|
|
58
|
-
arrived();
|
|
59
|
-
});
|
|
60
|
-
request.on('error', (err) => {
|
|
61
|
-
failure ??= err;
|
|
62
|
-
arrived();
|
|
63
|
-
});
|
|
64
|
-
request.on('done', () => {
|
|
65
|
-
done = true;
|
|
66
|
-
arrived();
|
|
67
|
-
});
|
|
41
|
+
const rows = request.toReadableStream();
|
|
68
42
|
const completed = request.query(query).catch((err) => {
|
|
69
|
-
|
|
70
|
-
arrived();
|
|
43
|
+
rows.destroy(err instanceof Error ? err : new Error(String(err)));
|
|
71
44
|
});
|
|
72
45
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const batch = pending;
|
|
76
|
-
pending = [];
|
|
77
|
-
yield* batch;
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
if (failure)
|
|
81
|
-
throw failure;
|
|
82
|
-
if (done)
|
|
83
|
-
return;
|
|
84
|
-
await new Promise((resolve) => {
|
|
85
|
-
wake = resolve;
|
|
86
|
-
});
|
|
46
|
+
for await (const row of rows) {
|
|
47
|
+
yield row;
|
|
87
48
|
}
|
|
88
49
|
}
|
|
89
50
|
finally {
|
|
90
|
-
//
|
|
91
|
-
|
|
51
|
+
// The cancel reports itself as an error on the stream, and the loop that would hear it is gone.
|
|
52
|
+
rows.on('error', () => { });
|
|
92
53
|
request.cancel();
|
|
93
54
|
await completed;
|
|
94
55
|
}
|
|
@@ -96,24 +57,23 @@ export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
|
96
57
|
/**
|
|
97
58
|
* `mssql` owns its pool and hands out a `Request` per call, so a `BEGIN TRANSACTION` sent as text
|
|
98
59
|
* would open one on a connection the next call may not be given. Its `Transaction` object is the
|
|
99
|
-
* only thing that pins them together, so the
|
|
100
|
-
*
|
|
101
|
-
* so renaming one cannot silently turn it back into text.
|
|
60
|
+
* only thing that pins them together, so the transaction is that object rather than statements, and
|
|
61
|
+
* the level goes to its `begin`: sent as a statement it would land on whichever connection served it.
|
|
102
62
|
*/
|
|
103
|
-
async
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
63
|
+
async internalBegin(opts) {
|
|
64
|
+
const transaction = this.getConn().transaction();
|
|
65
|
+
await transaction.begin(opts?.isolationLevel && ISOLATION_LEVEL[ISOLATION[opts.isolationLevel]]);
|
|
66
|
+
this.#transaction = transaction;
|
|
67
|
+
}
|
|
68
|
+
async internalCommit() {
|
|
69
|
+
const transaction = this.#transaction;
|
|
70
|
+
this.#transaction = undefined;
|
|
71
|
+
await transaction?.commit();
|
|
72
|
+
}
|
|
73
|
+
async internalRollback() {
|
|
113
74
|
const transaction = this.#transaction;
|
|
114
75
|
this.#transaction = undefined;
|
|
115
|
-
await
|
|
116
|
-
return true;
|
|
76
|
+
await transaction?.rollback();
|
|
117
77
|
}
|
|
118
78
|
/** The pool owns the socket; releasing a querier only drops this one's claim on it. */
|
|
119
79
|
async releaseConn(_conn, _discard) {
|
|
@@ -123,15 +83,10 @@ export class MsSqlQuerier extends AbstractPoolQuerier {
|
|
|
123
83
|
await transaction?.rollback().catch(() => undefined);
|
|
124
84
|
}
|
|
125
85
|
}
|
|
126
|
-
/**
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
.trim()
|
|
134
|
-
.toUpperCase()
|
|
135
|
-
.replaceAll(' ', '_');
|
|
136
|
-
return level ? ISOLATION_LEVEL[level] : undefined;
|
|
137
|
-
}
|
|
86
|
+
/** The driver's constant for each level UQL names; total, so a new level is a compile error here. */
|
|
87
|
+
const ISOLATION = {
|
|
88
|
+
'read uncommitted': 'READ_UNCOMMITTED',
|
|
89
|
+
'read committed': 'READ_COMMITTED',
|
|
90
|
+
'repeatable read': 'REPEATABLE_READ',
|
|
91
|
+
serializable: 'SERIALIZABLE',
|
|
92
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ConnectionPool } from 'mssql';
|
|
2
2
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
3
3
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
4
|
+
import { attachPoolErrorHandler } from '../util/index.js';
|
|
4
5
|
import { MsSqlDialect } from './mssqlDialect.js';
|
|
5
6
|
import { MsSqlQuerier } from './mssqlQuerier.js';
|
|
6
7
|
export class MsSqlQuerierPool extends AbstractSqlQuerierPool {
|
|
@@ -9,6 +10,7 @@ export class MsSqlQuerierPool extends AbstractSqlQuerierPool {
|
|
|
9
10
|
constructor(opts, extra) {
|
|
10
11
|
super(new MsSqlDialect(dialectOptionsFrom(extra)), extra);
|
|
11
12
|
this.pool = new ConnectionPool(opts);
|
|
13
|
+
attachPoolErrorHandler(this.pool, 'Idle SQL Server pool connection encountered an error', extra?.logger);
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* `mssql` connects the pool as a whole rather than per checkout, so the promise is shared. A
|
|
@@ -14,10 +14,9 @@ type ColumnTypes = Record<string, {
|
|
|
14
14
|
* reads, the ids an `OUTPUT` reports, raw SQL, counts, aggregates - where the ORM's own hydration
|
|
15
15
|
* only ever sees entity reads.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* column that big is the declaration - `@Field({ type: String, columnType: 'bigint' })`.
|
|
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' })`.
|
|
21
20
|
*/
|
|
22
21
|
export declare function decodeWireTypes<T>(rows: T[] | undefined, columns: ColumnTypes | undefined): T[];
|
|
23
22
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
1
2
|
/**
|
|
2
3
|
* Decode `BIGINT` as a JS number, leaving every other type to the driver.
|
|
3
4
|
*
|
|
@@ -10,10 +11,9 @@
|
|
|
10
11
|
* reads, the ids an `OUTPUT` reports, raw SQL, counts, aggregates - where the ORM's own hydration
|
|
11
12
|
* only ever sees entity reads.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* column that big is the declaration - `@Field({ type: String, columnType: 'bigint' })`.
|
|
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' })`.
|
|
17
17
|
*/
|
|
18
18
|
export function decodeWireTypes(rows, columns) {
|
|
19
19
|
if (!rows?.length || !columns) {
|
|
@@ -29,10 +29,7 @@ export function decodeWireTypes(rows, columns) {
|
|
|
29
29
|
for (const name of wide) {
|
|
30
30
|
const value = decoded[name];
|
|
31
31
|
if (typeof value === 'string') {
|
|
32
|
-
|
|
33
|
-
if (Number.isSafeInteger(asNumber)) {
|
|
34
|
-
decoded[name] = asNumber;
|
|
35
|
-
}
|
|
32
|
+
decoded[name] = decodeWideNumber(value);
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
return decoded;
|
package/dist/mysql/index.d.ts
CHANGED
package/dist/mysql/index.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { PoolConnection } from 'mysql2/promise';
|
|
2
2
|
import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
|
|
3
|
-
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import type { MySqlDialect } from './mysqlDialect.js';
|
|
5
3
|
export declare class MySql2Querier extends AbstractPoolQuerier<PoolConnection> {
|
|
6
|
-
constructor(connect: () => Promise<PoolConnection>, dialect: MySqlDialect, extra?: ExtraOptions);
|
|
7
4
|
internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
8
|
-
internalRun(query: string, values?: unknown[]): Promise<import("../
|
|
5
|
+
internalRun(query: string, values?: unknown[]): Promise<import("../index.js").QueryUpdateResult>;
|
|
9
6
|
internalStream<T>(query: string, values?: unknown[]): AsyncGenerator<Awaited<T>, void, unknown>;
|
|
10
7
|
protected releaseConn(conn: PoolConnection, discard: boolean): Promise<void>;
|
|
11
8
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
|
|
2
2
|
export class MySql2Querier extends AbstractPoolQuerier {
|
|
3
|
-
constructor(connect, dialect, extra) {
|
|
4
|
-
super(dialect, connect, extra);
|
|
5
|
-
}
|
|
6
3
|
async internalAll(query, values) {
|
|
7
4
|
const [res] = await this.getConn().query(query, values);
|
|
8
5
|
return res;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type Pool, type PoolOptions } from 'mysql2/promise';
|
|
2
2
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
3
3
|
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import { MySql2Dialect } from './mysql2Dialect.js';
|
|
5
4
|
import { MySql2Querier } from './mysql2Querier.js';
|
|
6
|
-
|
|
5
|
+
import { MySqlDialect } from './mysqlDialect.js';
|
|
6
|
+
export declare class MySql2QuerierPool extends AbstractSqlQuerierPool<MySql2Querier, MySqlDialect> {
|
|
7
7
|
readonly pool: Pool;
|
|
8
8
|
constructor(opts: PoolOptions, extra?: ExtraOptions);
|
|
9
9
|
getQuerier(): Promise<MySql2Querier>;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { createPool } from 'mysql2/promise';
|
|
2
2
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
3
3
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
4
|
-
import { MySql2Dialect } from './mysql2Dialect.js';
|
|
5
4
|
import { MySql2Querier } from './mysql2Querier.js';
|
|
5
|
+
import { MySqlDialect } from './mysqlDialect.js';
|
|
6
6
|
export class MySql2QuerierPool extends AbstractSqlQuerierPool {
|
|
7
7
|
pool;
|
|
8
8
|
constructor(opts, extra) {
|
|
9
|
-
super(new
|
|
10
|
-
|
|
9
|
+
super(new MySqlDialect(dialectOptionsFrom(extra)), extra);
|
|
10
|
+
// A BIGINT past 2^53 as its exact text rather than a rounded number, the rule every driver here
|
|
11
|
+
// decodes by (`decodeWideNumber`); within that range it stays a number, and DECIMAL is untouched.
|
|
12
|
+
this.pool = createPool({ supportBigNumbers: true, ...opts });
|
|
11
13
|
}
|
|
12
14
|
async getQuerier() {
|
|
13
15
|
return new MySql2Querier(() => this.pool.getConnection(), this.dialect, this.extra);
|
package/dist/neon/index.d.ts
CHANGED
package/dist/neon/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Pool, type PoolClient, type PoolConfig } from '@neondatabase/serverless';
|
|
2
2
|
import { AbstractPgQuerierPool } from '../postgres/abstractPgQuerierPool.js';
|
|
3
|
+
import { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
3
4
|
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
|
|
5
|
-
import { NeonQuerier } from './neonQuerier.js';
|
|
6
|
-
export declare class NeonQuerierPool extends AbstractPgQuerierPool<PoolClient, NeonQuerier, NeonDialect> {
|
|
5
|
+
export declare class NeonQuerierPool extends AbstractPgQuerierPool<PoolClient, PostgresDialect> {
|
|
7
6
|
readonly pool: Pool;
|
|
8
7
|
constructor(opts: PoolConfig, extra?: ExtraOptions);
|
|
9
|
-
protected buildQuerier(connect: () => Promise<PoolClient>): NeonQuerier;
|
|
10
8
|
}
|
|
@@ -2,14 +2,10 @@ import { Pool, types } from '@neondatabase/serverless';
|
|
|
2
2
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
3
3
|
import { AbstractPgQuerierPool } from '../postgres/abstractPgQuerierPool.js';
|
|
4
4
|
import { numericTypes } from '../postgres/pgNumericTypes.js';
|
|
5
|
-
import {
|
|
6
|
-
import { NeonQuerier } from './neonQuerier.js';
|
|
5
|
+
import { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
7
6
|
export class NeonQuerierPool extends AbstractPgQuerierPool {
|
|
8
7
|
constructor(opts, extra) {
|
|
9
8
|
// Neon's own `types`, not `pg`'s: this entry has to load on an edge runtime where `pg` is absent.
|
|
10
|
-
super(new
|
|
11
|
-
}
|
|
12
|
-
buildQuerier(connect) {
|
|
13
|
-
return new NeonQuerier(connect, this.dialect, this.extra);
|
|
9
|
+
super(new PostgresDialect(dialectOptionsFrom(extra)), new Pool({ types: numericTypes(types), ...opts }), extra);
|
|
14
10
|
}
|
|
15
11
|
}
|
package/dist/pglite/index.d.ts
CHANGED
package/dist/pglite/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
1
2
|
import { AbstractSqlQuerier } from '../querier/index.js';
|
|
2
3
|
import type { ExtraOptions } from '../type/index.js';
|
|
3
|
-
import type { PgliteDialect } from './pgliteDialect.js';
|
|
4
4
|
/**
|
|
5
5
|
* Structural subset of the `@electric-sql/pglite` API actually used here, declared locally so this
|
|
6
6
|
* package does not couple its published types to a pre-1.0 dependency.
|
|
@@ -20,7 +20,7 @@ export type PgliteDatabase = {
|
|
|
20
20
|
/**
|
|
21
21
|
* Querier for PGlite, Postgres compiled to WASM and run in this process.
|
|
22
22
|
*
|
|
23
|
-
* @remarks Extends {@link AbstractSqlQuerier} rather than `
|
|
23
|
+
* @remarks Extends {@link AbstractSqlQuerier} rather than `PgQuerier`, whose `internalStream`
|
|
24
24
|
* hands a `pg-query-stream` object to `query()`, which PGlite's client has no equivalent of - so
|
|
25
25
|
* streaming pages the rows in SQL instead. `BEGIN`/`COMMIT` are plain statements on the single
|
|
26
26
|
* connection, leaving transactions to the base class.
|
|
@@ -28,7 +28,7 @@ export type PgliteDatabase = {
|
|
|
28
28
|
export declare class PgliteQuerier extends AbstractSqlQuerier {
|
|
29
29
|
readonly db: PgliteDatabase;
|
|
30
30
|
readonly extra?: ExtraOptions | undefined;
|
|
31
|
-
constructor(db: PgliteDatabase, dialect:
|
|
31
|
+
constructor(db: PgliteDatabase, dialect: PostgresDialect, extra?: ExtraOptions | undefined);
|
|
32
32
|
internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
33
33
|
internalRun(query: string, values?: unknown[]): Promise<import("../type/query.js").QueryUpdateResult>;
|
|
34
34
|
/** Postgres compiled to WASM is still Postgres: `DECLARE`/`FETCH` streams what the client cannot. */
|
|
@@ -3,7 +3,7 @@ import { AbstractSqlQuerier } from '../querier/index.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Querier for PGlite, Postgres compiled to WASM and run in this process.
|
|
5
5
|
*
|
|
6
|
-
* @remarks Extends {@link AbstractSqlQuerier} rather than `
|
|
6
|
+
* @remarks Extends {@link AbstractSqlQuerier} rather than `PgQuerier`, whose `internalStream`
|
|
7
7
|
* hands a `pg-query-stream` object to `query()`, which PGlite's client has no equivalent of - so
|
|
8
8
|
* streaming pages the rows in SQL instead. `BEGIN`/`COMMIT` are plain statements on the single
|
|
9
9
|
* connection, leaving transactions to the base class.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PGliteOptions } from '@electric-sql/pglite';
|
|
2
|
+
import { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
2
3
|
import { AbstractSharedHandleQuerierPool } from '../querier/abstractSharedHandleQuerierPool.js';
|
|
3
4
|
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import { PgliteDialect } from './pgliteDialect.js';
|
|
5
5
|
import { type PgliteDatabase, PgliteQuerier } from './pgliteQuerier.js';
|
|
6
6
|
/**
|
|
7
7
|
* The driver's own options, minus the `dataDir` this pool takes as its first argument.
|
|
@@ -26,8 +26,13 @@ export type PglitePoolOptions = Omit<PGliteOptions, 'dataDir'>;
|
|
|
26
26
|
* The cost is that PGlite cannot see the transaction, so it flushes to the filesystem after each
|
|
27
27
|
* statement within one: pass `relaxedDurability: true` on a persistent `dataDir` to skip waiting on
|
|
28
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]`.
|
|
29
34
|
*/
|
|
30
|
-
export declare class PgliteQuerierPool extends AbstractSharedHandleQuerierPool<PgliteDatabase, PgliteQuerier,
|
|
35
|
+
export declare class PgliteQuerierPool extends AbstractSharedHandleQuerierPool<PgliteDatabase, PgliteQuerier, PostgresDialect> {
|
|
31
36
|
readonly dataDir: string;
|
|
32
37
|
readonly opts?: PglitePoolOptions | undefined;
|
|
33
38
|
constructor(dataDir?: string, opts?: PglitePoolOptions | undefined, extra?: ExtraOptions);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
2
|
+
import { PostgresDialect } from '../postgres/postgresDialect.js';
|
|
2
3
|
import { AbstractSharedHandleQuerierPool } from '../querier/abstractSharedHandleQuerierPool.js';
|
|
3
|
-
import {
|
|
4
|
+
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
4
5
|
import { PgliteQuerier } from './pgliteQuerier.js';
|
|
5
6
|
/**
|
|
6
7
|
* Pool for PGlite, Postgres compiled to WASM and run in this process. No server, no container.
|
|
@@ -16,20 +17,29 @@ import { PgliteQuerier } from './pgliteQuerier.js';
|
|
|
16
17
|
* The cost is that PGlite cannot see the transaction, so it flushes to the filesystem after each
|
|
17
18
|
* statement within one: pass `relaxedDurability: true` on a persistent `dataDir` to skip waiting on
|
|
18
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]`.
|
|
19
25
|
*/
|
|
20
26
|
export class PgliteQuerierPool extends AbstractSharedHandleQuerierPool {
|
|
21
27
|
dataDir;
|
|
22
28
|
opts;
|
|
23
29
|
constructor(dataDir = 'memory://', opts, extra) {
|
|
24
|
-
super(new
|
|
30
|
+
super(new PostgresDialect(dialectOptionsFrom(extra)), extra);
|
|
25
31
|
this.dataDir = dataDir;
|
|
26
32
|
this.opts = opts;
|
|
27
33
|
}
|
|
28
34
|
async openDb() {
|
|
29
|
-
const { PGlite } = await import('@electric-sql/pglite');
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
35
|
+
const { PGlite, types } = await import('@electric-sql/pglite');
|
|
36
|
+
// INT8 by the one wide-integer rule, where PGlite's own answers a `bigint` past 2^53; a caller's own
|
|
37
|
+
// `parsers` still win. The declared return type is what checks {@link PgliteDatabase} against the
|
|
38
|
+
// real driver, so no cast is needed here or anywhere below it.
|
|
39
|
+
return PGlite.create(this.dataDir, {
|
|
40
|
+
...this.opts,
|
|
41
|
+
parsers: { [types.INT8]: decodeWideNumber, ...this.opts?.parsers },
|
|
42
|
+
});
|
|
33
43
|
}
|
|
34
44
|
buildQuerier(db) {
|
|
35
45
|
return new PgliteQuerier(db, this.dialect, this.extra);
|
|
@@ -2,26 +2,22 @@ import type { AbstractSqlDialect } from '../dialect/index.js';
|
|
|
2
2
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
3
3
|
import type { ExtraOptions } from '../type/index.js';
|
|
4
4
|
import { type ErrorEmittingPool } from '../util/index.js';
|
|
5
|
-
import
|
|
5
|
+
import { type PgAnyClient, PgQuerier } from './pgQuerier.js';
|
|
6
6
|
export interface PgAnyPool<C extends PgAnyClient> extends ErrorEmittingPool {
|
|
7
7
|
connect: () => Promise<C>;
|
|
8
8
|
end: () => Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Shared base class for Postgres-compatible querier pools.
|
|
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.
|
|
12
13
|
*
|
|
13
|
-
* Wires the crash-preventing error handler here, once, so a new pg-compatible
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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.
|
|
16
17
|
*/
|
|
17
|
-
export declare abstract class AbstractPgQuerierPool<C extends PgAnyClient,
|
|
18
|
+
export declare abstract class AbstractPgQuerierPool<C extends PgAnyClient, D extends AbstractSqlDialect> extends AbstractSqlQuerierPool<PgQuerier<C>, D> {
|
|
18
19
|
readonly pool: PgAnyPool<C>;
|
|
19
20
|
constructor(dialect: D, pool: PgAnyPool<C>, extra?: ExtraOptions);
|
|
20
|
-
|
|
21
|
-
* Every pg-compatible pool acquires a client the same way, so only the querier class varies.
|
|
22
|
-
* Subclasses name that instead of restating the lazy `connect` the querier expects.
|
|
23
|
-
*/
|
|
24
|
-
protected abstract buildQuerier(connect: () => Promise<C>): Q;
|
|
25
|
-
getQuerier(): Promise<Q>;
|
|
21
|
+
getQuerier(): Promise<PgQuerier<C>>;
|
|
26
22
|
end(): Promise<void>;
|
|
27
23
|
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
2
2
|
import { attachPoolErrorHandler } from '../util/index.js';
|
|
3
|
+
import { PgQuerier } from './pgQuerier.js';
|
|
3
4
|
/**
|
|
4
|
-
* Shared base class for Postgres-compatible querier pools.
|
|
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.
|
|
5
7
|
*
|
|
6
|
-
* Wires the crash-preventing error handler here, once, so a new pg-compatible
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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.
|
|
9
11
|
*/
|
|
10
12
|
export class AbstractPgQuerierPool extends AbstractSqlQuerierPool {
|
|
11
13
|
pool;
|
|
12
14
|
constructor(dialect, pool, extra) {
|
|
13
15
|
super(dialect, extra);
|
|
14
16
|
this.pool = pool;
|
|
15
|
-
attachPoolErrorHandler(pool, 'Idle Postgres pool client encountered an error');
|
|
17
|
+
attachPoolErrorHandler(pool, 'Idle Postgres pool client encountered an error', extra?.logger);
|
|
16
18
|
}
|
|
17
19
|
async getQuerier() {
|
|
18
|
-
return
|
|
20
|
+
return new PgQuerier(() => this.pool.connect(), this.dialect, this.extra);
|
|
19
21
|
}
|
|
20
22
|
async end() {
|
|
21
23
|
await this.pool.end();
|
package/dist/postgres/index.d.ts
CHANGED
package/dist/postgres/index.js
CHANGED
|
@@ -10,7 +10,8 @@ type PgTypes = {
|
|
|
10
10
|
getTypeParser(oid: number, format?: 'text' | 'binary'): (value: string) => unknown;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* Decode `INT8` and `FLOAT8
|
|
13
|
+
* Decode `INT8` and `FLOAT8`, leaving every other type to the driver: an INT8 by `decodeWideNumber` - a
|
|
14
|
+
* number where one is exact, its exact text past 2^53 - and a FLOAT8 as the float64 it already is.
|
|
14
15
|
*
|
|
15
16
|
* uql owes this to the caller because uql picks the column: `type: Number` maps to BIGINT (see
|
|
16
17
|
* `schema/canonicalType.ts`), so without it a field declared `number` read back as `'9'` - including
|
|
@@ -32,10 +33,9 @@ type PgTypes = {
|
|
|
32
33
|
* `types.setTypeParser` calls in `neon/neonQuerier.test.ts` - and both made the suite pass on
|
|
33
34
|
* behaviour the library never shipped. Do not reintroduce one.
|
|
34
35
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* keeps the column DECIMAL while leaving the value as the exact text the driver returned.
|
|
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.
|
|
39
39
|
*/
|
|
40
40
|
export declare function numericTypes(types: PgTypes): CustomTypesConfig;
|
|
41
41
|
export {};
|