metal-orm 1.0.1 → 1.0.3
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/.github/workflows/publish-metal-orm.yml +38 -0
- package/README.md +46 -482
- package/docs/advanced-features.md +85 -0
- package/docs/api-reference.md +22 -0
- package/docs/getting-started.md +104 -0
- package/docs/hydration.md +41 -0
- package/docs/index.md +31 -0
- package/docs/multi-dialect-support.md +34 -0
- package/docs/query-builder.md +75 -0
- package/docs/schema-definition.md +61 -0
- package/package.json +1 -1
- package/src/ast/expression.ts +433 -175
- package/src/ast/join.ts +8 -1
- package/src/ast/query.ts +64 -9
- package/src/builder/hydration-manager.ts +42 -11
- package/src/builder/hydration-planner.ts +80 -31
- package/src/builder/operations/column-selector.ts +37 -1
- package/src/builder/operations/cte-manager.ts +16 -0
- package/src/builder/operations/filter-manager.ts +32 -0
- package/src/builder/operations/join-manager.ts +17 -7
- package/src/builder/operations/pagination-manager.ts +19 -0
- package/src/builder/operations/relation-manager.ts +58 -3
- package/src/builder/query-ast-service.ts +100 -29
- package/src/builder/relation-conditions.ts +30 -1
- package/src/builder/relation-projection-helper.ts +43 -1
- package/src/builder/relation-service.ts +68 -13
- package/src/builder/relation-types.ts +6 -0
- package/src/builder/select-query-builder-deps.ts +64 -3
- package/src/builder/select-query-state.ts +72 -0
- package/src/builder/select.ts +166 -0
- package/src/codegen/typescript.ts +142 -44
- package/src/constants/sql-operator-config.ts +36 -0
- package/src/constants/sql.ts +125 -57
- package/src/dialect/abstract.ts +97 -22
- package/src/dialect/mssql/index.ts +27 -0
- package/src/dialect/mysql/index.ts +22 -0
- package/src/dialect/postgres/index.ts +103 -0
- package/src/dialect/sqlite/index.ts +22 -0
- package/src/runtime/als.ts +15 -1
- package/src/runtime/hydration.ts +20 -15
- package/src/schema/column.ts +45 -5
- package/src/schema/relation.ts +49 -2
- package/src/schema/table.ts +27 -3
- package/src/utils/join-node.ts +20 -0
- package/src/utils/raw-column-parser.ts +32 -0
- package/src/utils/relation-alias.ts +43 -0
- package/tests/postgres.test.ts +30 -0
- package/tests/window-function.test.ts +14 -0
|
@@ -16,17 +16,41 @@ import {
|
|
|
16
16
|
LiteralNode,
|
|
17
17
|
FunctionNode
|
|
18
18
|
} from '../ast/expression';
|
|
19
|
-
|
|
19
|
+
import { SQL_OPERATOR_REGISTRY } from '../constants/sql-operator-config';
|
|
20
|
+
import { SqlOperator } from '../constants/sql';
|
|
21
|
+
import { isRelationAlias } from '../utils/relation-alias';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Capitalizes the first letter of a string
|
|
25
|
+
* @param s - String to capitalize
|
|
26
|
+
* @returns Capitalized string
|
|
27
|
+
*/
|
|
20
28
|
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
21
|
-
const isRelationAlias = (alias?: string) => alias ? alias.includes('__') : false;
|
|
22
29
|
|
|
30
|
+
const assertNever = (value: never): never => {
|
|
31
|
+
throw new Error(`Unhandled SQL operator: ${value}`);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Function type for printing expression nodes
|
|
36
|
+
*/
|
|
23
37
|
type ExpressionPrinter = (expr: ExpressionNode) => string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Function type for printing operand nodes
|
|
41
|
+
*/
|
|
24
42
|
type OperandPrinter = (node: OperandNode) => string;
|
|
25
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Generates TypeScript code from query AST nodes
|
|
46
|
+
*/
|
|
26
47
|
export class TypeScriptGenerator {
|
|
27
48
|
private readonly expressionPrinters: Partial<Record<ExpressionNode['type'], ExpressionPrinter>>;
|
|
28
49
|
private readonly operandPrinters: Partial<Record<OperandNode['type'], OperandPrinter>>;
|
|
29
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new TypeScriptGenerator instance
|
|
53
|
+
*/
|
|
30
54
|
constructor() {
|
|
31
55
|
this.expressionPrinters = {
|
|
32
56
|
BinaryExpression: expr => this.printBinaryExpression(expr as BinaryExpressionNode),
|
|
@@ -48,6 +72,11 @@ export class TypeScriptGenerator {
|
|
|
48
72
|
};
|
|
49
73
|
}
|
|
50
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Generates TypeScript code from a query AST
|
|
77
|
+
* @param ast - Query AST to generate code from
|
|
78
|
+
* @returns Generated TypeScript code
|
|
79
|
+
*/
|
|
51
80
|
generate(ast: SelectQueryNode): string {
|
|
52
81
|
const chainLines = this.buildSelectLines(ast);
|
|
53
82
|
const lines = chainLines.map((line, index) => (index === 0 ? `const query = ${line}` : line));
|
|
@@ -55,6 +84,11 @@ export class TypeScriptGenerator {
|
|
|
55
84
|
return lines.join('\n');
|
|
56
85
|
}
|
|
57
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Builds TypeScript method chain lines from query AST
|
|
89
|
+
* @param ast - Query AST
|
|
90
|
+
* @returns Array of TypeScript method chain lines
|
|
91
|
+
*/
|
|
58
92
|
private buildSelectLines(ast: SelectQueryNode): string[] {
|
|
59
93
|
const lines: string[] = [];
|
|
60
94
|
const hydration = ast.meta?.hydration;
|
|
@@ -136,27 +170,53 @@ export class TypeScriptGenerator {
|
|
|
136
170
|
return lines;
|
|
137
171
|
}
|
|
138
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Prints an expression node to TypeScript code
|
|
175
|
+
* @param expr - Expression node to print
|
|
176
|
+
* @returns TypeScript code representation
|
|
177
|
+
*/
|
|
139
178
|
private printExpression(expr: ExpressionNode): string {
|
|
140
179
|
const printer = this.expressionPrinters[expr.type];
|
|
141
|
-
|
|
180
|
+
if (!printer) {
|
|
181
|
+
throw new Error(`Unsupported expression type "${expr.type}" in TypeScript generator`);
|
|
182
|
+
}
|
|
183
|
+
return printer(expr);
|
|
142
184
|
}
|
|
143
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Prints an operand node to TypeScript code
|
|
188
|
+
* @param node - Operand node to print
|
|
189
|
+
* @returns TypeScript code representation
|
|
190
|
+
*/
|
|
144
191
|
private printOperand(node: OperandNode): string {
|
|
145
192
|
const printer = this.operandPrinters[node.type];
|
|
146
|
-
|
|
193
|
+
if (!printer) {
|
|
194
|
+
throw new Error(`Unsupported operand type "${node.type}" in TypeScript generator`);
|
|
195
|
+
}
|
|
196
|
+
return printer(node);
|
|
147
197
|
}
|
|
148
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Prints a binary expression to TypeScript code
|
|
201
|
+
* @param binary - Binary expression node
|
|
202
|
+
* @returns TypeScript code representation
|
|
203
|
+
*/
|
|
149
204
|
private printBinaryExpression(binary: BinaryExpressionNode): string {
|
|
150
205
|
const left = this.printOperand(binary.left);
|
|
151
206
|
const right = this.printOperand(binary.right);
|
|
152
|
-
const
|
|
207
|
+
const fn = this.mapOp(binary.operator);
|
|
208
|
+
const args = [left, right];
|
|
153
209
|
if (binary.escape) {
|
|
154
|
-
|
|
155
|
-
return `${base} ESCAPE ${escapeOperand}`;
|
|
210
|
+
args.push(this.printOperand(binary.escape));
|
|
156
211
|
}
|
|
157
|
-
return
|
|
212
|
+
return `${fn}(${args.join(', ')})`;
|
|
158
213
|
}
|
|
159
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Prints a logical expression to TypeScript code
|
|
217
|
+
* @param logical - Logical expression node
|
|
218
|
+
* @returns TypeScript code representation
|
|
219
|
+
*/
|
|
160
220
|
private printLogicalExpression(logical: LogicalExpressionNode): string {
|
|
161
221
|
if (logical.operands.length === 0) return '';
|
|
162
222
|
const parts = logical.operands.map(op => {
|
|
@@ -166,17 +226,34 @@ export class TypeScriptGenerator {
|
|
|
166
226
|
return `${this.mapOp(logical.operator)}(\n ${parts.join(',\n ')}\n )`;
|
|
167
227
|
}
|
|
168
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Prints an IN expression to TypeScript code
|
|
231
|
+
* @param inExpr - IN expression node
|
|
232
|
+
* @returns TypeScript code representation
|
|
233
|
+
*/
|
|
169
234
|
private printInExpression(inExpr: InExpressionNode): string {
|
|
170
235
|
const left = this.printOperand(inExpr.left);
|
|
171
236
|
const values = inExpr.right.map(v => this.printOperand(v)).join(', ');
|
|
172
|
-
|
|
237
|
+
const fn = this.mapOp(inExpr.operator);
|
|
238
|
+
return `${fn}(${left}, [${values}])`;
|
|
173
239
|
}
|
|
174
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Prints a null expression to TypeScript code
|
|
243
|
+
* @param nullExpr - Null expression node
|
|
244
|
+
* @returns TypeScript code representation
|
|
245
|
+
*/
|
|
175
246
|
private printNullExpression(nullExpr: NullExpressionNode): string {
|
|
176
247
|
const left = this.printOperand(nullExpr.left);
|
|
177
|
-
|
|
248
|
+
const fn = this.mapOp(nullExpr.operator);
|
|
249
|
+
return `${fn}(${left})`;
|
|
178
250
|
}
|
|
179
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Prints a BETWEEN expression to TypeScript code
|
|
254
|
+
* @param betweenExpr - BETWEEN expression node
|
|
255
|
+
* @returns TypeScript code representation
|
|
256
|
+
*/
|
|
180
257
|
private printBetweenExpression(betweenExpr: BetweenExpressionNode): string {
|
|
181
258
|
const left = this.printOperand(betweenExpr.left);
|
|
182
259
|
const lower = this.printOperand(betweenExpr.lower);
|
|
@@ -184,34 +261,69 @@ export class TypeScriptGenerator {
|
|
|
184
261
|
return `${this.mapOp(betweenExpr.operator)}(${left}, ${lower}, ${upper})`;
|
|
185
262
|
}
|
|
186
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Prints an EXISTS expression to TypeScript code
|
|
266
|
+
* @param existsExpr - EXISTS expression node
|
|
267
|
+
* @returns TypeScript code representation
|
|
268
|
+
*/
|
|
187
269
|
private printExistsExpression(existsExpr: ExistsExpressionNode): string {
|
|
188
270
|
const subquery = this.inlineChain(this.buildSelectLines(existsExpr.subquery));
|
|
189
271
|
return `${this.mapOp(existsExpr.operator)}(${subquery})`;
|
|
190
272
|
}
|
|
191
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Prints a column operand to TypeScript code
|
|
276
|
+
* @param column - Column node
|
|
277
|
+
* @returns TypeScript code representation
|
|
278
|
+
*/
|
|
192
279
|
private printColumnOperand(column: ColumnNode): string {
|
|
193
280
|
return `${capitalize(column.table)}.${column.name}`;
|
|
194
281
|
}
|
|
195
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Prints a literal operand to TypeScript code
|
|
285
|
+
* @param literal - Literal node
|
|
286
|
+
* @returns TypeScript code representation
|
|
287
|
+
*/
|
|
196
288
|
private printLiteralOperand(literal: LiteralNode): string {
|
|
197
289
|
if (literal.value === null) return 'null';
|
|
198
290
|
return typeof literal.value === 'string' ? `'${literal.value}'` : String(literal.value);
|
|
199
291
|
}
|
|
200
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Prints a function operand to TypeScript code
|
|
295
|
+
* @param fn - Function node
|
|
296
|
+
* @returns TypeScript code representation
|
|
297
|
+
*/
|
|
201
298
|
private printFunctionOperand(fn: FunctionNode): string {
|
|
202
299
|
const args = fn.args.map(a => this.printOperand(a)).join(', ');
|
|
203
300
|
return `${fn.name.toLowerCase()}(${args})`;
|
|
204
301
|
}
|
|
205
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Prints a JSON path operand to TypeScript code
|
|
305
|
+
* @param json - JSON path node
|
|
306
|
+
* @returns TypeScript code representation
|
|
307
|
+
*/
|
|
206
308
|
private printJsonPathOperand(json: JsonPathNode): string {
|
|
207
309
|
return `jsonPath(${capitalize(json.column.table)}.${json.column.name}, '${json.path}')`;
|
|
208
310
|
}
|
|
209
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Prints a scalar subquery operand to TypeScript code
|
|
314
|
+
* @param node - Scalar subquery node
|
|
315
|
+
* @returns TypeScript code representation
|
|
316
|
+
*/
|
|
210
317
|
private printScalarSubqueryOperand(node: ScalarSubqueryNode): string {
|
|
211
318
|
const subquery = this.inlineChain(this.buildSelectLines(node.query));
|
|
212
319
|
return `(${subquery})`;
|
|
213
320
|
}
|
|
214
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Prints a CASE expression operand to TypeScript code
|
|
324
|
+
* @param node - CASE expression node
|
|
325
|
+
* @returns TypeScript code representation
|
|
326
|
+
*/
|
|
215
327
|
private printCaseExpressionOperand(node: CaseExpressionNode): string {
|
|
216
328
|
const clauses = node.conditions.map(
|
|
217
329
|
condition =>
|
|
@@ -221,6 +333,11 @@ export class TypeScriptGenerator {
|
|
|
221
333
|
return `caseWhen([${clauses.join(', ')}]${elseValue})`;
|
|
222
334
|
}
|
|
223
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Prints a window function operand to TypeScript code
|
|
338
|
+
* @param node - Window function node
|
|
339
|
+
* @returns TypeScript code representation
|
|
340
|
+
*/
|
|
224
341
|
private printWindowFunctionOperand(node: WindowFunctionNode): string {
|
|
225
342
|
let result = `${node.name}(`;
|
|
226
343
|
if (node.args.length > 0) {
|
|
@@ -249,6 +366,11 @@ export class TypeScriptGenerator {
|
|
|
249
366
|
return result;
|
|
250
367
|
}
|
|
251
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Converts method chain lines to inline format
|
|
371
|
+
* @param lines - Method chain lines
|
|
372
|
+
* @returns Inline method chain string
|
|
373
|
+
*/
|
|
252
374
|
private inlineChain(lines: string[]): string {
|
|
253
375
|
return lines
|
|
254
376
|
.map(line => line.trim())
|
|
@@ -256,40 +378,16 @@ export class TypeScriptGenerator {
|
|
|
256
378
|
.join(' ');
|
|
257
379
|
}
|
|
258
380
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return 'like';
|
|
269
|
-
case 'NOT LIKE':
|
|
270
|
-
return 'notLike';
|
|
271
|
-
case 'IN':
|
|
272
|
-
return 'inList';
|
|
273
|
-
case 'NOT IN':
|
|
274
|
-
return 'notInList';
|
|
275
|
-
case 'IS NULL':
|
|
276
|
-
return 'isNull';
|
|
277
|
-
case 'IS NOT NULL':
|
|
278
|
-
return 'isNotNull';
|
|
279
|
-
case 'AND':
|
|
280
|
-
return 'and';
|
|
281
|
-
case 'OR':
|
|
282
|
-
return 'or';
|
|
283
|
-
case 'BETWEEN':
|
|
284
|
-
return 'between';
|
|
285
|
-
case 'NOT BETWEEN':
|
|
286
|
-
return 'notBetween';
|
|
287
|
-
case 'EXISTS':
|
|
288
|
-
return 'exists';
|
|
289
|
-
case 'NOT EXISTS':
|
|
290
|
-
return 'notExists';
|
|
291
|
-
default:
|
|
292
|
-
return 'eq';
|
|
381
|
+
/**
|
|
382
|
+
* Maps SQL operators to TypeScript function names
|
|
383
|
+
* @param op - SQL operator
|
|
384
|
+
* @returns TypeScript function name
|
|
385
|
+
*/
|
|
386
|
+
private mapOp(op: SqlOperator): string {
|
|
387
|
+
const config = SQL_OPERATOR_REGISTRY[op];
|
|
388
|
+
if (!config) {
|
|
389
|
+
return assertNever(op as never);
|
|
293
390
|
}
|
|
391
|
+
return config.tsName;
|
|
294
392
|
}
|
|
295
393
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SQL_OPERATORS, SqlOperator } from './sql';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for how SQL operators map to TypeScript builder helpers
|
|
5
|
+
*/
|
|
6
|
+
export interface SqlOperatorConfig {
|
|
7
|
+
/**
|
|
8
|
+
* SQL operator literal
|
|
9
|
+
*/
|
|
10
|
+
sql: SqlOperator;
|
|
11
|
+
/**
|
|
12
|
+
* Corresponding TypeScript helper name
|
|
13
|
+
*/
|
|
14
|
+
tsName: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Registry of supported SQL operators and their companion helper names
|
|
19
|
+
*/
|
|
20
|
+
export const SQL_OPERATOR_REGISTRY: Record<SqlOperator, SqlOperatorConfig> = {
|
|
21
|
+
[SQL_OPERATORS.EQUALS]: { sql: SQL_OPERATORS.EQUALS, tsName: 'eq' },
|
|
22
|
+
[SQL_OPERATORS.GREATER_THAN]: { sql: SQL_OPERATORS.GREATER_THAN, tsName: 'gt' },
|
|
23
|
+
[SQL_OPERATORS.LESS_THAN]: { sql: SQL_OPERATORS.LESS_THAN, tsName: 'lt' },
|
|
24
|
+
[SQL_OPERATORS.LIKE]: { sql: SQL_OPERATORS.LIKE, tsName: 'like' },
|
|
25
|
+
[SQL_OPERATORS.NOT_LIKE]: { sql: SQL_OPERATORS.NOT_LIKE, tsName: 'notLike' },
|
|
26
|
+
[SQL_OPERATORS.IN]: { sql: SQL_OPERATORS.IN, tsName: 'inList' },
|
|
27
|
+
[SQL_OPERATORS.NOT_IN]: { sql: SQL_OPERATORS.NOT_IN, tsName: 'notInList' },
|
|
28
|
+
[SQL_OPERATORS.IS_NULL]: { sql: SQL_OPERATORS.IS_NULL, tsName: 'isNull' },
|
|
29
|
+
[SQL_OPERATORS.IS_NOT_NULL]: { sql: SQL_OPERATORS.IS_NOT_NULL, tsName: 'isNotNull' },
|
|
30
|
+
[SQL_OPERATORS.AND]: { sql: SQL_OPERATORS.AND, tsName: 'and' },
|
|
31
|
+
[SQL_OPERATORS.OR]: { sql: SQL_OPERATORS.OR, tsName: 'or' },
|
|
32
|
+
[SQL_OPERATORS.BETWEEN]: { sql: SQL_OPERATORS.BETWEEN, tsName: 'between' },
|
|
33
|
+
[SQL_OPERATORS.NOT_BETWEEN]: { sql: SQL_OPERATORS.NOT_BETWEEN, tsName: 'notBetween' },
|
|
34
|
+
[SQL_OPERATORS.EXISTS]: { sql: SQL_OPERATORS.EXISTS, tsName: 'exists' },
|
|
35
|
+
[SQL_OPERATORS.NOT_EXISTS]: { sql: SQL_OPERATORS.NOT_EXISTS, tsName: 'notExists' }
|
|
36
|
+
};
|
package/src/constants/sql.ts
CHANGED
|
@@ -1,57 +1,125 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} as const;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SQL keywords used in query generation
|
|
3
|
+
*/
|
|
4
|
+
export const SQL_KEYWORDS = {
|
|
5
|
+
/** SELECT clause keyword */
|
|
6
|
+
SELECT: 'SELECT',
|
|
7
|
+
/** FROM clause keyword */
|
|
8
|
+
FROM: 'FROM',
|
|
9
|
+
/** WHERE clause keyword */
|
|
10
|
+
WHERE: 'WHERE',
|
|
11
|
+
/** JOIN keyword */
|
|
12
|
+
JOIN: 'JOIN',
|
|
13
|
+
/** INNER JOIN keyword */
|
|
14
|
+
INNER_JOIN: 'INNER JOIN',
|
|
15
|
+
/** LEFT JOIN keyword */
|
|
16
|
+
LEFT_JOIN: 'LEFT JOIN',
|
|
17
|
+
/** RIGHT JOIN keyword */
|
|
18
|
+
RIGHT_JOIN: 'RIGHT JOIN',
|
|
19
|
+
/** ORDER BY clause keyword */
|
|
20
|
+
ORDER_BY: 'ORDER BY',
|
|
21
|
+
/** GROUP BY clause keyword */
|
|
22
|
+
GROUP_BY: 'GROUP BY',
|
|
23
|
+
/** HAVING clause keyword */
|
|
24
|
+
HAVING: 'HAVING',
|
|
25
|
+
/** DISTINCT keyword */
|
|
26
|
+
DISTINCT: 'DISTINCT',
|
|
27
|
+
/** EXISTS operator */
|
|
28
|
+
EXISTS: 'EXISTS',
|
|
29
|
+
/** NOT EXISTS operator */
|
|
30
|
+
NOT_EXISTS: 'NOT EXISTS'
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* SQL operators used in query conditions
|
|
35
|
+
*/
|
|
36
|
+
export const SQL_OPERATORS = {
|
|
37
|
+
/** Equality operator */
|
|
38
|
+
EQUALS: '=',
|
|
39
|
+
/** Greater than operator */
|
|
40
|
+
GREATER_THAN: '>',
|
|
41
|
+
/** Less than operator */
|
|
42
|
+
LESS_THAN: '<',
|
|
43
|
+
/** LIKE pattern matching operator */
|
|
44
|
+
LIKE: 'LIKE',
|
|
45
|
+
/** NOT LIKE pattern matching operator */
|
|
46
|
+
NOT_LIKE: 'NOT LIKE',
|
|
47
|
+
/** IN membership operator */
|
|
48
|
+
IN: 'IN',
|
|
49
|
+
/** NOT IN membership operator */
|
|
50
|
+
NOT_IN: 'NOT IN',
|
|
51
|
+
/** BETWEEN range operator */
|
|
52
|
+
BETWEEN: 'BETWEEN',
|
|
53
|
+
/** NOT BETWEEN range operator */
|
|
54
|
+
NOT_BETWEEN: 'NOT BETWEEN',
|
|
55
|
+
/** IS NULL null check operator */
|
|
56
|
+
IS_NULL: 'IS NULL',
|
|
57
|
+
/** IS NOT NULL null check operator */
|
|
58
|
+
IS_NOT_NULL: 'IS NOT NULL',
|
|
59
|
+
/** Logical AND operator */
|
|
60
|
+
AND: 'AND',
|
|
61
|
+
/** Logical OR operator */
|
|
62
|
+
OR: 'OR',
|
|
63
|
+
/** EXISTS operator */
|
|
64
|
+
EXISTS: 'EXISTS',
|
|
65
|
+
/** NOT EXISTS operator */
|
|
66
|
+
NOT_EXISTS: 'NOT EXISTS'
|
|
67
|
+
} as const;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Type representing any supported SQL operator
|
|
71
|
+
*/
|
|
72
|
+
export type SqlOperator = (typeof SQL_OPERATORS)[keyof typeof SQL_OPERATORS];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Types of SQL joins supported
|
|
76
|
+
*/
|
|
77
|
+
export const JOIN_KINDS = {
|
|
78
|
+
/** INNER JOIN type */
|
|
79
|
+
INNER: 'INNER',
|
|
80
|
+
/** LEFT JOIN type */
|
|
81
|
+
LEFT: 'LEFT',
|
|
82
|
+
/** RIGHT JOIN type */
|
|
83
|
+
RIGHT: 'RIGHT',
|
|
84
|
+
/** CROSS JOIN type */
|
|
85
|
+
CROSS: 'CROSS'
|
|
86
|
+
} as const;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Type representing any supported join kind
|
|
90
|
+
*/
|
|
91
|
+
export type JoinKind = (typeof JOIN_KINDS)[keyof typeof JOIN_KINDS];
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Ordering directions for result sorting
|
|
95
|
+
*/
|
|
96
|
+
export const ORDER_DIRECTIONS = {
|
|
97
|
+
/** Ascending order */
|
|
98
|
+
ASC: 'ASC',
|
|
99
|
+
/** Descending order */
|
|
100
|
+
DESC: 'DESC'
|
|
101
|
+
} as const;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Type representing any supported order direction
|
|
105
|
+
*/
|
|
106
|
+
export type OrderDirection = (typeof ORDER_DIRECTIONS)[keyof typeof ORDER_DIRECTIONS];
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Supported database dialects
|
|
110
|
+
*/
|
|
111
|
+
export const SUPPORTED_DIALECTS = {
|
|
112
|
+
/** MySQL database dialect */
|
|
113
|
+
MYSQL: 'mysql',
|
|
114
|
+
/** SQLite database dialect */
|
|
115
|
+
SQLITE: 'sqlite',
|
|
116
|
+
/** Microsoft SQL Server dialect */
|
|
117
|
+
MSSQL: 'mssql',
|
|
118
|
+
/** PostgreSQL database dialect */
|
|
119
|
+
POSTGRES: 'postgres'
|
|
120
|
+
} as const;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Type representing any supported database dialect
|
|
124
|
+
*/
|
|
125
|
+
export type DialectName = (typeof SUPPORTED_DIALECTS)[keyof typeof SUPPORTED_DIALECTS];
|