@itwin/imodel-transformer 2.0.0-dev.7 → 2.0.0-dev.71
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 +13 -27
- package/lib/cjs/Algo.d.ts +0 -4
- package/lib/cjs/Algo.d.ts.map +1 -1
- package/lib/cjs/Algo.js +0 -11
- package/lib/cjs/Algo.js.map +1 -1
- package/lib/cjs/BigMap.d.ts.map +1 -1
- package/lib/cjs/BigMap.js.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.js +26 -26
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/ChangedElementForest.d.ts +14 -0
- package/lib/cjs/ChangedElementForest.d.ts.map +1 -0
- package/lib/cjs/ChangedElementForest.js +86 -0
- package/lib/cjs/ChangedElementForest.js.map +1 -0
- package/lib/cjs/ChangesetScanner.d.ts +141 -0
- package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
- package/lib/cjs/ChangesetScanner.js +187 -0
- package/lib/cjs/ChangesetScanner.js.map +1 -0
- package/lib/cjs/ECReferenceTypesCache.d.ts +0 -4
- package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.js +61 -111
- package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
- package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
- package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
- package/lib/cjs/ElementAspectCleanup.js +87 -0
- package/lib/cjs/ElementAspectCleanup.js.map +1 -0
- package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
- package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
- package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
- package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
- package/lib/cjs/ElementAspectExportProcessor.d.ts +44 -0
- package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
- package/lib/cjs/ElementAspectExportProcessor.js +152 -0
- package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
- package/lib/cjs/ElementBulkDelete.d.ts +30 -0
- package/lib/cjs/ElementBulkDelete.d.ts.map +1 -0
- package/lib/cjs/ElementBulkDelete.js +358 -0
- package/lib/cjs/ElementBulkDelete.js.map +1 -0
- package/lib/cjs/EntityExistenceCache.d.ts +43 -0
- package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
- package/lib/cjs/EntityExistenceCache.js +91 -0
- package/lib/cjs/EntityExistenceCache.js.map +1 -0
- package/lib/cjs/EntityUnifier.d.ts +7 -7
- package/lib/cjs/EntityUnifier.d.ts.map +1 -1
- package/lib/cjs/EntityUnifier.js +55 -24
- package/lib/cjs/EntityUnifier.js.map +1 -1
- package/lib/cjs/IModelCloneContext.d.ts +9 -3
- package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
- package/lib/cjs/IModelCloneContext.js +56 -22
- package/lib/cjs/IModelCloneContext.js.map +1 -1
- package/lib/cjs/IModelExporter.d.ts +180 -43
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +946 -247
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelImporter.d.ts +75 -30
- package/lib/cjs/IModelImporter.d.ts.map +1 -1
- package/lib/cjs/IModelImporter.js +292 -132
- package/lib/cjs/IModelImporter.js.map +1 -1
- package/lib/cjs/IModelTransformContext.d.ts +54 -0
- package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
- package/lib/cjs/IModelTransformContext.js +3 -0
- package/lib/cjs/IModelTransformContext.js.map +1 -0
- package/lib/cjs/IModelTransformer.d.ts +184 -206
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +819 -1278
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/lib/cjs/IModelTransformerError.d.ts +84 -0
- package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
- package/lib/cjs/IModelTransformerError.js +93 -0
- package/lib/cjs/IModelTransformerError.js.map +1 -0
- package/lib/cjs/ProvenanceManager.d.ts +177 -0
- package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
- package/lib/cjs/ProvenanceManager.js +719 -0
- package/lib/cjs/ProvenanceManager.js.map +1 -0
- package/lib/cjs/SourceClassKinds.d.ts +22 -0
- package/lib/cjs/SourceClassKinds.d.ts.map +1 -0
- package/lib/cjs/SourceClassKinds.js +60 -0
- package/lib/cjs/SourceClassKinds.js.map +1 -0
- package/lib/cjs/SyncTypeResolver.d.ts +32 -0
- package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
- package/lib/cjs/SyncTypeResolver.js +92 -0
- package/lib/cjs/SyncTypeResolver.js.map +1 -0
- package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
- package/lib/cjs/TransformerLoggerCategory.js +1 -1
- package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
- package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
- package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
- package/lib/cjs/TransformerPackageMetadata.js +47 -0
- package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
- package/lib/cjs/imodel-transformer.d.ts +28 -0
- package/lib/cjs/imodel-transformer.d.ts.map +1 -1
- package/lib/cjs/imodel-transformer.js +61 -34
- package/lib/cjs/imodel-transformer.js.map +1 -1
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
- package/lib/cjs/schema-processing.d.ts +7 -0
- package/lib/cjs/schema-processing.d.ts.map +1 -0
- package/lib/cjs/schema-processing.js +27 -0
- package/lib/cjs/schema-processing.js.map +1 -0
- package/package.json +70 -57
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
- package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
- package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
- package/lib/cjs/ElementCascadingDeleter.d.ts +0 -22
- package/lib/cjs/ElementCascadingDeleter.d.ts.map +0 -1
- package/lib/cjs/ElementCascadingDeleter.js +0 -57
- package/lib/cjs/ElementCascadingDeleter.js.map +0 -1
- package/lib/cjs/EntityMap.d.ts +0 -26
- package/lib/cjs/EntityMap.d.ts.map +0 -1
- package/lib/cjs/EntityMap.js +0 -54
- package/lib/cjs/EntityMap.js.map +0 -1
- package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
- package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
- package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
- package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
|
@@ -11,8 +11,9 @@ exports.ECReferenceTypesCache = exports.SchemaNotInCacheErr = void 0;
|
|
|
11
11
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
12
12
|
const core_common_1 = require("@itwin/core-common");
|
|
13
13
|
const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
|
|
14
|
-
const
|
|
14
|
+
const node_assert_1 = require("node:assert");
|
|
15
15
|
const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
|
|
16
|
+
const IModelTransformerError_1 = require("./IModelTransformerError");
|
|
16
17
|
/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
|
|
17
18
|
* @internal
|
|
18
19
|
*/
|
|
@@ -35,12 +36,7 @@ class ECReferenceTypesCache {
|
|
|
35
36
|
_propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
|
|
36
37
|
_relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
|
|
37
38
|
_initedSchemas = new Map();
|
|
38
|
-
// Performance optimization caches
|
|
39
|
-
_rootBisClassCache = new Map();
|
|
40
|
-
_relationshipInfoCache = new Map();
|
|
41
|
-
_constraintClassCache = new Map();
|
|
42
39
|
static bisRootClassToRefType = {
|
|
43
|
-
/* eslint-disable quote-props, @typescript-eslint/naming-convention */
|
|
44
40
|
Element: core_common_1.ConcreteEntityTypes.Element,
|
|
45
41
|
Model: core_common_1.ConcreteEntityTypes.Model,
|
|
46
42
|
ElementAspect: core_common_1.ConcreteEntityTypes.ElementAspect,
|
|
@@ -48,14 +44,8 @@ class ECReferenceTypesCache {
|
|
|
48
44
|
ElementDrivesElement: core_common_1.ConcreteEntityTypes.Relationship,
|
|
49
45
|
// code spec is technically a potential root class but it is ignored currently
|
|
50
46
|
// see [ConcreteEntityTypes]($common)
|
|
51
|
-
/* eslint-enable quote-props, @typescript-eslint/naming-convention */
|
|
52
47
|
};
|
|
53
48
|
async getRootBisClass(ecclass) {
|
|
54
|
-
const cacheKey = ecclass.fullName;
|
|
55
|
-
const cached = this._rootBisClassCache.get(cacheKey);
|
|
56
|
-
if (cached) {
|
|
57
|
-
return cached;
|
|
58
|
-
}
|
|
59
49
|
let bisRootForConstraint = ecclass;
|
|
60
50
|
await ecclass.traverseBaseClasses((baseClass) => {
|
|
61
51
|
// The depth first traversal will descend all the way to the root class before making any lateral traversal
|
|
@@ -71,68 +61,54 @@ class ECReferenceTypesCache {
|
|
|
71
61
|
});
|
|
72
62
|
// if the root class of the constraint was a mixin, use its AppliesToEntityClass
|
|
73
63
|
if (bisRootForConstraint instanceof ecschema_metadata_1.Mixin) {
|
|
74
|
-
|
|
64
|
+
(0, node_assert_1.strict)(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
|
|
75
65
|
bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
|
|
76
66
|
}
|
|
77
|
-
this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
|
|
78
67
|
return bisRootForConstraint;
|
|
79
68
|
}
|
|
80
69
|
async getAbstractConstraintClass(constraint) {
|
|
81
|
-
const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || "abstract"}`;
|
|
82
|
-
const cached = this._constraintClassCache.get(cacheKey);
|
|
83
|
-
if (cached) {
|
|
84
|
-
return cached;
|
|
85
|
-
}
|
|
86
70
|
// constraint classes must share a base so we can get the root from any of them, just use the first
|
|
87
71
|
const ecclass = await (constraint.constraintClasses?.[0] ||
|
|
88
72
|
constraint.abstractConstraint);
|
|
89
|
-
|
|
90
|
-
this._constraintClassCache.set(cacheKey, ecclass);
|
|
73
|
+
(0, node_assert_1.strict)(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
|
|
91
74
|
return ecclass;
|
|
92
75
|
}
|
|
93
76
|
/** initialize from an imodel with metadata */
|
|
94
77
|
async initAllSchemasInIModel(imodel) {
|
|
95
|
-
let totalSchemaCount = 0;
|
|
96
|
-
let schemaCompletedCount = 0;
|
|
97
|
-
const initStartTime = performance.now();
|
|
98
78
|
const query = `
|
|
99
79
|
WITH RECURSIVE refs(SchemaId) AS (
|
|
100
80
|
SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
|
|
101
|
-
UNION
|
|
81
|
+
UNION
|
|
102
82
|
SELECT sr.SourceECInstanceId
|
|
103
83
|
FROM ECDbMeta.SchemaHasSchemaReferences sr
|
|
104
84
|
JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
|
|
105
85
|
)
|
|
106
|
-
SELECT
|
|
86
|
+
SELECT s.Name as name
|
|
107
87
|
FROM refs
|
|
108
88
|
JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
|
|
109
|
-
-- ensure schema dependency order
|
|
110
|
-
ORDER BY s.ECInstanceId
|
|
111
89
|
`;
|
|
112
|
-
for await (const row of imodel.createQueryReader(query
|
|
90
|
+
for await (const row of imodel.createQueryReader(query, undefined, {
|
|
91
|
+
usePrimaryConn: true,
|
|
92
|
+
})) {
|
|
113
93
|
const schemaName = row.name;
|
|
114
|
-
const startTime = performance.now();
|
|
115
|
-
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
|
|
116
94
|
const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
|
|
117
95
|
const schema = await imodel.schemaContext.getSchema(schemaItemKey);
|
|
118
|
-
if (schema) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
96
|
+
if (!schema) {
|
|
97
|
+
core_bentley_1.ITwinError.throwError({
|
|
98
|
+
iTwinErrorId: {
|
|
99
|
+
scope: IModelTransformerError_1.IModelTransformerErrorScope,
|
|
100
|
+
key: IModelTransformerError_1.IModelTransformerError.SchemaLoadFailed,
|
|
101
|
+
},
|
|
102
|
+
message: `Failed to load schema: ${schemaName}`,
|
|
103
|
+
});
|
|
126
104
|
}
|
|
127
|
-
|
|
105
|
+
await this.considerInitSchema(schema);
|
|
128
106
|
}
|
|
129
|
-
const initEndTime = performance.now();
|
|
130
|
-
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`);
|
|
131
107
|
}
|
|
132
108
|
async considerInitSchema(schema) {
|
|
133
109
|
if (this._initedSchemas.has(schema.name)) {
|
|
134
110
|
const cachedSchemaKey = this._initedSchemas.get(schema.name);
|
|
135
|
-
|
|
111
|
+
(0, node_assert_1.strict)(cachedSchemaKey !== undefined);
|
|
136
112
|
const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;
|
|
137
113
|
if (incomingSchemaIsEqualOrOlder) {
|
|
138
114
|
return;
|
|
@@ -141,73 +117,55 @@ class ECReferenceTypesCache {
|
|
|
141
117
|
return this.initSchema(schema);
|
|
142
118
|
}
|
|
143
119
|
async initSchema(schema) {
|
|
144
|
-
core_bentley_1.Logger.
|
|
120
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema started for ${schema.name}`);
|
|
145
121
|
const schemaNameLower = schema.name.toLowerCase();
|
|
146
|
-
//
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (!ecschema_metadata_1.ECClass.isECClass(item))
|
|
154
|
-
continue;
|
|
155
|
-
ecClasses.push(item);
|
|
156
|
-
if (item instanceof ecschema_metadata_1.RelationshipClass) {
|
|
157
|
-
relationshipClasses.push(item);
|
|
122
|
+
// Local dedup map — scoped to this single initSchema call, not persisted
|
|
123
|
+
const localRelInfoMap = new Map();
|
|
124
|
+
const getRelInfo = async (relClass) => {
|
|
125
|
+
let promise = localRelInfoMap.get(relClass.fullName);
|
|
126
|
+
if (!promise) {
|
|
127
|
+
promise = this.relInfoFromRelClass(relClass);
|
|
128
|
+
localRelInfoMap.set(relClass.fullName, promise);
|
|
158
129
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
130
|
+
return promise;
|
|
131
|
+
};
|
|
132
|
+
// Process all classes concurrently
|
|
133
|
+
const classPromises = Array.from(schema.getItems())
|
|
134
|
+
.filter((item) => ecschema_metadata_1.ECClass.isECClass(item))
|
|
135
|
+
.map(async (ecclass) => {
|
|
136
|
+
// Handle relationship end types
|
|
137
|
+
if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
|
|
138
|
+
const relInfo = await getRelInfo(ecclass);
|
|
139
|
+
if (relInfo) {
|
|
140
|
+
this._relClassNameEndToRefTypes.set([schemaNameLower, ecclass.name.toLowerCase()], relInfo);
|
|
141
|
+
}
|
|
166
142
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const classBatch = ecClasses.slice(i, i + propertyBatchSize);
|
|
175
|
-
const classPromises = classBatch.map(async (ecclass) => {
|
|
176
|
-
const properties = await ecclass.getProperties();
|
|
177
|
-
if (!properties)
|
|
143
|
+
// Handle nav props
|
|
144
|
+
const properties = await ecclass.getProperties();
|
|
145
|
+
const classNameLower = ecclass.name.toLowerCase();
|
|
146
|
+
const navPropPromises = Array.from(properties)
|
|
147
|
+
.filter((prop) => prop.isNavigation())
|
|
148
|
+
.map(async (prop) => {
|
|
149
|
+
if (!prop.isNavigation())
|
|
178
150
|
return;
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (navProps.length === 0)
|
|
151
|
+
const relClass = await prop.relationshipClass;
|
|
152
|
+
const relInfo = await getRelInfo(relClass);
|
|
153
|
+
if (relInfo === undefined)
|
|
183
154
|
return;
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (relInfo === undefined &&
|
|
189
|
-
!this._relationshipInfoCache.has(relClass.fullName)) {
|
|
190
|
-
relInfo = await this.relInfoFromRelClass(relClass);
|
|
191
|
-
this._relationshipInfoCache.set(relClass.fullName, relInfo);
|
|
192
|
-
}
|
|
193
|
-
if (relInfo === undefined)
|
|
194
|
-
return;
|
|
195
|
-
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
196
|
-
? // eslint-disable-next-line @itwin/no-internal
|
|
197
|
-
relInfo.target
|
|
198
|
-
: // eslint-disable-next-line @itwin/no-internal
|
|
199
|
-
relInfo.source;
|
|
200
|
-
this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
|
|
201
|
-
});
|
|
202
|
-
await Promise.all(navPropPromises);
|
|
155
|
+
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
156
|
+
? relInfo.target
|
|
157
|
+
: relInfo.source;
|
|
158
|
+
this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
|
|
203
159
|
});
|
|
204
|
-
await Promise.all(
|
|
205
|
-
}
|
|
160
|
+
await Promise.all(navPropPromises);
|
|
161
|
+
});
|
|
162
|
+
await Promise.all(classPromises);
|
|
206
163
|
this._initedSchemas.set(schema.name, schema.schemaKey);
|
|
164
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema completed for ${schema.name}`);
|
|
207
165
|
}
|
|
208
166
|
async relInfoFromRelClass(ecclass) {
|
|
209
|
-
|
|
210
|
-
|
|
167
|
+
(0, node_assert_1.strict)(ecclass.source.constraintClasses !== undefined);
|
|
168
|
+
(0, node_assert_1.strict)(ecclass.target.constraintClasses !== undefined);
|
|
211
169
|
const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass],] = await Promise.all([
|
|
212
170
|
this.getAbstractConstraintClass(ecclass.source).then(async (constraintClass) => [
|
|
213
171
|
constraintClass,
|
|
@@ -236,8 +194,8 @@ class ECReferenceTypesCache {
|
|
|
236
194
|
`the nav prop reference type cache for ${cls.fullName}.`,
|
|
237
195
|
"This is a bug.",
|
|
238
196
|
].join("\n");
|
|
239
|
-
|
|
240
|
-
|
|
197
|
+
(0, node_assert_1.strict)(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
|
|
198
|
+
(0, node_assert_1.strict)(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
|
|
241
199
|
return { source: sourceType, target: targetType };
|
|
242
200
|
}
|
|
243
201
|
getNavPropRefType(schemaName, className, propName) {
|
|
@@ -257,14 +215,6 @@ class ECReferenceTypesCache {
|
|
|
257
215
|
className.toLowerCase(),
|
|
258
216
|
]);
|
|
259
217
|
}
|
|
260
|
-
clear() {
|
|
261
|
-
this._initedSchemas.clear();
|
|
262
|
-
this._propQualifierToRefType.clear();
|
|
263
|
-
this._relClassNameEndToRefTypes.clear();
|
|
264
|
-
this._rootBisClassCache.clear();
|
|
265
|
-
this._relationshipInfoCache.clear();
|
|
266
|
-
this._constraintClassCache.clear();
|
|
267
|
-
}
|
|
268
218
|
}
|
|
269
219
|
exports.ECReferenceTypesCache = ECReferenceTypesCache;
|
|
270
220
|
//# sourceMappingURL=ECReferenceTypesCache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\n\nimport { Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport * as assert from \"assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n // Performance optimization caches\n private _rootBisClassCache = new Map<string, ECClass>();\n private _relationshipInfoCache = new Map<string, RelTypeInfo | undefined>();\n private _constraintClassCache = new Map<string, ECClass>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n /* eslint-disable quote-props, @typescript-eslint/naming-convention */\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n /* eslint-enable quote-props, @typescript-eslint/naming-convention */\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n const cacheKey = ecclass.fullName;\n const cached = this._rootBisClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n\n this._rootBisClassCache.set(cacheKey, bisRootForConstraint);\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || \"abstract\"}`;\n const cached = this._constraintClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n\n this._constraintClassCache.set(cacheKey, ecclass);\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n let totalSchemaCount = 0;\n let schemaCompletedCount = 0;\n\n const initStartTime = performance.now();\n\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION ALL\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT DISTINCT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n -- ensure schema dependency order\n ORDER BY s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query)) {\n const schemaName = row.name;\n const startTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Loading schema: ${schemaName}`\n );\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (schema) {\n await this.considerInitSchema(schema);\n const endTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`\n );\n schemaCompletedCount++;\n } else {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Did not load schema: ${schemaName}`\n );\n }\n\n totalSchemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`\n );\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Init Schema: ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Pre-collect all items to reduce iterator overhead\n const allItems = Array.from(schema.getItems());\n const ecClasses: ECClass[] = [];\n const relationshipClasses: RelationshipClass[] = [];\n\n // Single pass through items with type checking\n for (const item of allItems) {\n // eslint-disable-next-line @itwin/no-internal\n if (!ECClass.isECClass(item)) continue;\n ecClasses.push(item);\n if (item instanceof RelationshipClass) {\n relationshipClasses.push(item);\n }\n }\n\n // Process relationship classes in parallel and populate global cache\n const relInfoPromises = relationshipClasses.map(async (relClass) => {\n const relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, relClass.name.toLowerCase()],\n relInfo\n );\n }\n return relInfo;\n });\n\n // Wait for all relationship info to be cached\n await Promise.all(relInfoPromises);\n\n // Process navigation properties with optimized batching\n const propertyBatchSize = 25;\n for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {\n const classBatch = ecClasses.slice(i, i + propertyBatchSize);\n\n const classPromises = classBatch.map(async (ecclass) => {\n const properties = await ecclass.getProperties();\n if (!properties) return;\n\n const classNameLower = ecclass.name.toLowerCase();\n\n // Efficiently filter navigation properties\n const navProps = Array.from(properties).filter((prop) =>\n prop.isNavigation()\n );\n if (navProps.length === 0) return;\n\n const navPropPromises = navProps.map(async (prop) => {\n const relClass = await prop.relationshipClass;\n\n // Use cached relation info\n let relInfo = this._relationshipInfoCache.get(relClass.fullName);\n if (\n relInfo === undefined &&\n !this._relationshipInfoCache.has(relClass.fullName)\n ) {\n relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n }\n\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? // eslint-disable-next-line @itwin/no-internal\n relInfo.target\n : // eslint-disable-next-line @itwin/no-internal\n relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n\n public clear() {\n this._initedSchemas.clear();\n this._propQualifierToRefType.clear();\n this._relClassNameEndToRefTypes.clear();\n this._rootBisClassCache.clear();\n this._relationshipInfoCache.clear();\n this._constraintClassCache.clear();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;GAEG;;;AAEH,sDAAwE;AACxE,oDAAsE;AACtE,gEASkC;AAClC,6CAA+C;AAE/C,2EAAwE;AACxE,qEAGkC;AAElC;;GAEG;AACH,yBAAiC,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC3D,CAAC;CACF;;AAED;;;;;;;GAOG;AACH;IACE,uGAAuG;IAC/F,uBAAuB,GAAG,IAAI,4BAAa,EAGhD,CAAC;IACI,0BAA0B,GAAG,IAAI,4BAAa,EAGnD,CAAC;IACI,cAAc,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE9C,MAAM,CAAC,qBAAqB,GAGhC;QACF,OAAO,EAAE,iCAAmB,CAAC,OAAO;QACpC,KAAK,EAAE,iCAAmB,CAAC,KAAK;QAChC,aAAa,EAAE,iCAAmB,CAAC,aAAa;QAChD,uBAAuB,EAAE,iCAAmB,CAAC,YAAY;QACzD,oBAAoB,EAAE,iCAAmB,CAAC,YAAY;QACtD,8EAA8E;QAC9E,qCAAqC;KACtC,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,OAAgB;QAC5C,IAAI,oBAAoB,GAAY,OAAO,CAAC;QAC5C,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,SAAS,EAAE,EAAE;YAC9C,2GAA2G;YAC3G,+GAA+G;YAC/G,iEAAiE;YACjE,MAAM,WAAW,GAAG,oBAAoB,KAAK,OAAO,CAAC;YACrD,MAAM,yBAAyB,GAC7B,SAAS,CAAC,IAAI,KAAK,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC;YAC1D,MAAM,uBAAuB,GAAG,WAAW,IAAI,CAAC,yBAAyB,CAAC;YAC1E,IAAI,CAAC,uBAAuB;gBAAE,OAAO,IAAI,CAAC,CAAC,uBAAuB;YAClE,oBAAoB,GAAG,SAAS,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,gFAAgF;QAChF,IAAI,oBAAoB,YAAY,yBAAK,EAAE,CAAC;YAC1C,IAAA,oBAAM,EACJ,oBAAoB,CAAC,SAAS,KAAK,SAAS,EAC5C,4FAA4F,CAC7F,CAAC;YACF,oBAAoB,GAAG,MAAM,IAAI,CAAC,eAAe,CAC/C,MAAM,oBAAoB,CAAC,SAAS,CACrC,CAAC;QACJ,CAAC;QACD,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,0BAA0B,CACtC,UAAkC;QAElC,mGAAmG;QACnG,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACtD,UAAU,CAAC,kBAAkB,CAAC,CAAC;QACjC,IAAA,oBAAM,EACJ,OAAO,KAAK,SAAS,EACrB,6GAA6G,CAC9G,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,8CAA8C;IACvC,KAAK,CAAC,sBAAsB,CAAC,MAAgB;QAClD,MAAM,KAAK,GAAG;;;;;;;;;;;KAWb,CAAC;QAEF,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE;YACjE,cAAc,EAAE,IAAI;SACrB,CAAC,EAAE,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC;YAC5B,MAAM,aAAa,GAAG,IAAI,6BAAS,CAAC,UAAU,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACnE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,yBAAU,CAAC,UAAU,CAAC;oBACpB,YAAY,EAAE;wBACZ,KAAK,EAAE,oDAA2B;wBAClC,GAAG,EAAE,+CAAsB,CAAC,gBAAgB;qBAC7C;oBACD,OAAO,EAAE,0BAA0B,UAAU,EAAE;iBAChD,CAAC,CAAC;YACL,CAAC;YACD,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,MAAc;QAC7C,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7D,IAAA,oBAAM,EAAC,eAAe,KAAK,SAAS,CAAC,CAAC;YACtC,MAAM,4BAA4B,GAChC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC1D,IAAI,4BAA4B,EAAE,CAAC;gBACjC,OAAO;YACT,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAc;QACrC,qBAAM,CAAC,QAAQ,CACb,qDAAyB,CAAC,qBAAqB,EAC/C,0BAA0B,MAAM,CAAC,IAAI,EAAE,CACxC,CAAC;QACF,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAElD,yEAAyE;QACzE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA4C,CAAC;QAE5E,MAAM,UAAU,GAAG,KAAK,EAAE,QAA2B,EAAE,EAAE;YACvD,IAAI,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gBAC7C,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;QAEF,mCAAmC;QACnC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;aAChD,MAAM,CAAC,CAAC,IAAI,EAAmB,EAAE,CAAC,2BAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;aAC1D,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACrB,gCAAgC;YAChC,IAAI,OAAO,YAAY,qCAAiB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC1C,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,0BAA0B,CAAC,GAAG,CACjC,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAC7C,OAAO,CACR,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,mBAAmB;YACnB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;YACjD,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAElD,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;iBAC3C,MAAM,CAAC,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBAC/C,GAAG,CAAC,KAAK,EAAE,IAAc,EAAE,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;oBAAE,OAAO;gBACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC;gBAC9C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC3C,IAAI,OAAO,KAAK,SAAS;oBAAE,OAAO;gBAElC,MAAM,cAAc,GAClB,IAAI,CAAC,SAAS,KAAK,qCAAiB,CAAC,OAAO;oBAC1C,CAAC,CAAC,OAAO,CAAC,MAAM;oBAChB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBAErB,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAC9B,CAAC,eAAe,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAC1D,cAAc,CACf,CAAC;YACJ,CAAC,CAAC,CAAC;YAEL,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEL,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACvD,qBAAM,CAAC,QAAQ,CACb,qDAAyB,CAAC,qBAAqB,EAC/C,4BAA4B,MAAM,CAAC,IAAI,EAAE,CAC1C,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,OAA0B;QAE1B,IAAA,oBAAM,EAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC;QACvD,IAAA,oBAAM,EAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC;QACvD,MAAM,CACJ,CAAC,WAAW,EAAE,kBAAkB,CAAC,EACjC,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAClC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACpB,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAClD,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC;gBACzB,eAAe;gBACf,MAAM,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC;aAC5C,CACF;YACD,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAClD,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC;gBACzB,eAAe;gBACf,MAAM,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC;aAC5C,CACF;SACF,CAAC,CAAC;QAEH,IACE,kBAAkB,CAAC,IAAI,KAAK,UAAU;YACtC,kBAAkB,CAAC,IAAI,KAAK,UAAU;YAEtC,OAAO,SAAS,CAAC;QACnB,MAAM,UAAU,GACd,qBAAqB,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,UAAU,GACd,qBAAqB,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACvE,IACE,CAAC,CAAC,UAAU;YACV,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAChE,CAAC,CAAC,UAAU;gBACV,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,EAChE,CAAC;YACD,qFAAqF;YACrF,wGAAwG;YACxG,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,IAAa,EAAE,GAAY,EAAE,EAAE,CACpD;YACE,0BAA0B,IAAI,CAAC,QAAQ,oCAAoC;YAC3E,yCAAyC,GAAG,CAAC,QAAQ,GAAG;YACxD,gBAAgB;SACjB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,IAAA,oBAAM,EACJ,UAAU,KAAK,SAAS,EACxB,aAAa,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAC/C,CAAC;QACF,IAAA,oBAAM,EACJ,UAAU,KAAK,SAAS,EACxB,aAAa,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAC/C,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACpD,CAAC;IAEM,iBAAiB,CACtB,UAAkB,EAClB,SAAiB,EACjB,QAAgB;QAEhB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAC1E,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC;YACtC,UAAU,CAAC,WAAW,EAAE;YACxB,SAAS,CAAC,WAAW,EAAE;YACvB,QAAQ,CAAC,WAAW,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAEM,sBAAsB,CAC3B,UAAkB,EAClB,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAC1E,OAAO,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC;YACzC,UAAU,CAAC,WAAW,EAAE;YACxB,SAAS,CAAC,WAAW,EAAE;SACxB,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\n\nimport { ITwinError, Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n Property,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport { strict as assert } from \"node:assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaName = row.name;\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (!schema) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.SchemaLoadFailed,\n },\n message: `Failed to load schema: ${schemaName}`,\n });\n }\n await this.considerInitSchema(schema);\n }\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema started for ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Local dedup map — scoped to this single initSchema call, not persisted\n const localRelInfoMap = new Map<string, Promise<RelTypeInfo | undefined>>();\n\n const getRelInfo = async (relClass: RelationshipClass) => {\n let promise = localRelInfoMap.get(relClass.fullName);\n if (!promise) {\n promise = this.relInfoFromRelClass(relClass);\n localRelInfoMap.set(relClass.fullName, promise);\n }\n return promise;\n };\n\n // Process all classes concurrently\n const classPromises = Array.from(schema.getItems())\n .filter((item): item is ECClass => ECClass.isECClass(item))\n .map(async (ecclass) => {\n // Handle relationship end types\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await getRelInfo(ecclass);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, ecclass.name.toLowerCase()],\n relInfo\n );\n }\n }\n\n // Handle nav props\n const properties = await ecclass.getProperties();\n const classNameLower = ecclass.name.toLowerCase();\n\n const navPropPromises = Array.from(properties)\n .filter((prop: Property) => prop.isNavigation())\n .map(async (prop: Property) => {\n if (!prop.isNavigation()) return;\n const relClass = await prop.relationshipClass;\n const relInfo = await getRelInfo(relClass);\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? relInfo.target\n : relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n this._initedSchemas.set(schema.name, schema.schemaKey);\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema completed for ${schema.name}`\n );\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,
|
|
1
|
+
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCAAwC,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAC/E,OAAO,CAAC,YAAY;IAAvC,YAA2B,YAAY,EAAE,WAAW,EAAI;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC,CAEpE;IAEY,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAM/D;CACF;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,WAAW,EACP,CAAC,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAChE,qBAAqB,CAAC,aAAa,CAAC,CAUtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG
|
|
1
|
+
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;AAIhG;;;;GAIG;AACH;IAC6B,YAAY;IAAvC,YAA2B,YAAyB;4BAAzB,YAAY;IAAgB,CAAC;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;;AAED;;;;GAIG;AACH,kDACE,WAEiE;IAEjE,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;QACxC,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,kBAAkB;QAClB,OAAO,IAAI,uCAAuC,CAChD,WAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter implements AsyncIterableIterator<QueryRowProxy> {\n public constructor(private _ecSqlReader: ECSqlReader) {}\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(\n ecSqlReader:\n | (ECSqlReader & AsyncIterableIterator<QueryRowProxy>)\n | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>\n): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) {\n // using itwin 4.x\n return ecSqlReader;\n } else {\n // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(\n ecSqlReader as ECSqlReader\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EditTxn, ElementAspect, IModelDb } from "@itwin/core-backend";
|
|
2
|
+
import { Id64String } from "@itwin/core-bentley";
|
|
3
|
+
/** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare class ElementAspectCleanup {
|
|
7
|
+
private readonly _targetDb;
|
|
8
|
+
private readonly _editTxn;
|
|
9
|
+
private readonly _deleteAspect;
|
|
10
|
+
constructor(_targetDb: IModelDb, _editTxn: EditTxn, _deleteAspect: (aspect: ElementAspect) => Promise<void>);
|
|
11
|
+
/** Deletes replaceable unique and multi-aspects owned by the supplied target elements.
|
|
12
|
+
* Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.
|
|
13
|
+
*/
|
|
14
|
+
delete(targetElementIds: ReadonlySet<Id64String>, excludedElementAspectClassFullNames: ReadonlySet<string>, provenanceScopeId?: Id64String, pageSize?: number): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ElementAspectCleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementAspectCleanup.d.ts","sourceRoot":"","sources":["../../src/ElementAspectCleanup.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EACP,aAAa,EAIb,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;GAEG;AACH,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAHhC,YACmB,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,OAAO,EACjB,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE;IAEJ;;OAEG;IACU,MAAM,CACjB,gBAAgB,EAAE,WAAW,CAAC,UAAU,CAAC,EACzC,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,iBAAiB,CAAC,EAAE,UAAU,EAC9B,QAAQ,SAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA8Cf;CACF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ElementAspectCleanup = void 0;
|
|
8
|
+
const core_backend_1 = require("@itwin/core-backend");
|
|
9
|
+
const core_common_1 = require("@itwin/core-common");
|
|
10
|
+
/** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
class ElementAspectCleanup {
|
|
14
|
+
_targetDb;
|
|
15
|
+
_editTxn;
|
|
16
|
+
_deleteAspect;
|
|
17
|
+
constructor(_targetDb, _editTxn, _deleteAspect) {
|
|
18
|
+
this._targetDb = _targetDb;
|
|
19
|
+
this._editTxn = _editTxn;
|
|
20
|
+
this._deleteAspect = _deleteAspect;
|
|
21
|
+
}
|
|
22
|
+
/** Deletes replaceable unique and multi-aspects owned by the supplied target elements.
|
|
23
|
+
* Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.
|
|
24
|
+
*/
|
|
25
|
+
async delete(targetElementIds, excludedElementAspectClassFullNames, provenanceScopeId, pageSize = core_backend_1.IModelDb.maxLimit - 1) {
|
|
26
|
+
if (!this._editTxn.isActive) {
|
|
27
|
+
throw new Error("The target EditTxn must be active when deleting ElementAspects.");
|
|
28
|
+
}
|
|
29
|
+
if (pageSize <= 0 || !Number.isSafeInteger(pageSize)) {
|
|
30
|
+
throw new Error("ElementAspect deletion pageSize must be a positive integer.");
|
|
31
|
+
}
|
|
32
|
+
if (targetElementIds.size === 0)
|
|
33
|
+
return;
|
|
34
|
+
const targetExcludedElementAspectClassFullNames = [
|
|
35
|
+
...excludedElementAspectClassFullNames,
|
|
36
|
+
].filter((classFullName) => this._targetDb.containsClass(classFullName));
|
|
37
|
+
for (const aspectClassFullName of [
|
|
38
|
+
core_backend_1.ElementUniqueAspect.classFullName,
|
|
39
|
+
core_backend_1.ElementMultiAspect.classFullName,
|
|
40
|
+
]) {
|
|
41
|
+
const { ecsql, params } = replaceableAspectQuery(aspectClassFullName, targetElementIds, targetExcludedElementAspectClassFullNames, provenanceScopeId, pageSize);
|
|
42
|
+
while (true) {
|
|
43
|
+
// Drain the full page before deleting: mutating a table while a reader is still
|
|
44
|
+
// scanning it is unsafe.
|
|
45
|
+
const candidateIds = [];
|
|
46
|
+
for await (const row of this._targetDb.createQueryReader(ecsql, params, { usePrimaryConn: true })) {
|
|
47
|
+
candidateIds.push(row.id);
|
|
48
|
+
}
|
|
49
|
+
if (candidateIds.length === 0)
|
|
50
|
+
break;
|
|
51
|
+
for (const aspectId of candidateIds) {
|
|
52
|
+
const aspect = this._targetDb.elements.getAspect(aspectId);
|
|
53
|
+
await this._deleteAspect(aspect);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ElementAspectCleanup = ElementAspectCleanup;
|
|
60
|
+
/** Builds the page query for aspects of `aspectClassFullName` owned by `elementIds`, skipping excluded classes and provenance aspects for `provenanceScopeId`. */
|
|
61
|
+
function replaceableAspectQuery(aspectClassFullName, elementIds, excludedClassFullNames, provenanceScopeId, pageSize) {
|
|
62
|
+
const params = new core_common_1.QueryBinder().bindIdSet("elementIds", elementIds);
|
|
63
|
+
const conditions = [];
|
|
64
|
+
if (excludedClassFullNames.length > 0) {
|
|
65
|
+
conditions.push(`aspect.ECClassId IS NOT (${excludedClassFullNames.join(", ")})`);
|
|
66
|
+
}
|
|
67
|
+
// ExternalSourceAspect is a multi-aspect, so provenance aspects are only found
|
|
68
|
+
// when querying ElementMultiAspect. For each candidate, check whether it is a
|
|
69
|
+
// provenance aspect rather than listing every provenance aspect on each page.
|
|
70
|
+
if (provenanceScopeId !== undefined &&
|
|
71
|
+
aspectClassFullName === core_backend_1.ElementMultiAspect.classFullName) {
|
|
72
|
+
params.bindId("provenanceScopeId", provenanceScopeId);
|
|
73
|
+
conditions.push(`NOT EXISTS (
|
|
74
|
+
SELECT 1 FROM ${core_backend_1.ExternalSourceAspect.classFullName} esa
|
|
75
|
+
WHERE esa.ECInstanceId = aspect.ECInstanceId
|
|
76
|
+
AND (esa.Element.Id = :provenanceScopeId OR esa.Scope.Id = :provenanceScopeId)
|
|
77
|
+
)`);
|
|
78
|
+
}
|
|
79
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
80
|
+
const ecsql = `SELECT aspect.ECInstanceId as id
|
|
81
|
+
FROM ${aspectClassFullName} aspect
|
|
82
|
+
INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id
|
|
83
|
+
${whereClause}
|
|
84
|
+
LIMIT ${pageSize}`;
|
|
85
|
+
return { ecsql, params };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=ElementAspectCleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementAspectCleanup.js","sourceRoot":"","sources":["../../src/ElementAspectCleanup.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n EditTxn,\n ElementAspect,\n ElementMultiAspect,\n ElementUniqueAspect,\n ExternalSourceAspect,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\n\n/** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.\n * @internal\n */\nexport class ElementAspectCleanup {\n public constructor(\n private readonly _targetDb: IModelDb,\n private readonly _editTxn: EditTxn,\n private readonly _deleteAspect: (aspect: ElementAspect) => Promise<void>\n ) {}\n\n /** Deletes replaceable unique and multi-aspects owned by the supplied target elements.\n * Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.\n */\n public async delete(\n targetElementIds: ReadonlySet<Id64String>,\n excludedElementAspectClassFullNames: ReadonlySet<string>,\n provenanceScopeId?: Id64String,\n pageSize = IModelDb.maxLimit - 1\n ): Promise<void> {\n if (!this._editTxn.isActive) {\n throw new Error(\n \"The target EditTxn must be active when deleting ElementAspects.\"\n );\n }\n if (pageSize <= 0 || !Number.isSafeInteger(pageSize)) {\n throw new Error(\n \"ElementAspect deletion pageSize must be a positive integer.\"\n );\n }\n if (targetElementIds.size === 0) return;\n\n const targetExcludedElementAspectClassFullNames = [\n ...excludedElementAspectClassFullNames,\n ].filter((classFullName) => this._targetDb.containsClass(classFullName));\n for (const aspectClassFullName of [\n ElementUniqueAspect.classFullName,\n ElementMultiAspect.classFullName,\n ]) {\n const { ecsql, params } = replaceableAspectQuery(\n aspectClassFullName,\n targetElementIds,\n targetExcludedElementAspectClassFullNames,\n provenanceScopeId,\n pageSize\n );\n while (true) {\n // Drain the full page before deleting: mutating a table while a reader is still\n // scanning it is unsafe.\n const candidateIds: Id64String[] = [];\n for await (const row of this._targetDb.createQueryReader(\n ecsql,\n params,\n { usePrimaryConn: true }\n )) {\n candidateIds.push(row.id);\n }\n if (candidateIds.length === 0) break;\n\n for (const aspectId of candidateIds) {\n const aspect = this._targetDb.elements.getAspect(aspectId);\n await this._deleteAspect(aspect);\n }\n }\n }\n }\n}\n\n/** Builds the page query for aspects of `aspectClassFullName` owned by `elementIds`, skipping excluded classes and provenance aspects for `provenanceScopeId`. */\nfunction replaceableAspectQuery(\n aspectClassFullName: string,\n elementIds: ReadonlySet<Id64String>,\n excludedClassFullNames: readonly string[],\n provenanceScopeId: Id64String | undefined,\n pageSize: number\n): { ecsql: string; params: QueryBinder } {\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const conditions: string[] = [];\n if (excludedClassFullNames.length > 0) {\n conditions.push(\n `aspect.ECClassId IS NOT (${excludedClassFullNames.join(\", \")})`\n );\n }\n // ExternalSourceAspect is a multi-aspect, so provenance aspects are only found\n // when querying ElementMultiAspect. For each candidate, check whether it is a\n // provenance aspect rather than listing every provenance aspect on each page.\n if (\n provenanceScopeId !== undefined &&\n aspectClassFullName === ElementMultiAspect.classFullName\n ) {\n params.bindId(\"provenanceScopeId\", provenanceScopeId);\n conditions.push(`NOT EXISTS (\n SELECT 1 FROM ${ExternalSourceAspect.classFullName} esa\n WHERE esa.ECInstanceId = aspect.ECInstanceId\n AND (esa.Element.Id = :provenanceScopeId OR esa.Scope.Id = :provenanceScopeId)\n )`);\n }\n const whereClause =\n conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const ecsql = `SELECT aspect.ECInstanceId as id\n FROM ${aspectClassFullName} aspect\n INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id\n ${whereClause}\n LIMIT ${pageSize}`;\n return { ecsql, params };\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Id64String } from "@itwin/core-bentley";
|
|
2
|
+
export type ElementAspectExportPreparation = (excludedElementAspectClassFullNames: ReadonlySet<string>, ownerElementIds: ReadonlySet<Id64String>) => Promise<void>;
|
|
3
|
+
/** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare class ElementAspectExportCoordinator {
|
|
7
|
+
private readonly _defaultBatchSize;
|
|
8
|
+
private readonly _excludedClassFullNames;
|
|
9
|
+
private readonly _exportAspects;
|
|
10
|
+
private readonly _resetCaches;
|
|
11
|
+
private readonly _acceptedOwnerIds;
|
|
12
|
+
private readonly _processedOwnerIds;
|
|
13
|
+
private _batchSize;
|
|
14
|
+
private _depth;
|
|
15
|
+
private _prepare?;
|
|
16
|
+
constructor(_defaultBatchSize: number, _excludedClassFullNames: () => ReadonlySet<string>, _exportAspects: (ownerElementIds: ReadonlySet<Id64String>) => Promise<void>, _resetCaches?: () => void);
|
|
17
|
+
/** Whether an accepted-owner collection scope is active. */
|
|
18
|
+
get isActive(): boolean;
|
|
19
|
+
/** Sets the callback that prepares each accepted-owner group before its aspects are exported. */
|
|
20
|
+
setPreparation(prepare: ElementAspectExportPreparation): void;
|
|
21
|
+
/** Begins an accepted-owner collection scope.
|
|
22
|
+
* Nested scopes share the outer scope's state and batch size.
|
|
23
|
+
*/
|
|
24
|
+
begin(batchSize?: number): void;
|
|
25
|
+
/** Ends an accepted-owner collection scope.
|
|
26
|
+
* Ending the outermost scope exports pending owners and resets all scope state.
|
|
27
|
+
*/
|
|
28
|
+
end(): Promise<void>;
|
|
29
|
+
/** Discards the active scope and its pending owner state without exporting it. */
|
|
30
|
+
abort(): void;
|
|
31
|
+
/** Runs element export within an accepted-owner collection scope.
|
|
32
|
+
* A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.
|
|
33
|
+
*/
|
|
34
|
+
run(exportElements: () => Promise<void>): Promise<void>;
|
|
35
|
+
/** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
|
|
36
|
+
addAcceptedOwner(elementId: Id64String): Promise<void>;
|
|
37
|
+
/** Runs preparation and aspect export for an explicit owner set in bounded groups. */
|
|
38
|
+
exportOwners(ownerElementIds: ReadonlySet<Id64String>): Promise<void>;
|
|
39
|
+
private exportOwnerBatch;
|
|
40
|
+
private flush;
|
|
41
|
+
private resetScopeState;
|
|
42
|
+
private reset;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ElementAspectExportCoordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementAspectExportCoordinator.d.ts","sourceRoot":"","sources":["../../src/ElementAspectExportCoordinator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,8BAA8B,GAAG,CAC3C,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;GAEG;AACH,qBAAa,8BAA8B;IAQvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAG/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAZ/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;IAC5D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,CAAiC;IAElD,YACmB,iBAAiB,EAAE,MAAM,EACzB,uBAAuB,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,EAClD,cAAc,EAAE,CAC/B,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,EACD,YAAY,GAAE,MAAM,IAAe,EAGrD;IAED,4DAA4D;IAC5D,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,iGAAiG;IAC1F,cAAc,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI,CAEnE;IAED;;OAEG;IACI,KAAK,CAAC,SAAS,SAAyB,GAAG,IAAI,CAOrD;IAED;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAehC;IAED,kFAAkF;IAC3E,KAAK,IAAI,IAAI,CAEnB;IAED;;OAEG;IACU,GAAG,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnE;IAED,0HAA0H;IAC7G,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlE;IAED,sFAAsF;IACzE,YAAY,CACvB,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CA8Bf;YAEa,gBAAgB;YAOhB,KAAK;IAMnB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,KAAK;CAKd"}
|