linkgress-orm 0.4.23 → 0.4.25

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.
Files changed (33) hide show
  1. package/dist/entity/db-context.d.ts.map +1 -1
  2. package/dist/entity/db-context.js +3 -2
  3. package/dist/entity/db-context.js.map +1 -1
  4. package/dist/query/collection-strategy.interface.d.ts +25 -1
  5. package/dist/query/collection-strategy.interface.d.ts.map +1 -1
  6. package/dist/query/grouped-query.d.ts.map +1 -1
  7. package/dist/query/grouped-query.js +4 -2
  8. package/dist/query/grouped-query.js.map +1 -1
  9. package/dist/query/join-utils.d.ts +55 -0
  10. package/dist/query/join-utils.d.ts.map +1 -1
  11. package/dist/query/join-utils.js +92 -0
  12. package/dist/query/join-utils.js.map +1 -1
  13. package/dist/query/query-builder.d.ts +3 -1
  14. package/dist/query/query-builder.d.ts.map +1 -1
  15. package/dist/query/query-builder.js +41 -14
  16. package/dist/query/query-builder.js.map +1 -1
  17. package/dist/query/strategies/cte-collection-strategy.d.ts +15 -0
  18. package/dist/query/strategies/cte-collection-strategy.d.ts.map +1 -1
  19. package/dist/query/strategies/cte-collection-strategy.js +40 -10
  20. package/dist/query/strategies/cte-collection-strategy.js.map +1 -1
  21. package/dist/query/strategies/lateral-collection-strategy.d.ts +14 -0
  22. package/dist/query/strategies/lateral-collection-strategy.d.ts.map +1 -1
  23. package/dist/query/strategies/lateral-collection-strategy.js +27 -6
  24. package/dist/query/strategies/lateral-collection-strategy.js.map +1 -1
  25. package/dist/query/strategies/temptable-collection-strategy.d.ts +9 -0
  26. package/dist/query/strategies/temptable-collection-strategy.d.ts.map +1 -1
  27. package/dist/query/strategies/temptable-collection-strategy.js +25 -5
  28. package/dist/query/strategies/temptable-collection-strategy.js.map +1 -1
  29. package/dist/query/union-builder.d.ts +40 -0
  30. package/dist/query/union-builder.d.ts.map +1 -1
  31. package/dist/query/union-builder.js +49 -9
  32. package/dist/query/union-builder.js.map +1 -1
  33. package/package.json +1 -1
@@ -254,8 +254,9 @@ class QueryBuilder {
254
254
  // Non-enumerable to prevent Object.entries triggering getters (avoids stack overflow)
255
255
  Object.defineProperty(mock, relName, {
256
256
  get: () => {
257
- return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', this.schema.name, targetSchema, this.schemaRegistry // Pass schema registry for nested navigation resolution
258
- );
257
+ return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', this.schema.name, targetSchema, this.schemaRegistry, // Pass schema registry for nested navigation resolution
258
+ undefined, relConfig.foreignKeys, // Propagate composite FK / literal predicates
259
+ relConfig.matches);
259
260
  },
260
261
  enumerable: false,
261
262
  configurable: true,
@@ -418,7 +419,8 @@ class QueryBuilder {
418
419
  // Non-enumerable to prevent Object.entries triggering getters (avoids stack overflow)
419
420
  Object.defineProperty(mock, relName, {
420
421
  get: () => {
421
- return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', schema.name, targetSchema);
422
+ return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', schema.name, targetSchema, undefined, undefined, relConfig.foreignKeys, // Propagate composite FK / literal predicates
423
+ relConfig.matches);
422
424
  },
423
425
  enumerable: false,
424
426
  configurable: true,
@@ -804,7 +806,8 @@ class SelectQueryBuilder {
804
806
  // Non-enumerable to prevent Object.entries triggering getters (avoids stack overflow)
805
807
  Object.defineProperty(mock, relName, {
806
808
  get: () => {
807
- return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', schema.name, targetSchema);
809
+ return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', schema.name, targetSchema, undefined, undefined, relConfig.foreignKeys, // Propagate composite FK / literal predicates
810
+ relConfig.matches);
808
811
  },
809
812
  enumerable: false,
810
813
  configurable: true,
@@ -2734,8 +2737,9 @@ ${joinClauses.join('\n')}`;
2734
2737
  Object.defineProperty(mock, relName, {
2735
2738
  get: () => {
2736
2739
  return new CollectionQueryBuilder(relName, relConfig.targetTable, relConfig.foreignKey || relConfig.foreignKeys?.[0] || '', this.schema.name, targetSchema, // Pass the target schema directly
2737
- this.schemaRegistry // Pass schema registry for nested resolution
2738
- );
2740
+ this.schemaRegistry, // Pass schema registry for nested resolution
2741
+ undefined, relConfig.foreignKeys, // Propagate composite FK / literal predicates
2742
+ relConfig.matches);
2739
2743
  },
2740
2744
  enumerable: false,
2741
2745
  configurable: true,
@@ -4830,8 +4834,9 @@ class ReferenceQueryBuilder {
4830
4834
  return new CollectionQueryBuilder(relName, relConfig.targetTable, fk, this.relationName, // Use alias (relationName) for correlation in lateral joins
4831
4835
  nestedTargetSchema, // Pass the target schema directly
4832
4836
  this.schemaRegistry, // Pass schema registry for nested resolution
4833
- extendedNavPath // Pass navigation path for intermediate joins (empty if main query)
4834
- );
4837
+ extendedNavPath, // Pass navigation path for intermediate joins (empty if main query)
4838
+ relConfig.foreignKeys, // Propagate composite FK / literal predicates
4839
+ relConfig.matches);
4835
4840
  },
4836
4841
  enumerable: false,
4837
4842
  configurable: true,
@@ -4869,7 +4874,7 @@ exports.ReferenceQueryBuilder = ReferenceQueryBuilder;
4869
4874
  * Collection query builder for nested queries
4870
4875
  */
4871
4876
  class CollectionQueryBuilder {
4872
- constructor(relationName, targetTable, foreignKey, sourceTable, targetTableSchema, schemaRegistry, navigationPath) {
4877
+ constructor(relationName, targetTable, foreignKey, sourceTable, targetTableSchema, schemaRegistry, navigationPath, foreignKeys, matches) {
4873
4878
  this.orderByFields = [];
4874
4879
  this.isMarkedAsList = false;
4875
4880
  this.isDistinct = false;
@@ -4879,6 +4884,12 @@ class CollectionQueryBuilder {
4879
4884
  this.targetTable = targetTable;
4880
4885
  this.targetTableSchema = targetTableSchema;
4881
4886
  this.foreignKey = foreignKey;
4887
+ // Default `foreignKeys` to the single-column form so every strategy can
4888
+ // iterate uniformly. Constant FK predicates ([col, literal] + [id, true])
4889
+ // arrive via the explicit `foreignKeys`/`matches` arrays passed from the
4890
+ // navigation metadata.
4891
+ this.foreignKeys = (foreignKeys && foreignKeys.length > 0) ? foreignKeys : (foreignKey ? [foreignKey] : []);
4892
+ this.matches = (matches && matches.length > 0) ? matches : ['id'];
4882
4893
  this.sourceTable = sourceTable;
4883
4894
  this.schemaRegistry = schemaRegistry;
4884
4895
  this.navigationPath = navigationPath || [];
@@ -4899,8 +4910,9 @@ class CollectionQueryBuilder {
4899
4910
  */
4900
4911
  select(selector) {
4901
4912
  const newBuilder = new CollectionQueryBuilder(this.relationName, this.targetTable, this.foreignKey, this.sourceTable, this.targetTableSchema, this.schemaRegistry, // Pass schema registry for nested navigation resolution
4902
- this.navigationPath // Pass navigation path for intermediate joins
4903
- );
4913
+ this.navigationPath, // Pass navigation path for intermediate joins
4914
+ this.foreignKeys, // Propagate composite/literal FK metadata
4915
+ this.matches);
4904
4916
  newBuilder.selector = selector;
4905
4917
  newBuilder.whereCond = this.whereCond;
4906
4918
  newBuilder.limitValue = this.limitValue;
@@ -4984,9 +4996,10 @@ class CollectionQueryBuilder {
4984
4996
  // Don't call build() - it returns schema without relations
4985
4997
  const fk = relConfig.foreignKey || relConfig.foreignKeys?.[0] || '';
4986
4998
  return new CollectionQueryBuilder(relName, relConfig.targetTable, fk, this.targetTable, undefined, // Don't pass schema, force registry lookup
4987
- this.schemaRegistry // Pass schema registry for nested resolution
4999
+ this.schemaRegistry, // Pass schema registry for nested resolution
4988
5000
  // No navigation path needed here - direct collection access from parent
4989
- );
5001
+ undefined, relConfig.foreignKeys, // Propagate composite FK / literal predicates
5002
+ relConfig.matches);
4990
5003
  },
4991
5004
  enumerable: false,
4992
5005
  configurable: true,
@@ -5279,8 +5292,17 @@ class CollectionQueryBuilder {
5279
5292
  }
5280
5293
  const navJoinsSQL = allJoins.join('\n');
5281
5294
  // Build WHERE clause: correlation + additional conditions
5295
+ // Use full composite-FK / literal-predicate form when navigation declared
5296
+ // multiple key pairs (e.g. SCD2 `[productId, isCurrent] / [id, true]`).
5282
5297
  const fkTableAlias = this.foreignKeyTableAlias || targetTable;
5283
- let whereSQL = `"${fkTableAlias}"."${foreignKey}" = "${sourceTable}"."id"`;
5298
+ let whereSQL;
5299
+ if (this.foreignKeys && this.foreignKeys.length > 0) {
5300
+ const matches = this.matches && this.matches.length > 0 ? this.matches : ['id'];
5301
+ whereSQL = (0, join_utils_1.buildCollectionCorrelationWhere)(fkTableAlias, sourceTable, this.foreignKeys, matches);
5302
+ }
5303
+ else {
5304
+ whereSQL = `"${fkTableAlias}"."${foreignKey}" = "${sourceTable}"."id"`;
5305
+ }
5284
5306
  if (this.whereCond) {
5285
5307
  const condBuilder = new conditions_1.ConditionBuilder();
5286
5308
  const { sql: condSql, params, placeholders, paramCounter } = condBuilder.build(this.whereCond, context.paramCounter, context.placeholders);
@@ -5872,6 +5894,11 @@ class CollectionQueryBuilder {
5872
5894
  relationName: this.relationName,
5873
5895
  targetTable: this.targetTable,
5874
5896
  foreignKey: this.foreignKey,
5897
+ // Composite FK metadata: enables strategies to emit constant FK predicates
5898
+ // (e.g. SCD2 `is_current = TRUE` from `withForeignKey: [col, isCurrent] /
5899
+ // withPrincipalKey: [id, true]`) in the projection WHERE clause.
5900
+ foreignKeys: this.foreignKeys,
5901
+ matches: this.matches,
5875
5902
  foreignKeyTableAlias: this.foreignKeyTableAlias,
5876
5903
  sourceTable: this.sourceTable,
5877
5904
  parentIds, // Pass parent IDs for temp table strategy