@itwin/imodel-transformer 2.0.0-dev.11 → 2.0.0-dev.12

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.
@@ -106,7 +106,7 @@ class IModelImporter {
106
106
  this._elementsToUpdateDuringPreserveIds.add(elementId);
107
107
  }
108
108
  /** Import the specified ModelProps (either as an insert or an update) into the target iModel. */
109
- importModel(modelProps) {
109
+ async importModel(modelProps) {
110
110
  if (undefined === modelProps.id || !core_bentley_1.Id64.isValidId64(modelProps.id))
111
111
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Model Id not provided, should be the same as the ModeledElementId");
112
112
  if (this.doNotUpdateElement(modelProps.id)) {
@@ -116,14 +116,14 @@ class IModelImporter {
116
116
  try {
117
117
  const model = this.targetDb.models.getModel(modelProps.id); // throws IModelError.NotFound if model does not exist
118
118
  if (hasEntityChanged(model, modelProps, this._modelPropertiesToIgnore)) {
119
- this.onUpdateModel(modelProps);
119
+ await this.onUpdateModel(modelProps);
120
120
  }
121
121
  }
122
122
  catch (error) {
123
123
  // catch NotFound error and insertModel
124
124
  if (error instanceof core_common_1.IModelError &&
125
125
  error.errorNumber === core_bentley_1.IModelStatus.NotFound) {
126
- this.onInsertModel(modelProps);
126
+ await this.onInsertModel(modelProps);
127
127
  return;
128
128
  }
129
129
  throw error;
@@ -132,11 +132,11 @@ class IModelImporter {
132
132
  /** Create a new Model from the specified ModelProps and insert it into the target iModel.
133
133
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertModel`.
134
134
  */
135
- onInsertModel(modelProps) {
135
+ async onInsertModel(modelProps) {
136
136
  try {
137
137
  const modelId = this.targetDb.models.insertModel(modelProps);
138
138
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatModelForLogger(modelProps)}`);
139
- this.trackProgress();
139
+ await this.trackProgress();
140
140
  return modelId;
141
141
  }
142
142
  catch (error) {
@@ -151,10 +151,10 @@ class IModelImporter {
151
151
  /** Update an existing Model in the target iModel from the specified ModelProps.
152
152
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateModel`.
153
153
  */
154
- onUpdateModel(modelProps) {
154
+ async onUpdateModel(modelProps) {
155
155
  this.targetDb.models.updateModel(modelProps);
156
156
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatModelForLogger(modelProps)}`);
157
- this.trackProgress();
157
+ await this.trackProgress();
158
158
  }
159
159
  /** Format a Model for the Logger. */
160
160
  formatModelForLogger(modelProps) {
@@ -165,9 +165,9 @@ class IModelImporter {
165
165
  * Tries to update an element with the specified element properties.
166
166
  * If a duplicate code error occurs, it assigns a new unique code value and retries the update
167
167
  */
168
- tryUpdateElement(elemProps) {
168
+ async tryUpdateElement(elemProps) {
169
169
  try {
170
- this.onUpdateElement(elemProps);
170
+ await this.onUpdateElement(elemProps);
171
171
  }
172
172
  catch (err) {
173
173
  if (err.errorNumber === core_bentley_1.IModelStatus.DuplicateCode) {
@@ -176,7 +176,7 @@ class IModelImporter {
176
176
  this._duplicateCodeValueMap.set(elemProps.id, elemProps.code.value);
177
177
  // Using NULL code values as an alternative is not valid because definition elements cannot have NULL code values.
178
178
  elemProps.code.value = core_bentley_1.Guid.createValue();
179
- this.onUpdateElement(elemProps);
179
+ await this.onUpdateElement(elemProps);
180
180
  }
181
181
  else {
182
182
  throw err;
@@ -184,7 +184,7 @@ class IModelImporter {
184
184
  }
185
185
  }
186
186
  /** Import the specified ElementProps (either as an insert or an update) into the target iModel. */
187
- importElement(elementProps) {
187
+ async importElement(elementProps) {
188
188
  if (undefined !== elementProps.id &&
189
189
  this.doNotUpdateElement(elementProps.id)) {
190
190
  core_bentley_1.Logger.logInfo(loggerCategory, `Do not update target element ${elementProps.id}`);
@@ -200,24 +200,24 @@ class IModelImporter {
200
200
  // Always present elements (0xe, 0x1, 0x10) also will be updated to prevent duplicate inserts.
201
201
  if ((isSubCategory(elementProps) && isDefaultSubCategory(elementProps)) ||
202
202
  this._rootElementIds.has(elementProps.id)) {
203
- this.onUpdateElement(elementProps);
203
+ await this.onUpdateElement(elementProps);
204
204
  }
205
205
  else {
206
206
  if (this._elementsToUpdateDuringPreserveIds.has(elementProps.id)) {
207
- this.tryUpdateElement(elementProps);
207
+ await this.tryUpdateElement(elementProps);
208
208
  this._elementsToUpdateDuringPreserveIds.delete(elementProps.id);
209
209
  }
210
210
  else {
211
- this.onInsertElement(elementProps);
211
+ await this.onInsertElement(elementProps);
212
212
  }
213
213
  }
214
214
  }
215
215
  else {
216
216
  if (undefined !== elementProps.id) {
217
- this.tryUpdateElement(elementProps);
217
+ await this.tryUpdateElement(elementProps);
218
218
  }
219
219
  else {
220
- elementProps.id = this.onInsertElement(elementProps); // targetElementProps.id assigned by insertElement
220
+ elementProps.id = await this.onInsertElement(elementProps); // targetElementProps.id assigned by insertElement
221
221
  }
222
222
  }
223
223
  return elementProps.id;
@@ -226,7 +226,7 @@ class IModelImporter {
226
226
  * @returns The Id of the newly inserted Element.
227
227
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertElement`.
228
228
  */
229
- onInsertElement(elementProps) {
229
+ async onInsertElement(elementProps) {
230
230
  try {
231
231
  const elementId = this.targetDb.elements.insertElement(elementProps, {
232
232
  forceUseId: this.options.preserveElementIdsForFiltering,
@@ -234,7 +234,7 @@ class IModelImporter {
234
234
  // set the id like [IModelDb.insertElement]($backend), does, the raw nativeDb method does not
235
235
  elementProps.id = elementId;
236
236
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatElementForLogger(elementProps)}`);
237
- this.trackProgress();
237
+ await this.trackProgress();
238
238
  if (this.options.simplifyElementGeometry) {
239
239
  this.targetDb.simplifyElementGeometry({
240
240
  id: elementId,
@@ -256,13 +256,13 @@ class IModelImporter {
256
256
  /** Update an existing Element in the target iModel from the specified ElementProps.
257
257
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateElement`.
258
258
  */
259
- onUpdateElement(elementProps) {
259
+ async onUpdateElement(elementProps) {
260
260
  if (!elementProps.id) {
261
261
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "ElementId not provided");
262
262
  }
263
263
  this.targetDb.elements.updateElement(elementProps);
264
264
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatElementForLogger(elementProps)}`);
265
- this.trackProgress();
265
+ await this.trackProgress();
266
266
  if (this.options.simplifyElementGeometry) {
267
267
  this.targetDb.simplifyElementGeometry({
268
268
  id: elementProps.id,
@@ -275,18 +275,18 @@ class IModelImporter {
275
275
  * Will delete special elements like definition elements and subjects.
276
276
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteElement`.
277
277
  */
278
- onDeleteElement(elementId) {
278
+ async onDeleteElement(elementId) {
279
279
  (0, ElementCascadingDeleter_1.deleteElementTreeCascade)(this.targetDb, elementId);
280
280
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted element ${elementId} and its descendants`);
281
- this.trackProgress();
281
+ await this.trackProgress();
282
282
  }
283
283
  /** Delete the specified Element from the target iModel. */
284
- deleteElement(elementId) {
284
+ async deleteElement(elementId) {
285
285
  if (this.doNotUpdateElement(elementId)) {
286
286
  core_bentley_1.Logger.logInfo(loggerCategory, `Do not delete target element ${elementId}`);
287
287
  return;
288
288
  }
289
- this.onDeleteElement(elementId);
289
+ await this.onDeleteElement(elementId);
290
290
  }
291
291
  /** Delete the specified Model from the target iModel.
292
292
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteModel`.
@@ -294,7 +294,7 @@ class IModelImporter {
294
294
  async onDeleteModel(modelId) {
295
295
  this.targetDb.models.deleteModel(modelId);
296
296
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted model ${modelId}`);
297
- this.trackProgress();
297
+ await this.trackProgress();
298
298
  }
299
299
  /** Delete the specified Model from the target iModel. */
300
300
  async deleteModel(modelId) {
@@ -310,14 +310,14 @@ class IModelImporter {
310
310
  return `${elementProps.classFullName} ${namePiece}[${elementProps.id}]`;
311
311
  }
312
312
  /** Import an ElementUniqueAspect into the target iModel. */
313
- importElementUniqueAspect(aspectProps) {
313
+ async importElementUniqueAspect(aspectProps) {
314
314
  const aspects = this.targetDb.elements.getAspects(aspectProps.element.id, aspectProps.classFullName);
315
315
  if (aspects.length === 0) {
316
316
  return this.onInsertElementAspect(aspectProps);
317
317
  }
318
318
  else if (hasEntityChanged(aspects[0], aspectProps)) {
319
319
  aspectProps.id = aspects[0].id;
320
- this.onUpdateElementAspect(aspectProps);
320
+ await this.onUpdateElementAspect(aspectProps);
321
321
  }
322
322
  return aspects[0].id;
323
323
  }
@@ -327,7 +327,7 @@ class IModelImporter {
327
327
  * @note For insert vs. update reasons, it is important to process all ElementMultiAspects owned by an Element at once since we don't have aspect-specific provenance.
328
328
  * @returns the array of ids of the resulting ElementMultiAspects, in the same order of the aspectPropsArray parameter
329
329
  */
330
- importElementMultiAspects(aspectPropsArray,
330
+ async importElementMultiAspects(aspectPropsArray,
331
331
  /** caller must use this to enforce any aspects added by IModelTransformer are not considered for update */
332
332
  filterFunc = () => true) {
333
333
  const result = new Array(aspectPropsArray.length).fill(undefined);
@@ -341,7 +341,7 @@ class IModelImporter {
341
341
  aspectClassFullNames.add(aspectsProps.classFullName);
342
342
  });
343
343
  // Handle ElementMultiAspects in groups by class
344
- aspectClassFullNames.forEach((aspectClassFullName) => {
344
+ for (const aspectClassFullName of aspectClassFullNames) {
345
345
  const proposedAspects = aspectPropsArray
346
346
  .map((props, index) => ({ props, index }))
347
347
  .filter(({ props }) => aspectClassFullName === props.classFullName);
@@ -350,50 +350,52 @@ class IModelImporter {
350
350
  .map((props, index) => ({ props, index }))
351
351
  .filter(({ props }) => filterFunc(props));
352
352
  if (proposedAspects.length >= currentAspects.length) {
353
- proposedAspects.forEach(({ props, index: resultIndex }, index) => {
353
+ for (let index = 0; index < proposedAspects.length; index++) {
354
+ const { props, index: resultIndex } = proposedAspects[index];
354
355
  let id;
355
356
  if (index < currentAspects.length) {
356
357
  id = currentAspects[index].props.id;
357
358
  props.id = id;
358
359
  if (hasEntityChanged(currentAspects[index].props, props)) {
359
- this.onUpdateElementAspect(props);
360
+ await this.onUpdateElementAspect(props);
360
361
  }
361
362
  id = props.id;
362
363
  }
363
364
  else {
364
- id = this.onInsertElementAspect(props);
365
+ id = await this.onInsertElementAspect(props);
365
366
  }
366
367
  result[resultIndex] = id;
367
- });
368
+ }
368
369
  }
369
370
  else {
370
- currentAspects.forEach(({ props, index: resultIndex }, index) => {
371
+ for (let index = 0; index < currentAspects.length; index++) {
372
+ const { props, index: resultIndex } = currentAspects[index];
371
373
  let id;
372
374
  if (index < proposedAspects.length) {
373
375
  id = props.id;
374
376
  proposedAspects[index].props.id = id;
375
377
  if (hasEntityChanged(props, proposedAspects[index].props)) {
376
- this.onUpdateElementAspect(proposedAspects[index].props);
378
+ await this.onUpdateElementAspect(proposedAspects[index].props);
377
379
  }
378
380
  result[resultIndex] = id;
379
381
  }
380
382
  else {
381
- this.onDeleteElementAspect(props);
383
+ await this.onDeleteElementAspect(props);
382
384
  }
383
- });
385
+ }
384
386
  }
385
- });
387
+ }
386
388
  assert(result.every((r) => typeof r !== undefined));
387
389
  return result;
388
390
  }
389
391
  /** Insert the ElementAspect into the target iModel.
390
392
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertElementAspect`.
391
393
  */
392
- onInsertElementAspect(aspectProps) {
394
+ async onInsertElementAspect(aspectProps) {
393
395
  try {
394
396
  const id = this.targetDb.elements.insertAspect(aspectProps);
395
397
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatElementAspectForLogger(aspectProps)}`);
396
- this.trackProgress();
398
+ await this.trackProgress();
397
399
  return id;
398
400
  }
399
401
  catch (error) {
@@ -408,18 +410,18 @@ class IModelImporter {
408
410
  /** Update the ElementAspect within the target iModel.
409
411
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateElementAspect`.
410
412
  */
411
- onUpdateElementAspect(aspectProps) {
413
+ async onUpdateElementAspect(aspectProps) {
412
414
  this.targetDb.elements.updateAspect(aspectProps);
413
415
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatElementAspectForLogger(aspectProps)}`);
414
- this.trackProgress();
416
+ await this.trackProgress();
415
417
  }
416
418
  /** Delete the specified ElementAspect from the target iModel.
417
419
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteElementAspect`.
418
420
  */
419
- onDeleteElementAspect(targetElementAspect) {
421
+ async onDeleteElementAspect(targetElementAspect) {
420
422
  this.targetDb.elements.deleteAspect(targetElementAspect.id);
421
423
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted ${this.formatElementAspectForLogger(targetElementAspect)}`);
422
- this.trackProgress();
424
+ await this.trackProgress();
423
425
  }
424
426
  /** Format an ElementAspect for the Logger. */
425
427
  formatElementAspectForLogger(elementAspectProps) {
@@ -428,7 +430,7 @@ class IModelImporter {
428
430
  /** Import the specified RelationshipProps (either as an insert or an update) into the target iModel.
429
431
  * @returns The instance Id of the inserted or updated Relationship.
430
432
  */
431
- importRelationship(relationshipProps) {
433
+ async importRelationship(relationshipProps) {
432
434
  if (undefined === relationshipProps.sourceId ||
433
435
  !core_bentley_1.Id64.isValidId64(relationshipProps.sourceId)) {
434
436
  core_bentley_1.Logger.logInfo(loggerCategory, `Ignoring ${relationshipProps.classFullName} instance because of invalid RelationshipProps.sourceId`);
@@ -449,7 +451,7 @@ class IModelImporter {
449
451
  // if relationship found, update it
450
452
  relationshipProps.id = relationship.id;
451
453
  if (hasEntityChanged(relationship, relationshipProps)) {
452
- this.onUpdateRelationship(relationshipProps);
454
+ await this.onUpdateRelationship(relationshipProps);
453
455
  }
454
456
  return relationshipProps.id;
455
457
  }
@@ -461,11 +463,11 @@ class IModelImporter {
461
463
  * @returns The instance Id of the newly inserted relationship.
462
464
  * @note A subclass may override this method to customize insert behavior but should call `super.onInsertRelationship`.
463
465
  */
464
- onInsertRelationship(relationshipProps) {
466
+ async onInsertRelationship(relationshipProps) {
465
467
  try {
466
468
  const targetRelInstanceId = this.targetDb.relationships.insertInstance(relationshipProps);
467
469
  core_bentley_1.Logger.logInfo(loggerCategory, `Inserted ${this.formatRelationshipForLogger(relationshipProps)}`);
468
- this.trackProgress();
470
+ await this.trackProgress();
469
471
  return targetRelInstanceId;
470
472
  }
471
473
  catch (error) {
@@ -480,43 +482,43 @@ class IModelImporter {
480
482
  /** Update an existing Relationship in the target iModel from the specified RelationshipProps.
481
483
  * @note A subclass may override this method to customize update behavior but should call `super.onUpdateRelationship`.
482
484
  */
483
- onUpdateRelationship(relationshipProps) {
485
+ async onUpdateRelationship(relationshipProps) {
484
486
  if (!relationshipProps.id) {
485
487
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Relationship instance Id not provided");
486
488
  }
487
489
  this.targetDb.relationships.updateInstance(relationshipProps);
488
490
  core_bentley_1.Logger.logInfo(loggerCategory, `Updated ${this.formatRelationshipForLogger(relationshipProps)}`);
489
- this.trackProgress();
491
+ await this.trackProgress();
490
492
  }
491
493
  /** Delete the specified Relationship from the target iModel. */
492
- onDeleteRelationship(relationshipProps) {
494
+ async onDeleteRelationship(relationshipProps) {
493
495
  // Only passing in what deleteInstance actually uses, full relationshipProps is not necessary.
494
496
  this.targetDb.relationships.deleteInstance({
495
497
  id: relationshipProps.id,
496
498
  classFullName: relationshipProps.classFullName,
497
499
  });
498
500
  core_bentley_1.Logger.logInfo(loggerCategory, `Deleted relationship ${relationshipProps.classFullName} id=${relationshipProps.id}`);
499
- this.trackProgress();
501
+ await this.trackProgress();
500
502
  }
501
503
  /** Delete the specified Relationship from the target iModel. */
502
- deleteRelationship(relationshipProps) {
503
- this.onDeleteRelationship(relationshipProps);
504
+ async deleteRelationship(relationshipProps) {
505
+ await this.onDeleteRelationship(relationshipProps);
504
506
  }
505
507
  /** Format a Relationship for the Logger. */
506
508
  formatRelationshipForLogger(relProps) {
507
509
  return `${relProps.classFullName} sourceId=[${relProps.sourceId}] targetId=[${relProps.targetId}]`;
508
510
  }
509
511
  /** Tracks incremental progress */
510
- trackProgress() {
512
+ async trackProgress() {
511
513
  this._progressCounter++;
512
514
  if (0 === this._progressCounter % this.progressInterval) {
513
- this.onProgress();
515
+ await this.onProgress();
514
516
  }
515
517
  }
516
518
  /** This method is called when IModelImporter has made incremental progress based on the [[progressInterval]] setting.
517
519
  * @note A subclass may override this method to report custom progress but should call `super.onProgress`.
518
520
  */
519
- onProgress() { }
521
+ async onProgress() { }
520
522
  /** Optionally compute the projectExtents for the target iModel depending on the options for this IModelImporter.
521
523
  * @note This method is automatically called from [IModelTransformer.process]($transformer).
522
524
  * @see [IModelDb.computeProjectExtents]($backend), [[autoExtendProjectExtents]]