metal-orm 1.0.43 → 1.0.45
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 +700 -557
- package/dist/index.cjs +896 -476
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1146 -275
- package/dist/index.d.ts +1146 -275
- package/dist/index.js +896 -474
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/adapters.ts +8 -2
- package/src/core/ast/builders.ts +105 -81
- package/src/core/ast/expression-builders.ts +430 -390
- package/src/core/ast/expression-visitor.ts +47 -8
- package/src/core/ast/helpers.ts +23 -0
- package/src/core/ast/join-node.ts +17 -1
- package/src/core/ddl/dialects/base-schema-dialect.ts +7 -1
- package/src/core/ddl/dialects/index.ts +1 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -0
- package/src/core/ddl/introspect/catalogs/index.ts +1 -0
- package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
- package/src/core/ddl/introspect/context.ts +6 -0
- package/src/core/ddl/introspect/functions/postgres.ts +13 -0
- package/src/core/ddl/introspect/mssql.ts +11 -0
- package/src/core/ddl/introspect/mysql.ts +2 -0
- package/src/core/ddl/introspect/postgres.ts +14 -0
- package/src/core/ddl/introspect/registry.ts +14 -0
- package/src/core/ddl/introspect/run-select.ts +13 -0
- package/src/core/ddl/introspect/sqlite.ts +22 -0
- package/src/core/ddl/introspect/utils.ts +18 -0
- package/src/core/ddl/naming-strategy.ts +6 -0
- package/src/core/ddl/schema-dialect.ts +19 -6
- package/src/core/ddl/schema-diff.ts +22 -0
- package/src/core/ddl/schema-generator.ts +22 -0
- package/src/core/ddl/schema-plan-executor.ts +6 -0
- package/src/core/ddl/schema-types.ts +6 -0
- package/src/core/dialect/abstract.ts +2 -2
- package/src/core/execution/pooling/pool.ts +12 -7
- package/src/core/functions/datetime.ts +57 -33
- package/src/core/functions/numeric.ts +95 -30
- package/src/core/functions/standard-strategy.ts +35 -0
- package/src/core/functions/text.ts +83 -22
- package/src/core/functions/types.ts +23 -8
- package/src/decorators/bootstrap.ts +16 -4
- package/src/decorators/column.ts +17 -0
- package/src/decorators/decorator-metadata.ts +27 -0
- package/src/decorators/entity.ts +8 -0
- package/src/decorators/index.ts +3 -0
- package/src/decorators/relations.ts +32 -0
- package/src/orm/als.ts +34 -9
- package/src/orm/entity-context.ts +54 -0
- package/src/orm/entity-metadata.ts +122 -9
- package/src/orm/execute.ts +15 -0
- package/src/orm/lazy-batch.ts +158 -98
- package/src/orm/relations/has-many.ts +44 -0
- package/src/orm/save-graph.ts +45 -0
- package/src/query/index.ts +74 -0
- package/src/query/target.ts +46 -0
- package/src/query-builder/delete-query-state.ts +30 -0
- package/src/query-builder/delete.ts +64 -19
- package/src/query-builder/hydration-manager.ts +46 -0
- package/src/query-builder/insert-query-state.ts +30 -0
- package/src/query-builder/insert.ts +46 -2
- package/src/query-builder/query-ast-service.ts +5 -0
- package/src/query-builder/query-resolution.ts +78 -0
- package/src/query-builder/raw-column-parser.ts +5 -0
- package/src/query-builder/relation-alias.ts +7 -0
- package/src/query-builder/relation-conditions.ts +61 -48
- package/src/query-builder/relation-service.ts +68 -63
- package/src/query-builder/relation-utils.ts +3 -0
- package/src/query-builder/select/cte-facet.ts +40 -0
- package/src/query-builder/select/from-facet.ts +80 -0
- package/src/query-builder/select/join-facet.ts +62 -0
- package/src/query-builder/select/predicate-facet.ts +103 -0
- package/src/query-builder/select/projection-facet.ts +69 -0
- package/src/query-builder/select/relation-facet.ts +81 -0
- package/src/query-builder/select/setop-facet.ts +36 -0
- package/src/query-builder/select-helpers.ts +13 -0
- package/src/query-builder/select-query-builder-deps.ts +19 -1
- package/src/query-builder/select-query-state.ts +2 -1
- package/src/query-builder/select.ts +795 -1163
- package/src/query-builder/update-query-state.ts +52 -0
- package/src/query-builder/update.ts +69 -19
- package/src/schema/table-guards.ts +31 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ColumnDef } from '../../schema/column.js';
|
|
2
|
+
import { ColumnNode, FunctionNode, CaseExpressionNode, WindowFunctionNode } from '../../core/ast/expression.js';
|
|
3
|
+
import { SelectQueryBuilderContext } from '../select-query-builder-deps.js';
|
|
4
|
+
import { ColumnSelector } from '../column-selector.js';
|
|
5
|
+
import { SelectQueryNode } from '../../core/ast/query.js';
|
|
6
|
+
|
|
7
|
+
type ColumnSelectionValue = ColumnDef | FunctionNode | CaseExpressionNode | WindowFunctionNode;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Facet responsible for projection operations (SELECT, DISTINCT, etc.)
|
|
11
|
+
*/
|
|
12
|
+
export class SelectProjectionFacet {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new SelectProjectionFacet instance
|
|
15
|
+
* @param columnSelector - Column selector dependency
|
|
16
|
+
*/
|
|
17
|
+
constructor(private readonly columnSelector: ColumnSelector) { }
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Selects columns for the query
|
|
21
|
+
* @param context - Current query context
|
|
22
|
+
* @param columns - Columns to select
|
|
23
|
+
* @returns Updated query context with selected columns
|
|
24
|
+
*/
|
|
25
|
+
select(
|
|
26
|
+
context: SelectQueryBuilderContext,
|
|
27
|
+
columns: Record<string, ColumnSelectionValue>
|
|
28
|
+
): SelectQueryBuilderContext {
|
|
29
|
+
return { ...context, state: this.columnSelector.select(context, columns).state };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Selects raw column expressions
|
|
34
|
+
* @param context - Current query context
|
|
35
|
+
* @param cols - Raw column expressions
|
|
36
|
+
* @returns Updated query context with raw column selections
|
|
37
|
+
*/
|
|
38
|
+
selectRaw(context: SelectQueryBuilderContext, cols: string[]): SelectQueryBuilderContext {
|
|
39
|
+
return { ...context, state: this.columnSelector.selectRaw(context, cols).state };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Selects a subquery as a column
|
|
44
|
+
* @param context - Current query context
|
|
45
|
+
* @param alias - Alias for the subquery
|
|
46
|
+
* @param query - Subquery to select
|
|
47
|
+
* @returns Updated query context with subquery selection
|
|
48
|
+
*/
|
|
49
|
+
selectSubquery(
|
|
50
|
+
context: SelectQueryBuilderContext,
|
|
51
|
+
alias: string,
|
|
52
|
+
query: SelectQueryNode
|
|
53
|
+
): SelectQueryBuilderContext {
|
|
54
|
+
return { ...context, state: this.columnSelector.selectSubquery(context, alias, query).state };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Adds DISTINCT clause to the query
|
|
59
|
+
* @param context - Current query context
|
|
60
|
+
* @param cols - Columns to make distinct
|
|
61
|
+
* @returns Updated query context with DISTINCT clause
|
|
62
|
+
*/
|
|
63
|
+
distinct(
|
|
64
|
+
context: SelectQueryBuilderContext,
|
|
65
|
+
cols: (ColumnDef | ColumnNode)[]
|
|
66
|
+
): SelectQueryBuilderContext {
|
|
67
|
+
return { ...context, state: this.columnSelector.distinct(context, cols).state };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ExpressionNode } from '../../core/ast/expression.js';
|
|
2
|
+
import { JoinKind } from '../../core/sql/sql.js';
|
|
3
|
+
import { SelectQueryBuilderContext } from '../select-query-builder-deps.js';
|
|
4
|
+
import { RelationManager } from '../relation-manager.js';
|
|
5
|
+
import { RelationIncludeOptions } from '../relation-types.js';
|
|
6
|
+
import { SelectQueryNode } from '../../core/ast/query.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Facet responsible for relation operations (include, match, whereHas, etc.)
|
|
10
|
+
*/
|
|
11
|
+
export class SelectRelationFacet {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new SelectRelationFacet instance
|
|
14
|
+
* @param relationManager - Relation manager dependency
|
|
15
|
+
*/
|
|
16
|
+
constructor(private readonly relationManager: RelationManager) { }
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Matches records based on a relationship
|
|
20
|
+
* @param context - Current query context
|
|
21
|
+
* @param relationName - Name of the relationship
|
|
22
|
+
* @param predicate - Optional predicate
|
|
23
|
+
* @returns Updated query context with relation match
|
|
24
|
+
*/
|
|
25
|
+
match(
|
|
26
|
+
context: SelectQueryBuilderContext,
|
|
27
|
+
relationName: string,
|
|
28
|
+
predicate?: ExpressionNode
|
|
29
|
+
): SelectQueryBuilderContext {
|
|
30
|
+
return this.relationManager.match(context, relationName, predicate);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Joins a related table
|
|
35
|
+
* @param context - Current query context
|
|
36
|
+
* @param relationName - Name of the relationship
|
|
37
|
+
* @param joinKind - Type of join
|
|
38
|
+
* @param extraCondition - Optional additional condition
|
|
39
|
+
* @returns Updated query context with relation join
|
|
40
|
+
*/
|
|
41
|
+
joinRelation(
|
|
42
|
+
context: SelectQueryBuilderContext,
|
|
43
|
+
relationName: string,
|
|
44
|
+
joinKind: JoinKind,
|
|
45
|
+
extraCondition?: ExpressionNode
|
|
46
|
+
): SelectQueryBuilderContext {
|
|
47
|
+
return this.relationManager.joinRelation(context, relationName, joinKind, extraCondition);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Includes related data in the query results
|
|
52
|
+
* @param context - Current query context
|
|
53
|
+
* @param relationName - Name of the relationship to include
|
|
54
|
+
* @param options - Optional include options
|
|
55
|
+
* @returns Updated query context with relation inclusion
|
|
56
|
+
*/
|
|
57
|
+
include(
|
|
58
|
+
context: SelectQueryBuilderContext,
|
|
59
|
+
relationName: string,
|
|
60
|
+
options?: RelationIncludeOptions
|
|
61
|
+
): SelectQueryBuilderContext {
|
|
62
|
+
return this.relationManager.include(context, relationName, options);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Applies correlation for relation-based subqueries
|
|
67
|
+
* @param context - Current query context
|
|
68
|
+
* @param relationName - Name of the relationship
|
|
69
|
+
* @param subAst - Subquery AST
|
|
70
|
+
* @param extraCorrelate - Optional additional correlation
|
|
71
|
+
* @returns Modified subquery AST with correlation
|
|
72
|
+
*/
|
|
73
|
+
applyRelationCorrelation(
|
|
74
|
+
context: SelectQueryBuilderContext,
|
|
75
|
+
relationName: string,
|
|
76
|
+
subAst: SelectQueryNode,
|
|
77
|
+
extraCorrelate?: ExpressionNode
|
|
78
|
+
): SelectQueryNode {
|
|
79
|
+
return this.relationManager.applyRelationCorrelation(context, relationName, subAst, extraCorrelate);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SelectQueryNode, SetOperationKind } 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 set operations (UNION, INTERSECT, EXCEPT)
|
|
8
|
+
*/
|
|
9
|
+
export class SelectSetOpFacet {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new SelectSetOpFacet 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
|
+
* Applies a set operation to the query
|
|
22
|
+
* @param context - Current query context
|
|
23
|
+
* @param operator - Set operation kind
|
|
24
|
+
* @param subAst - Subquery AST to combine
|
|
25
|
+
* @returns Updated query context with set operation
|
|
26
|
+
*/
|
|
27
|
+
applySetOperation(
|
|
28
|
+
context: SelectQueryBuilderContext,
|
|
29
|
+
operator: SetOperationKind,
|
|
30
|
+
subAst: SelectQueryNode
|
|
31
|
+
): SelectQueryBuilderContext {
|
|
32
|
+
const astService = this.createAstService(context.state);
|
|
33
|
+
const nextState = astService.withSetOperation(operator, subAst);
|
|
34
|
+
return { state: nextState, hydration: context.hydration };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -4,6 +4,12 @@ import { getTableDefFromEntity } from '../decorators/bootstrap.js';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Build a typed selection map from a TableDef.
|
|
7
|
+
* @template TTable - The table definition type
|
|
8
|
+
* @template K - The column name keys
|
|
9
|
+
* @param table - The table definition to select columns from
|
|
10
|
+
* @param cols - Column names to include in the selection
|
|
11
|
+
* @returns A typed record mapping column names to their definitions
|
|
12
|
+
* @throws Error if a specified column is not found on the table
|
|
7
13
|
*/
|
|
8
14
|
export function sel<
|
|
9
15
|
TTable extends TableDef,
|
|
@@ -26,6 +32,13 @@ type Ctor<T> = { new(...args: unknown[]): T };
|
|
|
26
32
|
|
|
27
33
|
/**
|
|
28
34
|
* Build a typed selection map from an entity constructor.
|
|
35
|
+
* @template TEntity - The entity type
|
|
36
|
+
* @template K - The property name keys
|
|
37
|
+
* @param entity - The entity constructor to get table definition from
|
|
38
|
+
* @param props - Property names to include in the selection
|
|
39
|
+
* @returns A record mapping property names to their column definitions
|
|
40
|
+
* @throws Error if no table definition is registered for the entity
|
|
41
|
+
* @throws Error if a specified property is not found as a column
|
|
29
42
|
*/
|
|
30
43
|
export function esel<TEntity extends object, K extends keyof TEntity & string>(
|
|
31
44
|
entity: Ctor<TEntity>,
|
|
@@ -4,6 +4,8 @@ import { HydrationManager } from './hydration-manager.js';
|
|
|
4
4
|
import { HydrationPlanner } from './hydration-planner.js';
|
|
5
5
|
import { QueryAstService } from './query-ast-service.js';
|
|
6
6
|
import { RelationService } from './relation-service.js';
|
|
7
|
+
import { ColumnSelector } from './column-selector.js';
|
|
8
|
+
import { RelationManager } from './relation-manager.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Context for query building operations
|
|
@@ -60,6 +62,18 @@ export interface SelectQueryBuilderDependencies {
|
|
|
60
62
|
state: SelectQueryState,
|
|
61
63
|
hydration: HydrationManager
|
|
62
64
|
) => RelationService;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new column selector
|
|
67
|
+
* @param env - Query builder environment
|
|
68
|
+
* @returns New column selector
|
|
69
|
+
*/
|
|
70
|
+
createColumnSelector: (env: SelectQueryBuilderEnvironment) => ColumnSelector;
|
|
71
|
+
/**
|
|
72
|
+
* Creates a new relation manager
|
|
73
|
+
* @param env - Query builder environment
|
|
74
|
+
* @returns New relation manager
|
|
75
|
+
*/
|
|
76
|
+
createRelationManager: (env: SelectQueryBuilderEnvironment) => RelationManager;
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
/**
|
|
@@ -99,13 +113,17 @@ export const resolveSelectQueryBuilderDependencies = (
|
|
|
99
113
|
const createRelationService =
|
|
100
114
|
overrides.createRelationService ??
|
|
101
115
|
((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
|
|
116
|
+
const createColumnSelector = overrides.createColumnSelector ?? (env => new ColumnSelector(env));
|
|
117
|
+
const createRelationManager = overrides.createRelationManager ?? (env => new RelationManager(env));
|
|
102
118
|
|
|
103
119
|
return {
|
|
104
120
|
createState: overrides.createState ?? (table => new SelectQueryState(table)),
|
|
105
121
|
createHydration,
|
|
106
122
|
createHydrationPlanner,
|
|
107
123
|
createQueryAstService,
|
|
108
|
-
createRelationService
|
|
124
|
+
createRelationService,
|
|
125
|
+
createColumnSelector,
|
|
126
|
+
createRelationManager
|
|
109
127
|
};
|
|
110
128
|
};
|
|
111
129
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
TableSourceNode,
|
|
8
8
|
OrderingTerm
|
|
9
9
|
} from '../core/ast/query.js';
|
|
10
|
+
import { createTableNode } from '../core/ast/builders.js';
|
|
10
11
|
import {
|
|
11
12
|
ColumnNode,
|
|
12
13
|
ExpressionNode,
|
|
@@ -49,7 +50,7 @@ export class SelectQueryState {
|
|
|
49
50
|
this.table = table;
|
|
50
51
|
this.ast = ast ?? {
|
|
51
52
|
type: 'SelectQuery',
|
|
52
|
-
from:
|
|
53
|
+
from: createTableNode(table),
|
|
53
54
|
columns: [],
|
|
54
55
|
joins: []
|
|
55
56
|
};
|