metal-orm 1.1.11 → 1.1.18
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,87 +1,87 @@
|
|
|
1
|
-
import { ExpressionNode } from '../core/ast/expression.js';
|
|
2
|
-
import { SelectQueryNode } from '../core/ast/query.js';
|
|
3
|
-
import { SelectQueryBuilderContext, SelectQueryBuilderEnvironment } from './select-query-builder-deps.js';
|
|
4
|
-
import { JoinKind } from '../core/sql/sql.js';
|
|
5
|
-
import { RelationIncludeOptions } from './relation-types.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Manages relation operations (joins, includes, etc.) for query building
|
|
9
|
-
*/
|
|
10
|
-
export class RelationManager {
|
|
11
|
-
/**
|
|
12
|
-
* Creates a new RelationManager instance
|
|
13
|
-
* @param env - Query builder environment
|
|
14
|
-
*/
|
|
15
|
-
constructor(private readonly env: SelectQueryBuilderEnvironment) {}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Matches records based on a relation with an optional predicate
|
|
19
|
-
* @param context - Current query context
|
|
20
|
-
* @param relationName - Name of the relation to match
|
|
21
|
-
* @param predicate - Optional predicate expression
|
|
22
|
-
* @returns Updated query context with relation match
|
|
23
|
-
*/
|
|
24
|
-
match(context: SelectQueryBuilderContext, relationName: string, predicate?: ExpressionNode): SelectQueryBuilderContext {
|
|
25
|
-
const result = this.createService(context).match(relationName, predicate);
|
|
26
|
-
return { state: result.state, hydration: result.hydration };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Joins a relation to the query
|
|
31
|
-
* @param context - Current query context
|
|
32
|
-
* @param relationName - Name of the relation to join
|
|
33
|
-
* @param joinKind - Type of join to use
|
|
34
|
-
* @param extraCondition - Additional join condition
|
|
35
|
-
* @returns Updated query context with relation join
|
|
36
|
-
*/
|
|
37
|
-
joinRelation(
|
|
38
|
-
context: SelectQueryBuilderContext,
|
|
39
|
-
relationName: string,
|
|
40
|
-
joinKind: JoinKind,
|
|
41
|
-
extraCondition?: ExpressionNode
|
|
42
|
-
): SelectQueryBuilderContext {
|
|
43
|
-
const result = this.createService(context).joinRelation(relationName, joinKind, extraCondition);
|
|
44
|
-
return { state: result.state, hydration: result.hydration };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Includes a relation in the query result
|
|
49
|
-
* @param context - Current query context
|
|
50
|
-
* @param relationName - Name of the relation to include
|
|
51
|
-
* @param options - Options for relation inclusion
|
|
52
|
-
* @returns Updated query context with included relation
|
|
53
|
-
*/
|
|
54
|
-
include(
|
|
55
|
-
context: SelectQueryBuilderContext,
|
|
56
|
-
relationName: string,
|
|
57
|
-
options?: RelationIncludeOptions
|
|
58
|
-
): SelectQueryBuilderContext {
|
|
59
|
-
const result = this.createService(context).include(relationName, options);
|
|
60
|
-
return { state: result.state, hydration: result.hydration };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Applies relation correlation to a query AST
|
|
65
|
-
* @param context - Current query context
|
|
66
|
-
* @param relationName - Name of the relation
|
|
67
|
-
* @param ast - Query AST to modify
|
|
68
|
-
* @returns Modified query AST with relation correlation
|
|
69
|
-
*/
|
|
70
|
-
applyRelationCorrelation(
|
|
71
|
-
context: SelectQueryBuilderContext,
|
|
72
|
-
relationName: string,
|
|
73
|
-
ast: SelectQueryNode,
|
|
74
|
-
additionalCorrelation?: ExpressionNode
|
|
75
|
-
): SelectQueryNode {
|
|
76
|
-
return this.createService(context).applyRelationCorrelation(relationName, ast, additionalCorrelation);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Creates a relation service instance
|
|
81
|
-
* @param context - Current query context
|
|
82
|
-
* @returns Relation service instance
|
|
83
|
-
*/
|
|
84
|
-
private createService(context: SelectQueryBuilderContext) {
|
|
85
|
-
return this.env.deps.createRelationService(this.env.table, context.state, context.hydration);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
1
|
+
import { ExpressionNode } from '../core/ast/expression.js';
|
|
2
|
+
import { SelectQueryNode } from '../core/ast/query.js';
|
|
3
|
+
import { SelectQueryBuilderContext, SelectQueryBuilderEnvironment } from './select-query-builder-deps.js';
|
|
4
|
+
import { JoinKind } from '../core/sql/sql.js';
|
|
5
|
+
import { RelationIncludeOptions } from './relation-types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Manages relation operations (joins, includes, etc.) for query building
|
|
9
|
+
*/
|
|
10
|
+
export class RelationManager {
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new RelationManager instance
|
|
13
|
+
* @param env - Query builder environment
|
|
14
|
+
*/
|
|
15
|
+
constructor(private readonly env: SelectQueryBuilderEnvironment) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Matches records based on a relation with an optional predicate
|
|
19
|
+
* @param context - Current query context
|
|
20
|
+
* @param relationName - Name of the relation to match
|
|
21
|
+
* @param predicate - Optional predicate expression
|
|
22
|
+
* @returns Updated query context with relation match
|
|
23
|
+
*/
|
|
24
|
+
match(context: SelectQueryBuilderContext, relationName: string, predicate?: ExpressionNode): SelectQueryBuilderContext {
|
|
25
|
+
const result = this.createService(context).match(relationName, predicate);
|
|
26
|
+
return { state: result.state, hydration: result.hydration };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Joins a relation to the query
|
|
31
|
+
* @param context - Current query context
|
|
32
|
+
* @param relationName - Name of the relation to join
|
|
33
|
+
* @param joinKind - Type of join to use
|
|
34
|
+
* @param extraCondition - Additional join condition
|
|
35
|
+
* @returns Updated query context with relation join
|
|
36
|
+
*/
|
|
37
|
+
joinRelation(
|
|
38
|
+
context: SelectQueryBuilderContext,
|
|
39
|
+
relationName: string,
|
|
40
|
+
joinKind: JoinKind,
|
|
41
|
+
extraCondition?: ExpressionNode
|
|
42
|
+
): SelectQueryBuilderContext {
|
|
43
|
+
const result = this.createService(context).joinRelation(relationName, joinKind, extraCondition);
|
|
44
|
+
return { state: result.state, hydration: result.hydration };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Includes a relation in the query result
|
|
49
|
+
* @param context - Current query context
|
|
50
|
+
* @param relationName - Name of the relation to include
|
|
51
|
+
* @param options - Options for relation inclusion
|
|
52
|
+
* @returns Updated query context with included relation
|
|
53
|
+
*/
|
|
54
|
+
include(
|
|
55
|
+
context: SelectQueryBuilderContext,
|
|
56
|
+
relationName: string,
|
|
57
|
+
options?: RelationIncludeOptions
|
|
58
|
+
): SelectQueryBuilderContext {
|
|
59
|
+
const result = this.createService(context).include(relationName, options);
|
|
60
|
+
return { state: result.state, hydration: result.hydration };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Applies relation correlation to a query AST
|
|
65
|
+
* @param context - Current query context
|
|
66
|
+
* @param relationName - Name of the relation
|
|
67
|
+
* @param ast - Query AST to modify
|
|
68
|
+
* @returns Modified query AST with relation correlation
|
|
69
|
+
*/
|
|
70
|
+
applyRelationCorrelation(
|
|
71
|
+
context: SelectQueryBuilderContext,
|
|
72
|
+
relationName: string,
|
|
73
|
+
ast: SelectQueryNode,
|
|
74
|
+
additionalCorrelation?: ExpressionNode
|
|
75
|
+
): SelectQueryNode {
|
|
76
|
+
return this.createService(context).applyRelationCorrelation(relationName, ast, additionalCorrelation);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Creates a relation service instance
|
|
81
|
+
* @param context - Current query context
|
|
82
|
+
* @returns Relation service instance
|
|
83
|
+
*/
|
|
84
|
+
private createService(context: SelectQueryBuilderContext) {
|
|
85
|
+
return this.env.deps.createRelationService(this.env.table, context.state, context.hydration);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
import { TableDef } from '../schema/table.js';
|
|
2
|
-
import { ColumnDef } from '../schema/column-types.js';
|
|
3
|
-
import { SelectQueryState } from './select-query-state.js';
|
|
4
|
-
import { HydrationManager } from './hydration-manager.js';
|
|
5
|
-
import { ColumnNode } from '../core/ast/expression.js';
|
|
6
|
-
import { findPrimaryKey } from './hydration-planner.js';
|
|
7
|
-
import { isRelationAlias } from './relation-alias.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Result of a relation operation
|
|
11
|
-
*/
|
|
12
|
-
export interface RelationResult {
|
|
13
|
-
/**
|
|
14
|
-
* Updated query state
|
|
15
|
-
*/
|
|
16
|
-
state: SelectQueryState;
|
|
17
|
-
/**
|
|
18
|
-
* Updated hydration manager
|
|
19
|
-
*/
|
|
20
|
-
hydration: HydrationManager;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Callback function for selecting columns
|
|
25
|
-
*/
|
|
26
|
-
type SelectColumnsCallback = (
|
|
27
|
-
state: SelectQueryState,
|
|
28
|
-
hydration: HydrationManager,
|
|
29
|
-
columns: Record<string, ColumnDef>
|
|
30
|
-
) => RelationResult;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Helper class for managing relation projections in queries
|
|
34
|
-
*/
|
|
35
|
-
export class RelationProjectionHelper {
|
|
36
|
-
/**
|
|
37
|
-
* Creates a new RelationProjectionHelper instance
|
|
38
|
-
* @param table - Table definition
|
|
39
|
-
* @param selectColumns - Callback for selecting columns
|
|
40
|
-
*/
|
|
41
|
-
constructor(
|
|
42
|
-
private readonly table: TableDef,
|
|
43
|
-
private readonly selectColumns: SelectColumnsCallback
|
|
44
|
-
) {}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Ensures base projection is included in the query
|
|
48
|
-
* @param state - Current query state
|
|
49
|
-
* @param hydration - Hydration manager
|
|
50
|
-
* @returns Relation result with updated state and hydration
|
|
51
|
-
*/
|
|
52
|
-
ensureBaseProjection(state: SelectQueryState, hydration: HydrationManager): RelationResult {
|
|
53
|
-
const primaryKey = findPrimaryKey(this.table);
|
|
54
|
-
|
|
55
|
-
if (!this.hasBaseProjection(state)) {
|
|
56
|
-
return this.selectColumns(state, hydration, this.getBaseColumns());
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (primaryKey && !this.hasPrimarySelected(state, primaryKey) && this.table.columns[primaryKey]) {
|
|
60
|
-
return this.selectColumns(state, hydration, {
|
|
61
|
-
[primaryKey]: this.table.columns[primaryKey]
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return { state, hydration };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Checks if base projection exists in the query
|
|
70
|
-
* @param state - Current query state
|
|
71
|
-
* @returns True if base projection exists
|
|
72
|
-
*/
|
|
73
|
-
private hasBaseProjection(state: SelectQueryState): boolean {
|
|
74
|
-
return state.ast.columns.some(col => !isRelationAlias((col as ColumnNode).alias));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Checks if primary key is selected in the query
|
|
79
|
-
* @param state - Current query state
|
|
80
|
-
* @param primaryKey - Primary key name
|
|
81
|
-
* @returns True if primary key is selected
|
|
82
|
-
*/
|
|
83
|
-
private hasPrimarySelected(state: SelectQueryState, primaryKey: string): boolean {
|
|
84
|
-
return state.ast.columns.some(col => {
|
|
85
|
-
const alias = (col as ColumnNode).alias;
|
|
86
|
-
const name = alias || (col as ColumnNode).name;
|
|
87
|
-
return !isRelationAlias(alias) && name === primaryKey;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Gets all base columns for the table
|
|
93
|
-
* @returns Record of all table columns
|
|
94
|
-
*/
|
|
95
|
-
private getBaseColumns(): Record<string, ColumnDef> {
|
|
96
|
-
return Object.keys(this.table.columns).reduce((acc, key) => {
|
|
97
|
-
acc[key] = (this.table.columns as Record<string, ColumnDef>)[key];
|
|
98
|
-
return acc;
|
|
99
|
-
}, {} as Record<string, ColumnDef>);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
1
|
+
import { TableDef } from '../schema/table.js';
|
|
2
|
+
import { ColumnDef } from '../schema/column-types.js';
|
|
3
|
+
import { SelectQueryState } from './select-query-state.js';
|
|
4
|
+
import { HydrationManager } from './hydration-manager.js';
|
|
5
|
+
import { ColumnNode } from '../core/ast/expression.js';
|
|
6
|
+
import { findPrimaryKey } from './hydration-planner.js';
|
|
7
|
+
import { isRelationAlias } from './relation-alias.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Result of a relation operation
|
|
11
|
+
*/
|
|
12
|
+
export interface RelationResult {
|
|
13
|
+
/**
|
|
14
|
+
* Updated query state
|
|
15
|
+
*/
|
|
16
|
+
state: SelectQueryState;
|
|
17
|
+
/**
|
|
18
|
+
* Updated hydration manager
|
|
19
|
+
*/
|
|
20
|
+
hydration: HydrationManager;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Callback function for selecting columns
|
|
25
|
+
*/
|
|
26
|
+
type SelectColumnsCallback = (
|
|
27
|
+
state: SelectQueryState,
|
|
28
|
+
hydration: HydrationManager,
|
|
29
|
+
columns: Record<string, ColumnDef>
|
|
30
|
+
) => RelationResult;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Helper class for managing relation projections in queries
|
|
34
|
+
*/
|
|
35
|
+
export class RelationProjectionHelper {
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new RelationProjectionHelper instance
|
|
38
|
+
* @param table - Table definition
|
|
39
|
+
* @param selectColumns - Callback for selecting columns
|
|
40
|
+
*/
|
|
41
|
+
constructor(
|
|
42
|
+
private readonly table: TableDef,
|
|
43
|
+
private readonly selectColumns: SelectColumnsCallback
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Ensures base projection is included in the query
|
|
48
|
+
* @param state - Current query state
|
|
49
|
+
* @param hydration - Hydration manager
|
|
50
|
+
* @returns Relation result with updated state and hydration
|
|
51
|
+
*/
|
|
52
|
+
ensureBaseProjection(state: SelectQueryState, hydration: HydrationManager): RelationResult {
|
|
53
|
+
const primaryKey = findPrimaryKey(this.table);
|
|
54
|
+
|
|
55
|
+
if (!this.hasBaseProjection(state)) {
|
|
56
|
+
return this.selectColumns(state, hydration, this.getBaseColumns());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (primaryKey && !this.hasPrimarySelected(state, primaryKey) && this.table.columns[primaryKey]) {
|
|
60
|
+
return this.selectColumns(state, hydration, {
|
|
61
|
+
[primaryKey]: this.table.columns[primaryKey]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { state, hydration };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Checks if base projection exists in the query
|
|
70
|
+
* @param state - Current query state
|
|
71
|
+
* @returns True if base projection exists
|
|
72
|
+
*/
|
|
73
|
+
private hasBaseProjection(state: SelectQueryState): boolean {
|
|
74
|
+
return state.ast.columns.some(col => !isRelationAlias((col as ColumnNode).alias));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Checks if primary key is selected in the query
|
|
79
|
+
* @param state - Current query state
|
|
80
|
+
* @param primaryKey - Primary key name
|
|
81
|
+
* @returns True if primary key is selected
|
|
82
|
+
*/
|
|
83
|
+
private hasPrimarySelected(state: SelectQueryState, primaryKey: string): boolean {
|
|
84
|
+
return state.ast.columns.some(col => {
|
|
85
|
+
const alias = (col as ColumnNode).alias;
|
|
86
|
+
const name = alias || (col as ColumnNode).name;
|
|
87
|
+
return !isRelationAlias(alias) && name === primaryKey;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Gets all base columns for the table
|
|
93
|
+
* @returns Record of all table columns
|
|
94
|
+
*/
|
|
95
|
+
private getBaseColumns(): Record<string, ColumnDef> {
|
|
96
|
+
return Object.keys(this.table.columns).reduce((acc, key) => {
|
|
97
|
+
acc[key] = (this.table.columns as Record<string, ColumnDef>)[key];
|
|
98
|
+
return acc;
|
|
99
|
+
}, {} as Record<string, ColumnDef>);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
@@ -3,15 +3,15 @@ import { JOIN_KINDS } from '../core/sql/sql.js';
|
|
|
3
3
|
import { TableDef } from '../schema/table.js';
|
|
4
4
|
import { BelongsToManyRelation, RelationDef } from '../schema/relation.js';
|
|
5
5
|
import { RelationTargetTable } from '../schema/types.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Join kinds allowed when including a relation using `.include(...)`.
|
|
9
|
-
*/
|
|
10
|
-
export type RelationIncludeJoinKind = typeof JOIN_KINDS.LEFT | typeof JOIN_KINDS.INNER;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Options for including a relation in a query
|
|
14
|
-
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Join kinds allowed when including a relation using `.include(...)`.
|
|
9
|
+
*/
|
|
10
|
+
export type RelationIncludeJoinKind = typeof JOIN_KINDS.LEFT | typeof JOIN_KINDS.INNER;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for including a relation in a query
|
|
14
|
+
*/
|
|
15
15
|
export interface RelationIncludeOptions {
|
|
16
16
|
columns?: readonly string[];
|
|
17
17
|
aliasPrefix?: string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { BelongsToManyRelation } from '../schema/relation.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Builds a default set of pivot columns, excluding keys used for joins.
|
|
5
|
-
* @param rel - The BelongsToMany relation definition
|
|
6
|
-
* @param pivotPk - The primary key column name of the pivot table
|
|
7
|
-
* @returns Array of column names that can be included in pivot table selections
|
|
8
|
-
*/
|
|
9
|
-
export const buildDefaultPivotColumns = (
|
|
10
|
-
rel: BelongsToManyRelation,
|
|
11
|
-
pivotPk: string
|
|
12
|
-
): string[] => {
|
|
13
|
-
const excluded = new Set([pivotPk, rel.pivotForeignKeyToRoot, rel.pivotForeignKeyToTarget]);
|
|
14
|
-
return Object.keys(rel.pivotTable.columns).filter(col => !excluded.has(col));
|
|
15
|
-
};
|
|
1
|
+
import { BelongsToManyRelation } from '../schema/relation.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Builds a default set of pivot columns, excluding keys used for joins.
|
|
5
|
+
* @param rel - The BelongsToMany relation definition
|
|
6
|
+
* @param pivotPk - The primary key column name of the pivot table
|
|
7
|
+
* @returns Array of column names that can be included in pivot table selections
|
|
8
|
+
*/
|
|
9
|
+
export const buildDefaultPivotColumns = (
|
|
10
|
+
rel: BelongsToManyRelation,
|
|
11
|
+
pivotPk: string
|
|
12
|
+
): string[] => {
|
|
13
|
+
const excluded = new Set([pivotPk, rel.pivotForeignKeyToRoot, rel.pivotForeignKeyToTarget]);
|
|
14
|
+
return Object.keys(rel.pivotTable.columns).filter(col => !excluded.has(col));
|
|
15
|
+
};
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { SelectQueryNode } from '../../core/ast/query.js';
|
|
2
|
-
import { SelectQueryBuilderContext, SelectQueryBuilderEnvironment } from '../select-query-builder-deps.js';
|
|
3
|
-
import { QueryAstService } from '../query-ast-service.js';
|
|
4
|
-
import { SelectQueryState } from '../select-query-state.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Facet responsible for Common Table Expressions (WITH clauses)
|
|
8
|
-
*/
|
|
9
|
-
export class SelectCTEFacet {
|
|
10
|
-
/**
|
|
11
|
-
* Creates a new SelectCTEFacet instance
|
|
12
|
-
* @param env - Query builder environment
|
|
13
|
-
* @param createAstService - Function to create AST service
|
|
14
|
-
*/
|
|
15
|
-
constructor(
|
|
16
|
-
private readonly env: SelectQueryBuilderEnvironment,
|
|
17
|
-
private readonly createAstService: (state: SelectQueryState) => QueryAstService
|
|
18
|
-
) { }
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Adds a Common Table Expression to the query
|
|
22
|
-
* @param context - Current query context
|
|
23
|
-
* @param name - CTE name
|
|
24
|
-
* @param subAst - CTE query AST
|
|
25
|
-
* @param columns - Optional column names
|
|
26
|
-
* @param recursive - Whether the CTE is recursive
|
|
27
|
-
* @returns Updated query context with CTE
|
|
28
|
-
*/
|
|
29
|
-
withCTE(
|
|
30
|
-
context: SelectQueryBuilderContext,
|
|
31
|
-
name: string,
|
|
32
|
-
subAst: SelectQueryNode,
|
|
33
|
-
columns: string[] | undefined,
|
|
34
|
-
recursive: boolean
|
|
35
|
-
): SelectQueryBuilderContext {
|
|
36
|
-
const astService = this.createAstService(context.state);
|
|
37
|
-
const nextState = astService.withCte(name, subAst, columns, recursive);
|
|
38
|
-
return { state: nextState, hydration: context.hydration };
|
|
39
|
-
}
|
|
40
|
-
}
|
|
1
|
+
import { SelectQueryNode } from '../../core/ast/query.js';
|
|
2
|
+
import { SelectQueryBuilderContext, SelectQueryBuilderEnvironment } from '../select-query-builder-deps.js';
|
|
3
|
+
import { QueryAstService } from '../query-ast-service.js';
|
|
4
|
+
import { SelectQueryState } from '../select-query-state.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Facet responsible for Common Table Expressions (WITH clauses)
|
|
8
|
+
*/
|
|
9
|
+
export class SelectCTEFacet {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new SelectCTEFacet instance
|
|
12
|
+
* @param env - Query builder environment
|
|
13
|
+
* @param createAstService - Function to create AST service
|
|
14
|
+
*/
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly env: SelectQueryBuilderEnvironment,
|
|
17
|
+
private readonly createAstService: (state: SelectQueryState) => QueryAstService
|
|
18
|
+
) { }
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Adds a Common Table Expression to the query
|
|
22
|
+
* @param context - Current query context
|
|
23
|
+
* @param name - CTE name
|
|
24
|
+
* @param subAst - CTE query AST
|
|
25
|
+
* @param columns - Optional column names
|
|
26
|
+
* @param recursive - Whether the CTE is recursive
|
|
27
|
+
* @returns Updated query context with CTE
|
|
28
|
+
*/
|
|
29
|
+
withCTE(
|
|
30
|
+
context: SelectQueryBuilderContext,
|
|
31
|
+
name: string,
|
|
32
|
+
subAst: SelectQueryNode,
|
|
33
|
+
columns: string[] | undefined,
|
|
34
|
+
recursive: boolean
|
|
35
|
+
): SelectQueryBuilderContext {
|
|
36
|
+
const astService = this.createAstService(context.state);
|
|
37
|
+
const nextState = astService.withCte(name, subAst, columns, recursive);
|
|
38
|
+
return { state: nextState, hydration: context.hydration };
|
|
39
|
+
}
|
|
40
|
+
}
|