typeorm 0.3.29 → 0.3.30

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 (37) hide show
  1. package/browser/driver/cockroachdb/CockroachQueryRunner.js +4 -4
  2. package/browser/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
  3. package/browser/driver/sqlserver/SqlServerQueryRunner.js +4 -2
  4. package/browser/driver/sqlserver/SqlServerQueryRunner.js.map +1 -1
  5. package/browser/entity-manager/EntityManager.js +8 -4
  6. package/browser/entity-manager/EntityManager.js.map +1 -1
  7. package/browser/find-options/operator/JsonContains.d.ts +1 -1
  8. package/browser/find-options/operator/JsonContains.js.map +1 -1
  9. package/browser/persistence/SubjectChangedColumnsComputer.js +6 -2
  10. package/browser/persistence/SubjectChangedColumnsComputer.js.map +1 -1
  11. package/browser/query-builder/QueryBuilder.js +7 -24
  12. package/browser/query-builder/QueryBuilder.js.map +1 -1
  13. package/browser/query-builder/SelectQueryBuilder.d.ts +6 -6
  14. package/browser/query-builder/SelectQueryBuilder.js +27 -22
  15. package/browser/query-builder/SelectQueryBuilder.js.map +1 -1
  16. package/browser/util/OrmUtils.d.ts +13 -0
  17. package/browser/util/OrmUtils.js +53 -0
  18. package/browser/util/OrmUtils.js.map +1 -1
  19. package/driver/cockroachdb/CockroachQueryRunner.js +4 -4
  20. package/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
  21. package/driver/sqlserver/SqlServerQueryRunner.js +4 -2
  22. package/driver/sqlserver/SqlServerQueryRunner.js.map +1 -1
  23. package/entity-manager/EntityManager.js +8 -4
  24. package/entity-manager/EntityManager.js.map +1 -1
  25. package/find-options/operator/JsonContains.d.ts +1 -1
  26. package/find-options/operator/JsonContains.js.map +1 -1
  27. package/package.json +6 -6
  28. package/persistence/SubjectChangedColumnsComputer.js +6 -2
  29. package/persistence/SubjectChangedColumnsComputer.js.map +1 -1
  30. package/query-builder/QueryBuilder.js +7 -24
  31. package/query-builder/QueryBuilder.js.map +1 -1
  32. package/query-builder/SelectQueryBuilder.d.ts +6 -6
  33. package/query-builder/SelectQueryBuilder.js +27 -22
  34. package/query-builder/SelectQueryBuilder.js.map +1 -1
  35. package/util/OrmUtils.d.ts +13 -0
  36. package/util/OrmUtils.js +53 -0
  37. package/util/OrmUtils.js.map +1 -1
@@ -535,9 +535,9 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
535
535
  }
536
536
  /**
537
537
  * Sets LIMIT - maximum number of rows to be selected.
538
- * When joins are present, a two-query distinct-id strategy is used
539
- * so that LIMIT applies to root entities rather than raw joined rows.
540
- * @param limit
538
+ * NOTE that it may not work as you expect if you are using joins.
539
+ * If you want to implement pagination, and you are having join in your query,
540
+ * then use the take method instead.
541
541
  */
542
542
  limit(limit) {
543
543
  this.expressionMap.limit = this.validateNumericInput("limit", limit);
@@ -545,9 +545,9 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
545
545
  }
546
546
  /**
547
547
  * Sets OFFSET - selection offset.
548
- * When joins are present, a two-query distinct-id strategy is used
549
- * so that OFFSET applies to root entities rather than raw joined rows.
550
- * @param offset
548
+ * NOTE that it may not work as you expect if you are using joins.
549
+ * If you want to implement pagination, and you are having join in your query,
550
+ * then use the skip method instead.
551
551
  */
552
552
  offset(offset) {
553
553
  this.expressionMap.offset = this.validateNumericInput("offset", offset);
@@ -1985,10 +1985,7 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
1985
1985
  // where we make two queries to find the data we need
1986
1986
  // first query find ids in skip and take range
1987
1987
  // and second query loads the actual data in given ids range
1988
- if ((this.expressionMap.skip ||
1989
- this.expressionMap.take ||
1990
- this.expressionMap.offset ||
1991
- this.expressionMap.limit) &&
1988
+ if ((this.expressionMap.skip || this.expressionMap.take) &&
1992
1989
  this.expressionMap.joinAttributes.length > 0) {
1993
1990
  // we are skipping order by here because its not working in subqueries anyway
1994
1991
  // to make order by working we need to apply it on a distinct query
@@ -2005,9 +2002,6 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
2005
2002
  return `${distinctAlias}.${columnAlias} AS ${this.escape(alias)}`;
2006
2003
  });
2007
2004
  const originalQuery = this.clone();
2008
- // clear limit/offset from the inner query since pagination is handled by the outer distinct query
2009
- originalQuery.expressionMap.limit = undefined;
2010
- originalQuery.expressionMap.offset = undefined;
2011
2005
  // preserve original timeTravel value since we set it to "false" in subquery
2012
2006
  const originalQueryTimeTravel = originalQuery.expressionMap.timeTravel;
2013
2007
  rawResults = await new SelectQueryBuilder(this.connection, queryRunner)
@@ -2018,8 +2012,8 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
2018
2012
  .timeTravelQuery(false) // set it to "false" since time travel clause must appear at the very end and applies to the entire SELECT clause.
2019
2013
  .getQuery()})`, "distinctAlias")
2020
2014
  .timeTravelQuery(originalQueryTimeTravel)
2021
- .offset(this.expressionMap.skip ?? this.expressionMap.offset)
2022
- .limit(this.expressionMap.take ?? this.expressionMap.limit)
2015
+ .offset(this.expressionMap.skip)
2016
+ .limit(this.expressionMap.take)
2023
2017
  .orderBy(orderBys)
2024
2018
  .cache(this.expressionMap.cache && this.expressionMap.cacheId
2025
2019
  ? `${this.expressionMap.cacheId}-pagination`
@@ -2062,14 +2056,12 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
2062
2056
  " IN (:...orm_distinct_ids)";
2063
2057
  }
2064
2058
  }
2065
- const secondQuery = this.clone()
2059
+ rawResults = await this.clone()
2066
2060
  .mergeExpressionMap({
2067
2061
  extraAppendedAndWhereCondition: condition,
2068
2062
  })
2069
- .setParameters(parameters);
2070
- secondQuery.expressionMap.limit = undefined;
2071
- secondQuery.expressionMap.offset = undefined;
2072
- rawResults = await secondQuery.loadRawResults(queryRunner);
2063
+ .setParameters(parameters)
2064
+ .loadRawResults(queryRunner);
2073
2065
  }
2074
2066
  }
2075
2067
  else {
@@ -2575,8 +2567,21 @@ class SelectQueryBuilder extends QueryBuilder_1.QueryBuilder {
2575
2567
  // if all properties of where are undefined we don't need to join anything
2576
2568
  // this can happen when user defines map with conditional queries inside
2577
2569
  if (typeof where[key] === "object") {
2578
- const allAllUndefined = Object.keys(where[key]).every((k) => where[key][k] === undefined);
2579
- if (allAllUndefined) {
2570
+ const whereKeys = Object.keys(where[key]);
2571
+ // empty object — no predicates to apply, skip the join
2572
+ if (whereKeys.length === 0) {
2573
+ continue;
2574
+ }
2575
+ const allUndefined = whereKeys.every((k) => where[key][k] === undefined);
2576
+ if (allUndefined) {
2577
+ const undefinedBehavior = this.connection.options
2578
+ .invalidWhereValuesBehavior?.undefined ||
2579
+ "ignore";
2580
+ if (undefinedBehavior === "throw") {
2581
+ throw new error_1.TypeORMError(`Undefined value encountered in nested relation '${alias}.${key}' of a where condition. ` +
2582
+ `All properties of the nested object are undefined. ` +
2583
+ `Set 'invalidWhereValuesBehavior.undefined' to 'ignore' in connection options to skip properties with undefined values.`);
2584
+ }
2580
2585
  continue;
2581
2586
  }
2582
2587
  }