metal-orm 1.0.11 → 1.0.13
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 +21 -18
- package/dist/decorators/index.cjs +317 -34
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +1 -1
- package/dist/decorators/index.d.ts +1 -1
- package/dist/decorators/index.js +317 -34
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +1965 -267
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +273 -23
- package/dist/index.d.ts +273 -23
- package/dist/index.js +1947 -267
- package/dist/index.js.map +1 -1
- package/dist/{select-654m4qy8.d.cts → select-CCp1oz9p.d.cts} +254 -4
- package/dist/{select-654m4qy8.d.ts → select-CCp1oz9p.d.ts} +254 -4
- package/package.json +3 -2
- package/src/core/ast/query.ts +40 -22
- package/src/core/ddl/dialects/base-schema-dialect.ts +48 -0
- package/src/core/ddl/dialects/index.ts +5 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +97 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +109 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +99 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +103 -0
- package/src/core/ddl/introspect/mssql.ts +149 -0
- package/src/core/ddl/introspect/mysql.ts +99 -0
- package/src/core/ddl/introspect/postgres.ts +154 -0
- package/src/core/ddl/introspect/sqlite.ts +66 -0
- package/src/core/ddl/introspect/types.ts +19 -0
- package/src/core/ddl/introspect/utils.ts +27 -0
- package/src/core/ddl/schema-diff.ts +179 -0
- package/src/core/ddl/schema-generator.ts +229 -0
- package/src/core/ddl/schema-introspect.ts +32 -0
- package/src/core/ddl/schema-types.ts +39 -0
- package/src/core/dialect/abstract.ts +122 -37
- package/src/core/dialect/base/sql-dialect.ts +204 -0
- package/src/core/dialect/mssql/index.ts +125 -80
- package/src/core/dialect/mysql/index.ts +18 -112
- package/src/core/dialect/postgres/index.ts +29 -126
- package/src/core/dialect/sqlite/index.ts +28 -129
- package/src/index.ts +4 -0
- package/src/orm/execute.ts +25 -16
- package/src/orm/orm-context.ts +60 -55
- package/src/orm/query-logger.ts +38 -0
- package/src/orm/relations/belongs-to.ts +42 -26
- package/src/orm/relations/has-many.ts +41 -25
- package/src/orm/relations/many-to-many.ts +43 -27
- package/src/orm/unit-of-work.ts +60 -23
- package/src/query-builder/hydration-manager.ts +229 -25
- package/src/query-builder/query-ast-service.ts +27 -12
- package/src/query-builder/select-query-state.ts +24 -12
- package/src/query-builder/select.ts +58 -14
- package/src/schema/column.ts +206 -27
- package/src/schema/table.ts +89 -32
- package/src/schema/types.ts +8 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as TableHooks, Q as ColumnType, C as ColumnDef, T as TableDef, a0 as CascadeMode, z as SelectQueryBuilder } from '../select-CCp1oz9p.cjs';
|
|
2
2
|
|
|
3
3
|
interface EntityOptions {
|
|
4
4
|
tableName?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as TableHooks, Q as ColumnType, C as ColumnDef, T as TableDef, a0 as CascadeMode, z as SelectQueryBuilder } from '../select-CCp1oz9p.js';
|
|
2
2
|
|
|
3
3
|
interface EntityOptions {
|
|
4
4
|
tableName?: string;
|
package/dist/decorators/index.js
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
// src/schema/table.ts
|
|
2
|
-
var defineTable = (name, columns, relations = {}, hooks) => {
|
|
2
|
+
var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
3
3
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
4
4
|
acc[key] = { ...def, name: key, table: name };
|
|
5
5
|
return acc;
|
|
6
6
|
}, {});
|
|
7
|
-
return {
|
|
7
|
+
return {
|
|
8
|
+
name,
|
|
9
|
+
schema: options.schema,
|
|
10
|
+
columns: colsWithNames,
|
|
11
|
+
relations,
|
|
12
|
+
hooks,
|
|
13
|
+
primaryKey: options.primaryKey,
|
|
14
|
+
indexes: options.indexes,
|
|
15
|
+
checks: options.checks,
|
|
16
|
+
comment: options.comment,
|
|
17
|
+
engine: options.engine,
|
|
18
|
+
charset: options.charset,
|
|
19
|
+
collation: options.collation
|
|
20
|
+
};
|
|
8
21
|
};
|
|
9
22
|
|
|
10
23
|
// src/orm/entity-metadata.ts
|
|
@@ -454,6 +467,44 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
454
467
|
ctes: [...this.ast.ctes ?? [], cte]
|
|
455
468
|
});
|
|
456
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Adds a set operation (UNION/INTERSECT/EXCEPT) to the query
|
|
472
|
+
* @param op - Set operation node to add
|
|
473
|
+
* @returns New SelectQueryState with set operation
|
|
474
|
+
*/
|
|
475
|
+
withSetOperation(op) {
|
|
476
|
+
return this.clone({
|
|
477
|
+
...this.ast,
|
|
478
|
+
setOps: [...this.ast.setOps ?? [], op]
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/core/ast/join-node.ts
|
|
484
|
+
var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
485
|
+
type: "Join",
|
|
486
|
+
kind,
|
|
487
|
+
table: { type: "Table", name: tableName },
|
|
488
|
+
condition,
|
|
489
|
+
relationName
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// src/core/sql/sql.ts
|
|
493
|
+
var JOIN_KINDS = {
|
|
494
|
+
/** INNER JOIN type */
|
|
495
|
+
INNER: "INNER",
|
|
496
|
+
/** LEFT JOIN type */
|
|
497
|
+
LEFT: "LEFT",
|
|
498
|
+
/** RIGHT JOIN type */
|
|
499
|
+
RIGHT: "RIGHT",
|
|
500
|
+
/** CROSS JOIN type */
|
|
501
|
+
CROSS: "CROSS"
|
|
502
|
+
};
|
|
503
|
+
var ORDER_DIRECTIONS = {
|
|
504
|
+
/** Ascending order */
|
|
505
|
+
ASC: "ASC",
|
|
506
|
+
/** Descending order */
|
|
507
|
+
DESC: "DESC"
|
|
457
508
|
};
|
|
458
509
|
|
|
459
510
|
// src/query-builder/hydration-manager.ts
|
|
@@ -505,8 +556,26 @@ var HydrationManager = class _HydrationManager {
|
|
|
505
556
|
* @returns AST with hydration metadata
|
|
506
557
|
*/
|
|
507
558
|
applyToAst(ast) {
|
|
559
|
+
if (ast.setOps && ast.setOps.length > 0) {
|
|
560
|
+
return ast;
|
|
561
|
+
}
|
|
508
562
|
const plan = this.planner.getPlan();
|
|
509
563
|
if (!plan) return ast;
|
|
564
|
+
const needsPaginationGuard = this.requiresParentPagination(ast, plan);
|
|
565
|
+
const rewritten = needsPaginationGuard ? this.wrapForParentPagination(ast, plan) : ast;
|
|
566
|
+
return this.attachHydrationMeta(rewritten, plan);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Gets the current hydration plan
|
|
570
|
+
* @returns Hydration plan or undefined if none exists
|
|
571
|
+
*/
|
|
572
|
+
getPlan() {
|
|
573
|
+
return this.planner.getPlan();
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Attaches hydration metadata to a query AST node.
|
|
577
|
+
*/
|
|
578
|
+
attachHydrationMeta(ast, plan) {
|
|
510
579
|
return {
|
|
511
580
|
...ast,
|
|
512
581
|
meta: {
|
|
@@ -516,11 +585,154 @@ var HydrationManager = class _HydrationManager {
|
|
|
516
585
|
};
|
|
517
586
|
}
|
|
518
587
|
/**
|
|
519
|
-
*
|
|
520
|
-
*
|
|
588
|
+
* Determines whether the query needs pagination rewriting to keep LIMIT/OFFSET
|
|
589
|
+
* applied to parent rows when eager-loading multiplicative relations.
|
|
521
590
|
*/
|
|
522
|
-
|
|
523
|
-
|
|
591
|
+
requiresParentPagination(ast, plan) {
|
|
592
|
+
const hasPagination = ast.limit !== void 0 || ast.offset !== void 0;
|
|
593
|
+
return hasPagination && this.hasMultiplyingRelations(plan);
|
|
594
|
+
}
|
|
595
|
+
hasMultiplyingRelations(plan) {
|
|
596
|
+
return plan.relations.some(
|
|
597
|
+
(rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Rewrites the query using CTEs so LIMIT/OFFSET target distinct parent rows
|
|
602
|
+
* instead of the joined result set.
|
|
603
|
+
*
|
|
604
|
+
* The strategy:
|
|
605
|
+
* - Hoist the original query (minus limit/offset) into a base CTE.
|
|
606
|
+
* - Select distinct parent ids from that base CTE with the original ordering and pagination.
|
|
607
|
+
* - Join the base CTE against the paged ids to retrieve the joined rows for just that page.
|
|
608
|
+
*/
|
|
609
|
+
wrapForParentPagination(ast, plan) {
|
|
610
|
+
const projectionNames = this.getProjectionNames(ast.columns);
|
|
611
|
+
if (!projectionNames) {
|
|
612
|
+
return ast;
|
|
613
|
+
}
|
|
614
|
+
const projectionAliases = this.buildProjectionAliasMap(ast.columns);
|
|
615
|
+
const projectionSet = new Set(projectionNames);
|
|
616
|
+
const rootPkAlias = projectionAliases.get(`${plan.rootTable}.${plan.rootPrimaryKey}`) ?? plan.rootPrimaryKey;
|
|
617
|
+
const baseCteName = this.nextCteName(ast.ctes, "__metal_pagination_base");
|
|
618
|
+
const baseQuery = {
|
|
619
|
+
...ast,
|
|
620
|
+
ctes: void 0,
|
|
621
|
+
limit: void 0,
|
|
622
|
+
offset: void 0,
|
|
623
|
+
orderBy: void 0,
|
|
624
|
+
meta: void 0
|
|
625
|
+
};
|
|
626
|
+
const baseCte = {
|
|
627
|
+
type: "CommonTableExpression",
|
|
628
|
+
name: baseCteName,
|
|
629
|
+
query: baseQuery,
|
|
630
|
+
recursive: false
|
|
631
|
+
};
|
|
632
|
+
const orderBy = this.mapOrderBy(ast.orderBy, plan, projectionAliases, baseCteName, projectionSet);
|
|
633
|
+
if (orderBy === null) {
|
|
634
|
+
return ast;
|
|
635
|
+
}
|
|
636
|
+
const pageCteName = this.nextCteName([...ast.ctes ?? [], baseCte], "__metal_pagination_page");
|
|
637
|
+
const pagingColumns = this.buildPagingColumns(rootPkAlias, orderBy, baseCteName);
|
|
638
|
+
const pageCte = {
|
|
639
|
+
type: "CommonTableExpression",
|
|
640
|
+
name: pageCteName,
|
|
641
|
+
query: {
|
|
642
|
+
type: "SelectQuery",
|
|
643
|
+
from: { type: "Table", name: baseCteName },
|
|
644
|
+
columns: pagingColumns,
|
|
645
|
+
joins: [],
|
|
646
|
+
distinct: [{ type: "Column", table: baseCteName, name: rootPkAlias }],
|
|
647
|
+
orderBy,
|
|
648
|
+
limit: ast.limit,
|
|
649
|
+
offset: ast.offset
|
|
650
|
+
},
|
|
651
|
+
recursive: false
|
|
652
|
+
};
|
|
653
|
+
const joinCondition = eq(
|
|
654
|
+
{ type: "Column", table: baseCteName, name: rootPkAlias },
|
|
655
|
+
{ type: "Column", table: pageCteName, name: rootPkAlias }
|
|
656
|
+
);
|
|
657
|
+
const outerColumns = projectionNames.map((name) => ({
|
|
658
|
+
type: "Column",
|
|
659
|
+
table: baseCteName,
|
|
660
|
+
name,
|
|
661
|
+
alias: name
|
|
662
|
+
}));
|
|
663
|
+
return {
|
|
664
|
+
type: "SelectQuery",
|
|
665
|
+
from: { type: "Table", name: baseCteName },
|
|
666
|
+
columns: outerColumns,
|
|
667
|
+
joins: [createJoinNode(JOIN_KINDS.INNER, pageCteName, joinCondition)],
|
|
668
|
+
orderBy,
|
|
669
|
+
ctes: [...ast.ctes ?? [], baseCte, pageCte]
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
nextCteName(existing, baseName) {
|
|
673
|
+
const names = new Set((existing ?? []).map((cte) => cte.name));
|
|
674
|
+
let candidate = baseName;
|
|
675
|
+
let suffix = 1;
|
|
676
|
+
while (names.has(candidate)) {
|
|
677
|
+
suffix += 1;
|
|
678
|
+
candidate = `${baseName}_${suffix}`;
|
|
679
|
+
}
|
|
680
|
+
return candidate;
|
|
681
|
+
}
|
|
682
|
+
getProjectionNames(columns) {
|
|
683
|
+
const names = [];
|
|
684
|
+
for (const col of columns) {
|
|
685
|
+
const alias = col.alias ?? col.name;
|
|
686
|
+
if (!alias) return void 0;
|
|
687
|
+
names.push(alias);
|
|
688
|
+
}
|
|
689
|
+
return names;
|
|
690
|
+
}
|
|
691
|
+
buildProjectionAliasMap(columns) {
|
|
692
|
+
const map = /* @__PURE__ */ new Map();
|
|
693
|
+
for (const col of columns) {
|
|
694
|
+
if (col.type !== "Column") continue;
|
|
695
|
+
const node = col;
|
|
696
|
+
const key = `${node.table}.${node.name}`;
|
|
697
|
+
map.set(key, node.alias ?? node.name);
|
|
698
|
+
}
|
|
699
|
+
return map;
|
|
700
|
+
}
|
|
701
|
+
mapOrderBy(orderBy, plan, projectionAliases, baseAlias, availableColumns) {
|
|
702
|
+
if (!orderBy || orderBy.length === 0) {
|
|
703
|
+
return void 0;
|
|
704
|
+
}
|
|
705
|
+
const mapped = [];
|
|
706
|
+
for (const ob of orderBy) {
|
|
707
|
+
if (ob.column.table !== plan.rootTable) {
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
const alias = projectionAliases.get(`${ob.column.table}.${ob.column.name}`) ?? ob.column.name;
|
|
711
|
+
if (!availableColumns.has(alias)) {
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
mapped.push({
|
|
715
|
+
type: "OrderBy",
|
|
716
|
+
column: { type: "Column", table: baseAlias, name: alias },
|
|
717
|
+
direction: ob.direction
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
return mapped;
|
|
721
|
+
}
|
|
722
|
+
buildPagingColumns(primaryKey, orderBy, tableAlias) {
|
|
723
|
+
const columns = [{ type: "Column", table: tableAlias, name: primaryKey, alias: primaryKey }];
|
|
724
|
+
if (!orderBy) return columns;
|
|
725
|
+
for (const ob of orderBy) {
|
|
726
|
+
if (!columns.some((col) => col.name === ob.column.name)) {
|
|
727
|
+
columns.push({
|
|
728
|
+
type: "Column",
|
|
729
|
+
table: tableAlias,
|
|
730
|
+
name: ob.column.name,
|
|
731
|
+
alias: ob.column.name
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return columns;
|
|
524
736
|
}
|
|
525
737
|
};
|
|
526
738
|
|
|
@@ -774,6 +986,20 @@ var QueryAstService = class {
|
|
|
774
986
|
};
|
|
775
987
|
return this.state.withCte(cte);
|
|
776
988
|
}
|
|
989
|
+
/**
|
|
990
|
+
* Adds a set operation (UNION/UNION ALL/INTERSECT/EXCEPT) to the query
|
|
991
|
+
* @param operator - Set operator
|
|
992
|
+
* @param query - Right-hand side query
|
|
993
|
+
* @returns Updated query state with set operation
|
|
994
|
+
*/
|
|
995
|
+
withSetOperation(operator, query) {
|
|
996
|
+
const op = {
|
|
997
|
+
type: "SetOperation",
|
|
998
|
+
operator,
|
|
999
|
+
query
|
|
1000
|
+
};
|
|
1001
|
+
return this.state.withSetOperation(op);
|
|
1002
|
+
}
|
|
777
1003
|
/**
|
|
778
1004
|
* Selects a subquery as a column
|
|
779
1005
|
* @param alias - Alias for the subquery
|
|
@@ -926,15 +1152,6 @@ var RelationProjectionHelper = class {
|
|
|
926
1152
|
}
|
|
927
1153
|
};
|
|
928
1154
|
|
|
929
|
-
// src/core/ast/join-node.ts
|
|
930
|
-
var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
931
|
-
type: "Join",
|
|
932
|
-
kind,
|
|
933
|
-
table: { type: "Table", name: tableName },
|
|
934
|
-
condition,
|
|
935
|
-
relationName
|
|
936
|
-
});
|
|
937
|
-
|
|
938
1155
|
// src/query-builder/relation-conditions.ts
|
|
939
1156
|
var assertNever = (value) => {
|
|
940
1157
|
throw new Error(`Unhandled relation type: ${JSON.stringify(value)}`);
|
|
@@ -990,24 +1207,6 @@ var buildRelationCorrelation = (root, relation) => {
|
|
|
990
1207
|
return baseRelationCondition(root, relation);
|
|
991
1208
|
};
|
|
992
1209
|
|
|
993
|
-
// src/core/sql/sql.ts
|
|
994
|
-
var JOIN_KINDS = {
|
|
995
|
-
/** INNER JOIN type */
|
|
996
|
-
INNER: "INNER",
|
|
997
|
-
/** LEFT JOIN type */
|
|
998
|
-
LEFT: "LEFT",
|
|
999
|
-
/** RIGHT JOIN type */
|
|
1000
|
-
RIGHT: "RIGHT",
|
|
1001
|
-
/** CROSS JOIN type */
|
|
1002
|
-
CROSS: "CROSS"
|
|
1003
|
-
};
|
|
1004
|
-
var ORDER_DIRECTIONS = {
|
|
1005
|
-
/** Ascending order */
|
|
1006
|
-
ASC: "ASC",
|
|
1007
|
-
/** Descending order */
|
|
1008
|
-
DESC: "DESC"
|
|
1009
|
-
};
|
|
1010
|
-
|
|
1011
1210
|
// src/query-builder/relation-service.ts
|
|
1012
1211
|
var RelationService = class {
|
|
1013
1212
|
/**
|
|
@@ -1453,6 +1652,16 @@ var hasEntityMeta = (entity) => {
|
|
|
1453
1652
|
|
|
1454
1653
|
// src/orm/relations/has-many.ts
|
|
1455
1654
|
var toKey2 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
1655
|
+
var hideInternal = (obj, keys) => {
|
|
1656
|
+
for (const key of keys) {
|
|
1657
|
+
Object.defineProperty(obj, key, {
|
|
1658
|
+
value: obj[key],
|
|
1659
|
+
writable: false,
|
|
1660
|
+
configurable: false,
|
|
1661
|
+
enumerable: false
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
};
|
|
1456
1665
|
var DefaultHasManyCollection = class {
|
|
1457
1666
|
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
1458
1667
|
this.ctx = ctx;
|
|
@@ -1468,6 +1677,7 @@ var DefaultHasManyCollection = class {
|
|
|
1468
1677
|
this.items = [];
|
|
1469
1678
|
this.added = /* @__PURE__ */ new Set();
|
|
1470
1679
|
this.removed = /* @__PURE__ */ new Set();
|
|
1680
|
+
hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
1471
1681
|
this.hydrateFromCache();
|
|
1472
1682
|
}
|
|
1473
1683
|
async load() {
|
|
@@ -1543,10 +1753,23 @@ var DefaultHasManyCollection = class {
|
|
|
1543
1753
|
this.items = rows.map((row) => this.createEntity(row));
|
|
1544
1754
|
this.loaded = true;
|
|
1545
1755
|
}
|
|
1756
|
+
toJSON() {
|
|
1757
|
+
return this.items;
|
|
1758
|
+
}
|
|
1546
1759
|
};
|
|
1547
1760
|
|
|
1548
1761
|
// src/orm/relations/belongs-to.ts
|
|
1549
1762
|
var toKey3 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
1763
|
+
var hideInternal2 = (obj, keys) => {
|
|
1764
|
+
for (const key of keys) {
|
|
1765
|
+
Object.defineProperty(obj, key, {
|
|
1766
|
+
value: obj[key],
|
|
1767
|
+
writable: false,
|
|
1768
|
+
configurable: false,
|
|
1769
|
+
enumerable: false
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1550
1773
|
var DefaultBelongsToReference = class {
|
|
1551
1774
|
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, targetKey) {
|
|
1552
1775
|
this.ctx = ctx;
|
|
@@ -1560,6 +1783,7 @@ var DefaultBelongsToReference = class {
|
|
|
1560
1783
|
this.targetKey = targetKey;
|
|
1561
1784
|
this.loaded = false;
|
|
1562
1785
|
this.current = null;
|
|
1786
|
+
hideInternal2(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "targetKey"]);
|
|
1563
1787
|
this.populateFromHydrationCache();
|
|
1564
1788
|
}
|
|
1565
1789
|
async load() {
|
|
@@ -1620,10 +1844,23 @@ var DefaultBelongsToReference = class {
|
|
|
1620
1844
|
this.current = this.createEntity(row);
|
|
1621
1845
|
this.loaded = true;
|
|
1622
1846
|
}
|
|
1847
|
+
toJSON() {
|
|
1848
|
+
return this.current;
|
|
1849
|
+
}
|
|
1623
1850
|
};
|
|
1624
1851
|
|
|
1625
1852
|
// src/orm/relations/many-to-many.ts
|
|
1626
1853
|
var toKey4 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
1854
|
+
var hideInternal3 = (obj, keys) => {
|
|
1855
|
+
for (const key of keys) {
|
|
1856
|
+
Object.defineProperty(obj, key, {
|
|
1857
|
+
value: obj[key],
|
|
1858
|
+
writable: false,
|
|
1859
|
+
configurable: false,
|
|
1860
|
+
enumerable: false
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1627
1864
|
var DefaultManyToManyCollection = class {
|
|
1628
1865
|
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
1629
1866
|
this.ctx = ctx;
|
|
@@ -1637,6 +1874,7 @@ var DefaultManyToManyCollection = class {
|
|
|
1637
1874
|
this.localKey = localKey;
|
|
1638
1875
|
this.loaded = false;
|
|
1639
1876
|
this.items = [];
|
|
1877
|
+
hideInternal3(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
1640
1878
|
this.hydrateFromCache();
|
|
1641
1879
|
}
|
|
1642
1880
|
async load() {
|
|
@@ -1742,6 +1980,9 @@ var DefaultManyToManyCollection = class {
|
|
|
1742
1980
|
});
|
|
1743
1981
|
this.loaded = true;
|
|
1744
1982
|
}
|
|
1983
|
+
toJSON() {
|
|
1984
|
+
return this.items;
|
|
1985
|
+
}
|
|
1745
1986
|
};
|
|
1746
1987
|
|
|
1747
1988
|
// src/orm/lazy-batch.ts
|
|
@@ -2102,9 +2343,15 @@ var flattenResults = (results) => {
|
|
|
2102
2343
|
return rows;
|
|
2103
2344
|
};
|
|
2104
2345
|
async function executeHydrated(ctx, qb) {
|
|
2105
|
-
const
|
|
2346
|
+
const ast = qb.getAST();
|
|
2347
|
+
const compiled = ctx.dialect.compileSelect(ast);
|
|
2106
2348
|
const executed = await ctx.executor.executeSql(compiled.sql, compiled.params);
|
|
2107
2349
|
const rows = flattenResults(executed);
|
|
2350
|
+
if (ast.setOps && ast.setOps.length > 0) {
|
|
2351
|
+
return rows.map(
|
|
2352
|
+
(row) => createEntityProxy(ctx, qb.getTable(), row, qb.getLazyRelations())
|
|
2353
|
+
);
|
|
2354
|
+
}
|
|
2108
2355
|
const hydrated = hydrateRows(rows, qb.getHydrationPlan());
|
|
2109
2356
|
return hydrated.map(
|
|
2110
2357
|
(row) => createEntityFromRow(ctx, qb.getTable(), row, qb.getLazyRelations())
|
|
@@ -2151,6 +2398,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
2151
2398
|
const joinNode = createJoinNode(kind, table.name, condition);
|
|
2152
2399
|
return this.applyAst(context, (service) => service.withJoin(joinNode));
|
|
2153
2400
|
}
|
|
2401
|
+
applySetOperation(operator, query) {
|
|
2402
|
+
const subAst = this.resolveQueryNode(query);
|
|
2403
|
+
return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
|
|
2404
|
+
}
|
|
2154
2405
|
/**
|
|
2155
2406
|
* Selects specific columns for the query
|
|
2156
2407
|
* @param columns - Record of column definitions, function nodes, case expressions, or window functions
|
|
@@ -2339,6 +2590,38 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
2339
2590
|
const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
|
|
2340
2591
|
return this.clone(nextContext);
|
|
2341
2592
|
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Combines this query with another using UNION
|
|
2595
|
+
* @param query - Query to union with
|
|
2596
|
+
* @returns New query builder instance with the set operation
|
|
2597
|
+
*/
|
|
2598
|
+
union(query) {
|
|
2599
|
+
return this.clone(this.applySetOperation("UNION", query));
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* Combines this query with another using UNION ALL
|
|
2603
|
+
* @param query - Query to union with
|
|
2604
|
+
* @returns New query builder instance with the set operation
|
|
2605
|
+
*/
|
|
2606
|
+
unionAll(query) {
|
|
2607
|
+
return this.clone(this.applySetOperation("UNION ALL", query));
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Combines this query with another using INTERSECT
|
|
2611
|
+
* @param query - Query to intersect with
|
|
2612
|
+
* @returns New query builder instance with the set operation
|
|
2613
|
+
*/
|
|
2614
|
+
intersect(query) {
|
|
2615
|
+
return this.clone(this.applySetOperation("INTERSECT", query));
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Combines this query with another using EXCEPT
|
|
2619
|
+
* @param query - Query to subtract
|
|
2620
|
+
* @returns New query builder instance with the set operation
|
|
2621
|
+
*/
|
|
2622
|
+
except(query) {
|
|
2623
|
+
return this.clone(this.applySetOperation("EXCEPT", query));
|
|
2624
|
+
}
|
|
2342
2625
|
/**
|
|
2343
2626
|
* Adds a WHERE EXISTS condition to the query
|
|
2344
2627
|
* @param subquery - Subquery to check for existence
|