uql-orm 0.54.0 → 0.56.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 +2 -2
- package/dist/browser/uql-browser.min.js.map +4 -4
- 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/mysqlLikeSqlDialect.js +2 -3
- package/dist/dialect/pgLikeSqlDialect.d.ts +5 -0
- package/dist/dialect/pgLikeSqlDialect.js +14 -4
- package/dist/dialect/queryJoins.js +2 -4
- package/dist/entity/index.d.ts +1 -1
- package/dist/entity/index.js +1 -1
- package/dist/entity/metadata/definition.d.ts +5 -1
- package/dist/entity/metadata/definition.js +32 -26
- 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/builder/splitSqlStatements.js +2 -2
- package/dist/migrate/cli.js +2 -9
- package/dist/migrate/codegen/fieldOptionsSource.js +1 -1
- package/dist/migrate/ddl/index.d.ts +3 -3
- package/dist/migrate/ddl/index.js +3 -3
- package/dist/migrate/ddl/pgIndexDdl.d.ts +5 -0
- package/dist/migrate/ddl/pgIndexDdl.js +9 -0
- package/dist/migrate/drift/driftDetector.js +21 -8
- package/dist/migrate/generator/mongoSchemaGenerator.js +1 -1
- package/dist/migrate/introspection/baseSqlIntrospector.d.ts +1 -1
- package/dist/migrate/introspection/baseSqlIntrospector.js +65 -76
- package/dist/migrate/introspection/mssqlIntrospector.js +2 -1
- package/dist/migrate/introspection/mysqlIntrospector.js +5 -8
- package/dist/migrate/introspection/sqliteIntrospector.js +2 -5
- package/dist/migrate/migrator.d.ts +5 -2
- package/dist/migrate/migrator.js +9 -14
- package/dist/migrate/schemaGenerator.js +2 -6
- package/dist/mongo/index.d.ts +0 -1
- package/dist/mongo/index.js +0 -1
- package/dist/mongo/mongoDialect.d.ts +1 -2
- package/dist/mongo/mongoDialect.js +7 -21
- package/dist/mongo/mongodbQuerier.js +12 -11
- 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/abstractQuerier.js +17 -22
- package/dist/querier/abstractSqlQuerier.d.ts +21 -12
- package/dist/querier/abstractSqlQuerier.js +61 -43
- package/dist/schema/canonicalType.js +0 -2
- package/dist/schema/dependencyGraph.js +2 -4
- package/dist/schema/indexDifferences.js +2 -2
- package/dist/schema/schemaASTBuilder.js +3 -10
- package/dist/schema/schemaASTDiffer.d.ts +10 -2
- package/dist/schema/schemaASTDiffer.js +12 -11
- package/dist/schema/types.d.ts +1 -1
- 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/sqliteDialect.js +2 -1
- 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 +8 -2
- package/dist/util/dialect.util.js +20 -1
- package/dist/util/logger.d.ts +17 -9
- package/dist/util/logger.js +36 -11
- package/dist/util/object.util.d.ts +2 -0
- package/dist/util/object.util.js +4 -0
- package/dist/util/raw.js +3 -3
- package/dist/util/relationQuery.util.d.ts +3 -3
- package/dist/util/relationQuery.util.js +8 -2
- 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
|
@@ -7,6 +7,13 @@ import { SqliteDialect } from '../sqlite/sqliteDialect.js';
|
|
|
7
7
|
export class D1SqliteDialect extends SqliteDialect {
|
|
8
8
|
// Cloudflare D1 caps bound parameters at 100 per query.
|
|
9
9
|
maxBindValues = 100;
|
|
10
|
+
/**
|
|
11
|
+
* D1's Worker API refuses a `bigint` bind ([workerd#4195](https://github.com/cloudflare/workerd/issues/4195)),
|
|
12
|
+
* so one goes as its exact text, which SQLite's INTEGER affinity stores as the same integer.
|
|
13
|
+
*/
|
|
14
|
+
normalizeValue(value) {
|
|
15
|
+
return typeof value === 'bigint' ? String(value) : super.normalizeValue(value);
|
|
16
|
+
}
|
|
10
17
|
/**
|
|
11
18
|
* D1 loads no extensions (its allowlist is FTS5, JSON and the math functions) and has no vector
|
|
12
19
|
* functions of its own, so the sqlite-vec names inherited from {@link SqliteDialect} would compile
|
|
@@ -84,6 +84,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
|
|
|
84
84
|
* shared for the same reason - see {@link SqlQueryContext}.
|
|
85
85
|
*/
|
|
86
86
|
protected buildFragment(ctx: QueryContext, build: QueryBuildFn): string;
|
|
87
|
+
/** A `raw()` operand, rendered in place: bound, it would reach the driver as the object itself. */
|
|
88
|
+
protected rawFragment(ctx: QueryContext, value: QueryRaw): string;
|
|
87
89
|
/**
|
|
88
90
|
* Each operand rendered into its own fragment, keeping only those that emitted SQL.
|
|
89
91
|
*
|
|
@@ -95,10 +97,9 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
|
|
|
95
97
|
protected renderOperands<T>(ctx: QueryContext, operands: readonly T[], render: (ctx: QueryContext, operand: T) => void): string[];
|
|
96
98
|
addValue(values: unknown[], value: unknown): string;
|
|
97
99
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* Postgres overrides to pass objects through to its native JSONB driver.
|
|
100
|
+
* A parameter value as this engine's driver takes it: a boolean as the integer an engine with no
|
|
101
|
+
* boolean type stores, and everything else as it is - a `bigint` included, which every driver here
|
|
102
|
+
* binds exactly, where a number would round it past 2^53. A driver that refuses one (D1) overrides.
|
|
102
103
|
*/
|
|
103
104
|
normalizeValue(value: unknown): unknown;
|
|
104
105
|
/**
|
|
@@ -354,10 +355,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
|
|
|
354
355
|
* caller reached for this to avoid, and only say so by taking a long time.
|
|
355
356
|
*/
|
|
356
357
|
estimatedCount<E>(_ctx: QueryContext, _entity: Type<E>): void;
|
|
357
|
-
/** `$group` aggregate operator
|
|
358
|
-
|
|
359
|
-
* through as a raw SQL function name. */
|
|
360
|
-
private static readonly AGGREGATE_FN_MAP;
|
|
358
|
+
/** `$group` aggregate operator to SQL function name, over ops `resolveAggregateOp` has already allowlisted. */
|
|
359
|
+
private static readonly AGGREGATE_FN;
|
|
361
360
|
aggregate<E, G extends QueryGroupMap<E>, A extends QueryAggMap<E>>(ctx: QueryContext, entity: Type<E>, q: QueryAggregate<E, G, A>, opts?: QueryOptions): void;
|
|
362
361
|
/**
|
|
363
362
|
* ORDER BY for aggregate queries - handles both entity-field and alias references. A grouped
|
|
@@ -658,6 +657,7 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
|
|
|
658
657
|
* Postgres overrides to use `= ANY($1)` / `<> ALL($1)` with a single array parameter.
|
|
659
658
|
*/
|
|
660
659
|
protected formatIn(ctx: QueryContext, values: unknown[], negate: boolean): string;
|
|
661
|
-
|
|
660
|
+
/** Reads extracted JSON text as a number, which every engine spells its own way. */
|
|
661
|
+
protected abstract numericCast(expr: string): string;
|
|
662
662
|
toString(): string;
|
|
663
663
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMeta, soleIdOf } from '../entity/index.js';
|
|
1
|
+
import { fieldOf, getMeta, soleIdOf } from '../entity/index.js';
|
|
2
2
|
import { parseQueryLock, QueryRaw, RAW_ALIAS, RAW_VALUE, VECTOR_QUERY_KEYS, } from '../type/index.js';
|
|
3
3
|
import { isInlinedExpression } from '../util/field.util.js';
|
|
4
4
|
import { asSelectMap, assertNonNegativeInteger, escapeSqlId, fillOnFields, filterFieldKeys, getInsertFieldKeys, getKeys, getSoftDeleteValue, hasKeys, columnFamily, isJsonUpdateOp, isOperatorMap, isOperatorObject, isOperatorOnlyObject, isVectorSearch, normalizeScalarFieldSelection, parentJoins, targetKeyColumns, parseGroupMap, parseRelationSize, parseSortByCount, populatesRelations, queryChildrenOf, raw, someValue, throwUnknownAggregateColumn, withoutSoftDeleteFilter, } from '../util/index.js';
|
|
@@ -10,6 +10,13 @@ import { SqlQueryContext } from './queryContext.js';
|
|
|
10
10
|
import { NO_JOINS, resolveQueryJoins, resolveSortableJoin, } from './queryJoins.js';
|
|
11
11
|
import { resolveVectorCast } from './vectorCast.js';
|
|
12
12
|
import { VectorSqlDialect } from './vectorSqlDialect.js';
|
|
13
|
+
/** An `$in`/`$nin` operand, which the types require to be an array but `/http` hands over untyped. */
|
|
14
|
+
function inOperands(op, value) {
|
|
15
|
+
if (!Array.isArray(value)) {
|
|
16
|
+
throw TypeError(`${op} expects an array, got ${value === null ? 'null' : typeof value}`);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
13
20
|
export class AbstractSqlDialect extends VectorSqlDialect {
|
|
14
21
|
/**
|
|
15
22
|
* Whether {@link autoIncrementSuffix} states `PRIMARY KEY` itself, so the table must not state it again.
|
|
@@ -99,6 +106,10 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
99
106
|
build(fragmentCtx);
|
|
100
107
|
return fragmentCtx.sql;
|
|
101
108
|
}
|
|
109
|
+
/** A `raw()` operand, rendered in place: bound, it would reach the driver as the object itself. */
|
|
110
|
+
rawFragment(ctx, value) {
|
|
111
|
+
return this.buildFragment(ctx, (fragmentCtx) => this.getRawValue(fragmentCtx, { value }));
|
|
112
|
+
}
|
|
102
113
|
/**
|
|
103
114
|
* Each operand rendered into its own fragment, keeping only those that emitted SQL.
|
|
104
115
|
*
|
|
@@ -117,20 +128,13 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
117
128
|
return this.placeholder(values.length);
|
|
118
129
|
}
|
|
119
130
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* Postgres overrides to pass objects through to its native JSONB driver.
|
|
131
|
+
* A parameter value as this engine's driver takes it: a boolean as the integer an engine with no
|
|
132
|
+
* boolean type stores, and everything else as it is - a `bigint` included, which every driver here
|
|
133
|
+
* binds exactly, where a number would round it past 2^53. A driver that refuses one (D1) overrides.
|
|
124
134
|
*/
|
|
125
135
|
normalizeValue(value) {
|
|
126
|
-
if (
|
|
127
|
-
return value;
|
|
128
|
-
}
|
|
129
|
-
if (typeof value === 'bigint') {
|
|
130
|
-
return Number(value);
|
|
131
|
-
}
|
|
132
|
-
if (typeof value === 'boolean') {
|
|
133
|
-
return this.booleanLiteral === 'native' ? value : value ? 1 : 0;
|
|
136
|
+
if (typeof value === 'boolean' && this.booleanLiteral !== 'native') {
|
|
137
|
+
return value ? 1 : 0;
|
|
134
138
|
}
|
|
135
139
|
return value;
|
|
136
140
|
}
|
|
@@ -198,9 +202,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
198
202
|
});
|
|
199
203
|
}
|
|
200
204
|
else {
|
|
201
|
-
const field = meta
|
|
202
|
-
if (!field)
|
|
203
|
-
return;
|
|
205
|
+
const field = fieldOf(meta, key);
|
|
204
206
|
if (isInlinedExpression(field)) {
|
|
205
207
|
// Qualified even when nothing else in this statement is: the expression is spliced in, and
|
|
206
208
|
// one that opens a correlated subquery has the inner table's columns in scope, so a bare
|
|
@@ -427,7 +429,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
427
429
|
if (entry instanceof QueryRaw) {
|
|
428
430
|
this.getRawValue(fragmentCtx, { value: entry });
|
|
429
431
|
}
|
|
430
|
-
else
|
|
432
|
+
else {
|
|
431
433
|
this.renderWhere(fragmentCtx, entity, entry, { prefix: opts.prefix, operand: childOperand, clause: false });
|
|
432
434
|
}
|
|
433
435
|
});
|
|
@@ -589,13 +591,8 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
589
591
|
case '$regex':
|
|
590
592
|
return this.regexCondition(operand, this.addValue(ctx.values, val));
|
|
591
593
|
case '$in':
|
|
592
|
-
case '$nin':
|
|
593
|
-
|
|
594
|
-
// Not covered by the types: `/http` casts client JSON straight to `Query`, so this arrives untyped.
|
|
595
|
-
throw TypeError(`${op} expects an array, got ${val === null ? 'null' : typeof val}`);
|
|
596
|
-
}
|
|
597
|
-
return operand + this.formatIn(ctx, val, op === '$nin');
|
|
598
|
-
}
|
|
594
|
+
case '$nin':
|
|
595
|
+
return operand + this.formatIn(ctx, inOperands(op, val), op === '$nin');
|
|
599
596
|
case '$between': {
|
|
600
597
|
const [min, max] = val;
|
|
601
598
|
return `${operand} BETWEEN ${this.addValue(ctx.values, min)} AND ${this.addValue(ctx.values, max)}`;
|
|
@@ -663,7 +660,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
663
660
|
}
|
|
664
661
|
}
|
|
665
662
|
jsonInNin(ctx, jsonField, comparand, op, value, asJson) {
|
|
666
|
-
const values =
|
|
663
|
+
const values = inOperands(op, value);
|
|
667
664
|
const negate = op === '$nin';
|
|
668
665
|
if (!asJson) {
|
|
669
666
|
return `${comparand(values)}${this.formatIn(ctx, values, negate)}`;
|
|
@@ -739,7 +736,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
739
736
|
*/
|
|
740
737
|
jsonScalarParam(ctx, value) {
|
|
741
738
|
if (value instanceof QueryRaw) {
|
|
742
|
-
return this.
|
|
739
|
+
return this.rawFragment(ctx, value);
|
|
743
740
|
}
|
|
744
741
|
ctx.pushValue(JSON.stringify(value));
|
|
745
742
|
// The placeholder for the value just pushed, so a named or numbered one is spelled correctly.
|
|
@@ -917,16 +914,14 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
917
914
|
estimatedCount(_ctx, _entity) {
|
|
918
915
|
throw new TypeError(`${this.dialectName} does not support estimatedCount`);
|
|
919
916
|
}
|
|
920
|
-
/** `$group` aggregate operator
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
['$max', 'MAX'],
|
|
929
|
-
]);
|
|
917
|
+
/** `$group` aggregate operator to SQL function name, over ops `resolveAggregateOp` has already allowlisted. */
|
|
918
|
+
static AGGREGATE_FN = {
|
|
919
|
+
$count: 'COUNT',
|
|
920
|
+
$sum: 'SUM',
|
|
921
|
+
$avg: 'AVG',
|
|
922
|
+
$min: 'MIN',
|
|
923
|
+
$max: 'MAX',
|
|
924
|
+
};
|
|
930
925
|
aggregate(ctx, entity, q, opts = {}) {
|
|
931
926
|
const meta = getMeta(entity);
|
|
932
927
|
const tableName = this.escapedTableName(meta);
|
|
@@ -946,10 +941,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
946
941
|
selectParts.push(columnName !== entry.alias ? `${escaped} ${this.escapeId(entry.alias)}` : escaped);
|
|
947
942
|
}
|
|
948
943
|
else {
|
|
949
|
-
const sqlFn = AbstractSqlDialect.
|
|
950
|
-
if (!sqlFn) {
|
|
951
|
-
throw TypeError(`unsupported aggregate operator: ${entry.op}`);
|
|
952
|
-
}
|
|
944
|
+
const sqlFn = AbstractSqlDialect.AGGREGATE_FN[entry.op];
|
|
953
945
|
const sqlArg = entry.fieldRef === '*' ? '*' : this.escapeId(this.columnOf(meta, entry.fieldRef));
|
|
954
946
|
const expr = `${sqlFn}(${entry.distinct ? 'DISTINCT ' : ''}${sqlArg})`;
|
|
955
947
|
emittedColumns[entry.alias] = expr;
|
|
@@ -1238,14 +1230,12 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
1238
1230
|
// Soft-delete (stamp only live rows) unless `hardDelete` is requested or the entity has no
|
|
1239
1231
|
// soft-delete field (e.g. a cascade onto a non-soft-deletable child).
|
|
1240
1232
|
if (!opts.hardDelete && meta.softDelete) {
|
|
1241
|
-
const field = meta
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
return;
|
|
1248
|
-
}
|
|
1233
|
+
const field = fieldOf(meta, meta.softDelete);
|
|
1234
|
+
const columnName = this.resolveColumnName(meta.softDelete, field);
|
|
1235
|
+
ctx.append(`UPDATE ${tableName} SET ${this.escapeId(columnName)} = `);
|
|
1236
|
+
this.formatPersistableValue(ctx, field, getSoftDeleteValue(field));
|
|
1237
|
+
this.search(ctx, entity, q, opts);
|
|
1238
|
+
return;
|
|
1249
1239
|
}
|
|
1250
1240
|
// Hard delete removes matching rows regardless of soft-delete state (keeps other filters, e.g. tenant).
|
|
1251
1241
|
// Only rewrite the filters when there is a soft-delete filter to disable.
|
|
@@ -1764,9 +1754,6 @@ export class AbstractSqlDialect extends VectorSqlDialect {
|
|
|
1764
1754
|
const phs = values.map((v) => this.addValue(ctx.values, v)).join(', ');
|
|
1765
1755
|
return ` ${negate ? 'NOT IN' : 'IN'} (${phs})`;
|
|
1766
1756
|
}
|
|
1767
|
-
numericCast(expr) {
|
|
1768
|
-
return expr;
|
|
1769
|
-
}
|
|
1770
1757
|
toString() {
|
|
1771
1758
|
return this.dialectName;
|
|
1772
1759
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeWideNumber } from '../util/wideNumber.js';
|
|
1
2
|
import { parseVectorLiteral } from './vectorCast.js';
|
|
2
3
|
/**
|
|
3
4
|
* Decode one non-null cell. Kept beside {@link HydrateKind} rather than inlined into the querier's
|
|
@@ -31,8 +32,7 @@ export function decodeColumn(value, kind) {
|
|
|
31
32
|
return value;
|
|
32
33
|
}
|
|
33
34
|
if (kind === 'number') {
|
|
34
|
-
|
|
35
|
-
return Number.isNaN(decoded) ? value : decoded;
|
|
35
|
+
return Number.isNaN(Number(text)) ? value : decodeWideNumber(text);
|
|
36
36
|
}
|
|
37
37
|
if (kind === 'json') {
|
|
38
38
|
try {
|
|
@@ -38,8 +38,8 @@ export declare abstract class MergeSqlDialect extends AbstractSqlDialect {
|
|
|
38
38
|
* holds it across both. Empty on Oracle, which does not have the hint and does not need it.
|
|
39
39
|
*/
|
|
40
40
|
protected readonly mergeTargetHint: string;
|
|
41
|
-
/** How the merge reports the row it wrote
|
|
42
|
-
protected mergeReturning(expression: string): string;
|
|
41
|
+
/** How the merge reports the row it wrote: SQL Server's `OUTPUT`. Oracle has no such clause on a `MERGE`. */
|
|
42
|
+
protected abstract mergeReturning(expression: string): string;
|
|
43
43
|
/** `MERGE` must be terminated on SQL Server; nothing else here cares. */
|
|
44
44
|
protected readonly statementTerminator: string;
|
|
45
45
|
}
|
|
@@ -80,10 +80,6 @@ export class MergeSqlDialect extends AbstractSqlDialect {
|
|
|
80
80
|
* holds it across both. Empty on Oracle, which does not have the hint and does not need it.
|
|
81
81
|
*/
|
|
82
82
|
mergeTargetHint = '';
|
|
83
|
-
/** How the merge reports the row it wrote. Oracle has no such clause on a `MERGE` and omits it. */
|
|
84
|
-
mergeReturning(expression) {
|
|
85
|
-
return `RETURNING ${expression}`;
|
|
86
|
-
}
|
|
87
83
|
/** `MERGE` must be terminated on SQL Server; nothing else here cares. */
|
|
88
84
|
statementTerminator = '';
|
|
89
85
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getMeta } from '../entity/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { textSearchFields } from '../util/index.js';
|
|
3
3
|
import { escapeMysqlSqlLiteral, escapeSingleQuotes } from '../util/sqlLiteral.js';
|
|
4
4
|
import { AbstractSqlDialect } from './abstractSqlDialect.js';
|
|
5
5
|
import { COUNT_ALIAS, JSON_PULL_ALIAS } from './aliases.js';
|
|
@@ -135,8 +135,7 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
|
|
|
135
135
|
* `@Index([...], { type: 'fulltext' })`.
|
|
136
136
|
*/
|
|
137
137
|
appendTextSearch(ctx, _entity, meta, search) {
|
|
138
|
-
const
|
|
139
|
-
const columns = searchFields.map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])));
|
|
138
|
+
const columns = textSearchFields(meta, search).map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])));
|
|
140
139
|
ctx.append(`MATCH(${columns.join(', ')}) AGAINST(`);
|
|
141
140
|
ctx.addValue(search.$value);
|
|
142
141
|
ctx.append(')');
|
|
@@ -93,6 +93,11 @@ export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
|
|
|
93
93
|
* ORDINALITY` keeps the surviving elements in their original order.
|
|
94
94
|
*/
|
|
95
95
|
protected jsonPullKey(ctx: QueryContext, expr: string, escapedCol: string, key: string, value: unknown): string;
|
|
96
|
+
/**
|
|
97
|
+
* The plain values merge as one bound object; a `raw()` one is an SQL expression rather than JSON,
|
|
98
|
+
* so it merges through `JSONB_BUILD_OBJECT` and is evaluated in place - stringified with the rest,
|
|
99
|
+
* it would land as `{}`.
|
|
100
|
+
*/
|
|
96
101
|
protected jsonSet(ctx: QueryContext, expr: string, set: Record<string, unknown>, field?: FieldOptions): string;
|
|
97
102
|
/** The only fragment that references `expr` twice - safe here because placeholders are numbered. */
|
|
98
103
|
protected jsonPush(ctx: QueryContext, expr: string, push: Record<string, unknown>): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { canonicalToSql, fieldOptionsToCanonical } from '../schema/canonicalType.js';
|
|
2
2
|
import { QueryRaw, } from '../type/index.js';
|
|
3
|
-
import { hasVectorNear } from '../util/dialect.util.js';
|
|
3
|
+
import { hasVectorNear, textSearchFields } from '../util/dialect.util.js';
|
|
4
4
|
import { raw } from '../util/raw.js';
|
|
5
5
|
import { queryNarrowedTo } from '../util/relationQuery.util.js';
|
|
6
6
|
import { escapeSingleQuotes } from '../util/sqlLiteral.js';
|
|
@@ -147,7 +147,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
|
|
|
147
147
|
* rejects anything unparseable - including a plain two-word search.
|
|
148
148
|
*/
|
|
149
149
|
appendTextSearch(ctx, _entity, meta, search) {
|
|
150
|
-
const fields = (search
|
|
150
|
+
const fields = textSearchFields(meta, search)
|
|
151
151
|
.map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])))
|
|
152
152
|
.join(` || ' ' || `);
|
|
153
153
|
// The config is bound once and its numbered placeholder reused by both calls.
|
|
@@ -213,8 +213,18 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
|
|
|
213
213
|
const kept = `SELECT JSONB_AGG(${JSON_PULL_ALIAS}.val ORDER BY ${JSON_PULL_ALIAS}.ord) FROM JSONB_ARRAY_ELEMENTS(${escapedCol}->'${escapedKey}') WITH ORDINALITY AS ${JSON_PULL_ALIAS}(val, ord) WHERE ${JSON_PULL_ALIAS}.val <> ${this.jsonVal(ctx, value)}`;
|
|
214
214
|
return `JSONB_SET(${expr}, '{${escapedKey}}', COALESCE((${kept}), '[]'::jsonb), false)`;
|
|
215
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* The plain values merge as one bound object; a `raw()` one is an SQL expression rather than JSON,
|
|
218
|
+
* so it merges through `JSONB_BUILD_OBJECT` and is evaluated in place - stringified with the rest,
|
|
219
|
+
* it would land as `{}`.
|
|
220
|
+
*/
|
|
216
221
|
jsonSet(ctx, expr, set, field) {
|
|
217
|
-
|
|
222
|
+
const entries = Object.entries(set);
|
|
223
|
+
const merged = this.jsonVal(ctx, Object.fromEntries(entries.filter(([, value]) => !(value instanceof QueryRaw))));
|
|
224
|
+
const raws = entries.flatMap(([key, value]) => value instanceof QueryRaw
|
|
225
|
+
? [` || JSONB_BUILD_OBJECT('${escapeSingleQuotes(key)}', ${this.rawFragment(ctx, value)})`]
|
|
226
|
+
: []);
|
|
227
|
+
return `${jsonSetTarget(expr, field, `'{}'::jsonb`)} || ${merged}${raws.join('')}`;
|
|
218
228
|
}
|
|
219
229
|
/** The only fragment that references `expr` twice - safe here because placeholders are numbered. */
|
|
220
230
|
jsonPush(ctx, expr, push) {
|
|
@@ -236,7 +246,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
|
|
|
236
246
|
*/
|
|
237
247
|
jsonVal(ctx, value, type = 'jsonb') {
|
|
238
248
|
if (value instanceof QueryRaw)
|
|
239
|
-
return this.
|
|
249
|
+
return this.rawFragment(ctx, value);
|
|
240
250
|
if (value == null)
|
|
241
251
|
return `${this.addValue(ctx.values, null)}::${type}`;
|
|
242
252
|
const json = JSON.stringify(value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMeta } from '../entity/index.js';
|
|
1
|
+
import { getMeta, relationOf } from '../entity/index.js';
|
|
2
2
|
import { getKeys, getRelationRequestSummary, isToManyRelation, parseRelationAtKey, } from '../util/index.js';
|
|
3
3
|
export const NO_JOINS = new Map();
|
|
4
4
|
/**
|
|
@@ -54,9 +54,7 @@ function addJoin(joins, parent, key, relation, query, required, projected) {
|
|
|
54
54
|
}
|
|
55
55
|
function addPopulateJoins(joins, meta, populate, parent) {
|
|
56
56
|
for (const key of getRelationRequestSummary(meta, populate).joinableKeys) {
|
|
57
|
-
const relation = meta
|
|
58
|
-
if (!relation)
|
|
59
|
-
continue;
|
|
57
|
+
const relation = relationOf(meta, key);
|
|
60
58
|
const { query, required } = parseRelationAtKey(key, populate);
|
|
61
59
|
const join = addJoin(joins, parent, key, relation, query, required, true);
|
|
62
60
|
addPopulateJoins(joins, join.meta, query.$populate, join);
|
package/dist/entity/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './decorator/entity.js';
|
|
2
2
|
export * from './decorator/members.js';
|
|
3
|
-
export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, idOf, namesKey, soleIdOf, } from './metadata/definition.js';
|
|
3
|
+
export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, fieldOf, idOf, namesKey, relationOf, soleIdOf, } from './metadata/definition.js';
|
package/dist/entity/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './decorator/entity.js';
|
|
2
2
|
export * from './decorator/members.js';
|
|
3
|
-
export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, idOf, namesKey, soleIdOf, } from './metadata/definition.js';
|
|
3
|
+
export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, fieldOf, idOf, namesKey, relationOf, soleIdOf, } from './metadata/definition.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityData, EntityIndexInput, EntityMembers, EntityMeta, EntityOptions, FieldKey, FieldOptions, FilterOptions, HookEvent, IdKey, RelationOptions, Type, WrittenId } from '../../type/index.js';
|
|
1
|
+
import type { EntityData, EntityIndexInput, EntityMembers, EntityMeta, EntityOptions, FieldKey, FieldMeta, FieldOptions, FilterOptions, HookEvent, IdKey, RelationKey, RelationMeta, RelationOptions, Type, WrittenId } from '../../type/index.js';
|
|
2
2
|
export declare function defineField<E>(entity: Type<E>, key: string, opts?: FieldOptions): EntityMeta<E>;
|
|
3
3
|
export declare function defineId<E>(entity: Type<E>, key: string, opts: FieldOptions): EntityMeta<E>;
|
|
4
4
|
export declare function defineRelation<E>(entity: Type<E>, key: string, opts: RelationOptions): EntityMeta<E>;
|
|
@@ -30,6 +30,10 @@ export declare function defineEntity<E>(entity: Type<E>, opts?: EntityOptions<E>
|
|
|
30
30
|
export declare function assertSoleId<E>(meta: EntityMeta<E>, what: string): void;
|
|
31
31
|
/** The entity's one primary key, for a path that cannot express a composite. See {@link assertSoleId}. */
|
|
32
32
|
export declare function soleIdOf<E>(meta: EntityMeta<E>, what: string): IdKey<E>;
|
|
33
|
+
/** The field `key` names, for a caller that took `key` from the metadata itself. */
|
|
34
|
+
export declare function fieldOf<E>(meta: EntityMeta<E>, key: FieldKey<E>): FieldMeta;
|
|
35
|
+
/** The relation `key` names, for a caller that took `key` from the metadata itself. */
|
|
36
|
+
export declare function relationOf<E>(meta: EntityMeta<E>, key: RelationKey<E>): RelationMeta;
|
|
33
37
|
/**
|
|
34
38
|
* Whether the caller named every column of the row's primary key, so {@link idOf} can name the row.
|
|
35
39
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SOFT_DELETE_FILTER } from '../../type/index.js';
|
|
2
2
|
import { isInlinedExpression } from '../../util/field.util.js';
|
|
3
|
-
import { entityName, fieldOptionConflict, getKeys, ddlText, hasKeys, isToManyRelation, lowerFirst, normalizeIndexColumn, upperFirst, } from '../../util/index.js';
|
|
3
|
+
import { entityName, fieldOptionConflict, getKeys, ddlText, hasKeys, isToManyRelation, lowerFirst, normalizeIndexColumn, upperFirst, definedEntries, } from '../../util/index.js';
|
|
4
4
|
import { ownRegistrations } from '../decorator/bag.js';
|
|
5
5
|
/**
|
|
6
6
|
* A map held on `globalThis` through the global symbol registry, so a single one survives multiple
|
|
@@ -95,9 +95,7 @@ export function defineFilter(entity, name, opts) {
|
|
|
95
95
|
* API converge on one registration path before anything is finalized.
|
|
96
96
|
*/
|
|
97
97
|
export function applyMembers(entity, specs) {
|
|
98
|
-
for (const [key, spec] of
|
|
99
|
-
if (!spec)
|
|
100
|
-
continue;
|
|
98
|
+
for (const [key, spec] of definedEntries(specs?.fields ?? {})) {
|
|
101
99
|
if (spec.isId) {
|
|
102
100
|
defineId(entity, key, spec);
|
|
103
101
|
}
|
|
@@ -105,12 +103,11 @@ export function applyMembers(entity, specs) {
|
|
|
105
103
|
defineField(entity, key, spec);
|
|
106
104
|
}
|
|
107
105
|
}
|
|
108
|
-
for (const [key, spec] of
|
|
109
|
-
|
|
110
|
-
defineRelation(entity, key, spec);
|
|
106
|
+
for (const [key, spec] of definedEntries(specs?.relations ?? {})) {
|
|
107
|
+
defineRelation(entity, key, spec);
|
|
111
108
|
}
|
|
112
|
-
for (const [event, methodNames] of
|
|
113
|
-
for (const methodName of methodNames
|
|
109
|
+
for (const [event, methodNames] of definedEntries(specs?.hooks ?? {})) {
|
|
110
|
+
for (const methodName of methodNames) {
|
|
114
111
|
defineHook(entity, methodName, event);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
@@ -143,9 +140,8 @@ export function defineEntity(entity, opts = {}) {
|
|
|
143
140
|
for (const index of opts.indexes ?? []) {
|
|
144
141
|
defineIndex(entity, index);
|
|
145
142
|
}
|
|
146
|
-
for (const [name, filter] of
|
|
147
|
-
|
|
148
|
-
defineFilter(entity, name, filter);
|
|
143
|
+
for (const [name, filter] of definedEntries(opts.filters ?? {})) {
|
|
144
|
+
defineFilter(entity, name, filter);
|
|
149
145
|
}
|
|
150
146
|
if (!hasKeys(meta.fields)) {
|
|
151
147
|
throw TypeError(`'${entity.name}' must have fields`);
|
|
@@ -219,6 +215,22 @@ export function soleIdOf(meta, what) {
|
|
|
219
215
|
assertSoleId(meta, what);
|
|
220
216
|
return meta.ids[0];
|
|
221
217
|
}
|
|
218
|
+
/** The field `key` names, for a caller that took `key` from the metadata itself. */
|
|
219
|
+
export function fieldOf(meta, key) {
|
|
220
|
+
const field = meta.fields[key];
|
|
221
|
+
if (!field) {
|
|
222
|
+
throw new TypeError(`'${meta.entity.name}' has no field '${key}'`);
|
|
223
|
+
}
|
|
224
|
+
return field;
|
|
225
|
+
}
|
|
226
|
+
/** The relation `key` names, for a caller that took `key` from the metadata itself. */
|
|
227
|
+
export function relationOf(meta, key) {
|
|
228
|
+
const relation = meta.relations[key];
|
|
229
|
+
if (!relation) {
|
|
230
|
+
throw new TypeError(`'${meta.entity.name}' has no relation '${key}'`);
|
|
231
|
+
}
|
|
232
|
+
return relation;
|
|
233
|
+
}
|
|
222
234
|
/**
|
|
223
235
|
* Whether the caller named every column of the row's primary key, so {@link idOf} can name the row.
|
|
224
236
|
*
|
|
@@ -295,11 +307,9 @@ export function getMeta(entity) {
|
|
|
295
307
|
return fillRelations(meta);
|
|
296
308
|
}
|
|
297
309
|
function fillRelations(meta) {
|
|
298
|
-
for (const relKey
|
|
310
|
+
for (const [relKey, relation] of definedEntries(meta.relations)) {
|
|
299
311
|
// The authored view: `mappedBy` may still be the callback and `references` unset until this settles them.
|
|
300
|
-
const relOpts =
|
|
301
|
-
if (!relOpts)
|
|
302
|
-
continue;
|
|
312
|
+
const relOpts = relation;
|
|
303
313
|
const at = `'${meta.entity.name}.${relKey}'`;
|
|
304
314
|
if (relOpts.mappedBy) {
|
|
305
315
|
fillInverseSide(at, meta, relOpts);
|
|
@@ -355,7 +365,7 @@ function fillOwningSide(at, meta, relKey, relOpts) {
|
|
|
355
365
|
for (const { local, foreign } of relOpts.references) {
|
|
356
366
|
fields[local] ??= {
|
|
357
367
|
name: local,
|
|
358
|
-
type: relMeta.
|
|
368
|
+
type: fieldOf(relMeta, foreign).type ?? Number,
|
|
359
369
|
references: relOpts.entity,
|
|
360
370
|
referencedKey: foreign,
|
|
361
371
|
typeFromReference: true,
|
|
@@ -405,9 +415,8 @@ function fillInverseSide(at, meta, relOpts) {
|
|
|
405
415
|
* own cardinality and `cascade`.
|
|
406
416
|
*/
|
|
407
417
|
function fillForeignKeyRelations(meta) {
|
|
408
|
-
const joined = new Set(
|
|
409
|
-
for (const fieldKey of
|
|
410
|
-
const references = meta.fields[fieldKey]?.references;
|
|
418
|
+
const joined = new Set(definedEntries(meta.relations).flatMap(([, relation]) => relation.references.map(({ local }) => local)));
|
|
419
|
+
for (const [fieldKey, { references }] of definedEntries(meta.fields)) {
|
|
411
420
|
if (!references || joined.has(fieldKey))
|
|
412
421
|
continue;
|
|
413
422
|
const target = ensureMeta(references());
|
|
@@ -437,7 +446,7 @@ function fillForeignKeyRelations(meta) {
|
|
|
437
446
|
}
|
|
438
447
|
/** `<entityName><IdColumn>`, not the `<relationKey>Id` an owning to-one derives: a junction row has no relation key to borrow from. */
|
|
439
448
|
function junctionColumn(meta, idKey) {
|
|
440
|
-
return lowerFirst(entityName(meta)) + upperFirst(meta.
|
|
449
|
+
return lowerFirst(entityName(meta)) + upperFirst(fieldOf(meta, idKey).name ?? idKey);
|
|
441
450
|
}
|
|
442
451
|
/** A callback only reads one property off the key map, and that property is the key, so one serves every entity. */
|
|
443
452
|
const RELATION_KEY_MAP = new Proxy({}, { get: (_, key) => key });
|
|
@@ -470,11 +479,8 @@ function extendMeta(target, source) {
|
|
|
470
479
|
if (source.hooks) {
|
|
471
480
|
if (!target.hooks)
|
|
472
481
|
target.hooks = {};
|
|
473
|
-
for (const event of
|
|
474
|
-
|
|
475
|
-
if (sourceList?.length) {
|
|
476
|
-
target.hooks[event] = [...sourceList, ...(target.hooks[event] ?? [])];
|
|
477
|
-
}
|
|
482
|
+
for (const [event, sourceList] of definedEntries(source.hooks)) {
|
|
483
|
+
target.hooks[event] = [...sourceList, ...(target.hooks[event] ?? [])];
|
|
478
484
|
}
|
|
479
485
|
}
|
|
480
486
|
}
|
package/dist/libsql/index.d.ts
CHANGED
package/dist/libsql/index.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import type { Config } from '@libsql/client';
|
|
2
|
-
import type
|
|
2
|
+
import { type HranaClient, HranaQuerier } from '../sqlite/hranaQuerier.js';
|
|
3
3
|
import { AbstractHranaQuerierPool } from '../sqlite/hranaQuerierPool.js';
|
|
4
4
|
import type { ExtraOptions } from '../type/index.js';
|
|
5
5
|
import { LibsqlDialect } from './libsqlDialect.js';
|
|
6
|
-
import { LibsqlQuerier } from './libsqlQuerier.js';
|
|
7
6
|
/** Embedded replica: local `file:` DB + `syncUrl` remote - DDL should run on the remote (sqld). */
|
|
8
7
|
export declare function libsqlUseRemoteForMigrations(config: Pick<Config, 'url' | 'syncUrl'>): boolean;
|
|
9
|
-
export declare class LibsqlQuerierPool extends AbstractHranaQuerierPool<
|
|
8
|
+
export declare class LibsqlQuerierPool extends AbstractHranaQuerierPool<LibsqlDialect> {
|
|
10
9
|
private readonly conf;
|
|
11
10
|
constructor(conf: Config, extra?: ExtraOptions);
|
|
12
11
|
protected openClient(): Promise<HranaClient>;
|
|
13
|
-
protected buildQuerier(client: HranaClient, connection?: HranaQuerierConnectionOptions): LibsqlQuerier;
|
|
14
12
|
/**
|
|
15
13
|
* For embedded replicas (`file:` + `syncUrl`), returns a querier connected to `syncUrl` so migrations hit sqld.
|
|
16
14
|
* Otherwise same as `getQuerier`. The migrator calls this for `up`/`down`, `syncForce`, and `autoSync` DDL.
|
|
17
15
|
*/
|
|
18
|
-
getMigrationQuerier(): Promise<
|
|
16
|
+
getMigrationQuerier(): Promise<HranaQuerier>;
|
|
19
17
|
/** Imported on use, so `uql-orm/libsql` loads without the optional `@libsql/client` peer installed. */
|
|
20
18
|
private createClient;
|
|
21
19
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
2
|
+
import { HranaQuerier } from '../sqlite/hranaQuerier.js';
|
|
2
3
|
import { AbstractHranaQuerierPool } from '../sqlite/hranaQuerierPool.js';
|
|
3
4
|
import { LibsqlDialect } from './libsqlDialect.js';
|
|
4
|
-
import { LibsqlQuerier } from './libsqlQuerier.js';
|
|
5
5
|
/** Embedded replica: local `file:` DB + `syncUrl` remote - DDL should run on the remote (sqld). */
|
|
6
6
|
export function libsqlUseRemoteForMigrations(config) {
|
|
7
7
|
return Boolean(config.syncUrl && config.url.startsWith('file:'));
|
|
@@ -20,9 +20,6 @@ export class LibsqlQuerierPool extends AbstractHranaQuerierPool {
|
|
|
20
20
|
openClient() {
|
|
21
21
|
return this.createClient(this.conf);
|
|
22
22
|
}
|
|
23
|
-
buildQuerier(client, connection) {
|
|
24
|
-
return new LibsqlQuerier(client, this.dialect, this.extra, connection);
|
|
25
|
-
}
|
|
26
23
|
/**
|
|
27
24
|
* For embedded replicas (`file:` + `syncUrl`), returns a querier connected to `syncUrl` so migrations hit sqld.
|
|
28
25
|
* Otherwise same as `getQuerier`. The migrator calls this for `up`/`down`, `syncForce`, and `autoSync` DDL.
|
|
@@ -32,7 +29,7 @@ export class LibsqlQuerierPool extends AbstractHranaQuerierPool {
|
|
|
32
29
|
return this.getQuerier();
|
|
33
30
|
}
|
|
34
31
|
const remote = await this.createClient(remoteMigrationClientConfig(this.conf));
|
|
35
|
-
return
|
|
32
|
+
return new HranaQuerier(remote, this.dialect, this.extra, { closeClientOnRelease: true });
|
|
36
33
|
}
|
|
37
34
|
/** Imported on use, so `uql-orm/libsql` loads without the optional `@libsql/client` peer installed. */
|
|
38
35
|
async createClient(conf) {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { PoolConnection } from 'mariadb';
|
|
2
2
|
import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
|
|
3
|
-
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
import type { MariaDialect } from './mariaDialect.js';
|
|
5
3
|
export declare class MariadbQuerier extends AbstractPoolQuerier<PoolConnection> {
|
|
6
|
-
constructor(connect: () => Promise<PoolConnection>, dialect: MariaDialect, extra?: ExtraOptions);
|
|
7
4
|
internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
|
|
8
5
|
internalRun(query: string, values?: unknown[]): Promise<import("../type/query.js").QueryUpdateResult>;
|
|
9
6
|
internalStream<T>(query: string, values?: unknown[]): AsyncGenerator<Awaited<T>, void, unknown>;
|