@itwin/imodel-transformer 2.0.0-dev.5 → 2.0.0-dev.50

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.
Files changed (115) hide show
  1. package/README.md +13 -27
  2. package/lib/cjs/Algo.js.map +1 -1
  3. package/lib/cjs/BigMap.d.ts.map +1 -1
  4. package/lib/cjs/BigMap.js.map +1 -1
  5. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  6. package/lib/cjs/BranchProvenanceInitializer.js +34 -36
  7. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  8. package/lib/cjs/ChangesetScanner.d.ts +60 -0
  9. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  10. package/lib/cjs/ChangesetScanner.js +101 -0
  11. package/lib/cjs/ChangesetScanner.js.map +1 -0
  12. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -3
  13. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  14. package/lib/cjs/ECReferenceTypesCache.js +61 -103
  15. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  16. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
  17. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
  18. package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
  19. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  20. package/lib/cjs/ElementAspectCleanup.js +83 -0
  21. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  22. package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
  23. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  24. package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
  25. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  26. package/lib/cjs/ElementAspectExportProcessor.d.ts +43 -0
  27. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  28. package/lib/cjs/ElementAspectExportProcessor.js +167 -0
  29. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  30. package/lib/cjs/ElementCascadingDeleter.d.ts +3 -3
  31. package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
  32. package/lib/cjs/ElementCascadingDeleter.js +12 -12
  33. package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
  34. package/lib/cjs/EntityExistenceCache.d.ts +43 -0
  35. package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
  36. package/lib/cjs/EntityExistenceCache.js +91 -0
  37. package/lib/cjs/EntityExistenceCache.js.map +1 -0
  38. package/lib/cjs/EntityMap.d.ts.map +1 -1
  39. package/lib/cjs/EntityMap.js.map +1 -1
  40. package/lib/cjs/EntityUnifier.d.ts +8 -8
  41. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  42. package/lib/cjs/EntityUnifier.js +55 -32
  43. package/lib/cjs/EntityUnifier.js.map +1 -1
  44. package/lib/cjs/IModelCloneContext.d.ts +11 -5
  45. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  46. package/lib/cjs/IModelCloneContext.js +94 -58
  47. package/lib/cjs/IModelCloneContext.js.map +1 -1
  48. package/lib/cjs/IModelExporter.d.ts +108 -34
  49. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  50. package/lib/cjs/IModelExporter.js +702 -208
  51. package/lib/cjs/IModelExporter.js.map +1 -1
  52. package/lib/cjs/IModelImporter.d.ts +50 -25
  53. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  54. package/lib/cjs/IModelImporter.js +231 -130
  55. package/lib/cjs/IModelImporter.js.map +1 -1
  56. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  57. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  58. package/lib/cjs/IModelTransformContext.js +3 -0
  59. package/lib/cjs/IModelTransformContext.js.map +1 -0
  60. package/lib/cjs/IModelTransformer.d.ts +125 -203
  61. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  62. package/lib/cjs/IModelTransformer.js +646 -1190
  63. package/lib/cjs/IModelTransformer.js.map +1 -1
  64. package/lib/cjs/IModelTransformerError.d.ts +82 -0
  65. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  66. package/lib/cjs/IModelTransformerError.js +91 -0
  67. package/lib/cjs/IModelTransformerError.js.map +1 -0
  68. package/lib/cjs/ProvenanceManager.d.ts +182 -0
  69. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  70. package/lib/cjs/ProvenanceManager.js +743 -0
  71. package/lib/cjs/ProvenanceManager.js.map +1 -0
  72. package/lib/cjs/SyncTypeResolver.d.ts +34 -0
  73. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  74. package/lib/cjs/SyncTypeResolver.js +98 -0
  75. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  76. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  77. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  78. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  79. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  80. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  81. package/lib/cjs/TransformerPackageMetadata.js +47 -0
  82. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  83. package/lib/cjs/imodel-transformer.d.ts +19 -0
  84. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  85. package/lib/cjs/imodel-transformer.js +53 -34
  86. package/lib/cjs/imodel-transformer.js.map +1 -1
  87. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
  88. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  89. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
  90. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  91. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
  92. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  93. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
  94. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  95. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
  96. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  97. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
  98. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  99. package/lib/cjs/schema-processing.d.ts +7 -0
  100. package/lib/cjs/schema-processing.d.ts.map +1 -0
  101. package/lib/cjs/schema-processing.js +27 -0
  102. package/lib/cjs/schema-processing.js.map +1 -0
  103. package/package.json +65 -43
  104. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  105. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  106. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  107. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  108. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  109. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  110. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  111. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  112. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  113. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  114. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  115. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ElementAspectExportCoordinator = void 0;
8
+ /** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
9
+ * @internal
10
+ */
11
+ class ElementAspectExportCoordinator {
12
+ _defaultBatchSize;
13
+ _excludedClassFullNames;
14
+ _exportAspects;
15
+ _resetCaches;
16
+ _acceptedOwnerIds = new Set();
17
+ _processedOwnerIds = new Set();
18
+ _batchSize;
19
+ _depth = 0;
20
+ _prepare;
21
+ constructor(_defaultBatchSize, _excludedClassFullNames, _exportAspects, _resetCaches = () => { }) {
22
+ this._defaultBatchSize = _defaultBatchSize;
23
+ this._excludedClassFullNames = _excludedClassFullNames;
24
+ this._exportAspects = _exportAspects;
25
+ this._resetCaches = _resetCaches;
26
+ this._batchSize = _defaultBatchSize;
27
+ }
28
+ /** Whether an accepted-owner collection scope is active. */
29
+ get isActive() {
30
+ return this._depth > 0;
31
+ }
32
+ /** Sets the callback that prepares each accepted-owner group before its aspects are exported. */
33
+ setPreparation(prepare) {
34
+ this._prepare = prepare;
35
+ }
36
+ /** Begins an accepted-owner collection scope.
37
+ * Nested scopes share the outer scope's state and batch size.
38
+ */
39
+ begin(batchSize = this._defaultBatchSize) {
40
+ if (this._depth === 0) {
41
+ this.resetScopeState();
42
+ this._resetCaches();
43
+ this._batchSize = batchSize;
44
+ }
45
+ this._depth++;
46
+ }
47
+ /** Ends an accepted-owner collection scope.
48
+ * Ending the outermost scope exports pending owners and resets all scope state.
49
+ */
50
+ async end() {
51
+ if (this._depth === 0) {
52
+ throw new Error("No scoped element export is active.");
53
+ }
54
+ this._depth--;
55
+ if (this._depth > 0)
56
+ return;
57
+ try {
58
+ if (this._acceptedOwnerIds.size > 0) {
59
+ await this.flush();
60
+ }
61
+ }
62
+ finally {
63
+ this.reset();
64
+ }
65
+ }
66
+ /** Discards the active scope and its pending owner state without exporting it. */
67
+ abort() {
68
+ this.reset();
69
+ }
70
+ /** Runs element export within an accepted-owner collection scope.
71
+ * A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.
72
+ */
73
+ async run(exportElements) {
74
+ if (this.isActive) {
75
+ await exportElements();
76
+ return;
77
+ }
78
+ this.begin();
79
+ try {
80
+ await exportElements();
81
+ }
82
+ catch (error) {
83
+ this.abort();
84
+ throw error;
85
+ }
86
+ await this.end();
87
+ }
88
+ /** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
89
+ async addAcceptedOwner(elementId) {
90
+ if (!this.isActive || this._processedOwnerIds.has(elementId))
91
+ return;
92
+ this._acceptedOwnerIds.add(elementId);
93
+ if (this._acceptedOwnerIds.size >= this._batchSize) {
94
+ await this.flush();
95
+ }
96
+ }
97
+ /** Runs preparation and aspect export for an explicit owner set in bounded groups. */
98
+ async exportOwners(ownerElementIds) {
99
+ let ownerIds = ownerElementIds;
100
+ if (this.isActive && ownerElementIds.size > 0) {
101
+ const unprocessedOwnerIds = new Set();
102
+ for (const elementId of ownerElementIds) {
103
+ if (!this._processedOwnerIds.has(elementId)) {
104
+ unprocessedOwnerIds.add(elementId);
105
+ this._processedOwnerIds.add(elementId);
106
+ }
107
+ }
108
+ if (unprocessedOwnerIds.size === 0)
109
+ return;
110
+ ownerIds = unprocessedOwnerIds;
111
+ }
112
+ if (ownerIds.size <= this._defaultBatchSize) {
113
+ await this.exportOwnerBatch(ownerIds);
114
+ return;
115
+ }
116
+ let ownerBatch = new Set();
117
+ for (const elementId of ownerIds) {
118
+ ownerBatch.add(elementId);
119
+ if (ownerBatch.size === this._defaultBatchSize) {
120
+ await this.exportOwnerBatch(ownerBatch);
121
+ ownerBatch = new Set();
122
+ }
123
+ }
124
+ if (ownerBatch.size > 0) {
125
+ await this.exportOwnerBatch(ownerBatch);
126
+ }
127
+ }
128
+ async exportOwnerBatch(ownerElementIds) {
129
+ await this._prepare?.(this._excludedClassFullNames(), ownerElementIds);
130
+ await this._exportAspects(ownerElementIds);
131
+ }
132
+ async flush() {
133
+ const ownerElementIds = new Set(this._acceptedOwnerIds);
134
+ this._acceptedOwnerIds.clear();
135
+ await this.exportOwners(ownerElementIds);
136
+ }
137
+ resetScopeState() {
138
+ this._acceptedOwnerIds.clear();
139
+ this._processedOwnerIds.clear();
140
+ }
141
+ reset() {
142
+ this._depth = 0;
143
+ this.resetScopeState();
144
+ this._batchSize = this._defaultBatchSize;
145
+ }
146
+ }
147
+ exports.ElementAspectExportCoordinator = ElementAspectExportCoordinator;
148
+ //# sourceMappingURL=ElementAspectExportCoordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportCoordinator.js","sourceRoot":"","sources":["../../src/ElementAspectExportCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Id64String } from \"@itwin/core-bentley\";\n\nexport type ElementAspectExportPreparation = (\n excludedElementAspectClassFullNames: ReadonlySet<string>,\n ownerElementIds: ReadonlySet<Id64String>\n) => Promise<void>;\n\n/** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.\n * @internal\n */\nexport class ElementAspectExportCoordinator {\n private readonly _acceptedOwnerIds = new Set<Id64String>();\n private readonly _processedOwnerIds = new Set<Id64String>();\n private _batchSize: number;\n private _depth = 0;\n private _prepare?: ElementAspectExportPreparation;\n\n public constructor(\n private readonly _defaultBatchSize: number,\n private readonly _excludedClassFullNames: () => ReadonlySet<string>,\n private readonly _exportAspects: (\n ownerElementIds: ReadonlySet<Id64String>\n ) => Promise<void>,\n private readonly _resetCaches: () => void = () => {}\n ) {\n this._batchSize = _defaultBatchSize;\n }\n\n /** Whether an accepted-owner collection scope is active. */\n public get isActive(): boolean {\n return this._depth > 0;\n }\n\n /** Sets the callback that prepares each accepted-owner group before its aspects are exported. */\n public setPreparation(prepare: ElementAspectExportPreparation): void {\n this._prepare = prepare;\n }\n\n /** Begins an accepted-owner collection scope.\n * Nested scopes share the outer scope's state and batch size.\n */\n public begin(batchSize = this._defaultBatchSize): void {\n if (this._depth === 0) {\n this.resetScopeState();\n this._resetCaches();\n this._batchSize = batchSize;\n }\n this._depth++;\n }\n\n /** Ends an accepted-owner collection scope.\n * Ending the outermost scope exports pending owners and resets all scope state.\n */\n public async end(): Promise<void> {\n if (this._depth === 0) {\n throw new Error(\"No scoped element export is active.\");\n }\n\n this._depth--;\n if (this._depth > 0) return;\n\n try {\n if (this._acceptedOwnerIds.size > 0) {\n await this.flush();\n }\n } finally {\n this.reset();\n }\n }\n\n /** Discards the active scope and its pending owner state without exporting it. */\n public abort(): void {\n this.reset();\n }\n\n /** Runs element export within an accepted-owner collection scope.\n * A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.\n */\n public async run(exportElements: () => Promise<void>): Promise<void> {\n if (this.isActive) {\n await exportElements();\n return;\n }\n\n this.begin();\n try {\n await exportElements();\n } catch (error) {\n this.abort();\n throw error;\n }\n await this.end();\n }\n\n /** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */\n public async addAcceptedOwner(elementId: Id64String): Promise<void> {\n if (!this.isActive || this._processedOwnerIds.has(elementId)) return;\n\n this._acceptedOwnerIds.add(elementId);\n if (this._acceptedOwnerIds.size >= this._batchSize) {\n await this.flush();\n }\n }\n\n /** Runs preparation and aspect export for an explicit owner set in bounded groups. */\n public async exportOwners(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n let ownerIds = ownerElementIds;\n if (this.isActive && ownerElementIds.size > 0) {\n const unprocessedOwnerIds = new Set<Id64String>();\n for (const elementId of ownerElementIds) {\n if (!this._processedOwnerIds.has(elementId)) {\n unprocessedOwnerIds.add(elementId);\n this._processedOwnerIds.add(elementId);\n }\n }\n if (unprocessedOwnerIds.size === 0) return;\n ownerIds = unprocessedOwnerIds;\n }\n\n if (ownerIds.size <= this._defaultBatchSize) {\n await this.exportOwnerBatch(ownerIds);\n return;\n }\n\n let ownerBatch = new Set<Id64String>();\n for (const elementId of ownerIds) {\n ownerBatch.add(elementId);\n if (ownerBatch.size === this._defaultBatchSize) {\n await this.exportOwnerBatch(ownerBatch);\n ownerBatch = new Set<Id64String>();\n }\n }\n if (ownerBatch.size > 0) {\n await this.exportOwnerBatch(ownerBatch);\n }\n }\n\n private async exportOwnerBatch(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n await this._prepare?.(this._excludedClassFullNames(), ownerElementIds);\n await this._exportAspects(ownerElementIds);\n }\n\n private async flush(): Promise<void> {\n const ownerElementIds = new Set(this._acceptedOwnerIds);\n this._acceptedOwnerIds.clear();\n await this.exportOwners(ownerElementIds);\n }\n\n private resetScopeState(): void {\n this._acceptedOwnerIds.clear();\n this._processedOwnerIds.clear();\n }\n\n private reset(): void {\n this._depth = 0;\n this.resetScopeState();\n this._batchSize = this._defaultBatchSize;\n }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import { ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb } from "@itwin/core-backend";
2
+ import { Id64String } from "@itwin/core-bentley";
3
+ interface AspectChanges {
4
+ readonly insertIds: ReadonlySet<Id64String>;
5
+ readonly updateIds: ReadonlySet<Id64String>;
6
+ }
7
+ export interface ElementAspectExportProcessorHandler {
8
+ shouldExportElementAspect(aspect: ElementAspect): Promise<boolean>;
9
+ onExportElementUniqueAspect(uniqueAspect: ElementUniqueAspect, isUpdate?: boolean | undefined): Promise<void>;
10
+ onExportElementMultiAspects(multiAspects: ElementMultiAspect[]): Promise<void>;
11
+ trackProgress: () => Promise<void>;
12
+ }
13
+ /** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.
14
+ * @internal
15
+ */
16
+ export declare class ElementAspectExportProcessor {
17
+ /** ElementAspect classes excluded from source queries. */
18
+ private readonly _excludedElementAspectClassFullNames;
19
+ private _hasExportableAspects;
20
+ private _aspectChanges;
21
+ /** ElementAspect class names excluded from source queries. */
22
+ get excludedElementAspectClassFullNames(): ReadonlySet<string>;
23
+ private readonly _sourceDb;
24
+ private readonly _handler;
25
+ constructor(sourceDb: IModelDb, handler: ElementAspectExportProcessorHandler);
26
+ /** Exports ElementAspects owned by the supplied elements.
27
+ * Multi-aspects are emitted in one callback group per owner.
28
+ */
29
+ exportAllElementAspects(ownerElementIds: ReadonlySet<Id64String>): Promise<void>;
30
+ /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */
31
+ setAspectChanges(aspectChanges?: AspectChanges): void;
32
+ /** Clears source schema and content caches at an outer export-scope boundary. */
33
+ resetCaches(): void;
34
+ /** Excludes an ElementAspect class from subsequent queries and export callbacks. */
35
+ excludeElementAspectClass(classFullName: string): void;
36
+ private getExcludedClassFilter;
37
+ private getHasExportableAspects;
38
+ private queryHasExportableAspects;
39
+ private getAspectProps;
40
+ private queryAspects;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=ElementAspectExportProcessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportProcessor.d.ts","sourceRoot":"","sources":["../../src/ElementAspectExportProcessor.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAa,MAAM,qBAAqB,CAAC;AAS5D,UAAU,aAAa;IACrB,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,mCAAmC;IAClD,yBAAyB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,2BAA2B,CACzB,YAAY,EAAE,mBAAmB,EACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,2BAA2B,CACzB,YAAY,EAAE,kBAAkB,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,qBAAa,4BAA4B;IACvC,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAAqB;IAC1E,OAAO,CAAC,qBAAqB,CAA+B;IAC5D,OAAO,CAAC,cAAc,CAA4B;IAElD,8DAA8D;IAC9D,IAAW,mCAAmC,IAAI,WAAW,CAAC,MAAM,CAAC,CAEpE;IACD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAE/D,YACE,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,mCAAmC,EAI7C;IAED;;OAEG;IACU,uBAAuB,CAClC,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CA2Cf;IAED,4GAA4G;IACrG,gBAAgB,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAE3D;IAED,iFAAiF;IAC1E,WAAW,IAAI,IAAI,CAEzB;IAED,oFAAoF;IAC7E,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAI5D;IAED,OAAO,CAAC,sBAAsB;YAkBhB,uBAAuB;YAKvB,yBAAyB;IAuBvC,OAAO,CAAC,cAAc;YA4BP,YAAY;CAqC5B"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ElementAspectExportProcessor = void 0;
8
+ const core_backend_1 = require("@itwin/core-backend");
9
+ const core_bentley_1 = require("@itwin/core-bentley");
10
+ const ECSqlReaderAsyncIterableIteratorAdapter_1 = require("./ECSqlReaderAsyncIterableIteratorAdapter");
11
+ const core_common_1 = require("@itwin/core-common");
12
+ /** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.
13
+ * @internal
14
+ */
15
+ class ElementAspectExportProcessor {
16
+ /** ElementAspect classes excluded from source queries. */
17
+ _excludedElementAspectClassFullNames = new Set();
18
+ _hasExportableAspects;
19
+ _aspectChanges;
20
+ /** ElementAspect class names excluded from source queries. */
21
+ get excludedElementAspectClassFullNames() {
22
+ return this._excludedElementAspectClassFullNames;
23
+ }
24
+ _sourceDb;
25
+ _handler;
26
+ constructor(sourceDb, handler) {
27
+ this._sourceDb = sourceDb;
28
+ this._handler = handler;
29
+ }
30
+ /** Exports ElementAspects owned by the supplied elements.
31
+ * Multi-aspects are emitted in one callback group per owner.
32
+ */
33
+ async exportAllElementAspects(ownerElementIds) {
34
+ if (ownerElementIds.size === 0 || !(await this.getHasExportableAspects()))
35
+ return;
36
+ let multiAspectOwnerId;
37
+ let multiAspects = [];
38
+ const exportMultiAspects = async () => {
39
+ if (multiAspects.length === 0)
40
+ return;
41
+ await this._handler.onExportElementMultiAspects(multiAspects);
42
+ await this._handler.trackProgress();
43
+ multiAspects = [];
44
+ multiAspectOwnerId = undefined;
45
+ };
46
+ for await (const aspect of this.queryAspects(ownerElementIds)) {
47
+ if (!(await this._handler.shouldExportElementAspect(aspect)))
48
+ continue;
49
+ if (multiAspectOwnerId !== undefined &&
50
+ multiAspectOwnerId !== aspect.element.id) {
51
+ await exportMultiAspects();
52
+ }
53
+ if (aspect instanceof core_backend_1.ElementUniqueAspect) {
54
+ const isUpdate = this._aspectChanges?.updateIds.has(aspect.id)
55
+ ? true
56
+ : this._aspectChanges?.insertIds.has(aspect.id)
57
+ ? false
58
+ : undefined;
59
+ await this._handler.onExportElementUniqueAspect(aspect, isUpdate);
60
+ await this._handler.trackProgress();
61
+ }
62
+ else if (aspect instanceof core_backend_1.ElementMultiAspect) {
63
+ multiAspectOwnerId = aspect.element.id;
64
+ multiAspects.push(aspect);
65
+ }
66
+ else {
67
+ throw new Error(`Unexpected ElementAspect type ${aspect.classFullName}`);
68
+ }
69
+ }
70
+ await exportMultiAspects();
71
+ }
72
+ /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */
73
+ setAspectChanges(aspectChanges) {
74
+ this._aspectChanges = aspectChanges;
75
+ }
76
+ /** Clears source schema and content caches at an outer export-scope boundary. */
77
+ resetCaches() {
78
+ this._hasExportableAspects = undefined;
79
+ }
80
+ /** Excludes an ElementAspect class from subsequent queries and export callbacks. */
81
+ excludeElementAspectClass(classFullName) {
82
+ if (this._excludedElementAspectClassFullNames.has(classFullName))
83
+ return;
84
+ this._excludedElementAspectClassFullNames.add(classFullName);
85
+ this.resetCaches();
86
+ }
87
+ getExcludedClassFilter(queryParams) {
88
+ const excludedClassParameters = [];
89
+ let excludedClassIndex = 0;
90
+ for (const classFullName of this._excludedElementAspectClassFullNames) {
91
+ const parameterName = `excludedAspectClass${excludedClassIndex++}`;
92
+ excludedClassParameters.push(`ec_classid(:${parameterName})`);
93
+ queryParams.bindString(parameterName, classFullName.replace(".", ":"));
94
+ }
95
+ return excludedClassParameters.length === 0
96
+ ? ""
97
+ : `AND NOT EXISTS (
98
+ SELECT 1 FROM meta.ClassHasAllBaseClasses excluded
99
+ WHERE excluded.SourceECInstanceId = aspect.ECClassId
100
+ AND excluded.TargetECInstanceId IN (${excludedClassParameters.join(",")})
101
+ )`;
102
+ }
103
+ async getHasExportableAspects() {
104
+ this._hasExportableAspects ??= this.queryHasExportableAspects();
105
+ return this._hasExportableAspects;
106
+ }
107
+ async queryHasExportableAspects() {
108
+ const queryParams = new core_common_1.QueryBinder();
109
+ const excludedClassFilter = this.getExcludedClassFilter(queryParams);
110
+ const reader = this._sourceDb.createQueryReader(`SELECT ECInstanceId FROM (
111
+ SELECT aspect.ECInstanceId
112
+ FROM Bis.ElementMultiAspect aspect
113
+ WHERE TRUE ${excludedClassFilter}
114
+ UNION ALL
115
+ SELECT aspect.ECInstanceId
116
+ FROM Bis.ElementUniqueAspect aspect
117
+ WHERE TRUE ${excludedClassFilter}
118
+ )
119
+ LIMIT 1`, queryParams, { usePrimaryConn: true });
120
+ for await (const _row of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(reader))
121
+ return true;
122
+ return false;
123
+ }
124
+ getAspectProps(rawInstance) {
125
+ const parsedRow = typeof rawInstance === "string"
126
+ ? JSON.parse(rawInstance, core_common_1.Base64EncodedString.reviver)
127
+ : rawInstance;
128
+ if (!core_bentley_1.JsonUtils.isObject(parsedRow))
129
+ throw new Error("Expected an ElementAspect instance query to return an object");
130
+ const row = {};
131
+ for (const [key, value] of Object.entries(parsedRow)) {
132
+ const ecPropertyName = key.length === 0 ? key : key[0].toUpperCase() + key.substring(1);
133
+ row[core_common_1.ECJsNames.toJsName(ecPropertyName)] = value;
134
+ }
135
+ const className = row.className;
136
+ if (typeof className !== "string")
137
+ throw new Error("Expected an ElementAspect instance query to return a className");
138
+ row.classFullName = className.replace(".", ":");
139
+ delete row.className;
140
+ return row;
141
+ }
142
+ async *queryAspects(ownerElementIds) {
143
+ const queryParams = new core_common_1.QueryBinder().bindIdSet("ownerElementIds", ownerElementIds);
144
+ const excludedClassFilter = this.getExcludedClassFilter(queryParams);
145
+ const aspectQueryReader = this._sourceDb.createQueryReader(`WITH OwnerIds AS (SELECT id FROM IdSet(:ownerElementIds))
146
+ SELECT $ FROM (
147
+ SELECT aspect.ECInstanceId, aspect.ECClassId,
148
+ aspect.Element.Id AS OwnerId, 1 AS AspectKind
149
+ FROM OwnerIds owners
150
+ CROSS JOIN Bis.ElementMultiAspect aspect
151
+ WHERE aspect.Element.Id = owners.id ${excludedClassFilter}
152
+ UNION ALL
153
+ SELECT aspect.ECInstanceId, aspect.ECClassId,
154
+ aspect.Element.Id AS OwnerId, 0 AS AspectKind
155
+ FROM OwnerIds owners
156
+ CROSS JOIN Bis.ElementUniqueAspect aspect
157
+ WHERE aspect.Element.Id = owners.id ${excludedClassFilter}
158
+ )
159
+ ORDER BY AspectKind, OwnerId, ECClassId, ECInstanceId
160
+ OPTIONS USE_JS_PROP_NAMES DO_NOT_TRUNCATE_BLOB`, queryParams, { usePrimaryConn: true });
161
+ for await (const rowProxy of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectQueryReader)) {
162
+ yield this._sourceDb.constructEntity(this.getAspectProps(rowProxy[0]));
163
+ }
164
+ }
165
+ }
166
+ exports.ElementAspectExportProcessor = ElementAspectExportProcessor;
167
+ //# sourceMappingURL=ElementAspectExportProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportProcessor.js","sourceRoot":"","sources":["../../src/ElementAspectExportProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n ElementAspect,\n ElementMultiAspect,\n ElementUniqueAspect,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { Id64String, JsonUtils } from \"@itwin/core-bentley\";\nimport { ensureECSqlReaderIsAsyncIterableIterator } from \"./ECSqlReaderAsyncIterableIteratorAdapter\";\nimport {\n Base64EncodedString,\n ECJsNames,\n ElementAspectProps,\n QueryBinder,\n} from \"@itwin/core-common\";\n\ninterface AspectChanges {\n readonly insertIds: ReadonlySet<Id64String>;\n readonly updateIds: ReadonlySet<Id64String>;\n}\n\nexport interface ElementAspectExportProcessorHandler {\n shouldExportElementAspect(aspect: ElementAspect): Promise<boolean>;\n onExportElementUniqueAspect(\n uniqueAspect: ElementUniqueAspect,\n isUpdate?: boolean | undefined\n ): Promise<void>;\n onExportElementMultiAspects(\n multiAspects: ElementMultiAspect[]\n ): Promise<void>;\n trackProgress: () => Promise<void>;\n}\n\n/** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.\n * @internal\n */\nexport class ElementAspectExportProcessor {\n /** ElementAspect classes excluded from source queries. */\n private readonly _excludedElementAspectClassFullNames = new Set<string>();\n private _hasExportableAspects: Promise<boolean> | undefined;\n private _aspectChanges: AspectChanges | undefined;\n\n /** ElementAspect class names excluded from source queries. */\n public get excludedElementAspectClassFullNames(): ReadonlySet<string> {\n return this._excludedElementAspectClassFullNames;\n }\n private readonly _sourceDb: IModelDb;\n private readonly _handler: ElementAspectExportProcessorHandler;\n\n public constructor(\n sourceDb: IModelDb,\n handler: ElementAspectExportProcessorHandler\n ) {\n this._sourceDb = sourceDb;\n this._handler = handler;\n }\n\n /** Exports ElementAspects owned by the supplied elements.\n * Multi-aspects are emitted in one callback group per owner.\n */\n public async exportAllElementAspects(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n if (ownerElementIds.size === 0 || !(await this.getHasExportableAspects()))\n return;\n\n let multiAspectOwnerId: Id64String | undefined;\n let multiAspects: ElementMultiAspect[] = [];\n const exportMultiAspects = async () => {\n if (multiAspects.length === 0) return;\n await this._handler.onExportElementMultiAspects(multiAspects);\n await this._handler.trackProgress();\n multiAspects = [];\n multiAspectOwnerId = undefined;\n };\n\n for await (const aspect of this.queryAspects(ownerElementIds)) {\n if (!(await this._handler.shouldExportElementAspect(aspect))) continue;\n\n if (\n multiAspectOwnerId !== undefined &&\n multiAspectOwnerId !== aspect.element.id\n ) {\n await exportMultiAspects();\n }\n\n if (aspect instanceof ElementUniqueAspect) {\n const isUpdate = this._aspectChanges?.updateIds.has(aspect.id)\n ? true\n : this._aspectChanges?.insertIds.has(aspect.id)\n ? false\n : undefined;\n await this._handler.onExportElementUniqueAspect(aspect, isUpdate);\n await this._handler.trackProgress();\n } else if (aspect instanceof ElementMultiAspect) {\n multiAspectOwnerId = aspect.element.id;\n multiAspects.push(aspect);\n } else {\n throw new Error(\n `Unexpected ElementAspect type ${aspect.classFullName}`\n );\n }\n }\n\n await exportMultiAspects();\n }\n\n /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */\n public setAspectChanges(aspectChanges?: AspectChanges): void {\n this._aspectChanges = aspectChanges;\n }\n\n /** Clears source schema and content caches at an outer export-scope boundary. */\n public resetCaches(): void {\n this._hasExportableAspects = undefined;\n }\n\n /** Excludes an ElementAspect class from subsequent queries and export callbacks. */\n public excludeElementAspectClass(classFullName: string): void {\n if (this._excludedElementAspectClassFullNames.has(classFullName)) return;\n this._excludedElementAspectClassFullNames.add(classFullName);\n this.resetCaches();\n }\n\n private getExcludedClassFilter(queryParams: QueryBinder): string {\n const excludedClassParameters: string[] = [];\n let excludedClassIndex = 0;\n for (const classFullName of this._excludedElementAspectClassFullNames) {\n const parameterName = `excludedAspectClass${excludedClassIndex++}`;\n excludedClassParameters.push(`ec_classid(:${parameterName})`);\n queryParams.bindString(parameterName, classFullName.replace(\".\", \":\"));\n }\n\n return excludedClassParameters.length === 0\n ? \"\"\n : `AND NOT EXISTS (\n SELECT 1 FROM meta.ClassHasAllBaseClasses excluded\n WHERE excluded.SourceECInstanceId = aspect.ECClassId\n AND excluded.TargetECInstanceId IN (${excludedClassParameters.join(\",\")})\n )`;\n }\n\n private async getHasExportableAspects(): Promise<boolean> {\n this._hasExportableAspects ??= this.queryHasExportableAspects();\n return this._hasExportableAspects;\n }\n\n private async queryHasExportableAspects(): Promise<boolean> {\n const queryParams = new QueryBinder();\n const excludedClassFilter = this.getExcludedClassFilter(queryParams);\n const reader = this._sourceDb.createQueryReader(\n `SELECT ECInstanceId FROM (\n SELECT aspect.ECInstanceId\n FROM Bis.ElementMultiAspect aspect\n WHERE TRUE ${excludedClassFilter}\n UNION ALL\n SELECT aspect.ECInstanceId\n FROM Bis.ElementUniqueAspect aspect\n WHERE TRUE ${excludedClassFilter}\n )\n LIMIT 1`,\n queryParams,\n { usePrimaryConn: true }\n );\n\n for await (const _row of ensureECSqlReaderIsAsyncIterableIterator(reader))\n return true;\n return false;\n }\n\n private getAspectProps(rawInstance: unknown): ElementAspectProps {\n const parsedRow: unknown =\n typeof rawInstance === \"string\"\n ? JSON.parse(rawInstance, Base64EncodedString.reviver)\n : rawInstance;\n if (!JsonUtils.isObject(parsedRow))\n throw new Error(\n \"Expected an ElementAspect instance query to return an object\"\n );\n\n const row: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(parsedRow)) {\n const ecPropertyName =\n key.length === 0 ? key : key[0].toUpperCase() + key.substring(1);\n row[ECJsNames.toJsName(ecPropertyName)] = value;\n }\n\n const className = row.className;\n if (typeof className !== \"string\")\n throw new Error(\n \"Expected an ElementAspect instance query to return a className\"\n );\n\n row.classFullName = className.replace(\".\", \":\");\n delete row.className;\n return row as unknown as ElementAspectProps;\n }\n\n private async *queryAspects(\n ownerElementIds: ReadonlySet<Id64String>\n ): AsyncIterableIterator<ElementAspect> {\n const queryParams = new QueryBinder().bindIdSet(\n \"ownerElementIds\",\n ownerElementIds\n );\n const excludedClassFilter = this.getExcludedClassFilter(queryParams);\n const aspectQueryReader = this._sourceDb.createQueryReader(\n `WITH OwnerIds AS (SELECT id FROM IdSet(:ownerElementIds))\n SELECT $ FROM (\n SELECT aspect.ECInstanceId, aspect.ECClassId,\n aspect.Element.Id AS OwnerId, 1 AS AspectKind\n FROM OwnerIds owners\n CROSS JOIN Bis.ElementMultiAspect aspect\n WHERE aspect.Element.Id = owners.id ${excludedClassFilter}\n UNION ALL\n SELECT aspect.ECInstanceId, aspect.ECClassId,\n aspect.Element.Id AS OwnerId, 0 AS AspectKind\n FROM OwnerIds owners\n CROSS JOIN Bis.ElementUniqueAspect aspect\n WHERE aspect.Element.Id = owners.id ${excludedClassFilter}\n )\n ORDER BY AspectKind, OwnerId, ECClassId, ECInstanceId\n OPTIONS USE_JS_PROP_NAMES DO_NOT_TRUNCATE_BLOB`,\n queryParams,\n { usePrimaryConn: true }\n );\n\n for await (const rowProxy of ensureECSqlReaderIsAsyncIterableIterator(\n aspectQueryReader\n )) {\n yield this._sourceDb.constructEntity<ElementAspect>(\n this.getAspectProps(rowProxy[0])\n );\n }\n }\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  /** @packageDocumentation
2
2
  * @module iModels
3
3
  */
4
- import { ElementTreeDeleter, ElementTreeWalkerScope, IModelDb } from "@itwin/core-backend";
4
+ import { EditTxn, ElementTreeDeleter, ElementTreeWalkerScope } from "@itwin/core-backend";
5
5
  import { Id64String } from "@itwin/core-bentley";
6
6
  /** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
7
- * @param iModel The iModel
7
+ * @param editTxn The active EditTxn for the iModel
8
8
  * @param topElement The parent of the sub-tree
9
9
  */
10
- export declare function deleteElementTreeCascade(iModel: IModelDb, topElement: Id64String): void;
10
+ export declare function deleteElementTreeCascade(editTxn: EditTxn, topElement: Id64String): void;
11
11
  /** Deletes an entire element tree, including sub-models, child elements and code scope references.
12
12
  * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.
13
13
  * Call deleteNormalElements on each tree. Then call deleteSpecialElements.
@@ -1 +1 @@
1
- {"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAY,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,EAChB,UAAU,EAAE,UAAU,GACrB,IAAI,CAIN;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,SAAS,CAAC,qBAAqB,CAC7B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB;IAKhC,qCAAqC;cAClB,kBAAkB,CACnC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,sBAAsB,GAC5B,IAAI;IAMP,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;CAsB3B"}
1
+ {"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,GACrB,IAAI,CAIN;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,SAAS,CAAC,qBAAqB,CAC7B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB,WAG/B;IAED,qCAAqC;IACrC,UAAmB,kBAAkB,CACnC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,sBAAsB,GAC5B,IAAI,CAKN;IACD,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;CAyB3B"}
@@ -10,13 +10,13 @@ exports.deleteElementTreeCascade = deleteElementTreeCascade;
10
10
  * @module iModels
11
11
  */
12
12
  const core_backend_1 = require("@itwin/core-backend");
13
- const core_bentley_1 = require("@itwin/core-bentley");
13
+ const core_common_1 = require("@itwin/core-common");
14
14
  /** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
15
- * @param iModel The iModel
15
+ * @param editTxn The active EditTxn for the iModel
16
16
  * @param topElement The parent of the sub-tree
17
17
  */
18
- function deleteElementTreeCascade(iModel, topElement) {
19
- const del = new ElementCascadingDeleter(iModel);
18
+ function deleteElementTreeCascade(editTxn, topElement) {
19
+ const del = new ElementCascadingDeleter(editTxn);
20
20
  del.deleteNormalElements(topElement);
21
21
  del.deleteSpecialElements();
22
22
  }
@@ -38,19 +38,19 @@ class ElementCascadingDeleter extends core_backend_1.ElementTreeDeleter {
38
38
  /** Process code scope references */
39
39
  _processCodeScopes(element, scope) {
40
40
  const newScope = new core_backend_1.ElementTreeWalkerScope(scope, element);
41
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
42
- this._iModel.withPreparedStatement(`
41
+ const query = `
43
42
  SELECT ECInstanceId
44
43
  FROM bis.Element
45
- WHERE CodeScope.id=?
44
+ WHERE CodeScope.id=:scopeId
46
45
  AND Parent.id IS NULL
47
- `, (stmt) => {
48
- stmt.bindId(1, element);
49
- while (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW) {
50
- const elementId = stmt.getValue(0).getId();
46
+ `;
47
+ const params = new core_common_1.QueryBinder().bindId("scopeId", element);
48
+ this.txn.iModel.withQueryReader(query, (reader) => {
49
+ for (const row of reader) {
50
+ const elementId = row[0];
51
51
  this.processElementTree(elementId, newScope);
52
52
  }
53
- });
53
+ }, params);
54
54
  }
55
55
  }
56
56
  exports.ElementCascadingDeleter = ElementCascadingDeleter;
@@ -1 +1 @@
1
- {"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAkBA,4DAOC;AAzBD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAC7B,sDAA2D;AAE3D;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,MAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,gFAAgF;QAChF,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAChC;;;;;KAKD,EACC,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,uBAAQ,CAAC,aAAa,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC3C,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAzCD,0DAyCC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\nimport {\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64String } from \"@itwin/core-bentley\";\n\n/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.\n * @param iModel The iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n iModel: IModelDb,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(iModel);\n del.deleteNormalElements(topElement);\n del.deleteSpecialElements();\n}\n\n/** Deletes an entire element tree, including sub-models, child elements and code scope references.\n * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.\n * Call deleteNormalElements on each tree. Then call deleteSpecialElements.\n */\nexport class ElementCascadingDeleter extends ElementTreeDeleter {\n protected shouldVisitCodeScopes(\n _elementId: Id64String,\n _scope: ElementTreeWalkerScope\n ) {\n return true;\n }\n\n /** The main tree-walking function */\n protected override processElementTree(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ): void {\n if (this.shouldVisitCodeScopes(element, scope)) {\n this._processCodeScopes(element, scope);\n }\n super.processElementTree(element, scope);\n }\n /** Process code scope references */\n private _processCodeScopes(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ) {\n const newScope = new ElementTreeWalkerScope(scope, element);\n // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated\n this._iModel.withPreparedStatement(\n `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=?\n AND Parent.id IS NULL\n `,\n (stmt) => {\n stmt.bindId(1, element);\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\n const elementId = stmt.getValue(0).getId();\n this.processElementTree(elementId, newScope);\n }\n }\n );\n }\n}\n"]}
1
+ {"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAE7B,oDAAiD;AAEjD;;;GAGG;AACH,kCACE,OAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,6BAAqC,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG;;;;;KAKb,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAC7B,KAAK,EACL,CAAC,MAAM,EAAE,EAAE;YACT,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAe,CAAC;gBACvC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\nimport {\n EditTxn,\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\n\n/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.\n * @param editTxn The active EditTxn for the iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n editTxn: EditTxn,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(editTxn);\n del.deleteNormalElements(topElement);\n del.deleteSpecialElements();\n}\n\n/** Deletes an entire element tree, including sub-models, child elements and code scope references.\n * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.\n * Call deleteNormalElements on each tree. Then call deleteSpecialElements.\n */\nexport class ElementCascadingDeleter extends ElementTreeDeleter {\n protected shouldVisitCodeScopes(\n _elementId: Id64String,\n _scope: ElementTreeWalkerScope\n ) {\n return true;\n }\n\n /** The main tree-walking function */\n protected override processElementTree(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ): void {\n if (this.shouldVisitCodeScopes(element, scope)) {\n this._processCodeScopes(element, scope);\n }\n super.processElementTree(element, scope);\n }\n /** Process code scope references */\n private _processCodeScopes(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ) {\n const newScope = new ElementTreeWalkerScope(scope, element);\n const query = `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=:scopeId\n AND Parent.id IS NULL\n `;\n\n const params = new QueryBinder().bindId(\"scopeId\", element);\n\n this.txn.iModel.withQueryReader(\n query,\n (reader) => {\n for (const row of reader) {\n const elementId = row[0] as Id64String;\n this.processElementTree(elementId, newScope);\n }\n },\n params\n );\n }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ /** @packageDocumentation
2
+ * @module Utils
3
+ */
4
+ import { EntityReference } from "@itwin/core-common";
5
+ import { IModelDb } from "@itwin/core-backend";
6
+ /** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
7
+ *
8
+ * Entities are created continuously as a transformation progresses, so a negative
9
+ * ("does not exist") result may become stale at any moment — therefore only positive
10
+ * results are ever cached. Positive results can only be invalidated by deletes, which the
11
+ * transformer routes through [[invalidate]] and [[clearDb]].
12
+ *
13
+ * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations
14
+ * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.
15
+ *
16
+ * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed
17
+ * directly through an `EditTxn` while a transformation is active are out-of-band and must not be
18
+ * mixed with transformer operations. A successful high-level `process()` clears the cache when the
19
+ * transformation finalizes; low-level or failed transformations clear it when the transformer is
20
+ * disposed.
21
+ * @internal
22
+ */
23
+ export declare class EntityExistenceCache {
24
+ private _existsByDb;
25
+ private getDbSet;
26
+ /** Check whether an entity exists in `db`, consulting the cache first.
27
+ * A `true` result is cached; a `false` result is never cached and will be re-queried.
28
+ */
29
+ exists(db: IModelDb, entityReference: EntityReference): Promise<boolean>;
30
+ /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */
31
+ existsAll(db: IModelDb, entityReferences: Iterable<EntityReference>): Promise<ReadonlySet<EntityReference>>;
32
+ /** Record that an entity is known to exist in `db` (e.g. it was just imported). */
33
+ markExists(db: IModelDb, entityReference: EntityReference): void;
34
+ /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */
35
+ invalidate(db: IModelDb, entityReference: EntityReference): void;
36
+ /** Drop all cached results for `db`. Used when a delete may cascade to entities the
37
+ * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).
38
+ */
39
+ clearDb(db: IModelDb): void;
40
+ /** Drop all cached results. */
41
+ clear(): void;
42
+ }
43
+ //# sourceMappingURL=EntityExistenceCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityExistenceCache.d.ts","sourceRoot":"","sources":["../../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAA6C;IAEhE,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACU,MAAM,CACjB,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,OAAO,CAAC,CAMlB;IAED,6GAA6G;IAChG,SAAS,CACpB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAkBvC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED;;OAEG;IACI,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEjC;IAED,+BAA+B;IACxB,KAAK,IAAI,IAAI,CAEnB;CACF"}