typeorm 1.0.0-beta.2 → 1.0.0-beta.3
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 +1 -3
- package/browser/connection/ConnectionOptionsReader.js +1 -1
- package/browser/connection/ConnectionOptionsReader.js.map +1 -1
- package/browser/data-source/DataSource.d.ts +1 -1
- package/browser/data-source/DataSource.js.map +1 -1
- package/browser/decorator/options/JoinColumnOptions.js.map +1 -1
- package/browser/driver/DriverUtils.d.ts +1 -0
- package/browser/driver/DriverUtils.js +27 -29
- package/browser/driver/DriverUtils.js.map +1 -1
- package/browser/driver/aurora-mysql/AuroraMysqlDriver.js +4 -4
- package/browser/driver/aurora-mysql/AuroraMysqlDriver.js.map +1 -1
- package/browser/driver/aurora-mysql/AuroraMysqlQueryRunner.d.ts +2 -1
- package/browser/driver/aurora-mysql/AuroraMysqlQueryRunner.js +9 -6
- package/browser/driver/aurora-mysql/AuroraMysqlQueryRunner.js.map +1 -1
- package/browser/driver/aurora-postgres/AuroraPostgresQueryRunner.d.ts +2 -1
- package/browser/driver/aurora-postgres/AuroraPostgresQueryRunner.js +3 -0
- package/browser/driver/aurora-postgres/AuroraPostgresQueryRunner.js.map +1 -1
- package/browser/driver/better-sqlite3/BetterSqlite3QueryRunner.d.ts +2 -1
- package/browser/driver/better-sqlite3/BetterSqlite3QueryRunner.js +3 -0
- package/browser/driver/better-sqlite3/BetterSqlite3QueryRunner.js.map +1 -1
- package/browser/driver/capacitor/CapacitorQueryRunner.d.ts +1 -1
- package/browser/driver/capacitor/CapacitorQueryRunner.js +5 -1
- package/browser/driver/capacitor/CapacitorQueryRunner.js.map +1 -1
- package/browser/driver/cockroachdb/CockroachDriver.js +3 -3
- package/browser/driver/cockroachdb/CockroachDriver.js.map +1 -1
- package/browser/driver/cockroachdb/CockroachQueryRunner.d.ts +2 -1
- package/browser/driver/cockroachdb/CockroachQueryRunner.js +55 -50
- package/browser/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
- package/browser/driver/cordova/CordovaQueryRunner.d.ts +1 -1
- package/browser/driver/cordova/CordovaQueryRunner.js +2 -0
- package/browser/driver/cordova/CordovaQueryRunner.js.map +1 -1
- package/browser/driver/expo/ExpoDataSourceOptions.d.ts +5 -3
- package/browser/driver/expo/ExpoDataSourceOptions.js.map +1 -1
- package/browser/driver/expo/ExpoDriver.d.ts +16 -1
- package/browser/driver/expo/ExpoDriver.js +68 -6
- package/browser/driver/expo/ExpoDriver.js.map +1 -1
- package/browser/driver/expo/ExpoQueryRunner.d.ts +2 -1
- package/browser/driver/expo/ExpoQueryRunner.js +3 -0
- package/browser/driver/expo/ExpoQueryRunner.js.map +1 -1
- package/browser/driver/mysql/MysqlDriver.js +4 -4
- package/browser/driver/mysql/MysqlDriver.js.map +1 -1
- package/browser/driver/mysql/MysqlQueryRunner.d.ts +2 -1
- package/browser/driver/mysql/MysqlQueryRunner.js +78 -82
- package/browser/driver/mysql/MysqlQueryRunner.js.map +1 -1
- package/browser/driver/nativescript/NativescriptQueryRunner.d.ts +1 -1
- package/browser/driver/nativescript/NativescriptQueryRunner.js +3 -0
- package/browser/driver/nativescript/NativescriptQueryRunner.js.map +1 -1
- package/browser/driver/oracle/OracleDriver.js +2 -2
- package/browser/driver/oracle/OracleDriver.js.map +1 -1
- package/browser/driver/postgres/PostgresDriver.js +8 -8
- package/browser/driver/postgres/PostgresDriver.js.map +1 -1
- package/browser/driver/postgres/PostgresQueryRunner.d.ts +2 -1
- package/browser/driver/postgres/PostgresQueryRunner.js +12 -8
- package/browser/driver/postgres/PostgresQueryRunner.js.map +1 -1
- package/browser/driver/react-native/ReactNativeDriver.js +1 -1
- package/browser/driver/react-native/ReactNativeDriver.js.map +1 -1
- package/browser/driver/react-native/ReactNativeQueryRunner.d.ts +1 -1
- package/browser/driver/react-native/ReactNativeQueryRunner.js +3 -0
- package/browser/driver/react-native/ReactNativeQueryRunner.js.map +1 -1
- package/browser/driver/sap/SapDriver.js +5 -3
- package/browser/driver/sap/SapDriver.js.map +1 -1
- package/browser/driver/sap/SapQueryRunner.d.ts +2 -1
- package/browser/driver/sap/SapQueryRunner.js +171 -16
- package/browser/driver/sap/SapQueryRunner.js.map +1 -1
- package/browser/driver/spanner/SpannerDriver.d.ts +1 -1
- package/browser/driver/spanner/SpannerDriver.js +6 -8
- package/browser/driver/spanner/SpannerDriver.js.map +1 -1
- package/browser/driver/spanner/SpannerQueryRunner.d.ts +16 -1
- package/browser/driver/spanner/SpannerQueryRunner.js +75 -7
- package/browser/driver/spanner/SpannerQueryRunner.js.map +1 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteDriver.js +1 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteDriver.js.map +1 -1
- package/browser/driver/sqlite-abstract/AbstractSqliteQueryRunner.js +10 -14
- package/browser/driver/sqlite-abstract/AbstractSqliteQueryRunner.js.map +1 -1
- package/browser/driver/sqljs/SqljsQueryRunner.d.ts +2 -1
- package/browser/driver/sqljs/SqljsQueryRunner.js +3 -0
- package/browser/driver/sqljs/SqljsQueryRunner.js.map +1 -1
- package/browser/driver/sqlserver/SqlServerDriver.js +1 -1
- package/browser/driver/sqlserver/SqlServerDriver.js.map +1 -1
- package/browser/driver/sqlserver/SqlServerQueryRunner.d.ts +2 -1
- package/browser/driver/sqlserver/SqlServerQueryRunner.js +65 -60
- package/browser/driver/sqlserver/SqlServerQueryRunner.js.map +1 -1
- package/browser/entity-manager/EntityManager.d.ts +1 -1
- package/browser/entity-manager/EntityManager.js.map +1 -1
- package/browser/error/NamedPlaceholdersNotSupportedError.d.ts +7 -0
- package/browser/error/NamedPlaceholdersNotSupportedError.js +14 -0
- package/browser/error/NamedPlaceholdersNotSupportedError.js.map +1 -0
- package/browser/error/QueryFailedError.d.ts +3 -2
- package/browser/error/QueryFailedError.js.map +1 -1
- package/browser/error/index.d.ts +1 -0
- package/browser/error/index.js +1 -0
- package/browser/error/index.js.map +1 -1
- package/browser/index.d.ts +0 -1
- package/browser/index.js +1 -3
- package/browser/index.js.map +1 -1
- package/browser/logger/AbstractLogger.d.ts +5 -4
- package/browser/logger/AbstractLogger.js +3 -1
- package/browser/logger/AbstractLogger.js.map +1 -1
- package/browser/logger/DebugLogger.js +3 -1
- package/browser/logger/DebugLogger.js.map +1 -1
- package/browser/logger/Logger.d.ts +5 -4
- package/browser/logger/Logger.js.map +1 -1
- package/browser/naming-strategy/DefaultNamingStrategy.d.ts +7 -26
- package/browser/naming-strategy/DefaultNamingStrategy.js +19 -37
- package/browser/naming-strategy/DefaultNamingStrategy.js.map +1 -1
- package/browser/naming-strategy/NamingStrategyInterface.d.ts +9 -13
- package/browser/naming-strategy/NamingStrategyInterface.js.map +1 -1
- package/browser/persistence/EntityPersistExecutor.js +20 -8
- package/browser/persistence/EntityPersistExecutor.js.map +1 -1
- package/browser/persistence/SubjectDatabaseEntityLoader.js +15 -5
- package/browser/persistence/SubjectDatabaseEntityLoader.js.map +1 -1
- package/browser/persistence/SubjectExecutor.js +50 -30
- package/browser/persistence/SubjectExecutor.js.map +1 -1
- package/browser/platform/PlatformTools.js +1 -1
- package/browser/platform/PlatformTools.js.map +1 -1
- package/browser/query-builder/JoinAttribute.js +3 -3
- package/browser/query-builder/JoinAttribute.js.map +1 -1
- package/browser/query-builder/QueryBuilder.d.ts +0 -1
- package/browser/query-builder/QueryBuilder.js +3 -13
- package/browser/query-builder/QueryBuilder.js.map +1 -1
- package/browser/query-builder/SelectQueryBuilder.js +33 -27
- package/browser/query-builder/SelectQueryBuilder.js.map +1 -1
- package/browser/query-builder/SoftDeleteQueryBuilder.js +0 -2
- package/browser/query-builder/SoftDeleteQueryBuilder.js.map +1 -1
- package/browser/query-builder/UpdateQueryBuilder.js +0 -2
- package/browser/query-builder/UpdateQueryBuilder.js.map +1 -1
- package/browser/query-builder/relation-id/RelationIdAttribute.js +4 -4
- package/browser/query-builder/relation-id/RelationIdAttribute.js.map +1 -1
- package/browser/query-builder/relation-id/RelationIdLoader.js +16 -9
- package/browser/query-builder/relation-id/RelationIdLoader.js.map +1 -1
- package/browser/query-runner/BaseQueryRunner.d.ts +44 -21
- package/browser/query-runner/BaseQueryRunner.js +61 -21
- package/browser/query-runner/BaseQueryRunner.js.map +1 -1
- package/browser/query-runner/QueryRunner.d.ts +11 -2
- package/browser/query-runner/QueryRunner.js.map +1 -1
- package/browser/repository/BaseEntity.d.ts +2 -1
- package/browser/repository/BaseEntity.js.map +1 -1
- package/browser/repository/Repository.d.ts +1 -1
- package/browser/repository/Repository.js.map +1 -1
- package/browser/subscriber/Broadcaster.d.ts +4 -4
- package/browser/subscriber/Broadcaster.js.map +1 -1
- package/browser/subscriber/event/QueryEvent.d.ts +2 -1
- package/browser/subscriber/event/QueryEvent.js.map +1 -1
- package/browser/util/DirectoryExportedClassesLoader.js +1 -1
- package/browser/util/DirectoryExportedClassesLoader.js.map +1 -1
- package/browser/util/ImportUtils.js +1 -1
- package/browser/util/ImportUtils.js.map +1 -1
- package/browser/util/OrmUtils.js +1 -1
- package/browser/util/OrmUtils.js.map +1 -1
- package/browser/util/PathUtils.js +1 -1
- package/browser/util/PathUtils.js.map +1 -1
- package/browser/util/RandomGenerator.d.ts +1 -10
- package/browser/util/RandomGenerator.js +1 -10
- package/browser/util/RandomGenerator.js.map +1 -1
- package/browser/util/StringUtils.js +9 -9
- package/browser/util/StringUtils.js.map +1 -1
- package/browser/util/escapeRegExp.js +1 -1
- package/browser/util/escapeRegExp.js.map +1 -1
- package/commands/InitCommand.d.ts +0 -3
- package/commands/InitCommand.js +4 -31
- package/commands/InitCommand.js.map +1 -1
- package/commands/MigrationGenerateCommand.js +3 -1
- package/commands/MigrationGenerateCommand.js.map +1 -1
- package/commands/VersionCommand.js +2 -2
- package/commands/VersionCommand.js.map +1 -1
- package/connection/ConnectionOptionsReader.js +1 -1
- package/connection/ConnectionOptionsReader.js.map +1 -1
- package/data-source/DataSource.d.ts +1 -1
- package/data-source/DataSource.js.map +1 -1
- package/decorator/options/JoinColumnOptions.js.map +1 -1
- package/driver/DriverUtils.d.ts +1 -0
- package/driver/DriverUtils.js +27 -29
- package/driver/DriverUtils.js.map +1 -1
- package/driver/aurora-mysql/AuroraMysqlDriver.js +4 -4
- package/driver/aurora-mysql/AuroraMysqlDriver.js.map +1 -1
- package/driver/aurora-mysql/AuroraMysqlQueryRunner.d.ts +2 -1
- package/driver/aurora-mysql/AuroraMysqlQueryRunner.js +9 -6
- package/driver/aurora-mysql/AuroraMysqlQueryRunner.js.map +1 -1
- package/driver/aurora-postgres/AuroraPostgresQueryRunner.d.ts +2 -1
- package/driver/aurora-postgres/AuroraPostgresQueryRunner.js +3 -0
- package/driver/aurora-postgres/AuroraPostgresQueryRunner.js.map +1 -1
- package/driver/better-sqlite3/BetterSqlite3QueryRunner.d.ts +2 -1
- package/driver/better-sqlite3/BetterSqlite3QueryRunner.js +3 -0
- package/driver/better-sqlite3/BetterSqlite3QueryRunner.js.map +1 -1
- package/driver/capacitor/CapacitorQueryRunner.d.ts +1 -1
- package/driver/capacitor/CapacitorQueryRunner.js +5 -1
- package/driver/capacitor/CapacitorQueryRunner.js.map +1 -1
- package/driver/cockroachdb/CockroachDriver.js +3 -3
- package/driver/cockroachdb/CockroachDriver.js.map +1 -1
- package/driver/cockroachdb/CockroachQueryRunner.d.ts +2 -1
- package/driver/cockroachdb/CockroachQueryRunner.js +55 -50
- package/driver/cockroachdb/CockroachQueryRunner.js.map +1 -1
- package/driver/cordova/CordovaQueryRunner.d.ts +1 -1
- package/driver/cordova/CordovaQueryRunner.js +2 -0
- package/driver/cordova/CordovaQueryRunner.js.map +1 -1
- package/driver/expo/ExpoDataSourceOptions.d.ts +5 -3
- package/driver/expo/ExpoDataSourceOptions.js.map +1 -1
- package/driver/expo/ExpoDriver.d.ts +16 -1
- package/driver/expo/ExpoDriver.js +68 -6
- package/driver/expo/ExpoDriver.js.map +1 -1
- package/driver/expo/ExpoQueryRunner.d.ts +2 -1
- package/driver/expo/ExpoQueryRunner.js +3 -0
- package/driver/expo/ExpoQueryRunner.js.map +1 -1
- package/driver/mysql/MysqlDriver.js +4 -4
- package/driver/mysql/MysqlDriver.js.map +1 -1
- package/driver/mysql/MysqlQueryRunner.d.ts +2 -1
- package/driver/mysql/MysqlQueryRunner.js +78 -82
- package/driver/mysql/MysqlQueryRunner.js.map +1 -1
- package/driver/nativescript/NativescriptQueryRunner.d.ts +1 -1
- package/driver/nativescript/NativescriptQueryRunner.js +3 -0
- package/driver/nativescript/NativescriptQueryRunner.js.map +1 -1
- package/driver/oracle/OracleDriver.js +2 -2
- package/driver/oracle/OracleDriver.js.map +1 -1
- package/driver/postgres/PostgresDriver.js +8 -8
- package/driver/postgres/PostgresDriver.js.map +1 -1
- package/driver/postgres/PostgresQueryRunner.d.ts +2 -1
- package/driver/postgres/PostgresQueryRunner.js +12 -8
- package/driver/postgres/PostgresQueryRunner.js.map +1 -1
- package/driver/react-native/ReactNativeDriver.js +1 -1
- package/driver/react-native/ReactNativeDriver.js.map +1 -1
- package/driver/react-native/ReactNativeQueryRunner.d.ts +1 -1
- package/driver/react-native/ReactNativeQueryRunner.js +3 -0
- package/driver/react-native/ReactNativeQueryRunner.js.map +1 -1
- package/driver/sap/SapDriver.js +5 -3
- package/driver/sap/SapDriver.js.map +1 -1
- package/driver/sap/SapQueryRunner.d.ts +2 -1
- package/driver/sap/SapQueryRunner.js +171 -16
- package/driver/sap/SapQueryRunner.js.map +1 -1
- package/driver/spanner/SpannerDriver.d.ts +1 -1
- package/driver/spanner/SpannerDriver.js +6 -8
- package/driver/spanner/SpannerDriver.js.map +1 -1
- package/driver/spanner/SpannerQueryRunner.d.ts +16 -1
- package/driver/spanner/SpannerQueryRunner.js +75 -7
- package/driver/spanner/SpannerQueryRunner.js.map +1 -1
- package/driver/sqlite-abstract/AbstractSqliteDriver.js +1 -1
- package/driver/sqlite-abstract/AbstractSqliteDriver.js.map +1 -1
- package/driver/sqlite-abstract/AbstractSqliteQueryRunner.js +10 -14
- package/driver/sqlite-abstract/AbstractSqliteQueryRunner.js.map +1 -1
- package/driver/sqljs/SqljsQueryRunner.d.ts +2 -1
- package/driver/sqljs/SqljsQueryRunner.js +3 -0
- package/driver/sqljs/SqljsQueryRunner.js.map +1 -1
- package/driver/sqlserver/SqlServerDriver.js +1 -1
- package/driver/sqlserver/SqlServerDriver.js.map +1 -1
- package/driver/sqlserver/SqlServerQueryRunner.d.ts +2 -1
- package/driver/sqlserver/SqlServerQueryRunner.js +65 -60
- package/driver/sqlserver/SqlServerQueryRunner.js.map +1 -1
- package/entity-manager/EntityManager.d.ts +1 -1
- package/entity-manager/EntityManager.js.map +1 -1
- package/error/NamedPlaceholdersNotSupportedError.d.ts +7 -0
- package/error/NamedPlaceholdersNotSupportedError.js +14 -0
- package/error/NamedPlaceholdersNotSupportedError.js.map +1 -0
- package/error/QueryFailedError.d.ts +3 -2
- package/error/QueryFailedError.js.map +1 -1
- package/error/index.d.ts +1 -0
- package/error/index.js +1 -0
- package/error/index.js.map +1 -1
- package/index.d.ts +0 -1
- package/index.js +1 -3
- package/index.js.map +1 -1
- package/index.mjs +2 -2
- package/logger/AbstractLogger.d.ts +5 -4
- package/logger/AbstractLogger.js +3 -1
- package/logger/AbstractLogger.js.map +1 -1
- package/logger/DebugLogger.js +3 -1
- package/logger/DebugLogger.js.map +1 -1
- package/logger/Logger.d.ts +5 -4
- package/logger/Logger.js.map +1 -1
- package/naming-strategy/DefaultNamingStrategy.d.ts +7 -26
- package/naming-strategy/DefaultNamingStrategy.js +19 -37
- package/naming-strategy/DefaultNamingStrategy.js.map +1 -1
- package/naming-strategy/NamingStrategyInterface.d.ts +9 -13
- package/naming-strategy/NamingStrategyInterface.js.map +1 -1
- package/package.json +6 -6
- package/persistence/EntityPersistExecutor.js +20 -8
- package/persistence/EntityPersistExecutor.js.map +1 -1
- package/persistence/SubjectDatabaseEntityLoader.js +15 -5
- package/persistence/SubjectDatabaseEntityLoader.js.map +1 -1
- package/persistence/SubjectExecutor.js +50 -30
- package/persistence/SubjectExecutor.js.map +1 -1
- package/platform/PlatformTools.js +1 -1
- package/platform/PlatformTools.js.map +1 -1
- package/query-builder/JoinAttribute.js +3 -3
- package/query-builder/JoinAttribute.js.map +1 -1
- package/query-builder/QueryBuilder.d.ts +0 -1
- package/query-builder/QueryBuilder.js +3 -13
- package/query-builder/QueryBuilder.js.map +1 -1
- package/query-builder/SelectQueryBuilder.js +33 -27
- package/query-builder/SelectQueryBuilder.js.map +1 -1
- package/query-builder/SoftDeleteQueryBuilder.js +0 -2
- package/query-builder/SoftDeleteQueryBuilder.js.map +1 -1
- package/query-builder/UpdateQueryBuilder.js +0 -2
- package/query-builder/UpdateQueryBuilder.js.map +1 -1
- package/query-builder/relation-id/RelationIdAttribute.js +4 -4
- package/query-builder/relation-id/RelationIdAttribute.js.map +1 -1
- package/query-builder/relation-id/RelationIdLoader.js +16 -9
- package/query-builder/relation-id/RelationIdLoader.js.map +1 -1
- package/query-runner/BaseQueryRunner.d.ts +44 -21
- package/query-runner/BaseQueryRunner.js +61 -21
- package/query-runner/BaseQueryRunner.js.map +1 -1
- package/query-runner/QueryRunner.d.ts +11 -2
- package/query-runner/QueryRunner.js.map +1 -1
- package/repository/BaseEntity.d.ts +2 -1
- package/repository/BaseEntity.js.map +1 -1
- package/repository/Repository.d.ts +1 -1
- package/repository/Repository.js.map +1 -1
- package/subscriber/Broadcaster.d.ts +4 -4
- package/subscriber/Broadcaster.js.map +1 -1
- package/subscriber/event/QueryEvent.d.ts +2 -1
- package/subscriber/event/QueryEvent.js.map +1 -1
- package/util/DirectoryExportedClassesLoader.js +1 -1
- package/util/DirectoryExportedClassesLoader.js.map +1 -1
- package/util/ImportUtils.js +1 -1
- package/util/ImportUtils.js.map +1 -1
- package/util/OrmUtils.js +1 -1
- package/util/OrmUtils.js.map +1 -1
- package/util/PathUtils.js +1 -1
- package/util/PathUtils.js.map +1 -1
- package/util/RandomGenerator.d.ts +1 -10
- package/util/RandomGenerator.js +1 -10
- package/util/RandomGenerator.js.map +1 -1
- package/util/StringUtils.js +9 -9
- package/util/StringUtils.js.map +1 -1
- package/util/escapeRegExp.js +1 -1
- package/util/escapeRegExp.js.map +1 -1
- package/browser/naming-strategy/LegacyOracleNamingStrategy.d.ts +0 -21
- package/browser/naming-strategy/LegacyOracleNamingStrategy.js +0 -49
- package/browser/naming-strategy/LegacyOracleNamingStrategy.js.map +0 -1
- package/naming-strategy/LegacyOracleNamingStrategy.d.ts +0 -21
- package/naming-strategy/LegacyOracleNamingStrategy.js +0 -49
- package/naming-strategy/LegacyOracleNamingStrategy.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NamingStrategyInterface.js","sourceRoot":"../build/browser/src/","sources":["naming-strategy/NamingStrategyInterface.ts"],"names":[],"mappings":"","sourcesContent":["import type { Table } from \"../schema-builder/table/Table\"\nimport type { View } from \"../schema-builder/view/View\"\n\n/**\n * Naming strategy defines how auto-generated names for such things like table name, or table column gonna be\n * generated.\n */\nexport interface NamingStrategyInterface {\n /**\n *
|
|
1
|
+
{"version":3,"file":"NamingStrategyInterface.js","sourceRoot":"../build/browser/src/","sources":["naming-strategy/NamingStrategyInterface.ts"],"names":[],"mappings":"","sourcesContent":["import type { Table } from \"../schema-builder/table/Table\"\nimport type { View } from \"../schema-builder/view/View\"\n\n/**\n * Naming strategy defines how auto-generated names for such things like table name, or table column gonna be\n * generated.\n */\nexport interface NamingStrategyInterface {\n /**\n * Column name for materialized paths.\n */\n materializedPathColumnName: string\n\n /**\n * Column names for nested sets.\n */\n nestedSetColumnNames: { left: string; right: string }\n\n /**\n * Normalizes table name.\n *\n * @param targetName Name of the target entity that can be used to generate a table name.\n * @param userSpecifiedName For example if user specified a table name in a decorator, e.g. `@Entity(\"name\")`\n */\n tableName(targetName: string, userSpecifiedName: string | undefined): string\n\n /**\n * Creates a table name for a junction table of a closure table.\n *\n * @param originalClosureTableName Name of the closure table which owns this junction table.\n */\n closureJunctionTableName(originalClosureTableName: string): string\n\n /**\n * Gets the table's column name from the given property name.\n */\n columnName(\n propertyName: string,\n customName: string | undefined,\n embeddedPrefixes: string[],\n ): string\n\n /**\n * Gets the table's relation name from the given property name.\n */\n relationName(propertyName: string): string\n\n /**\n * Gets the table's primary key name from the given table name and column names.\n */\n primaryKeyName(tableOrName: Table | string, columnNames: string[]): string\n\n /**\n * Gets the table's unique constraint name from the given table name and column names.\n */\n uniqueConstraintName(\n tableOrName: Table | string,\n columnNames: string[],\n ): string\n\n /**\n * Gets the relation constraint (UNIQUE or UNIQUE INDEX) name from the given table name, column names\n * and WHERE condition, if UNIQUE INDEX used.\n */\n relationConstraintName(\n tableOrName: Table | string,\n columnNames: string[],\n where?: string,\n ): string\n\n /**\n * Gets the table's default constraint name from the given table name and column name.\n */\n defaultConstraintName(\n tableOrName: Table | string,\n columnName: string,\n ): string\n\n /**\n * Gets the name of the foreign key.\n */\n foreignKeyName(\n tableOrName: Table | string,\n columnNames: string[],\n referencedTablePath?: string,\n referencedColumnNames?: string[],\n ): string\n\n /**\n * Gets the name of the index - simple and compose index.\n */\n indexName(\n tableOrName: Table | View | string,\n columns: string[],\n where?: string,\n ): string\n\n /**\n * Gets the name of the check constraint.\n *\n * \"isEnum\" parameter is used to indicate if this check constraint used\n * to handle \"simple-enum\" type for databases that are not supporting \"enum\"\n * type out of the box. If \"true\", constraint is ignored during CHECK constraints\n * synchronization.\n */\n checkConstraintName(\n tableOrName: Table | string,\n expression: string,\n isEnum?: boolean,\n ): string\n\n /**\n * Gets the name of the exclusion constraint.\n */\n exclusionConstraintName(\n tableOrName: Table | string,\n expression: string,\n ): string\n\n /**\n * Gets the name of the join column used in the one-to-one and many-to-one relations.\n */\n joinColumnName(relationName: string, referencedColumnName: string): string\n\n /**\n * Gets the name of the join table used in the many-to-many relations.\n */\n joinTableName(\n firstTableName: string,\n secondTableName: string,\n firstPropertyName: string,\n secondPropertyName: string,\n ): string\n\n /**\n * Columns in join tables can have duplicate names in case of self-referencing.\n * This method provide a resolution for such column names.\n */\n joinTableColumnDuplicationPrefix(columnName: string, index: number): string\n\n /**\n * Gets the name of the column used for columns in the junction tables.\n *\n * The reverse?:boolean parameter denotes if the joinTableColumnName is called for the junctionColumn (false)\n * or the inverseJunctionColumns (true)\n */\n joinTableColumnName(\n tableName: string,\n propertyName: string,\n columnName?: string,\n ): string\n\n /**\n * Gets the name of the column used for columns in the junction tables from the invers side of the relationship.\n */\n joinTableInverseColumnName(\n tableName: string,\n propertyName: string,\n columnName?: string,\n ): string\n\n /**\n * Adds globally set prefix to the table name.\n * This method is executed no matter if prefix was set or not.\n * Table name is either user's given table name, either name generated from entity target.\n * Note that table name comes here already normalized by #tableName method.\n */\n prefixTableName(prefix: string, tableName: string): string\n}\n"]}
|
|
@@ -44,7 +44,7 @@ class EntityPersistExecutor {
|
|
|
44
44
|
// save data in the query runner - this is useful functionality to share data from outside of the world
|
|
45
45
|
// with third classes - like subscribers and listener methods
|
|
46
46
|
const oldQueryRunnerData = queryRunner.data;
|
|
47
|
-
if (this.options
|
|
47
|
+
if (this.options?.data) {
|
|
48
48
|
queryRunner.data = this.options.data;
|
|
49
49
|
}
|
|
50
50
|
try {
|
|
@@ -52,11 +52,9 @@ class EntityPersistExecutor {
|
|
|
52
52
|
const entities = Array.isArray(this.entity)
|
|
53
53
|
? this.entity
|
|
54
54
|
: [this.entity];
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// console.time("building subject executors...");
|
|
59
|
-
const executors = await Promise.all(entitiesInChunks.map(async (entities) => {
|
|
55
|
+
const chunkSize = this.options?.chunk ?? 0;
|
|
56
|
+
const entitiesInChunks = chunkSize > 0 ? OrmUtils_1.OrmUtils.chunk(entities, chunkSize) : [entities];
|
|
57
|
+
const buildExecutor = async (entities) => {
|
|
60
58
|
const subjects = [];
|
|
61
59
|
// create subjects for all entities we received for the persistence
|
|
62
60
|
entities.forEach((entity) => {
|
|
@@ -111,7 +109,21 @@ class EntityPersistExecutor {
|
|
|
111
109
|
// console.log("subjects", subjects);
|
|
112
110
|
// create a subject executor
|
|
113
111
|
return new SubjectExecutor_1.SubjectExecutor(queryRunner, subjects, this.options);
|
|
114
|
-
}
|
|
112
|
+
};
|
|
113
|
+
// console.time("building subject executors...");
|
|
114
|
+
// Avoid concurrent queries on the same pg client; see #12238.
|
|
115
|
+
// CockroachDB uses the pg package over a single connection too.
|
|
116
|
+
const driverType = this.dataSource.options.type;
|
|
117
|
+
let executors;
|
|
118
|
+
if (driverType === "postgres" || driverType === "cockroachdb") {
|
|
119
|
+
executors = [];
|
|
120
|
+
for (const entities of entitiesInChunks) {
|
|
121
|
+
executors.push(await buildExecutor(entities));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
executors = await Promise.all(entitiesInChunks.map(buildExecutor));
|
|
126
|
+
}
|
|
115
127
|
// console.timeEnd("building subject executors...");
|
|
116
128
|
// make sure we have at least one executable operation before we create a transaction and proceed
|
|
117
129
|
// if we don't have operations it means we don't really need to update or remove something
|
|
@@ -126,7 +138,7 @@ class EntityPersistExecutor {
|
|
|
126
138
|
// open transaction if its not opened yet
|
|
127
139
|
if (!queryRunner.isTransactionActive) {
|
|
128
140
|
if (this.dataSource.driver.transactionSupport !== "none" &&
|
|
129
|
-
|
|
141
|
+
this.options?.transaction !== false) {
|
|
130
142
|
// start transaction until it was not explicitly disabled
|
|
131
143
|
isTransactionStartedByUs = true;
|
|
132
144
|
await queryRunner.startTransaction();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityPersistExecutor.js","sourceRoot":"../build/browser/src/","sources":["persistence/EntityPersistExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport type { SaveOptions } from \"../repository/SaveOptions\"\nimport type { RemoveOptions } from \"../repository/RemoveOptions\"\nimport { MustBeEntityError } from \"../error/MustBeEntityError\"\nimport { SubjectExecutor } from \"./SubjectExecutor\"\nimport { CannotDetermineEntityError } from \"../error/CannotDetermineEntityError\"\nimport type { QueryRunner } from \"../query-runner/QueryRunner\"\nimport type { DataSource } from \"../data-source/DataSource\"\nimport { Subject } from \"./Subject\"\nimport { OneToManySubjectBuilder } from \"./subject-builder/OneToManySubjectBuilder\"\nimport { OneToOneInverseSideSubjectBuilder } from \"./subject-builder/OneToOneInverseSideSubjectBuilder\"\nimport { ManyToManySubjectBuilder } from \"./subject-builder/ManyToManySubjectBuilder\"\nimport { SubjectDatabaseEntityLoader } from \"./SubjectDatabaseEntityLoader\"\nimport { CascadesSubjectBuilder } from \"./subject-builder/CascadesSubjectBuilder\"\nimport { OrmUtils } from \"../util/OrmUtils\"\n\n/**\n * Persists a single entity or multiple entities - saves or removes them.\n */\nexport class EntityPersistExecutor {\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(\n protected dataSource: DataSource,\n protected queryRunner: QueryRunner | undefined,\n protected mode: \"save\" | \"remove\" | \"soft-remove\" | \"recover\",\n protected target: Function | string | undefined,\n protected entity: ObjectLiteral | ObjectLiteral[],\n protected options?: SaveOptions & RemoveOptions,\n ) {}\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Executes persistence operation ob given entity or entities.\n */\n async execute(): Promise<void> {\n // check if entity we are going to save is valid and is an object\n if (!this.entity || typeof this.entity !== \"object\")\n return Promise.reject(new MustBeEntityError(this.mode, this.entity))\n\n // we MUST call \"fake\" resolve here to make sure all properties of lazily loaded relations are resolved\n await Promise.resolve()\n\n // if query runner is already defined in this class, it means this entity manager was already created for a single connection\n // if its not defined we create a new query runner - single connection where we'll execute all our operations\n const queryRunner =\n this.queryRunner ?? this.dataSource.createQueryRunner()\n\n // save data in the query runner - this is useful functionality to share data from outside of the world\n // with third classes - like subscribers and listener methods\n const oldQueryRunnerData = queryRunner.data\n if (this.options && this.options.data) {\n queryRunner.data = this.options.data\n }\n\n try {\n // collect all operate subjects\n const entities: ObjectLiteral[] = Array.isArray(this.entity)\n ? this.entity\n : [this.entity]\n const entitiesInChunks =\n this.options && this.options.chunk && this.options.chunk > 0\n ? OrmUtils.chunk(entities, this.options.chunk)\n : [entities]\n\n // console.time(\"building subject executors...\");\n const executors = await Promise.all(\n entitiesInChunks.map(async (entities) => {\n const subjects: Subject[] = []\n\n // create subjects for all entities we received for the persistence\n entities.forEach((entity) => {\n const entityTarget = this.target ?? entity.constructor\n if (entityTarget === Object)\n throw new CannotDetermineEntityError(this.mode)\n\n const metadata = this.dataSource\n .getMetadata(entityTarget)\n .findInheritanceMetadata(entity)\n\n subjects.push(\n new Subject({\n metadata,\n entity: entity,\n canBeInserted: this.mode === \"save\",\n canBeUpdated: this.mode === \"save\",\n mustBeRemoved: this.mode === \"remove\",\n canBeSoftRemoved: this.mode === \"soft-remove\",\n canBeRecovered: this.mode === \"recover\",\n }),\n )\n })\n\n // console.time(\"building cascades...\");\n // go through each entity with metadata and create subjects and subjects by cascades for them\n const cascadesSubjectBuilder = new CascadesSubjectBuilder(\n subjects,\n )\n subjects.forEach((subject) => {\n // next step we build list of subjects we will operate with\n // these subjects are subjects that we need to insert or update alongside with main persisted entity\n cascadesSubjectBuilder.build(subject, this.mode)\n })\n // console.timeEnd(\"building cascades...\");\n\n // load database entities for all subjects we have\n // next step is to load database entities for all operate subjects\n // console.time(\"loading...\");\n await new SubjectDatabaseEntityLoader(\n queryRunner,\n subjects,\n ).load(this.mode)\n // console.timeEnd(\"loading...\");\n\n // console.time(\"other subjects...\");\n // build all related subjects and change maps\n if (\n this.mode === \"save\" ||\n this.mode === \"soft-remove\" ||\n this.mode === \"recover\"\n ) {\n new OneToManySubjectBuilder(subjects).build()\n new OneToOneInverseSideSubjectBuilder(subjects).build()\n new ManyToManySubjectBuilder(subjects).build()\n } else {\n subjects.forEach((subject) => {\n if (subject.mustBeRemoved) {\n new ManyToManySubjectBuilder(\n subjects,\n ).buildForAllRemoval(subject)\n }\n })\n }\n // console.timeEnd(\"other subjects...\");\n // console.timeEnd(\"building subjects...\");\n // console.log(\"subjects\", subjects);\n\n // create a subject executor\n return new SubjectExecutor(\n queryRunner,\n subjects,\n this.options,\n )\n }),\n )\n // console.timeEnd(\"building subject executors...\");\n\n // make sure we have at least one executable operation before we create a transaction and proceed\n // if we don't have operations it means we don't really need to update or remove something\n const executorsWithExecutableOperations = executors.filter(\n (executor) => executor.hasExecutableOperations,\n )\n if (executorsWithExecutableOperations.length === 0) return\n\n // start execute queries in a transaction\n // if transaction is already opened in this query runner then we don't touch it\n // if its not opened yet then we open it here, and once we finish - we close it\n let isTransactionStartedByUs = false\n try {\n // open transaction if its not opened yet\n if (!queryRunner.isTransactionActive) {\n if (\n this.dataSource.driver.transactionSupport !== \"none\" &&\n (!this.options || this.options.transaction !== false)\n ) {\n // start transaction until it was not explicitly disabled\n isTransactionStartedByUs = true\n await queryRunner.startTransaction()\n }\n }\n\n // execute all persistence operations for all entities we have\n // console.time(\"executing subject executors...\");\n for (const executor of executorsWithExecutableOperations) {\n await executor.execute()\n }\n // console.timeEnd(\"executing subject executors...\");\n\n // commit transaction if it was started by us\n // console.time(\"commit\");\n if (isTransactionStartedByUs === true)\n await queryRunner.commitTransaction()\n // console.timeEnd(\"commit\");\n } catch (error) {\n // rollback transaction if it was started by us\n if (isTransactionStartedByUs) {\n try {\n await queryRunner.rollbackTransaction()\n } catch (rollbackError) {}\n }\n throw error\n }\n } finally {\n queryRunner.data = oldQueryRunnerData\n\n // release query runner only if its created by us\n if (!this.queryRunner) await queryRunner.release()\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EntityPersistExecutor.js","sourceRoot":"../build/browser/src/","sources":["persistence/EntityPersistExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport type { SaveOptions } from \"../repository/SaveOptions\"\nimport type { RemoveOptions } from \"../repository/RemoveOptions\"\nimport { MustBeEntityError } from \"../error/MustBeEntityError\"\nimport { SubjectExecutor } from \"./SubjectExecutor\"\nimport { CannotDetermineEntityError } from \"../error/CannotDetermineEntityError\"\nimport type { QueryRunner } from \"../query-runner/QueryRunner\"\nimport type { DataSource } from \"../data-source/DataSource\"\nimport { Subject } from \"./Subject\"\nimport { OneToManySubjectBuilder } from \"./subject-builder/OneToManySubjectBuilder\"\nimport { OneToOneInverseSideSubjectBuilder } from \"./subject-builder/OneToOneInverseSideSubjectBuilder\"\nimport { ManyToManySubjectBuilder } from \"./subject-builder/ManyToManySubjectBuilder\"\nimport { SubjectDatabaseEntityLoader } from \"./SubjectDatabaseEntityLoader\"\nimport { CascadesSubjectBuilder } from \"./subject-builder/CascadesSubjectBuilder\"\nimport { OrmUtils } from \"../util/OrmUtils\"\n\n/**\n * Persists a single entity or multiple entities - saves or removes them.\n */\nexport class EntityPersistExecutor {\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(\n protected dataSource: DataSource,\n protected queryRunner: QueryRunner | undefined,\n protected mode: \"save\" | \"remove\" | \"soft-remove\" | \"recover\",\n protected target: Function | string | undefined,\n protected entity: ObjectLiteral | ObjectLiteral[],\n protected options?: SaveOptions & RemoveOptions,\n ) {}\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Executes persistence operation ob given entity or entities.\n */\n async execute(): Promise<void> {\n // check if entity we are going to save is valid and is an object\n if (!this.entity || typeof this.entity !== \"object\")\n return Promise.reject(new MustBeEntityError(this.mode, this.entity))\n\n // we MUST call \"fake\" resolve here to make sure all properties of lazily loaded relations are resolved\n await Promise.resolve()\n\n // if query runner is already defined in this class, it means this entity manager was already created for a single connection\n // if its not defined we create a new query runner - single connection where we'll execute all our operations\n const queryRunner =\n this.queryRunner ?? this.dataSource.createQueryRunner()\n\n // save data in the query runner - this is useful functionality to share data from outside of the world\n // with third classes - like subscribers and listener methods\n const oldQueryRunnerData = queryRunner.data\n if (this.options?.data) {\n queryRunner.data = this.options.data\n }\n\n try {\n // collect all operate subjects\n const entities: ObjectLiteral[] = Array.isArray(this.entity)\n ? this.entity\n : [this.entity]\n const chunkSize = this.options?.chunk ?? 0\n const entitiesInChunks =\n chunkSize > 0 ? OrmUtils.chunk(entities, chunkSize) : [entities]\n\n const buildExecutor = async (\n entities: ObjectLiteral[],\n ): Promise<SubjectExecutor> => {\n const subjects: Subject[] = []\n\n // create subjects for all entities we received for the persistence\n entities.forEach((entity) => {\n const entityTarget = this.target ?? entity.constructor\n if (entityTarget === Object)\n throw new CannotDetermineEntityError(this.mode)\n\n const metadata = this.dataSource\n .getMetadata(entityTarget)\n .findInheritanceMetadata(entity)\n\n subjects.push(\n new Subject({\n metadata,\n entity: entity,\n canBeInserted: this.mode === \"save\",\n canBeUpdated: this.mode === \"save\",\n mustBeRemoved: this.mode === \"remove\",\n canBeSoftRemoved: this.mode === \"soft-remove\",\n canBeRecovered: this.mode === \"recover\",\n }),\n )\n })\n\n // console.time(\"building cascades...\");\n // go through each entity with metadata and create subjects and subjects by cascades for them\n const cascadesSubjectBuilder = new CascadesSubjectBuilder(\n subjects,\n )\n subjects.forEach((subject) => {\n // next step we build list of subjects we will operate with\n // these subjects are subjects that we need to insert or update alongside with main persisted entity\n cascadesSubjectBuilder.build(subject, this.mode)\n })\n // console.timeEnd(\"building cascades...\");\n\n // load database entities for all subjects we have\n // next step is to load database entities for all operate subjects\n // console.time(\"loading...\");\n await new SubjectDatabaseEntityLoader(\n queryRunner,\n subjects,\n ).load(this.mode)\n // console.timeEnd(\"loading...\");\n\n // console.time(\"other subjects...\");\n // build all related subjects and change maps\n if (\n this.mode === \"save\" ||\n this.mode === \"soft-remove\" ||\n this.mode === \"recover\"\n ) {\n new OneToManySubjectBuilder(subjects).build()\n new OneToOneInverseSideSubjectBuilder(subjects).build()\n new ManyToManySubjectBuilder(subjects).build()\n } else {\n subjects.forEach((subject) => {\n if (subject.mustBeRemoved) {\n new ManyToManySubjectBuilder(\n subjects,\n ).buildForAllRemoval(subject)\n }\n })\n }\n // console.timeEnd(\"other subjects...\");\n // console.timeEnd(\"building subjects...\");\n // console.log(\"subjects\", subjects);\n\n // create a subject executor\n return new SubjectExecutor(queryRunner, subjects, this.options)\n }\n\n // console.time(\"building subject executors...\");\n // Avoid concurrent queries on the same pg client; see #12238.\n // CockroachDB uses the pg package over a single connection too.\n const driverType = this.dataSource.options.type\n let executors: SubjectExecutor[]\n if (driverType === \"postgres\" || driverType === \"cockroachdb\") {\n executors = []\n for (const entities of entitiesInChunks) {\n executors.push(await buildExecutor(entities))\n }\n } else {\n executors = await Promise.all(\n entitiesInChunks.map(buildExecutor),\n )\n }\n // console.timeEnd(\"building subject executors...\");\n\n // make sure we have at least one executable operation before we create a transaction and proceed\n // if we don't have operations it means we don't really need to update or remove something\n const executorsWithExecutableOperations = executors.filter(\n (executor) => executor.hasExecutableOperations,\n )\n if (executorsWithExecutableOperations.length === 0) return\n\n // start execute queries in a transaction\n // if transaction is already opened in this query runner then we don't touch it\n // if its not opened yet then we open it here, and once we finish - we close it\n let isTransactionStartedByUs = false\n try {\n // open transaction if its not opened yet\n if (!queryRunner.isTransactionActive) {\n if (\n this.dataSource.driver.transactionSupport !== \"none\" &&\n this.options?.transaction !== false\n ) {\n // start transaction until it was not explicitly disabled\n isTransactionStartedByUs = true\n await queryRunner.startTransaction()\n }\n }\n\n // execute all persistence operations for all entities we have\n // console.time(\"executing subject executors...\");\n for (const executor of executorsWithExecutableOperations) {\n await executor.execute()\n }\n // console.timeEnd(\"executing subject executors...\");\n\n // commit transaction if it was started by us\n // console.time(\"commit\");\n if (isTransactionStartedByUs === true)\n await queryRunner.commitTransaction()\n // console.timeEnd(\"commit\");\n } catch (error) {\n // rollback transaction if it was started by us\n if (isTransactionStartedByUs) {\n try {\n await queryRunner.rollbackTransaction()\n } catch (rollbackError) {}\n }\n throw error\n }\n } finally {\n queryRunner.data = oldQueryRunnerData\n\n // release query runner only if its created by us\n if (!this.queryRunner) await queryRunner.release()\n }\n }\n}\n"]}
|
|
@@ -30,7 +30,7 @@ class SubjectDatabaseEntityLoader {
|
|
|
30
30
|
async load(operationType) {
|
|
31
31
|
// we are grouping subjects by target to perform more optimized queries using WHERE IN operator
|
|
32
32
|
// go through the groups and perform loading of database entities of each subject in the group
|
|
33
|
-
const
|
|
33
|
+
const loadSubjectGroup = async (subjectGroup) => {
|
|
34
34
|
// prepare entity ids of the subjects we need to load
|
|
35
35
|
const allIds = [];
|
|
36
36
|
const allSubjects = [];
|
|
@@ -82,8 +82,7 @@ class SubjectDatabaseEntityLoader {
|
|
|
82
82
|
};
|
|
83
83
|
// load database entities for all given ids
|
|
84
84
|
let entities;
|
|
85
|
-
if (this.queryRunner.dataSource.driver.options.type ===
|
|
86
|
-
"mongodb") {
|
|
85
|
+
if (this.queryRunner.dataSource.driver.options.type === "mongodb") {
|
|
87
86
|
const mongoRepo = this.queryRunner.manager.getRepository(subjectGroup.target);
|
|
88
87
|
entities = await mongoRepo.findByIds(allIds, findOptions);
|
|
89
88
|
}
|
|
@@ -112,8 +111,19 @@ class SubjectDatabaseEntityLoader {
|
|
|
112
111
|
for (const subject of allSubjects) {
|
|
113
112
|
subject.databaseEntityLoaded = true;
|
|
114
113
|
}
|
|
115
|
-
}
|
|
116
|
-
|
|
114
|
+
};
|
|
115
|
+
const subjectGroups = this.groupByEntityTargets();
|
|
116
|
+
// Avoid concurrent queries on the same pg client; see #12238.
|
|
117
|
+
// CockroachDB uses the pg package over a single connection too.
|
|
118
|
+
const driverType = this.queryRunner.dataSource.options.type;
|
|
119
|
+
if (driverType === "postgres" || driverType === "cockroachdb") {
|
|
120
|
+
for (const subjectGroup of subjectGroups) {
|
|
121
|
+
await loadSubjectGroup(subjectGroup);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await Promise.all(subjectGroups.map(loadSubjectGroup));
|
|
126
|
+
}
|
|
117
127
|
}
|
|
118
128
|
// ---------------------------------------------------------------------
|
|
119
129
|
// Protected Methods
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubjectDatabaseEntityLoader.js","sourceRoot":"../build/browser/src/","sources":["persistence/SubjectDatabaseEntityLoader.ts"],"names":[],"mappings":";;;AAKA,+CAA2C;AAE3C;;;;;GAKG;AACH,MAAa,2BAA2B;IACpC,wEAAwE;IACxE,cAAc;IACd,wEAAwE;IAExE,YACc,WAAwB,EACxB,QAAmB;QADnB,gBAAW,GAAX,WAAW,CAAa;QACxB,aAAQ,GAAR,QAAQ,CAAW;IAC9B,CAAC;IAEJ,wEAAwE;IACxE,iBAAiB;IACjB,wEAAwE;IAExE;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CACN,aAA4D;QAE5D,+FAA+F;QAC/F,8FAA8F;QAC9F,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAC5C,KAAK,EAAE,YAAY,EAAE,EAAE;YACnB,qDAAqD;YACrD,MAAM,MAAM,GAAoB,EAAE,CAAA;YAClC,MAAM,WAAW,GAAc,EAAE,CAAA;YACjC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACtC,gEAAgE;gBAChE,IAAI,OAAO,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,UAAU;oBAAE,OAAM;gBAEzD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBAC/B,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC7B,CAAC,CAAC,CAAA;YAEF,yGAAyG;YACzG,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAM;YAE1B,MAAM,yBAAyB,GAAa,EAAE,CAAA;YAE9C,kDAAkD;YAClD,+EAA+E;YAC/E,sFAAsF;YACtF,sFAAsF;YACtF,6EAA6E;YAC7E,IACI,aAAa,KAAK,MAAM;gBACxB,aAAa,KAAK,aAAa;gBAC/B,aAAa,KAAK,SAAS,EAC7B,CAAC;gBACC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACtC,uEAAuE;oBACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CACjC,OAAO,CAAC,sBAAuB,CAClC,CAAA;wBACD,IAAI,KAAK,KAAK,SAAS;4BAAE,OAAM;wBAE/B,IACI,yBAAyB,CAAC,OAAO,CAC7B,QAAQ,CAAC,YAAY,CACxB,KAAK,CAAC,CAAC;4BAER,yBAAyB,CAAC,IAAI,CAC1B,QAAQ,CAAC,YAAY,CACxB,CAAA;oBACT,CAAC,CAAC,CAAA;gBACN,CAAC,CAAC,CAAA;YACN,CAAC;iBAAM,CAAC;gBACJ,SAAS;gBAET,uBAAuB;gBACvB,qFAAqF;gBACrF,yBAAyB,CAAC,IAAI,CAC1B,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CACxD,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CACtC,CACJ,CAAA;YACL,CAAC;YAED,MAAM,WAAW,GAAyB;gBACtC,kBAAkB,EAAE,KAAK;gBACzB,eAAe,EAAE;oBACb,SAAS,EAAE,yBAAyB;oBACpC,eAAe,EAAE,IAAI;iBACxB;gBACD,+DAA+D;gBAC/D,6DAA6D;gBAC7D,WAAW,EAAE,IAAI;aACpB,CAAA;YAED,2CAA2C;YAC3C,IAAI,QAAe,CAAA;YACnB,IACI,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;gBAC/C,SAAS,EACX,CAAC;gBACC,MAAM,SAAS,GACX,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,CAClC,YAAY,CAAC,MAAM,CACY,CAAA;gBACvC,QAAQ,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;YAC7D,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO;qBACpC,aAAa,CAAgB,YAAY,CAAC,MAAM,CAAC;qBACjD,kBAAkB,EAAE;qBACpB,cAAc,CAAC,WAAW,CAAC;qBAC3B,UAAU,CAAC,MAAM,CAAC;qBAClB,OAAO,EAAE,CAAA;YAClB,CAAC;YAED,mEAAmE;YACnE,qEAAqE;YACrE,gFAAgF;YAChF,6FAA6F;YAC7F,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACxB,MAAM,QAAQ,GACV,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAClD,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC5B,IAAI,OAAO,CAAC,cAAc;wBAAE,OAAM;oBAClC,IAAI,mBAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;wBACjD,OAAO,CAAC,cAAc,GAAG,MAAM,CAAA;gBACvC,CAAC,CAAC,CAAA;YACN,CAAC,CAAC,CAAA;YAEF,uEAAuE;YACvE,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAChC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAA;YACvC,CAAC;QACL,CAAC,CACJ,CAAA;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC;IAED,wEAAwE;IACxE,oBAAoB;IACpB,wEAAwE;IAExE;;OAEG;IACO,oBAAoB;QAI1B,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CACvB,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE;YACvB,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CACnB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,cAAc,CAAC,QAAQ,CAAC,MAAM,CAC7D,CAAA;YACD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,KAAK,GAAG;oBACJ,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM;oBACtC,QAAQ,EAAE,EAAE;iBACf,CAAA;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACnC,OAAO,MAAM,CAAA;QACjB,CAAC,EACD,EAA0D,CAC7D,CAAA;IACL,CAAC;CACJ;AAzKD,kEAyKC","sourcesContent":["import type { Subject } from \"./Subject\"\nimport type { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport type { QueryRunner } from \"../query-runner/QueryRunner\"\nimport type { FindManyOptions } from \"../find-options/FindManyOptions\"\nimport type { MongoRepository } from \"../repository/MongoRepository\"\nimport { OrmUtils } from \"../util/OrmUtils\"\n\n/**\n * Loads database entities for all operate subjects which do not have database entity set.\n * All entities that we load database entities for are marked as updated or inserted.\n * To understand which of them really needs to be inserted or updated we need to load\n * their original representations from the database.\n */\nexport class SubjectDatabaseEntityLoader {\n // ---------------------------------------------------------------------\n // Constructor\n // ---------------------------------------------------------------------\n\n constructor(\n protected queryRunner: QueryRunner,\n protected subjects: Subject[],\n ) {}\n\n // ---------------------------------------------------------------------\n // Public Methods\n // ---------------------------------------------------------------------\n\n /**\n * Loads database entities for all subjects.\n *\n * loadAllRelations flag is used to load all relation ids of the object, no matter if they present in subject entity or not.\n * This option is used for deletion.\n *\n * @param operationType\n */\n async load(\n operationType: \"save\" | \"remove\" | \"soft-remove\" | \"recover\",\n ): Promise<void> {\n // we are grouping subjects by target to perform more optimized queries using WHERE IN operator\n // go through the groups and perform loading of database entities of each subject in the group\n const promises = this.groupByEntityTargets().map(\n async (subjectGroup) => {\n // prepare entity ids of the subjects we need to load\n const allIds: ObjectLiteral[] = []\n const allSubjects: Subject[] = []\n subjectGroup.subjects.forEach((subject) => {\n // we don't load if subject already has a database entity loaded\n if (subject.databaseEntity || !subject.identifier) return\n\n allIds.push(subject.identifier)\n allSubjects.push(subject)\n })\n\n // if there no ids found (means all entities are new and have generated ids) - then nothing to load there\n if (!allIds.length) return\n\n const loadRelationPropertyPaths: string[] = []\n\n // for the save, soft-remove and recover operation\n // extract all property paths of the relations we need to load relation ids for\n // this is for optimization purpose - this way we don't load relation ids for entities\n // whose relations are undefined, and since they are undefined its really pointless to\n // load something for them, since undefined properties are skipped by the orm\n if (\n operationType === \"save\" ||\n operationType === \"soft-remove\" ||\n operationType === \"recover\"\n ) {\n subjectGroup.subjects.forEach((subject) => {\n // gets all relation property paths that exist in the persisted entity.\n subject.metadata.relations.forEach((relation) => {\n const value = relation.getEntityValue(\n subject.entityWithFulfilledIds!,\n )\n if (value === undefined) return\n\n if (\n loadRelationPropertyPaths.indexOf(\n relation.propertyPath,\n ) === -1\n )\n loadRelationPropertyPaths.push(\n relation.propertyPath,\n )\n })\n })\n } else {\n // remove\n\n // for remove operation\n // we only need to load junction relation ids since only they are removed by cascades\n loadRelationPropertyPaths.push(\n ...subjectGroup.subjects[0].metadata.manyToManyRelations.map(\n (relation) => relation.propertyPath,\n ),\n )\n }\n\n const findOptions: FindManyOptions<any> = {\n loadEagerRelations: false,\n loadRelationIds: {\n relations: loadRelationPropertyPaths,\n disableMixedMap: true,\n },\n // include soft-deleted entities so save, soft-remove, recover,\n // and remove can find them by PK and load their relation IDs\n withDeleted: true,\n }\n\n // load database entities for all given ids\n let entities: any[]\n if (\n this.queryRunner.dataSource.driver.options.type ===\n \"mongodb\"\n ) {\n const mongoRepo =\n this.queryRunner.manager.getRepository<ObjectLiteral>(\n subjectGroup.target,\n ) as MongoRepository<ObjectLiteral>\n entities = await mongoRepo.findByIds(allIds, findOptions)\n } else {\n entities = await this.queryRunner.manager\n .getRepository<ObjectLiteral>(subjectGroup.target)\n .createQueryBuilder()\n .setFindOptions(findOptions)\n .whereInIds(allIds)\n .getMany()\n }\n\n // Now when we have entities we need to find subject of each entity\n // and insert that entity into database entity of the found subjects.\n // A single entity can be applied to many subjects as there might be duplicates.\n // This will likely result in the same row being updated multiple times during a transaction.\n entities.forEach((entity) => {\n const entityId =\n allSubjects[0].metadata.getEntityIdMap(entity)\n allSubjects.forEach((subject) => {\n if (subject.databaseEntity) return\n if (OrmUtils.compareIds(subject.identifier, entityId))\n subject.databaseEntity = entity\n })\n })\n\n // this way we tell what subjects we tried to load database entities of\n for (const subject of allSubjects) {\n subject.databaseEntityLoaded = true\n }\n },\n )\n\n await Promise.all(promises)\n }\n\n // ---------------------------------------------------------------------\n // Protected Methods\n // ---------------------------------------------------------------------\n\n /**\n * Groups given Subject objects into groups separated by entity targets.\n */\n protected groupByEntityTargets(): {\n target: Function | string\n subjects: Subject[]\n }[] {\n return this.subjects.reduce(\n (groups, operatedEntity) => {\n let group = groups.find(\n (group) => group.target === operatedEntity.metadata.target,\n )\n if (!group) {\n group = {\n target: operatedEntity.metadata.target,\n subjects: [],\n }\n groups.push(group)\n }\n group.subjects.push(operatedEntity)\n return groups\n },\n [] as { target: Function | string; subjects: Subject[] }[],\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SubjectDatabaseEntityLoader.js","sourceRoot":"../build/browser/src/","sources":["persistence/SubjectDatabaseEntityLoader.ts"],"names":[],"mappings":";;;AAKA,+CAA2C;AAE3C;;;;;GAKG;AACH,MAAa,2BAA2B;IACpC,wEAAwE;IACxE,cAAc;IACd,wEAAwE;IAExE,YACc,WAAwB,EACxB,QAAmB;QADnB,gBAAW,GAAX,WAAW,CAAa;QACxB,aAAQ,GAAR,QAAQ,CAAW;IAC9B,CAAC;IAEJ,wEAAwE;IACxE,iBAAiB;IACjB,wEAAwE;IAExE;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CACN,aAA4D;QAE5D,+FAA+F;QAC/F,8FAA8F;QAC9F,MAAM,gBAAgB,GAAG,KAAK,EAAE,YAG/B,EAAiB,EAAE;YAChB,qDAAqD;YACrD,MAAM,MAAM,GAAoB,EAAE,CAAA;YAClC,MAAM,WAAW,GAAc,EAAE,CAAA;YACjC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACtC,gEAAgE;gBAChE,IAAI,OAAO,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,UAAU;oBAAE,OAAM;gBAEzD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBAC/B,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC7B,CAAC,CAAC,CAAA;YAEF,yGAAyG;YACzG,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAM;YAE1B,MAAM,yBAAyB,GAAa,EAAE,CAAA;YAE9C,kDAAkD;YAClD,+EAA+E;YAC/E,sFAAsF;YACtF,sFAAsF;YACtF,6EAA6E;YAC7E,IACI,aAAa,KAAK,MAAM;gBACxB,aAAa,KAAK,aAAa;gBAC/B,aAAa,KAAK,SAAS,EAC7B,CAAC;gBACC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACtC,uEAAuE;oBACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CACjC,OAAO,CAAC,sBAAuB,CAClC,CAAA;wBACD,IAAI,KAAK,KAAK,SAAS;4BAAE,OAAM;wBAE/B,IACI,yBAAyB,CAAC,OAAO,CAC7B,QAAQ,CAAC,YAAY,CACxB,KAAK,CAAC,CAAC;4BAER,yBAAyB,CAAC,IAAI,CAC1B,QAAQ,CAAC,YAAY,CACxB,CAAA;oBACT,CAAC,CAAC,CAAA;gBACN,CAAC,CAAC,CAAA;YACN,CAAC;iBAAM,CAAC;gBACJ,SAAS;gBAET,uBAAuB;gBACvB,qFAAqF;gBACrF,yBAAyB,CAAC,IAAI,CAC1B,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CACxD,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CACtC,CACJ,CAAA;YACL,CAAC;YAED,MAAM,WAAW,GAAyB;gBACtC,kBAAkB,EAAE,KAAK;gBACzB,eAAe,EAAE;oBACb,SAAS,EAAE,yBAAyB;oBACpC,eAAe,EAAE,IAAI;iBACxB;gBACD,+DAA+D;gBAC/D,6DAA6D;gBAC7D,WAAW,EAAE,IAAI;aACpB,CAAA;YAED,2CAA2C;YAC3C,IAAI,QAAe,CAAA;YACnB,IAAI,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAChE,MAAM,SAAS,GACX,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,CAClC,YAAY,CAAC,MAAM,CACY,CAAA;gBACvC,QAAQ,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;YAC7D,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO;qBACpC,aAAa,CAAgB,YAAY,CAAC,MAAM,CAAC;qBACjD,kBAAkB,EAAE;qBACpB,cAAc,CAAC,WAAW,CAAC;qBAC3B,UAAU,CAAC,MAAM,CAAC;qBAClB,OAAO,EAAE,CAAA;YAClB,CAAC;YAED,mEAAmE;YACnE,qEAAqE;YACrE,gFAAgF;YAChF,6FAA6F;YAC7F,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACxB,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAC/D,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC5B,IAAI,OAAO,CAAC,cAAc;wBAAE,OAAM;oBAClC,IAAI,mBAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;wBACjD,OAAO,CAAC,cAAc,GAAG,MAAM,CAAA;gBACvC,CAAC,CAAC,CAAA;YACN,CAAC,CAAC,CAAA;YAEF,uEAAuE;YACvE,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAChC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAA;YACvC,CAAC;QACL,CAAC,CAAA;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAA;QAEjD,8DAA8D;QAC9D,gEAAgE;QAChE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAA;QAC3D,IAAI,UAAU,KAAK,UAAU,IAAI,UAAU,KAAK,aAAa,EAAE,CAAC;YAC5D,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACvC,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAA;YACxC,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAA;QAC1D,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,oBAAoB;IACpB,wEAAwE;IAExE;;OAEG;IACO,oBAAoB;QAI1B,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CACvB,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE;YACvB,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CACnB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,cAAc,CAAC,QAAQ,CAAC,MAAM,CAC7D,CAAA;YACD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,KAAK,GAAG;oBACJ,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM;oBACtC,QAAQ,EAAE,EAAE;iBACf,CAAA;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACnC,OAAO,MAAM,CAAA;QACjB,CAAC,EACD,EAA0D,CAC7D,CAAA;IACL,CAAC;CACJ;AAjLD,kEAiLC","sourcesContent":["import type { Subject } from \"./Subject\"\nimport type { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport type { QueryRunner } from \"../query-runner/QueryRunner\"\nimport type { FindManyOptions } from \"../find-options/FindManyOptions\"\nimport type { MongoRepository } from \"../repository/MongoRepository\"\nimport { OrmUtils } from \"../util/OrmUtils\"\n\n/**\n * Loads database entities for all operate subjects which do not have database entity set.\n * All entities that we load database entities for are marked as updated or inserted.\n * To understand which of them really needs to be inserted or updated we need to load\n * their original representations from the database.\n */\nexport class SubjectDatabaseEntityLoader {\n // ---------------------------------------------------------------------\n // Constructor\n // ---------------------------------------------------------------------\n\n constructor(\n protected queryRunner: QueryRunner,\n protected subjects: Subject[],\n ) {}\n\n // ---------------------------------------------------------------------\n // Public Methods\n // ---------------------------------------------------------------------\n\n /**\n * Loads database entities for all subjects.\n *\n * loadAllRelations flag is used to load all relation ids of the object, no matter if they present in subject entity or not.\n * This option is used for deletion.\n *\n * @param operationType\n */\n async load(\n operationType: \"save\" | \"remove\" | \"soft-remove\" | \"recover\",\n ): Promise<void> {\n // we are grouping subjects by target to perform more optimized queries using WHERE IN operator\n // go through the groups and perform loading of database entities of each subject in the group\n const loadSubjectGroup = async (subjectGroup: {\n target: Function | string\n subjects: Subject[]\n }): Promise<void> => {\n // prepare entity ids of the subjects we need to load\n const allIds: ObjectLiteral[] = []\n const allSubjects: Subject[] = []\n subjectGroup.subjects.forEach((subject) => {\n // we don't load if subject already has a database entity loaded\n if (subject.databaseEntity || !subject.identifier) return\n\n allIds.push(subject.identifier)\n allSubjects.push(subject)\n })\n\n // if there no ids found (means all entities are new and have generated ids) - then nothing to load there\n if (!allIds.length) return\n\n const loadRelationPropertyPaths: string[] = []\n\n // for the save, soft-remove and recover operation\n // extract all property paths of the relations we need to load relation ids for\n // this is for optimization purpose - this way we don't load relation ids for entities\n // whose relations are undefined, and since they are undefined its really pointless to\n // load something for them, since undefined properties are skipped by the orm\n if (\n operationType === \"save\" ||\n operationType === \"soft-remove\" ||\n operationType === \"recover\"\n ) {\n subjectGroup.subjects.forEach((subject) => {\n // gets all relation property paths that exist in the persisted entity.\n subject.metadata.relations.forEach((relation) => {\n const value = relation.getEntityValue(\n subject.entityWithFulfilledIds!,\n )\n if (value === undefined) return\n\n if (\n loadRelationPropertyPaths.indexOf(\n relation.propertyPath,\n ) === -1\n )\n loadRelationPropertyPaths.push(\n relation.propertyPath,\n )\n })\n })\n } else {\n // remove\n\n // for remove operation\n // we only need to load junction relation ids since only they are removed by cascades\n loadRelationPropertyPaths.push(\n ...subjectGroup.subjects[0].metadata.manyToManyRelations.map(\n (relation) => relation.propertyPath,\n ),\n )\n }\n\n const findOptions: FindManyOptions<any> = {\n loadEagerRelations: false,\n loadRelationIds: {\n relations: loadRelationPropertyPaths,\n disableMixedMap: true,\n },\n // include soft-deleted entities so save, soft-remove, recover,\n // and remove can find them by PK and load their relation IDs\n withDeleted: true,\n }\n\n // load database entities for all given ids\n let entities: any[]\n if (this.queryRunner.dataSource.driver.options.type === \"mongodb\") {\n const mongoRepo =\n this.queryRunner.manager.getRepository<ObjectLiteral>(\n subjectGroup.target,\n ) as MongoRepository<ObjectLiteral>\n entities = await mongoRepo.findByIds(allIds, findOptions)\n } else {\n entities = await this.queryRunner.manager\n .getRepository<ObjectLiteral>(subjectGroup.target)\n .createQueryBuilder()\n .setFindOptions(findOptions)\n .whereInIds(allIds)\n .getMany()\n }\n\n // Now when we have entities we need to find subject of each entity\n // and insert that entity into database entity of the found subjects.\n // A single entity can be applied to many subjects as there might be duplicates.\n // This will likely result in the same row being updated multiple times during a transaction.\n entities.forEach((entity) => {\n const entityId = allSubjects[0].metadata.getEntityIdMap(entity)\n allSubjects.forEach((subject) => {\n if (subject.databaseEntity) return\n if (OrmUtils.compareIds(subject.identifier, entityId))\n subject.databaseEntity = entity\n })\n })\n\n // this way we tell what subjects we tried to load database entities of\n for (const subject of allSubjects) {\n subject.databaseEntityLoaded = true\n }\n }\n\n const subjectGroups = this.groupByEntityTargets()\n\n // Avoid concurrent queries on the same pg client; see #12238.\n // CockroachDB uses the pg package over a single connection too.\n const driverType = this.queryRunner.dataSource.options.type\n if (driverType === \"postgres\" || driverType === \"cockroachdb\") {\n for (const subjectGroup of subjectGroups) {\n await loadSubjectGroup(subjectGroup)\n }\n } else {\n await Promise.all(subjectGroups.map(loadSubjectGroup))\n }\n }\n\n // ---------------------------------------------------------------------\n // Protected Methods\n // ---------------------------------------------------------------------\n\n /**\n * Groups given Subject objects into groups separated by entity targets.\n */\n protected groupByEntityTargets(): {\n target: Function | string\n subjects: Subject[]\n }[] {\n return this.subjects.reduce(\n (groups, operatedEntity) => {\n let group = groups.find(\n (group) => group.target === operatedEntity.metadata.target,\n )\n if (!group) {\n group = {\n target: operatedEntity.metadata.target,\n subjects: [],\n }\n groups.push(group)\n }\n group.subjects.push(operatedEntity)\n return groups\n },\n [] as { target: Function | string; subjects: Subject[] }[],\n )\n }\n}\n"]}
|
|
@@ -65,7 +65,7 @@ class SubjectExecutor {
|
|
|
65
65
|
// console.time("SubjectExecutor.execute");
|
|
66
66
|
// broadcast "before" events before we start insert / update / remove operations
|
|
67
67
|
let broadcasterResult = undefined;
|
|
68
|
-
if (
|
|
68
|
+
if (this.options?.listeners !== false) {
|
|
69
69
|
// console.time(".broadcastBeforeEventsForAll");
|
|
70
70
|
broadcasterResult = this.broadcastBeforeEventsForAll();
|
|
71
71
|
if (broadcasterResult.promises.length > 0)
|
|
@@ -116,7 +116,7 @@ class SubjectExecutor {
|
|
|
116
116
|
this.updateSpecialColumnsInPersistedEntities();
|
|
117
117
|
// console.timeEnd(".updateSpecialColumnsInPersistedEntities");
|
|
118
118
|
// finally broadcast "after" events after we finish insert / update / remove operations
|
|
119
|
-
if (
|
|
119
|
+
if (this.options?.listeners !== false) {
|
|
120
120
|
// console.time(".broadcastAfterEventsForAll");
|
|
121
121
|
broadcasterResult = this.broadcastAfterEventsForAll();
|
|
122
122
|
if (broadcasterResult.promises.length > 0)
|
|
@@ -262,9 +262,7 @@ class SubjectExecutor {
|
|
|
262
262
|
.insert()
|
|
263
263
|
.into(subjects[0].metadata.target)
|
|
264
264
|
.values(bulkInsertMaps)
|
|
265
|
-
.updateEntity(this.options
|
|
266
|
-
? false
|
|
267
|
-
: true)
|
|
265
|
+
.updateEntity(this.options?.reload !== false)
|
|
268
266
|
.callListeners(false)
|
|
269
267
|
.execute();
|
|
270
268
|
bulkInsertSubjects.forEach((subject, index) => {
|
|
@@ -286,9 +284,7 @@ class SubjectExecutor {
|
|
|
286
284
|
.insert()
|
|
287
285
|
.into(subject.metadata.target)
|
|
288
286
|
.values(subject.insertedValueSet)
|
|
289
|
-
.updateEntity(this.options
|
|
290
|
-
? false
|
|
291
|
-
: true)
|
|
287
|
+
.updateEntity(this.options?.reload !== false)
|
|
292
288
|
.callListeners(false)
|
|
293
289
|
.execute()
|
|
294
290
|
.then((insertResult) => {
|
|
@@ -363,9 +359,7 @@ class SubjectExecutor {
|
|
|
363
359
|
.createQueryBuilder()
|
|
364
360
|
.update(subject.metadata.target)
|
|
365
361
|
.set(updateMap)
|
|
366
|
-
.updateEntity(this.options
|
|
367
|
-
? false
|
|
368
|
-
: true)
|
|
362
|
+
.updateEntity(this.options?.reload !== false)
|
|
369
363
|
.callListeners(false);
|
|
370
364
|
if (subject.entity) {
|
|
371
365
|
updateQueryBuilder.whereEntity(subject.identifier);
|
|
@@ -407,11 +401,21 @@ class SubjectExecutor {
|
|
|
407
401
|
await updateSubject(subject);
|
|
408
402
|
}
|
|
409
403
|
};
|
|
410
|
-
//
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
404
|
+
// Avoid concurrent queries on the same pg client; see #12238.
|
|
405
|
+
// CockroachDB uses the pg package over a single connection too.
|
|
406
|
+
const driverType = this.queryRunner.dataSource.options.type;
|
|
407
|
+
if (driverType === "postgres" || driverType === "cockroachdb") {
|
|
408
|
+
for (const subject of remainingSubjects) {
|
|
409
|
+
await updateSubject(subject);
|
|
410
|
+
}
|
|
411
|
+
await updateNestSetSubjects();
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
await Promise.all([
|
|
415
|
+
...remainingSubjects.map(updateSubject),
|
|
416
|
+
updateNestSetSubjects(),
|
|
417
|
+
]);
|
|
418
|
+
}
|
|
415
419
|
}
|
|
416
420
|
/**
|
|
417
421
|
* Removes all given subjects from the database.
|
|
@@ -470,7 +474,7 @@ class SubjectExecutor {
|
|
|
470
474
|
* Soft-removes all given subjects in the database.
|
|
471
475
|
*/
|
|
472
476
|
async executeSoftRemoveOperations() {
|
|
473
|
-
|
|
477
|
+
const softRemoveSubject = async (subject) => {
|
|
474
478
|
if (!subject.identifier)
|
|
475
479
|
throw new SubjectWithoutIdentifierError_1.SubjectWithoutIdentifierError(subject);
|
|
476
480
|
let updateResult;
|
|
@@ -489,8 +493,7 @@ class SubjectExecutor {
|
|
|
489
493
|
if (subject.metadata.deleteDateColumn?.propertyName) {
|
|
490
494
|
partialEntity[subject.metadata.deleteDateColumn.propertyName] = new Date();
|
|
491
495
|
}
|
|
492
|
-
const manager = this.queryRunner
|
|
493
|
-
.manager;
|
|
496
|
+
const manager = this.queryRunner.manager;
|
|
494
497
|
updateResult = await manager.update(subject.metadata.target, subject.identifier, partialEntity);
|
|
495
498
|
}
|
|
496
499
|
else {
|
|
@@ -502,9 +505,7 @@ class SubjectExecutor {
|
|
|
502
505
|
.createQueryBuilder()
|
|
503
506
|
.softDelete()
|
|
504
507
|
.from(subject.metadata.target)
|
|
505
|
-
.updateEntity(this.options
|
|
506
|
-
? false
|
|
507
|
-
: true)
|
|
508
|
+
.updateEntity(this.options?.reload !== false)
|
|
508
509
|
.callListeners(false);
|
|
509
510
|
if (subject.entity) {
|
|
510
511
|
softDeleteQueryBuilder.whereEntity(subject.identifier);
|
|
@@ -536,13 +537,24 @@ class SubjectExecutor {
|
|
|
536
537
|
// }
|
|
537
538
|
// }));
|
|
538
539
|
// }
|
|
539
|
-
}
|
|
540
|
+
};
|
|
541
|
+
// Avoid concurrent queries on the same pg client; see #12238.
|
|
542
|
+
// CockroachDB uses the pg package over a single connection too.
|
|
543
|
+
const driverType = this.queryRunner.dataSource.options.type;
|
|
544
|
+
if (driverType === "postgres" || driverType === "cockroachdb") {
|
|
545
|
+
for (const subject of this.softRemoveSubjects) {
|
|
546
|
+
await softRemoveSubject(subject);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
await Promise.all(this.softRemoveSubjects.map(softRemoveSubject));
|
|
551
|
+
}
|
|
540
552
|
}
|
|
541
553
|
/**
|
|
542
554
|
* Recovers all given subjects in the database.
|
|
543
555
|
*/
|
|
544
556
|
async executeRecoverOperations() {
|
|
545
|
-
|
|
557
|
+
const recoverSubject = async (subject) => {
|
|
546
558
|
if (!subject.identifier)
|
|
547
559
|
throw new SubjectWithoutIdentifierError_1.SubjectWithoutIdentifierError(subject);
|
|
548
560
|
let updateResult;
|
|
@@ -561,8 +573,7 @@ class SubjectExecutor {
|
|
|
561
573
|
if (subject.metadata.deleteDateColumn?.propertyName) {
|
|
562
574
|
partialEntity[subject.metadata.deleteDateColumn.propertyName] = null;
|
|
563
575
|
}
|
|
564
|
-
const manager = this.queryRunner
|
|
565
|
-
.manager;
|
|
576
|
+
const manager = this.queryRunner.manager;
|
|
566
577
|
updateResult = await manager.update(subject.metadata.target, subject.identifier, partialEntity);
|
|
567
578
|
}
|
|
568
579
|
else {
|
|
@@ -574,9 +585,7 @@ class SubjectExecutor {
|
|
|
574
585
|
.createQueryBuilder()
|
|
575
586
|
.restore()
|
|
576
587
|
.from(subject.metadata.target)
|
|
577
|
-
.updateEntity(this.options
|
|
578
|
-
? false
|
|
579
|
-
: true)
|
|
588
|
+
.updateEntity(this.options?.reload !== false)
|
|
580
589
|
.callListeners(false);
|
|
581
590
|
if (subject.entity) {
|
|
582
591
|
softDeleteQueryBuilder.whereEntity(subject.identifier);
|
|
@@ -608,7 +617,18 @@ class SubjectExecutor {
|
|
|
608
617
|
// }
|
|
609
618
|
// }));
|
|
610
619
|
// }
|
|
611
|
-
}
|
|
620
|
+
};
|
|
621
|
+
// Avoid concurrent queries on the same pg client; see #12238.
|
|
622
|
+
// CockroachDB uses the pg package over a single connection too.
|
|
623
|
+
const driverType = this.queryRunner.dataSource.options.type;
|
|
624
|
+
if (driverType === "postgres" || driverType === "cockroachdb") {
|
|
625
|
+
for (const subject of this.recoverSubjects) {
|
|
626
|
+
await recoverSubject(subject);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
await Promise.all(this.recoverSubjects.map(recoverSubject));
|
|
631
|
+
}
|
|
612
632
|
}
|
|
613
633
|
/**
|
|
614
634
|
* Updates all special columns of the saving entities (create date, update date, version, etc.).
|