@itwin/core-backend 5.15.0-dev.2 → 5.15.0-dev.20

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 (272) hide show
  1. package/CHANGELOG.md +52 -1
  2. package/lib/cjs/BlobContainerService.d.ts +2 -0
  3. package/lib/cjs/BlobContainerService.d.ts.map +1 -1
  4. package/lib/cjs/BlobContainerService.js.map +1 -1
  5. package/lib/cjs/BriefcaseManager.d.ts +4 -3
  6. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  7. package/lib/cjs/BriefcaseManager.js +39 -9
  8. package/lib/cjs/BriefcaseManager.js.map +1 -1
  9. package/lib/cjs/ChangeUnifier.d.ts +82 -0
  10. package/lib/cjs/ChangeUnifier.d.ts.map +1 -0
  11. package/lib/cjs/ChangeUnifier.js +163 -0
  12. package/lib/cjs/ChangeUnifier.js.map +1 -0
  13. package/lib/cjs/ChangesetReader.d.ts +21 -2
  14. package/lib/cjs/ChangesetReader.d.ts.map +1 -1
  15. package/lib/cjs/ChangesetReader.js +37 -1
  16. package/lib/cjs/ChangesetReader.js.map +1 -1
  17. package/lib/cjs/ChangesetReaderTypes.d.ts +1 -1
  18. package/lib/cjs/ChangesetReaderTypes.js.map +1 -1
  19. package/lib/cjs/CloudSqlite.d.ts +15 -0
  20. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  21. package/lib/cjs/CloudSqlite.js.map +1 -1
  22. package/lib/cjs/ECDb.d.ts +1 -0
  23. package/lib/cjs/ECDb.d.ts.map +1 -1
  24. package/lib/cjs/ECDb.js +4 -1
  25. package/lib/cjs/ECDb.js.map +1 -1
  26. package/lib/cjs/ECSqlRowExecutor.d.ts +3 -3
  27. package/lib/cjs/ECSqlRowExecutor.d.ts.map +1 -1
  28. package/lib/cjs/ECSqlRowExecutor.js +2 -2
  29. package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
  30. package/lib/cjs/ECSqlStatement.d.ts +5 -0
  31. package/lib/cjs/ECSqlStatement.d.ts.map +1 -1
  32. package/lib/cjs/ECSqlStatement.js +15 -2
  33. package/lib/cjs/ECSqlStatement.js.map +1 -1
  34. package/lib/cjs/ECSqlSyncReader.d.ts.map +1 -1
  35. package/lib/cjs/ECSqlSyncReader.js +2 -2
  36. package/lib/cjs/ECSqlSyncReader.js.map +1 -1
  37. package/lib/cjs/EditTxn.d.ts +61 -19
  38. package/lib/cjs/EditTxn.d.ts.map +1 -1
  39. package/lib/cjs/EditTxn.js +84 -29
  40. package/lib/cjs/EditTxn.js.map +1 -1
  41. package/lib/cjs/Element.d.ts +29 -2
  42. package/lib/cjs/Element.d.ts.map +1 -1
  43. package/lib/cjs/Element.js +38 -2
  44. package/lib/cjs/Element.js.map +1 -1
  45. package/lib/cjs/GeoCoordConfig.d.ts +1 -0
  46. package/lib/cjs/GeoCoordConfig.d.ts.map +1 -1
  47. package/lib/cjs/GeoCoordConfig.js +12 -8
  48. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  49. package/lib/cjs/GeographicCRSServices.d.ts +50 -2
  50. package/lib/cjs/GeographicCRSServices.d.ts.map +1 -1
  51. package/lib/cjs/GeographicCRSServices.js +11 -1
  52. package/lib/cjs/GeographicCRSServices.js.map +1 -1
  53. package/lib/cjs/IModelDb.d.ts +22 -9
  54. package/lib/cjs/IModelDb.d.ts.map +1 -1
  55. package/lib/cjs/IModelDb.js +54 -12
  56. package/lib/cjs/IModelDb.js.map +1 -1
  57. package/lib/cjs/NativeHost.d.ts.map +1 -1
  58. package/lib/cjs/NativeHost.js +5 -1
  59. package/lib/cjs/NativeHost.js.map +1 -1
  60. package/lib/cjs/Relationship.d.ts +28 -0
  61. package/lib/cjs/Relationship.d.ts.map +1 -1
  62. package/lib/cjs/Relationship.js +78 -0
  63. package/lib/cjs/Relationship.js.map +1 -1
  64. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  65. package/lib/cjs/SchemaSync.js +1 -0
  66. package/lib/cjs/SchemaSync.js.map +1 -1
  67. package/lib/cjs/TxnManager.d.ts +126 -89
  68. package/lib/cjs/TxnManager.d.ts.map +1 -1
  69. package/lib/cjs/TxnManager.js +114 -76
  70. package/lib/cjs/TxnManager.js.map +1 -1
  71. package/lib/cjs/ViewStateHydrator.d.ts.map +1 -1
  72. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  73. package/lib/cjs/ViewStore.d.ts.map +1 -1
  74. package/lib/cjs/ViewStore.js +62 -19
  75. package/lib/cjs/ViewStore.js.map +1 -1
  76. package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
  77. package/lib/cjs/annotations/LeaderGeometry.js +3 -0
  78. package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
  79. package/lib/cjs/core-backend.d.ts +1 -0
  80. package/lib/cjs/core-backend.d.ts.map +1 -1
  81. package/lib/cjs/core-backend.js +1 -0
  82. package/lib/cjs/core-backend.js.map +1 -1
  83. package/lib/cjs/internal/BriefcaseUtils.d.ts +19 -0
  84. package/lib/cjs/internal/BriefcaseUtils.d.ts.map +1 -0
  85. package/lib/cjs/internal/BriefcaseUtils.js +65 -0
  86. package/lib/cjs/internal/BriefcaseUtils.js.map +1 -0
  87. package/lib/cjs/internal/QueryMetadataCache.d.ts +44 -0
  88. package/lib/cjs/internal/QueryMetadataCache.d.ts.map +1 -0
  89. package/lib/cjs/internal/QueryMetadataCache.js +107 -0
  90. package/lib/cjs/internal/QueryMetadataCache.js.map +1 -0
  91. package/lib/cjs/internal/Symbols.d.ts +9 -0
  92. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  93. package/lib/cjs/internal/Symbols.js +10 -1
  94. package/lib/cjs/internal/Symbols.js.map +1 -1
  95. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  96. package/lib/cjs/internal/workspace/WorkspaceImpl.js +20 -6
  97. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  98. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  99. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  100. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  101. package/lib/cjs/workspace/SettingsEditor.d.ts +4 -3
  102. package/lib/cjs/workspace/SettingsEditor.d.ts.map +1 -1
  103. package/lib/cjs/workspace/SettingsEditor.js +7 -5
  104. package/lib/cjs/workspace/SettingsEditor.js.map +1 -1
  105. package/lib/esm/BlobContainerService.d.ts +2 -0
  106. package/lib/esm/BlobContainerService.d.ts.map +1 -1
  107. package/lib/esm/BlobContainerService.js.map +1 -1
  108. package/lib/esm/BriefcaseManager.d.ts +4 -3
  109. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  110. package/lib/esm/BriefcaseManager.js +40 -10
  111. package/lib/esm/BriefcaseManager.js.map +1 -1
  112. package/lib/esm/ChangeUnifier.d.ts +82 -0
  113. package/lib/esm/ChangeUnifier.d.ts.map +1 -0
  114. package/lib/esm/ChangeUnifier.js +159 -0
  115. package/lib/esm/ChangeUnifier.js.map +1 -0
  116. package/lib/esm/ChangesetReader.d.ts +21 -2
  117. package/lib/esm/ChangesetReader.d.ts.map +1 -1
  118. package/lib/esm/ChangesetReader.js +38 -2
  119. package/lib/esm/ChangesetReader.js.map +1 -1
  120. package/lib/esm/ChangesetReaderTypes.d.ts +1 -1
  121. package/lib/esm/ChangesetReaderTypes.js.map +1 -1
  122. package/lib/esm/CloudSqlite.d.ts +15 -0
  123. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  124. package/lib/esm/CloudSqlite.js.map +1 -1
  125. package/lib/esm/ECDb.d.ts +1 -0
  126. package/lib/esm/ECDb.d.ts.map +1 -1
  127. package/lib/esm/ECDb.js +4 -1
  128. package/lib/esm/ECDb.js.map +1 -1
  129. package/lib/esm/ECSqlRowExecutor.d.ts +3 -3
  130. package/lib/esm/ECSqlRowExecutor.d.ts.map +1 -1
  131. package/lib/esm/ECSqlRowExecutor.js +2 -2
  132. package/lib/esm/ECSqlRowExecutor.js.map +1 -1
  133. package/lib/esm/ECSqlStatement.d.ts +5 -0
  134. package/lib/esm/ECSqlStatement.d.ts.map +1 -1
  135. package/lib/esm/ECSqlStatement.js +15 -2
  136. package/lib/esm/ECSqlStatement.js.map +1 -1
  137. package/lib/esm/ECSqlSyncReader.d.ts.map +1 -1
  138. package/lib/esm/ECSqlSyncReader.js +3 -3
  139. package/lib/esm/ECSqlSyncReader.js.map +1 -1
  140. package/lib/esm/EditTxn.d.ts +61 -19
  141. package/lib/esm/EditTxn.d.ts.map +1 -1
  142. package/lib/esm/EditTxn.js +85 -30
  143. package/lib/esm/EditTxn.js.map +1 -1
  144. package/lib/esm/Element.d.ts +29 -2
  145. package/lib/esm/Element.d.ts.map +1 -1
  146. package/lib/esm/Element.js +41 -5
  147. package/lib/esm/Element.js.map +1 -1
  148. package/lib/esm/GeoCoordConfig.d.ts +1 -0
  149. package/lib/esm/GeoCoordConfig.d.ts.map +1 -1
  150. package/lib/esm/GeoCoordConfig.js +12 -8
  151. package/lib/esm/GeoCoordConfig.js.map +1 -1
  152. package/lib/esm/GeographicCRSServices.d.ts +50 -2
  153. package/lib/esm/GeographicCRSServices.d.ts.map +1 -1
  154. package/lib/esm/GeographicCRSServices.js +10 -1
  155. package/lib/esm/GeographicCRSServices.js.map +1 -1
  156. package/lib/esm/IModelDb.d.ts +22 -9
  157. package/lib/esm/IModelDb.d.ts.map +1 -1
  158. package/lib/esm/IModelDb.js +56 -14
  159. package/lib/esm/IModelDb.js.map +1 -1
  160. package/lib/esm/NativeHost.d.ts.map +1 -1
  161. package/lib/esm/NativeHost.js +5 -1
  162. package/lib/esm/NativeHost.js.map +1 -1
  163. package/lib/esm/Relationship.d.ts +28 -0
  164. package/lib/esm/Relationship.d.ts.map +1 -1
  165. package/lib/esm/Relationship.js +78 -0
  166. package/lib/esm/Relationship.js.map +1 -1
  167. package/lib/esm/SchemaSync.d.ts.map +1 -1
  168. package/lib/esm/SchemaSync.js +1 -0
  169. package/lib/esm/SchemaSync.js.map +1 -1
  170. package/lib/esm/TxnManager.d.ts +126 -89
  171. package/lib/esm/TxnManager.d.ts.map +1 -1
  172. package/lib/esm/TxnManager.js +116 -78
  173. package/lib/esm/TxnManager.js.map +1 -1
  174. package/lib/esm/ViewStateHydrator.d.ts.map +1 -1
  175. package/lib/esm/ViewStateHydrator.js.map +1 -1
  176. package/lib/esm/ViewStore.d.ts.map +1 -1
  177. package/lib/esm/ViewStore.js +62 -19
  178. package/lib/esm/ViewStore.js.map +1 -1
  179. package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
  180. package/lib/esm/annotations/LeaderGeometry.js +3 -0
  181. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  182. package/lib/esm/core-backend.d.ts +1 -0
  183. package/lib/esm/core-backend.d.ts.map +1 -1
  184. package/lib/esm/core-backend.js +1 -0
  185. package/lib/esm/core-backend.js.map +1 -1
  186. package/lib/esm/internal/BriefcaseUtils.d.ts +19 -0
  187. package/lib/esm/internal/BriefcaseUtils.d.ts.map +1 -0
  188. package/lib/esm/internal/BriefcaseUtils.js +61 -0
  189. package/lib/esm/internal/BriefcaseUtils.js.map +1 -0
  190. package/lib/esm/internal/QueryMetadataCache.d.ts +44 -0
  191. package/lib/esm/internal/QueryMetadataCache.d.ts.map +1 -0
  192. package/lib/esm/internal/QueryMetadataCache.js +103 -0
  193. package/lib/esm/internal/QueryMetadataCache.js.map +1 -0
  194. package/lib/esm/internal/Symbols.d.ts +9 -0
  195. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  196. package/lib/esm/internal/Symbols.js +9 -0
  197. package/lib/esm/internal/Symbols.js.map +1 -1
  198. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  199. package/lib/esm/internal/workspace/WorkspaceImpl.js +20 -6
  200. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  201. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  202. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  203. package/lib/esm/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  204. package/lib/esm/test/annotations/LeaderGeometry.test.js +15 -1
  205. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  206. package/lib/esm/test/ecdb/ConcurrentQuery.test.js +144 -30
  207. package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
  208. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +140 -0
  209. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  210. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts +2 -0
  211. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts.map +1 -0
  212. package/lib/esm/test/ecdb/QueryMetadataCache.test.js +630 -0
  213. package/lib/esm/test/ecdb/QueryMetadataCache.test.js.map +1 -0
  214. package/lib/esm/test/element/DeleteDefinitionElements.test.js +403 -249
  215. package/lib/esm/test/element/DeleteDefinitionElements.test.js.map +1 -1
  216. package/lib/esm/test/element/ElementSubModelInsert.test.d.ts +2 -0
  217. package/lib/esm/test/element/ElementSubModelInsert.test.d.ts.map +1 -0
  218. package/lib/esm/test/element/ElementSubModelInsert.test.js +183 -0
  219. package/lib/esm/test/element/ElementSubModelInsert.test.js.map +1 -0
  220. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts +2 -0
  221. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts.map +1 -0
  222. package/lib/esm/test/element/RelationshipBatchLookup.test.js +202 -0
  223. package/lib/esm/test/element/RelationshipBatchLookup.test.js.map +1 -0
  224. package/lib/esm/test/hubaccess/BriefcaseManager.test.js +187 -1
  225. package/lib/esm/test/hubaccess/BriefcaseManager.test.js.map +1 -1
  226. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts +2 -0
  227. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts.map +1 -0
  228. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js +142 -0
  229. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js.map +1 -0
  230. package/lib/esm/test/imodel/IModelGeolocation.test.js +13 -11
  231. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -1
  232. package/lib/esm/test/imodel/IModelProps.test.d.ts +2 -0
  233. package/lib/esm/test/imodel/IModelProps.test.d.ts.map +1 -0
  234. package/lib/esm/test/imodel/IModelProps.test.js +411 -0
  235. package/lib/esm/test/imodel/IModelProps.test.js.map +1 -0
  236. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts +2 -0
  237. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts.map +1 -0
  238. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js +240 -0
  239. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js.map +1 -0
  240. package/lib/esm/test/schema/SchemaViewValidation.test.js +2 -8
  241. package/lib/esm/test/schema/SchemaViewValidation.test.js.map +1 -1
  242. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts +2 -0
  243. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts.map +1 -0
  244. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js +159 -0
  245. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js.map +1 -0
  246. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts +2 -0
  247. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts.map +1 -0
  248. package/lib/esm/test/standalone/ChangeUnifier.test.js +732 -0
  249. package/lib/esm/test/standalone/ChangeUnifier.test.js.map +1 -0
  250. package/lib/esm/test/standalone/DeleteElements.test.js +962 -83
  251. package/lib/esm/test/standalone/DeleteElements.test.js.map +1 -1
  252. package/lib/esm/test/standalone/EditTxn.test.js +72 -1
  253. package/lib/esm/test/standalone/EditTxn.test.js.map +1 -1
  254. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts +2 -0
  255. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts.map +1 -0
  256. package/lib/esm/test/standalone/GeoCoordConfig.test.js +158 -0
  257. package/lib/esm/test/standalone/GeoCoordConfig.test.js.map +1 -0
  258. package/lib/esm/test/standalone/SessionApplyIndirect.test.d.ts +2 -0
  259. package/lib/esm/test/standalone/SessionApplyIndirect.test.d.ts.map +1 -0
  260. package/lib/esm/test/standalone/SessionApplyIndirect.test.js +211 -0
  261. package/lib/esm/test/standalone/SessionApplyIndirect.test.js.map +1 -0
  262. package/lib/esm/test/standalone/ViewStoreDb.test.js +53 -0
  263. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  264. package/lib/esm/test/workspace/SettingsContainers.test.d.ts +2 -0
  265. package/lib/esm/test/workspace/SettingsContainers.test.d.ts.map +1 -0
  266. package/lib/esm/test/workspace/SettingsContainers.test.js +95 -0
  267. package/lib/esm/test/workspace/SettingsContainers.test.js.map +1 -0
  268. package/lib/esm/workspace/SettingsEditor.d.ts +4 -3
  269. package/lib/esm/workspace/SettingsEditor.d.ts.map +1 -1
  270. package/lib/esm/workspace/SettingsEditor.js +7 -5
  271. package/lib/esm/workspace/SettingsEditor.js.map +1 -1
  272. package/package.json +18 -18
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ElementSubModelInsert.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementSubModelInsert.test.d.ts","sourceRoot":"","sources":["../../../../src/test/element/ElementSubModelInsert.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the repository root for full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { expect } from "chai";
6
+ import { spy as sinonSpy } from "sinon";
7
+ import { Id64, IModelStatus } from "@itwin/core-bentley";
8
+ import { Code, IModel, IModelError } from "@itwin/core-common";
9
+ import { ClassRegistry } from "../../ClassRegistry";
10
+ import { withEditTxn } from "../../EditTxn";
11
+ import { Document, Drawing, SectionDrawing, Sheet, TemplateRecipe2d } from "../../Element";
12
+ import { GenericSchema } from "../../domains/GenericSchema";
13
+ import { SnapshotDb } from "../../IModelDb";
14
+ import { DefinitionModel, DocumentListModel, DrawingModel, SectionDrawingModel, SheetModel } from "../../Model";
15
+ import { Schema, Schemas } from "../../Schema";
16
+ import { IModelTestUtils } from "../IModelTestUtils";
17
+ class TestSubModelSchema extends Schema {
18
+ static get schemaName() { return "TestSubModel"; }
19
+ }
20
+ /** A Sheet subclass that overrides the hook and defers to the inherited validation via `super`. */
21
+ class TestSheetSpy extends Sheet {
22
+ static get className() { return "TestSheetSpy"; }
23
+ static onSubModelInsert(arg) {
24
+ super.onSubModelInsert(arg);
25
+ }
26
+ }
27
+ /** A Sheet subclass that widens the inherited rule to also permit a DrawingModel. */
28
+ class TestSheetWidened extends Sheet {
29
+ static get className() { return "TestSheetWidened"; }
30
+ static get allowedSubModelClasses() { return [SheetModel, DrawingModel]; }
31
+ }
32
+ /** A Sheet subclass that replaces the hook without calling `super`, opting out of validation. */
33
+ class TestSheetUnvalidated extends Sheet {
34
+ static get className() { return "TestSheetUnvalidated"; }
35
+ static onSubModelInsert(_arg) { }
36
+ }
37
+ /** A domain ISubModeledElement unrelated to Sheet/Drawing that opts in by overriding only the getter. */
38
+ class TestRestrictedDocument extends Document {
39
+ static get className() { return "TestRestrictedDocument"; }
40
+ static get allowedSubModelClasses() { return [DrawingModel]; }
41
+ }
42
+ const testSchemaXml = `<?xml version="1.0" encoding="UTF-8"?>
43
+ <ECSchema schemaName="TestSubModel" alias="tsm" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
44
+ <ECSchemaReference name="BisCore" version="01.00.04" alias="bis"/>
45
+ <ECCustomAttributes>
46
+ <SchemaHasBehavior xmlns="BisCore.01.00.00"/>
47
+ </ECCustomAttributes>
48
+ <ECEntityClass typeName="TestSheetModel">
49
+ <BaseClass>bis:SheetModel</BaseClass>
50
+ </ECEntityClass>
51
+ <ECEntityClass typeName="TestSheetGenerated">
52
+ <BaseClass>bis:Sheet</BaseClass>
53
+ </ECEntityClass>
54
+ <ECEntityClass typeName="TestSheetSpy">
55
+ <BaseClass>bis:Sheet</BaseClass>
56
+ </ECEntityClass>
57
+ <ECEntityClass typeName="TestSheetWidened">
58
+ <BaseClass>bis:Sheet</BaseClass>
59
+ </ECEntityClass>
60
+ <ECEntityClass typeName="TestSheetUnvalidated">
61
+ <BaseClass>bis:Sheet</BaseClass>
62
+ </ECEntityClass>
63
+ <ECEntityClass typeName="TestHostDocument">
64
+ <BaseClass>bis:Document</BaseClass>
65
+ <BaseClass>bis:ISubModeledElement</BaseClass>
66
+ </ECEntityClass>
67
+ <ECEntityClass typeName="TestRestrictedDocument">
68
+ <BaseClass>bis:Document</BaseClass>
69
+ <BaseClass>bis:ISubModeledElement</BaseClass>
70
+ </ECEntityClass>
71
+ </ECSchema>`;
72
+ describe("Sub-model insert validation", () => {
73
+ let imodel;
74
+ let documentListModelId;
75
+ before(async () => {
76
+ GenericSchema.registerSchema();
77
+ Schemas.registerSchema(TestSubModelSchema);
78
+ ClassRegistry.register(TestSheetSpy, TestSubModelSchema);
79
+ ClassRegistry.register(TestSheetWidened, TestSubModelSchema);
80
+ ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);
81
+ ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);
82
+ const iModelPath = IModelTestUtils.prepareOutputFile("SubModelInsert", "SubModelInsert.bim");
83
+ imodel = SnapshotDb.createEmpty(iModelPath, { rootSubject: { name: "SubModelInsertTest" } });
84
+ await imodel.importSchemaStrings([testSchemaXml]);
85
+ documentListModelId = withEditTxn(imodel, (txn) => DocumentListModel.insert(txn, SnapshotDb.rootSubjectId, "DocumentList"));
86
+ });
87
+ after(() => {
88
+ imodel.close();
89
+ Schemas.unregisterSchema(TestSubModelSchema.schemaName);
90
+ });
91
+ function insertHost(classFullName, modelId = documentListModelId) {
92
+ const id = withEditTxn(imodel, (txn) => txn.insertElement({ classFullName, model: modelId, code: Code.createEmpty() }));
93
+ expect(Id64.isValidId64(id)).to.be.true;
94
+ return id;
95
+ }
96
+ function insertSubModel(modelClassFullName, modeledElementId) {
97
+ return withEditTxn(imodel, (txn) => txn.insertModel({ classFullName: modelClassFullName, modeledElement: { id: modeledElementId } }));
98
+ }
99
+ function expectAccepted(hostClassFullName, modelClassFullName, hostModelId) {
100
+ const hostId = insertHost(hostClassFullName, hostModelId);
101
+ const modelId = insertSubModel(modelClassFullName, hostId);
102
+ expect(modelId).to.equal(hostId);
103
+ expect(imodel.models.getModel(modelId).classFullName).to.equal(modelClassFullName);
104
+ }
105
+ function expectRejected(hostClassFullName, modelClassFullName, hostModelId) {
106
+ const hostId = insertHost(hostClassFullName, hostModelId);
107
+ let error;
108
+ try {
109
+ insertSubModel(modelClassFullName, hostId);
110
+ }
111
+ catch (err) {
112
+ error = err;
113
+ }
114
+ expect(error).to.be.instanceOf(IModelError);
115
+ expect(error.errorNumber).to.equal(IModelStatus.WrongModel);
116
+ expect(error.message).to.contain("must be sub-modeled by");
117
+ expect(imodel.models.tryGetModel(hostId)).to.be.undefined;
118
+ }
119
+ describe("accepts", () => {
120
+ it("Sheet + SheetModel", () => expectAccepted(Sheet.classFullName, SheetModel.classFullName));
121
+ it("Drawing + DrawingModel", () => expectAccepted(Drawing.classFullName, DrawingModel.classFullName));
122
+ it("SectionDrawing + DrawingModel", () => expectAccepted(SectionDrawing.classFullName, DrawingModel.classFullName));
123
+ it("SectionDrawing + SectionDrawingModel", () => expectAccepted(SectionDrawing.classFullName, SectionDrawingModel.classFullName));
124
+ it("SectionDrawing + Generic:GraphicalModel3d", () => expectAccepted(SectionDrawing.classFullName, "Generic:GraphicalModel3d"));
125
+ it("TemplateRecipe2d + DrawingModel", () => expectAccepted(TemplateRecipe2d.classFullName, DrawingModel.classFullName, IModel.dictionaryId));
126
+ it("Sheet + SheetModel subclass without a JS class", () => expectAccepted(Sheet.classFullName, "TestSubModel:TestSheetModel"));
127
+ it("no allowedSubModelClasses → any model accepted", () => {
128
+ expectAccepted("TestSubModel:TestHostDocument", SheetModel.classFullName);
129
+ expectAccepted("TestSubModel:TestHostDocument", DrawingModel.classFullName);
130
+ });
131
+ it("Sheet subclass that widens allowedSubModelClasses + DrawingModel", () => expectAccepted(TestSheetWidened.classFullName, DrawingModel.classFullName));
132
+ it("Sheet subclass that overrides onSubModelInsert without super + DrawingModel", () => expectAccepted(TestSheetUnvalidated.classFullName, DrawingModel.classFullName));
133
+ it("Document subclass with allowedSubModelClasses + DrawingModel", () => expectAccepted(TestRestrictedDocument.classFullName, DrawingModel.classFullName));
134
+ });
135
+ describe("rejects with IModelStatus.WrongModel", () => {
136
+ it("Sheet + DrawingModel", () => expectRejected(Sheet.classFullName, DrawingModel.classFullName));
137
+ it("Drawing + SheetModel", () => expectRejected(Drawing.classFullName, SheetModel.classFullName));
138
+ it("SectionDrawing + SheetModel", () => expectRejected(SectionDrawing.classFullName, SheetModel.classFullName));
139
+ it("TemplateRecipe2d + SheetModel", () => expectRejected(TemplateRecipe2d.classFullName, SheetModel.classFullName, IModel.dictionaryId));
140
+ it("Sheet subclass without a JS class + DrawingModel", () => expectRejected("TestSubModel:TestSheetGenerated", DrawingModel.classFullName));
141
+ it("Document subclass with allowedSubModelClasses + SheetModel", () => expectRejected(TestRestrictedDocument.classFullName, SheetModel.classFullName));
142
+ });
143
+ it("invokes an overriding subclass hook that defers to the inherited validation", () => {
144
+ const spy = sinonSpy(TestSheetSpy, "onSubModelInsert");
145
+ try {
146
+ expectAccepted(TestSheetSpy.classFullName, SheetModel.classFullName);
147
+ expect(spy.calledOnce).to.be.true;
148
+ expect(spy.getCall(0).args[0].subModelProps.classFullName).to.equal(SheetModel.classFullName);
149
+ expectRejected(TestSheetSpy.classFullName, DrawingModel.classFullName);
150
+ expect(spy.calledTwice).to.be.true;
151
+ expect(spy.getCall(1).threw()).to.be.true;
152
+ }
153
+ finally {
154
+ spy.restore();
155
+ }
156
+ });
157
+ describe("missing required behavior", () => {
158
+ it("rejects sub-model insertion", () => {
159
+ const hostId = insertHost(TestRestrictedDocument.classFullName);
160
+ Schemas.unregisterSchema(TestSubModelSchema.schemaName);
161
+ try {
162
+ let error;
163
+ try {
164
+ insertSubModel(DefinitionModel.classFullName, hostId);
165
+ }
166
+ catch (err) {
167
+ error = err;
168
+ }
169
+ expect(error).to.be.instanceOf(IModelError);
170
+ expect(error.errorNumber).to.equal(IModelStatus.WrongHandler);
171
+ expect(imodel.models.tryGetModel(hostId)).to.be.undefined;
172
+ }
173
+ finally {
174
+ Schemas.registerSchema(TestSubModelSchema);
175
+ ClassRegistry.register(TestSheetSpy, TestSubModelSchema);
176
+ ClassRegistry.register(TestSheetWidened, TestSubModelSchema);
177
+ ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);
178
+ ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);
179
+ }
180
+ });
181
+ });
182
+ });
183
+ //# sourceMappingURL=ElementSubModelInsert.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementSubModelInsert.test.js","sourceRoot":"","sources":["../../../../src/test/element/ElementSubModelInsert.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the repository root for full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { expect } from \"chai\";\r\nimport { spy as sinonSpy } from \"sinon\";\r\nimport { Id64, Id64String, IModelStatus } from \"@itwin/core-bentley\";\r\nimport { Code, IModel, IModelError } from \"@itwin/core-common\";\r\nimport { ClassRegistry } from \"../../ClassRegistry\";\r\nimport { withEditTxn } from \"../../EditTxn\";\r\nimport { Document, Drawing, OnSubModelPropsArg, SectionDrawing, Sheet, TemplateRecipe2d } from \"../../Element\";\r\nimport { EntityClassType } from \"../../Entity\";\r\nimport { GenericSchema } from \"../../domains/GenericSchema\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { DefinitionModel, DocumentListModel, DrawingModel, Model, SectionDrawingModel, SheetModel } from \"../../Model\";\r\nimport { Schema, Schemas } from \"../../Schema\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\nclass TestSubModelSchema extends Schema {\r\n public static override get schemaName(): string { return \"TestSubModel\"; }\r\n}\r\n\r\n/** A Sheet subclass that overrides the hook and defers to the inherited validation via `super`. */\r\nclass TestSheetSpy extends Sheet {\r\n public static override get className(): string { return \"TestSheetSpy\"; }\r\n public static override onSubModelInsert(arg: OnSubModelPropsArg): void {\r\n super.onSubModelInsert(arg);\r\n }\r\n}\r\n\r\n/** A Sheet subclass that widens the inherited rule to also permit a DrawingModel. */\r\nclass TestSheetWidened extends Sheet {\r\n public static override get className(): string { return \"TestSheetWidened\"; }\r\n protected static override get allowedSubModelClasses(): Array<EntityClassType<Model>> { return [SheetModel, DrawingModel]; }\r\n}\r\n\r\n/** A Sheet subclass that replaces the hook without calling `super`, opting out of validation. */\r\nclass TestSheetUnvalidated extends Sheet {\r\n public static override get className(): string { return \"TestSheetUnvalidated\"; }\r\n public static override onSubModelInsert(_arg: OnSubModelPropsArg): void { }\r\n}\r\n\r\n/** A domain ISubModeledElement unrelated to Sheet/Drawing that opts in by overriding only the getter. */\r\nclass TestRestrictedDocument extends Document {\r\n public static override get className(): string { return \"TestRestrictedDocument\"; }\r\n protected static override get allowedSubModelClasses(): Array<EntityClassType<Model>> { return [DrawingModel]; }\r\n}\r\n\r\nconst testSchemaXml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ECSchema schemaName=\"TestSubModel\" alias=\"tsm\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.04\" alias=\"bis\"/>\r\n <ECCustomAttributes>\r\n <SchemaHasBehavior xmlns=\"BisCore.01.00.00\"/>\r\n </ECCustomAttributes>\r\n <ECEntityClass typeName=\"TestSheetModel\">\r\n <BaseClass>bis:SheetModel</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetGenerated\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetSpy\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetWidened\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetUnvalidated\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestHostDocument\">\r\n <BaseClass>bis:Document</BaseClass>\r\n <BaseClass>bis:ISubModeledElement</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestRestrictedDocument\">\r\n <BaseClass>bis:Document</BaseClass>\r\n <BaseClass>bis:ISubModeledElement</BaseClass>\r\n </ECEntityClass>\r\n</ECSchema>`;\r\n\r\ndescribe(\"Sub-model insert validation\", () => {\r\n let imodel: SnapshotDb;\r\n let documentListModelId: Id64String;\r\n\r\n before(async () => {\r\n GenericSchema.registerSchema();\r\n Schemas.registerSchema(TestSubModelSchema);\r\n ClassRegistry.register(TestSheetSpy, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetWidened, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);\r\n ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);\r\n\r\n const iModelPath = IModelTestUtils.prepareOutputFile(\"SubModelInsert\", \"SubModelInsert.bim\");\r\n imodel = SnapshotDb.createEmpty(iModelPath, { rootSubject: { name: \"SubModelInsertTest\" } });\r\n await imodel.importSchemaStrings([testSchemaXml]);\r\n documentListModelId = withEditTxn(imodel, (txn) => DocumentListModel.insert(txn, SnapshotDb.rootSubjectId, \"DocumentList\"));\r\n });\r\n\r\n after(() => {\r\n imodel.close();\r\n Schemas.unregisterSchema(TestSubModelSchema.schemaName);\r\n });\r\n\r\n function insertHost(classFullName: string, modelId: Id64String = documentListModelId): Id64String {\r\n const id = withEditTxn(imodel, (txn) => txn.insertElement({ classFullName, model: modelId, code: Code.createEmpty() }));\r\n expect(Id64.isValidId64(id)).to.be.true;\r\n return id;\r\n }\r\n\r\n function insertSubModel(modelClassFullName: string, modeledElementId: Id64String): Id64String {\r\n return withEditTxn(imodel, (txn) => txn.insertModel({ classFullName: modelClassFullName, modeledElement: { id: modeledElementId } }));\r\n }\r\n\r\n function expectAccepted(hostClassFullName: string, modelClassFullName: string, hostModelId?: Id64String): void {\r\n const hostId = insertHost(hostClassFullName, hostModelId);\r\n const modelId = insertSubModel(modelClassFullName, hostId);\r\n expect(modelId).to.equal(hostId);\r\n expect(imodel.models.getModel(modelId).classFullName).to.equal(modelClassFullName);\r\n }\r\n\r\n function expectRejected(hostClassFullName: string, modelClassFullName: string, hostModelId?: Id64String): void {\r\n const hostId = insertHost(hostClassFullName, hostModelId);\r\n let error: unknown;\r\n try {\r\n insertSubModel(modelClassFullName, hostId);\r\n } catch (err) {\r\n error = err;\r\n }\r\n\r\n expect(error).to.be.instanceOf(IModelError);\r\n expect((error as IModelError).errorNumber).to.equal(IModelStatus.WrongModel);\r\n expect((error as IModelError).message).to.contain(\"must be sub-modeled by\");\r\n expect(imodel.models.tryGetModel(hostId)).to.be.undefined;\r\n }\r\n\r\n describe(\"accepts\", () => {\r\n it(\"Sheet + SheetModel\", () => expectAccepted(Sheet.classFullName, SheetModel.classFullName));\r\n it(\"Drawing + DrawingModel\", () => expectAccepted(Drawing.classFullName, DrawingModel.classFullName));\r\n it(\"SectionDrawing + DrawingModel\", () => expectAccepted(SectionDrawing.classFullName, DrawingModel.classFullName));\r\n it(\"SectionDrawing + SectionDrawingModel\", () => expectAccepted(SectionDrawing.classFullName, SectionDrawingModel.classFullName));\r\n it(\"SectionDrawing + Generic:GraphicalModel3d\", () => expectAccepted(SectionDrawing.classFullName, \"Generic:GraphicalModel3d\"));\r\n it(\"TemplateRecipe2d + DrawingModel\", () => expectAccepted(TemplateRecipe2d.classFullName, DrawingModel.classFullName, IModel.dictionaryId));\r\n it(\"Sheet + SheetModel subclass without a JS class\", () => expectAccepted(Sheet.classFullName, \"TestSubModel:TestSheetModel\"));\r\n it(\"no allowedSubModelClasses → any model accepted\", () => {\r\n expectAccepted(\"TestSubModel:TestHostDocument\", SheetModel.classFullName);\r\n expectAccepted(\"TestSubModel:TestHostDocument\", DrawingModel.classFullName);\r\n });\r\n it(\"Sheet subclass that widens allowedSubModelClasses + DrawingModel\", () => expectAccepted(TestSheetWidened.classFullName, DrawingModel.classFullName));\r\n it(\"Sheet subclass that overrides onSubModelInsert without super + DrawingModel\", () => expectAccepted(TestSheetUnvalidated.classFullName, DrawingModel.classFullName));\r\n it(\"Document subclass with allowedSubModelClasses + DrawingModel\", () => expectAccepted(TestRestrictedDocument.classFullName, DrawingModel.classFullName));\r\n });\r\n\r\n describe(\"rejects with IModelStatus.WrongModel\", () => {\r\n it(\"Sheet + DrawingModel\", () => expectRejected(Sheet.classFullName, DrawingModel.classFullName));\r\n it(\"Drawing + SheetModel\", () => expectRejected(Drawing.classFullName, SheetModel.classFullName));\r\n it(\"SectionDrawing + SheetModel\", () => expectRejected(SectionDrawing.classFullName, SheetModel.classFullName));\r\n it(\"TemplateRecipe2d + SheetModel\", () => expectRejected(TemplateRecipe2d.classFullName, SheetModel.classFullName, IModel.dictionaryId));\r\n it(\"Sheet subclass without a JS class + DrawingModel\", () => expectRejected(\"TestSubModel:TestSheetGenerated\", DrawingModel.classFullName));\r\n it(\"Document subclass with allowedSubModelClasses + SheetModel\", () => expectRejected(TestRestrictedDocument.classFullName, SheetModel.classFullName));\r\n });\r\n\r\n it(\"invokes an overriding subclass hook that defers to the inherited validation\", () => {\r\n const spy = sinonSpy(TestSheetSpy, \"onSubModelInsert\");\r\n try {\r\n expectAccepted(TestSheetSpy.classFullName, SheetModel.classFullName);\r\n expect(spy.calledOnce).to.be.true;\r\n expect(spy.getCall(0).args[0].subModelProps.classFullName).to.equal(SheetModel.classFullName);\r\n\r\n expectRejected(TestSheetSpy.classFullName, DrawingModel.classFullName);\r\n expect(spy.calledTwice).to.be.true;\r\n expect(spy.getCall(1).threw()).to.be.true;\r\n } finally {\r\n spy.restore();\r\n }\r\n });\r\n\r\n describe(\"missing required behavior\", () => {\r\n it(\"rejects sub-model insertion\", () => {\r\n const hostId = insertHost(TestRestrictedDocument.classFullName);\r\n Schemas.unregisterSchema(TestSubModelSchema.schemaName);\r\n\r\n try {\r\n let error: unknown;\r\n try {\r\n insertSubModel(DefinitionModel.classFullName, hostId);\r\n } catch (err) {\r\n error = err;\r\n }\r\n\r\n expect(error).to.be.instanceOf(IModelError);\r\n expect((error as IModelError).errorNumber).to.equal(IModelStatus.WrongHandler);\r\n expect(imodel.models.tryGetModel(hostId)).to.be.undefined;\r\n } finally {\r\n Schemas.registerSchema(TestSubModelSchema);\r\n ClassRegistry.register(TestSheetSpy, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetWidened, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);\r\n ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);\r\n }\r\n });\r\n });\r\n});\r\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RelationshipBatchLookup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationshipBatchLookup.test.d.ts","sourceRoot":"","sources":["../../../../src/test/element/RelationshipBatchLookup.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { expect } from "chai";
6
+ import * as sinon from "sinon";
7
+ import { Guid, Id64 } from "@itwin/core-bentley";
8
+ import { Code, IModel } from "@itwin/core-common";
9
+ import { withEditTxn } from "../../EditTxn";
10
+ import { RepositoryLink } from "../../Element";
11
+ import { SnapshotDb } from "../../IModelDb";
12
+ import { ElementDrivesElement, ElementGroupsMembers, ElementRefersToElements } from "../../Relationship";
13
+ import { IModelTestUtils } from "../IModelTestUtils";
14
+ describe("Relationships batched lookup", () => {
15
+ const testSchema = `<?xml version="1.0" encoding="UTF-8"?>
16
+ <ECSchema schemaName="BatchLookupTest" alias="blt" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
17
+ <ECSchemaReference name="BisCore" version="01.00.00" alias="bis"/>
18
+ <ECStructClass typeName="TestStruct">
19
+ <ECProperty propertyName="label" typeName="string"/>
20
+ <ECProperty propertyName="origin" typeName="point2d"/>
21
+ </ECStructClass>
22
+ <ECRelationshipClass typeName="TestRefersToElements" strength="referencing" modifier="Sealed">
23
+ <BaseClass>bis:ElementRefersToElements</BaseClass>
24
+ <Source multiplicity="(0..*)" roleLabel="refers to" polymorphic="true">
25
+ <Class class="bis:Element"/>
26
+ </Source>
27
+ <Target multiplicity="(0..*)" roleLabel="is referenced by" polymorphic="true">
28
+ <Class class="bis:Element"/>
29
+ </Target>
30
+ <ECProperty propertyName="Location" typeName="point3d"/>
31
+ <ECStructProperty propertyName="Info" typeName="TestStruct"/>
32
+ <ECArrayProperty propertyName="Points" typeName="point3d" minOccurs="0" maxOccurs="unbounded"/>
33
+ </ECRelationshipClass>
34
+ </ECSchema>`;
35
+ const testRelClass = "BatchLookupTest:TestRefersToElements";
36
+ let imodel;
37
+ let elementIds;
38
+ let relIds;
39
+ before(async () => {
40
+ imodel = SnapshotDb.createEmpty(IModelTestUtils.prepareOutputFile("Relationship", "BatchLookup.bim"), { rootSubject: { name: "BatchLookup" } });
41
+ await imodel.importSchemaStrings([testSchema]);
42
+ withEditTxn(imodel, (txn) => {
43
+ elementIds = [];
44
+ for (let i = 0; i < 6; ++i) {
45
+ const props = {
46
+ classFullName: RepositoryLink.classFullName,
47
+ model: IModel.repositoryModelId,
48
+ code: Code.createEmpty(),
49
+ repositoryGuid: Guid.createValue(),
50
+ };
51
+ elementIds.push(txn.insertElement(props));
52
+ }
53
+ // Chain e0->e1->e2->e3->e4 with memberPriority equal to the source index.
54
+ relIds = [];
55
+ for (let i = 0; i < 4; ++i)
56
+ relIds.push(txn.insertRelationship(ElementGroupsMembers.create(imodel, elementIds[i], elementIds[i + 1], i).toJSON()));
57
+ });
58
+ });
59
+ after(() => imodel.close());
60
+ it("matches tryGetInstanceProps for ids and source/target pairs, preserving order", async () => {
61
+ const [e0, e1, e2, e3, e4, e5] = elementIds;
62
+ const criteria = [
63
+ relIds[2],
64
+ { sourceId: e0, targetId: e1 },
65
+ Id64.fromLocalAndBriefcaseIds(0x7fff, 0), // non-existent id
66
+ { sourceId: e3, targetId: e4 },
67
+ { sourceId: e0, targetId: e2 }, // both ends requested elsewhere, but not related as a pair
68
+ { sourceId: e4, targetId: e5 }, // unrelated
69
+ Id64.invalid,
70
+ relIds[2], // duplicate
71
+ { sourceId: e1, targetId: e2 },
72
+ relIds[0],
73
+ ];
74
+ const batch = await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, criteria);
75
+ expect(batch.length).to.equal(criteria.length);
76
+ criteria.forEach((criterion, i) => {
77
+ expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(ElementGroupsMembers.classFullName, criterion), `criterion ${i}`);
78
+ });
79
+ expect(batch[0]?.id).to.equal(relIds[2]);
80
+ expect(batch[0]?.classFullName).to.equal(ElementGroupsMembers.classFullName);
81
+ expect(batch[1].memberPriority).to.equal(0);
82
+ expect(batch[1]?.id).to.equal(relIds[0]);
83
+ expect(batch[2]).to.be.undefined;
84
+ expect(batch[3]?.id).to.equal(relIds[3]);
85
+ expect(batch[4]).to.be.undefined;
86
+ expect(batch[5]).to.be.undefined;
87
+ expect(batch[6]).to.be.undefined;
88
+ expect(batch[7]?.id).to.equal(relIds[2]);
89
+ expect(batch[8]?.id).to.equal(relIds[1]);
90
+ // The concurrent query connection sees the same saved data.
91
+ expect(await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, criteria, { usePrimaryConn: false })).to.deep.equal(batch);
92
+ });
93
+ it("returns an empty array for empty criteria", async () => {
94
+ expect(await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, [])).to.deep.equal([]);
95
+ expect(await imodel.relationships.queryInstances(ElementGroupsMembers.classFullName, [])).to.deep.equal([]);
96
+ });
97
+ it("queries polymorphically and respects the relationship class", async () => {
98
+ const criteria = [relIds[0], { sourceId: elementIds[1], targetId: elementIds[2] }];
99
+ const viaBase = await imodel.relationships.queryInstancesProps(ElementRefersToElements.classFullName, criteria);
100
+ expect(viaBase.map((p) => p?.classFullName)).to.deep.equal([ElementGroupsMembers.classFullName, ElementGroupsMembers.classFullName]);
101
+ criteria.forEach((criterion, i) => expect(viaBase[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(ElementRefersToElements.classFullName, criterion), `criterion ${i}`));
102
+ const viaOther = await imodel.relationships.queryInstancesProps(ElementDrivesElement.classFullName, criteria);
103
+ expect(viaOther).to.deep.equal([undefined, undefined]);
104
+ });
105
+ it("queryInstances constructs Relationship entities", async () => {
106
+ const criteria = [relIds[1], { sourceId: elementIds[3], targetId: elementIds[4] }, Id64.invalid];
107
+ const rels = await imodel.relationships.queryInstances(ElementGroupsMembers.classFullName, criteria);
108
+ expect(rels.length).to.equal(3);
109
+ expect(rels[0]).to.be.instanceOf(ElementGroupsMembers);
110
+ expect(rels[0]?.id).to.equal(relIds[1]);
111
+ expect(rels[0]?.memberPriority).to.equal(1);
112
+ expect(rels[1]).to.be.instanceOf(ElementGroupsMembers);
113
+ expect(rels[1]?.sourceId).to.equal(elementIds[3]);
114
+ expect(rels[1]?.targetId).to.equal(elementIds[4]);
115
+ expect(rels[2]).to.be.undefined;
116
+ criteria.forEach((criterion, i) => expect(rels[i]?.toJSON()).to.deep.equal(imodel.relationships.tryGetInstance(ElementGroupsMembers.classFullName, criterion)?.toJSON(), `criterion ${i}`));
117
+ });
118
+ it("sees unsaved changes by default", async () => {
119
+ const cls = ElementGroupsMembers.classFullName;
120
+ const pair = { sourceId: elementIds[4], targetId: elementIds[5] };
121
+ await withEditTxn(imodel, async (txn) => {
122
+ const id = txn.insertRelationship(ElementGroupsMembers.create(imodel, pair.sourceId, pair.targetId, 4).toJSON());
123
+ const found = await imodel.relationships.queryInstances(cls, [id, pair]);
124
+ expect(found.map((r) => r?.id)).to.deep.equal([id, id]);
125
+ txn.deleteRelationship(imodel.relationships.getInstanceProps(cls, id));
126
+ });
127
+ });
128
+ it("converts point, struct and array properties like tryGetInstanceProps", async () => {
129
+ const pair = { sourceId: elementIds[0], targetId: elementIds[5] };
130
+ await withEditTxn(imodel, async (txn) => {
131
+ const id = txn.insertRelationship({
132
+ classFullName: testRelClass,
133
+ ...pair,
134
+ location: { x: 1, y: 2, z: 3 },
135
+ info: { label: "a", origin: { x: 4, y: 5 } },
136
+ points: [{ x: 6, y: 7, z: 8 }, { x: 9, y: 10, z: 11 }],
137
+ });
138
+ const criteria = [id, pair];
139
+ const batch = await imodel.relationships.queryInstancesProps(testRelClass, criteria);
140
+ criteria.forEach((criterion, i) => expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(testRelClass, criterion), `criterion ${i}`));
141
+ expect(batch[0]).to.include({ id, classFullName: testRelClass });
142
+ expect(batch[0]).to.deep.include({
143
+ location: { x: 1, y: 2, z: 3 },
144
+ info: { label: "a", origin: { x: 4, y: 5 } },
145
+ points: [{ x: 6, y: 7, z: 8 }, { x: 9, y: 10, z: 11 }],
146
+ });
147
+ txn.deleteRelationship(batch[0]);
148
+ });
149
+ });
150
+ it("reads only the requested pairs in a dense many-to-many graph", async () => {
151
+ const cls = ElementGroupsMembers.classFullName;
152
+ const n = 5;
153
+ await withEditTxn(imodel, async (txn) => {
154
+ const sources = [];
155
+ const targets = [];
156
+ for (let i = 0; i < 2 * n; ++i) {
157
+ const id = txn.insertElement({ classFullName: RepositoryLink.classFullName, model: IModel.repositoryModelId, code: Code.createEmpty(), repositoryGuid: Guid.createValue() });
158
+ (i < n ? sources : targets).push(id);
159
+ }
160
+ // Connect every source to every target, then request only the "diagonal" pairs.
161
+ for (const sourceId of sources)
162
+ for (const targetId of targets)
163
+ txn.insertRelationship(ElementGroupsMembers.create(imodel, sourceId, targetId, 0).toJSON());
164
+ const pairs = sources.map((sourceId, i) => ({ sourceId, targetId: targets[i] }));
165
+ let rowsRead = 0;
166
+ const createQueryReader = imodel.createQueryReader.bind(imodel);
167
+ const stub = sinon.stub(imodel, "createQueryReader").callsFake((ecsql, params, config) => {
168
+ const reader = createQueryReader(ecsql, params, config);
169
+ const step = reader.step.bind(reader);
170
+ reader.step = async () => {
171
+ const hasRow = await step();
172
+ if (hasRow)
173
+ ++rowsRead;
174
+ return hasRow;
175
+ };
176
+ return reader;
177
+ });
178
+ try {
179
+ const found = await imodel.relationships.queryInstancesProps(cls, pairs);
180
+ expect(found.map((p) => p && { sourceId: p.sourceId, targetId: p.targetId })).to.deep.equal(pairs);
181
+ }
182
+ finally {
183
+ stub.restore();
184
+ }
185
+ expect(rowsRead).to.equal(n);
186
+ });
187
+ });
188
+ it("supports relationships stored as navigation properties and ids from any briefcase", async () => {
189
+ const cls = "BisCore:ModelContainsElements";
190
+ const highBriefcaseId = Id64.fromLocalAndBriefcaseIds(1, 0xfffffd);
191
+ const criteria = [
192
+ elementIds[0],
193
+ { sourceId: IModel.repositoryModelId, targetId: elementIds[1] },
194
+ highBriefcaseId,
195
+ { sourceId: highBriefcaseId, targetId: elementIds[1] },
196
+ ];
197
+ const batch = await imodel.relationships.queryInstancesProps(cls, criteria);
198
+ criteria.forEach((criterion, i) => expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(cls, criterion), `criterion ${i}`));
199
+ expect(batch.map((p) => p?.targetId)).to.deep.equal([elementIds[0], elementIds[1], undefined, undefined]);
200
+ });
201
+ });
202
+ //# sourceMappingURL=RelationshipBatchLookup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationshipBatchLookup.test.js","sourceRoot":"","sources":["../../../../src/test/element/RelationshipBatchLookup.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport { Guid, Id64, Id64String } from \"@itwin/core-bentley\";\r\nimport { Code, IModel, RelationshipProps, RepositoryLinkProps, SourceAndTarget } from \"@itwin/core-common\";\r\nimport { withEditTxn } from \"../../EditTxn\";\r\nimport { RepositoryLink } from \"../../Element\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { ElementDrivesElement, ElementGroupsMembers, ElementRefersToElements } from \"../../Relationship\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\ndescribe(\"Relationships batched lookup\", () => {\r\n const testSchema = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <ECSchema schemaName=\"BatchLookupTest\" alias=\"blt\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\r\n <ECStructClass typeName=\"TestStruct\">\r\n <ECProperty propertyName=\"label\" typeName=\"string\"/>\r\n <ECProperty propertyName=\"origin\" typeName=\"point2d\"/>\r\n </ECStructClass>\r\n <ECRelationshipClass typeName=\"TestRefersToElements\" strength=\"referencing\" modifier=\"Sealed\">\r\n <BaseClass>bis:ElementRefersToElements</BaseClass>\r\n <Source multiplicity=\"(0..*)\" roleLabel=\"refers to\" polymorphic=\"true\">\r\n <Class class=\"bis:Element\"/>\r\n </Source>\r\n <Target multiplicity=\"(0..*)\" roleLabel=\"is referenced by\" polymorphic=\"true\">\r\n <Class class=\"bis:Element\"/>\r\n </Target>\r\n <ECProperty propertyName=\"Location\" typeName=\"point3d\"/>\r\n <ECStructProperty propertyName=\"Info\" typeName=\"TestStruct\"/>\r\n <ECArrayProperty propertyName=\"Points\" typeName=\"point3d\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\r\n </ECRelationshipClass>\r\n </ECSchema>`;\r\n const testRelClass = \"BatchLookupTest:TestRefersToElements\";\r\n\r\n let imodel: SnapshotDb;\r\n let elementIds: Id64String[];\r\n let relIds: Id64String[];\r\n\r\n before(async () => {\r\n imodel = SnapshotDb.createEmpty(IModelTestUtils.prepareOutputFile(\"Relationship\", \"BatchLookup.bim\"), { rootSubject: { name: \"BatchLookup\" } });\r\n await imodel.importSchemaStrings([testSchema]);\r\n withEditTxn(imodel, (txn) => {\r\n elementIds = [];\r\n for (let i = 0; i < 6; ++i) {\r\n const props: RepositoryLinkProps = {\r\n classFullName: RepositoryLink.classFullName,\r\n model: IModel.repositoryModelId,\r\n code: Code.createEmpty(),\r\n repositoryGuid: Guid.createValue(),\r\n };\r\n elementIds.push(txn.insertElement(props));\r\n }\r\n\r\n // Chain e0->e1->e2->e3->e4 with memberPriority equal to the source index.\r\n relIds = [];\r\n for (let i = 0; i < 4; ++i)\r\n relIds.push(txn.insertRelationship(ElementGroupsMembers.create(imodel, elementIds[i], elementIds[i + 1], i).toJSON()));\r\n });\r\n });\r\n\r\n after(() => imodel.close());\r\n\r\n it(\"matches tryGetInstanceProps for ids and source/target pairs, preserving order\", async () => {\r\n const [e0, e1, e2, e3, e4, e5] = elementIds;\r\n const criteria: Array<Id64String | SourceAndTarget> = [\r\n relIds[2],\r\n { sourceId: e0, targetId: e1 },\r\n Id64.fromLocalAndBriefcaseIds(0x7fff, 0), // non-existent id\r\n { sourceId: e3, targetId: e4 },\r\n { sourceId: e0, targetId: e2 }, // both ends requested elsewhere, but not related as a pair\r\n { sourceId: e4, targetId: e5 }, // unrelated\r\n Id64.invalid,\r\n relIds[2], // duplicate\r\n { sourceId: e1, targetId: e2 },\r\n relIds[0],\r\n ];\r\n\r\n const batch = await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, criteria);\r\n expect(batch.length).to.equal(criteria.length);\r\n criteria.forEach((criterion, i) => {\r\n expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(ElementGroupsMembers.classFullName, criterion), `criterion ${i}`);\r\n });\r\n\r\n expect(batch[0]?.id).to.equal(relIds[2]);\r\n expect(batch[0]?.classFullName).to.equal(ElementGroupsMembers.classFullName);\r\n expect((batch[1] as any).memberPriority).to.equal(0);\r\n expect(batch[1]?.id).to.equal(relIds[0]);\r\n expect(batch[2]).to.be.undefined;\r\n expect(batch[3]?.id).to.equal(relIds[3]);\r\n expect(batch[4]).to.be.undefined;\r\n expect(batch[5]).to.be.undefined;\r\n expect(batch[6]).to.be.undefined;\r\n expect(batch[7]?.id).to.equal(relIds[2]);\r\n expect(batch[8]?.id).to.equal(relIds[1]);\r\n\r\n // The concurrent query connection sees the same saved data.\r\n expect(await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, criteria, { usePrimaryConn: false })).to.deep.equal(batch);\r\n });\r\n\r\n it(\"returns an empty array for empty criteria\", async () => {\r\n expect(await imodel.relationships.queryInstancesProps(ElementGroupsMembers.classFullName, [])).to.deep.equal([]);\r\n expect(await imodel.relationships.queryInstances(ElementGroupsMembers.classFullName, [])).to.deep.equal([]);\r\n });\r\n\r\n it(\"queries polymorphically and respects the relationship class\", async () => {\r\n const criteria = [relIds[0], { sourceId: elementIds[1], targetId: elementIds[2] }];\r\n\r\n const viaBase = await imodel.relationships.queryInstancesProps(ElementRefersToElements.classFullName, criteria);\r\n expect(viaBase.map((p) => p?.classFullName)).to.deep.equal([ElementGroupsMembers.classFullName, ElementGroupsMembers.classFullName]);\r\n criteria.forEach((criterion, i) => expect(viaBase[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(ElementRefersToElements.classFullName, criterion), `criterion ${i}`));\r\n\r\n const viaOther = await imodel.relationships.queryInstancesProps(ElementDrivesElement.classFullName, criteria);\r\n expect(viaOther).to.deep.equal([undefined, undefined]);\r\n });\r\n\r\n it(\"queryInstances constructs Relationship entities\", async () => {\r\n const criteria = [relIds[1], { sourceId: elementIds[3], targetId: elementIds[4] }, Id64.invalid];\r\n const rels = await imodel.relationships.queryInstances<ElementGroupsMembers>(ElementGroupsMembers.classFullName, criteria);\r\n expect(rels.length).to.equal(3);\r\n expect(rels[0]).to.be.instanceOf(ElementGroupsMembers);\r\n expect(rels[0]?.id).to.equal(relIds[1]);\r\n expect(rels[0]?.memberPriority).to.equal(1);\r\n expect(rels[1]).to.be.instanceOf(ElementGroupsMembers);\r\n expect(rels[1]?.sourceId).to.equal(elementIds[3]);\r\n expect(rels[1]?.targetId).to.equal(elementIds[4]);\r\n expect(rels[2]).to.be.undefined;\r\n criteria.forEach((criterion, i) => expect(rels[i]?.toJSON()).to.deep.equal(imodel.relationships.tryGetInstance(ElementGroupsMembers.classFullName, criterion)?.toJSON(), `criterion ${i}`));\r\n });\r\n\r\n it(\"sees unsaved changes by default\", async () => {\r\n const cls = ElementGroupsMembers.classFullName;\r\n const pair = { sourceId: elementIds[4], targetId: elementIds[5] };\r\n await withEditTxn(imodel, async (txn) => {\r\n const id = txn.insertRelationship(ElementGroupsMembers.create(imodel, pair.sourceId, pair.targetId, 4).toJSON());\r\n const found = await imodel.relationships.queryInstances(cls, [id, pair]);\r\n expect(found.map((r) => r?.id)).to.deep.equal([id, id]);\r\n txn.deleteRelationship(imodel.relationships.getInstanceProps(cls, id));\r\n });\r\n });\r\n\r\n it(\"converts point, struct and array properties like tryGetInstanceProps\", async () => {\r\n const pair = { sourceId: elementIds[0], targetId: elementIds[5] };\r\n await withEditTxn(imodel, async (txn) => {\r\n const id = txn.insertRelationship({\r\n classFullName: testRelClass,\r\n ...pair,\r\n location: { x: 1, y: 2, z: 3 },\r\n info: { label: \"a\", origin: { x: 4, y: 5 } },\r\n points: [{ x: 6, y: 7, z: 8 }, { x: 9, y: 10, z: 11 }],\r\n } as RelationshipProps);\r\n\r\n const criteria = [id, pair];\r\n const batch = await imodel.relationships.queryInstancesProps(testRelClass, criteria);\r\n criteria.forEach((criterion, i) => expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(testRelClass, criterion), `criterion ${i}`));\r\n expect(batch[0]).to.include({ id, classFullName: testRelClass });\r\n expect(batch[0]).to.deep.include({\r\n location: { x: 1, y: 2, z: 3 },\r\n info: { label: \"a\", origin: { x: 4, y: 5 } },\r\n points: [{ x: 6, y: 7, z: 8 }, { x: 9, y: 10, z: 11 }],\r\n });\r\n txn.deleteRelationship(batch[0]!);\r\n });\r\n });\r\n\r\n it(\"reads only the requested pairs in a dense many-to-many graph\", async () => {\r\n const cls = ElementGroupsMembers.classFullName;\r\n const n = 5;\r\n await withEditTxn(imodel, async (txn) => {\r\n const sources: Id64String[] = [];\r\n const targets: Id64String[] = [];\r\n for (let i = 0; i < 2 * n; ++i) {\r\n const id = txn.insertElement({ classFullName: RepositoryLink.classFullName, model: IModel.repositoryModelId, code: Code.createEmpty(), repositoryGuid: Guid.createValue() } as RepositoryLinkProps);\r\n (i < n ? sources : targets).push(id);\r\n }\r\n\r\n // Connect every source to every target, then request only the \"diagonal\" pairs.\r\n for (const sourceId of sources)\r\n for (const targetId of targets)\r\n txn.insertRelationship(ElementGroupsMembers.create(imodel, sourceId, targetId, 0).toJSON());\r\n\r\n const pairs = sources.map((sourceId, i) => ({ sourceId, targetId: targets[i] }));\r\n let rowsRead = 0;\r\n const createQueryReader = imodel.createQueryReader.bind(imodel);\r\n const stub = sinon.stub(imodel, \"createQueryReader\").callsFake((ecsql, params, config) => {\r\n const reader = createQueryReader(ecsql, params, config);\r\n const step = reader.step.bind(reader);\r\n reader.step = async () => {\r\n const hasRow = await step();\r\n if (hasRow)\r\n ++rowsRead;\r\n return hasRow;\r\n };\r\n return reader;\r\n });\r\n try {\r\n const found = await imodel.relationships.queryInstancesProps(cls, pairs);\r\n expect(found.map((p) => p && { sourceId: p.sourceId, targetId: p.targetId })).to.deep.equal(pairs);\r\n } finally {\r\n stub.restore();\r\n }\r\n expect(rowsRead).to.equal(n);\r\n });\r\n });\r\n\r\n it(\"supports relationships stored as navigation properties and ids from any briefcase\", async () => {\r\n const cls = \"BisCore:ModelContainsElements\";\r\n const highBriefcaseId = Id64.fromLocalAndBriefcaseIds(1, 0xfffffd);\r\n const criteria: Array<Id64String | SourceAndTarget> = [\r\n elementIds[0],\r\n { sourceId: IModel.repositoryModelId, targetId: elementIds[1] },\r\n highBriefcaseId,\r\n { sourceId: highBriefcaseId, targetId: elementIds[1] },\r\n ];\r\n const batch = await imodel.relationships.queryInstancesProps(cls, criteria);\r\n criteria.forEach((criterion, i) => expect(batch[i]).to.deep.equal(imodel.relationships.tryGetInstanceProps(cls, criterion), `criterion ${i}`));\r\n expect(batch.map((p) => p?.targetId)).to.deep.equal([elementIds[0], elementIds[1], undefined, undefined]);\r\n });\r\n});\r\n"]}