@itwin/core-backend 4.6.0-dev.9 → 4.7.0-dev.3

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 (162) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/BackendHubAccess.js +1 -1
  3. package/lib/cjs/BackendHubAccess.js.map +1 -1
  4. package/lib/cjs/BackendLoggerCategory.js +1 -1
  5. package/lib/cjs/BackendLoggerCategory.js.map +1 -1
  6. package/lib/cjs/BisCoreSchema.d.ts.map +1 -1
  7. package/lib/cjs/BisCoreSchema.js +2 -0
  8. package/lib/cjs/BisCoreSchema.js.map +1 -1
  9. package/lib/cjs/BlobContainerService.js +1 -1
  10. package/lib/cjs/BlobContainerService.js.map +1 -1
  11. package/lib/cjs/BriefcaseManager.js +2 -2
  12. package/lib/cjs/BriefcaseManager.js.map +1 -1
  13. package/lib/cjs/Category.d.ts +1 -1
  14. package/lib/cjs/Category.js +1 -1
  15. package/lib/cjs/Category.js.map +1 -1
  16. package/lib/cjs/ChangeSummaryManager.js +1 -1
  17. package/lib/cjs/ChangeSummaryManager.js.map +1 -1
  18. package/lib/cjs/ChangedElementsManager.js.map +1 -1
  19. package/lib/cjs/ChangesetECAdaptor.js +2 -2
  20. package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
  21. package/lib/cjs/ChannelControl.js +2 -2
  22. package/lib/cjs/ChannelControl.js.map +1 -1
  23. package/lib/cjs/CheckpointManager.js +4 -4
  24. package/lib/cjs/CheckpointManager.js.map +1 -1
  25. package/lib/cjs/ClassRegistry.d.ts +3 -0
  26. package/lib/cjs/ClassRegistry.d.ts.map +1 -1
  27. package/lib/cjs/ClassRegistry.js +19 -8
  28. package/lib/cjs/ClassRegistry.js.map +1 -1
  29. package/lib/cjs/CloudSqlite.js +1 -1
  30. package/lib/cjs/CloudSqlite.js.map +1 -1
  31. package/lib/cjs/CodeService.js +1 -1
  32. package/lib/cjs/CodeService.js.map +1 -1
  33. package/lib/cjs/CodeSpecs.js +1 -1
  34. package/lib/cjs/CodeSpecs.js.map +1 -1
  35. package/lib/cjs/CustomViewState3dCreator.js.map +1 -1
  36. package/lib/cjs/DevTools.js +2 -2
  37. package/lib/cjs/DevTools.js.map +1 -1
  38. package/lib/cjs/DisplayStyle.js.map +1 -1
  39. package/lib/cjs/ECDb.js +1 -1
  40. package/lib/cjs/ECDb.js.map +1 -1
  41. package/lib/cjs/ECSchemaXmlContext.js.map +1 -1
  42. package/lib/cjs/ECSqlStatement.js.map +1 -1
  43. package/lib/cjs/Element.d.ts +0 -16
  44. package/lib/cjs/Element.d.ts.map +1 -1
  45. package/lib/cjs/Element.js +7 -23
  46. package/lib/cjs/Element.js.map +1 -1
  47. package/lib/cjs/ElementAspect.js +1 -1
  48. package/lib/cjs/ElementAspect.js.map +1 -1
  49. package/lib/cjs/ElementGraphics.d.ts +0 -3
  50. package/lib/cjs/ElementGraphics.d.ts.map +1 -1
  51. package/lib/cjs/ElementGraphics.js +2 -5
  52. package/lib/cjs/ElementGraphics.js.map +1 -1
  53. package/lib/cjs/ElementTreeWalker.d.ts.map +1 -1
  54. package/lib/cjs/ElementTreeWalker.js +5 -0
  55. package/lib/cjs/ElementTreeWalker.js.map +1 -1
  56. package/lib/cjs/EntityReferences.js +1 -1
  57. package/lib/cjs/EntityReferences.js.map +1 -1
  58. package/lib/cjs/ExportGraphics.d.ts +1 -1
  59. package/lib/cjs/ExportGraphics.js +2 -2
  60. package/lib/cjs/ExportGraphics.js.map +1 -1
  61. package/lib/cjs/ExternalSource.js.map +1 -1
  62. package/lib/cjs/GeoCoordConfig.js +1 -1
  63. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  64. package/lib/cjs/GeometrySummary.js +5 -5
  65. package/lib/cjs/GeometrySummary.js.map +1 -1
  66. package/lib/cjs/HubMock.js +1 -1
  67. package/lib/cjs/HubMock.js.map +1 -1
  68. package/lib/cjs/IModelDb.d.ts +8 -2
  69. package/lib/cjs/IModelDb.d.ts.map +1 -1
  70. package/lib/cjs/IModelDb.js +62 -21
  71. package/lib/cjs/IModelDb.js.map +1 -1
  72. package/lib/cjs/IModelElementCloneContext.js.map +1 -1
  73. package/lib/cjs/IModelHost.js +2 -2
  74. package/lib/cjs/IModelHost.js.map +1 -1
  75. package/lib/cjs/IModelJsFs.js.map +1 -1
  76. package/lib/cjs/IpcHost.js +1 -1
  77. package/lib/cjs/IpcHost.js.map +1 -1
  78. package/lib/cjs/LineStyle.d.ts +1 -1
  79. package/lib/cjs/LineStyle.js +2 -2
  80. package/lib/cjs/LineStyle.js.map +1 -1
  81. package/lib/cjs/LocalHub.js.map +1 -1
  82. package/lib/cjs/LocalhostIpcHost.js +1 -1
  83. package/lib/cjs/LocalhostIpcHost.js.map +1 -1
  84. package/lib/cjs/Material.js +1 -1
  85. package/lib/cjs/Material.js.map +1 -1
  86. package/lib/cjs/NativeAppStorage.js +1 -1
  87. package/lib/cjs/NativeAppStorage.js.map +1 -1
  88. package/lib/cjs/NativeHost.js +1 -1
  89. package/lib/cjs/NativeHost.js.map +1 -1
  90. package/lib/cjs/NavigationRelationship.js +21 -21
  91. package/lib/cjs/NavigationRelationship.js.map +1 -1
  92. package/lib/cjs/PromiseMemoizer.d.ts +0 -3
  93. package/lib/cjs/PromiseMemoizer.d.ts.map +1 -1
  94. package/lib/cjs/PromiseMemoizer.js +2 -5
  95. package/lib/cjs/PromiseMemoizer.js.map +1 -1
  96. package/lib/cjs/PropertyStore.js +1 -1
  97. package/lib/cjs/PropertyStore.js.map +1 -1
  98. package/lib/cjs/Relationship.js.map +1 -1
  99. package/lib/cjs/SQLiteDb.js +2 -2
  100. package/lib/cjs/SQLiteDb.js.map +1 -1
  101. package/lib/cjs/Schema.js +1 -1
  102. package/lib/cjs/Schema.js.map +1 -1
  103. package/lib/cjs/SchemaSync.js +1 -1
  104. package/lib/cjs/SchemaSync.js.map +1 -1
  105. package/lib/cjs/ServerBasedLocks.js.map +1 -1
  106. package/lib/cjs/SqliteChangesetReader.js.map +1 -1
  107. package/lib/cjs/SqliteStatement.js +2 -2
  108. package/lib/cjs/SqliteStatement.js.map +1 -1
  109. package/lib/cjs/TextAnnotationElement.d.ts +54 -0
  110. package/lib/cjs/TextAnnotationElement.d.ts.map +1 -0
  111. package/lib/cjs/TextAnnotationElement.js +94 -0
  112. package/lib/cjs/TextAnnotationElement.js.map +1 -0
  113. package/lib/cjs/TextAnnotationGeometry.d.ts +28 -0
  114. package/lib/cjs/TextAnnotationGeometry.d.ts.map +1 -0
  115. package/lib/cjs/TextAnnotationGeometry.js +155 -0
  116. package/lib/cjs/TextAnnotationGeometry.js.map +1 -0
  117. package/lib/cjs/TextAnnotationLayout.d.ts +141 -0
  118. package/lib/cjs/TextAnnotationLayout.d.ts.map +1 -0
  119. package/lib/cjs/TextAnnotationLayout.js +414 -0
  120. package/lib/cjs/TextAnnotationLayout.js.map +1 -0
  121. package/lib/cjs/TileStorage.js.map +1 -1
  122. package/lib/cjs/TxnManager.d.ts.map +1 -1
  123. package/lib/cjs/TxnManager.js +53 -1
  124. package/lib/cjs/TxnManager.js.map +1 -1
  125. package/lib/cjs/ViewDefinition.js +4 -4
  126. package/lib/cjs/ViewDefinition.js.map +1 -1
  127. package/lib/cjs/ViewStateHydrator.d.ts +1 -0
  128. package/lib/cjs/ViewStateHydrator.d.ts.map +1 -1
  129. package/lib/cjs/ViewStateHydrator.js +1 -0
  130. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  131. package/lib/cjs/ViewStore.js +1 -1
  132. package/lib/cjs/ViewStore.js.map +1 -1
  133. package/lib/cjs/core-backend.d.ts +47 -61
  134. package/lib/cjs/core-backend.d.ts.map +1 -1
  135. package/lib/cjs/core-backend.js +49 -62
  136. package/lib/cjs/core-backend.js.map +1 -1
  137. package/lib/cjs/domains/FunctionalElements.js +1 -1
  138. package/lib/cjs/domains/FunctionalElements.js.map +1 -1
  139. package/lib/cjs/domains/FunctionalSchema.js.map +1 -1
  140. package/lib/cjs/domains/GenericSchema.js.map +1 -1
  141. package/lib/cjs/rpc/multipart.js.map +1 -1
  142. package/lib/cjs/rpc/tracing.js +2 -2
  143. package/lib/cjs/rpc/tracing.js.map +1 -1
  144. package/lib/cjs/rpc/web/logging.js +2 -2
  145. package/lib/cjs/rpc/web/logging.js.map +1 -1
  146. package/lib/cjs/rpc/web/request.js.map +1 -1
  147. package/lib/cjs/rpc/web/response.js +1 -1
  148. package/lib/cjs/rpc/web/response.js.map +1 -1
  149. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  150. package/lib/cjs/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  151. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js +1 -1
  152. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  153. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  154. package/lib/cjs/workspace/Settings.js +1 -1
  155. package/lib/cjs/workspace/Settings.js.map +1 -1
  156. package/lib/cjs/workspace/SettingsSchemas.d.ts +0 -5
  157. package/lib/cjs/workspace/SettingsSchemas.d.ts.map +1 -1
  158. package/lib/cjs/workspace/SettingsSchemas.js +1 -10
  159. package/lib/cjs/workspace/SettingsSchemas.js.map +1 -1
  160. package/lib/cjs/workspace/Workspace.js +4 -4
  161. package/lib/cjs/workspace/Workspace.js.map +1 -1
  162. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"ChangeSummaryManager.js","sourceRoot":"","sources":["../../src/ChangeSummaryManager.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\n/** @packageDocumentation\r\n * @module iModels\r\n */\r\n\r\nimport { AccessToken, assert, DbResult, GuidString, Id64String, IModelStatus, Logger, using } from \"@itwin/core-bentley\";\r\nimport { ChangedValueState, ChangeOpCode, ChangesetRange, IModelError, IModelVersion } from \"@itwin/core-common\";\r\nimport * as path from \"path\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { ECDb, ECDbOpenMode } from \"./ECDb\";\r\nimport { ECSqlStatement } from \"./ECSqlStatement\";\r\nimport { BriefcaseDb, IModelDb, TokenArg } from \"./IModelDb\";\r\nimport { IModelHost, KnownLocations } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Represents an instance of the `ChangeSummary` ECClass from the `ECDbChange` ECSchema\r\n * combined with the information from the related `Changeset` instance (from the `IModelChange` ECSchema) from\r\n * which the Change Summary was extracted.\r\n *\r\n * See also\r\n * - [ChangeSummaryManager.queryChangeSummary]($backend)\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport interface ChangeSummary {\r\n id: Id64String;\r\n changeSet: { wsgId: GuidString, parentWsgId: GuidString, description: string, pushDate: string, userCreated: GuidString };\r\n}\r\n\r\n/** Represents an instance of the `InstanceChange` ECClass from the `ECDbChange` ECSchema\r\n *\r\n * See also\r\n * - [ChangeSummaryManager.queryInstanceChange]($backend)\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport interface InstanceChange {\r\n id: Id64String;\r\n summaryId: Id64String;\r\n changedInstance: { id: Id64String, className: string };\r\n opCode: ChangeOpCode;\r\n isIndirect: boolean;\r\n}\r\n\r\n/** Options for [ChangeSummaryManager.createChangeSummaries]($backend).\r\n * @beta\r\n */\r\nexport interface CreateChangeSummaryArgs extends TokenArg {\r\n /** Id of the iTwin that contains the iModel */\r\n iTwinId: GuidString;\r\n\r\n /** Id of the iModel */\r\n iModelId: GuidString;\r\n\r\n /**\r\n * Range of change sets\r\n * - the Change Summary for the first and last versions are also included\r\n * - if unspecified, all change sets until the latest version are processed\r\n */\r\n range: ChangesetRange;\r\n}\r\n\r\n/** Class to extract Change Summaries for a briefcase.\r\n *\r\n * See also:\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport class ChangeSummaryManager {\r\n private static readonly _currentIModelChangeSchemaVersion = { read: 2, write: 0, minor: 0 };\r\n\r\n /** Determines whether the *Change Cache file* is attached to the specified iModel or not\r\n * @param iModel iModel to check whether a *Change Cache file* is attached\r\n * @returns Returns true if the *Change Cache file* is attached to the iModel. false otherwise\r\n */\r\n public static isChangeCacheAttached(iModel: IModelDb): boolean {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n return iModel.nativeDb.isChangeCacheAttached();\r\n }\r\n\r\n /** Attaches the *Change Cache file* to the specified iModel if it hasn't been attached yet.\r\n * A new *Change Cache file* will be created for the iModel if it hasn't existed before.\r\n * @param iModel iModel to attach the *Change Cache file* file to\r\n * @throws [IModelError]($common)\r\n */\r\n public static attachChangeCache(iModel: IModelDb): void {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n if (ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n return;\r\n\r\n const changesCacheFilePath: string = BriefcaseManager.getChangeCachePathName(iModel.iModelId);\r\n if (!IModelJsFs.existsSync(changesCacheFilePath)) {\r\n using(new ECDb(), (changeCacheFile: ECDb) => {\r\n ChangeSummaryManager.createChangeCacheFile(iModel, changeCacheFile, changesCacheFilePath);\r\n });\r\n }\r\n\r\n assert(IModelJsFs.existsSync(changesCacheFilePath));\r\n const res: DbResult = iModel.nativeDb.attachChangeCache(changesCacheFilePath);\r\n if (res !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(res, `Failed to attach Change Cache file to ${iModel.pathName}.`);\r\n }\r\n\r\n /** Detaches the *Change Cache file* from the specified iModel.\r\n * - note that this method will cause any pending (currently running or queued) queries to fail\r\n * @param iModel iModel to detach the *Change Cache file* to\r\n * @throws [IModelError]($common) in case of errors, e.g. if no *Change Cache file* was attached before.\r\n */\r\n public static detachChangeCache(iModel: IModelDb): void {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n iModel.clearCaches();\r\n const res: DbResult = iModel.nativeDb.detachChangeCache();\r\n if (res !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(res, `Failed to detach Change Cache file from ${iModel.pathName}.`);\r\n }\r\n\r\n private static openOrCreateChangesFile(iModel: BriefcaseDb): ECDb {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid iModel handle. iModel must be open.\");\r\n\r\n const changesFile = new ECDb();\r\n const changeCacheFilePath = BriefcaseManager.getChangeCachePathName(iModel.iModelId);\r\n if (IModelJsFs.existsSync(changeCacheFilePath)) {\r\n ChangeSummaryManager.openChangeCacheFile(changesFile, changeCacheFilePath);\r\n return changesFile;\r\n }\r\n\r\n try {\r\n ChangeSummaryManager.createChangeCacheFile(iModel, changesFile, changeCacheFilePath);\r\n return changesFile;\r\n } catch (e) {\r\n // delete cache file again in case it was created but schema import failed\r\n if (IModelJsFs.existsSync(changeCacheFilePath))\r\n IModelJsFs.removeSync(changeCacheFilePath);\r\n\r\n throw e;\r\n }\r\n }\r\n\r\n private static createChangeCacheFile(iModel: IModelDb, changesFile: ECDb, changeCacheFilePath: string): void {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid iModel object. iModel must be open.\");\r\n\r\n const stat: DbResult = iModel.nativeDb.createChangeCache(changesFile.nativeDb, changeCacheFilePath);\r\n if (stat !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(stat, `Failed to create Change Cache file at \"${changeCacheFilePath}\".`);\r\n\r\n // Extended information like changeset ids, push dates are persisted in the IModelChange ECSchema\r\n changesFile.importSchema(ChangeSummaryManager.getExtendedSchemaPath());\r\n }\r\n\r\n private static openChangeCacheFile(changesFile: ECDb, changeCacheFilePath: string): void {\r\n changesFile.openDb(changeCacheFilePath, ECDbOpenMode.FileUpgrade);\r\n\r\n const actualSchemaVersion: { read: number, write: number, minor: number } = changesFile.withPreparedStatement(\"SELECT VersionMajor read,VersionWrite write,VersionMinor minor FROM meta.ECSchemaDef WHERE Name='IModelChange'\",\r\n (stmt: ECSqlStatement) => {\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"File is not a valid Change Cache file.\");\r\n\r\n return stmt.getRow();\r\n });\r\n\r\n if (actualSchemaVersion.read === ChangeSummaryManager._currentIModelChangeSchemaVersion.read &&\r\n actualSchemaVersion.write === ChangeSummaryManager._currentIModelChangeSchemaVersion.write &&\r\n actualSchemaVersion.minor === ChangeSummaryManager._currentIModelChangeSchemaVersion.minor)\r\n return;\r\n\r\n changesFile.importSchema(ChangeSummaryManager.getExtendedSchemaPath());\r\n }\r\n\r\n private static getExtendedSchemaPath(): string { return path.join(KnownLocations.packageAssetsDir, \"IModelChange.02.00.00.ecschema.xml\"); }\r\n\r\n private static isSummaryAlreadyExtracted(changesFile: ECDb, changeSetId: GuidString): Id64String | undefined {\r\n return changesFile.withPreparedStatement(\"SELECT Summary.Id summaryid FROM imodelchange.ChangeSet WHERE WsgId=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindString(1, changeSetId);\r\n if (DbResult.BE_SQLITE_ROW === stmt.step())\r\n return stmt.getValue(0).getId();\r\n\r\n return undefined;\r\n });\r\n }\r\n\r\n private static addExtendedInfos(changesFile: ECDb, changeSummaryId: Id64String, changesetWsgId: GuidString, changesetParentWsgId?: GuidString, description?: string, changesetPushDate?: string, changeSetUserCreated?: GuidString): void {\r\n changesFile.withPreparedStatement(\"INSERT INTO imodelchange.ChangeSet(Summary.Id,WsgId,ParentWsgId,Description,PushDate,UserCreated) VALUES(?,?,?,?,?,?)\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, changeSummaryId);\r\n stmt.bindString(2, changesetWsgId);\r\n if (changesetParentWsgId)\r\n stmt.bindString(3, changesetParentWsgId);\r\n\r\n if (description)\r\n stmt.bindString(4, description);\r\n\r\n if (changesetPushDate)\r\n stmt.bindDateTime(5, changesetPushDate);\r\n\r\n if (changeSetUserCreated)\r\n stmt.bindString(6, changeSetUserCreated);\r\n\r\n const r: DbResult = stmt.step();\r\n if (r !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(r, `Failed to add changeset information to extracted change summary ${changeSummaryId}`);\r\n });\r\n }\r\n\r\n /** Queries the ChangeSummary for the specified change summary id\r\n *\r\n * See also\r\n * - `ECDbChange.ChangeSummary` ECClass in the *ECDbChange* ECSchema\r\n * - [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param changeSummaryId ECInstanceId of the ChangeSummary\r\n * @returns Returns the requested ChangeSummary object\r\n * @throws [IModelError]($common) If change summary does not exist for the specified id, or if the\r\n * change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static queryChangeSummary(iModel: BriefcaseDb, changeSummaryId: Id64String): ChangeSummary {\r\n if (!ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadArg, \"Change Cache file must be attached to iModel.\");\r\n\r\n return iModel.withPreparedStatement(\"SELECT WsgId,ParentWsgId,Description,PushDate,UserCreated FROM ecchange.imodelchange.ChangeSet WHERE Summary.Id=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, changeSummaryId);\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(IModelStatus.BadArg, `No ChangeSet information found for ChangeSummary ${changeSummaryId}.`);\r\n\r\n const row = stmt.getRow();\r\n return { id: changeSummaryId, changeSet: { wsgId: row.wsgId, parentWsgId: row.parentWsgId, description: row.description, pushDate: row.pushDate, userCreated: row.userCreated } };\r\n });\r\n }\r\n\r\n /** Queries the InstanceChange for the specified instance change id.\r\n *\r\n * See also\r\n * - `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema\r\n * - [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeId ECInstanceId of the InstanceChange (see `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema)\r\n * @returns Returns the requested InstanceChange object (see `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema)\r\n * @throws [IModelError]($common) if instance change does not exist for the specified id, or if the\r\n * change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static queryInstanceChange(iModel: BriefcaseDb, instanceChangeId: Id64String): InstanceChange {\r\n if (!ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadArg, \"Change Cache file must be attached to iModel.\");\r\n\r\n // query instance changes\r\n const instanceChange: InstanceChange = iModel.withPreparedStatement(`SELECT ic.Summary.Id summaryId, s.Name changedInstanceSchemaName, c.Name changedInstanceClassName, ic.ChangedInstance.Id changedInstanceId,\r\n ic.OpCode, ic.IsIndirect FROM ecchange.change.InstanceChange ic JOIN main.meta.ECClassDef c ON c.ECInstanceId = ic.ChangedInstance.ClassId\r\n JOIN main.meta.ECSchemaDef s ON c.Schema.Id = s.ECInstanceId WHERE ic.ECInstanceId =? `, (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, instanceChangeId);\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(IModelStatus.BadArg, `No InstanceChange found for id ${instanceChangeId}.`);\r\n\r\n const row = stmt.getRow();\r\n const changedInstanceId: Id64String = row.changedInstanceId;\r\n const changedInstanceClassName: string = `[${row.changedInstanceSchemaName}].[${row.changedInstanceClassName}]`;\r\n const op: ChangeOpCode = row.opCode as ChangeOpCode;\r\n\r\n return {\r\n id: instanceChangeId, summaryId: row.summaryId, changedInstance: { id: changedInstanceId, className: changedInstanceClassName },\r\n opCode: op, isIndirect: row.isIndirect,\r\n };\r\n });\r\n\r\n return instanceChange;\r\n }\r\n\r\n /** Retrieves the names of the properties whose values have changed for the given instance change\r\n *\r\n * See also [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeId Id of the InstanceChange to query the properties whose values have changed\r\n * @returns Returns names of the properties whose values have changed for the given instance change\r\n * @throws [IModelError]($common) if the change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static getChangedPropertyValueNames(iModel: IModelDb, instanceChangeId: Id64String): string[] {\r\n return iModel.withPreparedStatement(\"SELECT AccessString FROM ecchange.change.PropertyValueChange WHERE InstanceChange.Id=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, instanceChangeId);\r\n\r\n const selectClauseItems: string[] = [];\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n // access string tokens need to be escaped as they might collide with reserved words in ECSQL or SQLite\r\n const accessString: string = stmt.getValue(0).getString();\r\n const accessStringTokens: string[] = accessString.split(\".\");\r\n assert(accessStringTokens.length > 0);\r\n\r\n let isFirstToken: boolean = true;\r\n let item: string = \"\";\r\n for (const token of accessStringTokens) {\r\n if (!isFirstToken)\r\n item += \".\";\r\n\r\n item += `[${token}]`;\r\n isFirstToken = false;\r\n }\r\n selectClauseItems.push(item);\r\n }\r\n\r\n return selectClauseItems;\r\n });\r\n }\r\n\r\n /** Builds the ECSQL to query the property value changes for the specified instance change and the specified ChangedValueState.\r\n *\r\n * See also [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeInfo InstanceChange to query the property value changes for\r\n * changedInstance.className must be fully qualified and schema and class name must be escaped with square brackets if they collide with reserved ECSQL words: `[schema name].[class name]`\r\n * @param changedValueState The Changed State to query the values for. This must correspond to the [InstanceChange.OpCode]($backend) of the InstanceChange.\r\n * @param changedPropertyNames List of the property names for which values have changed for the specified instance change.\r\n * The list can be obtained by calling [ChangeSummaryManager.getChangedPropertyValueNames]($core-backend).\r\n * If omitted, the method will call the above method by itself. The parameter allows for checking first whether\r\n * an instance change has any property value changes at all. If there are no property value changes, this method\r\n * should not be called, as it will throw an error.\r\n * @returns Returns the ECSQL that will retrieve the property value changes\r\n * @throws [IModelError]($common) if instance change does not exist, if there are not property value changes for the instance change,\r\n * if the change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static buildPropertyValueChangesECSql(iModel: IModelDb, instanceChangeInfo: { id: Id64String, summaryId: Id64String, changedInstance: { id: Id64String, className: string } }, changedValueState: ChangedValueState, changedPropertyNames?: string[]): string {\r\n let selectClauseItems: string[];\r\n if (!changedPropertyNames) {\r\n // query property value changes just to build a SELECT statement against the class of the changed instance\r\n selectClauseItems = ChangeSummaryManager.getChangedPropertyValueNames(iModel, instanceChangeInfo.id);\r\n } else\r\n selectClauseItems = changedPropertyNames;\r\n\r\n if (selectClauseItems.length === 0)\r\n throw new IModelError(IModelStatus.BadArg, `No property value changes found for InstanceChange ${instanceChangeInfo.id}.`);\r\n\r\n let ecsql: string = \"SELECT \";\r\n selectClauseItems.map((item: string, index: number) => {\r\n if (index !== 0)\r\n ecsql += \",\";\r\n\r\n ecsql += item;\r\n });\r\n\r\n // Avoiding parameters in the Changes function speeds up performance because ECDb can do optimizations\r\n // if it knows the function args at prepare time\r\n ecsql += ` FROM main.${instanceChangeInfo.changedInstance.className}.Changes(${instanceChangeInfo.summaryId},${changedValueState}) WHERE ECInstanceId=${instanceChangeInfo.changedInstance.id}`;\r\n return ecsql;\r\n }\r\n\r\n /**\r\n * Creates a change summary for the last applied change set to the iModel\r\n * @param accessToken A valid access token string\r\n * @param iModel iModel to extract change summaries for. The iModel must not be a standalone iModel, and must have at least one change set applied to it.\r\n * @returns The id of the extracted change summary.\r\n * @beta\r\n */\r\n public static async createChangeSummary(accessToken: AccessToken, iModel: BriefcaseDb): Promise<Id64String> {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n const changesetId = iModel.changeset.id;\r\n if (!changesetId)\r\n throw new IModelError(IModelStatus.BadRequest, \"No change set was applied to the iModel\");\r\n if (this.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadRequest, \"Change cache must be detached before extraction\");\r\n\r\n const iModelId = iModel.iModelId;\r\n const changesetsFolder: string = BriefcaseManager.getChangeSetsPath(iModelId);\r\n const changeset = await IModelHost.hubAccess.downloadChangeset({ accessToken, iModelId, changeset: { id: iModel.changeset.id }, targetDir: changesetsFolder });\r\n\r\n if (!IModelJsFs.existsSync(changeset.pathname))\r\n throw new IModelError(IModelStatus.FileNotFound, `Failed to download change set: ${changeset.pathname}`);\r\n\r\n let changesFile: ECDb | undefined;\r\n try {\r\n changesFile = ChangeSummaryManager.openOrCreateChangesFile(iModel);\r\n assert(changesFile.nativeDb !== undefined, \"Invalid changesFile - should've caused an exception\");\r\n\r\n let changeSummaryId = ChangeSummaryManager.isSummaryAlreadyExtracted(changesFile, changesetId);\r\n if (changeSummaryId !== undefined) {\r\n Logger.logInfo(loggerCategory, `Change Summary for changeset already exists. It is not extracted again.`, () => ({ iModelId, changeSetId: changesetId }));\r\n return changeSummaryId;\r\n }\r\n\r\n const stat = iModel.nativeDb.extractChangeSummary(changesFile.nativeDb, changeset.pathname);\r\n if (stat.error && stat.error.status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(stat.error.status, stat.error.message);\r\n\r\n assert(undefined !== stat.result);\r\n changeSummaryId = stat.result;\r\n ChangeSummaryManager.addExtendedInfos(changesFile, changeSummaryId, changesetId, changeset.parentId, changeset.description, changeset.pushDate, changeset.userCreated);\r\n\r\n changesFile.saveChanges();\r\n return changeSummaryId;\r\n } finally {\r\n if (changesFile !== undefined)\r\n changesFile.dispose();\r\n IModelJsFs.unlinkSync(changeset.pathname);\r\n }\r\n }\r\n\r\n /**\r\n * Creates change summaries for the specified iModel and a specified range of versions\r\n * @note This may be an expensive operation - downloads the first version and starts applying the change sets, extracting summaries one by one\r\n * @param args Arguments including the range of versions for which Change Summaries are to be created, and other necessary input for creation\r\n */\r\n public static async createChangeSummaries(args: CreateChangeSummaryArgs): Promise<Id64String[]> {\r\n const accessToken = args.accessToken ?? await IModelHost.getAccessToken() ?? \"\";\r\n const { iModelId, iTwinId, range } = args;\r\n range.end = range.end ?? (await IModelHost.hubAccess.getChangesetFromVersion({ accessToken, iModelId, version: IModelVersion.latest() })).index;\r\n if (range.first > range.end)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid range of changesets\");\r\n if (range.first === 0 && range.end === 0)\r\n return []; // no changesets exist, so the inclusive range is empty\r\n\r\n const changesets = await IModelHost.hubAccess.queryChangesets({ accessToken, iModelId, range });\r\n\r\n // Setup a temporary briefcase to help with extracting change summaries\r\n const briefcasePath = BriefcaseManager.getBriefcaseBasePath(iModelId);\r\n const fileName: string = path.join(briefcasePath, `ChangeSummaryBriefcase.bim`);\r\n if (IModelJsFs.existsSync(fileName))\r\n IModelJsFs.removeSync(fileName);\r\n\r\n let iModel: BriefcaseDb | undefined;\r\n try {\r\n // Download a version that has the first change set applied\r\n const props = await BriefcaseManager.downloadBriefcase({ accessToken, iTwinId, iModelId, asOf: { afterChangeSetId: changesets[0].id }, briefcaseId: 0, fileName });\r\n iModel = await BriefcaseDb.open({ fileName: props.fileName });\r\n\r\n const summaryIds = new Array<Id64String>();\r\n for (let index = 0; index < changesets.length; index++) {\r\n // Apply a change set if necessary\r\n if (index > 0)\r\n await iModel.pullChanges({ accessToken, toIndex: changesets[index].index });\r\n\r\n // Create a change summary for the last change set that was applied\r\n const summaryId = await this.createChangeSummary(accessToken, iModel);\r\n summaryIds.push(summaryId);\r\n }\r\n return summaryIds;\r\n } finally {\r\n if (iModel !== undefined)\r\n iModel.close();\r\n IModelJsFs.removeSync(fileName);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ChangeSummaryManager.js","sourceRoot":"","sources":["../../src/ChangeSummaryManager.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\n/** @packageDocumentation\r\n * @module iModels\r\n */\r\n\r\nimport { AccessToken, assert, DbResult, GuidString, Id64String, IModelStatus, Logger, using } from \"@itwin/core-bentley\";\r\nimport { ChangedValueState, ChangeOpCode, ChangesetRange, IModelError, IModelVersion } from \"@itwin/core-common\";\r\nimport * as path from \"path\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { ECDb, ECDbOpenMode } from \"./ECDb\";\r\nimport { ECSqlStatement } from \"./ECSqlStatement\";\r\nimport { BriefcaseDb, IModelDb, TokenArg } from \"./IModelDb\";\r\nimport { IModelHost, KnownLocations } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Represents an instance of the `ChangeSummary` ECClass from the `ECDbChange` ECSchema\r\n * combined with the information from the related `Changeset` instance (from the `IModelChange` ECSchema) from\r\n * which the Change Summary was extracted.\r\n *\r\n * See also\r\n * - [ChangeSummaryManager.queryChangeSummary]($backend)\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport interface ChangeSummary {\r\n id: Id64String;\r\n changeSet: { wsgId: GuidString, parentWsgId: GuidString, description: string, pushDate: string, userCreated: GuidString };\r\n}\r\n\r\n/** Represents an instance of the `InstanceChange` ECClass from the `ECDbChange` ECSchema\r\n *\r\n * See also\r\n * - [ChangeSummaryManager.queryInstanceChange]($backend)\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport interface InstanceChange {\r\n id: Id64String;\r\n summaryId: Id64String;\r\n changedInstance: { id: Id64String, className: string };\r\n opCode: ChangeOpCode;\r\n isIndirect: boolean;\r\n}\r\n\r\n/** Options for [ChangeSummaryManager.createChangeSummaries]($backend).\r\n * @beta\r\n */\r\nexport interface CreateChangeSummaryArgs extends TokenArg {\r\n /** Id of the iTwin that contains the iModel */\r\n iTwinId: GuidString;\r\n\r\n /** Id of the iModel */\r\n iModelId: GuidString;\r\n\r\n /**\r\n * Range of change sets\r\n * - the Change Summary for the first and last versions are also included\r\n * - if unspecified, all change sets until the latest version are processed\r\n */\r\n range: ChangesetRange;\r\n}\r\n\r\n/** Class to extract Change Summaries for a briefcase.\r\n *\r\n * See also:\r\n * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)\r\n * @beta\r\n */\r\nexport class ChangeSummaryManager {\r\n private static readonly _currentIModelChangeSchemaVersion = { read: 2, write: 0, minor: 0 };\r\n\r\n /** Determines whether the *Change Cache file* is attached to the specified iModel or not\r\n * @param iModel iModel to check whether a *Change Cache file* is attached\r\n * @returns Returns true if the *Change Cache file* is attached to the iModel. false otherwise\r\n */\r\n public static isChangeCacheAttached(iModel: IModelDb): boolean {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n return iModel.nativeDb.isChangeCacheAttached();\r\n }\r\n\r\n /** Attaches the *Change Cache file* to the specified iModel if it hasn't been attached yet.\r\n * A new *Change Cache file* will be created for the iModel if it hasn't existed before.\r\n * @param iModel iModel to attach the *Change Cache file* file to\r\n * @throws [IModelError]($common)\r\n */\r\n public static attachChangeCache(iModel: IModelDb): void {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n if (ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n return;\r\n\r\n const changesCacheFilePath: string = BriefcaseManager.getChangeCachePathName(iModel.iModelId);\r\n if (!IModelJsFs.existsSync(changesCacheFilePath)) {\r\n using(new ECDb(), (changeCacheFile: ECDb) => {\r\n ChangeSummaryManager.createChangeCacheFile(iModel, changeCacheFile, changesCacheFilePath);\r\n });\r\n }\r\n\r\n assert(IModelJsFs.existsSync(changesCacheFilePath));\r\n const res: DbResult = iModel.nativeDb.attachChangeCache(changesCacheFilePath);\r\n if (res !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(res, `Failed to attach Change Cache file to ${iModel.pathName}.`);\r\n }\r\n\r\n /** Detaches the *Change Cache file* from the specified iModel.\r\n * - note that this method will cause any pending (currently running or queued) queries to fail\r\n * @param iModel iModel to detach the *Change Cache file* to\r\n * @throws [IModelError]($common) in case of errors, e.g. if no *Change Cache file* was attached before.\r\n */\r\n public static detachChangeCache(iModel: IModelDb): void {\r\n if (!iModel || !iModel.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n\r\n iModel.clearCaches();\r\n const res: DbResult = iModel.nativeDb.detachChangeCache();\r\n if (res !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(res, `Failed to detach Change Cache file from ${iModel.pathName}.`);\r\n }\r\n\r\n private static openOrCreateChangesFile(iModel: BriefcaseDb): ECDb {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid iModel handle. iModel must be open.\");\r\n\r\n const changesFile = new ECDb();\r\n const changeCacheFilePath = BriefcaseManager.getChangeCachePathName(iModel.iModelId);\r\n if (IModelJsFs.existsSync(changeCacheFilePath)) {\r\n ChangeSummaryManager.openChangeCacheFile(changesFile, changeCacheFilePath);\r\n return changesFile;\r\n }\r\n\r\n try {\r\n ChangeSummaryManager.createChangeCacheFile(iModel, changesFile, changeCacheFilePath);\r\n return changesFile;\r\n } catch (e) {\r\n // delete cache file again in case it was created but schema import failed\r\n if (IModelJsFs.existsSync(changeCacheFilePath))\r\n IModelJsFs.removeSync(changeCacheFilePath);\r\n\r\n throw e;\r\n }\r\n }\r\n\r\n private static createChangeCacheFile(iModel: IModelDb, changesFile: ECDb, changeCacheFilePath: string): void {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid iModel object. iModel must be open.\");\r\n\r\n const stat: DbResult = iModel.nativeDb.createChangeCache(changesFile.nativeDb, changeCacheFilePath);\r\n if (stat !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(stat, `Failed to create Change Cache file at \"${changeCacheFilePath}\".`);\r\n\r\n // Extended information like changeset ids, push dates are persisted in the IModelChange ECSchema\r\n changesFile.importSchema(ChangeSummaryManager.getExtendedSchemaPath());\r\n }\r\n\r\n private static openChangeCacheFile(changesFile: ECDb, changeCacheFilePath: string): void {\r\n changesFile.openDb(changeCacheFilePath, ECDbOpenMode.FileUpgrade);\r\n\r\n const actualSchemaVersion: { read: number, write: number, minor: number } = changesFile.withPreparedStatement(\"SELECT VersionMajor read,VersionWrite write,VersionMinor minor FROM meta.ECSchemaDef WHERE Name='IModelChange'\",\r\n (stmt: ECSqlStatement) => {\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"File is not a valid Change Cache file.\");\r\n\r\n return stmt.getRow();\r\n });\r\n\r\n if (actualSchemaVersion.read === ChangeSummaryManager._currentIModelChangeSchemaVersion.read &&\r\n actualSchemaVersion.write === ChangeSummaryManager._currentIModelChangeSchemaVersion.write &&\r\n actualSchemaVersion.minor === ChangeSummaryManager._currentIModelChangeSchemaVersion.minor)\r\n return;\r\n\r\n changesFile.importSchema(ChangeSummaryManager.getExtendedSchemaPath());\r\n }\r\n\r\n private static getExtendedSchemaPath(): string { return path.join(KnownLocations.packageAssetsDir, \"IModelChange.02.00.00.ecschema.xml\"); }\r\n\r\n private static isSummaryAlreadyExtracted(changesFile: ECDb, changeSetId: GuidString): Id64String | undefined {\r\n return changesFile.withPreparedStatement(\"SELECT Summary.Id summaryid FROM imodelchange.ChangeSet WHERE WsgId=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindString(1, changeSetId);\r\n if (DbResult.BE_SQLITE_ROW === stmt.step())\r\n return stmt.getValue(0).getId();\r\n\r\n return undefined;\r\n });\r\n }\r\n\r\n private static addExtendedInfos(changesFile: ECDb, changeSummaryId: Id64String, changesetWsgId: GuidString, changesetParentWsgId?: GuidString, description?: string, changesetPushDate?: string, changeSetUserCreated?: GuidString): void {\r\n changesFile.withPreparedStatement(\"INSERT INTO imodelchange.ChangeSet(Summary.Id,WsgId,ParentWsgId,Description,PushDate,UserCreated) VALUES(?,?,?,?,?,?)\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, changeSummaryId);\r\n stmt.bindString(2, changesetWsgId);\r\n if (changesetParentWsgId)\r\n stmt.bindString(3, changesetParentWsgId);\r\n\r\n if (description)\r\n stmt.bindString(4, description);\r\n\r\n if (changesetPushDate)\r\n stmt.bindDateTime(5, changesetPushDate);\r\n\r\n if (changeSetUserCreated)\r\n stmt.bindString(6, changeSetUserCreated);\r\n\r\n const r: DbResult = stmt.step();\r\n if (r !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(r, `Failed to add changeset information to extracted change summary ${changeSummaryId}`);\r\n });\r\n }\r\n\r\n /** Queries the ChangeSummary for the specified change summary id\r\n *\r\n * See also\r\n * - `ECDbChange.ChangeSummary` ECClass in the *ECDbChange* ECSchema\r\n * - [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param changeSummaryId ECInstanceId of the ChangeSummary\r\n * @returns Returns the requested ChangeSummary object\r\n * @throws [IModelError]($common) If change summary does not exist for the specified id, or if the\r\n * change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static queryChangeSummary(iModel: BriefcaseDb, changeSummaryId: Id64String): ChangeSummary {\r\n if (!ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadArg, \"Change Cache file must be attached to iModel.\");\r\n\r\n return iModel.withPreparedStatement(\"SELECT WsgId,ParentWsgId,Description,PushDate,UserCreated FROM ecchange.imodelchange.ChangeSet WHERE Summary.Id=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, changeSummaryId);\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(IModelStatus.BadArg, `No ChangeSet information found for ChangeSummary ${changeSummaryId}.`);\r\n\r\n const row = stmt.getRow();\r\n return { id: changeSummaryId, changeSet: { wsgId: row.wsgId, parentWsgId: row.parentWsgId, description: row.description, pushDate: row.pushDate, userCreated: row.userCreated } };\r\n });\r\n }\r\n\r\n /** Queries the InstanceChange for the specified instance change id.\r\n *\r\n * See also\r\n * - `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema\r\n * - [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeId ECInstanceId of the InstanceChange (see `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema)\r\n * @returns Returns the requested InstanceChange object (see `ECDbChange.InstanceChange` ECClass in the *ECDbChange* ECSchema)\r\n * @throws [IModelError]($common) if instance change does not exist for the specified id, or if the\r\n * change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static queryInstanceChange(iModel: BriefcaseDb, instanceChangeId: Id64String): InstanceChange {\r\n if (!ChangeSummaryManager.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadArg, \"Change Cache file must be attached to iModel.\");\r\n\r\n // query instance changes\r\n const instanceChange: InstanceChange = iModel.withPreparedStatement(`SELECT ic.Summary.Id summaryId, s.Name changedInstanceSchemaName, c.Name changedInstanceClassName, ic.ChangedInstance.Id changedInstanceId,\r\n ic.OpCode, ic.IsIndirect FROM ecchange.change.InstanceChange ic JOIN main.meta.ECClassDef c ON c.ECInstanceId = ic.ChangedInstance.ClassId\r\n JOIN main.meta.ECSchemaDef s ON c.Schema.Id = s.ECInstanceId WHERE ic.ECInstanceId =? `, (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, instanceChangeId);\r\n if (stmt.step() !== DbResult.BE_SQLITE_ROW)\r\n throw new IModelError(IModelStatus.BadArg, `No InstanceChange found for id ${instanceChangeId}.`);\r\n\r\n const row = stmt.getRow();\r\n const changedInstanceId: Id64String = row.changedInstanceId;\r\n const changedInstanceClassName: string = `[${row.changedInstanceSchemaName}].[${row.changedInstanceClassName}]`;\r\n const op: ChangeOpCode = row.opCode as ChangeOpCode;\r\n\r\n return {\r\n id: instanceChangeId, summaryId: row.summaryId, changedInstance: { id: changedInstanceId, className: changedInstanceClassName },\r\n opCode: op, isIndirect: row.isIndirect,\r\n };\r\n });\r\n\r\n return instanceChange;\r\n }\r\n\r\n /** Retrieves the names of the properties whose values have changed for the given instance change\r\n *\r\n * See also [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeId Id of the InstanceChange to query the properties whose values have changed\r\n * @returns Returns names of the properties whose values have changed for the given instance change\r\n * @throws [IModelError]($common) if the change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static getChangedPropertyValueNames(iModel: IModelDb, instanceChangeId: Id64String): string[] {\r\n return iModel.withPreparedStatement(\"SELECT AccessString FROM ecchange.change.PropertyValueChange WHERE InstanceChange.Id=?\",\r\n (stmt: ECSqlStatement) => {\r\n stmt.bindId(1, instanceChangeId);\r\n\r\n const selectClauseItems: string[] = [];\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n // access string tokens need to be escaped as they might collide with reserved words in ECSQL or SQLite\r\n const accessString: string = stmt.getValue(0).getString();\r\n const accessStringTokens: string[] = accessString.split(\".\");\r\n assert(accessStringTokens.length > 0);\r\n\r\n let isFirstToken: boolean = true;\r\n let item: string = \"\";\r\n for (const token of accessStringTokens) {\r\n if (!isFirstToken)\r\n item += \".\";\r\n\r\n item += `[${token}]`;\r\n isFirstToken = false;\r\n }\r\n selectClauseItems.push(item);\r\n }\r\n\r\n return selectClauseItems;\r\n });\r\n }\r\n\r\n /** Builds the ECSQL to query the property value changes for the specified instance change and the specified ChangedValueState.\r\n *\r\n * See also [Change Summary Overview]($docs/learning/ChangeSummaries)\r\n * @param iModel iModel\r\n * @param instanceChangeInfo InstanceChange to query the property value changes for\r\n * changedInstance.className must be fully qualified and schema and class name must be escaped with square brackets if they collide with reserved ECSQL words: `[schema name].[class name]`\r\n * @param changedValueState The Changed State to query the values for. This must correspond to the [InstanceChange.OpCode]($backend) of the InstanceChange.\r\n * @param changedPropertyNames List of the property names for which values have changed for the specified instance change.\r\n * The list can be obtained by calling [ChangeSummaryManager.getChangedPropertyValueNames]($core-backend).\r\n * If omitted, the method will call the above method by itself. The parameter allows for checking first whether\r\n * an instance change has any property value changes at all. If there are no property value changes, this method\r\n * should not be called, as it will throw an error.\r\n * @returns Returns the ECSQL that will retrieve the property value changes\r\n * @throws [IModelError]($common) if instance change does not exist, if there are not property value changes for the instance change,\r\n * if the change cache file hasn't been attached, or in case of other errors.\r\n */\r\n public static buildPropertyValueChangesECSql(iModel: IModelDb, instanceChangeInfo: { id: Id64String, summaryId: Id64String, changedInstance: { id: Id64String, className: string } }, changedValueState: ChangedValueState, changedPropertyNames?: string[]): string {\r\n let selectClauseItems: string[];\r\n if (!changedPropertyNames) {\r\n // query property value changes just to build a SELECT statement against the class of the changed instance\r\n selectClauseItems = ChangeSummaryManager.getChangedPropertyValueNames(iModel, instanceChangeInfo.id);\r\n } else\r\n selectClauseItems = changedPropertyNames;\r\n\r\n if (selectClauseItems.length === 0)\r\n throw new IModelError(IModelStatus.BadArg, `No property value changes found for InstanceChange ${instanceChangeInfo.id}.`);\r\n\r\n let ecsql: string = \"SELECT \";\r\n selectClauseItems.map((item: string, index: number) => {\r\n if (index !== 0)\r\n ecsql += \",\";\r\n\r\n ecsql += item;\r\n });\r\n\r\n // Avoiding parameters in the Changes function speeds up performance because ECDb can do optimizations\r\n // if it knows the function args at prepare time\r\n ecsql += ` FROM main.${instanceChangeInfo.changedInstance.className}.Changes(${instanceChangeInfo.summaryId},${changedValueState}) WHERE ECInstanceId=${instanceChangeInfo.changedInstance.id}`;\r\n return ecsql;\r\n }\r\n\r\n /**\r\n * Creates a change summary for the last applied change set to the iModel\r\n * @param accessToken A valid access token string\r\n * @param iModel iModel to extract change summaries for. The iModel must not be a standalone iModel, and must have at least one change set applied to it.\r\n * @returns The id of the extracted change summary.\r\n * @beta\r\n */\r\n public static async createChangeSummary(accessToken: AccessToken, iModel: BriefcaseDb): Promise<Id64String> {\r\n if (!iModel?.isOpen)\r\n throw new IModelError(IModelStatus.BadRequest, \"Briefcase must be open\");\r\n const changesetId = iModel.changeset.id;\r\n if (!changesetId)\r\n throw new IModelError(IModelStatus.BadRequest, \"No change set was applied to the iModel\");\r\n if (this.isChangeCacheAttached(iModel))\r\n throw new IModelError(IModelStatus.BadRequest, \"Change cache must be detached before extraction\");\r\n\r\n const iModelId = iModel.iModelId;\r\n const changesetsFolder: string = BriefcaseManager.getChangeSetsPath(iModelId);\r\n const changeset = await IModelHost.hubAccess.downloadChangeset({ accessToken, iModelId, changeset: { id: iModel.changeset.id }, targetDir: changesetsFolder });\r\n\r\n if (!IModelJsFs.existsSync(changeset.pathname))\r\n throw new IModelError(IModelStatus.FileNotFound, `Failed to download change set: ${changeset.pathname}`);\r\n\r\n let changesFile: ECDb | undefined;\r\n try {\r\n changesFile = ChangeSummaryManager.openOrCreateChangesFile(iModel);\r\n assert(changesFile.nativeDb !== undefined, \"Invalid changesFile - should've caused an exception\");\r\n\r\n let changeSummaryId = ChangeSummaryManager.isSummaryAlreadyExtracted(changesFile, changesetId);\r\n if (changeSummaryId !== undefined) {\r\n Logger.logInfo(loggerCategory, `Change Summary for changeset already exists. It is not extracted again.`, () => ({ iModelId, changeSetId: changesetId }));\r\n return changeSummaryId;\r\n }\r\n\r\n const stat = iModel.nativeDb.extractChangeSummary(changesFile.nativeDb, changeset.pathname);\r\n if (stat.error && stat.error.status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(stat.error.status, stat.error.message);\r\n\r\n assert(undefined !== stat.result);\r\n changeSummaryId = stat.result;\r\n ChangeSummaryManager.addExtendedInfos(changesFile, changeSummaryId, changesetId, changeset.parentId, changeset.description, changeset.pushDate, changeset.userCreated);\r\n\r\n changesFile.saveChanges();\r\n return changeSummaryId;\r\n } finally {\r\n if (changesFile !== undefined)\r\n changesFile.dispose();\r\n IModelJsFs.unlinkSync(changeset.pathname);\r\n }\r\n }\r\n\r\n /**\r\n * Creates change summaries for the specified iModel and a specified range of versions\r\n * @note This may be an expensive operation - downloads the first version and starts applying the change sets, extracting summaries one by one\r\n * @param args Arguments including the range of versions for which Change Summaries are to be created, and other necessary input for creation\r\n */\r\n public static async createChangeSummaries(args: CreateChangeSummaryArgs): Promise<Id64String[]> {\r\n const accessToken = args.accessToken ?? await IModelHost.getAccessToken() ?? \"\";\r\n const { iModelId, iTwinId, range } = args;\r\n range.end = range.end ?? (await IModelHost.hubAccess.getChangesetFromVersion({ accessToken, iModelId, version: IModelVersion.latest() })).index;\r\n if (range.first > range.end)\r\n throw new IModelError(IModelStatus.BadArg, \"Invalid range of changesets\");\r\n if (range.first === 0 && range.end === 0)\r\n return []; // no changesets exist, so the inclusive range is empty\r\n\r\n const changesets = await IModelHost.hubAccess.queryChangesets({ accessToken, iModelId, range });\r\n\r\n // Setup a temporary briefcase to help with extracting change summaries\r\n const briefcasePath = BriefcaseManager.getBriefcaseBasePath(iModelId);\r\n const fileName: string = path.join(briefcasePath, `ChangeSummaryBriefcase.bim`);\r\n if (IModelJsFs.existsSync(fileName))\r\n IModelJsFs.removeSync(fileName);\r\n\r\n let iModel: BriefcaseDb | undefined;\r\n try {\r\n // Download a version that has the first change set applied\r\n const props = await BriefcaseManager.downloadBriefcase({ accessToken, iTwinId, iModelId, asOf: { afterChangeSetId: changesets[0].id }, briefcaseId: 0, fileName });\r\n iModel = await BriefcaseDb.open({ fileName: props.fileName });\r\n\r\n const summaryIds = new Array<Id64String>();\r\n for (let index = 0; index < changesets.length; index++) {\r\n // Apply a change set if necessary\r\n if (index > 0)\r\n await iModel.pullChanges({ accessToken, toIndex: changesets[index].index });\r\n\r\n // Create a change summary for the last change set that was applied\r\n const summaryId = await this.createChangeSummary(accessToken, iModel);\r\n summaryIds.push(summaryId);\r\n }\r\n return summaryIds;\r\n } finally {\r\n if (iModel !== undefined)\r\n iModel.close();\r\n IModelJsFs.removeSync(fileName);\r\n }\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ChangedElementsManager.js","sourceRoot":"","sources":["../../src/ChangedElementsManager.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 { GuidString } from \"@itwin/core-bentley\";\r\nimport { ChangeData, ChangedElements, ChangedModels } from \"@itwin/core-common\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { ChangedElementsDb } from \"./ChangedElementsDb\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\n\r\n/** @internal */\r\ninterface ChangedElementsDbCacheEntry {\r\n iModelId: GuidString;\r\n db: ChangedElementsDb;\r\n}\r\n\r\n/** Utilities for querying changed elements caches */\r\n/** @internal */\r\nexport class ChangedElementsManager {\r\n /** Maintains a single entry since we will only have a cache per iModel, which means a ChangedElementsDb per backend instance */\r\n private static _entry: ChangedElementsDbCacheEntry | undefined;\r\n\r\n public static getChangedElementsPathName(iModelId: GuidString): string { return BriefcaseManager.getChangedElementsPathName(iModelId); }\r\n\r\n /** Get changed elements Db */\r\n private static getChangedElementsDb(iModelId: GuidString): ChangedElementsDb | undefined {\r\n if (this._entry && this._entry.iModelId === iModelId)\r\n return this._entry.db;\r\n if (this._entry && this._entry.iModelId !== iModelId) {\r\n this._entry.db.closeDb();\r\n this._entry.db.cleanCaches();\r\n this._entry = undefined;\r\n }\r\n if (!this._entry) {\r\n const path = ChangedElementsManager.getChangedElementsPathName(iModelId);\r\n if (!IModelJsFs.existsSync(path))\r\n return undefined;\r\n\r\n const db: ChangedElementsDb = ChangedElementsDb.openDb(path);\r\n this._entry = {\r\n iModelId,\r\n db,\r\n };\r\n\r\n return db;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public static cleanUp() {\r\n if (this._entry) {\r\n this._entry.db.closeDb();\r\n this._entry.db.cleanCaches();\r\n this._entry = undefined;\r\n }\r\n }\r\n\r\n /** Gets the changed elements from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed elements if found\r\n */\r\n public static getChangedElements(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangedElements | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangedElements(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Gets the changed models from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed models if found\r\n */\r\n public static getChangedModels(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangedModels | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangedModels(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Gets the change data (models and elements) from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed models if found\r\n */\r\n public static getChangeData(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangeData | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangeData(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Checks if the cache contains information about the changeset\r\n * @param iModelId Id of the iModel\r\n * @param changesetId Changeset to check for\r\n * @returns true if the changeset has been processed and exists in the cache\r\n */\r\n public static isProcessed(iModelId: GuidString, changesetId: string): boolean {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return false;\r\n\r\n return db.isProcessed(changesetId);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ChangedElementsManager.js","sourceRoot":"","sources":["../../src/ChangedElementsManager.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 { GuidString } from \"@itwin/core-bentley\";\r\nimport { ChangeData, ChangedElements, ChangedModels } from \"@itwin/core-common\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { ChangedElementsDb } from \"./ChangedElementsDb\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\n\r\n/** @internal */\r\ninterface ChangedElementsDbCacheEntry {\r\n iModelId: GuidString;\r\n db: ChangedElementsDb;\r\n}\r\n\r\n/** Utilities for querying changed elements caches */\r\n/** @internal */\r\nexport class ChangedElementsManager {\r\n /** Maintains a single entry since we will only have a cache per iModel, which means a ChangedElementsDb per backend instance */\r\n private static _entry: ChangedElementsDbCacheEntry | undefined;\r\n\r\n public static getChangedElementsPathName(iModelId: GuidString): string { return BriefcaseManager.getChangedElementsPathName(iModelId); }\r\n\r\n /** Get changed elements Db */\r\n private static getChangedElementsDb(iModelId: GuidString): ChangedElementsDb | undefined {\r\n if (this._entry && this._entry.iModelId === iModelId)\r\n return this._entry.db;\r\n if (this._entry && this._entry.iModelId !== iModelId) {\r\n this._entry.db.closeDb();\r\n this._entry.db.cleanCaches();\r\n this._entry = undefined;\r\n }\r\n if (!this._entry) {\r\n const path = ChangedElementsManager.getChangedElementsPathName(iModelId);\r\n if (!IModelJsFs.existsSync(path))\r\n return undefined;\r\n\r\n const db: ChangedElementsDb = ChangedElementsDb.openDb(path);\r\n this._entry = {\r\n iModelId,\r\n db,\r\n };\r\n\r\n return db;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public static cleanUp() {\r\n if (this._entry) {\r\n this._entry.db.closeDb();\r\n this._entry.db.cleanCaches();\r\n this._entry = undefined;\r\n }\r\n }\r\n\r\n /** Gets the changed elements from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed elements if found\r\n */\r\n public static getChangedElements(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangedElements | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangedElements(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Gets the changed models from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed models if found\r\n */\r\n public static getChangedModels(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangedModels | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangedModels(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Gets the change data (models and elements) from the cache if found\r\n * @param iModelId Id of the iModel\r\n * @param startChangesetId Start changeset Id\r\n * @param endChangesetId End changeset Id\r\n * @returns Changed models if found\r\n */\r\n public static getChangeData(iModelId: GuidString, startChangesetId: string, endChangesetId: string): ChangeData | undefined {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return undefined;\r\n\r\n return db.getChangeData(startChangesetId, endChangesetId);\r\n }\r\n\r\n /** Checks if the cache contains information about the changeset\r\n * @param iModelId Id of the iModel\r\n * @param changesetId Changeset to check for\r\n * @returns true if the changeset has been processed and exists in the cache\r\n */\r\n public static isProcessed(iModelId: GuidString, changesetId: string): boolean {\r\n const db: ChangedElementsDb | undefined = ChangedElementsManager.getChangedElementsDb(iModelId);\r\n if (!db)\r\n return false;\r\n\r\n return db.isProcessed(changesetId);\r\n }\r\n}\r\n"]}
@@ -528,8 +528,8 @@ class ChangesetECAdaptor {
528
528
  * set debug flags
529
529
  */
530
530
  this.debugFlags = {
531
- replaceBlobWithEllipsis: false,
532
- replaceGeomWithEllipsis: false,
531
+ replaceBlobWithEllipsis: false, // replace bolb with ... for debugging
532
+ replaceGeomWithEllipsis: false, // replace geom with ... for debugging
533
533
  replaceGuidWithEllipsis: false, // replace geom with ... for debugging
534
534
  };
535
535
  if (!reader.db)
@@ -1 +1 @@
1
- {"version":3,"file":"ChangesetECAdaptor.js","sourceRoot":"","sources":["../../src/ChangesetECAdaptor.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\n/** @packageDocumentation\r\n * @module ECDb\r\n */\r\nimport { DbResult, GuidString, Id64String, IDisposable } from \"@itwin/core-bentley\";\r\nimport { AnyDb, SqliteChange, SqliteChangeOp, SqliteChangesetReader, SqliteValueStage } from \"./SqliteChangesetReader\";\r\n\r\ninterface IClassRef {\r\n classId: Id64String;\r\n classFullName: string;\r\n}\r\n\r\ninterface IClassMap {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly mapStrategy: \"NotMapped\" | \"OwnTable\" | \"TablePerHierarchy\" | \"ExistingTable\" | \"ForeignKeyInTargetTable\" | \"ForeignKeyInSourceTable\";\r\n readonly type: \"Entity\" | \"Relationship\" | \"Struct\" | \"CustomAttribute\";\r\n readonly modifier: \"None\" | \"Abstract\" | \"Sealed\";\r\n readonly properties: IProperty[];\r\n}\r\n\r\ninterface IDateTimeInfo {\r\n readonly dateTimeKind?: \"Utc\" | \"Local\" | \"Unspecified\";\r\n readonly dateTimeComponent?: \"DateTime\" | \"Date\" | \"TimeOfDay\";\r\n}\r\n\r\ninterface IProperty {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly kind: \"Primitive\" | \"Struct\" | \"PrimitiveArray\" | \"StructArray\" | \"Navigation\";\r\n readonly primitiveType?: \"Binary\" | \"Boolean\" | \"DateTime\" | \"Double\" | \"Integer\" | \"Long\" | \"Point2d\" | \"Point3d\" | \"String\" | \"IGeometry\";\r\n readonly extendedTypeName?: string;\r\n readonly navigationRelationship?: IClassRef;\r\n readonly structClass?: IClassRef;\r\n readonly dateTimeInfo?: IDateTimeInfo;\r\n readonly columns: IColumn[];\r\n\r\n}\r\n\r\ninterface IColumn {\r\n readonly table: string;\r\n readonly column: string;\r\n readonly type: \"Any\" | \"Boolean\" | \"Blob\" | \"Timestamp\" | \"Real\" | \"Integer\" | \"Text\";\r\n readonly columnKind: \"Default\" | \"Id\" | \"ClassId\" | \"Shared\";\r\n readonly accessString: string;\r\n readonly isVirtual: boolean;\r\n}\r\n\r\ninterface ITable {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly type: \"Primary\" | \"Joined\" | \"Existing\" | \"Overflow\" | \"Virtual\";\r\n readonly exclusiveRootClassId: Id64String;\r\n readonly isClassIdVirtual: boolean;\r\n}\r\n\r\nclass ECDbMap {\r\n private _cachedClassMaps = new Map<Id64String, IClassMap>();\r\n private _cacheTables = new Map<string, ITable>();\r\n public constructor(public readonly db: AnyDb) { }\r\n public getAllDerivedClasses(classFullName: string) {\r\n const sql = `\r\n SELECT format('0x%x', ch.ClassId)\r\n FROM [ec_cache_ClassHierarchy] [ch]\r\n JOIN [ec_Class] [cs] ON [cs].[Id] = [ch].[BaseClassId]\r\n JOIN [ec_Schema] [sc] ON [sc].[Id] = [cs].[SchemaId]\r\n WHERE (([sc].[Alias] = :schemaNameOrAlias\r\n OR [sc].[Name] = :schemaNameOrAlias)\r\n AND ([cs].[Name] = :className))\r\n `;\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n const parts = classFullName.indexOf(\".\") !== -1 ? classFullName.split(\".\") : classFullName.split(\":\");\r\n stmt.bindString(\":schemaNameOrAlias\", parts[0]);\r\n stmt.bindString(\":className\", parts[1]);\r\n const classIds = [];\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n classIds.push(stmt.getValueString(0));\r\n return classIds;\r\n });\r\n }\r\n public getTable(tableName: string): ITable | undefined {\r\n if (this._cacheTables.has(tableName))\r\n return this._cacheTables.get(tableName);\r\n\r\n const sql = `\r\n SELECT\r\n JSON_OBJECT (\r\n 'id', FORMAT ('0x%x', [t].[id]),\r\n 'name', [t].[Name],\r\n 'type', (\r\n CASE\r\n [t].[type]\r\n WHEN 0 THEN 'Primary'\r\n WHEN 1 THEN 'Joined'\r\n WHEN 2 THEN 'Existing'\r\n WHEN 3 THEN 'Overflow'\r\n WHEN 4 THEN 'Virtual'\r\n END\r\n ),\r\n 'exclusiveRootClassId', FORMAT ('0x%x', [t].[ExclusiveRootClassId]),\r\n 'isClassIdVirtual', (\r\n SELECT\r\n [c].[IsVirtual]\r\n FROM\r\n [ec_Column] [c]\r\n WHERE\r\n [c].[Name] = 'ECClassId' AND [c].[TableId] = [t].[Id]\r\n )\r\n )\r\n FROM [ec_Table] [t]\r\n WHERE\r\n [t].[Name] = ?;\r\n `;\r\n\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n stmt.bindString(1, tableName);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const table = JSON.parse(stmt.getValueString(0), (key, value) => {\r\n if (value === null)\r\n return undefined;\r\n\r\n if (key === \"isClassIdVirtual\")\r\n return value === 0 ? false : true;\r\n\r\n return value;\r\n }) as ITable;\r\n\r\n this._cacheTables.set(tableName, table);\r\n return table;\r\n }\r\n return undefined;\r\n });\r\n }\r\n public getClassMap(classId: Id64String): IClassMap | undefined {\r\n if (this._cachedClassMaps.has(classId))\r\n return this._cachedClassMaps.get(classId);\r\n\r\n const sql = `\r\n SELECT\r\n JSON_OBJECT(\r\n 'id', format('0x%x', cs.id),\r\n 'name', format('%s:%s', ss.Name, cs.Name),\r\n 'mapStrategy',\r\n (\r\n CASE cm.MapStrategy\r\n WHEN 0 THEN 'NotMapped'\r\n WHEN 1 THEN 'OwnTable'\r\n WHEN 2 THEN 'TablePerHierarchy'\r\n WHEN 3 THEN 'ExistingTable'\r\n WHEN 10 THEN 'ForeignKeyInTargetTable'\r\n WHEN 11 THEN 'ForeignKeyInSourceTable'\r\n END\r\n ),\r\n 'type',\r\n (\r\n CASE cs.Type\r\n WHEN 0 THEN 'Entity'\r\n WHEN 1 THEN 'Relationship'\r\n WHEN 2 THEN 'Struct'\r\n WHEN 3 THEN 'CustomAttribute'\r\n END\r\n ),\r\n 'modifier',\r\n (\r\n CASE cs.Modifier\r\n WHEN 0 THEN 'None'\r\n WHEN 1 THEN 'Abstract'\r\n WHEN 2 THEN 'Sealed'\r\n END\r\n ),\r\n 'properties',\r\n (\r\n SELECT\r\n JSON_GROUP_ARRAY(JSON(propJson))\r\n FROM\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'id', format('0x%x', pt.id),\r\n 'name', pt.Name,\r\n 'kind',\r\n (\r\n CASE pt.Kind\r\n WHEN 0 THEN 'Primitive'\r\n WHEN 1 THEN 'Struct'\r\n WHEN 2 THEN 'PrimitiveArray'\r\n WHEN 3 THEN 'StructArray'\r\n WHEN 4 THEN 'Navigation'\r\n END\r\n ),\r\n 'primitiveType',\r\n (\r\n CASE pt.PrimitiveType\r\n WHEN 0x101 THEN 'Binary'\r\n WHEN 0x201 THEN 'Boolean'\r\n WHEN 0x301 THEN 'DateTime'\r\n WHEN 0x401 THEN 'Double'\r\n WHEN 0x501 THEN 'Integer'\r\n WHEN 0x601 THEN 'Long'\r\n WHEN 0x701 THEN 'Point2d'\r\n WHEN 0x801 THEN 'Point3d'\r\n WHEN 0x901 THEN 'String'\r\n WHEN 0xa01 THEN 'IGeometry'\r\n END\r\n ),\r\n 'extendedTypeName', ExtendedTypeName,\r\n 'navigationRelationship',\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'classId', format('0x%x', nc.Id),\r\n 'classFullName', format('%s:%s', ns.Name, nc.Name)\r\n )\r\n FROM ec_Class nc\r\n JOIN ec_Schema ns ON ns.Id = nc.SchemaId\r\n WHERE\r\n nc.Id = pt.NavigationRelationshipClassId\r\n ),\r\n 'structClass',\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'classId', format('0x%x', nc.Id),\r\n 'classFullName', format('%s:%s', ns.Name, nc.Name)\r\n )\r\n FROM ec_Class nc\r\n JOIN ec_Schema ns ON ns.Id = nc.SchemaId\r\n WHERE\r\n nc.Id = pt.StructClassId\r\n ),\r\n 'dateTimeInfo', (\r\n SELECT\r\n JSON_OBJECT (\r\n 'dateTimeKind', (\r\n CASE\r\n WHEN [ca].[Instance] LIKE '%<DateTimeKind>Utc</DateTimeKind>%' COLLATE [NoCase] THEN 'Utc'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeKind>Local</DateTimeKind>%' COLLATE [NoCase] THEN 'Local'\r\n ELSE 'Unspecified'\r\n END\r\n ),\r\n 'dateTimeComponent', (\r\n CASE\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>DateTime</DateTimeComponent>%' COLLATE [NoCase] THEN 'DateTime'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>Date</DateTimeComponent>%' COLLATE [NoCase] THEN 'Date'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>TimeOfDay</DateTimeComponent>%' COLLATE [NoCase] THEN 'TimeOfDay'\r\n ELSE 'DateTime'\r\n END\r\n )\r\n )\r\n FROM\r\n [ec_CustomAttribute] [ca]\r\n JOIN [ec_Class] [cl] ON [cl].[Id] = [ca].[ClassId]\r\n JOIN [ec_Schema] [sc] ON [sc].[Id] = [cl].[SchemaId]\r\n WHERE\r\n [ca].[ContainerType] = 992\r\n AND [cl].[Name] = 'DateTimeInfo'\r\n AND [sc].[Name] = 'CoreCustomAttributes'\r\n AND [ca].[ContainerId] = [pt].[Id]\r\n ),\r\n 'columns',\r\n (\r\n SELECT\r\n JSON_GROUP_ARRAY(JSON(columnJson))\r\n FROM\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'table', tb.Name,\r\n 'column', cc.Name,\r\n 'type',\r\n (\r\n CASE cc.Type\r\n WHEN 0 THEN 'Any'\r\n WHEN 1 THEN 'Boolean'\r\n WHEN 2 THEN 'Blob'\r\n WHEN 3 THEN 'Timestamp'\r\n WHEN 4 THEN 'Real'\r\n WHEN 5 THEN 'Integer'\r\n WHEN 6 THEN 'Text'\r\n END\r\n ),\r\n 'columnKind',\r\n (\r\n CASE cc.ColumnKind\r\n WHEN 0 THEN 'Default'\r\n WHEN 1 THEN 'Id'\r\n WHEN 2 THEN 'ClassId'\r\n WHEN 4 THEN 'SharedData'\r\n END\r\n ),\r\n 'accessString', pp0.AccessString,\r\n 'isVirtual', cc.IsVirtual OR tb.Type = 4\r\n ) columnJson\r\n FROM [ec_PropertyMap] [pm0]\r\n JOIN [ec_Column] [cc] ON [cc].[Id] = [pm0].[ColumnId]\r\n JOIN [ec_Table] [tb] ON [tb].[Id] = [cc].[TableId]\r\n JOIN [ec_PropertyPath] [pp0] ON [pp0].[Id] = [pm0].[PropertyPathId]\r\n WHERE\r\n [pp0].[RootPropertyId] = pt.Id AND pm0.ClassId = cs.Id\r\n )\r\n )\r\n ) propJson\r\n FROM [ec_PropertyMap] [pm]\r\n JOIN [ec_PropertyPath] [pp] ON [pp].[Id] = [pm].[PropertyPathId]\r\n JOIN [ec_Property] [pt] ON [pt].[Id] = [pp].[RootPropertyId]\r\n WHERE\r\n pm.ClassId = cs.Id\r\n GROUP BY\r\n pt.Id\r\n )\r\n )\r\n ) classDef\r\n FROM [ec_Class] [cs]\r\n JOIN [ec_ClassMap] [cm] ON [cm].[ClassId] = [cs].[Id]\r\n JOIN [ec_Schema] [ss] ON [ss].[Id] = [cs].[SchemaId]\r\n WHERE\r\n [cs].[Id] = ?\r\n `;\r\n\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n stmt.bindId(1, classId);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const classMap = JSON.parse(stmt.getValueString(0), (key, value) => {\r\n if (value === null) {\r\n return undefined;\r\n }\r\n if (key === \"isVirtual\") {\r\n return value === 0 ? false : true;\r\n }\r\n return value;\r\n }) as IClassMap;\r\n\r\n this._cachedClassMaps.set(classId, classMap);\r\n return classMap;\r\n }\r\n return undefined;\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Record meta data for the change.\r\n * @beta\r\n * */\r\nexport interface ChangeMetaData {\r\n /** list of tables making up this EC change */\r\n tables: string[];\r\n /** full name of the class of this EC change */\r\n classFullName?: string;\r\n /** sqlite operation that caused the change */\r\n op: SqliteChangeOp;\r\n /** version of the value read from sqlite change */\r\n stage: SqliteValueStage;\r\n /** if classId for the change was not found in db then fallback class for the table */\r\n fallbackClassId?: Id64String;\r\n /** list of change index making up this change (one per table) */\r\n changeIndexes: number[];\r\n}\r\n\r\n/**\r\n * Represent EC change derived from low level sqlite change\r\n * @beta\r\n */\r\nexport interface ChangedECInstance {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ECInstanceId: Id64String;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ECClassId?: Id64String;\r\n $meta?: ChangeMetaData;\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Helper function to convert between JS DateTime & SQLite JulianDay values.\r\n * @beta\r\n * */\r\nnamespace DateTime {\r\n /**\r\n * Convert JS date to JulianDay value.\r\n * @param dt JS Date object.\r\n * @param convertToUtc convert the input value to UTC.\r\n * @returns julian day value\r\n */\r\n export function toJulianDay(dt: Date, convertToUtc = true): number {\r\n const utcOffset = convertToUtc ? dt.getTimezoneOffset() / 1440 : 0;\r\n return (dt.valueOf() / 86400000) - utcOffset + 2440587.5;\r\n }\r\n /**\r\n * Convert Julian day to JS Date object\r\n * @param jd JulianDay value for date/time\r\n * @param isLocalTime if julian day is local time or UTC\r\n * @returns JS Date object.\r\n */\r\n export function fromJulianDay(jd: number, isLocalTime: boolean): Date {\r\n const utcOffset = isLocalTime ? 0 : new Date().getTimezoneOffset() / 1440;\r\n return new Date((jd - 2440587.5 + utcOffset) * 86400000);\r\n }\r\n}\r\n/**\r\n * Combine partial changed instance into single instance.\r\n * Partial changes is per table and a single instance can\r\n * span multiple tables.\r\n * @beta\r\n */\r\nexport class PartialECChangeUnifier {\r\n private _cache = new Map<string, ChangedECInstance>();\r\n private _readonly = false;\r\n /**\r\n * Get root class id for a given class\r\n * @param classId given class id\r\n * @param db use to find root class\r\n * @returns return root class id\r\n */\r\n private static getRootClassId(classId: Id64String, db: AnyDb): Id64String | undefined {\r\n const sql = `\r\n WITH\r\n [base_class]([classId], [baseClassId], [Level]) AS(\r\n SELECT [ch].[ClassId], [ch].[BaseClassId], 0\r\n FROM [ec_ClassHasBaseClasses] [ch] WHERE [ch].[ClassId] = ?\r\n UNION ALL\r\n SELECT [ch].[ClassId], [ch].[BaseClassId], [Level] + 1\r\n FROM [ec_ClassHasBaseClasses] [ch], [base_class] [bc] WHERE [bc].[BaseClassId] = [ch].[ClassId]\r\n\r\n )\r\n SELECT FORMAT('0x%x', [bc].[BaseClassId]) rootClass\r\n FROM [base_class] [bc]\r\n WHERE [bc].[ClassId] <> [bc].[BaseClassId]\r\n AND [bc].[BaseClassId] NOT IN (SELECT [ca].[ContainerId]\r\n FROM [ec_CustomAttribute] [ca]\r\n WHERE [ca].[ContainerType] = 30\r\n AND [ca].[ClassId] IN (SELECT [cc].[Id]\r\n FROM [ec_Class] [cc]\r\n JOIN [ec_Schema] [ss] ON [ss].[Id] = [cc].[SchemaId]\r\n WHERE [cc].[Name] = 'IsMixIn'\r\n AND [ss].[Name] = 'CoreCustomAttributes'))\r\n ORDER BY [Level] DESC`;\r\n\r\n return db.withSqliteStatement(sql, (stmt) => {\r\n stmt.bindId(1, classId);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW && !stmt.isValueNull(0)) {\r\n return stmt.getValueString(0);\r\n }\r\n return classId;\r\n });\r\n }\r\n /**\r\n * Combine partial instance with instance with same key if already exists.\r\n * @param rhs partial instance\r\n */\r\n private combine(rhs: ChangedECInstance, db?: AnyDb): void {\r\n if (!rhs.$meta) {\r\n throw new Error(\"PartialECChange being combine must have '$meta' property\");\r\n }\r\n const key = PartialECChangeUnifier.buildKey(rhs, db);\r\n const lhs = this._cache.get(key);\r\n if (lhs) {\r\n const { $meta: _, ...restOfRhs } = rhs;\r\n Object.assign(lhs, restOfRhs);\r\n if (lhs.$meta && rhs.$meta) {\r\n lhs.$meta.tables = [...rhs.$meta?.tables, ...lhs.$meta?.tables];\r\n lhs.$meta.changeIndexes = [...rhs.$meta?.changeIndexes, ...lhs.$meta?.changeIndexes];\r\n\r\n // we preserve child class name & id when merging instance.\r\n if (rhs.$meta.fallbackClassId && lhs.$meta.fallbackClassId && db && rhs.$meta.fallbackClassId !== lhs.$meta.fallbackClassId) {\r\n const lhsClassId = lhs.$meta.fallbackClassId;\r\n const rhsClassId = rhs.$meta.fallbackClassId;\r\n const isRhsIsSubClassOfLhs = db.withPreparedStatement(\"SELECT ec_instanceof(?,?)\", (stmt) => {\r\n stmt.bindId(1, rhsClassId);\r\n stmt.bindId(2, lhsClassId);\r\n stmt.step();\r\n return stmt.getValue(0).getInteger() === 1;\r\n });\r\n if (isRhsIsSubClassOfLhs) {\r\n lhs.$meta.fallbackClassId = rhs.$meta.fallbackClassId;\r\n lhs.$meta.classFullName = rhs.$meta.classFullName;\r\n }\r\n }\r\n }\r\n } else {\r\n this._cache.set(key, rhs);\r\n }\r\n }\r\n /**\r\n * Build key from EC change.\r\n * @param change EC change\r\n * @returns key created from EC change.\r\n */\r\n private static buildKey(change: ChangedECInstance, db?: AnyDb): string {\r\n let classId = change.ECClassId;\r\n if (typeof classId === \"undefined\") {\r\n if (db && change.$meta?.fallbackClassId) {\r\n classId = this.getRootClassId(change.$meta.fallbackClassId, db);\r\n }\r\n if (typeof classId === \"undefined\") {\r\n throw new Error(`unable to resolve ECClassId to root class id.`);\r\n }\r\n }\r\n return `${change.ECInstanceId}-${classId}-${change.$meta?.stage}`.toLowerCase();\r\n }\r\n /**\r\n * Append partial changes which will be combine using there instance key.\r\n * @note $meta property must be present on partial change as information\r\n * in it is used to combine partial instances.\r\n * @param adaptor changeset adaptor is use to read the partial EC change.\r\n * @beta\r\n */\r\n public appendFrom(adaptor: ChangesetECAdaptor): void {\r\n if (adaptor.disableMetaData) {\r\n throw new Error(\"change adaptor property 'disableMetaData' must be set to 'false'\");\r\n }\r\n if (this._readonly) {\r\n throw new Error(\"this instance is marked as readonly.\");\r\n }\r\n\r\n if (adaptor.op === \"Updated\" && adaptor.inserted && adaptor.deleted) {\r\n this.combine(adaptor.inserted, adaptor.reader.db);\r\n this.combine(adaptor.deleted, adaptor.reader.db);\r\n } else if (adaptor.op === \"Inserted\" && adaptor.inserted) {\r\n this.combine(adaptor.inserted, adaptor.reader.db);\r\n } else if (adaptor.op === \"Deleted\" && adaptor.deleted) {\r\n this.combine(adaptor.deleted, adaptor.reader.db);\r\n }\r\n }\r\n /**\r\n * Delete $meta from all the instances.\r\n */\r\n public stripMetaData(): void {\r\n for (const inst of this._cache.values()) {\r\n if (\"$meta\" in inst) {\r\n delete inst.$meta;\r\n }\r\n }\r\n this._readonly = true;\r\n }\r\n /**\r\n * Returns complete EC change instances.\r\n * @beta\r\n */\r\n public get instances(): IterableIterator<ChangedECInstance> { return this._cache.values(); }\r\n}\r\n\r\n/**\r\n * Transform sqlite change to ec change. EC change is partial change as\r\n * it is per table while a single instance can span multiple table.\r\n * @note PrimitiveArray and StructArray are not supported types.\r\n * @beta\r\n *\r\n*/\r\nexport class ChangesetECAdaptor implements IDisposable {\r\n private readonly _mapCache: ECDbMap;\r\n private readonly _tableFilter = new Set<string>();\r\n private readonly _opFilter = new Set<SqliteChangeOp>();\r\n private readonly _classFilter = new Set<string>();\r\n private _allowedClasses = new Set<string>();\r\n /**\r\n * set debug flags\r\n */\r\n public readonly debugFlags = {\r\n replaceBlobWithEllipsis: false, // replace bolb with ... for debugging\r\n replaceGeomWithEllipsis: false, // replace geom with ... for debugging\r\n replaceGuidWithEllipsis: false, // replace geom with ... for debugging\r\n };\r\n /**\r\n * Return partial inserted instance\r\n * For updates inserted represent new version of instance after update.\r\n */\r\n public inserted?: ChangedECInstance;\r\n /**\r\n * Return partial deleted instance.\r\n * For updates deleted represent old version of instance before update.\r\n */\r\n public deleted?: ChangedECInstance;\r\n\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of tables added by acceptTable().\r\n * @param table Name of the table\r\n * @returns Fluent reference to ChangesetAdaptor.\r\n */\r\n public acceptTable(table: string): ChangesetECAdaptor {\r\n if (!this._tableFilter.has(table))\r\n this._tableFilter.add(table);\r\n return this;\r\n }\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of op added by acceptOp().\r\n * @param op\r\n * @returns Fluent reference to ChangesetAdaptor.\r\n */\r\n public acceptOp(op: SqliteChangeOp): ChangesetECAdaptor {\r\n if (!this._opFilter.has(op))\r\n this._opFilter.add(op);\r\n return this;\r\n }\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of class and its derived classes added by acceptClass().\r\n * @param classFullName\r\n * @returns\r\n */\r\n public acceptClass(classFullName: string): ChangesetECAdaptor {\r\n if (!this._classFilter.has(classFullName))\r\n this._classFilter.add(classFullName);\r\n\r\n this._allowedClasses.clear();\r\n return this;\r\n }\r\n private buildClassFilter() {\r\n if (this._allowedClasses.size !== 0 || this._classFilter.size === 0)\r\n return;\r\n\r\n this._classFilter.forEach((className) => {\r\n this._mapCache.getAllDerivedClasses(className).forEach((classId) => {\r\n this._allowedClasses.add(classId);\r\n });\r\n });\r\n }\r\n /**\r\n * Construct adaptor with a initialized reader.\r\n * @note the changeset reader must have disableSchemaCheck\r\n * set to false and db must also be set.\r\n * @param reader wrap changeset reader.\r\n */\r\n public constructor(public readonly reader: SqliteChangesetReader, public readonly disableMetaData = false) {\r\n if (!reader.db)\r\n throw new Error(\"SqliteChangesetReader, 'db' param must be set to a valid IModelDb or ECDb.\");\r\n\r\n if (!reader.disableSchemaCheck)\r\n throw new Error(\"SqliteChangesetReader, 'disableSchemaCheck' param must be set to false.\");\r\n\r\n this._mapCache = new ECDbMap(reader.db);\r\n }\r\n /**\r\n * dispose current instance and it will also dispose the changeset reader.\r\n */\r\n public dispose(): void {\r\n this.close();\r\n }\r\n /**\r\n * close current instance and it will also close the changeset reader.\r\n */\r\n public close(): void {\r\n this.reader.close();\r\n }\r\n /**\r\n * Convert binary GUID into string GUID.\r\n * @param binaryGUID binary version of guid.\r\n * @returns GUID string.\r\n */\r\n private static convertBinaryToGuid(binaryGUID: Uint8Array): GuidString {\r\n // Check if the array has 16 elements\r\n if (binaryGUID.length !== 16) {\r\n throw new Error(\"Invalid array length for Guid\");\r\n }\r\n // Convert each element to a two-digit hexadecimal string\r\n const hex = Array.from(binaryGUID, (byte) => byte.toString(16).padStart(2, \"0\"));\r\n // Join the hexadecimal strings and insert hyphens\r\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10, 16).join(\"\")}`;\r\n\r\n }\r\n /**\r\n * Set value use access string in a JS object.\r\n * @param targetObj object that will be updated.\r\n * @param accessString access string token separated by '.'.\r\n */\r\n private static setValue(targetObj: any, accessString: string, value: any): void {\r\n let cursor = targetObj;\r\n const propPath = accessString.split(\".\");\r\n propPath.forEach((propertyName) => {\r\n if (propertyName === \"__proto__\")\r\n throw new Error(\"access string cannot container __proto__\");\r\n });\r\n\r\n const leafProp = propPath.splice(-1).shift();\r\n if (!leafProp)\r\n throw new Error(\"not access string was specified.\");\r\n\r\n for (const elem of propPath) {\r\n if (typeof cursor[elem] === \"undefined\")\r\n cursor[elem] = {};\r\n cursor = cursor[elem];\r\n }\r\n cursor[leafProp] = value;\r\n }\r\n\r\n /**\r\n * Check if sqlite change table is a EC data table\r\n * @param tableName name of the table.\r\n * @returns true if table has EC data.\r\n */\r\n public isECTable(tableName: string) {\r\n return typeof this._mapCache.getTable(tableName) !== \"undefined\";\r\n }\r\n /**\r\n * Attempt find ECClassId from ECInstanceId for a change of type 'updated'.\r\n * @param tableName name of the table to find ECClassId from given ECInstanceId\r\n * @param instanceId instance id for which we need ECClassId for.\r\n * @returns if successful returns ECClassId else return undefined.\r\n */\r\n private getClassIdFromDb(tableName: string, instanceId: Id64String): Id64String | undefined {\r\n try {\r\n return this.reader.db?.withPreparedSqliteStatement(`SELECT [ECClassId] FROM [${tableName}] WHERE [rowId]=?`, (stmt) => {\r\n stmt.bindId(1, instanceId);\r\n return stmt.step() === DbResult.BE_SQLITE_ROW ? stmt.getValueId(0) : undefined;\r\n });\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n /** helper method around reader.op */\r\n public get op() { return this.reader.op; }\r\n /** Return true if current change is of type \"Inserted\" */\r\n public get isInserted() { return this.op === \"Inserted\"; }\r\n /** Return true if current change is of type \"Deleted\" */\r\n public get isDeleted() { return this.op === \"Deleted\"; }\r\n /** Return true if current change is of type \"Updated\" */\r\n public get isUpdated() { return this.op === \"Updated\"; }\r\n\r\n /**\r\n * Advance reader to next change or a change that meets the filter set in the current adaptor\r\n * @returns return false if no more changes to read.\r\n */\r\n public step(): boolean {\r\n this.inserted = undefined;\r\n this.deleted = undefined;\r\n this.buildClassFilter();\r\n while (this.reader.step()) {\r\n if (!this.isECTable(this.reader.tableName))\r\n continue;\r\n\r\n if (this._tableFilter.size > 0) {\r\n if (!this._tableFilter.has(this.reader.tableName))\r\n continue;\r\n }\r\n\r\n if (this._opFilter.size > 0) {\r\n if (!this._opFilter.has(this.reader.op))\r\n continue;\r\n }\r\n\r\n if (this.reader.hasRow) {\r\n const table = this._mapCache.getTable(this.reader.tableName);\r\n if (!table || table.type === \"Virtual\") {\r\n throw new Error(`table in changeset not found or is virtual ${this.reader.tableName}`);\r\n }\r\n\r\n const change = {\r\n inserted: this.reader.getChangeValuesObject(\"New\", { includePrimaryKeyInUpdateNew: true }),\r\n deleted: this.reader.getChangeValuesObject(\"Old\", { includePrimaryKeyInUpdateNew: true }),\r\n };\r\n\r\n if (!change.inserted && !change.deleted) {\r\n throw new Error(`unable to get change from changeset reader`);\r\n }\r\n\r\n let ecClassId: Id64String | undefined = this.reader.op === \"Inserted\" ? change.inserted?.ECClassId : change.deleted?.ECClassId;\r\n const classIdPresentInChange = typeof ecClassId !== \"undefined\";\r\n let classMap: IClassMap | undefined;\r\n let fallbackClassId: Id64String | undefined;\r\n if (table.isClassIdVirtual) {\r\n classMap = this._mapCache.getClassMap(table.exclusiveRootClassId);\r\n } else {\r\n if (!ecClassId) {\r\n // attempt to find ECClassId against row from the db.\r\n const primaryKeys = this.reader.primaryKeyValues;\r\n if (primaryKeys.length === 1) {\r\n ecClassId = this.getClassIdFromDb(this.reader.tableName, this.reader.primaryKeyValues[0] as Id64String);\r\n }\r\n }\r\n if (ecClassId)\r\n classMap = this._mapCache.getClassMap(ecClassId);\r\n if (!classMap) {\r\n // fallback to root map for table.\r\n classMap = this._mapCache.getClassMap(table.exclusiveRootClassId);\r\n if (classMap)\r\n fallbackClassId = table.exclusiveRootClassId;\r\n }\r\n }\r\n\r\n if (!classMap)\r\n throw new Error(`unable to load class map`);\r\n\r\n if (!classIdPresentInChange && !ecClassId && !fallbackClassId)\r\n ecClassId = classMap.id;\r\n\r\n if (this._allowedClasses.size !== 0) {\r\n if (!this._allowedClasses.has(classMap.id))\r\n continue;\r\n }\r\n\r\n const $meta = {\r\n tables: [this.reader.tableName],\r\n op: this.reader.op,\r\n classFullName: classMap.name,\r\n fallbackClassId,\r\n changeIndexes: [this.reader.changeIndex],\r\n };\r\n\r\n if (this.reader.op === \"Inserted\" && change.inserted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.inserted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.inserted.$meta = { ...$meta, stage: \"New\" };\r\n this.transform(classMap, change.inserted, table, this.inserted);\r\n } else if (this.reader.op === \"Deleted\" && change.deleted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.deleted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.deleted.$meta = { ...$meta, stage: \"Old\" };\r\n this.transform(classMap, change.deleted, table, this.deleted);\r\n } else if (change.inserted && change.deleted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.inserted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.inserted.$meta = { ...$meta, stage: \"New\" };\r\n this.transform(classMap, change.inserted, table, this.inserted);\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.deleted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.deleted.$meta = { ...$meta, stage: \"Old\" };\r\n this.transform(classMap, change.deleted, table, this.deleted);\r\n } else {\r\n throw new Error(\"unable to read EC changes\");\r\n }\r\n break;\r\n }\r\n }\r\n return this.reader.hasRow;\r\n }\r\n /**\r\n * Transform nav change column into navigation EC property\r\n * @param prop navigation property definition.\r\n * @param change sqlite change.\r\n * @param out ec instance that will be updated with navigation property.\r\n */\r\n private transformNavigationProperty(prop: IProperty, change: SqliteChange, out: ChangedECInstance): void {\r\n const idCol = prop.columns.filter(($) => $.accessString.endsWith(\".Id\")).at(0);\r\n if (!idCol) {\r\n throw new Error(\"invalid map for nav property\");\r\n }\r\n\r\n const idValue = change[idCol.column];\r\n if (typeof idValue === \"undefined\")\r\n return;\r\n\r\n ChangesetECAdaptor.setValue(out, idCol.accessString, idValue);\r\n\r\n const relClassIdCol = prop.columns.filter(($) => $.accessString.endsWith(\".RelECClassId\")).at(0);\r\n if (!relClassIdCol) {\r\n throw new Error(\"invalid map for nav property\");\r\n }\r\n\r\n const relClassIdValue = relClassIdCol.isVirtual ? prop.navigationRelationship?.classId : change[relClassIdCol.column];\r\n if (typeof relClassIdValue === \"undefined\")\r\n return;\r\n\r\n ChangesetECAdaptor.setValue(out, relClassIdCol.accessString, relClassIdValue);\r\n }\r\n /**\r\n * Transform sqlite change into EC change.\r\n * @param classMap classMap use to deserialize sqlite change into EC change.\r\n * @param change sqlite change from changeset.\r\n * @param table table definition of sqlite change provided.\r\n * @param out EC changeset that will be updated with properties.\r\n */\r\n private transform(classMap: IClassMap, change: SqliteChange, table: ITable, out: ChangedECInstance): void {\r\n // transform change row to instance\r\n for (const prop of classMap.properties) {\r\n if (prop.kind === \"PrimitiveArray\" || prop.kind === \"StructArray\") {\r\n // Arrays not supported\r\n continue;\r\n }\r\n if (prop.columns.filter((_) => _.isVirtual).length === prop.columns.length) {\r\n continue;\r\n }\r\n if (prop.kind === \"Navigation\") {\r\n this.transformNavigationProperty(prop, change, out);\r\n } else {\r\n for (const col of prop.columns) {\r\n if (col.table !== table.name)\r\n continue;\r\n\r\n const columnValue = change[col.column];\r\n if (typeof columnValue === \"undefined\")\r\n continue;\r\n\r\n if (columnValue !== null) {\r\n if (prop.primitiveType === \"DateTime\") {\r\n const dt = DateTime.fromJulianDay(columnValue, prop.dateTimeInfo?.dateTimeKind === \"Local\");\r\n ChangesetECAdaptor.setValue(out, col.accessString, dt.toISOString());\r\n continue;\r\n }\r\n if (prop.extendedTypeName === \"BeGuid\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceGuidWithEllipsis ? \"...\" : ChangesetECAdaptor.convertBinaryToGuid(columnValue));\r\n continue;\r\n }\r\n if (prop.extendedTypeName === \"GeometryStream\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceGeomWithEllipsis ? \"...\" : columnValue);\r\n continue;\r\n }\r\n if (prop.primitiveType === \"Binary\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceBlobWithEllipsis ? \"...\" : columnValue);\r\n continue;\r\n }\r\n }\r\n ChangesetECAdaptor.setValue(out, col.accessString, columnValue);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ChangesetECAdaptor.js","sourceRoot":"","sources":["../../src/ChangesetECAdaptor.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\n/** @packageDocumentation\r\n * @module ECDb\r\n */\r\nimport { DbResult, GuidString, Id64String, IDisposable } from \"@itwin/core-bentley\";\r\nimport { AnyDb, SqliteChange, SqliteChangeOp, SqliteChangesetReader, SqliteValueStage } from \"./SqliteChangesetReader\";\r\n\r\ninterface IClassRef {\r\n classId: Id64String;\r\n classFullName: string;\r\n}\r\n\r\ninterface IClassMap {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly mapStrategy: \"NotMapped\" | \"OwnTable\" | \"TablePerHierarchy\" | \"ExistingTable\" | \"ForeignKeyInTargetTable\" | \"ForeignKeyInSourceTable\";\r\n readonly type: \"Entity\" | \"Relationship\" | \"Struct\" | \"CustomAttribute\";\r\n readonly modifier: \"None\" | \"Abstract\" | \"Sealed\";\r\n readonly properties: IProperty[];\r\n}\r\n\r\ninterface IDateTimeInfo {\r\n readonly dateTimeKind?: \"Utc\" | \"Local\" | \"Unspecified\";\r\n readonly dateTimeComponent?: \"DateTime\" | \"Date\" | \"TimeOfDay\";\r\n}\r\n\r\ninterface IProperty {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly kind: \"Primitive\" | \"Struct\" | \"PrimitiveArray\" | \"StructArray\" | \"Navigation\";\r\n readonly primitiveType?: \"Binary\" | \"Boolean\" | \"DateTime\" | \"Double\" | \"Integer\" | \"Long\" | \"Point2d\" | \"Point3d\" | \"String\" | \"IGeometry\";\r\n readonly extendedTypeName?: string;\r\n readonly navigationRelationship?: IClassRef;\r\n readonly structClass?: IClassRef;\r\n readonly dateTimeInfo?: IDateTimeInfo;\r\n readonly columns: IColumn[];\r\n\r\n}\r\n\r\ninterface IColumn {\r\n readonly table: string;\r\n readonly column: string;\r\n readonly type: \"Any\" | \"Boolean\" | \"Blob\" | \"Timestamp\" | \"Real\" | \"Integer\" | \"Text\";\r\n readonly columnKind: \"Default\" | \"Id\" | \"ClassId\" | \"Shared\";\r\n readonly accessString: string;\r\n readonly isVirtual: boolean;\r\n}\r\n\r\ninterface ITable {\r\n readonly id: Id64String;\r\n readonly name: string;\r\n readonly type: \"Primary\" | \"Joined\" | \"Existing\" | \"Overflow\" | \"Virtual\";\r\n readonly exclusiveRootClassId: Id64String;\r\n readonly isClassIdVirtual: boolean;\r\n}\r\n\r\nclass ECDbMap {\r\n private _cachedClassMaps = new Map<Id64String, IClassMap>();\r\n private _cacheTables = new Map<string, ITable>();\r\n public constructor(public readonly db: AnyDb) { }\r\n public getAllDerivedClasses(classFullName: string) {\r\n const sql = `\r\n SELECT format('0x%x', ch.ClassId)\r\n FROM [ec_cache_ClassHierarchy] [ch]\r\n JOIN [ec_Class] [cs] ON [cs].[Id] = [ch].[BaseClassId]\r\n JOIN [ec_Schema] [sc] ON [sc].[Id] = [cs].[SchemaId]\r\n WHERE (([sc].[Alias] = :schemaNameOrAlias\r\n OR [sc].[Name] = :schemaNameOrAlias)\r\n AND ([cs].[Name] = :className))\r\n `;\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n const parts = classFullName.indexOf(\".\") !== -1 ? classFullName.split(\".\") : classFullName.split(\":\");\r\n stmt.bindString(\":schemaNameOrAlias\", parts[0]);\r\n stmt.bindString(\":className\", parts[1]);\r\n const classIds = [];\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n classIds.push(stmt.getValueString(0));\r\n return classIds;\r\n });\r\n }\r\n public getTable(tableName: string): ITable | undefined {\r\n if (this._cacheTables.has(tableName))\r\n return this._cacheTables.get(tableName);\r\n\r\n const sql = `\r\n SELECT\r\n JSON_OBJECT (\r\n 'id', FORMAT ('0x%x', [t].[id]),\r\n 'name', [t].[Name],\r\n 'type', (\r\n CASE\r\n [t].[type]\r\n WHEN 0 THEN 'Primary'\r\n WHEN 1 THEN 'Joined'\r\n WHEN 2 THEN 'Existing'\r\n WHEN 3 THEN 'Overflow'\r\n WHEN 4 THEN 'Virtual'\r\n END\r\n ),\r\n 'exclusiveRootClassId', FORMAT ('0x%x', [t].[ExclusiveRootClassId]),\r\n 'isClassIdVirtual', (\r\n SELECT\r\n [c].[IsVirtual]\r\n FROM\r\n [ec_Column] [c]\r\n WHERE\r\n [c].[Name] = 'ECClassId' AND [c].[TableId] = [t].[Id]\r\n )\r\n )\r\n FROM [ec_Table] [t]\r\n WHERE\r\n [t].[Name] = ?;\r\n `;\r\n\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n stmt.bindString(1, tableName);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const table = JSON.parse(stmt.getValueString(0), (key, value) => {\r\n if (value === null)\r\n return undefined;\r\n\r\n if (key === \"isClassIdVirtual\")\r\n return value === 0 ? false : true;\r\n\r\n return value;\r\n }) as ITable;\r\n\r\n this._cacheTables.set(tableName, table);\r\n return table;\r\n }\r\n return undefined;\r\n });\r\n }\r\n public getClassMap(classId: Id64String): IClassMap | undefined {\r\n if (this._cachedClassMaps.has(classId))\r\n return this._cachedClassMaps.get(classId);\r\n\r\n const sql = `\r\n SELECT\r\n JSON_OBJECT(\r\n 'id', format('0x%x', cs.id),\r\n 'name', format('%s:%s', ss.Name, cs.Name),\r\n 'mapStrategy',\r\n (\r\n CASE cm.MapStrategy\r\n WHEN 0 THEN 'NotMapped'\r\n WHEN 1 THEN 'OwnTable'\r\n WHEN 2 THEN 'TablePerHierarchy'\r\n WHEN 3 THEN 'ExistingTable'\r\n WHEN 10 THEN 'ForeignKeyInTargetTable'\r\n WHEN 11 THEN 'ForeignKeyInSourceTable'\r\n END\r\n ),\r\n 'type',\r\n (\r\n CASE cs.Type\r\n WHEN 0 THEN 'Entity'\r\n WHEN 1 THEN 'Relationship'\r\n WHEN 2 THEN 'Struct'\r\n WHEN 3 THEN 'CustomAttribute'\r\n END\r\n ),\r\n 'modifier',\r\n (\r\n CASE cs.Modifier\r\n WHEN 0 THEN 'None'\r\n WHEN 1 THEN 'Abstract'\r\n WHEN 2 THEN 'Sealed'\r\n END\r\n ),\r\n 'properties',\r\n (\r\n SELECT\r\n JSON_GROUP_ARRAY(JSON(propJson))\r\n FROM\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'id', format('0x%x', pt.id),\r\n 'name', pt.Name,\r\n 'kind',\r\n (\r\n CASE pt.Kind\r\n WHEN 0 THEN 'Primitive'\r\n WHEN 1 THEN 'Struct'\r\n WHEN 2 THEN 'PrimitiveArray'\r\n WHEN 3 THEN 'StructArray'\r\n WHEN 4 THEN 'Navigation'\r\n END\r\n ),\r\n 'primitiveType',\r\n (\r\n CASE pt.PrimitiveType\r\n WHEN 0x101 THEN 'Binary'\r\n WHEN 0x201 THEN 'Boolean'\r\n WHEN 0x301 THEN 'DateTime'\r\n WHEN 0x401 THEN 'Double'\r\n WHEN 0x501 THEN 'Integer'\r\n WHEN 0x601 THEN 'Long'\r\n WHEN 0x701 THEN 'Point2d'\r\n WHEN 0x801 THEN 'Point3d'\r\n WHEN 0x901 THEN 'String'\r\n WHEN 0xa01 THEN 'IGeometry'\r\n END\r\n ),\r\n 'extendedTypeName', ExtendedTypeName,\r\n 'navigationRelationship',\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'classId', format('0x%x', nc.Id),\r\n 'classFullName', format('%s:%s', ns.Name, nc.Name)\r\n )\r\n FROM ec_Class nc\r\n JOIN ec_Schema ns ON ns.Id = nc.SchemaId\r\n WHERE\r\n nc.Id = pt.NavigationRelationshipClassId\r\n ),\r\n 'structClass',\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'classId', format('0x%x', nc.Id),\r\n 'classFullName', format('%s:%s', ns.Name, nc.Name)\r\n )\r\n FROM ec_Class nc\r\n JOIN ec_Schema ns ON ns.Id = nc.SchemaId\r\n WHERE\r\n nc.Id = pt.StructClassId\r\n ),\r\n 'dateTimeInfo', (\r\n SELECT\r\n JSON_OBJECT (\r\n 'dateTimeKind', (\r\n CASE\r\n WHEN [ca].[Instance] LIKE '%<DateTimeKind>Utc</DateTimeKind>%' COLLATE [NoCase] THEN 'Utc'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeKind>Local</DateTimeKind>%' COLLATE [NoCase] THEN 'Local'\r\n ELSE 'Unspecified'\r\n END\r\n ),\r\n 'dateTimeComponent', (\r\n CASE\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>DateTime</DateTimeComponent>%' COLLATE [NoCase] THEN 'DateTime'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>Date</DateTimeComponent>%' COLLATE [NoCase] THEN 'Date'\r\n WHEN [ca].[Instance] LIKE '%<DateTimeComponent>TimeOfDay</DateTimeComponent>%' COLLATE [NoCase] THEN 'TimeOfDay'\r\n ELSE 'DateTime'\r\n END\r\n )\r\n )\r\n FROM\r\n [ec_CustomAttribute] [ca]\r\n JOIN [ec_Class] [cl] ON [cl].[Id] = [ca].[ClassId]\r\n JOIN [ec_Schema] [sc] ON [sc].[Id] = [cl].[SchemaId]\r\n WHERE\r\n [ca].[ContainerType] = 992\r\n AND [cl].[Name] = 'DateTimeInfo'\r\n AND [sc].[Name] = 'CoreCustomAttributes'\r\n AND [ca].[ContainerId] = [pt].[Id]\r\n ),\r\n 'columns',\r\n (\r\n SELECT\r\n JSON_GROUP_ARRAY(JSON(columnJson))\r\n FROM\r\n (\r\n SELECT\r\n JSON_OBJECT(\r\n 'table', tb.Name,\r\n 'column', cc.Name,\r\n 'type',\r\n (\r\n CASE cc.Type\r\n WHEN 0 THEN 'Any'\r\n WHEN 1 THEN 'Boolean'\r\n WHEN 2 THEN 'Blob'\r\n WHEN 3 THEN 'Timestamp'\r\n WHEN 4 THEN 'Real'\r\n WHEN 5 THEN 'Integer'\r\n WHEN 6 THEN 'Text'\r\n END\r\n ),\r\n 'columnKind',\r\n (\r\n CASE cc.ColumnKind\r\n WHEN 0 THEN 'Default'\r\n WHEN 1 THEN 'Id'\r\n WHEN 2 THEN 'ClassId'\r\n WHEN 4 THEN 'SharedData'\r\n END\r\n ),\r\n 'accessString', pp0.AccessString,\r\n 'isVirtual', cc.IsVirtual OR tb.Type = 4\r\n ) columnJson\r\n FROM [ec_PropertyMap] [pm0]\r\n JOIN [ec_Column] [cc] ON [cc].[Id] = [pm0].[ColumnId]\r\n JOIN [ec_Table] [tb] ON [tb].[Id] = [cc].[TableId]\r\n JOIN [ec_PropertyPath] [pp0] ON [pp0].[Id] = [pm0].[PropertyPathId]\r\n WHERE\r\n [pp0].[RootPropertyId] = pt.Id AND pm0.ClassId = cs.Id\r\n )\r\n )\r\n ) propJson\r\n FROM [ec_PropertyMap] [pm]\r\n JOIN [ec_PropertyPath] [pp] ON [pp].[Id] = [pm].[PropertyPathId]\r\n JOIN [ec_Property] [pt] ON [pt].[Id] = [pp].[RootPropertyId]\r\n WHERE\r\n pm.ClassId = cs.Id\r\n GROUP BY\r\n pt.Id\r\n )\r\n )\r\n ) classDef\r\n FROM [ec_Class] [cs]\r\n JOIN [ec_ClassMap] [cm] ON [cm].[ClassId] = [cs].[Id]\r\n JOIN [ec_Schema] [ss] ON [ss].[Id] = [cs].[SchemaId]\r\n WHERE\r\n [cs].[Id] = ?\r\n `;\r\n\r\n return this.db.withPreparedSqliteStatement(sql, (stmt) => {\r\n stmt.bindId(1, classId);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const classMap = JSON.parse(stmt.getValueString(0), (key, value) => {\r\n if (value === null) {\r\n return undefined;\r\n }\r\n if (key === \"isVirtual\") {\r\n return value === 0 ? false : true;\r\n }\r\n return value;\r\n }) as IClassMap;\r\n\r\n this._cachedClassMaps.set(classId, classMap);\r\n return classMap;\r\n }\r\n return undefined;\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Record meta data for the change.\r\n * @beta\r\n * */\r\nexport interface ChangeMetaData {\r\n /** list of tables making up this EC change */\r\n tables: string[];\r\n /** full name of the class of this EC change */\r\n classFullName?: string;\r\n /** sqlite operation that caused the change */\r\n op: SqliteChangeOp;\r\n /** version of the value read from sqlite change */\r\n stage: SqliteValueStage;\r\n /** if classId for the change was not found in db then fallback class for the table */\r\n fallbackClassId?: Id64String;\r\n /** list of change index making up this change (one per table) */\r\n changeIndexes: number[];\r\n}\r\n\r\n/**\r\n * Represent EC change derived from low level sqlite change\r\n * @beta\r\n */\r\nexport interface ChangedECInstance {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ECInstanceId: Id64String;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n ECClassId?: Id64String;\r\n $meta?: ChangeMetaData;\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Helper function to convert between JS DateTime & SQLite JulianDay values.\r\n * @beta\r\n * */\r\nnamespace DateTime {\r\n /**\r\n * Convert JS date to JulianDay value.\r\n * @param dt JS Date object.\r\n * @param convertToUtc convert the input value to UTC.\r\n * @returns julian day value\r\n */\r\n export function toJulianDay(dt: Date, convertToUtc = true): number {\r\n const utcOffset = convertToUtc ? dt.getTimezoneOffset() / 1440 : 0;\r\n return (dt.valueOf() / 86400000) - utcOffset + 2440587.5;\r\n }\r\n /**\r\n * Convert Julian day to JS Date object\r\n * @param jd JulianDay value for date/time\r\n * @param isLocalTime if julian day is local time or UTC\r\n * @returns JS Date object.\r\n */\r\n export function fromJulianDay(jd: number, isLocalTime: boolean): Date {\r\n const utcOffset = isLocalTime ? 0 : new Date().getTimezoneOffset() / 1440;\r\n return new Date((jd - 2440587.5 + utcOffset) * 86400000);\r\n }\r\n}\r\n/**\r\n * Combine partial changed instance into single instance.\r\n * Partial changes is per table and a single instance can\r\n * span multiple tables.\r\n * @beta\r\n */\r\nexport class PartialECChangeUnifier {\r\n private _cache = new Map<string, ChangedECInstance>();\r\n private _readonly = false;\r\n /**\r\n * Get root class id for a given class\r\n * @param classId given class id\r\n * @param db use to find root class\r\n * @returns return root class id\r\n */\r\n private static getRootClassId(classId: Id64String, db: AnyDb): Id64String | undefined {\r\n const sql = `\r\n WITH\r\n [base_class]([classId], [baseClassId], [Level]) AS(\r\n SELECT [ch].[ClassId], [ch].[BaseClassId], 0\r\n FROM [ec_ClassHasBaseClasses] [ch] WHERE [ch].[ClassId] = ?\r\n UNION ALL\r\n SELECT [ch].[ClassId], [ch].[BaseClassId], [Level] + 1\r\n FROM [ec_ClassHasBaseClasses] [ch], [base_class] [bc] WHERE [bc].[BaseClassId] = [ch].[ClassId]\r\n\r\n )\r\n SELECT FORMAT('0x%x', [bc].[BaseClassId]) rootClass\r\n FROM [base_class] [bc]\r\n WHERE [bc].[ClassId] <> [bc].[BaseClassId]\r\n AND [bc].[BaseClassId] NOT IN (SELECT [ca].[ContainerId]\r\n FROM [ec_CustomAttribute] [ca]\r\n WHERE [ca].[ContainerType] = 30\r\n AND [ca].[ClassId] IN (SELECT [cc].[Id]\r\n FROM [ec_Class] [cc]\r\n JOIN [ec_Schema] [ss] ON [ss].[Id] = [cc].[SchemaId]\r\n WHERE [cc].[Name] = 'IsMixIn'\r\n AND [ss].[Name] = 'CoreCustomAttributes'))\r\n ORDER BY [Level] DESC`;\r\n\r\n return db.withSqliteStatement(sql, (stmt) => {\r\n stmt.bindId(1, classId);\r\n if (stmt.step() === DbResult.BE_SQLITE_ROW && !stmt.isValueNull(0)) {\r\n return stmt.getValueString(0);\r\n }\r\n return classId;\r\n });\r\n }\r\n /**\r\n * Combine partial instance with instance with same key if already exists.\r\n * @param rhs partial instance\r\n */\r\n private combine(rhs: ChangedECInstance, db?: AnyDb): void {\r\n if (!rhs.$meta) {\r\n throw new Error(\"PartialECChange being combine must have '$meta' property\");\r\n }\r\n const key = PartialECChangeUnifier.buildKey(rhs, db);\r\n const lhs = this._cache.get(key);\r\n if (lhs) {\r\n const { $meta: _, ...restOfRhs } = rhs;\r\n Object.assign(lhs, restOfRhs);\r\n if (lhs.$meta && rhs.$meta) {\r\n lhs.$meta.tables = [...rhs.$meta?.tables, ...lhs.$meta?.tables];\r\n lhs.$meta.changeIndexes = [...rhs.$meta?.changeIndexes, ...lhs.$meta?.changeIndexes];\r\n\r\n // we preserve child class name & id when merging instance.\r\n if (rhs.$meta.fallbackClassId && lhs.$meta.fallbackClassId && db && rhs.$meta.fallbackClassId !== lhs.$meta.fallbackClassId) {\r\n const lhsClassId = lhs.$meta.fallbackClassId;\r\n const rhsClassId = rhs.$meta.fallbackClassId;\r\n const isRhsIsSubClassOfLhs = db.withPreparedStatement(\"SELECT ec_instanceof(?,?)\", (stmt) => {\r\n stmt.bindId(1, rhsClassId);\r\n stmt.bindId(2, lhsClassId);\r\n stmt.step();\r\n return stmt.getValue(0).getInteger() === 1;\r\n });\r\n if (isRhsIsSubClassOfLhs) {\r\n lhs.$meta.fallbackClassId = rhs.$meta.fallbackClassId;\r\n lhs.$meta.classFullName = rhs.$meta.classFullName;\r\n }\r\n }\r\n }\r\n } else {\r\n this._cache.set(key, rhs);\r\n }\r\n }\r\n /**\r\n * Build key from EC change.\r\n * @param change EC change\r\n * @returns key created from EC change.\r\n */\r\n private static buildKey(change: ChangedECInstance, db?: AnyDb): string {\r\n let classId = change.ECClassId;\r\n if (typeof classId === \"undefined\") {\r\n if (db && change.$meta?.fallbackClassId) {\r\n classId = this.getRootClassId(change.$meta.fallbackClassId, db);\r\n }\r\n if (typeof classId === \"undefined\") {\r\n throw new Error(`unable to resolve ECClassId to root class id.`);\r\n }\r\n }\r\n return `${change.ECInstanceId}-${classId}-${change.$meta?.stage}`.toLowerCase();\r\n }\r\n /**\r\n * Append partial changes which will be combine using there instance key.\r\n * @note $meta property must be present on partial change as information\r\n * in it is used to combine partial instances.\r\n * @param adaptor changeset adaptor is use to read the partial EC change.\r\n * @beta\r\n */\r\n public appendFrom(adaptor: ChangesetECAdaptor): void {\r\n if (adaptor.disableMetaData) {\r\n throw new Error(\"change adaptor property 'disableMetaData' must be set to 'false'\");\r\n }\r\n if (this._readonly) {\r\n throw new Error(\"this instance is marked as readonly.\");\r\n }\r\n\r\n if (adaptor.op === \"Updated\" && adaptor.inserted && adaptor.deleted) {\r\n this.combine(adaptor.inserted, adaptor.reader.db);\r\n this.combine(adaptor.deleted, adaptor.reader.db);\r\n } else if (adaptor.op === \"Inserted\" && adaptor.inserted) {\r\n this.combine(adaptor.inserted, adaptor.reader.db);\r\n } else if (adaptor.op === \"Deleted\" && adaptor.deleted) {\r\n this.combine(adaptor.deleted, adaptor.reader.db);\r\n }\r\n }\r\n /**\r\n * Delete $meta from all the instances.\r\n */\r\n public stripMetaData(): void {\r\n for (const inst of this._cache.values()) {\r\n if (\"$meta\" in inst) {\r\n delete inst.$meta;\r\n }\r\n }\r\n this._readonly = true;\r\n }\r\n /**\r\n * Returns complete EC change instances.\r\n * @beta\r\n */\r\n public get instances(): IterableIterator<ChangedECInstance> { return this._cache.values(); }\r\n}\r\n\r\n/**\r\n * Transform sqlite change to ec change. EC change is partial change as\r\n * it is per table while a single instance can span multiple table.\r\n * @note PrimitiveArray and StructArray are not supported types.\r\n * @beta\r\n *\r\n*/\r\nexport class ChangesetECAdaptor implements IDisposable {\r\n private readonly _mapCache: ECDbMap;\r\n private readonly _tableFilter = new Set<string>();\r\n private readonly _opFilter = new Set<SqliteChangeOp>();\r\n private readonly _classFilter = new Set<string>();\r\n private _allowedClasses = new Set<string>();\r\n /**\r\n * set debug flags\r\n */\r\n public readonly debugFlags = {\r\n replaceBlobWithEllipsis: false, // replace bolb with ... for debugging\r\n replaceGeomWithEllipsis: false, // replace geom with ... for debugging\r\n replaceGuidWithEllipsis: false, // replace geom with ... for debugging\r\n };\r\n /**\r\n * Return partial inserted instance\r\n * For updates inserted represent new version of instance after update.\r\n */\r\n public inserted?: ChangedECInstance;\r\n /**\r\n * Return partial deleted instance.\r\n * For updates deleted represent old version of instance before update.\r\n */\r\n public deleted?: ChangedECInstance;\r\n\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of tables added by acceptTable().\r\n * @param table Name of the table\r\n * @returns Fluent reference to ChangesetAdaptor.\r\n */\r\n public acceptTable(table: string): ChangesetECAdaptor {\r\n if (!this._tableFilter.has(table))\r\n this._tableFilter.add(table);\r\n return this;\r\n }\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of op added by acceptOp().\r\n * @param op\r\n * @returns Fluent reference to ChangesetAdaptor.\r\n */\r\n public acceptOp(op: SqliteChangeOp): ChangesetECAdaptor {\r\n if (!this._opFilter.has(op))\r\n this._opFilter.add(op);\r\n return this;\r\n }\r\n /**\r\n * Setup filter that will result in change enumeration restricted to\r\n * list of class and its derived classes added by acceptClass().\r\n * @param classFullName\r\n * @returns\r\n */\r\n public acceptClass(classFullName: string): ChangesetECAdaptor {\r\n if (!this._classFilter.has(classFullName))\r\n this._classFilter.add(classFullName);\r\n\r\n this._allowedClasses.clear();\r\n return this;\r\n }\r\n private buildClassFilter() {\r\n if (this._allowedClasses.size !== 0 || this._classFilter.size === 0)\r\n return;\r\n\r\n this._classFilter.forEach((className) => {\r\n this._mapCache.getAllDerivedClasses(className).forEach((classId) => {\r\n this._allowedClasses.add(classId);\r\n });\r\n });\r\n }\r\n /**\r\n * Construct adaptor with a initialized reader.\r\n * @note the changeset reader must have disableSchemaCheck\r\n * set to false and db must also be set.\r\n * @param reader wrap changeset reader.\r\n */\r\n public constructor(public readonly reader: SqliteChangesetReader, public readonly disableMetaData = false) {\r\n if (!reader.db)\r\n throw new Error(\"SqliteChangesetReader, 'db' param must be set to a valid IModelDb or ECDb.\");\r\n\r\n if (!reader.disableSchemaCheck)\r\n throw new Error(\"SqliteChangesetReader, 'disableSchemaCheck' param must be set to false.\");\r\n\r\n this._mapCache = new ECDbMap(reader.db);\r\n }\r\n /**\r\n * dispose current instance and it will also dispose the changeset reader.\r\n */\r\n public dispose(): void {\r\n this.close();\r\n }\r\n /**\r\n * close current instance and it will also close the changeset reader.\r\n */\r\n public close(): void {\r\n this.reader.close();\r\n }\r\n /**\r\n * Convert binary GUID into string GUID.\r\n * @param binaryGUID binary version of guid.\r\n * @returns GUID string.\r\n */\r\n private static convertBinaryToGuid(binaryGUID: Uint8Array): GuidString {\r\n // Check if the array has 16 elements\r\n if (binaryGUID.length !== 16) {\r\n throw new Error(\"Invalid array length for Guid\");\r\n }\r\n // Convert each element to a two-digit hexadecimal string\r\n const hex = Array.from(binaryGUID, (byte) => byte.toString(16).padStart(2, \"0\"));\r\n // Join the hexadecimal strings and insert hyphens\r\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10, 16).join(\"\")}`;\r\n\r\n }\r\n /**\r\n * Set value use access string in a JS object.\r\n * @param targetObj object that will be updated.\r\n * @param accessString access string token separated by '.'.\r\n */\r\n private static setValue(targetObj: any, accessString: string, value: any): void {\r\n let cursor = targetObj;\r\n const propPath = accessString.split(\".\");\r\n propPath.forEach((propertyName) => {\r\n if (propertyName === \"__proto__\")\r\n throw new Error(\"access string cannot container __proto__\");\r\n });\r\n\r\n const leafProp = propPath.splice(-1).shift();\r\n if (!leafProp)\r\n throw new Error(\"not access string was specified.\");\r\n\r\n for (const elem of propPath) {\r\n if (typeof cursor[elem] === \"undefined\")\r\n cursor[elem] = {};\r\n cursor = cursor[elem];\r\n }\r\n cursor[leafProp] = value;\r\n }\r\n\r\n /**\r\n * Check if sqlite change table is a EC data table\r\n * @param tableName name of the table.\r\n * @returns true if table has EC data.\r\n */\r\n public isECTable(tableName: string) {\r\n return typeof this._mapCache.getTable(tableName) !== \"undefined\";\r\n }\r\n /**\r\n * Attempt find ECClassId from ECInstanceId for a change of type 'updated'.\r\n * @param tableName name of the table to find ECClassId from given ECInstanceId\r\n * @param instanceId instance id for which we need ECClassId for.\r\n * @returns if successful returns ECClassId else return undefined.\r\n */\r\n private getClassIdFromDb(tableName: string, instanceId: Id64String): Id64String | undefined {\r\n try {\r\n return this.reader.db?.withPreparedSqliteStatement(`SELECT [ECClassId] FROM [${tableName}] WHERE [rowId]=?`, (stmt) => {\r\n stmt.bindId(1, instanceId);\r\n return stmt.step() === DbResult.BE_SQLITE_ROW ? stmt.getValueId(0) : undefined;\r\n });\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n /** helper method around reader.op */\r\n public get op() { return this.reader.op; }\r\n /** Return true if current change is of type \"Inserted\" */\r\n public get isInserted() { return this.op === \"Inserted\"; }\r\n /** Return true if current change is of type \"Deleted\" */\r\n public get isDeleted() { return this.op === \"Deleted\"; }\r\n /** Return true if current change is of type \"Updated\" */\r\n public get isUpdated() { return this.op === \"Updated\"; }\r\n\r\n /**\r\n * Advance reader to next change or a change that meets the filter set in the current adaptor\r\n * @returns return false if no more changes to read.\r\n */\r\n public step(): boolean {\r\n this.inserted = undefined;\r\n this.deleted = undefined;\r\n this.buildClassFilter();\r\n while (this.reader.step()) {\r\n if (!this.isECTable(this.reader.tableName))\r\n continue;\r\n\r\n if (this._tableFilter.size > 0) {\r\n if (!this._tableFilter.has(this.reader.tableName))\r\n continue;\r\n }\r\n\r\n if (this._opFilter.size > 0) {\r\n if (!this._opFilter.has(this.reader.op))\r\n continue;\r\n }\r\n\r\n if (this.reader.hasRow) {\r\n const table = this._mapCache.getTable(this.reader.tableName);\r\n if (!table || table.type === \"Virtual\") {\r\n throw new Error(`table in changeset not found or is virtual ${this.reader.tableName}`);\r\n }\r\n\r\n const change = {\r\n inserted: this.reader.getChangeValuesObject(\"New\", { includePrimaryKeyInUpdateNew: true }),\r\n deleted: this.reader.getChangeValuesObject(\"Old\", { includePrimaryKeyInUpdateNew: true }),\r\n };\r\n\r\n if (!change.inserted && !change.deleted) {\r\n throw new Error(`unable to get change from changeset reader`);\r\n }\r\n\r\n let ecClassId: Id64String | undefined = this.reader.op === \"Inserted\" ? change.inserted?.ECClassId : change.deleted?.ECClassId;\r\n const classIdPresentInChange = typeof ecClassId !== \"undefined\";\r\n let classMap: IClassMap | undefined;\r\n let fallbackClassId: Id64String | undefined;\r\n if (table.isClassIdVirtual) {\r\n classMap = this._mapCache.getClassMap(table.exclusiveRootClassId);\r\n } else {\r\n if (!ecClassId) {\r\n // attempt to find ECClassId against row from the db.\r\n const primaryKeys = this.reader.primaryKeyValues;\r\n if (primaryKeys.length === 1) {\r\n ecClassId = this.getClassIdFromDb(this.reader.tableName, this.reader.primaryKeyValues[0] as Id64String);\r\n }\r\n }\r\n if (ecClassId)\r\n classMap = this._mapCache.getClassMap(ecClassId);\r\n if (!classMap) {\r\n // fallback to root map for table.\r\n classMap = this._mapCache.getClassMap(table.exclusiveRootClassId);\r\n if (classMap)\r\n fallbackClassId = table.exclusiveRootClassId;\r\n }\r\n }\r\n\r\n if (!classMap)\r\n throw new Error(`unable to load class map`);\r\n\r\n if (!classIdPresentInChange && !ecClassId && !fallbackClassId)\r\n ecClassId = classMap.id;\r\n\r\n if (this._allowedClasses.size !== 0) {\r\n if (!this._allowedClasses.has(classMap.id))\r\n continue;\r\n }\r\n\r\n const $meta = {\r\n tables: [this.reader.tableName],\r\n op: this.reader.op,\r\n classFullName: classMap.name,\r\n fallbackClassId,\r\n changeIndexes: [this.reader.changeIndex],\r\n };\r\n\r\n if (this.reader.op === \"Inserted\" && change.inserted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.inserted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.inserted.$meta = { ...$meta, stage: \"New\" };\r\n this.transform(classMap, change.inserted, table, this.inserted);\r\n } else if (this.reader.op === \"Deleted\" && change.deleted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.deleted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.deleted.$meta = { ...$meta, stage: \"Old\" };\r\n this.transform(classMap, change.deleted, table, this.deleted);\r\n } else if (change.inserted && change.deleted) {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.inserted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.inserted.$meta = { ...$meta, stage: \"New\" };\r\n this.transform(classMap, change.inserted, table, this.inserted);\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n this.deleted = { ECClassId: ecClassId, ECInstanceId: \"\" };\r\n if (!this.disableMetaData)\r\n this.deleted.$meta = { ...$meta, stage: \"Old\" };\r\n this.transform(classMap, change.deleted, table, this.deleted);\r\n } else {\r\n throw new Error(\"unable to read EC changes\");\r\n }\r\n break;\r\n }\r\n }\r\n return this.reader.hasRow;\r\n }\r\n /**\r\n * Transform nav change column into navigation EC property\r\n * @param prop navigation property definition.\r\n * @param change sqlite change.\r\n * @param out ec instance that will be updated with navigation property.\r\n */\r\n private transformNavigationProperty(prop: IProperty, change: SqliteChange, out: ChangedECInstance): void {\r\n const idCol = prop.columns.filter(($) => $.accessString.endsWith(\".Id\")).at(0);\r\n if (!idCol) {\r\n throw new Error(\"invalid map for nav property\");\r\n }\r\n\r\n const idValue = change[idCol.column];\r\n if (typeof idValue === \"undefined\")\r\n return;\r\n\r\n ChangesetECAdaptor.setValue(out, idCol.accessString, idValue);\r\n\r\n const relClassIdCol = prop.columns.filter(($) => $.accessString.endsWith(\".RelECClassId\")).at(0);\r\n if (!relClassIdCol) {\r\n throw new Error(\"invalid map for nav property\");\r\n }\r\n\r\n const relClassIdValue = relClassIdCol.isVirtual ? prop.navigationRelationship?.classId : change[relClassIdCol.column];\r\n if (typeof relClassIdValue === \"undefined\")\r\n return;\r\n\r\n ChangesetECAdaptor.setValue(out, relClassIdCol.accessString, relClassIdValue);\r\n }\r\n /**\r\n * Transform sqlite change into EC change.\r\n * @param classMap classMap use to deserialize sqlite change into EC change.\r\n * @param change sqlite change from changeset.\r\n * @param table table definition of sqlite change provided.\r\n * @param out EC changeset that will be updated with properties.\r\n */\r\n private transform(classMap: IClassMap, change: SqliteChange, table: ITable, out: ChangedECInstance): void {\r\n // transform change row to instance\r\n for (const prop of classMap.properties) {\r\n if (prop.kind === \"PrimitiveArray\" || prop.kind === \"StructArray\") {\r\n // Arrays not supported\r\n continue;\r\n }\r\n if (prop.columns.filter((_) => _.isVirtual).length === prop.columns.length) {\r\n continue;\r\n }\r\n if (prop.kind === \"Navigation\") {\r\n this.transformNavigationProperty(prop, change, out);\r\n } else {\r\n for (const col of prop.columns) {\r\n if (col.table !== table.name)\r\n continue;\r\n\r\n const columnValue = change[col.column];\r\n if (typeof columnValue === \"undefined\")\r\n continue;\r\n\r\n if (columnValue !== null) {\r\n if (prop.primitiveType === \"DateTime\") {\r\n const dt = DateTime.fromJulianDay(columnValue, prop.dateTimeInfo?.dateTimeKind === \"Local\");\r\n ChangesetECAdaptor.setValue(out, col.accessString, dt.toISOString());\r\n continue;\r\n }\r\n if (prop.extendedTypeName === \"BeGuid\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceGuidWithEllipsis ? \"...\" : ChangesetECAdaptor.convertBinaryToGuid(columnValue));\r\n continue;\r\n }\r\n if (prop.extendedTypeName === \"GeometryStream\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceGeomWithEllipsis ? \"...\" : columnValue);\r\n continue;\r\n }\r\n if (prop.primitiveType === \"Binary\") {\r\n ChangesetECAdaptor.setValue(out, col.accessString, this.debugFlags.replaceBlobWithEllipsis ? \"...\" : columnValue);\r\n continue;\r\n }\r\n }\r\n ChangesetECAdaptor.setValue(out, col.accessString, columnValue);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"]}
@@ -17,7 +17,7 @@ var ChannelControl;
17
17
  (function (ChannelControl) {
18
18
  /** the name of the special "shared" channel holding information that is editable by any application. */
19
19
  ChannelControl.sharedChannelName = "shared";
20
- })(ChannelControl = exports.ChannelControl || (exports.ChannelControl = {}));
20
+ })(ChannelControl || (exports.ChannelControl = ChannelControl = {}));
21
21
  /** @internal */
22
22
  class ChannelAdmin {
23
23
  constructor(_iModel) {
@@ -112,6 +112,6 @@ class ChannelAdmin {
112
112
  }
113
113
  }
114
114
  }
115
- ChannelAdmin.channelClassName = "bis:ChannelRootAspect";
116
115
  exports.ChannelAdmin = ChannelAdmin;
116
+ ChannelAdmin.channelClassName = "bis:ChannelRootAspect";
117
117
  //# sourceMappingURL=ChannelControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelControl.js","sourceRoot":"","sources":["../../src/ChannelControl.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\n/** @packageDocumentation\r\n * @module Elements\r\n */\r\n\r\nimport { DbResult, Id64String, IModelStatus, RepositoryStatus } from \"@itwin/core-bentley\";\r\nimport { ChannelRootAspectProps, IModel, IModelError } from \"@itwin/core-common\";\r\nimport { Subject } from \"./Element\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { IModelHost } from \"./IModelHost\";\r\n\r\n/** The key for a channel. Used for \"allowed channels\" in [[ChannelControl]]\r\n * @beta\r\n */\r\nexport type ChannelKey = string;\r\n\r\n/**\r\n * Controls which channels of an iModel are permitted for write operations. An implementation of this interface is\r\n * available via [[IModelDb.channels]].\r\n * @see [Working With Channels]($docs/learning/backend/Channel.md) for details\r\n * @beta\r\n */\r\nexport interface ChannelControl {\r\n /** Add a new channel to the list of allowed channels of the [[IModelDb]] for this session.\r\n * @param channelKey The key for the channel to become editable in this session.\r\n */\r\n addAllowedChannel(channelKey: ChannelKey): void;\r\n /** Remove a channel from the list of allowed channels of the [[IModelDb]] for this session.\r\n * @param channelKey The key of the channel that should no longer be editable in this session.\r\n */\r\n removeAllowedChannel(channelKey: ChannelKey): void;\r\n /** Get the channelKey of the channel for an element by ElementId.\r\n * @throws if the element does not exist\r\n */\r\n getChannelKey(elementId: Id64String): ChannelKey;\r\n /** Make an existing element a new Channel root.\r\n * @throws if the element is already in a channel different than the shared channel, or if\r\n * there is already another channelRoot element for the specified channelKey\r\n */\r\n makeChannelRoot(args: { elementId: Id64String, channelKey: ChannelKey }): void;\r\n /** Insert a new Subject element that is a Channel Root in this iModel.\r\n * @returns the ElementId of the new Subject element.\r\n * @note if the parentSubject element is already in a channel, this will add the Subject element and then throw an error without making it a Channel root.\r\n */\r\n insertChannelSubject(args: {\r\n /** The name of the new Subject element */\r\n subjectName: string;\r\n /** The channel key for the new [[Subject]]. This is the string to pass to [[addAllowedChannel]]*/\r\n channelKey: ChannelKey;\r\n /** the Id of the parent of the new Subject. Default is [[IModel.rootSubjectId]]. */\r\n parentSubjectId?: Id64String;\r\n /** Optional description for new Subject. */\r\n description?: string;\r\n }): Id64String;\r\n /**\r\n * Queries for the element Id acting as the ChannelRoot for a given channelKey, if any\r\n * @param channelKey The key for the channel to query for\r\n * @returns The element Id of the ChannelRoot element of the specified Channel key, or undefined if\r\n * there is no ChannelRoot for it\r\n */\r\n queryChannelRoot(channelKey: ChannelKey): Id64String | undefined;\r\n\r\n /** @internal */\r\n verifyChannel(modelId: Id64String): void;\r\n}\r\n\r\n/** @beta */\r\nexport namespace ChannelControl {\r\n /** the name of the special \"shared\" channel holding information that is editable by any application. */\r\n export const sharedChannelName = \"shared\";\r\n}\r\n\r\n/** @internal */\r\nexport class ChannelAdmin implements ChannelControl {\r\n public static readonly channelClassName = \"bis:ChannelRootAspect\";\r\n private _allowedChannels = new Set<ChannelKey>();\r\n private _allowedModels = new Set<Id64String>();\r\n private _deniedModels = new Map<Id64String, ChannelKey>();\r\n\r\n public constructor(private _iModel: IModelDb) {\r\n // for backwards compatibility, allow the shared channel unless explicitly turned off in IModelHostOptions.\r\n if (IModelHost.configuration?.allowSharedChannel !== false)\r\n this._allowedChannels.add(ChannelControl.sharedChannelName);\r\n\r\n }\r\n public addAllowedChannel(channelKey: ChannelKey) {\r\n this._allowedChannels.add(channelKey);\r\n this._deniedModels.clear();\r\n }\r\n public removeAllowedChannel(channelKey: ChannelKey) {\r\n this._allowedChannels.delete(channelKey);\r\n this._allowedModels.clear();\r\n }\r\n public getChannelKey(elementId: Id64String): ChannelKey {\r\n if (elementId === IModel.rootSubjectId)\r\n return ChannelControl.sharedChannelName;\r\n\r\n try {\r\n const channel = this._iModel.withPreparedStatement(`SELECT Owner FROM ${ChannelAdmin.channelClassName} WHERE Element.Id=?`, (stmt) => {\r\n stmt.bindId(1, elementId);\r\n return DbResult.BE_SQLITE_ROW === stmt.step() ? stmt.getValue(0).getString() : undefined;\r\n });\r\n if (channel !== undefined)\r\n return channel;\r\n } catch {\r\n // Exception happens if the iModel is too old: ChannelRootAspect class not present in the BisCore schema (older than v1.0.10).\r\n // In that case all data in such iModel is assumed to be in the shared channel.\r\n return ChannelControl.sharedChannelName;\r\n }\r\n const parentId = this._iModel.withPreparedSqliteStatement(\"SELECT ParentId,ModelId FROM bis_Element WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n if (DbResult.BE_SQLITE_ROW !== stmt.step())\r\n throw new IModelError(IModelStatus.NotFound, \"Element does not exist\");\r\n return stmt.getValueId(0) ?? stmt.getValueId(1); // if parent is undefined, use modelId\r\n });\r\n return this.getChannelKey(parentId);\r\n }\r\n public verifyChannel(modelId: Id64String): void {\r\n // Note: indirect changes are permitted to change any channel\r\n if (this._allowedModels.has(modelId) || this._iModel.nativeDb.isIndirectChanges())\r\n return;\r\n\r\n const deniedChannel = this._deniedModels.get(modelId);\r\n if (undefined !== deniedChannel)\r\n throw new IModelError(RepositoryStatus.ChannelConstraintViolation, `channel \"${deniedChannel}\" is not allowed`);\r\n\r\n const channel = this.getChannelKey(modelId);\r\n if (this._allowedChannels.has(channel)) {\r\n this._allowedModels.add(modelId);\r\n return;\r\n }\r\n this._deniedModels.set(modelId, channel);\r\n return this.verifyChannel(modelId);\r\n }\r\n public makeChannelRoot(args: { elementId: Id64String, channelKey: ChannelKey }) {\r\n if (ChannelControl.sharedChannelName !== this.getChannelKey(args.elementId))\r\n throw new Error(\"channels may not nest\");\r\n\r\n if (this.queryChannelRoot(args.channelKey) !== undefined)\r\n throw new Error(\"a channel root for the specified key already exists\");\r\n\r\n const props: ChannelRootAspectProps = { classFullName: ChannelAdmin.channelClassName, element: { id: args.elementId }, owner: args.channelKey };\r\n this._iModel.elements.insertAspect(props);\r\n }\r\n public insertChannelSubject(args: { subjectName: string, channelKey: ChannelKey, parentSubjectId?: Id64String, description?: string }): Id64String {\r\n // Check if channelKey already exists before inserting Subject.\r\n // makeChannelRoot will check that again, but at that point the new Subject is already inserted.\r\n // Prefer to check twice instead of deleting the Subject in the latter option.\r\n if (this.queryChannelRoot(args.channelKey) !== undefined)\r\n throw new Error(\"a channel root for the specified key already exists\");\r\n\r\n const elementId = Subject.insert(this._iModel, args.parentSubjectId ?? IModel.rootSubjectId, args.subjectName, args.description);\r\n this.makeChannelRoot({ elementId, channelKey: args.channelKey });\r\n return elementId;\r\n }\r\n public queryChannelRoot(channelKey: ChannelKey): Id64String | undefined {\r\n if (channelKey === ChannelControl.sharedChannelName)\r\n // RootSubject acts as the ChannelRoot element of the shared channel\r\n return IModel.rootSubjectId;\r\n\r\n try {\r\n const channelRoot = this._iModel.withPreparedStatement(`SELECT Element.Id FROM ${ChannelAdmin.channelClassName} WHERE Owner=?`, (stmt) => {\r\n stmt.bindString(1, channelKey);\r\n return DbResult.BE_SQLITE_ROW === stmt.step() ? stmt.getValue(0).getId() : undefined;\r\n });\r\n return channelRoot;\r\n } catch {\r\n // Exception happens if the iModel is too old: ChannelRootAspect class not present in the BisCore schema (older than v1.0.10).\r\n // In that case all data in such iModel is assumed to be in the shared channel.\r\n return undefined;\r\n }\r\n\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ChannelControl.js","sourceRoot":"","sources":["../../src/ChannelControl.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\n/** @packageDocumentation\r\n * @module Elements\r\n */\r\n\r\nimport { DbResult, Id64String, IModelStatus, RepositoryStatus } from \"@itwin/core-bentley\";\r\nimport { ChannelRootAspectProps, IModel, IModelError } from \"@itwin/core-common\";\r\nimport { Subject } from \"./Element\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { IModelHost } from \"./IModelHost\";\r\n\r\n/** The key for a channel. Used for \"allowed channels\" in [[ChannelControl]]\r\n * @beta\r\n */\r\nexport type ChannelKey = string;\r\n\r\n/**\r\n * Controls which channels of an iModel are permitted for write operations. An implementation of this interface is\r\n * available via [[IModelDb.channels]].\r\n * @see [Working With Channels]($docs/learning/backend/Channel.md) for details\r\n * @beta\r\n */\r\nexport interface ChannelControl {\r\n /** Add a new channel to the list of allowed channels of the [[IModelDb]] for this session.\r\n * @param channelKey The key for the channel to become editable in this session.\r\n */\r\n addAllowedChannel(channelKey: ChannelKey): void;\r\n /** Remove a channel from the list of allowed channels of the [[IModelDb]] for this session.\r\n * @param channelKey The key of the channel that should no longer be editable in this session.\r\n */\r\n removeAllowedChannel(channelKey: ChannelKey): void;\r\n /** Get the channelKey of the channel for an element by ElementId.\r\n * @throws if the element does not exist\r\n */\r\n getChannelKey(elementId: Id64String): ChannelKey;\r\n /** Make an existing element a new Channel root.\r\n * @throws if the element is already in a channel different than the shared channel, or if\r\n * there is already another channelRoot element for the specified channelKey\r\n */\r\n makeChannelRoot(args: { elementId: Id64String, channelKey: ChannelKey }): void;\r\n /** Insert a new Subject element that is a Channel Root in this iModel.\r\n * @returns the ElementId of the new Subject element.\r\n * @note if the parentSubject element is already in a channel, this will add the Subject element and then throw an error without making it a Channel root.\r\n */\r\n insertChannelSubject(args: {\r\n /** The name of the new Subject element */\r\n subjectName: string;\r\n /** The channel key for the new [[Subject]]. This is the string to pass to [[addAllowedChannel]]*/\r\n channelKey: ChannelKey;\r\n /** the Id of the parent of the new Subject. Default is [[IModel.rootSubjectId]]. */\r\n parentSubjectId?: Id64String;\r\n /** Optional description for new Subject. */\r\n description?: string;\r\n }): Id64String;\r\n /**\r\n * Queries for the element Id acting as the ChannelRoot for a given channelKey, if any\r\n * @param channelKey The key for the channel to query for\r\n * @returns The element Id of the ChannelRoot element of the specified Channel key, or undefined if\r\n * there is no ChannelRoot for it\r\n */\r\n queryChannelRoot(channelKey: ChannelKey): Id64String | undefined;\r\n\r\n /** @internal */\r\n verifyChannel(modelId: Id64String): void;\r\n}\r\n\r\n/** @beta */\r\nexport namespace ChannelControl {\r\n /** the name of the special \"shared\" channel holding information that is editable by any application. */\r\n export const sharedChannelName = \"shared\";\r\n}\r\n\r\n/** @internal */\r\nexport class ChannelAdmin implements ChannelControl {\r\n public static readonly channelClassName = \"bis:ChannelRootAspect\";\r\n private _allowedChannels = new Set<ChannelKey>();\r\n private _allowedModels = new Set<Id64String>();\r\n private _deniedModels = new Map<Id64String, ChannelKey>();\r\n\r\n public constructor(private _iModel: IModelDb) {\r\n // for backwards compatibility, allow the shared channel unless explicitly turned off in IModelHostOptions.\r\n if (IModelHost.configuration?.allowSharedChannel !== false)\r\n this._allowedChannels.add(ChannelControl.sharedChannelName);\r\n\r\n }\r\n public addAllowedChannel(channelKey: ChannelKey) {\r\n this._allowedChannels.add(channelKey);\r\n this._deniedModels.clear();\r\n }\r\n public removeAllowedChannel(channelKey: ChannelKey) {\r\n this._allowedChannels.delete(channelKey);\r\n this._allowedModels.clear();\r\n }\r\n public getChannelKey(elementId: Id64String): ChannelKey {\r\n if (elementId === IModel.rootSubjectId)\r\n return ChannelControl.sharedChannelName;\r\n\r\n try {\r\n const channel = this._iModel.withPreparedStatement(`SELECT Owner FROM ${ChannelAdmin.channelClassName} WHERE Element.Id=?`, (stmt) => {\r\n stmt.bindId(1, elementId);\r\n return DbResult.BE_SQLITE_ROW === stmt.step() ? stmt.getValue(0).getString() : undefined;\r\n });\r\n if (channel !== undefined)\r\n return channel;\r\n } catch {\r\n // Exception happens if the iModel is too old: ChannelRootAspect class not present in the BisCore schema (older than v1.0.10).\r\n // In that case all data in such iModel is assumed to be in the shared channel.\r\n return ChannelControl.sharedChannelName;\r\n }\r\n const parentId = this._iModel.withPreparedSqliteStatement(\"SELECT ParentId,ModelId FROM bis_Element WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n if (DbResult.BE_SQLITE_ROW !== stmt.step())\r\n throw new IModelError(IModelStatus.NotFound, \"Element does not exist\");\r\n return stmt.getValueId(0) ?? stmt.getValueId(1); // if parent is undefined, use modelId\r\n });\r\n return this.getChannelKey(parentId);\r\n }\r\n public verifyChannel(modelId: Id64String): void {\r\n // Note: indirect changes are permitted to change any channel\r\n if (this._allowedModels.has(modelId) || this._iModel.nativeDb.isIndirectChanges())\r\n return;\r\n\r\n const deniedChannel = this._deniedModels.get(modelId);\r\n if (undefined !== deniedChannel)\r\n throw new IModelError(RepositoryStatus.ChannelConstraintViolation, `channel \"${deniedChannel}\" is not allowed`);\r\n\r\n const channel = this.getChannelKey(modelId);\r\n if (this._allowedChannels.has(channel)) {\r\n this._allowedModels.add(modelId);\r\n return;\r\n }\r\n this._deniedModels.set(modelId, channel);\r\n return this.verifyChannel(modelId);\r\n }\r\n public makeChannelRoot(args: { elementId: Id64String, channelKey: ChannelKey }) {\r\n if (ChannelControl.sharedChannelName !== this.getChannelKey(args.elementId))\r\n throw new Error(\"channels may not nest\");\r\n\r\n if (this.queryChannelRoot(args.channelKey) !== undefined)\r\n throw new Error(\"a channel root for the specified key already exists\");\r\n\r\n const props: ChannelRootAspectProps = { classFullName: ChannelAdmin.channelClassName, element: { id: args.elementId }, owner: args.channelKey };\r\n this._iModel.elements.insertAspect(props);\r\n }\r\n public insertChannelSubject(args: { subjectName: string, channelKey: ChannelKey, parentSubjectId?: Id64String, description?: string }): Id64String {\r\n // Check if channelKey already exists before inserting Subject.\r\n // makeChannelRoot will check that again, but at that point the new Subject is already inserted.\r\n // Prefer to check twice instead of deleting the Subject in the latter option.\r\n if (this.queryChannelRoot(args.channelKey) !== undefined)\r\n throw new Error(\"a channel root for the specified key already exists\");\r\n\r\n const elementId = Subject.insert(this._iModel, args.parentSubjectId ?? IModel.rootSubjectId, args.subjectName, args.description);\r\n this.makeChannelRoot({ elementId, channelKey: args.channelKey });\r\n return elementId;\r\n }\r\n public queryChannelRoot(channelKey: ChannelKey): Id64String | undefined {\r\n if (channelKey === ChannelControl.sharedChannelName)\r\n // RootSubject acts as the ChannelRoot element of the shared channel\r\n return IModel.rootSubjectId;\r\n\r\n try {\r\n const channelRoot = this._iModel.withPreparedStatement(`SELECT Element.Id FROM ${ChannelAdmin.channelClassName} WHERE Owner=?`, (stmt) => {\r\n stmt.bindString(1, channelKey);\r\n return DbResult.BE_SQLITE_ROW === stmt.step() ? stmt.getValue(0).getId() : undefined;\r\n });\r\n return channelRoot;\r\n } catch {\r\n // Exception happens if the iModel is too old: ChannelRootAspect class not present in the BisCore schema (older than v1.0.10).\r\n // In that case all data in such iModel is assumed to be in the shared channel.\r\n return undefined;\r\n }\r\n\r\n }\r\n}\r\n"]}