metal-orm 1.1.24 → 1.1.25
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 +539 -412
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +225 -176
- package/dist/index.d.ts +225 -176
- package/dist/index.js +519 -412
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/dialect/base/returning-strategy.ts +40 -39
- package/src/core/dialect/base/sql-compiler-set.ts +33 -0
- package/src/core/dialect/base/sql-dialect.ts +79 -38
- package/src/core/dialect/base/upsert-strategy.ts +45 -0
- package/src/core/dialect/capabilities/procedure-compiler.ts +10 -8
- package/src/core/dialect/mssql/compiler-factory.ts +12 -0
- package/src/core/dialect/mssql/delete-compiler.ts +40 -0
- package/src/core/dialect/mssql/index.ts +24 -371
- package/src/core/dialect/mssql/insert-compiler.ts +112 -0
- package/src/core/dialect/mssql/output.ts +46 -0
- package/src/core/dialect/mssql/procedure-compiler.ts +81 -0
- package/src/core/dialect/mssql/select-compiler.ts +116 -0
- package/src/core/dialect/mssql/update-compiler.ts +37 -0
- package/src/core/dialect/mysql/index.ts +24 -117
- package/src/core/dialect/mysql/procedure-compiler.ts +67 -0
- package/src/core/dialect/mysql/upsert.ts +42 -0
- package/src/core/dialect/postgres/index.ts +34 -101
- package/src/core/dialect/postgres/procedure-compiler.ts +41 -0
- package/src/core/dialect/postgres/returning.ts +4 -0
- package/src/core/dialect/postgres/upsert.ts +43 -0
- package/src/core/dialect/sqlite/index.ts +15 -70
- package/src/core/dialect/sqlite/returning.ts +30 -0
- package/src/core/dialect/sqlite/upsert.ts +43 -0
- package/src/index.ts +22 -10
package/package.json
CHANGED
|
@@ -1,51 +1,39 @@
|
|
|
1
|
-
import { ColumnNode } from '../../ast/expression.js';
|
|
2
|
-
import { CompilerContext } from '../abstract.js';
|
|
1
|
+
import type { ColumnNode } from '../../ast/expression.js';
|
|
2
|
+
import type { CompilerContext } from '../abstract.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*/
|
|
4
|
+
export type QuoteIdentifier = (id: string) => string;
|
|
5
|
+
|
|
6
|
+
/** Backend-specific RETURNING/OUTPUT rendering strategy. */
|
|
8
7
|
export interface ReturningStrategy {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* @param returning - Array of columns to format.
|
|
20
|
-
* @param quoteIdentifier - Function to quote identifiers according to dialect rules.
|
|
21
|
-
* @returns Formatted column list (e.g., "table.col1, table.col2").
|
|
22
|
-
*/
|
|
23
|
-
formatReturningColumns(returning: ColumnNode[], quoteIdentifier: (id: string) => string): string;
|
|
8
|
+
compileReturning(
|
|
9
|
+
returning: ColumnNode[] | undefined,
|
|
10
|
+
ctx: CompilerContext,
|
|
11
|
+
quoteIdentifier: QuoteIdentifier
|
|
12
|
+
): string;
|
|
13
|
+
|
|
14
|
+
formatReturningColumns(
|
|
15
|
+
returning: ColumnNode[],
|
|
16
|
+
quoteIdentifier: QuoteIdentifier
|
|
17
|
+
): string;
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
/**
|
|
27
|
-
* Default RETURNING strategy that throws an error when RETURNING is used.
|
|
28
|
-
* Use this for dialects that don't support RETURNING clauses.
|
|
29
|
-
*/
|
|
20
|
+
/** Default RETURNING strategy for dialects without support. */
|
|
30
21
|
export class NoReturningStrategy implements ReturningStrategy {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*/
|
|
37
|
-
compileReturning(returning: ColumnNode[] | undefined, _ctx: CompilerContext): string {
|
|
22
|
+
compileReturning(
|
|
23
|
+
returning: ColumnNode[] | undefined,
|
|
24
|
+
_ctx: CompilerContext,
|
|
25
|
+
_quoteIdentifier: QuoteIdentifier
|
|
26
|
+
): string {
|
|
38
27
|
void _ctx;
|
|
28
|
+
void _quoteIdentifier;
|
|
39
29
|
if (!returning || returning.length === 0) return '';
|
|
40
30
|
throw new Error('RETURNING is not supported by this dialect.');
|
|
41
31
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
*/
|
|
48
|
-
formatReturningColumns(returning: ColumnNode[], quoteIdentifier: (id: string) => string): string {
|
|
32
|
+
|
|
33
|
+
formatReturningColumns(
|
|
34
|
+
returning: ColumnNode[],
|
|
35
|
+
quoteIdentifier: QuoteIdentifier
|
|
36
|
+
): string {
|
|
49
37
|
return returning
|
|
50
38
|
.map(column => {
|
|
51
39
|
const tablePart = column.table ? `${quoteIdentifier(column.table)}.` : '';
|
|
@@ -55,3 +43,16 @@ export class NoReturningStrategy implements ReturningStrategy {
|
|
|
55
43
|
.join(', ');
|
|
56
44
|
}
|
|
57
45
|
}
|
|
46
|
+
|
|
47
|
+
/** Standard SQL RETURNING implementation with qualified column support. */
|
|
48
|
+
export class StandardReturningStrategy extends NoReturningStrategy {
|
|
49
|
+
override compileReturning(
|
|
50
|
+
returning: ColumnNode[] | undefined,
|
|
51
|
+
_ctx: CompilerContext,
|
|
52
|
+
quoteIdentifier: QuoteIdentifier
|
|
53
|
+
): string {
|
|
54
|
+
void _ctx;
|
|
55
|
+
if (!returning || returning.length === 0) return '';
|
|
56
|
+
return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CompilerContext } from '../abstract.js';
|
|
2
|
+
import type {
|
|
3
|
+
DeleteQueryNode,
|
|
4
|
+
InsertQueryNode,
|
|
5
|
+
SelectQueryNode,
|
|
6
|
+
UpdateQueryNode
|
|
7
|
+
} from '../../ast/query.js';
|
|
8
|
+
import type { StandardSqlCompilerServices } from './standard-sql-services.js';
|
|
9
|
+
import type { StandardSqlSourceCompiler } from './standard-sql-source-compiler.js';
|
|
10
|
+
|
|
11
|
+
export interface SqlAstCompiler<TAst> {
|
|
12
|
+
compile(ast: TAst, ctx: CompilerContext): string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SqlCompilerSet {
|
|
16
|
+
select: SqlAstCompiler<SelectQueryNode>;
|
|
17
|
+
insert: SqlAstCompiler<InsertQueryNode>;
|
|
18
|
+
update: SqlAstCompiler<UpdateQueryNode>;
|
|
19
|
+
delete: SqlAstCompiler<DeleteQueryNode>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SqlCompilerAssemblyContext {
|
|
23
|
+
services: StandardSqlCompilerServices;
|
|
24
|
+
sources: StandardSqlSourceCompiler;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Allows a backend to replace only the standard query compilers whose SQL
|
|
29
|
+
* grammar genuinely differs from the common implementation.
|
|
30
|
+
*/
|
|
31
|
+
export type SqlCompilerFactory = (
|
|
32
|
+
context: SqlCompilerAssemblyContext
|
|
33
|
+
) => Partial<SqlCompilerSet>;
|
|
@@ -1,55 +1,71 @@
|
|
|
1
1
|
import { DialectBase } from '../abstract.js';
|
|
2
2
|
import type { CompilerContext } from '../abstract.js';
|
|
3
3
|
import type {
|
|
4
|
-
SelectQueryNode,
|
|
5
|
-
InsertQueryNode,
|
|
6
|
-
UpdateQueryNode,
|
|
7
4
|
DeleteQueryNode,
|
|
8
|
-
UpsertClause,
|
|
9
|
-
TableSourceNode,
|
|
10
5
|
DerivedTableNode,
|
|
11
6
|
FunctionTableNode,
|
|
7
|
+
InsertQueryNode,
|
|
12
8
|
OrderByNode,
|
|
13
|
-
|
|
9
|
+
SelectQueryNode,
|
|
10
|
+
TableNode,
|
|
11
|
+
TableSourceNode,
|
|
12
|
+
UpdateAssignmentNode,
|
|
13
|
+
UpdateQueryNode,
|
|
14
|
+
UpsertClause
|
|
14
15
|
} from '../../ast/query.js';
|
|
15
|
-
import type { ColumnNode
|
|
16
|
+
import type { ColumnNode } from '../../ast/expression.js';
|
|
16
17
|
import type { FunctionStrategy } from '../../functions/types.js';
|
|
17
18
|
import type { TableFunctionStrategy } from '../../functions/table-types.js';
|
|
18
19
|
import { StandardLimitOffsetPagination } from './pagination-strategy.js';
|
|
19
20
|
import type { PaginationStrategy } from './pagination-strategy.js';
|
|
20
21
|
import { NoReturningStrategy } from './returning-strategy.js';
|
|
21
22
|
import type { ReturningStrategy } from './returning-strategy.js';
|
|
23
|
+
import { NoUpsertStrategy } from './upsert-strategy.js';
|
|
24
|
+
import type { UpsertStrategy } from './upsert-strategy.js';
|
|
22
25
|
import { StandardSqlSourceCompiler } from './standard-sql-source-compiler.js';
|
|
23
26
|
import { StandardSelectCompiler } from './standard-select-compiler.js';
|
|
24
27
|
import { StandardInsertCompiler } from './standard-insert-compiler.js';
|
|
25
28
|
import { StandardUpdateCompiler } from './standard-update-compiler.js';
|
|
26
29
|
import { StandardDeleteCompiler } from './standard-delete-compiler.js';
|
|
27
30
|
import type { StandardSqlCompilerServices } from './standard-sql-services.js';
|
|
31
|
+
import type { SqlCompilerFactory, SqlCompilerSet } from './sql-compiler-set.js';
|
|
32
|
+
|
|
33
|
+
export interface SqlDialectBaseOptions {
|
|
34
|
+
functionStrategy?: FunctionStrategy;
|
|
35
|
+
tableFunctionStrategy?: TableFunctionStrategy;
|
|
36
|
+
paginationStrategy?: PaginationStrategy;
|
|
37
|
+
returningStrategy?: ReturningStrategy;
|
|
38
|
+
upsertStrategy?: UpsertStrategy;
|
|
39
|
+
compilerFactory?: SqlCompilerFactory;
|
|
40
|
+
supportsDmlReturning?: boolean;
|
|
41
|
+
}
|
|
28
42
|
|
|
29
43
|
/**
|
|
30
|
-
* Thin assembly base for dialects that use MetalORM's
|
|
44
|
+
* Thin assembly base for dialects that use MetalORM's reusable SQL compiler pieces.
|
|
31
45
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
46
|
+
* Query orchestration, source rendering, upsert behavior and returning behavior are
|
|
47
|
+
* injected components. Concrete dialects keep only syntax hooks that are genuinely
|
|
48
|
+
* intrinsic to that backend.
|
|
35
49
|
*/
|
|
36
50
|
export abstract class SqlDialectBase extends DialectBase {
|
|
37
51
|
abstract quoteIdentifier(id: string): string;
|
|
38
52
|
|
|
39
|
-
protected paginationStrategy: PaginationStrategy
|
|
40
|
-
protected returningStrategy: ReturningStrategy
|
|
53
|
+
protected readonly paginationStrategy: PaginationStrategy;
|
|
54
|
+
protected readonly returningStrategy: ReturningStrategy;
|
|
55
|
+
protected readonly upsertStrategy: UpsertStrategy;
|
|
41
56
|
|
|
57
|
+
private readonly dmlReturningSupported: boolean;
|
|
42
58
|
private readonly sourceCompiler: StandardSqlSourceCompiler;
|
|
43
|
-
private readonly
|
|
44
|
-
private readonly
|
|
45
|
-
private readonly updateCompiler: StandardUpdateCompiler;
|
|
46
|
-
private readonly deleteCompiler: StandardDeleteCompiler;
|
|
59
|
+
private readonly standardUpdateCompiler: StandardUpdateCompiler;
|
|
60
|
+
private readonly compilerSet: SqlCompilerSet;
|
|
47
61
|
|
|
48
|
-
protected constructor(
|
|
49
|
-
functionStrategy
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
protected constructor(options: SqlDialectBaseOptions = {}) {
|
|
63
|
+
super(options.functionStrategy, options.tableFunctionStrategy);
|
|
64
|
+
|
|
65
|
+
this.paginationStrategy = options.paginationStrategy ?? new StandardLimitOffsetPagination();
|
|
66
|
+
this.returningStrategy = options.returningStrategy ?? new NoReturningStrategy();
|
|
67
|
+
this.upsertStrategy = options.upsertStrategy ?? new NoUpsertStrategy();
|
|
68
|
+
this.dmlReturningSupported = options.supportsDmlReturning ?? false;
|
|
53
69
|
|
|
54
70
|
const services: StandardSqlCompilerServices = {
|
|
55
71
|
getDialectName: () => this.dialect,
|
|
@@ -69,48 +85,73 @@ export abstract class SqlDialectBase extends DialectBase {
|
|
|
69
85
|
};
|
|
70
86
|
|
|
71
87
|
this.sourceCompiler = new StandardSqlSourceCompiler(services);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.
|
|
75
|
-
|
|
88
|
+
const standardSelect = new StandardSelectCompiler(services, this.sourceCompiler);
|
|
89
|
+
const standardInsert = new StandardInsertCompiler(services, this.sourceCompiler);
|
|
90
|
+
this.standardUpdateCompiler = new StandardUpdateCompiler(services, this.sourceCompiler);
|
|
91
|
+
const standardDelete = new StandardDeleteCompiler(services, this.sourceCompiler);
|
|
92
|
+
|
|
93
|
+
const overrides = options.compilerFactory?.({
|
|
94
|
+
services,
|
|
95
|
+
sources: this.sourceCompiler
|
|
96
|
+
}) ?? {};
|
|
97
|
+
|
|
98
|
+
this.compilerSet = {
|
|
99
|
+
select: overrides.select ?? standardSelect,
|
|
100
|
+
insert: overrides.insert ?? standardInsert,
|
|
101
|
+
update: overrides.update ?? this.standardUpdateCompiler,
|
|
102
|
+
delete: overrides.delete ?? standardDelete
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override supportsDmlReturningClause(): boolean {
|
|
107
|
+
return this.dmlReturningSupported;
|
|
76
108
|
}
|
|
77
109
|
|
|
78
110
|
protected compileSelectAst(ast: SelectQueryNode, ctx: CompilerContext): string {
|
|
79
|
-
return this.
|
|
111
|
+
return this.compilerSet.select.compile(ast, ctx);
|
|
80
112
|
}
|
|
81
113
|
|
|
82
114
|
protected compileInsertAst(ast: InsertQueryNode, ctx: CompilerContext): string {
|
|
83
|
-
return this.
|
|
115
|
+
return this.compilerSet.insert.compile(ast, ctx);
|
|
84
116
|
}
|
|
85
117
|
|
|
86
118
|
protected compileUpdateAst(ast: UpdateQueryNode, ctx: CompilerContext): string {
|
|
87
|
-
return this.
|
|
119
|
+
return this.compilerSet.update.compile(ast, ctx);
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
protected compileDeleteAst(ast: DeleteQueryNode, ctx: CompilerContext): string {
|
|
91
|
-
return this.
|
|
123
|
+
return this.compilerSet.delete.compile(ast, ctx);
|
|
92
124
|
}
|
|
93
125
|
|
|
94
|
-
protected compileUpsertClause(ast: InsertQueryNode,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
protected compileUpsertClause(ast: InsertQueryNode, ctx: CompilerContext): string {
|
|
127
|
+
return this.upsertStrategy.compile(ast, ctx, {
|
|
128
|
+
getDialectName: () => this.dialect,
|
|
129
|
+
quoteIdentifier: id => this.quoteIdentifier(id),
|
|
130
|
+
compileOperand: (node, compilerContext) => this.compileOperand(node, compilerContext),
|
|
131
|
+
compileExpression: (node, compilerContext) => this.compileExpression(node, compilerContext),
|
|
132
|
+
compileUpdateAssignments: (assignments, table, compilerContext) =>
|
|
133
|
+
this.standardUpdateCompiler.compileAssignments(assignments, table, compilerContext)
|
|
134
|
+
});
|
|
98
135
|
}
|
|
99
136
|
|
|
100
137
|
protected compileReturning(returning: ColumnNode[] | undefined, ctx: CompilerContext): string {
|
|
101
|
-
return this.returningStrategy.compileReturning(
|
|
138
|
+
return this.returningStrategy.compileReturning(
|
|
139
|
+
returning,
|
|
140
|
+
ctx,
|
|
141
|
+
id => this.quoteIdentifier(id)
|
|
142
|
+
);
|
|
102
143
|
}
|
|
103
144
|
|
|
104
145
|
protected ensureConflictColumns(clause: UpsertClause, message: string): void {
|
|
105
|
-
|
|
146
|
+
if (!clause.target.columns.length) throw new Error(message);
|
|
106
147
|
}
|
|
107
148
|
|
|
108
149
|
protected compileUpdateAssignments(
|
|
109
|
-
assignments:
|
|
150
|
+
assignments: UpdateAssignmentNode[],
|
|
110
151
|
table: TableNode,
|
|
111
152
|
ctx: CompilerContext
|
|
112
153
|
): string {
|
|
113
|
-
return this.
|
|
154
|
+
return this.standardUpdateCompiler.compileAssignments(assignments, table, ctx);
|
|
114
155
|
}
|
|
115
156
|
|
|
116
157
|
protected compileSetTarget(column: ColumnNode, table: TableNode): string {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { CompilerContext } from '../abstract.js';
|
|
2
|
+
import type {
|
|
3
|
+
InsertQueryNode,
|
|
4
|
+
TableNode,
|
|
5
|
+
UpdateAssignmentNode
|
|
6
|
+
} from '../../ast/query.js';
|
|
7
|
+
import type { ExpressionNode, OperandNode } from '../../ast/expression.js';
|
|
8
|
+
import type { DialectName } from '../../sql/sql.js';
|
|
9
|
+
|
|
10
|
+
/** Narrow services needed by backend-specific UPSERT implementations. */
|
|
11
|
+
export interface UpsertCompilationServices {
|
|
12
|
+
getDialectName(): DialectName;
|
|
13
|
+
quoteIdentifier(id: string): string;
|
|
14
|
+
compileOperand(node: OperandNode, ctx: CompilerContext): string;
|
|
15
|
+
compileExpression(node: ExpressionNode, ctx: CompilerContext): string;
|
|
16
|
+
compileUpdateAssignments(
|
|
17
|
+
assignments: UpdateAssignmentNode[],
|
|
18
|
+
table: TableNode,
|
|
19
|
+
ctx: CompilerContext
|
|
20
|
+
): string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Backend-specific INSERT conflict/upsert rendering strategy. */
|
|
24
|
+
export interface UpsertStrategy {
|
|
25
|
+
compile(
|
|
26
|
+
ast: InsertQueryNode,
|
|
27
|
+
ctx: CompilerContext,
|
|
28
|
+
services: UpsertCompilationServices
|
|
29
|
+
): string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Default strategy for dialects without UPSERT support. */
|
|
33
|
+
export class NoUpsertStrategy implements UpsertStrategy {
|
|
34
|
+
compile(
|
|
35
|
+
ast: InsertQueryNode,
|
|
36
|
+
_ctx: CompilerContext,
|
|
37
|
+
services: UpsertCompilationServices
|
|
38
|
+
): string {
|
|
39
|
+
void _ctx;
|
|
40
|
+
if (!ast.onConflict) return '';
|
|
41
|
+
throw new Error(
|
|
42
|
+
`UPSERT/ON CONFLICT is not supported by dialect "${services.getDialectName()}".`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ProcedureCallNode } from '../../ast/procedure.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { OperandNode } from '../../ast/expression.js';
|
|
3
|
+
import type { CompiledQuery, CompilerContext } from '../abstract.js';
|
|
3
4
|
|
|
4
5
|
export interface CompiledProcedureCall extends CompiledQuery {
|
|
5
6
|
outParams: {
|
|
@@ -8,13 +9,14 @@ export interface CompiledProcedureCall extends CompiledQuery {
|
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
/** Narrow SQL services consumed by reusable procedure compiler components. */
|
|
13
|
+
export interface ProcedureCompilerServices {
|
|
14
|
+
quoteIdentifier(id: string): string;
|
|
15
|
+
createCompilerContext(): CompilerContext;
|
|
16
|
+
compileOperand(node: OperandNode, ctx: CompilerContext): string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Optional dialect capability for stored-procedure compilation. */
|
|
18
20
|
export interface ProcedureCompiler {
|
|
19
21
|
compileProcedureCall(ast: ProcedureCallNode): CompiledProcedureCall;
|
|
20
22
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SqlCompilerFactory } from '../base/sql-compiler-set.js';
|
|
2
|
+
import { MssqlDeleteCompiler } from './delete-compiler.js';
|
|
3
|
+
import { MssqlInsertCompiler } from './insert-compiler.js';
|
|
4
|
+
import { MssqlSelectCompiler } from './select-compiler.js';
|
|
5
|
+
import { MssqlUpdateCompiler } from './update-compiler.js';
|
|
6
|
+
|
|
7
|
+
export const createMssqlCompilerSet: SqlCompilerFactory = ({ services, sources }) => ({
|
|
8
|
+
select: new MssqlSelectCompiler(services, sources),
|
|
9
|
+
insert: new MssqlInsertCompiler(services, sources),
|
|
10
|
+
update: new MssqlUpdateCompiler(services, sources),
|
|
11
|
+
delete: new MssqlDeleteCompiler(services, sources)
|
|
12
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { DeleteQueryNode } from '../../ast/query.js';
|
|
2
|
+
import type { CompilerContext } from '../abstract.js';
|
|
3
|
+
import { JoinCompiler } from '../base/join-compiler.js';
|
|
4
|
+
import type { SqlAstCompiler } from '../base/sql-compiler-set.js';
|
|
5
|
+
import type { StandardSqlCompilerServices } from '../base/standard-sql-services.js';
|
|
6
|
+
import type { StandardSqlSourceCompiler } from '../base/standard-sql-source-compiler.js';
|
|
7
|
+
import { MssqlOutputStrategy } from './output.js';
|
|
8
|
+
|
|
9
|
+
export class MssqlDeleteCompiler implements SqlAstCompiler<DeleteQueryNode> {
|
|
10
|
+
private readonly output = new MssqlOutputStrategy();
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
private readonly services: StandardSqlCompilerServices,
|
|
14
|
+
private readonly sources: StandardSqlSourceCompiler
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
compile(ast: DeleteQueryNode, ctx: CompilerContext): string {
|
|
18
|
+
if (ast.using) {
|
|
19
|
+
throw new Error('DELETE ... USING is not supported in the MSSQL dialect; use join() instead.');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const alias = ast.from.alias ?? ast.from.name;
|
|
23
|
+
const target = this.sources.compileTableReference(ast.from);
|
|
24
|
+
const joins = JoinCompiler.compileJoins(
|
|
25
|
+
ast.joins,
|
|
26
|
+
ctx,
|
|
27
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
28
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
29
|
+
);
|
|
30
|
+
const where = ast.where
|
|
31
|
+
? ` WHERE ${this.services.compileExpression(ast.where, ctx)}`
|
|
32
|
+
: '';
|
|
33
|
+
const returning = this.output.compileOutput(
|
|
34
|
+
ast.returning,
|
|
35
|
+
'deleted',
|
|
36
|
+
id => this.services.quoteIdentifier(id)
|
|
37
|
+
);
|
|
38
|
+
return `DELETE ${this.services.quoteIdentifier(alias)}${returning} FROM ${target}${joins}${where}`;
|
|
39
|
+
}
|
|
40
|
+
}
|