metal-orm 1.1.11 → 1.1.16
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 +758 -769
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +100 -96
- package/scripts/generate-entities/schema.mjs +122 -122
- package/scripts/generate-entities/tree-detection.mjs +92 -92
- package/scripts/inflection/pt-br.mjs +468 -468
- package/scripts/run-eslint.mjs +33 -34
- package/scripts/show-sql-seed.sql +102 -0
- package/scripts/show-sql.mjs +321 -325
- package/src/codegen/naming-strategy.ts +54 -54
- package/src/codegen/typescript.ts +482 -482
- package/src/core/ast/adapters.ts +1 -1
- package/src/core/ast/builders.ts +123 -123
- package/src/core/ast/expression-builders.ts +745 -745
- package/src/core/ast/expression-nodes.ts +304 -304
- package/src/core/ast/expression-visitor.ts +212 -212
- package/src/core/ast/expression.ts +20 -20
- package/src/core/ast/helpers.ts +14 -14
- package/src/core/ast/join.ts +18 -18
- package/src/core/ast/query.ts +200 -200
- package/src/core/ddl/dialects/base-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/render-reference.test.ts +70 -70
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -1
- package/src/core/ddl/introspect/catalogs/index.ts +5 -5
- package/src/core/ddl/introspect/catalogs/postgres.ts +146 -146
- package/src/core/ddl/introspect/context.ts +15 -15
- package/src/core/ddl/introspect/functions/postgres.ts +35 -35
- package/src/core/ddl/introspect/registry.ts +40 -40
- package/src/core/ddl/introspect/run-select.ts +35 -35
- package/src/core/ddl/introspect/utils.ts +56 -56
- package/src/core/ddl/naming-strategy.ts +16 -16
- package/src/core/ddl/schema-dialect.ts +56 -56
- package/src/core/ddl/schema-diff.ts +234 -234
- package/src/core/ddl/schema-generator.ts +1 -1
- package/src/core/ddl/schema-introspect.ts +25 -25
- package/src/core/ddl/sql-writing.ts +171 -171
- package/src/core/dialect/abstract.ts +541 -541
- package/src/core/dialect/base/cte-compiler.ts +33 -33
- package/src/core/dialect/base/function-table-formatter.ts +103 -103
- package/src/core/dialect/base/groupby-compiler.ts +21 -21
- package/src/core/dialect/base/join-compiler.ts +25 -25
- package/src/core/dialect/base/orderby-compiler.ts +35 -35
- package/src/core/dialect/base/pagination-strategy.ts +32 -32
- package/src/core/dialect/base/returning-strategy.ts +57 -57
- package/src/core/dialect/base/sql-dialect.ts +294 -294
- package/src/core/dialect/dialect-factory.ts +91 -91
- package/src/core/dialect/mssql/functions.ts +120 -120
- package/src/core/dialect/mssql/index.ts +317 -317
- package/src/core/dialect/mysql/functions.ts +103 -103
- package/src/core/dialect/mysql/index.ts +105 -105
- package/src/core/dialect/postgres/functions.ts +108 -108
- package/src/core/dialect/postgres/index.ts +91 -91
- package/src/core/dialect/sqlite/functions.ts +129 -129
- package/src/core/dialect/sqlite/index.ts +67 -67
- package/src/core/driver/database-driver.ts +19 -19
- package/src/core/driver/mssql-driver.ts +23 -23
- package/src/core/driver/mysql-driver.ts +23 -23
- package/src/core/driver/postgres-driver.ts +23 -23
- package/src/core/driver/sqlite-driver.ts +23 -23
- package/src/core/execution/db-executor.ts +92 -92
- package/src/core/execution/executors/better-sqlite3-executor.ts +90 -90
- package/src/core/execution/executors/mssql-executor.ts +184 -184
- package/src/core/execution/executors/mysql-executor.ts +88 -88
- package/src/core/execution/executors/postgres-executor.ts +26 -26
- package/src/core/execution/executors/sqlite-executor.ts +42 -42
- package/src/core/execution/pooling/pool-types.ts +30 -30
- package/src/core/execution/pooling/pool.ts +275 -275
- package/src/core/functions/array.ts +35 -35
- package/src/core/functions/control-flow.ts +79 -79
- package/src/core/functions/datetime.ts +237 -237
- package/src/core/functions/json.ts +70 -70
- package/src/core/functions/numeric.ts +297 -297
- package/src/core/functions/text.ts +334 -334
- package/src/core/functions/types.ts +33 -33
- package/src/core/hydration/types.ts +51 -51
- package/src/core/sql/sql-operator-config.ts +39 -39
- package/src/core/sql/sql.ts +152 -152
- package/src/decorators/column-decorator.ts +87 -87
- package/src/decorators/decorator-metadata.ts +143 -143
- package/src/decorators/entity.ts +93 -93
- package/src/decorators/index.ts +39 -39
- package/src/decorators/relations.ts +231 -231
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -231
- package/src/decorators/transformers/transformer-decorators.ts +134 -134
- package/src/decorators/transformers/transformer-executor.ts +171 -171
- package/src/decorators/transformers/transformer-metadata.ts +73 -73
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -55
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -105
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -103
- package/src/decorators/validators/country-validator-registry.ts +64 -64
- package/src/decorators/validators/country-validators-decorators.ts +203 -203
- package/src/decorators/validators/country-validators.ts +105 -105
- package/src/decorators/validators/validator-metadata.ts +59 -59
- package/src/dto/dto-types.ts +226 -226
- package/src/dto/filter-types.ts +141 -141
- package/src/dto/index.ts +95 -95
- package/src/dto/openapi/generators/base.ts +29 -29
- package/src/dto/openapi/generators/column.ts +37 -37
- package/src/dto/openapi/generators/dto.ts +91 -91
- package/src/dto/openapi/generators/filter.ts +75 -75
- package/src/dto/openapi/generators/nested-dto.ts +618 -618
- package/src/dto/openapi/generators/pagination.ts +111 -111
- package/src/dto/openapi/generators/relation-filter.ts +228 -228
- package/src/dto/openapi/index.ts +12 -12
- package/src/dto/openapi/types.ts +101 -101
- package/src/dto/openapi/utilities.ts +95 -95
- package/src/dto/pagination-utils.ts +150 -150
- package/src/dto/transform.ts +197 -197
- package/src/index.ts +86 -86
- package/src/orm/als.ts +58 -58
- package/src/orm/domain-event-bus.ts +119 -119
- package/src/orm/entity-context.ts +86 -86
- package/src/orm/entity-materializer.ts +159 -159
- package/src/orm/entity-meta.ts +97 -97
- package/src/orm/entity-registry.ts +39 -39
- package/src/orm/entity-relation-cache.ts +39 -39
- package/src/orm/execute.ts +194 -194
- package/src/orm/execution-context.ts +18 -18
- package/src/orm/hydration-context.ts +26 -26
- package/src/orm/hydration.ts +112 -112
- package/src/orm/identity-map.ts +61 -61
- package/src/orm/interceptor-pipeline.ts +16 -16
- package/src/orm/lazy-batch/belongs-to-many.ts +119 -119
- package/src/orm/lazy-batch/belongs-to.ts +108 -108
- package/src/orm/lazy-batch/has-many.ts +69 -69
- package/src/orm/lazy-batch/has-one.ts +68 -68
- package/src/orm/lazy-batch/shared.ts +125 -125
- package/src/orm/orm-session.ts +620 -620
- package/src/orm/orm.ts +34 -34
- package/src/orm/pooled-executor-factory.ts +121 -121
- package/src/orm/query-logger.ts +40 -40
- package/src/orm/relation-change-processor.ts +420 -420
- package/src/orm/relations/belongs-to.ts +143 -143
- package/src/orm/relations/has-many.ts +204 -204
- package/src/orm/relations/has-one.ts +174 -174
- package/src/orm/relations/many-to-many.ts +288 -288
- package/src/orm/relations/morph-many.ts +156 -156
- package/src/orm/relations/morph-one.ts +151 -151
- package/src/orm/relations/morph-to.ts +162 -162
- package/src/orm/runtime-types.ts +92 -92
- package/src/orm/save-graph.ts +561 -561
- package/src/orm/transaction-runner.ts +24 -24
- package/src/orm/unit-of-work.ts +426 -426
- package/src/query/index.ts +69 -69
- package/src/query/target.ts +46 -46
- package/src/query-builder/column-selector.ts +81 -81
- package/src/query-builder/delete.ts +141 -141
- package/src/query-builder/insert-query-state.ts +149 -149
- package/src/query-builder/insert.ts +117 -117
- package/src/query-builder/query-ast-service.ts +287 -287
- package/src/query-builder/query-resolution.ts +78 -78
- package/src/query-builder/raw-column-parser.ts +38 -38
- package/src/query-builder/relation-filter-utils.ts +153 -153
- package/src/query-builder/relation-join-planner.ts +10 -10
- package/src/query-builder/relation-manager.ts +87 -87
- package/src/query-builder/relation-projection-helper.ts +102 -102
- package/src/query-builder/relation-types.ts +9 -9
- package/src/query-builder/relation-utils.ts +15 -15
- package/src/query-builder/select/cte-facet.ts +40 -40
- package/src/query-builder/select/from-facet.ts +80 -80
- package/src/query-builder/select/join-facet.ts +62 -62
- package/src/query-builder/select/predicate-facet.ts +104 -104
- package/src/query-builder/select/projection-facet.ts +70 -70
- package/src/query-builder/select/relation-facet.ts +81 -81
- package/src/query-builder/select/setop-facet.ts +36 -36
- package/src/query-builder/select-helpers.ts +1 -1
- package/src/query-builder/select-query-builder-deps.ts +130 -130
- package/src/query-builder/select-query-state.ts +207 -207
- package/src/query-builder/update.ts +151 -151
- package/src/schema/column-types.ts +322 -322
- package/src/schema/table-guards.ts +37 -37
- package/src/schema/table.ts +281 -281
- package/src/tree/index.ts +13 -13
- package/src/tree/nested-set-strategy.ts +545 -545
- package/src/tree/tree-decorator.ts +397 -397
- package/src/tree/tree-manager.ts +754 -754
- package/src/tree/tree-query.ts +427 -427
- package/src/tree/tree-types.ts +299 -299
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import { TableDef } from '../schema/table.js';
|
|
2
|
-
import { ColumnDef } from '../schema/column-types.js';
|
|
3
|
-
import { ColumnNode, ExpressionNode } from '../core/ast/expression.js';
|
|
4
|
-
import { JOIN_KINDS, JoinKind } from '../core/sql/sql.js';
|
|
5
|
-
import { CompiledQuery, Dialect } from '../core/dialect/abstract.js';
|
|
6
|
-
import { DialectKey, resolveDialectInput } from '../core/dialect/dialect-factory.js';
|
|
7
|
-
import { TableSourceNode, DeleteQueryNode } from '../core/ast/query.js';
|
|
8
|
-
import { DeleteQueryState } from './delete-query-state.js';
|
|
9
|
-
import { createJoinNode } from '../core/ast/join-node.js';
|
|
10
|
-
import { buildColumnNode } from '../core/ast/builders.js';
|
|
11
|
-
import { OrmSession } from '../orm/orm-session.js';
|
|
1
|
+
import { TableDef } from '../schema/table.js';
|
|
2
|
+
import { ColumnDef } from '../schema/column-types.js';
|
|
3
|
+
import { ColumnNode, ExpressionNode } from '../core/ast/expression.js';
|
|
4
|
+
import { JOIN_KINDS, JoinKind } from '../core/sql/sql.js';
|
|
5
|
+
import { CompiledQuery, Dialect } from '../core/dialect/abstract.js';
|
|
6
|
+
import { DialectKey, resolveDialectInput } from '../core/dialect/dialect-factory.js';
|
|
7
|
+
import { TableSourceNode, DeleteQueryNode } from '../core/ast/query.js';
|
|
8
|
+
import { DeleteQueryState } from './delete-query-state.js';
|
|
9
|
+
import { createJoinNode } from '../core/ast/join-node.js';
|
|
10
|
+
import { buildColumnNode } from '../core/ast/builders.js';
|
|
11
|
+
import { OrmSession } from '../orm/orm-session.js';
|
|
12
12
|
import { payloadResultSets, QueryResult } from '../core/execution/db-executor.js';
|
|
13
|
-
|
|
14
|
-
type DeleteDialectInput = Dialect | DialectKey;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Builder for DELETE queries
|
|
18
|
-
*/
|
|
19
|
-
export class DeleteQueryBuilder<T> {
|
|
20
|
-
private readonly table: TableDef;
|
|
21
|
-
private readonly state: DeleteQueryState;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Creates a new DeleteQueryBuilder instance
|
|
25
|
-
* @param table - The table definition for the DELETE query
|
|
26
|
-
* @param state - Optional initial query state, defaults to a new DeleteQueryState
|
|
27
|
-
*/
|
|
28
|
-
constructor(table: TableDef, state?: DeleteQueryState) {
|
|
29
|
-
this.table = table;
|
|
30
|
-
this.state = state ?? new DeleteQueryState(table);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private clone(state: DeleteQueryState): DeleteQueryBuilder<T> {
|
|
34
|
-
return new DeleteQueryBuilder(this.table, state);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Adds a WHERE clause to the DELETE query
|
|
39
|
-
* @param expr - The expression to use as the WHERE condition
|
|
40
|
-
* @returns A new DeleteQueryBuilder with the WHERE clause added
|
|
41
|
-
*/
|
|
42
|
-
where(expr: ExpressionNode): DeleteQueryBuilder<T> {
|
|
43
|
-
return this.clone(this.state.withWhere(expr));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Sets an alias for the table in the DELETE query
|
|
48
|
-
* @param alias - The alias to assign to the table
|
|
49
|
-
* @returns A new DeleteQueryBuilder with the table alias set
|
|
50
|
-
*/
|
|
51
|
-
as(alias: string): DeleteQueryBuilder<T> {
|
|
52
|
-
return this.clone(this.state.withTableAlias(alias));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Adds a USING clause to the DELETE query
|
|
57
|
-
* @param source - The table source to use in the USING clause
|
|
58
|
-
* @returns A new DeleteQueryBuilder with the USING clause added
|
|
59
|
-
*/
|
|
60
|
-
using(source: TableDef | TableSourceNode): DeleteQueryBuilder<T> {
|
|
61
|
-
return this.clone(this.state.withUsing(this.resolveTableSource(source)));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Adds a JOIN clause to the DELETE query
|
|
66
|
-
* @param table - The table to join with
|
|
67
|
-
* @param condition - The join condition expression
|
|
68
|
-
* @param kind - The type of join (defaults to INNER)
|
|
69
|
-
* @param relationName - Optional name for the relation
|
|
70
|
-
* @returns A new DeleteQueryBuilder with the JOIN clause added
|
|
71
|
-
*/
|
|
72
|
-
join(
|
|
73
|
-
table: TableDef | TableSourceNode | string,
|
|
74
|
-
condition: ExpressionNode,
|
|
75
|
-
kind: JoinKind = JOIN_KINDS.INNER,
|
|
76
|
-
relationName?: string
|
|
77
|
-
): DeleteQueryBuilder<T> {
|
|
78
|
-
const target = this.resolveJoinTarget(table);
|
|
79
|
-
const joinNode = createJoinNode(kind, target, condition, relationName);
|
|
80
|
-
return this.clone(this.state.withJoin(joinNode));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Adds a RETURNING clause to the DELETE query
|
|
85
|
-
* @param columns - The columns to return after deletion
|
|
86
|
-
* @returns A new DeleteQueryBuilder with the RETURNING clause added
|
|
87
|
-
*/
|
|
88
|
-
returning(...columns: (ColumnDef | ColumnNode)[]): DeleteQueryBuilder<T> {
|
|
89
|
-
if (!columns.length) return this;
|
|
90
|
-
const nodes = columns.map(column => buildColumnNode(this.table, column));
|
|
91
|
-
return this.clone(this.state.withReturning(nodes));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private resolveTableSource(source: TableDef | TableSourceNode): TableSourceNode {
|
|
95
|
-
if (isTableSourceNode(source)) {
|
|
96
|
-
return source;
|
|
97
|
-
}
|
|
98
|
-
return { type: 'Table', name: source.name, schema: source.schema };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private resolveJoinTarget(table: TableDef | TableSourceNode | string): TableSourceNode | string {
|
|
102
|
-
if (typeof table === 'string') return table;
|
|
103
|
-
return this.resolveTableSource(table);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Compiles the DELETE query for the specified dialect
|
|
108
|
-
* @param dialect - The SQL dialect to compile for
|
|
109
|
-
* @returns The compiled query with SQL and parameters
|
|
110
|
-
*/
|
|
111
|
-
compile(dialect: DeleteDialectInput): CompiledQuery {
|
|
112
|
-
const resolved = resolveDialectInput(dialect);
|
|
113
|
-
return resolved.compileDelete(this.state.ast);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Returns the SQL string for the DELETE query
|
|
118
|
-
* @param dialect - The SQL dialect to generate SQL for
|
|
119
|
-
* @returns The SQL string representation of the query
|
|
120
|
-
*/
|
|
121
|
-
toSql(dialect: DeleteDialectInput): string {
|
|
122
|
-
return this.compile(dialect).sql;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Executes the DELETE query using the provided session
|
|
127
|
-
* @param session - The ORM session to execute the query with
|
|
128
|
-
* @returns A promise that resolves to the query results
|
|
129
|
-
*/
|
|
13
|
+
|
|
14
|
+
type DeleteDialectInput = Dialect | DialectKey;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Builder for DELETE queries
|
|
18
|
+
*/
|
|
19
|
+
export class DeleteQueryBuilder<T> {
|
|
20
|
+
private readonly table: TableDef;
|
|
21
|
+
private readonly state: DeleteQueryState;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new DeleteQueryBuilder instance
|
|
25
|
+
* @param table - The table definition for the DELETE query
|
|
26
|
+
* @param state - Optional initial query state, defaults to a new DeleteQueryState
|
|
27
|
+
*/
|
|
28
|
+
constructor(table: TableDef, state?: DeleteQueryState) {
|
|
29
|
+
this.table = table;
|
|
30
|
+
this.state = state ?? new DeleteQueryState(table);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private clone(state: DeleteQueryState): DeleteQueryBuilder<T> {
|
|
34
|
+
return new DeleteQueryBuilder(this.table, state);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Adds a WHERE clause to the DELETE query
|
|
39
|
+
* @param expr - The expression to use as the WHERE condition
|
|
40
|
+
* @returns A new DeleteQueryBuilder with the WHERE clause added
|
|
41
|
+
*/
|
|
42
|
+
where(expr: ExpressionNode): DeleteQueryBuilder<T> {
|
|
43
|
+
return this.clone(this.state.withWhere(expr));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Sets an alias for the table in the DELETE query
|
|
48
|
+
* @param alias - The alias to assign to the table
|
|
49
|
+
* @returns A new DeleteQueryBuilder with the table alias set
|
|
50
|
+
*/
|
|
51
|
+
as(alias: string): DeleteQueryBuilder<T> {
|
|
52
|
+
return this.clone(this.state.withTableAlias(alias));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Adds a USING clause to the DELETE query
|
|
57
|
+
* @param source - The table source to use in the USING clause
|
|
58
|
+
* @returns A new DeleteQueryBuilder with the USING clause added
|
|
59
|
+
*/
|
|
60
|
+
using(source: TableDef | TableSourceNode): DeleteQueryBuilder<T> {
|
|
61
|
+
return this.clone(this.state.withUsing(this.resolveTableSource(source)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Adds a JOIN clause to the DELETE query
|
|
66
|
+
* @param table - The table to join with
|
|
67
|
+
* @param condition - The join condition expression
|
|
68
|
+
* @param kind - The type of join (defaults to INNER)
|
|
69
|
+
* @param relationName - Optional name for the relation
|
|
70
|
+
* @returns A new DeleteQueryBuilder with the JOIN clause added
|
|
71
|
+
*/
|
|
72
|
+
join(
|
|
73
|
+
table: TableDef | TableSourceNode | string,
|
|
74
|
+
condition: ExpressionNode,
|
|
75
|
+
kind: JoinKind = JOIN_KINDS.INNER,
|
|
76
|
+
relationName?: string
|
|
77
|
+
): DeleteQueryBuilder<T> {
|
|
78
|
+
const target = this.resolveJoinTarget(table);
|
|
79
|
+
const joinNode = createJoinNode(kind, target, condition, relationName);
|
|
80
|
+
return this.clone(this.state.withJoin(joinNode));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Adds a RETURNING clause to the DELETE query
|
|
85
|
+
* @param columns - The columns to return after deletion
|
|
86
|
+
* @returns A new DeleteQueryBuilder with the RETURNING clause added
|
|
87
|
+
*/
|
|
88
|
+
returning(...columns: (ColumnDef | ColumnNode)[]): DeleteQueryBuilder<T> {
|
|
89
|
+
if (!columns.length) return this;
|
|
90
|
+
const nodes = columns.map(column => buildColumnNode(this.table, column));
|
|
91
|
+
return this.clone(this.state.withReturning(nodes));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private resolveTableSource(source: TableDef | TableSourceNode): TableSourceNode {
|
|
95
|
+
if (isTableSourceNode(source)) {
|
|
96
|
+
return source;
|
|
97
|
+
}
|
|
98
|
+
return { type: 'Table', name: source.name, schema: source.schema };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private resolveJoinTarget(table: TableDef | TableSourceNode | string): TableSourceNode | string {
|
|
102
|
+
if (typeof table === 'string') return table;
|
|
103
|
+
return this.resolveTableSource(table);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Compiles the DELETE query for the specified dialect
|
|
108
|
+
* @param dialect - The SQL dialect to compile for
|
|
109
|
+
* @returns The compiled query with SQL and parameters
|
|
110
|
+
*/
|
|
111
|
+
compile(dialect: DeleteDialectInput): CompiledQuery {
|
|
112
|
+
const resolved = resolveDialectInput(dialect);
|
|
113
|
+
return resolved.compileDelete(this.state.ast);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns the SQL string for the DELETE query
|
|
118
|
+
* @param dialect - The SQL dialect to generate SQL for
|
|
119
|
+
* @returns The SQL string representation of the query
|
|
120
|
+
*/
|
|
121
|
+
toSql(dialect: DeleteDialectInput): string {
|
|
122
|
+
return this.compile(dialect).sql;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Executes the DELETE query using the provided session
|
|
127
|
+
* @param session - The ORM session to execute the query with
|
|
128
|
+
* @returns A promise that resolves to the query results
|
|
129
|
+
*/
|
|
130
130
|
async execute(session: OrmSession): Promise<QueryResult[]> {
|
|
131
131
|
const execCtx = session.getExecutionContext();
|
|
132
132
|
const compiled = this.compile(execCtx.dialect);
|
|
133
133
|
const payload = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
|
|
134
134
|
return payloadResultSets(payload);
|
|
135
135
|
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
139
|
-
* @returns The AST node for the DELETE query
|
|
140
|
-
*/
|
|
141
|
-
getAST(): DeleteQueryNode {
|
|
142
|
-
return this.state.ast;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const isTableSourceNode = (source: TableDef | TableSourceNode): source is TableSourceNode =>
|
|
147
|
-
typeof (source as TableSourceNode).type === 'string';
|
|
148
|
-
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
139
|
+
* @returns The AST node for the DELETE query
|
|
140
|
+
*/
|
|
141
|
+
getAST(): DeleteQueryNode {
|
|
142
|
+
return this.state.ast;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const isTableSourceNode = (source: TableDef | TableSourceNode): source is TableSourceNode =>
|
|
147
|
+
typeof (source as TableSourceNode).type === 'string';
|
|
148
|
+
|
|
@@ -4,155 +4,155 @@ import {
|
|
|
4
4
|
ColumnNode,
|
|
5
5
|
OperandNode,
|
|
6
6
|
isValueOperandInput,
|
|
7
|
-
valueToOperand
|
|
8
|
-
} from '../core/ast/expression.js';
|
|
9
|
-
import type { ValueOperandInput } from '../core/ast/expression.js';
|
|
10
|
-
import {
|
|
11
|
-
buildColumnNodes,
|
|
12
|
-
createTableNode
|
|
13
|
-
} from '../core/ast/builders.js';
|
|
14
|
-
|
|
15
|
-
type InsertRows = Record<string, ValueOperandInput>[];
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Maintains immutable state for building INSERT queries
|
|
19
|
-
*/
|
|
20
|
-
export class InsertQueryState {
|
|
21
|
-
public readonly table: TableDef;
|
|
22
|
-
public readonly ast: InsertQueryNode;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Creates a new InsertQueryState instance
|
|
26
|
-
* @param table - The table definition for the INSERT query
|
|
27
|
-
* @param ast - Optional initial AST node, defaults to a basic INSERT query
|
|
28
|
-
*/
|
|
29
|
-
constructor(table: TableDef, ast?: InsertQueryNode) {
|
|
30
|
-
this.table = table;
|
|
31
|
-
this.ast = ast ?? {
|
|
32
|
-
type: 'InsertQuery',
|
|
33
|
-
into: createTableNode(table),
|
|
34
|
-
columns: [],
|
|
35
|
-
source: {
|
|
36
|
-
type: 'InsertValues',
|
|
37
|
-
rows: []
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private clone(nextAst: InsertQueryNode): InsertQueryState {
|
|
43
|
-
return new InsertQueryState(this.table, nextAst);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private ensureColumnsFromRow(rows: InsertRows): ColumnNode[] {
|
|
47
|
-
if (this.ast.columns.length) return this.ast.columns;
|
|
48
|
-
return buildColumnNodes(this.table, Object.keys(rows[0]));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private appendValues(rows: OperandNode[][]): OperandNode[][] {
|
|
52
|
-
if (this.ast.source.type === 'InsertValues') {
|
|
53
|
-
return [...this.ast.source.rows, ...rows];
|
|
54
|
-
}
|
|
55
|
-
return rows;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private getTableColumns(): ColumnNode[] {
|
|
59
|
-
const names = Object.keys(this.table.columns);
|
|
60
|
-
if (!names.length) return [];
|
|
61
|
-
return buildColumnNodes(this.table, names);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Adds VALUES clause to the INSERT query
|
|
66
|
-
* @param rows - Array of row objects to insert
|
|
67
|
-
* @returns A new InsertQueryState with the VALUES clause added
|
|
68
|
-
* @throws Error if mixing VALUES with SELECT source
|
|
69
|
-
* @throws Error if invalid values are provided
|
|
70
|
-
*/
|
|
71
|
-
withValues(rows: InsertRows): InsertQueryState {
|
|
72
|
-
if (!rows.length) return this;
|
|
73
|
-
|
|
74
|
-
if (this.ast.source.type === 'InsertSelect') {
|
|
75
|
-
throw new Error('Cannot mix INSERT ... VALUES with INSERT ... SELECT source.');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const definedColumns = this.ensureColumnsFromRow(rows);
|
|
79
|
-
|
|
80
|
-
const newRows: OperandNode[][] = rows.map((row, rowIndex) =>
|
|
81
|
-
definedColumns.map(column => {
|
|
82
|
-
const rawValue = row[column.name];
|
|
83
|
-
|
|
84
|
-
if (!isValueOperandInput(rawValue)) {
|
|
85
|
-
throw new Error(
|
|
86
|
-
`Invalid insert value for column "${column.name}" in row ${rowIndex}: only string, number, boolean, Date, Buffer, null, or OperandNodes are allowed`
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return valueToOperand(rawValue);
|
|
91
|
-
})
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
return this.clone({
|
|
95
|
-
...this.ast,
|
|
96
|
-
columns: definedColumns,
|
|
97
|
-
source: {
|
|
98
|
-
type: 'InsertValues',
|
|
99
|
-
rows: this.appendValues(newRows)
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Sets the columns for the INSERT query
|
|
106
|
-
* @param columns - Column nodes to insert into
|
|
107
|
-
* @returns A new InsertQueryState with the specified columns
|
|
108
|
-
*/
|
|
109
|
-
withColumns(columns: ColumnNode[]): InsertQueryState {
|
|
110
|
-
if (!columns.length) return this;
|
|
111
|
-
return this.clone({
|
|
112
|
-
...this.ast,
|
|
113
|
-
columns: [...columns]
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Adds SELECT source to the INSERT query
|
|
119
|
-
* @param query - The SELECT query to use as source
|
|
120
|
-
* @param columns - Target columns for the INSERT
|
|
121
|
-
* @returns A new InsertQueryState with the SELECT source
|
|
122
|
-
* @throws Error if mixing SELECT with VALUES source
|
|
123
|
-
* @throws Error if no destination columns specified
|
|
124
|
-
*/
|
|
125
|
-
withSelect(query: SelectQueryNode, columns: ColumnNode[]): InsertQueryState {
|
|
126
|
-
const targetColumns =
|
|
127
|
-
columns.length
|
|
128
|
-
? columns
|
|
129
|
-
: this.ast.columns.length
|
|
130
|
-
? this.ast.columns
|
|
131
|
-
: this.getTableColumns();
|
|
132
|
-
|
|
133
|
-
if (!targetColumns.length) {
|
|
134
|
-
throw new Error('INSERT ... SELECT requires specifying destination columns.');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (this.ast.source.type === 'InsertValues' && this.ast.source.rows.length) {
|
|
138
|
-
throw new Error('Cannot mix INSERT ... SELECT with INSERT ... VALUES source.');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return this.clone({
|
|
142
|
-
...this.ast,
|
|
143
|
-
columns: [...targetColumns],
|
|
144
|
-
source: {
|
|
145
|
-
type: 'InsertSelect',
|
|
146
|
-
query
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Adds a RETURNING clause to the INSERT query
|
|
153
|
-
* @param columns - Columns to return after insertion
|
|
154
|
-
* @returns A new InsertQueryState with the RETURNING clause added
|
|
155
|
-
*/
|
|
7
|
+
valueToOperand
|
|
8
|
+
} from '../core/ast/expression.js';
|
|
9
|
+
import type { ValueOperandInput } from '../core/ast/expression.js';
|
|
10
|
+
import {
|
|
11
|
+
buildColumnNodes,
|
|
12
|
+
createTableNode
|
|
13
|
+
} from '../core/ast/builders.js';
|
|
14
|
+
|
|
15
|
+
type InsertRows = Record<string, ValueOperandInput>[];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Maintains immutable state for building INSERT queries
|
|
19
|
+
*/
|
|
20
|
+
export class InsertQueryState {
|
|
21
|
+
public readonly table: TableDef;
|
|
22
|
+
public readonly ast: InsertQueryNode;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new InsertQueryState instance
|
|
26
|
+
* @param table - The table definition for the INSERT query
|
|
27
|
+
* @param ast - Optional initial AST node, defaults to a basic INSERT query
|
|
28
|
+
*/
|
|
29
|
+
constructor(table: TableDef, ast?: InsertQueryNode) {
|
|
30
|
+
this.table = table;
|
|
31
|
+
this.ast = ast ?? {
|
|
32
|
+
type: 'InsertQuery',
|
|
33
|
+
into: createTableNode(table),
|
|
34
|
+
columns: [],
|
|
35
|
+
source: {
|
|
36
|
+
type: 'InsertValues',
|
|
37
|
+
rows: []
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private clone(nextAst: InsertQueryNode): InsertQueryState {
|
|
43
|
+
return new InsertQueryState(this.table, nextAst);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private ensureColumnsFromRow(rows: InsertRows): ColumnNode[] {
|
|
47
|
+
if (this.ast.columns.length) return this.ast.columns;
|
|
48
|
+
return buildColumnNodes(this.table, Object.keys(rows[0]));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private appendValues(rows: OperandNode[][]): OperandNode[][] {
|
|
52
|
+
if (this.ast.source.type === 'InsertValues') {
|
|
53
|
+
return [...this.ast.source.rows, ...rows];
|
|
54
|
+
}
|
|
55
|
+
return rows;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private getTableColumns(): ColumnNode[] {
|
|
59
|
+
const names = Object.keys(this.table.columns);
|
|
60
|
+
if (!names.length) return [];
|
|
61
|
+
return buildColumnNodes(this.table, names);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Adds VALUES clause to the INSERT query
|
|
66
|
+
* @param rows - Array of row objects to insert
|
|
67
|
+
* @returns A new InsertQueryState with the VALUES clause added
|
|
68
|
+
* @throws Error if mixing VALUES with SELECT source
|
|
69
|
+
* @throws Error if invalid values are provided
|
|
70
|
+
*/
|
|
71
|
+
withValues(rows: InsertRows): InsertQueryState {
|
|
72
|
+
if (!rows.length) return this;
|
|
73
|
+
|
|
74
|
+
if (this.ast.source.type === 'InsertSelect') {
|
|
75
|
+
throw new Error('Cannot mix INSERT ... VALUES with INSERT ... SELECT source.');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const definedColumns = this.ensureColumnsFromRow(rows);
|
|
79
|
+
|
|
80
|
+
const newRows: OperandNode[][] = rows.map((row, rowIndex) =>
|
|
81
|
+
definedColumns.map(column => {
|
|
82
|
+
const rawValue = row[column.name];
|
|
83
|
+
|
|
84
|
+
if (!isValueOperandInput(rawValue)) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Invalid insert value for column "${column.name}" in row ${rowIndex}: only string, number, boolean, Date, Buffer, null, or OperandNodes are allowed`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return valueToOperand(rawValue);
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return this.clone({
|
|
95
|
+
...this.ast,
|
|
96
|
+
columns: definedColumns,
|
|
97
|
+
source: {
|
|
98
|
+
type: 'InsertValues',
|
|
99
|
+
rows: this.appendValues(newRows)
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Sets the columns for the INSERT query
|
|
106
|
+
* @param columns - Column nodes to insert into
|
|
107
|
+
* @returns A new InsertQueryState with the specified columns
|
|
108
|
+
*/
|
|
109
|
+
withColumns(columns: ColumnNode[]): InsertQueryState {
|
|
110
|
+
if (!columns.length) return this;
|
|
111
|
+
return this.clone({
|
|
112
|
+
...this.ast,
|
|
113
|
+
columns: [...columns]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Adds SELECT source to the INSERT query
|
|
119
|
+
* @param query - The SELECT query to use as source
|
|
120
|
+
* @param columns - Target columns for the INSERT
|
|
121
|
+
* @returns A new InsertQueryState with the SELECT source
|
|
122
|
+
* @throws Error if mixing SELECT with VALUES source
|
|
123
|
+
* @throws Error if no destination columns specified
|
|
124
|
+
*/
|
|
125
|
+
withSelect(query: SelectQueryNode, columns: ColumnNode[]): InsertQueryState {
|
|
126
|
+
const targetColumns =
|
|
127
|
+
columns.length
|
|
128
|
+
? columns
|
|
129
|
+
: this.ast.columns.length
|
|
130
|
+
? this.ast.columns
|
|
131
|
+
: this.getTableColumns();
|
|
132
|
+
|
|
133
|
+
if (!targetColumns.length) {
|
|
134
|
+
throw new Error('INSERT ... SELECT requires specifying destination columns.');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (this.ast.source.type === 'InsertValues' && this.ast.source.rows.length) {
|
|
138
|
+
throw new Error('Cannot mix INSERT ... SELECT with INSERT ... VALUES source.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return this.clone({
|
|
142
|
+
...this.ast,
|
|
143
|
+
columns: [...targetColumns],
|
|
144
|
+
source: {
|
|
145
|
+
type: 'InsertSelect',
|
|
146
|
+
query
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Adds a RETURNING clause to the INSERT query
|
|
153
|
+
* @param columns - Columns to return after insertion
|
|
154
|
+
* @returns A new InsertQueryState with the RETURNING clause added
|
|
155
|
+
*/
|
|
156
156
|
withReturning(columns: ColumnNode[]): InsertQueryState {
|
|
157
157
|
return this.clone({
|
|
158
158
|
...this.ast,
|