metal-orm 1.0.42 → 1.0.44
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 +195 -37
- package/dist/index.cjs +1014 -538
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1267 -371
- package/dist/index.d.ts +1267 -371
- package/dist/index.js +1012 -536
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/scripts/run-eslint.mjs +34 -0
- package/src/codegen/typescript.ts +32 -15
- package/src/core/ast/adapters.ts +8 -2
- package/src/core/ast/builders.ts +105 -76
- package/src/core/ast/expression-builders.ts +430 -392
- package/src/core/ast/expression-nodes.ts +14 -5
- package/src/core/ast/expression-visitor.ts +56 -14
- package/src/core/ast/helpers.ts +23 -0
- package/src/core/ast/join-node.ts +18 -2
- package/src/core/ast/query.ts +6 -6
- package/src/core/ast/window-functions.ts +10 -2
- package/src/core/ddl/dialects/base-schema-dialect.ts +37 -4
- package/src/core/ddl/dialects/index.ts +1 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +5 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +3 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +14 -1
- package/src/core/ddl/dialects/render-reference.test.ts +69 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +10 -0
- package/src/core/ddl/introspect/catalogs/index.ts +1 -0
- package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
- package/src/core/ddl/introspect/context.ts +6 -0
- package/src/core/ddl/introspect/functions/postgres.ts +13 -0
- package/src/core/ddl/introspect/mssql.ts +53 -8
- package/src/core/ddl/introspect/mysql.ts +32 -6
- package/src/core/ddl/introspect/postgres.ts +102 -34
- package/src/core/ddl/introspect/registry.ts +14 -0
- package/src/core/ddl/introspect/run-select.ts +19 -4
- package/src/core/ddl/introspect/sqlite.ts +78 -11
- package/src/core/ddl/introspect/types.ts +0 -1
- package/src/core/ddl/introspect/utils.ts +21 -3
- package/src/core/ddl/naming-strategy.ts +6 -0
- package/src/core/ddl/schema-dialect.ts +20 -6
- package/src/core/ddl/schema-diff.ts +22 -0
- package/src/core/ddl/schema-generator.ts +26 -12
- package/src/core/ddl/schema-plan-executor.ts +6 -0
- package/src/core/ddl/schema-types.ts +6 -0
- package/src/core/ddl/sql-writing.ts +4 -4
- package/src/core/dialect/abstract.ts +19 -7
- package/src/core/dialect/base/function-table-formatter.ts +3 -2
- package/src/core/dialect/base/join-compiler.ts +5 -3
- package/src/core/dialect/base/returning-strategy.ts +1 -0
- package/src/core/dialect/base/sql-dialect.ts +3 -3
- package/src/core/dialect/mssql/functions.ts +24 -25
- package/src/core/dialect/mssql/index.ts +1 -4
- package/src/core/dialect/mysql/functions.ts +0 -1
- package/src/core/dialect/postgres/functions.ts +33 -34
- package/src/core/dialect/postgres/index.ts +1 -0
- package/src/core/dialect/sqlite/functions.ts +18 -19
- package/src/core/dialect/sqlite/index.ts +2 -0
- package/src/core/execution/db-executor.ts +1 -1
- package/src/core/execution/executors/mysql-executor.ts +2 -2
- package/src/core/execution/executors/postgres-executor.ts +1 -1
- package/src/core/execution/pooling/pool.ts +12 -5
- package/src/core/functions/datetime.ts +58 -34
- package/src/core/functions/numeric.ts +96 -31
- package/src/core/functions/standard-strategy.ts +35 -0
- package/src/core/functions/text.ts +84 -23
- package/src/core/functions/types.ts +23 -8
- package/src/decorators/bootstrap.ts +42 -11
- package/src/decorators/column.ts +20 -11
- package/src/decorators/decorator-metadata.ts +30 -9
- package/src/decorators/entity.ts +29 -5
- package/src/decorators/index.ts +3 -0
- package/src/decorators/relations.ts +34 -11
- package/src/orm/als.ts +34 -9
- package/src/orm/entity-context.ts +62 -8
- package/src/orm/entity-meta.ts +8 -8
- package/src/orm/entity-metadata.ts +131 -16
- package/src/orm/entity.ts +28 -29
- package/src/orm/execute.ts +19 -4
- package/src/orm/hydration.ts +42 -39
- package/src/orm/identity-map.ts +1 -1
- package/src/orm/lazy-batch.ts +74 -104
- package/src/orm/orm-session.ts +24 -23
- package/src/orm/orm.ts +2 -5
- package/src/orm/relation-change-processor.ts +12 -11
- package/src/orm/relations/belongs-to.ts +11 -11
- package/src/orm/relations/has-many.ts +54 -10
- package/src/orm/relations/has-one.ts +8 -7
- package/src/orm/relations/many-to-many.ts +13 -13
- package/src/orm/runtime-types.ts +4 -4
- package/src/orm/save-graph.ts +31 -25
- package/src/orm/unit-of-work.ts +17 -17
- package/src/query/index.ts +74 -0
- package/src/query/target.ts +46 -0
- package/src/query-builder/delete-query-state.ts +30 -0
- package/src/query-builder/delete.ts +64 -18
- package/src/query-builder/hydration-manager.ts +52 -5
- package/src/query-builder/insert-query-state.ts +30 -0
- package/src/query-builder/insert.ts +58 -10
- package/src/query-builder/query-ast-service.ts +7 -2
- package/src/query-builder/query-resolution.ts +78 -0
- package/src/query-builder/raw-column-parser.ts +7 -1
- package/src/query-builder/relation-alias.ts +7 -0
- package/src/query-builder/relation-conditions.ts +61 -48
- package/src/query-builder/relation-service.ts +68 -63
- package/src/query-builder/relation-utils.ts +3 -0
- package/src/query-builder/select/cte-facet.ts +40 -0
- package/src/query-builder/select/from-facet.ts +80 -0
- package/src/query-builder/select/join-facet.ts +62 -0
- package/src/query-builder/select/predicate-facet.ts +103 -0
- package/src/query-builder/select/projection-facet.ts +69 -0
- package/src/query-builder/select/relation-facet.ts +81 -0
- package/src/query-builder/select/setop-facet.ts +36 -0
- package/src/query-builder/select-helpers.ts +15 -2
- package/src/query-builder/select-query-builder-deps.ts +19 -1
- package/src/query-builder/select-query-state.ts +2 -1
- package/src/query-builder/select.ts +795 -1163
- package/src/query-builder/update-query-state.ts +52 -0
- package/src/query-builder/update.ts +69 -18
- package/src/schema/column.ts +26 -26
- package/src/schema/table-guards.ts +31 -0
- package/src/schema/table.ts +47 -18
- package/src/schema/types.ts +22 -22
|
@@ -8,7 +8,7 @@ export interface MysqlClientLike {
|
|
|
8
8
|
query(
|
|
9
9
|
sql: string,
|
|
10
10
|
params?: unknown[]
|
|
11
|
-
): Promise<[
|
|
11
|
+
): Promise<[unknown, unknown?]>; // rows, metadata
|
|
12
12
|
beginTransaction?(): Promise<void>;
|
|
13
13
|
commit?(): Promise<void>;
|
|
14
14
|
rollback?(): Promise<void>;
|
|
@@ -27,7 +27,7 @@ export function createMysqlExecutor(
|
|
|
27
27
|
transactions: supportsTransactions,
|
|
28
28
|
},
|
|
29
29
|
async executeSql(sql, params) {
|
|
30
|
-
const [rows] = await client.query(sql, params
|
|
30
|
+
const [rows] = await client.query(sql, params);
|
|
31
31
|
|
|
32
32
|
if (!Array.isArray(rows)) {
|
|
33
33
|
// e.g. insert/update returning only headers, treat as no rows
|
|
@@ -16,7 +16,7 @@ export function createPostgresExecutor(
|
|
|
16
16
|
): DbExecutor {
|
|
17
17
|
return createExecutorFromQueryRunner({
|
|
18
18
|
async query(sql, params) {
|
|
19
|
-
const { rows } = await client.query(sql, params
|
|
19
|
+
const { rows } = await client.query(sql, params);
|
|
20
20
|
return rows;
|
|
21
21
|
},
|
|
22
22
|
async beginTransaction() {
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { PoolAdapter, PoolLease, PoolOptions } from './pool-types.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Node.js Timer with optional unref method (for preventing event loop from staying alive)
|
|
5
|
+
*/
|
|
6
|
+
type NodeTimer = ReturnType<typeof setInterval> & {
|
|
7
|
+
unref?: () => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
3
10
|
type Deferred<T> = {
|
|
4
11
|
promise: Promise<T>;
|
|
5
12
|
resolve: (value: T) => void;
|
|
@@ -49,7 +56,7 @@ export class Pool<TResource> {
|
|
|
49
56
|
}, interval);
|
|
50
57
|
|
|
51
58
|
// Best-effort: avoid keeping the event loop alive.
|
|
52
|
-
(this.reapTimer as
|
|
59
|
+
(this.reapTimer as NodeTimer).unref?.();
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
// Best-effort warmup.
|
|
@@ -92,15 +99,16 @@ export class Pool<TResource> {
|
|
|
92
99
|
this.waiters.push(waiter);
|
|
93
100
|
|
|
94
101
|
const timeout = this.options.acquireTimeoutMillis;
|
|
95
|
-
let timer:
|
|
102
|
+
let timer: NodeTimer | null = null;
|
|
96
103
|
if (timeout && timeout > 0) {
|
|
97
104
|
timer = setTimeout(() => {
|
|
98
105
|
// Remove from queue if still waiting.
|
|
99
106
|
const idx = this.waiters.indexOf(waiter);
|
|
100
107
|
if (idx >= 0) this.waiters.splice(idx, 1);
|
|
101
108
|
waiter.reject(new Error('Pool acquire timeout'));
|
|
102
|
-
}, timeout);
|
|
103
|
-
|
|
109
|
+
}, timeout) as NodeTimer;
|
|
110
|
+
// Best-effort: avoid keeping the event loop alive.
|
|
111
|
+
timer.unref?.();
|
|
104
112
|
}
|
|
105
113
|
|
|
106
114
|
try {
|
|
@@ -265,4 +273,3 @@ export class Pool<TResource> {
|
|
|
265
273
|
}
|
|
266
274
|
}
|
|
267
275
|
}
|
|
268
|
-
|
|
@@ -6,7 +6,7 @@ import { FunctionNode, OperandNode, isOperandNode } from '../ast/expression.js';
|
|
|
6
6
|
|
|
7
7
|
type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
|
|
8
8
|
|
|
9
|
-
const isColumnDef = (val:
|
|
9
|
+
const isColumnDef = (val: unknown): val is ColumnDef => !!val && typeof val === 'object' && 'type' in val && 'name' in val;
|
|
10
10
|
|
|
11
11
|
const toOperand = (input: OperandInput): OperandNode => {
|
|
12
12
|
if (isOperandNode(input)) return input;
|
|
@@ -26,108 +26,132 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
|
|
|
26
26
|
// ----------------------
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Returns the current local date and time.
|
|
30
|
+
* @returns A FunctionNode representing the NOW() SQL function.
|
|
30
31
|
*/
|
|
31
32
|
export const now = (): FunctionNode => fn('NOW', []);
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
*
|
|
35
|
+
* Returns the current date without time.
|
|
36
|
+
* @returns A FunctionNode representing the CURRENT_DATE SQL function.
|
|
35
37
|
*/
|
|
36
38
|
export const currentDate = (): FunctionNode => fn('CURRENT_DATE', []);
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
*
|
|
41
|
+
* Returns the current time without date.
|
|
42
|
+
* @returns A FunctionNode representing the CURRENT_TIME SQL function.
|
|
40
43
|
*/
|
|
41
44
|
export const currentTime = (): FunctionNode => fn('CURRENT_TIME', []);
|
|
42
45
|
|
|
43
46
|
/**
|
|
44
|
-
*
|
|
47
|
+
* Returns the current UTC date and time.
|
|
48
|
+
* @returns A FunctionNode representing the UTC_NOW() SQL function.
|
|
45
49
|
*/
|
|
46
50
|
export const utcNow = (): FunctionNode => fn('UTC_NOW', []);
|
|
47
51
|
|
|
48
52
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @param part - The date part to extract (e.g., 'YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE', 'SECOND')
|
|
51
|
-
* @param date - The date
|
|
53
|
+
* Extracts a specified part from a date or datetime value.
|
|
54
|
+
* @param part - The date part to extract (e.g., 'YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE', 'SECOND').
|
|
55
|
+
* @param date - The date or datetime value to extract from.
|
|
56
|
+
* @returns A FunctionNode representing the EXTRACT SQL function.
|
|
52
57
|
*/
|
|
53
58
|
export const extract = (part: OperandInput, date: OperandInput): FunctionNode => fn('EXTRACT', [part, date]);
|
|
54
59
|
|
|
55
60
|
/**
|
|
56
|
-
*
|
|
61
|
+
* Extracts the year from a date or datetime value.
|
|
62
|
+
* @param date - The date or datetime value.
|
|
63
|
+
* @returns A FunctionNode representing the YEAR SQL function.
|
|
57
64
|
*/
|
|
58
65
|
export const year = (date: OperandInput): FunctionNode => fn('YEAR', [date]);
|
|
59
66
|
|
|
60
67
|
/**
|
|
61
|
-
*
|
|
68
|
+
* Extracts the month from a date or datetime value.
|
|
69
|
+
* @param date - The date or datetime value.
|
|
70
|
+
* @returns A FunctionNode representing the MONTH SQL function.
|
|
62
71
|
*/
|
|
63
72
|
export const month = (date: OperandInput): FunctionNode => fn('MONTH', [date]);
|
|
64
73
|
|
|
65
74
|
/**
|
|
66
|
-
*
|
|
75
|
+
* Extracts the day of the month from a date or datetime value.
|
|
76
|
+
* @param date - The date or datetime value.
|
|
77
|
+
* @returns A FunctionNode representing the DAY SQL function.
|
|
67
78
|
*/
|
|
68
79
|
export const day = (date: OperandInput): FunctionNode => fn('DAY', [date]);
|
|
69
80
|
|
|
70
81
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param date - The date
|
|
73
|
-
* @param interval - The number of units to add
|
|
74
|
-
* @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND')
|
|
82
|
+
* Adds a specified time interval to a date or datetime value.
|
|
83
|
+
* @param date - The date or datetime value to add to.
|
|
84
|
+
* @param interval - The number of units to add.
|
|
85
|
+
* @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND').
|
|
86
|
+
* @returns A FunctionNode representing the DATE_ADD SQL function.
|
|
75
87
|
*/
|
|
76
88
|
export const dateAdd = (date: OperandInput, interval: OperandInput, unit: OperandInput): FunctionNode =>
|
|
77
89
|
fn('DATE_ADD', [date, interval, unit]);
|
|
78
90
|
|
|
79
91
|
/**
|
|
80
|
-
*
|
|
81
|
-
* @param date - The date
|
|
82
|
-
* @param interval - The number of units to subtract
|
|
83
|
-
* @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND')
|
|
92
|
+
* Subtracts a specified time interval from a date or datetime value.
|
|
93
|
+
* @param date - The date or datetime value to subtract from.
|
|
94
|
+
* @param interval - The number of units to subtract.
|
|
95
|
+
* @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND').
|
|
96
|
+
* @returns A FunctionNode representing the DATE_SUB SQL function.
|
|
84
97
|
*/
|
|
85
98
|
export const dateSub = (date: OperandInput, interval: OperandInput, unit: OperandInput): FunctionNode =>
|
|
86
99
|
fn('DATE_SUB', [date, interval, unit]);
|
|
87
100
|
|
|
88
101
|
/**
|
|
89
|
-
*
|
|
90
|
-
* @param date1 - The end date
|
|
91
|
-
* @param date2 - The start date
|
|
102
|
+
* Returns the difference between two dates in days.
|
|
103
|
+
* @param date1 - The end date.
|
|
104
|
+
* @param date2 - The start date.
|
|
105
|
+
* @returns A FunctionNode representing the DATE_DIFF SQL function.
|
|
92
106
|
*/
|
|
93
107
|
export const dateDiff = (date1: OperandInput, date2: OperandInput): FunctionNode => fn('DATE_DIFF', [date1, date2]);
|
|
94
108
|
|
|
95
109
|
/**
|
|
96
|
-
*
|
|
97
|
-
* @param date - The date
|
|
98
|
-
* @param format - The format string (dialect-specific)
|
|
110
|
+
* Converts a date or datetime value to a formatted string.
|
|
111
|
+
* @param date - The date or datetime value to format.
|
|
112
|
+
* @param format - The format string (dialect-specific).
|
|
113
|
+
* @returns A FunctionNode representing the DATE_FORMAT SQL function.
|
|
99
114
|
*/
|
|
100
115
|
export const dateFormat = (date: OperandInput, format: OperandInput): FunctionNode => fn('DATE_FORMAT', [date, format]);
|
|
101
116
|
|
|
102
117
|
/**
|
|
103
|
-
*
|
|
118
|
+
* Returns the current Unix timestamp (seconds since 1970-01-01 00:00:00 UTC).
|
|
119
|
+
* @returns A FunctionNode representing the UNIX_TIMESTAMP SQL function.
|
|
104
120
|
*/
|
|
105
121
|
export const unixTimestamp = (): FunctionNode => fn('UNIX_TIMESTAMP', []);
|
|
106
122
|
|
|
107
123
|
/**
|
|
108
|
-
*
|
|
109
|
-
* @param timestamp - Unix timestamp in seconds
|
|
124
|
+
* Converts a Unix timestamp (seconds since 1970-01-01 00:00:00 UTC) to a date.
|
|
125
|
+
* @param timestamp - Unix timestamp in seconds.
|
|
126
|
+
* @returns A FunctionNode representing the FROM_UNIXTIME SQL function.
|
|
110
127
|
*/
|
|
111
128
|
export const fromUnixTime = (timestamp: OperandInput): FunctionNode => fn('FROM_UNIXTIME', [timestamp]);
|
|
112
129
|
|
|
113
130
|
/**
|
|
114
|
-
*
|
|
131
|
+
* Returns the last day of the month for a given date.
|
|
132
|
+
* @param date - The date value.
|
|
133
|
+
* @returns A FunctionNode representing the END_OF_MONTH SQL function.
|
|
115
134
|
*/
|
|
116
135
|
export const endOfMonth = (date: OperandInput): FunctionNode => fn('END_OF_MONTH', [date]);
|
|
117
136
|
|
|
118
137
|
/**
|
|
119
|
-
*
|
|
138
|
+
* Returns the index of the weekday for a given date (1 = Sunday, 2 = Monday, etc.).
|
|
139
|
+
* @param date - The date value.
|
|
140
|
+
* @returns A FunctionNode representing the DAY_OF_WEEK SQL function.
|
|
120
141
|
*/
|
|
121
142
|
export const dayOfWeek = (date: OperandInput): FunctionNode => fn('DAY_OF_WEEK', [date]);
|
|
122
143
|
|
|
123
144
|
/**
|
|
124
|
-
*
|
|
145
|
+
* Returns the week number of the year for a given date.
|
|
146
|
+
* @param date - The date value.
|
|
147
|
+
* @returns A FunctionNode representing the WEEK_OF_YEAR SQL function.
|
|
125
148
|
*/
|
|
126
149
|
export const weekOfYear = (date: OperandInput): FunctionNode => fn('WEEK_OF_YEAR', [date]);
|
|
127
150
|
|
|
128
151
|
/**
|
|
129
|
-
*
|
|
130
|
-
* @param part - The truncation precision (e.g., 'YEAR', 'MONTH', 'DAY')
|
|
131
|
-
* @param date - The date
|
|
152
|
+
* Truncates a date or datetime value to a specified precision (e.g., first day of the month/year).
|
|
153
|
+
* @param part - The truncation precision (e.g., 'YEAR', 'MONTH', 'DAY').
|
|
154
|
+
* @param date - The date or datetime value to truncate.
|
|
155
|
+
* @returns A FunctionNode representing the DATE_TRUNC SQL function.
|
|
132
156
|
*/
|
|
133
157
|
export const dateTrunc = (part: OperandInput, date: OperandInput): FunctionNode => fn('DATE_TRUNC', [part, date]);
|
|
@@ -6,7 +6,7 @@ import { FunctionNode, OperandNode, isOperandNode } from '../ast/expression.js';
|
|
|
6
6
|
|
|
7
7
|
type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
|
|
8
8
|
|
|
9
|
-
const isColumnDef = (val:
|
|
9
|
+
const isColumnDef = (val: unknown): val is ColumnDef => !!val && typeof val === 'object' && 'type' in val && 'name' in val;
|
|
10
10
|
|
|
11
11
|
const toOperand = (input: OperandInput): OperandNode => {
|
|
12
12
|
if (isOperandNode(input)) return input;
|
|
@@ -27,154 +27,219 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
|
|
|
27
27
|
// ----------------------
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Returns the absolute value of a number.
|
|
31
|
+
* @param value - The numeric value.
|
|
32
|
+
* @returns A FunctionNode representing the ABS SQL function.
|
|
31
33
|
*/
|
|
32
34
|
export const abs = (value: OperandInput): FunctionNode => fn('ABS', [value]);
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
|
-
*
|
|
37
|
+
* Returns the arccosine (inverse cosine) of a number.
|
|
38
|
+
* @param value - The numeric value.
|
|
39
|
+
* @returns A FunctionNode representing the ACOS SQL function.
|
|
36
40
|
*/
|
|
37
41
|
export const acos = (value: OperandInput): FunctionNode => fn('ACOS', [value]);
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
|
-
*
|
|
44
|
+
* Returns the arcsine (inverse sine) of a number.
|
|
45
|
+
* @param value - The numeric value.
|
|
46
|
+
* @returns A FunctionNode representing the ASIN SQL function.
|
|
41
47
|
*/
|
|
42
48
|
export const asin = (value: OperandInput): FunctionNode => fn('ASIN', [value]);
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
|
-
*
|
|
51
|
+
* Returns the arctangent (inverse tangent) of a number.
|
|
52
|
+
* @param value - The numeric value.
|
|
53
|
+
* @returns A FunctionNode representing the ATAN SQL function.
|
|
46
54
|
*/
|
|
47
55
|
export const atan = (value: OperandInput): FunctionNode => fn('ATAN', [value]);
|
|
48
56
|
|
|
49
57
|
/**
|
|
50
|
-
*
|
|
58
|
+
* Returns the arctangent of the two arguments.
|
|
59
|
+
* @param y - The y-coordinate.
|
|
60
|
+
* @param x - The x-coordinate.
|
|
61
|
+
* @returns A FunctionNode representing the ATAN2 SQL function.
|
|
51
62
|
*/
|
|
52
63
|
export const atan2 = (y: OperandInput, x: OperandInput): FunctionNode => fn('ATAN2', [y, x]);
|
|
53
64
|
|
|
54
65
|
/**
|
|
55
|
-
*
|
|
66
|
+
* Returns the smallest integer greater than or equal to a number.
|
|
67
|
+
* @param value - The numeric value.
|
|
68
|
+
* @returns A FunctionNode representing the CEIL SQL function.
|
|
56
69
|
*/
|
|
57
70
|
export const ceil = (value: OperandInput): FunctionNode => fn('CEIL', [value]);
|
|
58
71
|
|
|
59
72
|
/**
|
|
60
|
-
*
|
|
73
|
+
* Alias for ceil. Returns the smallest integer greater than or equal to a number.
|
|
74
|
+
* @param value - The numeric value.
|
|
75
|
+
* @returns A FunctionNode representing the CEILING SQL function.
|
|
61
76
|
*/
|
|
62
77
|
export const ceiling = (value: OperandInput): FunctionNode => fn('CEILING', [value]);
|
|
63
78
|
|
|
64
79
|
/**
|
|
65
|
-
*
|
|
80
|
+
* Returns the cosine of a number (in radians).
|
|
81
|
+
* @param value - The numeric value in radians.
|
|
82
|
+
* @returns A FunctionNode representing the COS SQL function.
|
|
66
83
|
*/
|
|
67
84
|
export const cos = (value: OperandInput): FunctionNode => fn('COS', [value]);
|
|
68
85
|
|
|
69
86
|
/**
|
|
70
|
-
*
|
|
87
|
+
* Returns the cotangent of a number.
|
|
88
|
+
* @param value - The numeric value.
|
|
89
|
+
* @returns A FunctionNode representing the COT SQL function.
|
|
71
90
|
*/
|
|
72
91
|
export const cot = (value: OperandInput): FunctionNode => fn('COT', [value]);
|
|
73
92
|
|
|
74
93
|
/**
|
|
75
|
-
*
|
|
94
|
+
* Converts radians to degrees.
|
|
95
|
+
* @param value - The angle in radians.
|
|
96
|
+
* @returns A FunctionNode representing the DEGREES SQL function.
|
|
76
97
|
*/
|
|
77
98
|
export const degrees = (value: OperandInput): FunctionNode => fn('DEGREES', [value]);
|
|
78
99
|
|
|
79
100
|
/**
|
|
80
|
-
*
|
|
101
|
+
* Returns e raised to the power of the argument.
|
|
102
|
+
* @param value - The exponent.
|
|
103
|
+
* @returns A FunctionNode representing the EXP SQL function.
|
|
81
104
|
*/
|
|
82
105
|
export const exp = (value: OperandInput): FunctionNode => fn('EXP', [value]);
|
|
83
106
|
|
|
84
107
|
/**
|
|
85
|
-
*
|
|
108
|
+
* Returns the largest integer less than or equal to a number.
|
|
109
|
+
* @param value - The numeric value.
|
|
110
|
+
* @returns A FunctionNode representing the FLOOR SQL function.
|
|
86
111
|
*/
|
|
87
112
|
export const floor = (value: OperandInput): FunctionNode => fn('FLOOR', [value]);
|
|
88
113
|
|
|
89
114
|
/**
|
|
90
|
-
*
|
|
115
|
+
* Returns the natural logarithm (base e) of a number.
|
|
116
|
+
* @param value - The numeric value.
|
|
117
|
+
* @returns A FunctionNode representing the LN SQL function.
|
|
91
118
|
*/
|
|
92
119
|
export const ln = (value: OperandInput): FunctionNode => fn('LN', [value]);
|
|
93
120
|
|
|
94
121
|
/**
|
|
95
|
-
*
|
|
122
|
+
* Returns the base-10 logarithm of a number.
|
|
123
|
+
* @param value - The numeric value.
|
|
124
|
+
* @returns A FunctionNode representing the LOG SQL function.
|
|
96
125
|
*/
|
|
97
126
|
export const log = (value: OperandInput): FunctionNode => fn('LOG', [value]);
|
|
98
127
|
|
|
99
128
|
/**
|
|
100
|
-
*
|
|
129
|
+
* Returns the base-10 logarithm of a number.
|
|
130
|
+
* @param value - The numeric value.
|
|
131
|
+
* @returns A FunctionNode representing the LOG10 SQL function.
|
|
101
132
|
*/
|
|
102
133
|
export const log10 = (value: OperandInput): FunctionNode => fn('LOG10', [value]);
|
|
103
134
|
|
|
104
135
|
/**
|
|
105
|
-
*
|
|
136
|
+
* Returns the logarithm of a number for a specific base.
|
|
137
|
+
* @param base - The base of the logarithm.
|
|
138
|
+
* @param value - The numeric value.
|
|
139
|
+
* @returns A FunctionNode representing the LOG_BASE SQL function.
|
|
106
140
|
*/
|
|
107
141
|
export const logBase = (base: OperandInput, value: OperandInput): FunctionNode => fn('LOG_BASE', [base, value]);
|
|
108
142
|
|
|
109
143
|
/**
|
|
110
|
-
*
|
|
144
|
+
* Returns the remainder of dividing x by y.
|
|
145
|
+
* @param x - The dividend.
|
|
146
|
+
* @param y - The divisor.
|
|
147
|
+
* @returns A FunctionNode representing the MOD SQL function.
|
|
111
148
|
*/
|
|
112
149
|
export const mod = (x: OperandInput, y: OperandInput): FunctionNode => fn('MOD', [x, y]);
|
|
113
150
|
|
|
114
151
|
/**
|
|
115
|
-
*
|
|
152
|
+
* Returns the value of PI (approximately 3.14159...).
|
|
153
|
+
* @returns A FunctionNode representing the PI SQL function.
|
|
116
154
|
*/
|
|
117
155
|
export const pi = (): FunctionNode => fn('PI', []);
|
|
118
156
|
|
|
119
157
|
/**
|
|
120
|
-
*
|
|
158
|
+
* Returns x raised to the power of y.
|
|
159
|
+
* @param x - The base.
|
|
160
|
+
* @param y - The exponent.
|
|
161
|
+
* @returns A FunctionNode representing the POWER SQL function.
|
|
121
162
|
*/
|
|
122
163
|
export const power = (x: OperandInput, y: OperandInput): FunctionNode => fn('POWER', [x, y]);
|
|
123
164
|
|
|
124
165
|
/**
|
|
125
|
-
*
|
|
166
|
+
* Alias for power. Returns x raised to the power of y.
|
|
167
|
+
* @param x - The base.
|
|
168
|
+
* @param y - The exponent.
|
|
169
|
+
* @returns A FunctionNode representing the POW SQL function.
|
|
126
170
|
*/
|
|
127
171
|
export const pow = (x: OperandInput, y: OperandInput): FunctionNode => fn('POW', [x, y]);
|
|
128
172
|
|
|
129
173
|
/**
|
|
130
|
-
*
|
|
174
|
+
* Converts degrees to radians.
|
|
175
|
+
* @param value - The angle in degrees.
|
|
176
|
+
* @returns A FunctionNode representing the RADIANS SQL function.
|
|
131
177
|
*/
|
|
132
178
|
export const radians = (value: OperandInput): FunctionNode => fn('RADIANS', [value]);
|
|
133
179
|
|
|
134
180
|
/**
|
|
135
|
-
*
|
|
181
|
+
* Returns a random number between 0 and 1.
|
|
182
|
+
* @returns A FunctionNode representing the RANDOM SQL function.
|
|
136
183
|
*/
|
|
137
184
|
export const random = (): FunctionNode => fn('RANDOM', []);
|
|
138
185
|
|
|
139
186
|
/**
|
|
140
|
-
*
|
|
187
|
+
* Alias for random. Returns a random number between 0 and 1.
|
|
188
|
+
* @returns A FunctionNode representing the RAND SQL function.
|
|
141
189
|
*/
|
|
142
190
|
export const rand = (): FunctionNode => fn('RAND', []);
|
|
143
191
|
|
|
144
192
|
/**
|
|
145
|
-
*
|
|
193
|
+
* Rounds a number to a specified number of decimal places.
|
|
194
|
+
* @param value - The numeric value to round.
|
|
195
|
+
* @param decimals - The number of decimal places (optional).
|
|
196
|
+
* @returns A FunctionNode representing the ROUND SQL function.
|
|
146
197
|
*/
|
|
147
198
|
export const round = (value: OperandInput, decimals?: OperandInput): FunctionNode =>
|
|
148
199
|
decimals === undefined ? fn('ROUND', [value]) : fn('ROUND', [value, decimals]);
|
|
149
200
|
|
|
150
201
|
/**
|
|
151
|
-
*
|
|
202
|
+
* Returns the sign of a number (-1 for negative, 0 for zero, 1 for positive).
|
|
203
|
+
* @param value - The numeric value.
|
|
204
|
+
* @returns A FunctionNode representing the SIGN SQL function.
|
|
152
205
|
*/
|
|
153
206
|
export const sign = (value: OperandInput): FunctionNode => fn('SIGN', [value]);
|
|
154
207
|
|
|
155
208
|
/**
|
|
156
|
-
*
|
|
209
|
+
* Returns the sine of a number (in radians).
|
|
210
|
+
* @param value - The numeric value in radians.
|
|
211
|
+
* @returns A FunctionNode representing the SIN SQL function.
|
|
157
212
|
*/
|
|
158
213
|
export const sin = (value: OperandInput): FunctionNode => fn('SIN', [value]);
|
|
159
214
|
|
|
160
215
|
/**
|
|
161
|
-
*
|
|
216
|
+
* Returns the square root of a number.
|
|
217
|
+
* @param value - The numeric value.
|
|
218
|
+
* @returns A FunctionNode representing the SQRT SQL function.
|
|
162
219
|
*/
|
|
163
220
|
export const sqrt = (value: OperandInput): FunctionNode => fn('SQRT', [value]);
|
|
164
221
|
|
|
165
222
|
/**
|
|
166
|
-
*
|
|
223
|
+
* Returns the tangent of a number (in radians).
|
|
224
|
+
* @param value - The numeric value in radians.
|
|
225
|
+
* @returns A FunctionNode representing the TAN SQL function.
|
|
167
226
|
*/
|
|
168
227
|
export const tan = (value: OperandInput): FunctionNode => fn('TAN', [value]);
|
|
169
228
|
|
|
170
229
|
/**
|
|
171
|
-
*
|
|
230
|
+
* Truncates a number to a specified number of decimal places without rounding.
|
|
231
|
+
* @param value - The numeric value to truncate.
|
|
232
|
+
* @param decimals - The number of decimal places (optional).
|
|
233
|
+
* @returns A FunctionNode representing the TRUNC SQL function.
|
|
172
234
|
*/
|
|
173
235
|
export const trunc = (value: OperandInput, decimals?: OperandInput): FunctionNode =>
|
|
174
236
|
decimals === undefined ? fn('TRUNC', [value]) : fn('TRUNC', [value, decimals]);
|
|
175
237
|
|
|
176
238
|
/**
|
|
177
|
-
*
|
|
239
|
+
* Alias for trunc. Truncates a number to a specified number of decimal places without rounding.
|
|
240
|
+
* @param value - The numeric value to truncate.
|
|
241
|
+
* @param decimals - The number of decimal places.
|
|
242
|
+
* @returns A FunctionNode representing the TRUNCATE SQL function.
|
|
178
243
|
*/
|
|
179
244
|
export const truncate = (value: OperandInput, decimals: OperandInput): FunctionNode =>
|
|
180
245
|
fn('TRUNCATE', [value, decimals]);
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { FunctionStrategy, FunctionRenderer, FunctionRenderContext } from './types.js';
|
|
2
2
|
import { LiteralNode, OperandNode, isOperandNode } from '../ast/expression.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Standard implementation of FunctionStrategy for ANSI SQL functions.
|
|
6
|
+
*/
|
|
4
7
|
export class StandardFunctionStrategy implements FunctionStrategy {
|
|
5
8
|
protected renderers: Map<string, FunctionRenderer> = new Map();
|
|
6
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new StandardFunctionStrategy and registers standard functions.
|
|
12
|
+
*/
|
|
7
13
|
constructor() {
|
|
8
14
|
this.registerStandard();
|
|
9
15
|
}
|
|
@@ -44,14 +50,27 @@ export class StandardFunctionStrategy implements FunctionStrategy {
|
|
|
44
50
|
this.add('GROUP_CONCAT', ctx => this.renderGroupConcat(ctx));
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Registers a renderer for a function name.
|
|
55
|
+
* @param name - The function name.
|
|
56
|
+
* @param renderer - The renderer function.
|
|
57
|
+
*/
|
|
47
58
|
protected add(name: string, renderer: FunctionRenderer) {
|
|
48
59
|
this.renderers.set(name, renderer);
|
|
49
60
|
}
|
|
50
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @inheritDoc
|
|
64
|
+
*/
|
|
51
65
|
getRenderer(name: string): FunctionRenderer | undefined {
|
|
52
66
|
return this.renderers.get(name);
|
|
53
67
|
}
|
|
54
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
|
|
71
|
+
* @param ctx - The function render context.
|
|
72
|
+
* @returns The rendered SQL string.
|
|
73
|
+
*/
|
|
55
74
|
private renderGroupConcat(ctx: FunctionRenderContext): string {
|
|
56
75
|
const arg = ctx.compiledArgs[0];
|
|
57
76
|
const orderClause = this.buildOrderByExpression(ctx);
|
|
@@ -60,6 +79,11 @@ export class StandardFunctionStrategy implements FunctionStrategy {
|
|
|
60
79
|
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
61
80
|
}
|
|
62
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Builds the ORDER BY clause for functions like GROUP_CONCAT.
|
|
84
|
+
* @param ctx - The function render context.
|
|
85
|
+
* @returns The ORDER BY SQL clause or empty string.
|
|
86
|
+
*/
|
|
63
87
|
protected buildOrderByExpression(ctx: FunctionRenderContext): string {
|
|
64
88
|
const orderBy = ctx.node.orderBy;
|
|
65
89
|
if (!orderBy || orderBy.length === 0) {
|
|
@@ -78,6 +102,11 @@ export class StandardFunctionStrategy implements FunctionStrategy {
|
|
|
78
102
|
return `ORDER BY ${parts.join(', ')}`;
|
|
79
103
|
}
|
|
80
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Formats the SEPARATOR clause for GROUP_CONCAT.
|
|
107
|
+
* @param ctx - The function render context.
|
|
108
|
+
* @returns The SEPARATOR SQL clause or empty string.
|
|
109
|
+
*/
|
|
81
110
|
protected formatGroupConcatSeparator(ctx: FunctionRenderContext): string {
|
|
82
111
|
if (!ctx.node.separator) {
|
|
83
112
|
return '';
|
|
@@ -85,10 +114,16 @@ export class StandardFunctionStrategy implements FunctionStrategy {
|
|
|
85
114
|
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
86
115
|
}
|
|
87
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Gets the separator operand for GROUP_CONCAT, defaulting to comma.
|
|
119
|
+
* @param ctx - The function render context.
|
|
120
|
+
* @returns The separator operand.
|
|
121
|
+
*/
|
|
88
122
|
protected getGroupConcatSeparatorOperand(ctx: FunctionRenderContext): OperandNode {
|
|
89
123
|
return ctx.node.separator ?? StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
90
124
|
}
|
|
91
125
|
|
|
126
|
+
/** Default separator for GROUP_CONCAT, a comma. */
|
|
92
127
|
protected static readonly DEFAULT_GROUP_CONCAT_SEPARATOR: LiteralNode = {
|
|
93
128
|
type: 'Literal',
|
|
94
129
|
value: ','
|