@itwin/imodel-transformer 1.0.0 → 1.0.1-customchanges.2

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/CHANGELOG.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Change Log - @itwin/imodel-transformer
2
2
 
3
- <!-- This log was last generated on Mon, 04 Nov 2024 14:45:39 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Mon, 04 Nov 2024 14:45:46 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
7
  ## 1.0.0
8
8
 
9
- Mon, 04 Nov 2024 14:45:39 GMT
9
+ Mon, 04 Nov 2024 14:45:46 GMT
10
10
 
11
11
  ### Patches
12
12
 
@@ -1,8 +1,8 @@
1
1
  /** @packageDocumentation
2
2
  * @module iModels
3
3
  */
4
- import { BriefcaseDb, ChangedECInstance, Element, ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb, IModelJsNative, Model, Relationship } from "@itwin/core-backend";
5
- import { Id64String } from "@itwin/core-bentley";
4
+ import { BriefcaseDb, ChangedECInstance, Element, ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb, IModelJsNative, Model, Relationship, SqliteChangeOp } from "@itwin/core-backend";
5
+ import { Id64Arg, Id64String } from "@itwin/core-bentley";
6
6
  import { ChangesetFileProps, CodeSpec, FontProps } from "@itwin/core-common";
7
7
  import { Schema, SchemaKey } from "@itwin/ecschema-metadata";
8
8
  import { ElementAspectsHandler, ExportElementAspectsStrategy } from "./ExportElementAspectsStrategy";
@@ -198,7 +198,7 @@ export declare class IModelExporter {
198
198
  private _sourceDbChanges?;
199
199
  /**
200
200
  * Retrieve the cached entity change information.
201
- * @note This will only be initialized after [IModelExporter.exportChanges] is invoked.
201
+ * @note This will only be initialized after [IModelExporter.exportChanges] is invoked or [IModelExporter.initialize] is called.
202
202
  */
203
203
  get sourceDbChanges(): ChangedInstanceIds | undefined;
204
204
  /** The handler called by this IModelExporter. */
@@ -254,6 +254,7 @@ export declare class IModelExporter {
254
254
  * range and open the source iModel as of the end (inclusive) of the desired range.
255
255
  * @note the changedInstanceIds are just for this call to exportChanges, so you must continue to pass it in
256
256
  * for consecutive calls
257
+ * @note Passing {} or undefined to exportChanges will result in the current changeset of the source iModel being exported.
257
258
  */
258
259
  exportChanges(args?: ExportChangesOptions): Promise<void>;
259
260
  private _resetChangeDataOnExport;
@@ -346,6 +347,18 @@ export declare class ChangedInstanceOps {
346
347
  deleteIds: Set<string>;
347
348
  /** Initializes the object from IModelJsNative.ChangedInstanceOpsProps. */
348
349
  addFromJson(val: IModelJsNative.ChangedInstanceOpsProps | undefined): void;
350
+ get isEmpty(): boolean;
351
+ }
352
+ /**
353
+ * Interface to describe a 'custom' change. A custom change is one which isn't found by reading changesets, but instead added by a user calling the 'addCustomChange' API on the ChangedInstanceIds instance.
354
+ * The purpose a custom change would serve is to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
355
+ * @beta
356
+ */
357
+ export interface ChangedInstanceCustomRelationshipData {
358
+ sourceIdOfRelationship: Id64String;
359
+ targetIdOfRelationship: Id64String;
360
+ ecClassId: Id64String;
361
+ classFullName: string;
349
362
  }
350
363
  /**
351
364
  * Class for discovering modified elements between 2 versions of an iModel.
@@ -363,6 +376,11 @@ export declare class ChangedInstanceIds {
363
376
  private _elementSubclassIds?;
364
377
  private _aspectSubclassIds?;
365
378
  private _relationshipSubclassIds?;
379
+ private _relationshipSubclassIdsToSkip?;
380
+ private _ecClassIdsToClassFullNames?;
381
+ /** c${string} is used to represent codeSpecs since they do not currently have a representation in the EntityReference class. This map holds information passed to the 'addCustom' functions. */
382
+ private _entityReferenceToCustomDataMap;
383
+ private _hasCustomRelationshipChanges;
366
384
  private _db;
367
385
  constructor(db: IModelDb);
368
386
  private setupECClassIds;
@@ -372,6 +390,8 @@ export declare class ChangedInstanceIds {
372
390
  private isAspect;
373
391
  private isModel;
374
392
  private isElement;
393
+ get hasCustomRelationshipChanges(): boolean;
394
+ get hasChanges(): boolean;
375
395
  /**
376
396
  * Adds the provided [[ChangedECInstance]] to the appropriate set of changes by class type (codeSpec, model, element, aspect, or relationship) maintained by this instance of ChangedInstanceIds.
377
397
  * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
@@ -379,6 +399,73 @@ export declare class ChangedInstanceIds {
379
399
  * @param change ChangedECInstance which has the ECInstanceId, changeType (insert, update, delete) and ECClassId of the changed entity
380
400
  */
381
401
  addChange(change: ChangedECInstance): Promise<void>;
402
+ /**
403
+ * Adds the provided change to the element changes maintained by this instance of ChangedInstanceIds
404
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
405
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
406
+ * @note element changes will also cause the element's model to be marked as updated in [[ChangedInstanceIds.model]], so that the element does not get skipped by the transformer.
407
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.
408
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
409
+ * @beta
410
+ */
411
+ addCustomElementChange(changeType: SqliteChangeOp, ids: Id64Arg): void;
412
+ /**
413
+ * Adds the provided change to the codespec changes maintained by this instance of ChangedInstanceIds
414
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
415
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
416
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact a codespec.
417
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
418
+ * @beta
419
+ */
420
+ addCustomCodeSpecChange(changeType: SqliteChangeOp, ids: Id64Arg): void;
421
+ /**
422
+ * Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds.
423
+ * Also adds the model's modeledElement to the element changes. This is to ensure the changes from the model and its modeledElement get exported together.
424
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
425
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
426
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.
427
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
428
+ * @beta
429
+ */
430
+ addCustomModelChange(changeType: SqliteChangeOp, ids: Id64Arg): void;
431
+ /**
432
+ * Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds
433
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
434
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
435
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.
436
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
437
+ * @beta
438
+ */
439
+ addCustomAspectChange(changeType: SqliteChangeOp, ids: Id64Arg): void;
440
+ /**
441
+ * TODO: Think more about permutations of model updated / inserted / deleted. Can you delete a model without deleting its elements?
442
+ * What if model delete but custom change si to insert element into target?
443
+ * // It is possible and apparently occasionally sensical to delete a model without deleting its underlying element.
444
+ // - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
445
+ // - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
446
+ * TODO: If the element is a custom delete we probably shouldnt be calling this?
447
+ * There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is part of
448
+ * the sourceDbChanges. This method is used in addCustomChange to add the model to the updatedIds set so that the custom element changes are exported.
449
+ */
450
+ private addModelToUpdated;
451
+ /** TODO: Maybe relationships only? maybe not.
452
+ * @beta
453
+ */
454
+ getCustomRelationshipDataFromId(id: Id64String): ChangedInstanceCustomRelationshipData | undefined;
455
+ /**
456
+ * Adds the provided change to the set of relationship changes maintained by this instance of ChangedInstanceIds.
457
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
458
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
459
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
460
+ * @throws if the ecClassId is NOT a relationship classId
461
+ * @param ecClassId class id of the custom change
462
+ * @param changeType insert, update or delete
463
+ * @param id ECInstanceID of the custom change
464
+ * @param sourceECInstanceId source ECInstanceId of the relationship
465
+ * @param targetECInstanceId target ECInstanceId of the relationship
466
+ * @beta
467
+ */
468
+ addCustomRelationshipChange(ecClassId: string, changeType: SqliteChangeOp, id: Id64String, sourceECInstanceId: Id64String, targetECInstanceId: Id64String): Promise<void>;
382
469
  private handleChange;
383
470
  /**
384
471
  * Initializes a new ChangedInstanceIds object with information taken from a range of changesets.
@@ -1 +1 @@
1
- {"version":3,"file":"IModelExporter.d.ts","sourceRoot":"","sources":["../../src/IModelExporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IModelExporter.d.ts","sourceRoot":"","sources":["../../src/IModelExporter.ts"],"names":[],"mappings":"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"}
@@ -132,7 +132,7 @@ exports.IModelExportHandler = IModelExportHandler;
132
132
  class IModelExporter {
133
133
  /**
134
134
  * Retrieve the cached entity change information.
135
- * @note This will only be initialized after [IModelExporter.exportChanges] is invoked.
135
+ * @note This will only be initialized after [IModelExporter.exportChanges] is invoked or [IModelExporter.initialize] is called.
136
136
  */
137
137
  get sourceDbChanges() {
138
138
  return this._sourceDbChanges;
@@ -260,6 +260,7 @@ class IModelExporter {
260
260
  * range and open the source iModel as of the end (inclusive) of the desired range.
261
261
  * @note the changedInstanceIds are just for this call to exportChanges, so you must continue to pass it in
262
262
  * for consecutive calls
263
+ * @note Passing {} or undefined to exportChanges will result in the current changeset of the source iModel being exported.
263
264
  */
264
265
  async exportChanges(args) {
265
266
  if (!this.sourceDb.isBriefcaseDb())
@@ -268,10 +269,17 @@ class IModelExporter {
268
269
  await this.exportAll(); // no changesets, so revert to exportAll
269
270
  return;
270
271
  }
271
- const startChangeset = args && "startChangeset" in args ? args.startChangeset : undefined;
272
- const initOpts = {
273
- startChangeset: { id: startChangeset?.id },
274
- };
272
+ const isEmptyObject = (obj) => Object.keys(obj).length === 0;
273
+ let initOpts;
274
+ if (args === undefined || isEmptyObject(args)) {
275
+ // Fallback behavior for exportChanges with no args / empty object, this.initialize will process the current changeset of the source iModel being exported when startChangeset.id is undefined.
276
+ initOpts = {
277
+ startChangeset: { id: undefined },
278
+ };
279
+ }
280
+ else {
281
+ initOpts = args;
282
+ }
275
283
  await this.initialize(initOpts);
276
284
  // _sourceDbChanges are initialized in this.initialize
277
285
  nodeAssert(this._sourceDbChanges !== undefined, "sourceDbChanges must be initialized.");
@@ -384,7 +392,7 @@ class IModelExporter {
384
392
  async exportCodeSpecByName(codeSpecName) {
385
393
  const codeSpec = this.sourceDb.codeSpecs.getByName(codeSpecName);
386
394
  let isUpdate;
387
- if (undefined !== this._sourceDbChanges) {
395
+ if (this._sourceDbChanges !== undefined) {
388
396
  // is changeset information available?
389
397
  if (this._sourceDbChanges.codeSpec.insertIds.has(codeSpec.id)) {
390
398
  isUpdate = false;
@@ -476,7 +484,7 @@ class IModelExporter {
476
484
  /** Export the model (the container only) from the source iModel. */
477
485
  async exportModelContainer(model) {
478
486
  let isUpdate;
479
- if (undefined !== this._sourceDbChanges) {
487
+ if (this._sourceDbChanges !== undefined) {
480
488
  // is changeset information available?
481
489
  if (this._sourceDbChanges.model.insertIds.has(model.id)) {
482
490
  isUpdate = false;
@@ -507,7 +515,7 @@ class IModelExporter {
507
515
  core_bentley_1.Logger.logTrace(loggerCategory, `visitElements=false, skipping exportModelContents(${modelId})`);
508
516
  return;
509
517
  }
510
- if (undefined !== this._sourceDbChanges) {
518
+ if (this._sourceDbChanges !== undefined) {
511
519
  // is changeset information available?
512
520
  if (!this._sourceDbChanges.model.insertIds.has(modelId) &&
513
521
  !this._sourceDbChanges.model.updateIds.has(modelId)) {
@@ -681,7 +689,7 @@ class IModelExporter {
681
689
  return;
682
690
  }
683
691
  let isUpdate;
684
- if (undefined !== this._sourceDbChanges) {
692
+ if (this._sourceDbChanges !== undefined) {
685
693
  // is changeset information available?
686
694
  if (this._sourceDbChanges.relationship.insertIds.has(relInstanceId)) {
687
695
  isUpdate = false;
@@ -737,6 +745,11 @@ class ChangedInstanceOps {
737
745
  val.delete.forEach((id) => this.deleteIds.add(id));
738
746
  }
739
747
  }
748
+ get isEmpty() {
749
+ return (0 === this.insertIds.size &&
750
+ 0 === this.updateIds.size &&
751
+ 0 === this.deleteIds.size);
752
+ }
740
753
  }
741
754
  exports.ChangedInstanceOps = ChangedInstanceOps;
742
755
  /**
@@ -752,6 +765,8 @@ class ChangedInstanceIds {
752
765
  this.relationship = new ChangedInstanceOps();
753
766
  this.font = new ChangedInstanceOps();
754
767
  this._db = db;
768
+ this._hasCustomRelationshipChanges = false;
769
+ this._entityReferenceToCustomDataMap = new Map();
755
770
  }
756
771
  async setupECClassIds() {
757
772
  this._codeSpecSubclassIds = new Set();
@@ -759,9 +774,12 @@ class ChangedInstanceIds {
759
774
  this._elementSubclassIds = new Set();
760
775
  this._aspectSubclassIds = new Set();
761
776
  this._relationshipSubclassIds = new Set();
777
+ this._relationshipSubclassIdsToSkip = new Set();
778
+ this._ecClassIdsToClassFullNames = new Map();
762
779
  const addECClassIdsToSet = async (setToModify, baseClass) => {
763
- for await (const row of this._db.createQueryReader(`SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (${baseClass})`)) {
764
- setToModify.add(row.ECInstanceId);
780
+ for await (const row of this._db.createQueryReader(`SELECT c.ECInstanceId ECClassId, c.Name className, s.Name schemaName FROM ECDbMeta.ECClassDef c JOIN ECDbMeta.ECSchemaDef s ON s.ECInstanceId = c.Schema.Id WHERE c.ECInstanceId IS (${baseClass})`)) {
781
+ setToModify.add(row.ECClassId);
782
+ this._ecClassIdsToClassFullNames?.set(row.ECClassId, `${row.schemaName}:${row.className}`);
765
783
  }
766
784
  };
767
785
  const promises = [
@@ -771,6 +789,7 @@ class ChangedInstanceIds {
771
789
  addECClassIdsToSet(this._aspectSubclassIds, "BisCore.ElementUniqueAspect"),
772
790
  addECClassIdsToSet(this._aspectSubclassIds, "BisCore.ElementMultiAspect"),
773
791
  addECClassIdsToSet(this._relationshipSubclassIds, "BisCore.ElementRefersToElements"),
792
+ addECClassIdsToSet(this._relationshipSubclassIdsToSkip, "BisCore.ElementDrivesElement"),
774
793
  ];
775
794
  await Promise.all(promises);
776
795
  }
@@ -779,7 +798,8 @@ class ChangedInstanceIds {
779
798
  this._modelSubclassIds &&
780
799
  this._elementSubclassIds &&
781
800
  this._aspectSubclassIds &&
782
- this._relationshipSubclassIds);
801
+ this._relationshipSubclassIds &&
802
+ this._relationshipSubclassIdsToSkip);
783
803
  }
784
804
  isRelationship(ecClassId) {
785
805
  return this._relationshipSubclassIds?.has(ecClassId);
@@ -796,6 +816,17 @@ class ChangedInstanceIds {
796
816
  isElement(ecClassId) {
797
817
  return this._elementSubclassIds?.has(ecClassId);
798
818
  }
819
+ get hasCustomRelationshipChanges() {
820
+ return this._hasCustomRelationshipChanges;
821
+ }
822
+ get hasChanges() {
823
+ return (!this.codeSpec.isEmpty ||
824
+ !this.model.isEmpty ||
825
+ !this.element.isEmpty ||
826
+ !this.aspect.isEmpty ||
827
+ !this.relationship.isEmpty ||
828
+ !this.font.isEmpty);
829
+ }
799
830
  /**
800
831
  * Adds the provided [[ChangedECInstance]] to the appropriate set of changes by class type (codeSpec, model, element, aspect, or relationship) maintained by this instance of ChangedInstanceIds.
801
832
  * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
@@ -811,6 +842,8 @@ class ChangedInstanceIds {
811
842
  const changeType = change.$meta?.op;
812
843
  if (changeType === undefined)
813
844
  throw new Error(`ChangeType was undefined for id: ${change.ECInstanceId}.`);
845
+ if (this._relationshipSubclassIdsToSkip?.has(ecClassId))
846
+ return;
814
847
  if (this.isRelationship(ecClassId))
815
848
  this.handleChange(this.relationship, changeType, change.ECInstanceId);
816
849
  else if (this.isCodeSpec(ecClassId))
@@ -822,6 +855,115 @@ class ChangedInstanceIds {
822
855
  else if (this.isElement(ecClassId))
823
856
  this.handleChange(this.element, changeType, change.ECInstanceId);
824
857
  }
858
+ /**
859
+ * Adds the provided change to the element changes maintained by this instance of ChangedInstanceIds
860
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
861
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
862
+ * @note element changes will also cause the element's model to be marked as updated in [[ChangedInstanceIds.model]], so that the element does not get skipped by the transformer.
863
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.
864
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
865
+ * @beta
866
+ */
867
+ addCustomElementChange(changeType, ids) {
868
+ // if delete unnecessary?
869
+ for (const id of core_bentley_1.Id64.iterable(ids)) {
870
+ this.addModelToUpdated(id);
871
+ this.handleChange(this.element, changeType, id);
872
+ }
873
+ }
874
+ /**
875
+ * Adds the provided change to the codespec changes maintained by this instance of ChangedInstanceIds
876
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
877
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
878
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact a codespec.
879
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
880
+ * @beta
881
+ */
882
+ addCustomCodeSpecChange(changeType, ids) {
883
+ for (const id of core_bentley_1.Id64.iterable(ids)) {
884
+ this.handleChange(this.codeSpec, changeType, id);
885
+ }
886
+ }
887
+ /**
888
+ * Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds.
889
+ * Also adds the model's modeledElement to the element changes. This is to ensure the changes from the model and its modeledElement get exported together.
890
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
891
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
892
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.
893
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
894
+ * @beta
895
+ */
896
+ addCustomModelChange(changeType, ids) {
897
+ for (const id of core_bentley_1.Id64.iterable(ids)) {
898
+ this.handleChange(this.model, changeType, id);
899
+ // Also add the model's modeledElement to the element changes. The modeledElement and model go hand in hand.
900
+ this.handleChange(this.element, changeType, id);
901
+ }
902
+ }
903
+ /**
904
+ * Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds
905
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
906
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
907
+ * @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.
908
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
909
+ * @beta
910
+ */
911
+ addCustomAspectChange(changeType, ids) {
912
+ for (const id of core_bentley_1.Id64.iterable(ids)) {
913
+ this.handleChange(this.aspect, changeType, id);
914
+ }
915
+ }
916
+ /**
917
+ * TODO: Think more about permutations of model updated / inserted / deleted. Can you delete a model without deleting its elements?
918
+ * What if model delete but custom change si to insert element into target?
919
+ * // It is possible and apparently occasionally sensical to delete a model without deleting its underlying element.
920
+ // - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
921
+ // - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
922
+ * TODO: If the element is a custom delete we probably shouldnt be calling this?
923
+ * There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is part of
924
+ * the sourceDbChanges. This method is used in addCustomChange to add the model to the updatedIds set so that the custom element changes are exported.
925
+ */
926
+ addModelToUpdated(elementId) {
927
+ const modelId = this._db.elements.getElement(elementId).model;
928
+ this.handleChange(this.model, "Updated", modelId);
929
+ }
930
+ /** TODO: Maybe relationships only? maybe not.
931
+ * @beta
932
+ */
933
+ getCustomRelationshipDataFromId(id) {
934
+ return this._entityReferenceToCustomDataMap.get(core_backend_1.EntityReferences.fromEntityType(id, core_common_1.ConcreteEntityTypes.Relationship));
935
+ }
936
+ /**
937
+ * Adds the provided change to the set of relationship changes maintained by this instance of ChangedInstanceIds.
938
+ * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'
939
+ * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
940
+ * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.
941
+ * @throws if the ecClassId is NOT a relationship classId
942
+ * @param ecClassId class id of the custom change
943
+ * @param changeType insert, update or delete
944
+ * @param id ECInstanceID of the custom change
945
+ * @param sourceECInstanceId source ECInstanceId of the relationship
946
+ * @param targetECInstanceId target ECInstanceId of the relationship
947
+ * @beta
948
+ */
949
+ async addCustomRelationshipChange(ecClassId, changeType, id, sourceECInstanceId, targetECInstanceId) {
950
+ if (!this._ecClassIdsInitialized)
951
+ await this.setupECClassIds();
952
+ if (this._relationshipSubclassIdsToSkip?.has(ecClassId))
953
+ return;
954
+ if (!this._relationshipSubclassIds?.has(ecClassId))
955
+ throw new Error(`Misuse. id: ${id}, ecClassId: ${ecClassId} is not a relationship class. Use 'addCustomChange' instead.`);
956
+ this._hasCustomRelationshipChanges = true;
957
+ const classFullName = this._ecClassIdsToClassFullNames?.get(ecClassId);
958
+ (0, core_bentley_1.assert)(classFullName !== undefined); // setupECClassIds adds an entry to the above map for every single ECClassId.
959
+ this._entityReferenceToCustomDataMap.set(core_backend_1.EntityReferences.fromEntityType(id, core_common_1.ConcreteEntityTypes.Relationship), {
960
+ sourceIdOfRelationship: sourceECInstanceId,
961
+ targetIdOfRelationship: targetECInstanceId,
962
+ ecClassId,
963
+ classFullName,
964
+ });
965
+ this.handleChange(this.relationship, changeType, id);
966
+ }
825
967
  handleChange(changedInstanceOps, changeType, id) {
826
968
  // if changeType is a delete and we already have the id in the inserts then we can remove the id from the inserts.
827
969
  // if changeType is a delete and we already have the id in the updates then we can remove the id from the updates AND add it to the deletes.
@@ -885,10 +1027,6 @@ class ChangedInstanceIds {
885
1027
  if (csFileProps === undefined)
886
1028
  return undefined;
887
1029
  const changedInstanceIds = new ChangedInstanceIds(opts.iModel);
888
- const relationshipECClassIdsToSkip = new Set();
889
- for await (const row of opts.iModel.createQueryReader("SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (BisCore.ElementDrivesElement)")) {
890
- relationshipECClassIdsToSkip.add(row.ECInstanceId);
891
- }
892
1030
  for (const csFile of csFileProps) {
893
1031
  const csReader = core_backend_1.SqliteChangesetReader.openFile({
894
1032
  fileName: csFile.pathname,
@@ -902,9 +1040,6 @@ class ChangedInstanceIds {
902
1040
  }
903
1041
  const changes = [...ecChangeUnifier.instances];
904
1042
  for (const change of changes) {
905
- if (change.ECClassId !== undefined &&
906
- relationshipECClassIdsToSkip.has(change.ECClassId))
907
- continue;
908
1043
  await changedInstanceIds.addChange(change);
909
1044
  }
910
1045
  csReader.close();