@itwin/core-backend 5.12.0-dev.9 → 5.12.1

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 (140) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/lib/cjs/Category.d.ts +4 -4
  3. package/lib/cjs/Category.js.map +1 -1
  4. package/lib/cjs/ClassRegistry.d.ts.map +1 -1
  5. package/lib/cjs/ClassRegistry.js +1 -2
  6. package/lib/cjs/ClassRegistry.js.map +1 -1
  7. package/lib/cjs/CodeSpecs.d.ts +3 -3
  8. package/lib/cjs/CodeSpecs.js.map +1 -1
  9. package/lib/cjs/DisplayStyle.d.ts +2 -2
  10. package/lib/cjs/DisplayStyle.js.map +1 -1
  11. package/lib/cjs/ECDb.d.ts.map +1 -1
  12. package/lib/cjs/ECDb.js +8 -3
  13. package/lib/cjs/ECDb.js.map +1 -1
  14. package/lib/cjs/ECSqlRowExecutor.d.ts +23 -10
  15. package/lib/cjs/ECSqlRowExecutor.d.ts.map +1 -1
  16. package/lib/cjs/ECSqlRowExecutor.js +77 -15
  17. package/lib/cjs/ECSqlRowExecutor.js.map +1 -1
  18. package/lib/cjs/Element.d.ts +8 -8
  19. package/lib/cjs/Element.d.ts.map +1 -1
  20. package/lib/cjs/Element.js +2 -2
  21. package/lib/cjs/Element.js.map +1 -1
  22. package/lib/cjs/IModelDb.d.ts +34 -22
  23. package/lib/cjs/IModelDb.d.ts.map +1 -1
  24. package/lib/cjs/IModelDb.js +97 -68
  25. package/lib/cjs/IModelDb.js.map +1 -1
  26. package/lib/cjs/IpcHost.d.ts +26 -0
  27. package/lib/cjs/IpcHost.d.ts.map +1 -1
  28. package/lib/cjs/IpcHost.js +68 -61
  29. package/lib/cjs/IpcHost.js.map +1 -1
  30. package/lib/cjs/Model.d.ts +5 -5
  31. package/lib/cjs/Model.d.ts.map +1 -1
  32. package/lib/cjs/Model.js.map +1 -1
  33. package/lib/cjs/Relationship.d.ts.map +1 -1
  34. package/lib/cjs/Relationship.js +13 -7
  35. package/lib/cjs/Relationship.js.map +1 -1
  36. package/lib/cjs/SQLiteDb.d.ts +43 -0
  37. package/lib/cjs/SQLiteDb.d.ts.map +1 -1
  38. package/lib/cjs/SQLiteDb.js +51 -0
  39. package/lib/cjs/SQLiteDb.js.map +1 -1
  40. package/lib/cjs/Texture.d.ts +1 -1
  41. package/lib/cjs/Texture.js.map +1 -1
  42. package/lib/cjs/ViewDefinition.d.ts +6 -6
  43. package/lib/cjs/ViewDefinition.d.ts.map +1 -1
  44. package/lib/cjs/ViewDefinition.js.map +1 -1
  45. package/lib/cjs/ViewStore.js +1 -1
  46. package/lib/cjs/ViewStore.js.map +1 -1
  47. package/lib/cjs/internal/ECSqlInstanceReshaper.d.ts +23 -0
  48. package/lib/cjs/internal/ECSqlInstanceReshaper.d.ts.map +1 -0
  49. package/lib/cjs/internal/ECSqlInstanceReshaper.js +125 -0
  50. package/lib/cjs/internal/ECSqlInstanceReshaper.js.map +1 -0
  51. package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
  52. package/lib/cjs/internal/annotations/fields.js +9 -4
  53. package/lib/cjs/internal/annotations/fields.js.map +1 -1
  54. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  55. package/lib/cjs/internal/workspace/WorkspaceImpl.js +7 -2
  56. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  57. package/lib/esm/Category.d.ts +4 -4
  58. package/lib/esm/Category.js.map +1 -1
  59. package/lib/esm/ClassRegistry.d.ts.map +1 -1
  60. package/lib/esm/ClassRegistry.js +1 -2
  61. package/lib/esm/ClassRegistry.js.map +1 -1
  62. package/lib/esm/CodeSpecs.d.ts +3 -3
  63. package/lib/esm/CodeSpecs.js.map +1 -1
  64. package/lib/esm/DisplayStyle.d.ts +2 -2
  65. package/lib/esm/DisplayStyle.js.map +1 -1
  66. package/lib/esm/ECDb.d.ts.map +1 -1
  67. package/lib/esm/ECDb.js +9 -4
  68. package/lib/esm/ECDb.js.map +1 -1
  69. package/lib/esm/ECSqlRowExecutor.d.ts +23 -10
  70. package/lib/esm/ECSqlRowExecutor.d.ts.map +1 -1
  71. package/lib/esm/ECSqlRowExecutor.js +77 -16
  72. package/lib/esm/ECSqlRowExecutor.js.map +1 -1
  73. package/lib/esm/Element.d.ts +8 -8
  74. package/lib/esm/Element.d.ts.map +1 -1
  75. package/lib/esm/Element.js +2 -2
  76. package/lib/esm/Element.js.map +1 -1
  77. package/lib/esm/IModelDb.d.ts +34 -22
  78. package/lib/esm/IModelDb.d.ts.map +1 -1
  79. package/lib/esm/IModelDb.js +99 -70
  80. package/lib/esm/IModelDb.js.map +1 -1
  81. package/lib/esm/IpcHost.d.ts +26 -0
  82. package/lib/esm/IpcHost.d.ts.map +1 -1
  83. package/lib/esm/IpcHost.js +70 -63
  84. package/lib/esm/IpcHost.js.map +1 -1
  85. package/lib/esm/Model.d.ts +5 -5
  86. package/lib/esm/Model.d.ts.map +1 -1
  87. package/lib/esm/Model.js.map +1 -1
  88. package/lib/esm/Relationship.d.ts.map +1 -1
  89. package/lib/esm/Relationship.js +13 -7
  90. package/lib/esm/Relationship.js.map +1 -1
  91. package/lib/esm/SQLiteDb.d.ts +43 -0
  92. package/lib/esm/SQLiteDb.d.ts.map +1 -1
  93. package/lib/esm/SQLiteDb.js +51 -0
  94. package/lib/esm/SQLiteDb.js.map +1 -1
  95. package/lib/esm/Texture.d.ts +1 -1
  96. package/lib/esm/Texture.js.map +1 -1
  97. package/lib/esm/ViewDefinition.d.ts +6 -6
  98. package/lib/esm/ViewDefinition.d.ts.map +1 -1
  99. package/lib/esm/ViewDefinition.js.map +1 -1
  100. package/lib/esm/ViewStore.js +1 -1
  101. package/lib/esm/ViewStore.js.map +1 -1
  102. package/lib/esm/internal/ECSqlInstanceReshaper.d.ts +23 -0
  103. package/lib/esm/internal/ECSqlInstanceReshaper.d.ts.map +1 -0
  104. package/lib/esm/internal/ECSqlInstanceReshaper.js +120 -0
  105. package/lib/esm/internal/ECSqlInstanceReshaper.js.map +1 -0
  106. package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
  107. package/lib/esm/internal/annotations/fields.js +9 -4
  108. package/lib/esm/internal/annotations/fields.js.map +1 -1
  109. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  110. package/lib/esm/internal/workspace/WorkspaceImpl.js +7 -2
  111. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  112. package/lib/esm/test/IpcHost.test.js +232 -1
  113. package/lib/esm/test/IpcHost.test.js.map +1 -1
  114. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js +139 -1
  115. package/lib/esm/test/ecdb/ECSqlSyncReader.test.js.map +1 -1
  116. package/lib/esm/test/imodel/IModel.test.js +20 -0
  117. package/lib/esm/test/imodel/IModel.test.js.map +1 -1
  118. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.d.ts +2 -0
  119. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.d.ts.map +1 -0
  120. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.js +289 -0
  121. package/lib/esm/test/internal/ECSqlInstanceReshaper.test.js.map +1 -0
  122. package/lib/esm/test/schema/ClassRegistry.test.js +2 -2
  123. package/lib/esm/test/schema/ClassRegistry.test.js.map +1 -1
  124. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.d.ts +2 -0
  125. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.d.ts.map +1 -0
  126. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.js +546 -0
  127. package/lib/esm/test/schema/SchemaViewFragmentLoading.test.js.map +1 -0
  128. package/lib/esm/test/schema/SchemaViewLifecycle.test.js +2 -2
  129. package/lib/esm/test/schema/SchemaViewLifecycle.test.js.map +1 -1
  130. package/lib/esm/test/standalone/MergeConflict.test.js +1 -1
  131. package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
  132. package/lib/esm/test/standalone/SQLiteDb.test.d.ts +1 -1
  133. package/lib/esm/test/standalone/SQLiteDb.test.d.ts.map +1 -1
  134. package/lib/esm/test/standalone/SQLiteDb.test.js +93 -1
  135. package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
  136. package/lib/esm/test/standalone/ViewStoreDb.test.js +30 -0
  137. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  138. package/lib/esm/test/standalone/Workspace.test.js +52 -0
  139. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  140. package/package.json +14 -15
@@ -19,6 +19,7 @@ const BriefcaseManager_1 = require("./BriefcaseManager");
19
19
  const ChannelControl_1 = require("./ChannelControl");
20
20
  const ChannelAdmin_1 = require("./internal/ChannelAdmin");
21
21
  const CheckpointManager_1 = require("./CheckpointManager");
22
+ const ECSqlInstanceReshaper_1 = require("./internal/ECSqlInstanceReshaper");
22
23
  const ClassRegistry_1 = require("./ClassRegistry");
23
24
  const CloudSqlite_1 = require("./CloudSqlite");
24
25
  const CodeService_1 = require("./CodeService");
@@ -165,7 +166,9 @@ class IModelDb extends core_common_1.IModel {
165
166
  _jsClassMap;
166
167
  _schemaMap;
167
168
  _schemaContext;
168
- _schemasPromise;
169
+ // Created lazily on the first getSchemaView call. Owns the SchemaView's lifetime and does all its
170
+ // data access through the SchemaViewDataProvider implemented below.
171
+ _schemaViewManager;
169
172
  /** @deprecated in 5.0.0 - might be removed in next major version. Use [[fonts]]. */
170
173
  _fontMap; // eslint-disable-line @typescript-eslint/no-deprecated
171
174
  _fonts = (0, IModelDbFontsImpl_1.createIModelDbFonts)(this);
@@ -613,16 +616,22 @@ class IModelDb extends core_common_1.IModel {
613
616
  * @param config Allow to specify certain flags which control how query is executed.
614
617
  * @returns the value returned by `callback`.
615
618
  * @throws IModelError if db is not open.
616
- * Should be used when we want true step by step behaviour from the reader without any intermediate caching involved.
619
+ * Use this method for true step-by-step row consumption without intermediate result or page caching.
620
+ * The prepared ECSQL statement may be reused from the statement cache between completed calls.
617
621
  * @beta
618
622
  * */
619
623
  withQueryReader(ecsql, callback, params, config) {
620
624
  if (!this[Symbols_1._nativeDb].isOpen())
621
625
  throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR_NOTOPEN, "db not open");
622
- const executor = new ECSqlRowExecutor_1.ECSqlRowExecutor(this);
623
- const reader = new ECSqlSyncReader_1.ECSqlSyncReader(executor, ecsql, params, config);
624
- const release = () => executor[Symbol.dispose]();
626
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
627
+ const stmt = this._statementCache.findAndRemove(ecsql) ?? new ECSqlStatement_1.ECSqlStatement();
628
+ const executor = new ECSqlRowExecutor_1.ECSqlRowExecutor(this, stmt, loggerCategory);
629
+ const release = () => {
630
+ executor[Symbol.dispose]();
631
+ (0, ECSqlRowExecutor_1.releaseECSqlStatement)(stmt, this._statementCache, loggerCategory, executor.canCacheStatement);
632
+ };
625
633
  try {
634
+ const reader = new ECSqlSyncReader_1.ECSqlSyncReader(executor, ecsql, params, config);
626
635
  const val = callback(reader);
627
636
  if (val instanceof Promise) {
628
637
  val.then(release, release);
@@ -722,8 +731,7 @@ class IModelDb extends core_common_1.IModel {
722
731
  const where = [...parentCategories].join(",");
723
732
  const query = `SELECT ECInstanceId as id, Parent.Id as parentId, Properties as appearance FROM BisCore.SubCategory WHERE Parent.Id IN (${where})`;
724
733
  try {
725
- // eslint-disable-next-line @typescript-eslint/no-deprecated
726
- for await (const row of this.createQueryReader(query, undefined, { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
734
+ for await (const row of this.createQueryReader(query, undefined, { rowFormat: core_common_1.QueryRowFormat.UseECSqlPropertyNames })) {
727
735
  result.push(row.toRow());
728
736
  }
729
737
  }
@@ -743,8 +751,7 @@ class IModelDb extends core_common_1.IModel {
743
751
  const where = [...categoryIds].join(",");
744
752
  const query = `SELECT ECInstanceId as id, Parent.Id as parentId, Properties as appearance FROM BisCore.SubCategory WHERE Parent.Id IN (${where})`;
745
753
  try {
746
- // eslint-disable-next-line @typescript-eslint/no-deprecated
747
- for await (const row of this.createQueryReader(query, undefined, { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
754
+ for await (const row of this.createQueryReader(query, undefined, { rowFormat: core_common_1.QueryRowFormat.UseECSqlPropertyNames })) {
748
755
  result.push(row.toRow());
749
756
  }
750
757
  }
@@ -787,7 +794,7 @@ class IModelDb extends core_common_1.IModel {
787
794
  }
788
795
  }
789
796
  }
790
- }, core_common_1.QueryBinder.from(params.bindings));
797
+ }, core_common_1.QueryBinder.fromSkippingNullish(params.bindings));
791
798
  return ids;
792
799
  }
793
800
  clearCaches(params) {
@@ -798,11 +805,7 @@ class IModelDb extends core_common_1.IModel {
798
805
  this._jsClassMap = undefined;
799
806
  this._schemaMap = undefined;
800
807
  this._schemaContext = undefined;
801
- if (this._schemasPromise) {
802
- const old = this._schemasPromise;
803
- this._schemasPromise = undefined;
804
- old.then((view) => view.markOutdated()).catch(() => { });
805
- }
808
+ this._schemaViewManager?.reset();
806
809
  this[Symbols_1._nativeDb].clearECDbCache();
807
810
  }
808
811
  this.elements[Symbols_1._cache].clear();
@@ -1298,53 +1301,74 @@ class IModelDb extends core_common_1.IModel {
1298
1301
  return this._schemaContext;
1299
1302
  }
1300
1303
  /** Get the schema view for this iModel. The view is built lazily on
1301
- * first call by fetching compact binary schema data via `PRAGMA schema_view` through
1302
- * the ConcurrentQuery thread pool. Subsequent calls return the cached view. Multiple
1303
- * concurrent callers share a single in-flight build.
1304
+ * first call by fetching compact binary schema data through
1305
+ * the ConcurrentQuery thread pool.
1304
1306
  *
1305
1307
  * The returned `SchemaView` is a lightweight, read-only, synchronous API for
1306
1308
  * navigating schema metadata - classes, properties, relationships, enumerations, etc.
1307
1309
  * It is the recommended default for runtime read-only metadata access and is significantly
1308
1310
  * faster and lower-memory than [[schemaContext]]. Use [[schemaContext]] for schema authoring,
1309
1311
  * custom-attribute deserialization, or anywhere you need the full ecschema-metadata object graph.
1312
+ *
1313
+ * Every call shares one accumulating view instance and concurrent calls are serialized, so a
1314
+ * caller never observes a partially loaded view. The instance is discarded by [[clearCaches]],
1315
+ * for example after a schema import; the next call builds a new one. See
1316
+ * [GetSchemaViewArgs]($ecschema-metadata) for the arguments.
1310
1317
  * @beta
1311
1318
  */
1312
- async getSchemaView() {
1313
- if (this._schemasPromise) {
1314
- const ctx = await this._schemasPromise;
1315
- if (!ctx.isOutdated)
1316
- return ctx;
1317
- }
1318
- // Capture the in-flight promise locally so the rejection handler only clears
1319
- // `_schemasPromise` if it still points at this build. A concurrent invalidation +
1320
- // re-fetch could otherwise replace the field before our hydrate fails, and a naive
1321
- // `_schemasPromise = undefined` would clobber that newer reference.
1322
- const inflight = this._hydrateSchemas();
1323
- this._schemasPromise = inflight;
1324
- inflight.catch(() => {
1325
- if (this._schemasPromise === inflight)
1326
- this._schemasPromise = undefined;
1327
- });
1328
- return inflight;
1329
- }
1330
- async _hydrateSchemas() {
1331
- // PRAGMA returns exactly one row with format, formatVersion, data (binary), schemaToken.
1332
- // Important: only call reader.next() once - do NOT use `for await` on PRAGMA results.
1333
- // ConcurrentQuery wraps regular ECSQL in LIMIT/OFFSET for pagination but skips this for
1334
- // PRAGMAs. If the serialized result exceeds the memory threshold, the response is marked
1335
- // "Partial", and a `for await` loop would re-issue the same PRAGMA forever since PRAGMAs
1336
- // don't support OFFSET-based pagination.
1337
- // This implementation uses the non-pinned version of the pragma other than frontend - because backend
1338
- // is always strictly coupled with the native code.
1339
- const reader = this.createQueryReader("PRAGMA schema_view");
1319
+ async getSchemaView(args) {
1320
+ this._schemaViewManager ??= new ecschema_metadata_1.SchemaViewManager(this._createSchemaViewDataProvider());
1321
+ return this._schemaViewManager.getSchemaView(args);
1322
+ }
1323
+ /** The [SchemaViewDataProvider]($ecschema-metadata) backing this iModel's [[getSchemaView]]: the
1324
+ * transport-specific half of schema-view loading. The backend always uses the latest blob version
1325
+ * since it is strictly coupled with native code.
1326
+ */
1327
+ _createSchemaViewDataProvider() {
1328
+ return {
1329
+ fetchFullBlob: async () => this._fetchSchemaBlob("PRAGMA schema_view"),
1330
+ // Names are ECNames, so a comma can never occur in one. Native re-validates each token as an
1331
+ // ECName and fails the pragma on an unknown name.
1332
+ fetchFragmentBlob: async (schemaNames) => this._fetchSchemaBlob(`PRAGMA schema_view_fragment('${schemaNames.join(",")}')`),
1333
+ fetchManifest: async () => {
1334
+ const schemaRows = [];
1335
+ const schemaSql = "SELECT ECInstanceId, Name, VersionMajor, VersionWrite, VersionMinor FROM meta.ECSchemaDef";
1336
+ for await (const row of this.createQueryReader(schemaSql)) {
1337
+ // ECInstanceId arrives as a hex Id64String. `ec_` metadata rowids carry no briefcase
1338
+ // prefix, so the local id is the full value.
1339
+ schemaRows.push({ ecInstanceId: core_bentley_1.Id64.getLocalId(row[0]), name: row[1], versionMajor: row[2], versionWrite: row[3], versionMinor: row[4] });
1340
+ }
1341
+ const referenceRows = [];
1342
+ const referenceSql = "SELECT SourceECInstanceId, TargetECInstanceId FROM meta.SchemaHasSchemaReferences";
1343
+ for await (const row of this.createQueryReader(referenceSql))
1344
+ referenceRows.push({ sourceECInstanceId: core_bentley_1.Id64.getLocalId(row[0]), targetECInstanceId: core_bentley_1.Id64.getLocalId(row[1]) });
1345
+ return ecschema_metadata_1.SchemaManifest.fromRows(schemaRows, referenceRows);
1346
+ },
1347
+ fetchSchemaToken: async () => {
1348
+ const reader = this.createQueryReader("PRAGMA checksum(schema_token)");
1349
+ const result = await reader.next();
1350
+ if (result.done)
1351
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "PRAGMA checksum(schema_token) returned no rows");
1352
+ return result.value.sha3_256;
1353
+ },
1354
+ };
1355
+ }
1356
+ /** Fetch one schema-view blob (full or fragment). Both `PRAGMA schema_view` and
1357
+ * `PRAGMA schema_view_fragment` return a single row with the same columns. */
1358
+ async _fetchSchemaBlob(pragma) {
1359
+ // Only call reader.next() once - do NOT use `for await` on PRAGMA results. ConcurrentQuery wraps
1360
+ // regular ECSQL in LIMIT/OFFSET for pagination but skips this for PRAGMAs; if the serialized result
1361
+ // exceeds the memory threshold the response is marked "Partial", and a `for await` loop would
1362
+ // re-issue the same PRAGMA forever since PRAGMAs don't support OFFSET-based pagination.
1363
+ const reader = this.createQueryReader(pragma);
1340
1364
  const result = await reader.next();
1341
1365
  if (result.done)
1342
- throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "PRAGMA schema_view returned no rows");
1366
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, `${pragma} returned no rows`);
1343
1367
  const data = result.value.data;
1344
1368
  const token = result.value.schemaToken;
1345
1369
  if (data === undefined || data === null)
1346
- throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "PRAGMA schema_view returned null data column");
1347
- return ecschema_metadata_1.SchemaView.fromBinary(data, token ?? "");
1370
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, `${pragma} returned null data column`);
1371
+ return { data, schemaToken: token ?? "" };
1348
1372
  }
1349
1373
  /** Get the linkTableRelationships for this IModel */
1350
1374
  get relationships() {
@@ -2149,7 +2173,7 @@ function processSchemaWriteStatus(status) {
2149
2173
  * @param props The data for the new model.
2150
2174
  * @returns The newly inserted model's Id.
2151
2175
  * @throws [[IModelError]] if insertion fails.
2152
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2176
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2153
2177
  */
2154
2178
  insertModel(props) {
2155
2179
  return this._iModel[Symbols_1._implicitTxn].insertModel(props);
@@ -2157,7 +2181,7 @@ function processSchemaWriteStatus(status) {
2157
2181
  /** Update an existing model.
2158
2182
  * @param props the properties of the model to change
2159
2183
  * @throws [[IModelError]] if update fails.
2160
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2184
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2161
2185
  */
2162
2186
  updateModel(props) {
2163
2187
  this._iModel[Symbols_1._implicitTxn].updateModel(props);
@@ -2169,7 +2193,7 @@ function processSchemaWriteStatus(status) {
2169
2193
  * Cached [Tile]($frontend)s are only invalidated after the geometry guid of the model changes.
2170
2194
  * @note This will throw IModelError with [IModelStatus.VersionTooOld]($core-bentley) if a version of the BisCore schema older than 1.0.11 is present in the iModel.
2171
2195
  * @throws [[IModelError]] if the update fails.
2172
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateGeometryGuid instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2196
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateGeometryGuid instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2173
2197
  * @see [[TxnManager.onModelGeometryChanged]] for the event emitted in response to such a change.
2174
2198
  */
2175
2199
  updateGeometryGuid(modelId) {
@@ -2178,7 +2202,7 @@ function processSchemaWriteStatus(status) {
2178
2202
  /** Delete one or more existing models.
2179
2203
  * @param ids The Ids of the models to be deleted
2180
2204
  * @throws [[IModelError]] if deletion fails.
2181
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2205
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2182
2206
  */
2183
2207
  deleteModel(ids) {
2184
2208
  this._iModel[Symbols_1._implicitTxn].deleteModel(ids);
@@ -2402,7 +2426,7 @@ function processSchemaWriteStatus(status) {
2402
2426
  * However when `elProps.federationGuid` is not present or undefined, a new Guid will be generated and stored on the resultant element. But
2403
2427
  * the value of `elProps.federationGuid` is *not* updated. Generally, it is best to re-read the element after inserting (e.g. via [[getElementProps]])
2404
2428
  * if you intend to continue working with it. That will ensure its values reflect the persistent state.
2405
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2429
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2406
2430
  */
2407
2431
  insertElement(elProps, options) {
2408
2432
  return this._iModel[Symbols_1._implicitTxn].insertElement(elProps, options);
@@ -2417,7 +2441,7 @@ function processSchemaWriteStatus(status) {
2417
2441
  * @note The values of `classFullName` and `model` *may not be changed* by this method. Further, it will permute the `elProps` object by adding or
2418
2442
  * overwriting their values to the correct values.
2419
2443
  * @throws [[ITwinError]] if update fails.
2420
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2444
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2421
2445
  */
2422
2446
  updateElement(elProps) {
2423
2447
  this._iModel[Symbols_1._implicitTxn].updateElement(elProps);
@@ -2426,7 +2450,7 @@ function processSchemaWriteStatus(status) {
2426
2450
  * @param ids The set of Ids of the element(s) to be deleted
2427
2451
  * @throws [[ITwinError]]
2428
2452
  * @see deleteDefinitionElements
2429
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2453
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2430
2454
  */
2431
2455
  deleteElement(ids) {
2432
2456
  this._iModel[Symbols_1._implicitTxn].deleteElement(ids);
@@ -2451,7 +2475,7 @@ function processSchemaWriteStatus(status) {
2451
2475
  * DefinitionElements rather than calling this method separately for each one. Ids that are not valid DefinitionElements will be ignored.
2452
2476
  * @returns An IdSet of the DefinitionElements that are used and were therefore not deleted.
2453
2477
  * @see deleteElement
2454
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteDefinitionElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2478
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteDefinitionElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2455
2479
  */
2456
2480
  deleteDefinitionElements(definitionElementIds) {
2457
2481
  return this._iModel[Symbols_1._implicitTxn].deleteDefinitionElements(definitionElementIds);
@@ -2520,16 +2544,21 @@ function processSchemaWriteStatus(status) {
2520
2544
  * @throws [[IModelError]]
2521
2545
  */
2522
2546
  _queryAspect(aspectInstanceId, aspectClassName) {
2523
- const sql = `SELECT *, ec_classname(ECClassId, 's:c') classFullName FROM ${aspectClassName} WHERE ECInstanceId=:aspectInstanceId`;
2547
+ // `SELECT *` targets a caller/runtime-determined ElementAspect subclass, so its shape can't be decomposed
2548
+ // ahead of time. Query using the non-deprecated UseECSqlPropertyNames format and reshape the row into the
2549
+ // legacy UseJsPropertyNames shape using ECSchema metadata (see ECSqlInstanceReshaper for why a naive,
2550
+ // non-schema-aware rename isn't safe here).
2551
+ const ecClass = (0, ECSqlInstanceReshaper_1.getRuntimeClass)(this._iModel, aspectClassName);
2552
+ const sql = `SELECT * FROM ${aspectClassName} WHERE ECInstanceId=:aspectInstanceId`;
2524
2553
  const aspect = this._iModel.withQueryReader(sql, (reader) => {
2525
2554
  if (reader.step()) {
2526
- const aspectProps = { ...reader.current.toRow() }; // start with everything that SELECT * returned; classFullName is supplied by the ec_classname alias
2527
- aspectProps.className = undefined; // clear the raw ECClassId-derived property from SELECT * that we don't want in the final instance
2555
+ const aspectProps = (0, ECSqlInstanceReshaper_1.reshapeInstanceRow)(reader.current.toRow(), ecClass, this._iModel);
2556
+ aspectProps.classFullName = aspectProps.className.replace(".", ":"); // add in property required by EntityProps
2557
+ aspectProps.className = undefined; // clear property from SELECT * that we don't want in the final instance
2528
2558
  return aspectProps;
2529
2559
  }
2530
2560
  return undefined;
2531
- // eslint-disable-next-line @typescript-eslint/no-deprecated
2532
- }, new core_common_1.QueryBinder().bindId("aspectInstanceId", aspectInstanceId), { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames });
2561
+ }, new core_common_1.QueryBinder().bindId("aspectInstanceId", aspectInstanceId), { rowFormat: core_common_1.QueryRowFormat.UseECSqlPropertyNames });
2533
2562
  if (undefined === aspect) {
2534
2563
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `ElementAspect not found ${aspectInstanceId}, ${aspectClassName}`);
2535
2564
  }
@@ -2633,7 +2662,7 @@ function processSchemaWriteStatus(status) {
2633
2662
  * @returns the id of the newly inserted aspect.
2634
2663
  * @note Aspect Ids may collide with element Ids, so don't put both in a container like Set or Map
2635
2664
  * use [EntityReference]($common) for that instead.
2636
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2665
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2637
2666
  */
2638
2667
  insertAspect(aspectProps) {
2639
2668
  return this._iModel[Symbols_1._implicitTxn].insertAspect(aspectProps);
@@ -2641,7 +2670,7 @@ function processSchemaWriteStatus(status) {
2641
2670
  /** Update an exist ElementAspect within the iModel.
2642
2671
  * @param aspectProps The properties to use to update the ElementAspect.
2643
2672
  * @throws [[IModelError]] if unable to update the ElementAspect.
2644
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2673
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2645
2674
  */
2646
2675
  updateAspect(aspectProps) {
2647
2676
  this._iModel[Symbols_1._implicitTxn].updateAspect(aspectProps);
@@ -2649,7 +2678,7 @@ function processSchemaWriteStatus(status) {
2649
2678
  /** Delete one or more ElementAspects from this iModel.
2650
2679
  * @param aspectInstanceIds The set of instance Ids of the ElementAspect(s) to be deleted
2651
2680
  * @throws [[IModelError]] if unable to delete the ElementAspect.
2652
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2681
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2653
2682
  */
2654
2683
  deleteAspect(aspectInstanceIds) {
2655
2684
  this._iModel[Symbols_1._implicitTxn].deleteAspect(aspectInstanceIds);
@@ -2658,7 +2687,7 @@ function processSchemaWriteStatus(status) {
2658
2687
  * @param props The properties specifying the element to reparent and its new parent.
2659
2688
  * @throws [[ITwinError]] if the operation fails.
2660
2689
  * @beta
2661
- * @deprecated in 5.11.0 - will not be removed until after 2026-08-04. Use EditTxn.changeElementParent instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2690
+ * @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementParent instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2662
2691
  */
2663
2692
  changeElementParent(props) {
2664
2693
  this._iModel[Symbols_1._implicitTxn].changeElementParent(props);
@@ -2667,7 +2696,7 @@ function processSchemaWriteStatus(status) {
2667
2696
  * @param props The properties specifying the element to move and its new model.
2668
2697
  * @throws [[ITwinError]] if the operation fails.
2669
2698
  * @beta
2670
- * @deprecated in 5.11.0 - will not be removed until after 2026-08-04. Use EditTxn.changeElementModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2699
+ * @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2671
2700
  */
2672
2701
  changeElementModel(props) {
2673
2702
  this._iModel[Symbols_1._implicitTxn].changeElementModel(props);
@@ -2714,7 +2743,7 @@ function processSchemaWriteStatus(status) {
2714
2743
  return this._viewStore;
2715
2744
  }
2716
2745
  /**
2717
- * @beta @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.saveDefaultViewStore instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2746
+ * @beta @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.saveDefaultViewStore instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2718
2747
  */
2719
2748
  saveDefaultViewStore(arg) {
2720
2749
  this._iModel[Symbols_1._implicitTxn].saveDefaultViewStore(arg);