@itwin/imodel-transformer 1.0.0 → 1.0.1-customchanges.0
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/EntityUnifier.d.ts +1 -1
- package/lib/cjs/IModelExporter.d.ts +91 -2
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +143 -16
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +23 -2
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +158 -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
|
|
|
@@ -7,7 +7,7 @@ import { EntityReference } from "@itwin/core-common";
|
|
|
7
7
|
import { ConcreteEntity, ConcreteEntityProps, IModelDb } from "@itwin/core-backend";
|
|
8
8
|
/** @internal */
|
|
9
9
|
export declare namespace EntityUnifier {
|
|
10
|
-
export function getReadableType(entity: ConcreteEntity): "element" | "
|
|
10
|
+
export function getReadableType(entity: ConcreteEntity): "element" | "relationship" | "element aspect" | "unknown entity type";
|
|
11
11
|
type EntityUpdater = (entityProps: ConcreteEntityProps) => void;
|
|
12
12
|
/** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
|
|
13
13
|
export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
|
|
@@ -1,7 +1,7 @@
|
|
|
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";
|
|
4
|
+
import { BriefcaseDb, ChangedECInstance, Element, ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb, IModelJsNative, Model, Relationship, SqliteChangeOp } from "@itwin/core-backend";
|
|
5
5
|
import { Id64String } from "@itwin/core-bentley";
|
|
6
6
|
import { ChangesetFileProps, CodeSpec, FontProps } from "@itwin/core-common";
|
|
7
7
|
import { Schema, SchemaKey } from "@itwin/ecschema-metadata";
|
|
@@ -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. */
|
|
@@ -230,6 +230,16 @@ export declare class IModelExporter {
|
|
|
230
230
|
* you pass to [[IModelExporter.exportChanges]]
|
|
231
231
|
*/
|
|
232
232
|
initialize(options: ExporterInitOptions): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* This function is called by the transformer as it is about to process the changesets passed to it in [[IModelTransformOptions.argsForProcessChanges]].
|
|
235
|
+
* This would be after the exporter has already processed the same set of changesets passed to the transformer in [[IModelTransformOptions.argsForProcessChanges]].
|
|
236
|
+
* This function should be used to modify the exporter's sourceDbChanges, if necessary, using [[ChangedInstanceIds.addCustomChange]]. See [[ChangedInstanceIds.addCustomChange]] for more information.
|
|
237
|
+
* @note [[IModelExporter.sourceDbChanges]] will only be defined if the transformer was called with [[IModelTransformOptions.argsForProcessChanges]].
|
|
238
|
+
* @note If defined, sourceDbChanges will already be populated with the changesets passed to the transformer, if any when this function is called by the transformer.
|
|
239
|
+
* @note The transformer will have built up the remap table between the source and target iModels before calling this function. This means that functions like [[IModelTransformer.context.findTargetElementId]] will return meaningful results.
|
|
240
|
+
* @note Its expected that this function be overridden by a subclass of exporter if it needs to modify sourceDbChanges.
|
|
241
|
+
*/
|
|
242
|
+
addCustomChanges(): void;
|
|
233
243
|
/** Register the handler that will be called by IModelExporter. */
|
|
234
244
|
registerHandler(handler: IModelExportHandler): void;
|
|
235
245
|
/** Add a rule to exclude a CodeSpec */
|
|
@@ -346,6 +356,18 @@ export declare class ChangedInstanceOps {
|
|
|
346
356
|
deleteIds: Set<string>;
|
|
347
357
|
/** Initializes the object from IModelJsNative.ChangedInstanceOpsProps. */
|
|
348
358
|
addFromJson(val: IModelJsNative.ChangedInstanceOpsProps | undefined): void;
|
|
359
|
+
get isEmpty(): boolean;
|
|
360
|
+
}
|
|
361
|
+
export type ChangedInstanceType = "codeSpec" | "model" | "element" | "aspect" | "relationship" | "font";
|
|
362
|
+
/**
|
|
363
|
+
* 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.
|
|
364
|
+
* 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.
|
|
365
|
+
*/
|
|
366
|
+
export interface ChangedInstanceCustomRelationshipData {
|
|
367
|
+
sourceIdOfRelationship: Id64String;
|
|
368
|
+
targetIdOfRelationship: Id64String;
|
|
369
|
+
ecClassId: Id64String;
|
|
370
|
+
classFullName: string;
|
|
349
371
|
}
|
|
350
372
|
/**
|
|
351
373
|
* Class for discovering modified elements between 2 versions of an iModel.
|
|
@@ -363,6 +385,11 @@ export declare class ChangedInstanceIds {
|
|
|
363
385
|
private _elementSubclassIds?;
|
|
364
386
|
private _aspectSubclassIds?;
|
|
365
387
|
private _relationshipSubclassIds?;
|
|
388
|
+
private _relationshipSubclassIdsToSkip?;
|
|
389
|
+
private _ecClassIdsToClassFullNames?;
|
|
390
|
+
/** 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. */
|
|
391
|
+
private _entityReferenceToCustomDataMap;
|
|
392
|
+
private _hasCustomChanges;
|
|
366
393
|
private _db;
|
|
367
394
|
constructor(db: IModelDb);
|
|
368
395
|
private setupECClassIds;
|
|
@@ -372,6 +399,8 @@ export declare class ChangedInstanceIds {
|
|
|
372
399
|
private isAspect;
|
|
373
400
|
private isModel;
|
|
374
401
|
private isElement;
|
|
402
|
+
get hasCustomChanges(): boolean;
|
|
403
|
+
get isEmpty(): boolean;
|
|
375
404
|
/**
|
|
376
405
|
* 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
406
|
* 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 +408,66 @@ export declare class ChangedInstanceIds {
|
|
|
379
408
|
* @param change ChangedECInstance which has the ECInstanceId, changeType (insert, update, delete) and ECClassId of the changed entity
|
|
380
409
|
*/
|
|
381
410
|
addChange(change: ChangedECInstance): Promise<void>;
|
|
411
|
+
/**
|
|
412
|
+
* Adds the provided change to the element changes maintained by this instance of ChangedInstanceIds
|
|
413
|
+
* 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'
|
|
414
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
415
|
+
* @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.
|
|
416
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.
|
|
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
|
+
*/
|
|
419
|
+
addCustomElementChange(changeType: SqliteChangeOp, id: Id64String): void;
|
|
420
|
+
/**
|
|
421
|
+
* Adds the provided change to the codespec changes maintained by this instance of ChangedInstanceIds
|
|
422
|
+
* 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'
|
|
423
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
424
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact a codespec.
|
|
425
|
+
* @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.
|
|
426
|
+
*/
|
|
427
|
+
addCustomCodeSpecChange(changeType: SqliteChangeOp, id: Id64String): void;
|
|
428
|
+
/**
|
|
429
|
+
* Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds
|
|
430
|
+
* 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'
|
|
431
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
432
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.
|
|
433
|
+
* @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.
|
|
434
|
+
*/
|
|
435
|
+
addCustomModelChange(changeType: SqliteChangeOp, id: Id64String): void;
|
|
436
|
+
/**
|
|
437
|
+
* Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds
|
|
438
|
+
* 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'
|
|
439
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
440
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.
|
|
441
|
+
* @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.
|
|
442
|
+
*/
|
|
443
|
+
addCustomAspectChange(changeType: SqliteChangeOp, id: Id64String): void;
|
|
444
|
+
/**
|
|
445
|
+
* TODO: Think more about permutations of model updated / inserted / deleted. Can you delete a model without deleting its elements?
|
|
446
|
+
* What if model delete but custom change si to insert element into target?
|
|
447
|
+
* // It is possible and apparently occasionally sensical to delete a model without deleting its underlying element.
|
|
448
|
+
// - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
|
|
449
|
+
// - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
|
|
450
|
+
* TODO: If the element is a custom delete we probably shouldnt be calling this?
|
|
451
|
+
* There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is part of
|
|
452
|
+
* the sourceDbChanges. This method is used in addCustomChange to add the model to the updatedIds set so that the custom element changes are exported.
|
|
453
|
+
*/
|
|
454
|
+
private addModelToUpdated;
|
|
455
|
+
/** TODO: Maybe relationships only? maybe not. */
|
|
456
|
+
getCustomRelationshipDataFromId(id: Id64String, type: ChangedInstanceType): ChangedInstanceCustomRelationshipData | undefined;
|
|
457
|
+
/**
|
|
458
|
+
* Adds the provided change to the set of relationship changes maintained by this instance of ChangedInstanceIds.
|
|
459
|
+
* 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'
|
|
460
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
461
|
+
* @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.
|
|
462
|
+
* @throws if the ecClassId is NOT a relationship classId
|
|
463
|
+
* @param ecClassId class id of the custom change
|
|
464
|
+
* @param changeType insert, update or delete
|
|
465
|
+
* @param id ECInstanceID of the custom change
|
|
466
|
+
* @param sourceECInstanceId source ECInstanceId of the relationship
|
|
467
|
+
* @param targetECInstanceId target ECInstanceId of the relationship
|
|
468
|
+
*/
|
|
469
|
+
addCustomRelationshipChange(ecClassId: string, changeType: SqliteChangeOp, id: Id64String, sourceECInstanceId: Id64String, targetECInstanceId: Id64String): Promise<void>;
|
|
470
|
+
private getClassFullNameFromECClassId;
|
|
382
471
|
private handleChange;
|
|
383
472
|
/**
|
|
384
473
|
* 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":"AAIA;;GAEG;AAEH,OAAO,EACL,WAAW,EAEX,iBAAiB,EAKjB,OAAO,EACP,aAAa,EACb,kBAAkB,EAElB,mBAAmB,EAGnB,QAAQ,EAER,cAAc,EACd,KAAK,EAGL,YAAY,EACZ,cAAc,EAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,UAAU,EAIX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,QAAQ,EAGR,SAAS,EAGV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,MAAM,EACN,SAAS,EAEV,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,gCAAgC,CAAC;AAKxC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C,CAAC;;;GAGC,GAAG,CACF;IAAE,WAAW,EAAE,kBAAkB,EAAE,CAAA;CAAE;AACvC;;;;;GAKG;GACD;IAAE,kBAAkB,EAAE,kBAAkB,CAAA;CAAE;AAC5C;;;GAGG;GACD;IAAE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE;AACzC;;;;;GAKG;GACD;IAAE,cAAc,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACnD,EAAE,CACL,CAAC;AAEF;;;;;GAKG;AACH,8BAAsB,mBAAmB;IACvC;;OAEG;IACI,oBAAoB,CAAC,SAAS,EAAE,QAAQ,GAAG,OAAO;IAIzD;;;;OAIG;IACI,gBAAgB,CACrB,SAAS,EAAE,QAAQ,EACnB,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,IAAI;IAEP;;;;OAIG;IACI,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI;IAE3E;;;;OAIG;IACI,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI;IAEzE,6CAA6C;IACtC,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;IAEhD;;OAEG;IACI,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO;IAItD;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAElD;;;;OAIG;IACI,eAAe,CACpB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,IAAI;IAEP;;;;;OAKG;IACU,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/D,gDAAgD;IACzC,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAEpD;;OAEG;IACI,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAIjE;;;;OAIG;IACI,2BAA2B,CAChC,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,IAAI;IAEP;;OAEG;IACI,2BAA2B,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,IAAI;IAExE;;OAEG;IACI,wBAAwB,CAAC,aAAa,EAAE,YAAY,GAAG,OAAO;IAIrE;;;;OAIG;IACI,oBAAoB,CACzB,aAAa,EAAE,YAAY,EAC3B,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,IAAI;IAEP,oDAAoD;IAC7C,oBAAoB,CAAC,cAAc,EAAE,UAAU,GAAG,IAAI;IAE7D;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO;IAIzD;;;;;OAKG;IACU,cAAc,CACzB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,GAAG,kBAAkB,CAAC;IAErC;;;OAGG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,mCAAmC;IACnC,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC;;;;;OAKG;IACI,YAAY,EAAE,OAAO,CAAQ;IACpC;;;OAGG;IACI,kBAAkB,EAAE,OAAO,CAAQ;IAC1C;;;OAGG;IACI,iBAAiB,EAAE,OAAO,CAAQ;IACzC;;OAEG;IACI,aAAa,EAAE,OAAO,CAAQ;IACrC;;OAEG;IACI,kBAAkB,EAAE,OAAO,CAAQ;IAC1C,sHAAsH;IAC/G,gBAAgB,EAAE,MAAM,CAAQ;IACvC,4DAA4D;IAC5D,OAAO,CAAC,gBAAgB,CAAa;IACrC,kDAAkD;IAClD,OAAO,CAAC,gBAAgB,CAAC,CAAqB;IAE9C;;;OAGG;IACH,IAAW,eAAe,IAAI,kBAAkB,GAAG,SAAS,CAE3D;IACD,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAkC;IAClD,iDAAiD;IACjD,SAAS,KAAK,OAAO,IAAI,mBAAmB,CAM3C;IAED,uDAAuD;IACvD,OAAO,CAAC,sBAAsB,CAAqB;IACnD,+DAA+D;IAC/D,OAAO,CAAC,mBAAmB,CAAyB;IACpD,uHAAuH;IACvH,OAAO,CAAC,2BAA2B,CAAyB;IAC5D,uHAAuH;IACvH,OAAO,CAAC,uBAAuB,CAA6B;IAC5D,4HAA4H;IAC5H,OAAO,CAAC,4BAA4B,CAAkC;IAEtE,mDAAmD;IACnD,OAAO,CAAC,6BAA6B,CAA+B;IAEpE;;;OAGG;gBAED,QAAQ,EAAE,QAAQ,EAClB,sBAAsB,GAAE,KACtB,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,qBAAqB,KAC3B,4BAAuE;IAiB9E;;;;;;OAMG;IACU,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpE;;;;;;;;OAQG;IACI,gBAAgB,IAAI,IAAI;IAE/B,kEAAkE;IAC3D,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI1D,uCAAuC;IAChC,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAIlD,gDAAgD;IACzC,cAAc,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAIlD,kEAAkE;IAC3D,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAI9D,+DAA+D;IACxD,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAMvD,qEAAqE;IAC9D,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAI7D,oEAAoE;IAC7D,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAM5D;;OAEG;IACU,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC;;;;;;OAMG;IACU,aAAa,CAAC,IAAI,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2EtE,OAAO,CAAC,wBAAwB,CAAQ;IAExC;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C3C,sDAAsD;IACtD,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAc7C;;OAEG;IACU,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BtE;;OAEG;IACU,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtE;;OAEG;IACU,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzC;;OAEG;IACU,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9D;;OAEG;IACU,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlE;;OAEG;IACU,WAAW,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBrE,oEAAoE;YACtD,oBAAoB;IAgBlC,OAAO,CAAC,aAAa,CAAsB;IAE3C;;;;;OAKG;IACU,mBAAmB,CAC9B,OAAO,EAAE,UAAU,EACnB,oBAAoB,GAAE,MAA8B,EACpD,eAAe,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,IAAI,CAAC;IA4ChB;;OAEG;IACU,eAAe,CAAC,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BtE;;;OAGG;IACI,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAqCrD;;OAEG;IACU,aAAa,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDhE;;OAEG;IACU,mBAAmB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBtE;OACG;YACW,gBAAgB;IAI9B;;OAEG;IACU,mBAAmB,CAC9B,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC,IAAI,CAAC;IA+BhB,oDAAoD;IACvC,kBAAkB,CAC7B,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,UAAU,GACxB,OAAO,CAAC,IAAI,CAAC;IA8ChB,kCAAkC;YACpB,aAAa;CAM5B;AAED;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,oBAAoB,GAAG;IACjE,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,qBAAa,kBAAkB;IACtB,SAAS,cAAyB;IAClC,SAAS,cAAyB;IAClC,SAAS,cAAyB;IAEzC,0EAA0E;IACnE,WAAW,CAChB,GAAG,EAAE,cAAc,CAAC,uBAAuB,GAAG,SAAS,GACtD,IAAI;IAaP,IAAW,OAAO,IAAI,OAAO,CAM5B;CACF;AAED,MAAM,MAAM,mBAAmB,GAC3B,UAAU,GACV,OAAO,GACP,SAAS,GACT,QAAQ,GACR,cAAc,GACd,MAAM,CAAC;AAEX;;;GAGG;AACH,MAAM,WAAW,qCAAqC;IACpD,sBAAsB,EAAE,UAAU,CAAC;IACnC,sBAAsB,EAAE,UAAU,CAAC;IACnC,SAAS,EAAE,UAAU,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IACtB,QAAQ,qBAA4B;IACpC,KAAK,qBAA4B;IACjC,OAAO,qBAA4B;IACnC,MAAM,qBAA4B;IAClC,YAAY,qBAA4B;IACxC,IAAI,qBAA4B;IACvC,OAAO,CAAC,oBAAoB,CAAC,CAAc;IAC3C,OAAO,CAAC,iBAAiB,CAAC,CAAc;IACxC,OAAO,CAAC,mBAAmB,CAAC,CAAc;IAC1C,OAAO,CAAC,kBAAkB,CAAC,CAAc;IACzC,OAAO,CAAC,wBAAwB,CAAC,CAAc;IAC/C,OAAO,CAAC,8BAA8B,CAAC,CAAc;IACrD,OAAO,CAAC,2BAA2B,CAAC,CAAsB;IAC1D,gMAAgM;IAChM,OAAO,CAAC,+BAA+B,CAGrC;IACF,OAAO,CAAC,iBAAiB,CAAU;IAEnC,OAAO,CAAC,GAAG,CAAW;gBACH,EAAE,EAAE,QAAQ;YASjB,eAAe;IA4C7B,OAAO,KAAK,sBAAsB,GASjC;IAED,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,SAAS;IAIjB,IAAW,gBAAgB,IAAI,OAAO,CAErC;IAED,IAAW,OAAO,IAAI,OAAO,CAS5B;IAED;;;;;OAKG;IACU,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BhE;;;;;;;OAOG;IACI,sBAAsB,CAC3B,UAAU,EAAE,cAAc,EAC1B,EAAE,EAAE,UAAU,GACb,IAAI;IAMP;;;;;;OAMG;IACI,uBAAuB,CAC5B,UAAU,EAAE,cAAc,EAC1B,EAAE,EAAE,UAAU,GACb,IAAI;IAIP;;;;;;OAMG;IACI,oBAAoB,CACzB,UAAU,EAAE,cAAc,EAC1B,EAAE,EAAE,UAAU,GACb,IAAI;IAIP;;;;;;OAMG;IACI,qBAAqB,CAC1B,UAAU,EAAE,cAAc,EAC1B,EAAE,EAAE,UAAU,GACb,IAAI;IAIP;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAKzB,iDAAiD;IAC1C,+BAA+B,CACpC,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,mBAAmB,GACxB,qCAAqC,GAAG,SAAS;IAUpD;;;;;;;;;;;OAWG;IACU,2BAA2B,CACtC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,cAAc,EAC1B,EAAE,EAAE,UAAU,EACd,kBAAkB,EAAE,UAAU,EAC9B,kBAAkB,EAAE,UAAU,GAC7B,OAAO,CAAC,IAAI,CAAC;IAuBhB,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,YAAY;IAyBpB;;;OAGG;WACiB,UAAU,CAC5B,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;CAyE3C"}
|
|
@@ -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;
|
|
@@ -216,6 +216,16 @@ class IModelExporter {
|
|
|
216
216
|
return;
|
|
217
217
|
this._exportElementAspectsStrategy.setAspectChanges(this._sourceDbChanges.aspect);
|
|
218
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* This function is called by the transformer as it is about to process the changesets passed to it in [[IModelTransformOptions.argsForProcessChanges]].
|
|
221
|
+
* This would be after the exporter has already processed the same set of changesets passed to the transformer in [[IModelTransformOptions.argsForProcessChanges]].
|
|
222
|
+
* This function should be used to modify the exporter's sourceDbChanges, if necessary, using [[ChangedInstanceIds.addCustomChange]]. See [[ChangedInstanceIds.addCustomChange]] for more information.
|
|
223
|
+
* @note [[IModelExporter.sourceDbChanges]] will only be defined if the transformer was called with [[IModelTransformOptions.argsForProcessChanges]].
|
|
224
|
+
* @note If defined, sourceDbChanges will already be populated with the changesets passed to the transformer, if any when this function is called by the transformer.
|
|
225
|
+
* @note The transformer will have built up the remap table between the source and target iModels before calling this function. This means that functions like [[IModelTransformer.context.findTargetElementId]] will return meaningful results.
|
|
226
|
+
* @note Its expected that this function be overridden by a subclass of exporter if it needs to modify sourceDbChanges.
|
|
227
|
+
*/
|
|
228
|
+
addCustomChanges() { }
|
|
219
229
|
/** Register the handler that will be called by IModelExporter. */
|
|
220
230
|
registerHandler(handler) {
|
|
221
231
|
this._handler = handler;
|
|
@@ -268,7 +278,8 @@ class IModelExporter {
|
|
|
268
278
|
await this.exportAll(); // no changesets, so revert to exportAll
|
|
269
279
|
return;
|
|
270
280
|
}
|
|
271
|
-
const startChangeset =
|
|
281
|
+
const startChangeset = // TODO: This is weird.. why is this needed? I suspect we can remove this and just pass args to initialize?
|
|
282
|
+
args && "startChangeset" in args ? args.startChangeset : undefined;
|
|
272
283
|
const initOpts = {
|
|
273
284
|
startChangeset: { id: startChangeset?.id },
|
|
274
285
|
};
|
|
@@ -384,7 +395,7 @@ class IModelExporter {
|
|
|
384
395
|
async exportCodeSpecByName(codeSpecName) {
|
|
385
396
|
const codeSpec = this.sourceDb.codeSpecs.getByName(codeSpecName);
|
|
386
397
|
let isUpdate;
|
|
387
|
-
if (
|
|
398
|
+
if (this._sourceDbChanges !== undefined) {
|
|
388
399
|
// is changeset information available?
|
|
389
400
|
if (this._sourceDbChanges.codeSpec.insertIds.has(codeSpec.id)) {
|
|
390
401
|
isUpdate = false;
|
|
@@ -476,7 +487,7 @@ class IModelExporter {
|
|
|
476
487
|
/** Export the model (the container only) from the source iModel. */
|
|
477
488
|
async exportModelContainer(model) {
|
|
478
489
|
let isUpdate;
|
|
479
|
-
if (
|
|
490
|
+
if (this._sourceDbChanges !== undefined) {
|
|
480
491
|
// is changeset information available?
|
|
481
492
|
if (this._sourceDbChanges.model.insertIds.has(model.id)) {
|
|
482
493
|
isUpdate = false;
|
|
@@ -507,7 +518,7 @@ class IModelExporter {
|
|
|
507
518
|
core_bentley_1.Logger.logTrace(loggerCategory, `visitElements=false, skipping exportModelContents(${modelId})`);
|
|
508
519
|
return;
|
|
509
520
|
}
|
|
510
|
-
if (
|
|
521
|
+
if (this._sourceDbChanges !== undefined) {
|
|
511
522
|
// is changeset information available?
|
|
512
523
|
if (!this._sourceDbChanges.model.insertIds.has(modelId) &&
|
|
513
524
|
!this._sourceDbChanges.model.updateIds.has(modelId)) {
|
|
@@ -681,7 +692,7 @@ class IModelExporter {
|
|
|
681
692
|
return;
|
|
682
693
|
}
|
|
683
694
|
let isUpdate;
|
|
684
|
-
if (
|
|
695
|
+
if (this._sourceDbChanges !== undefined) {
|
|
685
696
|
// is changeset information available?
|
|
686
697
|
if (this._sourceDbChanges.relationship.insertIds.has(relInstanceId)) {
|
|
687
698
|
isUpdate = false;
|
|
@@ -737,6 +748,11 @@ class ChangedInstanceOps {
|
|
|
737
748
|
val.delete.forEach((id) => this.deleteIds.add(id));
|
|
738
749
|
}
|
|
739
750
|
}
|
|
751
|
+
get isEmpty() {
|
|
752
|
+
return (0 === this.insertIds.size &&
|
|
753
|
+
0 === this.updateIds.size &&
|
|
754
|
+
0 === this.deleteIds.size);
|
|
755
|
+
}
|
|
740
756
|
}
|
|
741
757
|
exports.ChangedInstanceOps = ChangedInstanceOps;
|
|
742
758
|
/**
|
|
@@ -752,6 +768,8 @@ class ChangedInstanceIds {
|
|
|
752
768
|
this.relationship = new ChangedInstanceOps();
|
|
753
769
|
this.font = new ChangedInstanceOps();
|
|
754
770
|
this._db = db;
|
|
771
|
+
this._hasCustomChanges = false;
|
|
772
|
+
this._entityReferenceToCustomDataMap = new Map();
|
|
755
773
|
}
|
|
756
774
|
async setupECClassIds() {
|
|
757
775
|
this._codeSpecSubclassIds = new Set();
|
|
@@ -759,9 +777,12 @@ class ChangedInstanceIds {
|
|
|
759
777
|
this._elementSubclassIds = new Set();
|
|
760
778
|
this._aspectSubclassIds = new Set();
|
|
761
779
|
this._relationshipSubclassIds = new Set();
|
|
780
|
+
this._relationshipSubclassIdsToSkip = new Set();
|
|
781
|
+
this._ecClassIdsToClassFullNames = new Map();
|
|
762
782
|
const addECClassIdsToSet = async (setToModify, baseClass) => {
|
|
763
|
-
for await (const row of this._db.createQueryReader(`SELECT ECInstanceId FROM ECDbMeta.ECClassDef
|
|
764
|
-
setToModify.add(row.
|
|
783
|
+
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})`)) {
|
|
784
|
+
setToModify.add(row.ECClassId);
|
|
785
|
+
this._ecClassIdsToClassFullNames?.set(row.ECClassId, `${row.schemaName}:${row.className}`);
|
|
765
786
|
}
|
|
766
787
|
};
|
|
767
788
|
const promises = [
|
|
@@ -771,6 +792,7 @@ class ChangedInstanceIds {
|
|
|
771
792
|
addECClassIdsToSet(this._aspectSubclassIds, "BisCore.ElementUniqueAspect"),
|
|
772
793
|
addECClassIdsToSet(this._aspectSubclassIds, "BisCore.ElementMultiAspect"),
|
|
773
794
|
addECClassIdsToSet(this._relationshipSubclassIds, "BisCore.ElementRefersToElements"),
|
|
795
|
+
addECClassIdsToSet(this._relationshipSubclassIdsToSkip, "BisCore.ElementDrivesElement"),
|
|
774
796
|
];
|
|
775
797
|
await Promise.all(promises);
|
|
776
798
|
}
|
|
@@ -779,7 +801,8 @@ class ChangedInstanceIds {
|
|
|
779
801
|
this._modelSubclassIds &&
|
|
780
802
|
this._elementSubclassIds &&
|
|
781
803
|
this._aspectSubclassIds &&
|
|
782
|
-
this._relationshipSubclassIds
|
|
804
|
+
this._relationshipSubclassIds &&
|
|
805
|
+
this._relationshipSubclassIdsToSkip);
|
|
783
806
|
}
|
|
784
807
|
isRelationship(ecClassId) {
|
|
785
808
|
return this._relationshipSubclassIds?.has(ecClassId);
|
|
@@ -796,6 +819,17 @@ class ChangedInstanceIds {
|
|
|
796
819
|
isElement(ecClassId) {
|
|
797
820
|
return this._elementSubclassIds?.has(ecClassId);
|
|
798
821
|
}
|
|
822
|
+
get hasCustomChanges() {
|
|
823
|
+
return this._hasCustomChanges;
|
|
824
|
+
}
|
|
825
|
+
get isEmpty() {
|
|
826
|
+
return (this.codeSpec.isEmpty &&
|
|
827
|
+
this.model.isEmpty &&
|
|
828
|
+
this.element.isEmpty &&
|
|
829
|
+
this.aspect.isEmpty &&
|
|
830
|
+
this.relationship.isEmpty &&
|
|
831
|
+
this.font.isEmpty);
|
|
832
|
+
}
|
|
799
833
|
/**
|
|
800
834
|
* 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
835
|
* 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 +845,8 @@ class ChangedInstanceIds {
|
|
|
811
845
|
const changeType = change.$meta?.op;
|
|
812
846
|
if (changeType === undefined)
|
|
813
847
|
throw new Error(`ChangeType was undefined for id: ${change.ECInstanceId}.`);
|
|
848
|
+
if (this._relationshipSubclassIdsToSkip?.has(ecClassId))
|
|
849
|
+
return;
|
|
814
850
|
if (this.isRelationship(ecClassId))
|
|
815
851
|
this.handleChange(this.relationship, changeType, change.ECInstanceId);
|
|
816
852
|
else if (this.isCodeSpec(ecClassId))
|
|
@@ -822,6 +858,104 @@ class ChangedInstanceIds {
|
|
|
822
858
|
else if (this.isElement(ecClassId))
|
|
823
859
|
this.handleChange(this.element, changeType, change.ECInstanceId);
|
|
824
860
|
}
|
|
861
|
+
/**
|
|
862
|
+
* Adds the provided change to the element changes maintained by this instance of ChangedInstanceIds
|
|
863
|
+
* 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'
|
|
864
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
865
|
+
* @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.
|
|
866
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.
|
|
867
|
+
* @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.
|
|
868
|
+
*/
|
|
869
|
+
addCustomElementChange(changeType, id // TODO: Support bulk adds
|
|
870
|
+
) {
|
|
871
|
+
// if delete unnecessary?
|
|
872
|
+
this.addModelToUpdated(id);
|
|
873
|
+
this.handleChange(this.element, changeType, id);
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Adds the provided change to the codespec changes maintained by this instance of ChangedInstanceIds
|
|
877
|
+
* 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'
|
|
878
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
879
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact a codespec.
|
|
880
|
+
* @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.
|
|
881
|
+
*/
|
|
882
|
+
addCustomCodeSpecChange(changeType, id) {
|
|
883
|
+
this.handleChange(this.codeSpec, changeType, id);
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds
|
|
887
|
+
* 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'
|
|
888
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
889
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.
|
|
890
|
+
* @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.
|
|
891
|
+
*/
|
|
892
|
+
addCustomModelChange(changeType, id) {
|
|
893
|
+
this.handleChange(this.model, changeType, id);
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds
|
|
897
|
+
* 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'
|
|
898
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
899
|
+
* @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.
|
|
900
|
+
* @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.
|
|
901
|
+
*/
|
|
902
|
+
addCustomAspectChange(changeType, id) {
|
|
903
|
+
this.handleChange(this.aspect, changeType, id);
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* TODO: Think more about permutations of model updated / inserted / deleted. Can you delete a model without deleting its elements?
|
|
907
|
+
* What if model delete but custom change si to insert element into target?
|
|
908
|
+
* // It is possible and apparently occasionally sensical to delete a model without deleting its underlying element.
|
|
909
|
+
// - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
|
|
910
|
+
// - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
|
|
911
|
+
* TODO: If the element is a custom delete we probably shouldnt be calling this?
|
|
912
|
+
* There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is part of
|
|
913
|
+
* the sourceDbChanges. This method is used in addCustomChange to add the model to the updatedIds set so that the custom element changes are exported.
|
|
914
|
+
*/
|
|
915
|
+
addModelToUpdated(elementId) {
|
|
916
|
+
const modelId = this._db.elements.getElement(elementId).model;
|
|
917
|
+
this.handleChange(this.model, "Updated", modelId);
|
|
918
|
+
}
|
|
919
|
+
/** TODO: Maybe relationships only? maybe not. */
|
|
920
|
+
getCustomRelationshipDataFromId(id, type) {
|
|
921
|
+
if (type === "relationship") {
|
|
922
|
+
return this._entityReferenceToCustomDataMap.get(core_backend_1.EntityReferences.fromEntityType(id, core_common_1.ConcreteEntityTypes.Relationship));
|
|
923
|
+
}
|
|
924
|
+
return undefined;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Adds the provided change to the set of relationship changes maintained by this instance of ChangedInstanceIds.
|
|
928
|
+
* 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'
|
|
929
|
+
* from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.
|
|
930
|
+
* @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.
|
|
931
|
+
* @throws if the ecClassId is NOT a relationship classId
|
|
932
|
+
* @param ecClassId class id of the custom change
|
|
933
|
+
* @param changeType insert, update or delete
|
|
934
|
+
* @param id ECInstanceID of the custom change
|
|
935
|
+
* @param sourceECInstanceId source ECInstanceId of the relationship
|
|
936
|
+
* @param targetECInstanceId target ECInstanceId of the relationship
|
|
937
|
+
*/
|
|
938
|
+
async addCustomRelationshipChange(ecClassId, changeType, id, sourceECInstanceId, targetECInstanceId) {
|
|
939
|
+
if (!this._ecClassIdsInitialized)
|
|
940
|
+
await this.setupECClassIds();
|
|
941
|
+
if (this._relationshipSubclassIdsToSkip?.has(ecClassId))
|
|
942
|
+
return;
|
|
943
|
+
if (!this._relationshipSubclassIds?.has(ecClassId))
|
|
944
|
+
throw new Error(`Misuse. id: ${id}, ecClassId: ${ecClassId} is not a relationship class. Use 'addCustomChange' instead.`);
|
|
945
|
+
this._hasCustomChanges = true;
|
|
946
|
+
const classFullName = this._ecClassIdsToClassFullNames?.get(ecClassId);
|
|
947
|
+
(0, core_bentley_1.assert)(classFullName !== undefined); // setupECClassIds adds an entry to the above map for every single ECClassId.
|
|
948
|
+
this._entityReferenceToCustomDataMap.set(core_backend_1.EntityReferences.fromEntityType(id, core_common_1.ConcreteEntityTypes.Relationship), {
|
|
949
|
+
sourceIdOfRelationship: sourceECInstanceId,
|
|
950
|
+
targetIdOfRelationship: targetECInstanceId,
|
|
951
|
+
ecClassId,
|
|
952
|
+
classFullName,
|
|
953
|
+
});
|
|
954
|
+
this.handleChange(this.relationship, changeType, id);
|
|
955
|
+
}
|
|
956
|
+
getClassFullNameFromECClassId(ecClassid) {
|
|
957
|
+
return this._ecClassIdsToClassFullNames?.get(ecClassid);
|
|
958
|
+
}
|
|
825
959
|
handleChange(changedInstanceOps, changeType, id) {
|
|
826
960
|
// if changeType is a delete and we already have the id in the inserts then we can remove the id from the inserts.
|
|
827
961
|
// 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 +1019,6 @@ class ChangedInstanceIds {
|
|
|
885
1019
|
if (csFileProps === undefined)
|
|
886
1020
|
return undefined;
|
|
887
1021
|
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
1022
|
for (const csFile of csFileProps) {
|
|
893
1023
|
const csReader = core_backend_1.SqliteChangesetReader.openFile({
|
|
894
1024
|
fileName: csFile.pathname,
|
|
@@ -902,9 +1032,6 @@ class ChangedInstanceIds {
|
|
|
902
1032
|
}
|
|
903
1033
|
const changes = [...ecChangeUnifier.instances];
|
|
904
1034
|
for (const change of changes) {
|
|
905
|
-
if (change.ECClassId !== undefined &&
|
|
906
|
-
relationshipECClassIdsToSkip.has(change.ECClassId))
|
|
907
|
-
continue;
|
|
908
1035
|
await changedInstanceIds.addChange(change);
|
|
909
1036
|
}
|
|
910
1037
|
csReader.close();
|