metal-orm 1.0.52 → 1.0.54
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 +3 -1
- package/dist/index.cjs +68 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -7
- package/dist/index.d.ts +20 -7
- package/dist/index.js +67 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/aggregate-functions.ts +10 -0
- package/src/core/dialect/mssql/index.ts +2 -2
- package/src/core/functions/standard-strategy.ts +1 -1
- package/src/orm/execute.ts +37 -36
- package/src/orm/save-graph-types.ts +4 -6
- package/src/query-builder/delete.ts +5 -4
- package/src/query-builder/select.ts +68 -10
- package/src/query-builder/update.ts +5 -4
package/README.md
CHANGED
|
@@ -250,7 +250,9 @@ console.log(rows);
|
|
|
250
250
|
// ]
|
|
251
251
|
```
|
|
252
252
|
|
|
253
|
-
That’s it: schema, query, SQL, done.
|
|
253
|
+
That’s it: schema, query, SQL, done.
|
|
254
|
+
|
|
255
|
+
If you are using the Level 2 runtime (`OrmSession`), `SelectQueryBuilder` also provides `count(session)` and `executePaged(session, { page, pageSize })` for common pagination patterns.
|
|
254
256
|
|
|
255
257
|
#### Column pickers (preferred selection helpers)
|
|
256
258
|
|
package/dist/index.cjs
CHANGED
|
@@ -101,6 +101,7 @@ __export(index_exports, {
|
|
|
101
101
|
cos: () => cos,
|
|
102
102
|
cot: () => cot,
|
|
103
103
|
count: () => count,
|
|
104
|
+
countAll: () => countAll,
|
|
104
105
|
createEntityFromRow: () => createEntityFromRow,
|
|
105
106
|
createEntityProxy: () => createEntityProxy,
|
|
106
107
|
createExecutorFromQueryRunner: () => createExecutorFromQueryRunner,
|
|
@@ -874,6 +875,11 @@ var sum = buildAggregate("SUM");
|
|
|
874
875
|
var avg = buildAggregate("AVG");
|
|
875
876
|
var min = buildAggregate("MIN");
|
|
876
877
|
var max = buildAggregate("MAX");
|
|
878
|
+
var countAll = () => ({
|
|
879
|
+
type: "Function",
|
|
880
|
+
name: "COUNT",
|
|
881
|
+
args: []
|
|
882
|
+
});
|
|
877
883
|
var toOrderByNode = (order) => ({
|
|
878
884
|
type: "OrderBy",
|
|
879
885
|
term: columnOperand(order.column),
|
|
@@ -1076,7 +1082,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
1076
1082
|
this.registerStandard();
|
|
1077
1083
|
}
|
|
1078
1084
|
registerStandard() {
|
|
1079
|
-
this.add("COUNT", ({ compiledArgs }) => `COUNT(${compiledArgs.join(", ")})`);
|
|
1085
|
+
this.add("COUNT", ({ compiledArgs }) => compiledArgs.length ? `COUNT(${compiledArgs.join(", ")})` : "COUNT(*)");
|
|
1080
1086
|
this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
|
|
1081
1087
|
this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
|
|
1082
1088
|
this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
|
|
@@ -2571,9 +2577,9 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
2571
2577
|
return expr;
|
|
2572
2578
|
}).join(", ");
|
|
2573
2579
|
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
2574
|
-
const from = this.
|
|
2580
|
+
const from = this.compileFrom(ast.from, ctx);
|
|
2575
2581
|
const joins = ast.joins.map((j) => {
|
|
2576
|
-
const table = this.
|
|
2582
|
+
const table = this.compileFrom(j.table, ctx);
|
|
2577
2583
|
const cond = this.compileExpression(j.condition, ctx);
|
|
2578
2584
|
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
2579
2585
|
}).join(" ");
|
|
@@ -5002,10 +5008,10 @@ var flattenResults = (results) => {
|
|
|
5002
5008
|
}
|
|
5003
5009
|
return rows;
|
|
5004
5010
|
};
|
|
5005
|
-
var
|
|
5011
|
+
var executeWithContexts = async (execCtx, entityCtx, qb) => {
|
|
5006
5012
|
const ast = qb.getAST();
|
|
5007
|
-
const compiled =
|
|
5008
|
-
const executed = await
|
|
5013
|
+
const compiled = execCtx.dialect.compileSelect(ast);
|
|
5014
|
+
const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
5009
5015
|
const rows = flattenResults(executed);
|
|
5010
5016
|
if (ast.setOps && ast.setOps.length > 0) {
|
|
5011
5017
|
return rows.map((row) => createEntityProxy(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
@@ -5014,14 +5020,14 @@ var executeWithEntityContext = async (entityCtx, qb) => {
|
|
|
5014
5020
|
return hydrated.map((row) => createEntityFromRow(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
5015
5021
|
};
|
|
5016
5022
|
async function executeHydrated(session, qb) {
|
|
5017
|
-
return
|
|
5023
|
+
return executeWithContexts(session.getExecutionContext(), session, qb);
|
|
5018
5024
|
}
|
|
5019
|
-
async function executeHydratedWithContexts(
|
|
5025
|
+
async function executeHydratedWithContexts(execCtx, hydCtx, qb) {
|
|
5020
5026
|
const entityCtx = hydCtx.entityContext;
|
|
5021
5027
|
if (!entityCtx) {
|
|
5022
5028
|
throw new Error("Hydration context is missing an EntityContext");
|
|
5023
5029
|
}
|
|
5024
|
-
return
|
|
5030
|
+
return executeWithContexts(execCtx, entityCtx, qb);
|
|
5025
5031
|
}
|
|
5026
5032
|
|
|
5027
5033
|
// src/query-builder/query-resolution.ts
|
|
@@ -5375,6 +5381,52 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5375
5381
|
async execute(ctx) {
|
|
5376
5382
|
return executeHydrated(ctx, this);
|
|
5377
5383
|
}
|
|
5384
|
+
withAst(ast) {
|
|
5385
|
+
const nextState = new SelectQueryState(this.env.table, ast);
|
|
5386
|
+
const nextContext = {
|
|
5387
|
+
...this.context,
|
|
5388
|
+
state: nextState
|
|
5389
|
+
};
|
|
5390
|
+
return this.clone(nextContext);
|
|
5391
|
+
}
|
|
5392
|
+
async count(session) {
|
|
5393
|
+
const unpagedAst = {
|
|
5394
|
+
...this.context.state.ast,
|
|
5395
|
+
orderBy: void 0,
|
|
5396
|
+
limit: void 0,
|
|
5397
|
+
offset: void 0
|
|
5398
|
+
};
|
|
5399
|
+
const subAst = this.withAst(unpagedAst).getAST();
|
|
5400
|
+
const countQuery = {
|
|
5401
|
+
type: "SelectQuery",
|
|
5402
|
+
from: derivedTable(subAst, "__metal_count"),
|
|
5403
|
+
columns: [{ type: "Function", name: "COUNT", args: [], alias: "total" }],
|
|
5404
|
+
joins: []
|
|
5405
|
+
};
|
|
5406
|
+
const execCtx = session.getExecutionContext();
|
|
5407
|
+
const compiled = execCtx.dialect.compileSelect(countQuery);
|
|
5408
|
+
const results = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
5409
|
+
const value = results[0]?.values?.[0]?.[0];
|
|
5410
|
+
if (typeof value === "number") return value;
|
|
5411
|
+
if (typeof value === "bigint") return Number(value);
|
|
5412
|
+
if (typeof value === "string") return Number(value);
|
|
5413
|
+
return value === null || value === void 0 ? 0 : Number(value);
|
|
5414
|
+
}
|
|
5415
|
+
async executePaged(session, options) {
|
|
5416
|
+
const { page, pageSize } = options;
|
|
5417
|
+
if (!Number.isInteger(page) || page < 1) {
|
|
5418
|
+
throw new Error("executePaged: page must be an integer >= 1");
|
|
5419
|
+
}
|
|
5420
|
+
if (!Number.isInteger(pageSize) || pageSize < 1) {
|
|
5421
|
+
throw new Error("executePaged: pageSize must be an integer >= 1");
|
|
5422
|
+
}
|
|
5423
|
+
const offset = (page - 1) * pageSize;
|
|
5424
|
+
const [items, totalItems] = await Promise.all([
|
|
5425
|
+
this.limit(pageSize).offset(offset).execute(session),
|
|
5426
|
+
this.count(session)
|
|
5427
|
+
]);
|
|
5428
|
+
return { items, totalItems };
|
|
5429
|
+
}
|
|
5378
5430
|
/**
|
|
5379
5431
|
* Executes the query with provided execution and hydration contexts
|
|
5380
5432
|
* @param execCtx - Execution context
|
|
@@ -6224,8 +6276,9 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
|
6224
6276
|
* @returns A promise that resolves to the query results
|
|
6225
6277
|
*/
|
|
6226
6278
|
async execute(session) {
|
|
6227
|
-
const
|
|
6228
|
-
|
|
6279
|
+
const execCtx = session.getExecutionContext();
|
|
6280
|
+
const compiled = this.compile(execCtx.dialect);
|
|
6281
|
+
return execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
6229
6282
|
}
|
|
6230
6283
|
/**
|
|
6231
6284
|
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
@@ -6409,8 +6462,9 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
|
6409
6462
|
* @returns A promise that resolves to the query results
|
|
6410
6463
|
*/
|
|
6411
6464
|
async execute(session) {
|
|
6412
|
-
const
|
|
6413
|
-
|
|
6465
|
+
const execCtx = session.getExecutionContext();
|
|
6466
|
+
const compiled = this.compile(execCtx.dialect);
|
|
6467
|
+
return execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
6414
6468
|
}
|
|
6415
6469
|
/**
|
|
6416
6470
|
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
@@ -10923,6 +10977,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
10923
10977
|
cos,
|
|
10924
10978
|
cot,
|
|
10925
10979
|
count,
|
|
10980
|
+
countAll,
|
|
10926
10981
|
createEntityFromRow,
|
|
10927
10982
|
createEntityProxy,
|
|
10928
10983
|
createExecutorFromQueryRunner,
|