metal-orm 1.0.62 → 1.0.64
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 +10 -8
- package/dist/index.cjs +187 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +844 -422
- package/dist/index.d.ts +844 -422
- package/dist/index.js +184 -119
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/aggregate-functions.ts +13 -4
- package/src/core/ast/expression-builders.ts +325 -111
- package/src/core/ast/expression.ts +9 -0
- package/src/core/ast/window-functions.ts +62 -52
- package/src/core/functions/array.ts +12 -3
- package/src/core/functions/control-flow.ts +28 -18
- package/src/core/functions/datetime.ts +113 -84
- package/src/core/functions/json.ts +40 -8
- package/src/core/functions/numeric.ts +116 -79
- package/src/core/functions/text.ts +181 -114
- package/src/decorators/bootstrap.ts +23 -19
- package/src/query-builder/hydration-planner.ts +14 -16
- package/src/query-builder/select.ts +91 -55
package/package.json
CHANGED
|
@@ -2,9 +2,10 @@ import { ColumnNode, FunctionNode } from './expression-nodes.js';
|
|
|
2
2
|
import { columnOperand, valueToOperand, ValueOperandInput } from './expression-builders.js';
|
|
3
3
|
import { ColumnRef } from './types.js';
|
|
4
4
|
import { OrderByNode } from './query.js';
|
|
5
|
+
import { TypedExpression, asType } from './expression.js';
|
|
5
6
|
import { ORDER_DIRECTIONS, OrderDirection } from '../sql/sql.js';
|
|
6
7
|
|
|
7
|
-
const buildAggregate = (name: string) => (col: ColumnRef | ColumnNode):
|
|
8
|
+
const buildAggregate = (name: string) => (col: ColumnRef | ColumnNode): TypedExpression<number> => asType<number>({
|
|
8
9
|
type: 'Function',
|
|
9
10
|
name,
|
|
10
11
|
args: [columnOperand(col)]
|
|
@@ -47,9 +48,10 @@ export const max = buildAggregate('MAX');
|
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Creates a COUNT(*) function expression.
|
|
50
|
-
*
|
|
51
|
+
*
|
|
52
|
+
* @returns A `TypedExpression<number>` representing the `COUNT(*)` SQL function.
|
|
51
53
|
*/
|
|
52
|
-
export const countAll = ():
|
|
54
|
+
export const countAll = (): TypedExpression<number> => asType<number>({
|
|
53
55
|
type: 'Function',
|
|
54
56
|
name: 'COUNT',
|
|
55
57
|
args: []
|
|
@@ -73,11 +75,18 @@ const toOrderByNode = (order: GroupConcatOrderByInput): OrderByNode => ({
|
|
|
73
75
|
|
|
74
76
|
/**
|
|
75
77
|
* Aggregates grouped strings into a single value.
|
|
78
|
+
*
|
|
79
|
+
* @param col - Column or expression to aggregate.
|
|
80
|
+
* @param options - Optional separator and ordering.
|
|
81
|
+
* @returns A `TypedExpression<string>` representing the `GROUP_CONCAT` SQL function.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* groupConcat(users.name, { separator: ', ', orderBy: [{ column: users.name }] });
|
|
76
85
|
*/
|
|
77
86
|
export const groupConcat = (
|
|
78
87
|
col: ColumnRef | ColumnNode,
|
|
79
88
|
options?: GroupConcatOptions
|
|
80
|
-
):
|
|
89
|
+
): TypedExpression<string> => asType<string>({
|
|
81
90
|
type: 'Function',
|
|
82
91
|
name: 'GROUP_CONCAT',
|
|
83
92
|
args: [columnOperand(col)],
|
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
export type LiteralValue = LiteralNode['value'];
|
|
28
28
|
export type ValueOperandInput = OperandNode | LiteralValue;
|
|
29
29
|
|
|
30
|
+
export type TypedLike<T> = { tsType?: T } | { __tsType: T };
|
|
31
|
+
|
|
30
32
|
/**
|
|
31
33
|
* Type guard to check if a value is a literal value
|
|
32
34
|
*/
|
|
@@ -165,76 +167,149 @@ const createBinaryExpression = (
|
|
|
165
167
|
};
|
|
166
168
|
|
|
167
169
|
/**
|
|
168
|
-
* Creates an equality expression (left = right)
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
*
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
*
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Creates a
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
170
|
+
* Creates an equality expression (`left = right`).
|
|
171
|
+
*
|
|
172
|
+
* Supports type safety when used with `ColumnDef` objects containing strict type information.
|
|
173
|
+
*
|
|
174
|
+
* @param left - The left operand (column or value).
|
|
175
|
+
* @param right - The right operand (column or value).
|
|
176
|
+
* @returns A `BinaryExpressionNode` representing the equality check.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* // Basic usage
|
|
180
|
+
* eq(users.id, 1);
|
|
181
|
+
*
|
|
182
|
+
* // With strict typing (typescript will error if types mismatch)
|
|
183
|
+
* eq(users.firstName, 'Ada');
|
|
184
|
+
*/
|
|
185
|
+
export function eq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
186
|
+
export function eq(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number | boolean): BinaryExpressionNode;
|
|
187
|
+
export function eq(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | boolean | TypedLike<unknown>): BinaryExpressionNode {
|
|
188
|
+
return createBinaryExpression('=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number | boolean);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Creates a not equal expression (`left != right`).
|
|
193
|
+
*
|
|
194
|
+
* @param left - The left operand (column or value).
|
|
195
|
+
* @param right - The right operand (column or value).
|
|
196
|
+
* @returns A `BinaryExpressionNode` representing the inequality check.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* neq(users.status, 'inactive');
|
|
200
|
+
*/
|
|
201
|
+
export function neq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
202
|
+
export function neq(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number | boolean): BinaryExpressionNode;
|
|
203
|
+
export function neq(
|
|
204
|
+
left: OperandNode | ColumnRef | TypedLike<unknown>,
|
|
205
|
+
right: OperandNode | ColumnRef | string | number | boolean | TypedLike<unknown>
|
|
206
|
+
): BinaryExpressionNode {
|
|
207
|
+
return createBinaryExpression('!=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number | boolean);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Creates a greater-than expression (`left > right`).
|
|
212
|
+
*
|
|
213
|
+
* @param left - The left operand.
|
|
214
|
+
* @param right - The right operand.
|
|
215
|
+
* @returns A `BinaryExpressionNode`.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* gt(users.age, 18);
|
|
219
|
+
*/
|
|
220
|
+
export function gt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
221
|
+
export function gt(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
|
|
222
|
+
export function gt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
|
|
223
|
+
return createBinaryExpression('>', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Creates a greater-than-or-equal expression (`left >= right`).
|
|
228
|
+
*
|
|
229
|
+
* @param left - The left operand.
|
|
230
|
+
* @param right - The right operand.
|
|
231
|
+
* @returns A `BinaryExpressionNode`.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* gte(users.score, 100);
|
|
235
|
+
*/
|
|
236
|
+
export function gte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
237
|
+
export function gte(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
|
|
238
|
+
export function gte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
|
|
239
|
+
return createBinaryExpression('>=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Creates a less-than expression (`left < right`).
|
|
244
|
+
*
|
|
245
|
+
* @param left - The left operand.
|
|
246
|
+
* @param right - The right operand.
|
|
247
|
+
* @returns A `BinaryExpressionNode`.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* lt(inventory.stock, 5);
|
|
251
|
+
*/
|
|
252
|
+
export function lt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
253
|
+
export function lt(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
|
|
254
|
+
export function lt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
|
|
255
|
+
return createBinaryExpression('<', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Creates a less-than-or-equal expression (`left <= right`).
|
|
260
|
+
*
|
|
261
|
+
* @param left - The left operand.
|
|
262
|
+
* @param right - The right operand.
|
|
263
|
+
* @returns A `BinaryExpressionNode`.
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* lte(products.price, 50.00);
|
|
267
|
+
*/
|
|
268
|
+
export function lte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
269
|
+
export function lte(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
|
|
270
|
+
export function lte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
|
|
271
|
+
return createBinaryExpression('<=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Creates a `LIKE` pattern matching expression.
|
|
276
|
+
*
|
|
277
|
+
* @param left - The column or expression to check.
|
|
278
|
+
* @param pattern - The pattern string (e.g., 'A%').
|
|
279
|
+
* @param escape - Optional escape character.
|
|
280
|
+
* @returns A `BinaryExpressionNode`.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* like(users.email, '%@gmail.com');
|
|
220
284
|
*/
|
|
221
285
|
export const like = (left: OperandNode | ColumnRef, pattern: string, escape?: string): BinaryExpressionNode =>
|
|
222
286
|
createBinaryExpression('LIKE', left, pattern, escape);
|
|
223
287
|
|
|
224
288
|
/**
|
|
225
|
-
* Creates a NOT LIKE pattern matching expression
|
|
226
|
-
*
|
|
227
|
-
* @param
|
|
228
|
-
* @param
|
|
229
|
-
* @
|
|
289
|
+
* Creates a `NOT LIKE` pattern matching expression.
|
|
290
|
+
*
|
|
291
|
+
* @param left - The column or expression to check.
|
|
292
|
+
* @param pattern - The pattern string.
|
|
293
|
+
* @param escape - Optional escape character.
|
|
294
|
+
* @returns A `BinaryExpressionNode`.
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* notLike(users.email, 'test%');
|
|
230
298
|
*/
|
|
231
299
|
export const notLike = (left: OperandNode | ColumnRef, pattern: string, escape?: string): BinaryExpressionNode =>
|
|
232
300
|
createBinaryExpression('NOT LIKE', left, pattern, escape);
|
|
233
301
|
|
|
234
302
|
/**
|
|
235
|
-
* Creates a logical AND expression
|
|
236
|
-
*
|
|
237
|
-
* @
|
|
303
|
+
* Creates a logical AND expression to combine multiple conditions.
|
|
304
|
+
*
|
|
305
|
+
* @param operands - One or more conditions to combine.
|
|
306
|
+
* @returns A `LogicalExpressionNode`.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* and(
|
|
310
|
+
* eq(users.isActive, true),
|
|
311
|
+
* gt(users.age, 18)
|
|
312
|
+
* );
|
|
238
313
|
*/
|
|
239
314
|
export const and = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
|
|
240
315
|
type: 'LogicalExpression',
|
|
@@ -243,9 +318,16 @@ export const and = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
|
|
|
243
318
|
});
|
|
244
319
|
|
|
245
320
|
/**
|
|
246
|
-
* Creates a logical OR expression
|
|
247
|
-
*
|
|
248
|
-
* @
|
|
321
|
+
* Creates a logical OR expression to combine multiple conditions.
|
|
322
|
+
*
|
|
323
|
+
* @param operands - One or more conditions to combine.
|
|
324
|
+
* @returns A `LogicalExpressionNode`.
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* or(
|
|
328
|
+
* eq(users.role, 'admin'),
|
|
329
|
+
* eq(users.role, 'moderator')
|
|
330
|
+
* );
|
|
249
331
|
*/
|
|
250
332
|
export const or = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
|
|
251
333
|
type: 'LogicalExpression',
|
|
@@ -254,9 +336,13 @@ export const or = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
|
|
|
254
336
|
});
|
|
255
337
|
|
|
256
338
|
/**
|
|
257
|
-
* Creates an IS NULL
|
|
258
|
-
*
|
|
259
|
-
* @
|
|
339
|
+
* Creates an IS NULL check (`left IS NULL`).
|
|
340
|
+
*
|
|
341
|
+
* @param left - The operand to check.
|
|
342
|
+
* @returns A `NullExpressionNode`.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* isNull(users.deletedAt);
|
|
260
346
|
*/
|
|
261
347
|
export const isNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
|
|
262
348
|
type: 'NullExpression',
|
|
@@ -265,9 +351,13 @@ export const isNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
|
|
|
265
351
|
});
|
|
266
352
|
|
|
267
353
|
/**
|
|
268
|
-
* Creates an IS NOT NULL
|
|
269
|
-
*
|
|
270
|
-
* @
|
|
354
|
+
* Creates an IS NOT NULL check (`left IS NOT NULL`).
|
|
355
|
+
*
|
|
356
|
+
* @param left - The operand to check.
|
|
357
|
+
* @returns A `NullExpressionNode`.
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* isNotNull(users.email);
|
|
271
361
|
*/
|
|
272
362
|
export const isNotNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
|
|
273
363
|
type: 'NullExpression',
|
|
@@ -287,26 +377,60 @@ const createInExpression = (
|
|
|
287
377
|
});
|
|
288
378
|
|
|
289
379
|
/**
|
|
290
|
-
* Creates an IN
|
|
291
|
-
*
|
|
292
|
-
* @param
|
|
293
|
-
* @
|
|
380
|
+
* Creates an IN list check (`left IN (v1, v2, ...)`).
|
|
381
|
+
*
|
|
382
|
+
* @param left - The operand to check.
|
|
383
|
+
* @param values - An array of values to check against.
|
|
384
|
+
* @returns An `InExpressionNode`.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* inList(users.status, ['active', 'pending']);
|
|
294
388
|
*/
|
|
295
389
|
export const inList = (left: OperandNode | ColumnRef, values: (string | number | LiteralNode)[]): InExpressionNode =>
|
|
296
390
|
createInExpression('IN', left, values.map(v => toOperand(v)));
|
|
297
391
|
|
|
298
392
|
/**
|
|
299
|
-
* Creates a NOT IN
|
|
300
|
-
*
|
|
301
|
-
* @param
|
|
302
|
-
* @
|
|
393
|
+
* Creates a NOT IN list check (`left NOT IN (v1, v2, ...)`).
|
|
394
|
+
*
|
|
395
|
+
* @param left - The operand to check.
|
|
396
|
+
* @param values - An array of values to check against.
|
|
397
|
+
* @returns An `InExpressionNode`.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* notInList(users.id, [1, 2, 3]);
|
|
303
401
|
*/
|
|
304
402
|
export const notInList = (left: OperandNode | ColumnRef, values: (string | number | LiteralNode)[]): InExpressionNode =>
|
|
305
403
|
createInExpression('NOT IN', left, values.map(v => toOperand(v)));
|
|
306
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Creates an IN subquery check (`left IN (SELECT ...)`).
|
|
407
|
+
*
|
|
408
|
+
* @param left - The operand to check.
|
|
409
|
+
* @param subquery - The subquery to run.
|
|
410
|
+
* @returns An `InExpressionNode`.
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* inSubquery(
|
|
414
|
+
* posts.authorId,
|
|
415
|
+
* selectFromEntity(User).select({ id: users.id }).where(eq(users.isActive, true))
|
|
416
|
+
* );
|
|
417
|
+
*/
|
|
307
418
|
export const inSubquery = (left: OperandNode | ColumnRef, subquery: SelectQueryInput): InExpressionNode =>
|
|
308
419
|
createInExpression('IN', left, toScalarSubqueryNode(subquery));
|
|
309
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Creates a NOT IN subquery check (`left NOT IN (SELECT ...)`).
|
|
423
|
+
*
|
|
424
|
+
* @param left - The operand to check.
|
|
425
|
+
* @param subquery - The subquery to run.
|
|
426
|
+
* @returns An `InExpressionNode`.
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* notInSubquery(
|
|
430
|
+
* users.id,
|
|
431
|
+
* selectFromEntity(Blacklist).select({ userId: blacklist.userId })
|
|
432
|
+
* );
|
|
433
|
+
*/
|
|
310
434
|
export const notInSubquery = (left: OperandNode | ColumnRef, subquery: SelectQueryInput): InExpressionNode =>
|
|
311
435
|
createInExpression('NOT IN', left, toScalarSubqueryNode(subquery));
|
|
312
436
|
|
|
@@ -324,11 +448,15 @@ const createBetweenExpression = (
|
|
|
324
448
|
});
|
|
325
449
|
|
|
326
450
|
/**
|
|
327
|
-
* Creates a BETWEEN
|
|
328
|
-
*
|
|
329
|
-
* @param
|
|
330
|
-
* @param
|
|
331
|
-
* @
|
|
451
|
+
* Creates a BETWEEN check (`left BETWEEN lower AND upper`).
|
|
452
|
+
*
|
|
453
|
+
* @param left - The operand to check.
|
|
454
|
+
* @param lower - The lower bound (inclusive).
|
|
455
|
+
* @param upper - The upper bound (inclusive).
|
|
456
|
+
* @returns A `BetweenExpressionNode`.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* between(products.price, 10, 100);
|
|
332
460
|
*/
|
|
333
461
|
export const between = (
|
|
334
462
|
left: OperandNode | ColumnRef,
|
|
@@ -337,11 +465,15 @@ export const between = (
|
|
|
337
465
|
): BetweenExpressionNode => createBetweenExpression('BETWEEN', left, lower, upper);
|
|
338
466
|
|
|
339
467
|
/**
|
|
340
|
-
* Creates a NOT BETWEEN
|
|
341
|
-
*
|
|
342
|
-
* @param
|
|
343
|
-
* @param
|
|
344
|
-
* @
|
|
468
|
+
* Creates a NOT BETWEEN check (`left NOT BETWEEN lower AND upper`).
|
|
469
|
+
*
|
|
470
|
+
* @param left - The operand to check.
|
|
471
|
+
* @param lower - The lower bound (inclusive).
|
|
472
|
+
* @param upper - The upper bound (inclusive).
|
|
473
|
+
* @returns A `BetweenExpressionNode`.
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* notBetween(users.age, 20, 30);
|
|
345
477
|
*/
|
|
346
478
|
export const notBetween = (
|
|
347
479
|
left: OperandNode | ColumnRef,
|
|
@@ -360,21 +492,49 @@ const createArithmeticExpression = (
|
|
|
360
492
|
right: toOperand(right)
|
|
361
493
|
});
|
|
362
494
|
|
|
495
|
+
/**
|
|
496
|
+
* Creates an addition expression (`left + right`).
|
|
497
|
+
*
|
|
498
|
+
* @param left - The left operand.
|
|
499
|
+
* @param right - The right operand.
|
|
500
|
+
* @returns An `ArithmeticExpressionNode`.
|
|
501
|
+
*/
|
|
363
502
|
export const add = (
|
|
364
503
|
left: OperandNode | ColumnRef,
|
|
365
504
|
right: OperandNode | ColumnRef | string | number
|
|
366
505
|
): ArithmeticExpressionNode => createArithmeticExpression('+', left, right);
|
|
367
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Creates a subtraction expression (`left - right`).
|
|
509
|
+
*
|
|
510
|
+
* @param left - The left operand.
|
|
511
|
+
* @param right - The right operand.
|
|
512
|
+
* @returns An `ArithmeticExpressionNode`.
|
|
513
|
+
*/
|
|
368
514
|
export const sub = (
|
|
369
515
|
left: OperandNode | ColumnRef,
|
|
370
516
|
right: OperandNode | ColumnRef | string | number
|
|
371
517
|
): ArithmeticExpressionNode => createArithmeticExpression('-', left, right);
|
|
372
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Creates a multiplication expression (`left * right`).
|
|
521
|
+
*
|
|
522
|
+
* @param left - The left operand.
|
|
523
|
+
* @param right - The right operand.
|
|
524
|
+
* @returns An `ArithmeticExpressionNode`.
|
|
525
|
+
*/
|
|
373
526
|
export const mul = (
|
|
374
527
|
left: OperandNode | ColumnRef,
|
|
375
528
|
right: OperandNode | ColumnRef | string | number
|
|
376
529
|
): ArithmeticExpressionNode => createArithmeticExpression('*', left, right);
|
|
377
530
|
|
|
531
|
+
/**
|
|
532
|
+
* Creates a division expression (`left / right`).
|
|
533
|
+
*
|
|
534
|
+
* @param left - The left operand.
|
|
535
|
+
* @param right - The right operand.
|
|
536
|
+
* @returns An `ArithmeticExpressionNode`.
|
|
537
|
+
*/
|
|
378
538
|
export const div = (
|
|
379
539
|
left: OperandNode | ColumnRef,
|
|
380
540
|
right: OperandNode | ColumnRef | string | number
|
|
@@ -392,7 +552,11 @@ const createBitwiseExpression = (
|
|
|
392
552
|
});
|
|
393
553
|
|
|
394
554
|
/**
|
|
395
|
-
* Creates a bitwise AND expression (left & right)
|
|
555
|
+
* Creates a bitwise AND expression (`left & right`).
|
|
556
|
+
*
|
|
557
|
+
* @param left - The left operand.
|
|
558
|
+
* @param right - The right operand.
|
|
559
|
+
* @returns A `BitwiseExpressionNode`.
|
|
396
560
|
*/
|
|
397
561
|
export const bitAnd = (
|
|
398
562
|
left: OperandNode | ColumnRef,
|
|
@@ -400,7 +564,11 @@ export const bitAnd = (
|
|
|
400
564
|
): BitwiseExpressionNode => createBitwiseExpression('&', left, right);
|
|
401
565
|
|
|
402
566
|
/**
|
|
403
|
-
* Creates a bitwise OR expression (left | right)
|
|
567
|
+
* Creates a bitwise OR expression (`left | right`).
|
|
568
|
+
*
|
|
569
|
+
* @param left - The left operand.
|
|
570
|
+
* @param right - The right operand.
|
|
571
|
+
* @returns A `BitwiseExpressionNode`.
|
|
404
572
|
*/
|
|
405
573
|
export const bitOr = (
|
|
406
574
|
left: OperandNode | ColumnRef,
|
|
@@ -408,7 +576,11 @@ export const bitOr = (
|
|
|
408
576
|
): BitwiseExpressionNode => createBitwiseExpression('|', left, right);
|
|
409
577
|
|
|
410
578
|
/**
|
|
411
|
-
* Creates a bitwise XOR expression (left ^ right)
|
|
579
|
+
* Creates a bitwise XOR expression (`left ^ right`).
|
|
580
|
+
*
|
|
581
|
+
* @param left - The left operand.
|
|
582
|
+
* @param right - The right operand.
|
|
583
|
+
* @returns A `BitwiseExpressionNode`.
|
|
412
584
|
*/
|
|
413
585
|
export const bitXor = (
|
|
414
586
|
left: OperandNode | ColumnRef,
|
|
@@ -416,7 +588,11 @@ export const bitXor = (
|
|
|
416
588
|
): BitwiseExpressionNode => createBitwiseExpression('^', left, right);
|
|
417
589
|
|
|
418
590
|
/**
|
|
419
|
-
* Creates a bitwise shift
|
|
591
|
+
* Creates a bitwise left-shift expression (`left << right`).
|
|
592
|
+
*
|
|
593
|
+
* @param left - The left operand.
|
|
594
|
+
* @param right - The right operand (number of bits).
|
|
595
|
+
* @returns A `BitwiseExpressionNode`.
|
|
420
596
|
*/
|
|
421
597
|
export const shiftLeft = (
|
|
422
598
|
left: OperandNode | ColumnRef,
|
|
@@ -424,7 +600,11 @@ export const shiftLeft = (
|
|
|
424
600
|
): BitwiseExpressionNode => createBitwiseExpression('<<', left, right);
|
|
425
601
|
|
|
426
602
|
/**
|
|
427
|
-
* Creates a bitwise shift
|
|
603
|
+
* Creates a bitwise right-shift expression (`left >> right`).
|
|
604
|
+
*
|
|
605
|
+
* @param left - The left operand.
|
|
606
|
+
* @param right - The right operand (number of bits).
|
|
607
|
+
* @returns A `BitwiseExpressionNode`.
|
|
428
608
|
*/
|
|
429
609
|
export const shiftRight = (
|
|
430
610
|
left: OperandNode | ColumnRef,
|
|
@@ -432,10 +612,14 @@ export const shiftRight = (
|
|
|
432
612
|
): BitwiseExpressionNode => createBitwiseExpression('>>', left, right);
|
|
433
613
|
|
|
434
614
|
/**
|
|
435
|
-
* Creates a JSON path expression
|
|
436
|
-
*
|
|
437
|
-
* @param
|
|
438
|
-
* @
|
|
615
|
+
* Creates a JSON path extraction expression.
|
|
616
|
+
*
|
|
617
|
+
* @param col - The source column (should be a JSON/JSONB column).
|
|
618
|
+
* @param path - The JSON path expression (e.g., '$.address.city').
|
|
619
|
+
* @returns A `JsonPathNode`.
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* jsonPath(users.profile, '$.settings.theme');
|
|
439
623
|
*/
|
|
440
624
|
export const jsonPath = (col: ColumnRef | ColumnNode, path: string): JsonPathNode => ({
|
|
441
625
|
type: 'JsonPath',
|
|
@@ -444,10 +628,17 @@ export const jsonPath = (col: ColumnRef | ColumnNode, path: string): JsonPathNod
|
|
|
444
628
|
});
|
|
445
629
|
|
|
446
630
|
/**
|
|
447
|
-
* Creates a CASE expression
|
|
448
|
-
*
|
|
449
|
-
* @param
|
|
450
|
-
* @
|
|
631
|
+
* Creates a CASE expression (`CASE WHEN ... THEN ... ELSE ... END`).
|
|
632
|
+
*
|
|
633
|
+
* @param conditions - An array of `{ when, then }` objects.
|
|
634
|
+
* @param elseValue - Optional value for the `ELSE` clause.
|
|
635
|
+
* @returns A `CaseExpressionNode`.
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* caseWhen([
|
|
639
|
+
* { when: gt(users.age, 65), then: 'Senior' },
|
|
640
|
+
* { when: gt(users.age, 18), then: 'Adult' }
|
|
641
|
+
* ], 'Minor');
|
|
451
642
|
*/
|
|
452
643
|
export const caseWhen = (
|
|
453
644
|
conditions: { when: ExpressionNode; then: OperandNode | ColumnRef | string | number | boolean | null }[],
|
|
@@ -462,7 +653,14 @@ export const caseWhen = (
|
|
|
462
653
|
});
|
|
463
654
|
|
|
464
655
|
/**
|
|
465
|
-
*
|
|
656
|
+
* Creates a CAST expression (`CAST(expression AS type)`).
|
|
657
|
+
*
|
|
658
|
+
* @param expression - The expression to cast.
|
|
659
|
+
* @param castType - The target SQL type (e.g., 'VARCHAR', 'INTEGER').
|
|
660
|
+
* @returns A `CastExpressionNode`.
|
|
661
|
+
*
|
|
662
|
+
* @example
|
|
663
|
+
* cast(users.age, 'VARCHAR');
|
|
466
664
|
*/
|
|
467
665
|
export const cast = (
|
|
468
666
|
expression: OperandNode | ColumnRef | string | number | boolean | null,
|
|
@@ -474,9 +672,15 @@ export const cast = (
|
|
|
474
672
|
});
|
|
475
673
|
|
|
476
674
|
/**
|
|
477
|
-
* Creates an EXISTS
|
|
478
|
-
*
|
|
479
|
-
* @
|
|
675
|
+
* Creates an EXISTS check (`EXISTS (SELECT ...)`).
|
|
676
|
+
*
|
|
677
|
+
* @param subquery - The subquery to check.
|
|
678
|
+
* @returns An `ExistsExpressionNode`.
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* exists(
|
|
682
|
+
* selectFromEntity(Order).where(eq(orders.userId, users.id))
|
|
683
|
+
* );
|
|
480
684
|
*/
|
|
481
685
|
export const exists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
|
|
482
686
|
type: 'ExistsExpression',
|
|
@@ -485,9 +689,15 @@ export const exists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
|
|
|
485
689
|
});
|
|
486
690
|
|
|
487
691
|
/**
|
|
488
|
-
* Creates a NOT EXISTS
|
|
489
|
-
*
|
|
490
|
-
* @
|
|
692
|
+
* Creates a NOT EXISTS check (`NOT EXISTS (SELECT ...)`).
|
|
693
|
+
*
|
|
694
|
+
* @param subquery - The subquery to check.
|
|
695
|
+
* @returns An `ExistsExpressionNode`.
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* notExists(
|
|
699
|
+
* selectFromEntity(Subscription).where(eq(subscriptions.userId, users.id))
|
|
700
|
+
* );
|
|
491
701
|
*/
|
|
492
702
|
export const notExists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
|
|
493
703
|
type: 'ExistsExpression',
|
|
@@ -496,10 +706,14 @@ export const notExists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
|
|
|
496
706
|
});
|
|
497
707
|
|
|
498
708
|
/**
|
|
499
|
-
* Creates a COLLATE expression (expression COLLATE
|
|
500
|
-
*
|
|
501
|
-
* @param
|
|
502
|
-
* @
|
|
709
|
+
* Creates a COLLATE expression (`expression COLLATE collation`).
|
|
710
|
+
*
|
|
711
|
+
* @param expression - The expression string.
|
|
712
|
+
* @param collation - The collation name (e.g., 'nocase').
|
|
713
|
+
* @returns A `CollateExpressionNode`.
|
|
714
|
+
*
|
|
715
|
+
* @example
|
|
716
|
+
* collate(users.email, 'nocase');
|
|
503
717
|
*/
|
|
504
718
|
export const collate = (
|
|
505
719
|
expression: OperandNode | ColumnRef | string | number | boolean | null,
|