@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 +2 -2
- package/lib/cjs/IModelExporter.d.ts +90 -3
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +154 -19
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +34 -3
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +171 -86
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/package.json +1 -1
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:
|
|
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:
|
|
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":"AAIA;;GAEG;AAEH,OAAO,EACL,WAAW,EAEX,iBAAiB,EAKjB,OAAO,EACP,aAAa,EACb,kBAAkB,EAElB,mBAAmB,
|
|
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
|
|
272
|
-
|
|
273
|
-
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
764
|
-
setToModify.add(row.
|
|
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();
|