metal-orm 1.0.85 → 1.0.86
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/index.cjs +233 -173
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -13
- package/dist/index.d.ts +27 -13
- package/dist/index.js +231 -173
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/ast-validation.ts +10 -5
- package/src/core/ast/expression-visitor.ts +19 -0
- package/src/core/ast/query-visitor.ts +171 -125
- package/src/orm/execute.ts +60 -46
- package/src/query-builder/select/select-operations.ts +32 -24
- package/src/query-builder/select.ts +49 -35
package/dist/index.cjs
CHANGED
|
@@ -175,8 +175,10 @@ __export(index_exports, {
|
|
|
175
175
|
groupConcat: () => groupConcat,
|
|
176
176
|
gt: () => gt,
|
|
177
177
|
gte: () => gte,
|
|
178
|
+
hasExpressionDispatcher: () => hasExpressionDispatcher,
|
|
178
179
|
hasMany: () => hasMany,
|
|
179
180
|
hasOne: () => hasOne,
|
|
181
|
+
hasOperandDispatcher: () => hasOperandDispatcher,
|
|
180
182
|
hour: () => hour,
|
|
181
183
|
hydrateRows: () => hydrateRows,
|
|
182
184
|
ifNull: () => ifNull,
|
|
@@ -1054,6 +1056,8 @@ var registerExpressionDispatcher = (type, dispatcher) => {
|
|
|
1054
1056
|
var registerOperandDispatcher = (type, dispatcher) => {
|
|
1055
1057
|
operandRegistry = operandRegistry.register(type, dispatcher);
|
|
1056
1058
|
};
|
|
1059
|
+
var hasExpressionDispatcher = (type) => expressionRegistry.get(type) !== void 0;
|
|
1060
|
+
var hasOperandDispatcher = (type) => operandRegistry.get(type) !== void 0;
|
|
1057
1061
|
var clearExpressionDispatchers = () => {
|
|
1058
1062
|
expressionRegistry = expressionRegistry.clear();
|
|
1059
1063
|
};
|
|
@@ -1148,6 +1152,12 @@ var visitOperand = (node, visitor) => {
|
|
|
1148
1152
|
case "Collate":
|
|
1149
1153
|
if (visitor.visitCollate) return visitor.visitCollate(node);
|
|
1150
1154
|
break;
|
|
1155
|
+
case "ArithmeticExpression":
|
|
1156
|
+
if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
|
|
1157
|
+
break;
|
|
1158
|
+
case "BitwiseExpression":
|
|
1159
|
+
if (visitor.visitBitwiseExpression) return visitor.visitBitwiseExpression(node);
|
|
1160
|
+
break;
|
|
1151
1161
|
default:
|
|
1152
1162
|
break;
|
|
1153
1163
|
}
|
|
@@ -6436,9 +6446,9 @@ var flattenResults = (results) => {
|
|
|
6436
6446
|
}
|
|
6437
6447
|
return rows;
|
|
6438
6448
|
};
|
|
6439
|
-
var executeWithContexts = async (execCtx, entityCtx, qb) => {
|
|
6449
|
+
var executeWithContexts = async (execCtx, entityCtx, qb, options) => {
|
|
6440
6450
|
const ast = qb.getAST();
|
|
6441
|
-
const compiled = execCtx.dialect.compileSelect(ast);
|
|
6451
|
+
const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
|
|
6442
6452
|
const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
6443
6453
|
const rows = flattenResults(executed);
|
|
6444
6454
|
const lazyRelations = qb.getLazyRelations();
|
|
@@ -6456,9 +6466,9 @@ var executeWithContexts = async (execCtx, entityCtx, qb) => {
|
|
|
6456
6466
|
await preloadRelationIncludes(entities, includeTree);
|
|
6457
6467
|
return entities;
|
|
6458
6468
|
};
|
|
6459
|
-
var executePlainWithContexts = async (execCtx, qb) => {
|
|
6469
|
+
var executePlainWithContexts = async (execCtx, qb, options) => {
|
|
6460
6470
|
const ast = qb.getAST();
|
|
6461
|
-
const compiled = execCtx.dialect.compileSelect(ast);
|
|
6471
|
+
const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
|
|
6462
6472
|
const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
6463
6473
|
const rows = flattenResults(executed);
|
|
6464
6474
|
if (ast.setOps && ast.setOps.length > 0) {
|
|
@@ -6466,21 +6476,21 @@ var executePlainWithContexts = async (execCtx, qb) => {
|
|
|
6466
6476
|
}
|
|
6467
6477
|
return hydrateRows(rows, qb.getHydrationPlan());
|
|
6468
6478
|
};
|
|
6469
|
-
async function executeHydrated(session, qb) {
|
|
6470
|
-
return executeWithContexts(session.getExecutionContext(), session, qb);
|
|
6479
|
+
async function executeHydrated(session, qb, options) {
|
|
6480
|
+
return executeWithContexts(session.getExecutionContext(), session, qb, options);
|
|
6471
6481
|
}
|
|
6472
|
-
async function executeHydratedPlain(session, qb) {
|
|
6473
|
-
return executePlainWithContexts(session.getExecutionContext(), qb);
|
|
6482
|
+
async function executeHydratedPlain(session, qb, options) {
|
|
6483
|
+
return executePlainWithContexts(session.getExecutionContext(), qb, options);
|
|
6474
6484
|
}
|
|
6475
|
-
async function executeHydratedWithContexts(execCtx, hydCtx, qb) {
|
|
6485
|
+
async function executeHydratedWithContexts(execCtx, hydCtx, qb, options) {
|
|
6476
6486
|
const entityCtx = hydCtx.entityContext;
|
|
6477
6487
|
if (!entityCtx) {
|
|
6478
6488
|
throw new Error("Hydration context is missing an EntityContext");
|
|
6479
6489
|
}
|
|
6480
|
-
return executeWithContexts(execCtx, entityCtx, qb);
|
|
6490
|
+
return executeWithContexts(execCtx, entityCtx, qb, options);
|
|
6481
6491
|
}
|
|
6482
|
-
async function executeHydratedPlainWithContexts(execCtx, qb) {
|
|
6483
|
-
return executePlainWithContexts(execCtx, qb);
|
|
6492
|
+
async function executeHydratedPlainWithContexts(execCtx, qb, options) {
|
|
6493
|
+
return executePlainWithContexts(execCtx, qb, options);
|
|
6484
6494
|
}
|
|
6485
6495
|
var loadLazyRelationsForTable = async (ctx, table, lazyRelations, lazyRelationOptions) => {
|
|
6486
6496
|
if (!lazyRelations.length) return;
|
|
@@ -6681,7 +6691,7 @@ function applyOrderBy(context, predicateFacet, term, directionOrOptions) {
|
|
|
6681
6691
|
const dir = options.direction ?? ORDER_DIRECTIONS.ASC;
|
|
6682
6692
|
return predicateFacet.orderBy(context, term, dir, options.nulls, options.collation);
|
|
6683
6693
|
}
|
|
6684
|
-
async function executeCount(context, env, session) {
|
|
6694
|
+
async function executeCount(context, env, session, options) {
|
|
6685
6695
|
const unpagedAst = {
|
|
6686
6696
|
...context.state.ast,
|
|
6687
6697
|
orderBy: void 0,
|
|
@@ -6701,7 +6711,7 @@ async function executeCount(context, env, session) {
|
|
|
6701
6711
|
joins: []
|
|
6702
6712
|
};
|
|
6703
6713
|
const execCtx = session.getExecutionContext();
|
|
6704
|
-
const compiled = execCtx.dialect.compileSelect(countQuery);
|
|
6714
|
+
const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(countQuery, { allowParams: true }) : execCtx.dialect.compileSelect(countQuery);
|
|
6705
6715
|
const results = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
6706
6716
|
const value = results[0]?.values?.[0]?.[0];
|
|
6707
6717
|
if (typeof value === "number") return value;
|
|
@@ -6709,7 +6719,7 @@ async function executeCount(context, env, session) {
|
|
|
6709
6719
|
if (typeof value === "string") return Number(value);
|
|
6710
6720
|
return value === null || value === void 0 ? 0 : Number(value);
|
|
6711
6721
|
}
|
|
6712
|
-
async function executePagedQuery(builder, session, options, countCallback) {
|
|
6722
|
+
async function executePagedQuery(builder, session, options, countCallback, paramOptions) {
|
|
6713
6723
|
const { page, pageSize } = options;
|
|
6714
6724
|
if (!Number.isInteger(page) || page < 1) {
|
|
6715
6725
|
throw new Error("executePaged: page must be an integer >= 1");
|
|
@@ -6719,7 +6729,7 @@ async function executePagedQuery(builder, session, options, countCallback) {
|
|
|
6719
6729
|
}
|
|
6720
6730
|
const offset = (page - 1) * pageSize;
|
|
6721
6731
|
const totalItems = await countCallback(session);
|
|
6722
|
-
const items = await builder.limit(pageSize).offset(offset).execute(session);
|
|
6732
|
+
const items = await builder.limit(pageSize).offset(offset).execute(session, paramOptions);
|
|
6723
6733
|
return { items, totalItems, page, pageSize };
|
|
6724
6734
|
}
|
|
6725
6735
|
function buildWhereHasPredicate(env, context, relationFacet, createChildBuilder, relationName, callbackOrOptions, maybeOptions, negate = false) {
|
|
@@ -7651,7 +7661,7 @@ var collectFilterColumns = (expr, table, rootTables) => {
|
|
|
7651
7661
|
columns.add(node.name);
|
|
7652
7662
|
}
|
|
7653
7663
|
};
|
|
7654
|
-
const
|
|
7664
|
+
const visitOrderingTerm = (term) => {
|
|
7655
7665
|
if (!term || typeof term !== "object") return;
|
|
7656
7666
|
if (isOperandNode(term)) {
|
|
7657
7667
|
visitOperand2(term);
|
|
@@ -7663,7 +7673,7 @@ var collectFilterColumns = (expr, table, rootTables) => {
|
|
|
7663
7673
|
};
|
|
7664
7674
|
const visitOrderBy = (orderBy) => {
|
|
7665
7675
|
if (!orderBy) return;
|
|
7666
|
-
orderBy.forEach((node) =>
|
|
7676
|
+
orderBy.forEach((node) => visitOrderingTerm(node.term));
|
|
7667
7677
|
};
|
|
7668
7678
|
const visitOperand2 = (node) => {
|
|
7669
7679
|
switch (node.type) {
|
|
@@ -7815,137 +7825,174 @@ var getNodeType3 = (value) => {
|
|
|
7815
7825
|
}
|
|
7816
7826
|
return void 0;
|
|
7817
7827
|
};
|
|
7818
|
-
var
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
};
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
var visitTableSource = (source, visitor) => {
|
|
7830
|
-
visitor.visitTableSource?.(source);
|
|
7831
|
-
if (source.type === "DerivedTable") {
|
|
7832
|
-
visitor.visitDerivedTable?.(source);
|
|
7833
|
-
visitSelectQuery(source.query, visitor);
|
|
7834
|
-
return;
|
|
7835
|
-
}
|
|
7836
|
-
if (source.type === "FunctionTable") {
|
|
7837
|
-
visitor.visitFunctionTable?.(source);
|
|
7838
|
-
source.args?.forEach((arg) => visitOperandNode(arg, visitor));
|
|
7839
|
-
}
|
|
7840
|
-
};
|
|
7841
|
-
var visitExpressionNode = (node, visitor) => {
|
|
7842
|
-
visitor.visitExpression?.(node);
|
|
7843
|
-
const type = getNodeType3(node);
|
|
7844
|
-
if (!type) return;
|
|
7845
|
-
switch (type) {
|
|
7846
|
-
case "BinaryExpression":
|
|
7847
|
-
visitOperandNode(node.left, visitor);
|
|
7848
|
-
visitOperandNode(node.right, visitor);
|
|
7849
|
-
if (node.escape) {
|
|
7850
|
-
visitOperandNode(node.escape, visitor);
|
|
7851
|
-
}
|
|
7828
|
+
var visitSelectQuery = (ast, visitor) => {
|
|
7829
|
+
const visitExpressionNode = (node) => {
|
|
7830
|
+
visitExpression(node, expressionVisitor);
|
|
7831
|
+
};
|
|
7832
|
+
const visitOperandNode = (node) => {
|
|
7833
|
+
visitOperand(node, operandVisitor);
|
|
7834
|
+
};
|
|
7835
|
+
const visitOrderingTerm = (term) => {
|
|
7836
|
+
if (!term || typeof term !== "object") return;
|
|
7837
|
+
if (isOperandNode(term)) {
|
|
7838
|
+
visitOperandNode(term);
|
|
7852
7839
|
return;
|
|
7853
|
-
|
|
7854
|
-
|
|
7840
|
+
}
|
|
7841
|
+
const type = getNodeType3(term);
|
|
7842
|
+
if (type && hasOperandDispatcher(type)) {
|
|
7843
|
+
visitOperandNode(term);
|
|
7855
7844
|
return;
|
|
7856
|
-
|
|
7857
|
-
|
|
7845
|
+
}
|
|
7846
|
+
if (type) {
|
|
7847
|
+
visitExpressionNode(term);
|
|
7848
|
+
}
|
|
7849
|
+
};
|
|
7850
|
+
const visitOrderByNode = (node) => {
|
|
7851
|
+
visitor.visitOrderBy?.(node);
|
|
7852
|
+
visitOrderingTerm(node.term);
|
|
7853
|
+
};
|
|
7854
|
+
const visitTableSource = (source) => {
|
|
7855
|
+
visitor.visitTableSource?.(source);
|
|
7856
|
+
if (source.type === "DerivedTable") {
|
|
7857
|
+
visitor.visitDerivedTable?.(source);
|
|
7858
|
+
visitSelectQuery(source.query, visitor);
|
|
7858
7859
|
return;
|
|
7859
|
-
|
|
7860
|
-
|
|
7860
|
+
}
|
|
7861
|
+
if (source.type === "FunctionTable") {
|
|
7862
|
+
visitor.visitFunctionTable?.(source);
|
|
7863
|
+
source.args?.forEach((arg) => visitOperandNode(arg));
|
|
7864
|
+
}
|
|
7865
|
+
};
|
|
7866
|
+
const expressionVisitor = {
|
|
7867
|
+
visitBinaryExpression: (node) => {
|
|
7868
|
+
visitor.visitExpression?.(node);
|
|
7869
|
+
visitOperandNode(node.left);
|
|
7870
|
+
visitOperandNode(node.right);
|
|
7871
|
+
if (node.escape) {
|
|
7872
|
+
visitOperandNode(node.escape);
|
|
7873
|
+
}
|
|
7874
|
+
},
|
|
7875
|
+
visitLogicalExpression: (node) => {
|
|
7876
|
+
visitor.visitExpression?.(node);
|
|
7877
|
+
node.operands.forEach((operand) => visitExpressionNode(operand));
|
|
7878
|
+
},
|
|
7879
|
+
visitNullExpression: (node) => {
|
|
7880
|
+
visitor.visitExpression?.(node);
|
|
7881
|
+
visitOperandNode(node.left);
|
|
7882
|
+
},
|
|
7883
|
+
visitInExpression: (node) => {
|
|
7884
|
+
visitor.visitExpression?.(node);
|
|
7885
|
+
visitOperandNode(node.left);
|
|
7861
7886
|
if (Array.isArray(node.right)) {
|
|
7862
|
-
node.right.forEach((operand) => visitOperandNode(operand
|
|
7887
|
+
node.right.forEach((operand) => visitOperandNode(operand));
|
|
7863
7888
|
} else {
|
|
7864
|
-
visitOperandNode(node.right
|
|
7889
|
+
visitOperandNode(node.right);
|
|
7865
7890
|
}
|
|
7866
|
-
|
|
7867
|
-
|
|
7891
|
+
},
|
|
7892
|
+
visitExistsExpression: (node) => {
|
|
7893
|
+
visitor.visitExpression?.(node);
|
|
7868
7894
|
visitSelectQuery(node.subquery, visitor);
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
visitOperandNode(node.
|
|
7873
|
-
visitOperandNode(node.
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7895
|
+
},
|
|
7896
|
+
visitBetweenExpression: (node) => {
|
|
7897
|
+
visitor.visitExpression?.(node);
|
|
7898
|
+
visitOperandNode(node.left);
|
|
7899
|
+
visitOperandNode(node.lower);
|
|
7900
|
+
visitOperandNode(node.upper);
|
|
7901
|
+
},
|
|
7902
|
+
visitArithmeticExpression: (node) => {
|
|
7903
|
+
visitor.visitExpression?.(node);
|
|
7904
|
+
visitOperandNode(node.left);
|
|
7905
|
+
visitOperandNode(node.right);
|
|
7906
|
+
},
|
|
7907
|
+
visitBitwiseExpression: (node) => {
|
|
7908
|
+
visitor.visitExpression?.(node);
|
|
7909
|
+
visitOperandNode(node.left);
|
|
7910
|
+
visitOperandNode(node.right);
|
|
7911
|
+
},
|
|
7912
|
+
visitOperand: (node) => {
|
|
7913
|
+
visitOperandNode(node);
|
|
7914
|
+
},
|
|
7915
|
+
visitSelectQuery: (node) => {
|
|
7916
|
+
visitSelectQuery(node, visitor);
|
|
7917
|
+
},
|
|
7918
|
+
otherwise: (node) => {
|
|
7919
|
+
visitor.visitExpression?.(node);
|
|
7885
7920
|
}
|
|
7886
|
-
}
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
node.args?.forEach((arg) => visitOperandNode(arg, visitor));
|
|
7903
|
-
node.orderBy?.forEach((order) => visitOrderByNode(order, visitor));
|
|
7921
|
+
};
|
|
7922
|
+
const operandVisitor = {
|
|
7923
|
+
visitColumn: (node) => {
|
|
7924
|
+
visitor.visitOperand?.(node);
|
|
7925
|
+
},
|
|
7926
|
+
visitLiteral: (node) => {
|
|
7927
|
+
visitor.visitOperand?.(node);
|
|
7928
|
+
},
|
|
7929
|
+
visitParam: (node) => {
|
|
7930
|
+
visitor.visitOperand?.(node);
|
|
7931
|
+
visitor.visitParam?.(node);
|
|
7932
|
+
},
|
|
7933
|
+
visitFunction: (node) => {
|
|
7934
|
+
visitor.visitOperand?.(node);
|
|
7935
|
+
node.args?.forEach((arg) => visitOperandNode(arg));
|
|
7936
|
+
node.orderBy?.forEach((order) => visitOrderByNode(order));
|
|
7904
7937
|
if (node.separator) {
|
|
7905
|
-
visitOperandNode(node.separator
|
|
7938
|
+
visitOperandNode(node.separator);
|
|
7906
7939
|
}
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7940
|
+
},
|
|
7941
|
+
visitJsonPath: (node) => {
|
|
7942
|
+
visitor.visitOperand?.(node);
|
|
7943
|
+
visitOperandNode(node.column);
|
|
7944
|
+
},
|
|
7945
|
+
visitScalarSubquery: (node) => {
|
|
7946
|
+
visitor.visitOperand?.(node);
|
|
7912
7947
|
visitSelectQuery(node.query, visitor);
|
|
7913
|
-
|
|
7914
|
-
|
|
7948
|
+
},
|
|
7949
|
+
visitCaseExpression: (node) => {
|
|
7950
|
+
visitor.visitOperand?.(node);
|
|
7915
7951
|
node.conditions.forEach((cond) => {
|
|
7916
|
-
visitExpressionNode(cond.when
|
|
7917
|
-
visitOperandNode(cond.then
|
|
7952
|
+
visitExpressionNode(cond.when);
|
|
7953
|
+
visitOperandNode(cond.then);
|
|
7918
7954
|
});
|
|
7919
7955
|
if (node.else) {
|
|
7920
|
-
visitOperandNode(node.else
|
|
7956
|
+
visitOperandNode(node.else);
|
|
7921
7957
|
}
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
node.
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
visitOperandNode(node.
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
visitOperandNode(node.
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7958
|
+
},
|
|
7959
|
+
visitCast: (node) => {
|
|
7960
|
+
visitor.visitOperand?.(node);
|
|
7961
|
+
visitOperandNode(node.expression);
|
|
7962
|
+
},
|
|
7963
|
+
visitWindowFunction: (node) => {
|
|
7964
|
+
visitor.visitOperand?.(node);
|
|
7965
|
+
node.args?.forEach((arg) => visitOperandNode(arg));
|
|
7966
|
+
node.partitionBy?.forEach((term) => visitOperandNode(term));
|
|
7967
|
+
node.orderBy?.forEach((order) => visitOrderByNode(order));
|
|
7968
|
+
},
|
|
7969
|
+
visitArithmeticExpression: (node) => {
|
|
7970
|
+
visitor.visitOperand?.(node);
|
|
7971
|
+
visitOperandNode(node.left);
|
|
7972
|
+
visitOperandNode(node.right);
|
|
7973
|
+
},
|
|
7974
|
+
visitBitwiseExpression: (node) => {
|
|
7975
|
+
visitor.visitOperand?.(node);
|
|
7976
|
+
visitOperandNode(node.left);
|
|
7977
|
+
visitOperandNode(node.right);
|
|
7978
|
+
},
|
|
7979
|
+
visitExpression: (node) => {
|
|
7980
|
+
visitExpressionNode(node);
|
|
7981
|
+
},
|
|
7982
|
+
visitSelectQuery: (node) => {
|
|
7983
|
+
visitSelectQuery(node, visitor);
|
|
7984
|
+
},
|
|
7985
|
+
visitCollate: (node) => {
|
|
7986
|
+
visitor.visitOperand?.(node);
|
|
7987
|
+
visitOperandNode(node.expression);
|
|
7988
|
+
},
|
|
7989
|
+
visitAliasRef: (node) => {
|
|
7990
|
+
visitor.visitOperand?.(node);
|
|
7991
|
+
},
|
|
7992
|
+
otherwise: (node) => {
|
|
7993
|
+
visitor.visitOperand?.(node);
|
|
7945
7994
|
}
|
|
7946
|
-
}
|
|
7947
|
-
};
|
|
7948
|
-
var visitSelectQuery = (ast, visitor) => {
|
|
7995
|
+
};
|
|
7949
7996
|
visitor.visitSelectQuery?.(ast);
|
|
7950
7997
|
if (ast.ctes) {
|
|
7951
7998
|
for (const cte of ast.ctes) {
|
|
@@ -7953,29 +8000,29 @@ var visitSelectQuery = (ast, visitor) => {
|
|
|
7953
8000
|
visitSelectQuery(cte.query, visitor);
|
|
7954
8001
|
}
|
|
7955
8002
|
}
|
|
7956
|
-
visitTableSource(ast.from
|
|
8003
|
+
visitTableSource(ast.from);
|
|
7957
8004
|
ast.columns?.forEach((col2) => {
|
|
7958
|
-
visitOperandNode(col2
|
|
8005
|
+
visitOperandNode(col2);
|
|
7959
8006
|
});
|
|
7960
8007
|
ast.joins?.forEach((join) => {
|
|
7961
8008
|
visitor.visitJoin?.(join);
|
|
7962
|
-
visitTableSource(join.table
|
|
7963
|
-
visitExpressionNode(join.condition
|
|
8009
|
+
visitTableSource(join.table);
|
|
8010
|
+
visitExpressionNode(join.condition);
|
|
7964
8011
|
});
|
|
7965
8012
|
if (ast.where) {
|
|
7966
|
-
visitExpressionNode(ast.where
|
|
8013
|
+
visitExpressionNode(ast.where);
|
|
7967
8014
|
}
|
|
7968
8015
|
ast.groupBy?.forEach((term) => {
|
|
7969
|
-
visitOrderingTerm(term
|
|
8016
|
+
visitOrderingTerm(term);
|
|
7970
8017
|
});
|
|
7971
8018
|
if (ast.having) {
|
|
7972
|
-
visitExpressionNode(ast.having
|
|
8019
|
+
visitExpressionNode(ast.having);
|
|
7973
8020
|
}
|
|
7974
8021
|
ast.orderBy?.forEach((order) => {
|
|
7975
|
-
visitOrderByNode(order
|
|
8022
|
+
visitOrderByNode(order);
|
|
7976
8023
|
});
|
|
7977
8024
|
ast.distinct?.forEach((col2) => {
|
|
7978
|
-
visitOperandNode(col2
|
|
8025
|
+
visitOperandNode(col2);
|
|
7979
8026
|
});
|
|
7980
8027
|
ast.setOps?.forEach((op) => {
|
|
7981
8028
|
visitor.visitSetOperation?.(op);
|
|
@@ -7984,14 +8031,16 @@ var visitSelectQuery = (ast, visitor) => {
|
|
|
7984
8031
|
};
|
|
7985
8032
|
|
|
7986
8033
|
// src/core/ast/ast-validation.ts
|
|
7987
|
-
var
|
|
7988
|
-
let
|
|
8034
|
+
var findFirstParamOperandName = (ast) => {
|
|
8035
|
+
let name;
|
|
7989
8036
|
visitSelectQuery(ast, {
|
|
7990
|
-
visitParam: () => {
|
|
7991
|
-
|
|
8037
|
+
visitParam: (node) => {
|
|
8038
|
+
if (!name) {
|
|
8039
|
+
name = node.name;
|
|
8040
|
+
}
|
|
7992
8041
|
}
|
|
7993
8042
|
});
|
|
7994
|
-
return
|
|
8043
|
+
return name;
|
|
7995
8044
|
};
|
|
7996
8045
|
|
|
7997
8046
|
// src/query-builder/select.ts
|
|
@@ -8471,11 +8520,12 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8471
8520
|
* Validates that the query does not contain Param operands.
|
|
8472
8521
|
* Param proxies are only for schema generation, not execution.
|
|
8473
8522
|
*/
|
|
8474
|
-
validateNoParamOperands() {
|
|
8523
|
+
validateNoParamOperands(options) {
|
|
8524
|
+
if (options?.allowParamOperands) return;
|
|
8475
8525
|
const ast = this.context.hydration.applyToAst(this.context.state.ast);
|
|
8476
|
-
const
|
|
8477
|
-
if (
|
|
8478
|
-
throw new Error(
|
|
8526
|
+
const paramName = findFirstParamOperandName(ast);
|
|
8527
|
+
if (paramName) {
|
|
8528
|
+
throw new Error(`Cannot execute query containing Param operand "${paramName}". Param proxies are only for schema generation (getSchema()). If you need real parameters, use literal values.`);
|
|
8479
8529
|
}
|
|
8480
8530
|
}
|
|
8481
8531
|
/**
|
|
@@ -8490,13 +8540,13 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8490
8540
|
* // users is User[]
|
|
8491
8541
|
* users[0] instanceof User; // true
|
|
8492
8542
|
*/
|
|
8493
|
-
async execute(ctx) {
|
|
8494
|
-
this.validateNoParamOperands();
|
|
8543
|
+
async execute(ctx, options) {
|
|
8544
|
+
this.validateNoParamOperands(options);
|
|
8495
8545
|
if (this.entityConstructor) {
|
|
8496
|
-
return this.executeAs(this.entityConstructor, ctx);
|
|
8546
|
+
return this.executeAs(this.entityConstructor, ctx, options);
|
|
8497
8547
|
}
|
|
8498
8548
|
const builder = this.ensureDefaultSelection();
|
|
8499
|
-
return executeHydrated(ctx, builder);
|
|
8549
|
+
return executeHydrated(ctx, builder, options);
|
|
8500
8550
|
}
|
|
8501
8551
|
/**
|
|
8502
8552
|
* Executes the query and returns plain row objects (POJOs), ignoring any entity materialization.
|
|
@@ -8509,10 +8559,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8509
8559
|
* // rows is EntityInstance<UserTable>[] (plain objects)
|
|
8510
8560
|
* rows[0] instanceof User; // false
|
|
8511
8561
|
*/
|
|
8512
|
-
async executePlain(ctx) {
|
|
8513
|
-
this.validateNoParamOperands();
|
|
8562
|
+
async executePlain(ctx, options) {
|
|
8563
|
+
this.validateNoParamOperands(options);
|
|
8514
8564
|
const builder = this.ensureDefaultSelection();
|
|
8515
|
-
const rows = await executeHydratedPlain(ctx, builder);
|
|
8565
|
+
const rows = await executeHydratedPlain(ctx, builder, options);
|
|
8516
8566
|
return rows;
|
|
8517
8567
|
}
|
|
8518
8568
|
/**
|
|
@@ -8529,10 +8579,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8529
8579
|
* users[0] instanceof User; // true!
|
|
8530
8580
|
* users[0].getFullName(); // works!
|
|
8531
8581
|
*/
|
|
8532
|
-
async executeAs(entityClass, ctx) {
|
|
8533
|
-
this.validateNoParamOperands();
|
|
8582
|
+
async executeAs(entityClass, ctx, options) {
|
|
8583
|
+
this.validateNoParamOperands(options);
|
|
8534
8584
|
const builder = this.ensureDefaultSelection();
|
|
8535
|
-
const results = await executeHydrated(ctx, builder);
|
|
8585
|
+
const results = await executeHydrated(ctx, builder, options);
|
|
8536
8586
|
return materializeAs(entityClass, results);
|
|
8537
8587
|
}
|
|
8538
8588
|
/**
|
|
@@ -8541,9 +8591,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8541
8591
|
* @example
|
|
8542
8592
|
* const total = await qb.count(session);
|
|
8543
8593
|
*/
|
|
8544
|
-
async count(session) {
|
|
8545
|
-
this.validateNoParamOperands();
|
|
8546
|
-
return executeCount(this.context, this.env, session);
|
|
8594
|
+
async count(session, options) {
|
|
8595
|
+
this.validateNoParamOperands(options);
|
|
8596
|
+
return executeCount(this.context, this.env, session, options);
|
|
8547
8597
|
}
|
|
8548
8598
|
/**
|
|
8549
8599
|
* Executes the query and returns both the paged items and the total.
|
|
@@ -8552,9 +8602,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8552
8602
|
* const { items, totalItems, page, pageSize } = await qb.executePaged(session, { page: 1, pageSize: 20 });
|
|
8553
8603
|
*/
|
|
8554
8604
|
async executePaged(session, options) {
|
|
8555
|
-
this.validateNoParamOperands();
|
|
8605
|
+
this.validateNoParamOperands(options);
|
|
8556
8606
|
const builder = this.ensureDefaultSelection();
|
|
8557
|
-
return executePagedQuery(builder, session, options, (sess) => builder.count(sess));
|
|
8607
|
+
return executePagedQuery(builder, session, options, (sess) => builder.count(sess, options), options);
|
|
8558
8608
|
}
|
|
8559
8609
|
/**
|
|
8560
8610
|
* Executes the query with provided execution and hydration contexts
|
|
@@ -8566,10 +8616,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8566
8616
|
* const hydCtx = new HydrationContext();
|
|
8567
8617
|
* const users = await qb.executeWithContexts(execCtx, hydCtx);
|
|
8568
8618
|
*/
|
|
8569
|
-
async executeWithContexts(execCtx, hydCtx) {
|
|
8570
|
-
this.validateNoParamOperands();
|
|
8619
|
+
async executeWithContexts(execCtx, hydCtx, options) {
|
|
8620
|
+
this.validateNoParamOperands(options);
|
|
8571
8621
|
const builder = this.ensureDefaultSelection();
|
|
8572
|
-
const results = await executeHydratedWithContexts(execCtx, hydCtx, builder);
|
|
8622
|
+
const results = await executeHydratedWithContexts(execCtx, hydCtx, builder, options);
|
|
8573
8623
|
if (this.entityConstructor) {
|
|
8574
8624
|
return materializeAs(this.entityConstructor, results);
|
|
8575
8625
|
}
|
|
@@ -8802,9 +8852,17 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8802
8852
|
* .compile('postgres');
|
|
8803
8853
|
* console.log(compiled.sql); // SELECT "id", "name" FROM "users" WHERE "active" = true
|
|
8804
8854
|
*/
|
|
8805
|
-
compile(dialect) {
|
|
8855
|
+
compile(dialect, options) {
|
|
8806
8856
|
const resolved = resolveDialectInput(dialect);
|
|
8807
|
-
|
|
8857
|
+
const ast = this.getAST();
|
|
8858
|
+
if (!options?.allowParamOperands) {
|
|
8859
|
+
const paramName = findFirstParamOperandName(ast);
|
|
8860
|
+
if (paramName) {
|
|
8861
|
+
throw new Error(`Cannot compile query containing Param operand "${paramName}". Param proxies are only for schema generation (getSchema()). If you need real parameters, use literal values.`);
|
|
8862
|
+
}
|
|
8863
|
+
return resolved.compileSelect(ast);
|
|
8864
|
+
}
|
|
8865
|
+
return resolved.compileSelectWithOptions(ast, { allowParams: true });
|
|
8808
8866
|
}
|
|
8809
8867
|
/**
|
|
8810
8868
|
* Converts the query to SQL string for a specific dialect
|
|
@@ -8816,8 +8874,8 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
8816
8874
|
* .toSql('postgres');
|
|
8817
8875
|
* console.log(sql); // SELECT "id", "name" FROM "users" WHERE "active" = true
|
|
8818
8876
|
*/
|
|
8819
|
-
toSql(dialect) {
|
|
8820
|
-
return this.compile(dialect).sql;
|
|
8877
|
+
toSql(dialect, options) {
|
|
8878
|
+
return this.compile(dialect, options).sql;
|
|
8821
8879
|
}
|
|
8822
8880
|
/**
|
|
8823
8881
|
* Gets hydration plan for query
|
|
@@ -14506,8 +14564,10 @@ function createPooledExecutorFactory(opts) {
|
|
|
14506
14564
|
groupConcat,
|
|
14507
14565
|
gt,
|
|
14508
14566
|
gte,
|
|
14567
|
+
hasExpressionDispatcher,
|
|
14509
14568
|
hasMany,
|
|
14510
14569
|
hasOne,
|
|
14570
|
+
hasOperandDispatcher,
|
|
14511
14571
|
hour,
|
|
14512
14572
|
hydrateRows,
|
|
14513
14573
|
ifNull,
|