linkgress-orm 0.4.58 → 0.4.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entity/entity-base.d.ts +16 -0
- package/dist/entity/entity-base.d.ts.map +1 -1
- package/dist/entity/entity-base.js +1 -0
- package/dist/entity/entity-base.js.map +1 -1
- package/dist/entity/entity-builder.d.ts +23 -0
- package/dist/entity/entity-builder.d.ts.map +1 -1
- package/dist/entity/entity-builder.js +34 -0
- package/dist/entity/entity-builder.js.map +1 -1
- package/dist/entity/model-config.d.ts.map +1 -1
- package/dist/entity/model-config.js +4 -0
- package/dist/entity/model-config.js.map +1 -1
- package/dist/migration/check-constraint-sql.d.ts +45 -0
- package/dist/migration/check-constraint-sql.d.ts.map +1 -0
- package/dist/migration/check-constraint-sql.js +41 -0
- package/dist/migration/check-constraint-sql.js.map +1 -0
- package/dist/migration/db-schema-manager.d.ts +27 -0
- package/dist/migration/db-schema-manager.d.ts.map +1 -1
- package/dist/migration/db-schema-manager.js +213 -117
- package/dist/migration/db-schema-manager.js.map +1 -1
- package/dist/migration/migration-scaffold.d.ts.map +1 -1
- package/dist/migration/migration-scaffold.js +19 -0
- package/dist/migration/migration-scaffold.js.map +1 -1
- package/dist/query/query-builder.d.ts.map +1 -1
- package/dist/query/query-builder.js +62 -4
- package/dist/query/query-builder.js.map +1 -1
- package/dist/schema/table-builder.d.ts +23 -0
- package/dist/schema/table-builder.d.ts.map +1 -1
- package/dist/schema/table-builder.js +10 -0
- package/dist/schema/table-builder.js.map +1 -1
- package/package.json +80 -79
|
@@ -6006,12 +6006,22 @@ class CollectionQueryBuilder {
|
|
|
6006
6006
|
const sourceTable = this.sourceTable;
|
|
6007
6007
|
// Build JOINs needed inside the EXISTS subquery
|
|
6008
6008
|
const allJoins = [];
|
|
6009
|
+
// Inside a lateral, the collection's λ-root table is visible only under the
|
|
6010
|
+
// lateral's generated alias (e.g. `FROM "cart_discount_code" "lateral_3_cartDiscountCodes"`).
|
|
6011
|
+
// The first bridge hop / root correlation must anchor on that alias, not the raw
|
|
6012
|
+
// table name — mirrors lateral-collection-strategy's own correlation handling.
|
|
6013
|
+
// Only the λ-root is translated: bridge-internal aliases are emitted by this very
|
|
6014
|
+
// subquery and must never be remapped, even if they collide with a lateral's
|
|
6015
|
+
// target table name.
|
|
6016
|
+
const aliasMap = context.lateralTableAliasMap;
|
|
6017
|
+
const rootAnchor = (alias) => aliasMap?.get(alias) || alias;
|
|
6009
6018
|
// Navigation path joins (for reference navigation like pc.order → orders)
|
|
6010
|
-
for (const nav of this.navigationPath) {
|
|
6019
|
+
for (const [index, nav] of this.navigationPath.entries()) {
|
|
6011
6020
|
const joinType = nav.isMandatory ? 'JOIN' : 'LEFT JOIN';
|
|
6012
6021
|
const fk = nav.foreignKeys[0];
|
|
6013
6022
|
const pk = (nav.matches && nav.matches.length > 0) ? nav.matches[0] : 'id';
|
|
6014
|
-
|
|
6023
|
+
const src = index === 0 ? rootAnchor(nav.sourceAlias) : nav.sourceAlias;
|
|
6024
|
+
allJoins.push(`${joinType} "${nav.targetTable}" "${nav.alias}" ON "${src}"."${fk}" = "${nav.alias}"."${pk}"`);
|
|
6015
6025
|
}
|
|
6016
6026
|
// SelectMany joins (for selectMany navigation through intermediate tables)
|
|
6017
6027
|
for (const nav of this.selectManyJoins) {
|
|
@@ -6020,18 +6030,62 @@ class CollectionQueryBuilder {
|
|
|
6020
6030
|
const pk = (nav.matches && nav.matches.length > 0) ? nav.matches[0] : 'id';
|
|
6021
6031
|
allJoins.push(`${joinType} "${nav.targetTable}" "${nav.alias}" ON "${nav.sourceAlias}"."${fk}" = "${nav.alias}"."${pk}"`);
|
|
6022
6032
|
}
|
|
6033
|
+
// Joins required by REFERENCE navigations inside the collection's own
|
|
6034
|
+
// where-condition, e.g. `exists(links.where(l => eq(l.campaign.isPublic, true)))`.
|
|
6035
|
+
// Navigation joins were historically derived from selectors only; an EXISTS
|
|
6036
|
+
// aggregation has no selector, so a where-navigated alias rendered unjoined and
|
|
6037
|
+
// the statement failed with `missing FROM-clause entry for table "<alias>"`.
|
|
6038
|
+
// Reuses the selector path's machinery: seed aliases + chains from the
|
|
6039
|
+
// condition's FieldRefs, then resolve multi-hop paths against the target schema.
|
|
6040
|
+
if (this.whereCond) {
|
|
6041
|
+
const joinedAliases = new Set([
|
|
6042
|
+
...this.navigationPath.map(nav => nav.alias),
|
|
6043
|
+
...this.selectManyJoins.map(nav => nav.alias),
|
|
6044
|
+
]);
|
|
6045
|
+
const targetSchema = this.schemaRegistry?.get(targetTable);
|
|
6046
|
+
if (targetSchema) {
|
|
6047
|
+
const whereJoins = [];
|
|
6048
|
+
const whereAliases = new Set();
|
|
6049
|
+
for (const ref of this.whereCond.getFieldRefs()) {
|
|
6050
|
+
const refAlias = ref?.__tableAlias;
|
|
6051
|
+
// Direct columns of the target arrive under the `__collection_<table>__`
|
|
6052
|
+
// marker (rewritten below) or the bare table name — neither needs a join.
|
|
6053
|
+
if (!refAlias || refAlias === targetTable || refAlias.startsWith('__collection_') || joinedAliases.has(refAlias)) {
|
|
6054
|
+
continue;
|
|
6055
|
+
}
|
|
6056
|
+
this.addNavigationJoinForFieldRef(ref, whereJoins, targetTable, targetSchema, whereAliases);
|
|
6057
|
+
}
|
|
6058
|
+
if (whereAliases.size > 0) {
|
|
6059
|
+
this.resolveNavigationJoins(whereAliases, whereJoins, targetSchema);
|
|
6060
|
+
}
|
|
6061
|
+
for (const nav of whereJoins) {
|
|
6062
|
+
if (joinedAliases.has(nav.alias)) {
|
|
6063
|
+
continue;
|
|
6064
|
+
}
|
|
6065
|
+
joinedAliases.add(nav.alias);
|
|
6066
|
+
const joinType = nav.isMandatory ? 'JOIN' : 'LEFT JOIN';
|
|
6067
|
+
const fk = nav.foreignKeys[0];
|
|
6068
|
+
const pk = (nav.matches && nav.matches.length > 0) ? nav.matches[0] : 'id';
|
|
6069
|
+
allJoins.push(`${joinType} "${nav.targetTable}" "${nav.alias}" ON "${nav.sourceAlias}"."${fk}" = "${nav.alias}"."${pk}"`);
|
|
6070
|
+
}
|
|
6071
|
+
}
|
|
6072
|
+
}
|
|
6023
6073
|
const navJoinsSQL = allJoins.join('\n');
|
|
6024
6074
|
// Build WHERE clause: correlation + additional conditions
|
|
6025
6075
|
// Use full composite-FK / literal-predicate form when navigation declared
|
|
6026
6076
|
// multiple key pairs (e.g. SCD2 `[productId, isCurrent] / [id, true]`).
|
|
6027
6077
|
const fkTableAlias = this.foreignKeyTableAlias || targetTable;
|
|
6078
|
+
// Root-attached collections correlate on the λ-root itself, which a lateral
|
|
6079
|
+
// exposes only under its generated alias; nav-derived collections correlate on
|
|
6080
|
+
// the bridge's terminal alias, which this subquery emits itself — never remap it.
|
|
6081
|
+
const correlationSource = this.navigationPath.length === 0 ? rootAnchor(sourceTable) : sourceTable;
|
|
6028
6082
|
let whereSQL;
|
|
6029
6083
|
if (this.foreignKeys && this.foreignKeys.length > 0) {
|
|
6030
6084
|
const matches = this.matches && this.matches.length > 0 ? this.matches : ['id'];
|
|
6031
|
-
whereSQL = (0, join_utils_1.buildCollectionCorrelationWhere)(fkTableAlias,
|
|
6085
|
+
whereSQL = (0, join_utils_1.buildCollectionCorrelationWhere)(fkTableAlias, correlationSource, this.foreignKeys, matches);
|
|
6032
6086
|
}
|
|
6033
6087
|
else {
|
|
6034
|
-
whereSQL = `"${fkTableAlias}"."${foreignKey}" = "${
|
|
6088
|
+
whereSQL = `"${fkTableAlias}"."${foreignKey}" = "${correlationSource}"."id"`;
|
|
6035
6089
|
}
|
|
6036
6090
|
if (this.whereCond) {
|
|
6037
6091
|
const condBuilder = new conditions_1.ConditionBuilder();
|
|
@@ -6369,6 +6423,10 @@ class CollectionQueryBuilder {
|
|
|
6369
6423
|
paramCounter: context.paramCounter,
|
|
6370
6424
|
params: context.allParams,
|
|
6371
6425
|
placeholders: context.placeholders, // Pass placeholders for prepared statements
|
|
6426
|
+
// Thread the lateral alias scope into fragments: an EXISTS collection
|
|
6427
|
+
// rendered inside this lateral must anchor its λ-root on the lateral's
|
|
6428
|
+
// generated alias (see CollectionQueryBuilder.buildSql rootAnchor).
|
|
6429
|
+
lateralTableAliasMap: context.lateralTableAliasMap,
|
|
6372
6430
|
};
|
|
6373
6431
|
const fragmentSql = field.buildSql(sqlBuildContext);
|
|
6374
6432
|
context.paramCounter = sqlBuildContext.paramCounter;
|