UNPKG

@itwin/core-backend

Version:
165 lines • 8.58 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module ChangedElementsDb */ import { DbResult, IModelStatus, OpenMode } from "@itwin/core-bentley"; import { IModelError } from "@itwin/core-common"; import { BriefcaseManager } from "./BriefcaseManager"; import { ECDbOpenMode } from "./ECDb"; import { IModelHost } from "./IModelHost"; import { IModelNative } from "./internal/NativePlatform"; import { _hubAccess, _nativeDb } from "./internal/Symbols"; /** An ChangedElementsDb file * @internal */ export class ChangedElementsDb { _nativeDb; constructor() { this._nativeDb = new IModelNative.platform.ChangedElementsECDb(); } [Symbol.dispose]() { if (!this._nativeDb) return; this.closeDb(); this._nativeDb.dispose(); this._nativeDb = undefined; } /** Create a ChangedElementsDb * @param pathName The path to the ECDb file to create. * @throws [IModelError]($common) if the operation failed. */ _createDb(briefcase, pathName) { const status = this.nativeDb.createDb(briefcase[_nativeDb], pathName); if (status !== DbResult.BE_SQLITE_OK) throw new IModelError(status, "Failed to created ECDb"); } /** Open the Changed Elements Db. * @param pathName The path to the ECDb file to open * @param openMode Open mode * @throws [IModelError]($common) if the operation failed. */ _openDb(pathName, openMode = ECDbOpenMode.Readonly) { const nativeOpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite; const tryUpgrade = openMode === ECDbOpenMode.FileUpgrade; const status = this.nativeDb.openDb(pathName, nativeOpenMode, tryUpgrade); if (status !== DbResult.BE_SQLITE_OK) throw new IModelError(status, "Failed to open ECDb"); } /** Open the Changed Elements Db. * @param pathName The path to the ECDb file to open * @param openMode Open mode * @returns ChangedElementsDb */ static openDb(pathName, openMode = ECDbOpenMode.Readonly) { const cacheDb = new ChangedElementsDb(); cacheDb._openDb(pathName, openMode); return cacheDb; } /** Create the changed elements cache db * @param briefcase IModelDb to use * @param pathName The path to the ECDb file to create. * @returns The new cache db */ static createDb(briefcase, pathName) { const cacheDb = new ChangedElementsDb(); cacheDb._createDb(briefcase, pathName); return cacheDb; } /** Processes a range of changesets and adds it to the changed elements cache * @param briefcase iModel briefcase to use * @param options Options for processing */ async processChangesets(accessToken, briefcase, options) { const iModelId = briefcase.iModelId; const first = (await IModelHost[_hubAccess].queryChangeset({ iModelId, changeset: { id: options.startChangesetId }, accessToken })).index; const end = (await IModelHost[_hubAccess].queryChangeset({ iModelId, changeset: { id: options.endChangesetId }, accessToken })).index; const changesets = await IModelHost[_hubAccess].downloadChangesets({ accessToken, iModelId, range: { first, end }, targetDir: BriefcaseManager.getChangeSetsPath(iModelId) }); // ChangeSets need to be processed from newest to oldest changesets.reverse(); const status = this.nativeDb.processChangesets(briefcase[_nativeDb], changesets, options.rulesetId, options.filterSpatial, options.wantParents, options.wantPropertyChecksums, options.rulesetDir, options.tempDir, options.wantChunkTraversal); if (status !== DbResult.BE_SQLITE_OK) throw new IModelError(status, "Failed to process changesets"); return status; } /** Processes a range of changesets and adds it to the changed elements cache * This call will close the IModelDb object as it is required for processing and applying changesets * @param briefcase iModel briefcase to use * @param options options for processing */ async processChangesetsAndRoll(accessToken, briefcase, options) { const iModelId = briefcase.iModelId; const first = (await IModelHost[_hubAccess].queryChangeset({ iModelId, changeset: { id: options.startChangesetId }, accessToken })).index; const end = (await IModelHost[_hubAccess].queryChangeset({ iModelId, changeset: { id: options.endChangesetId }, accessToken })).index; const changesets = await IModelHost[_hubAccess].downloadChangesets({ accessToken, iModelId, range: { first, end }, targetDir: BriefcaseManager.getChangeSetsPath(iModelId) }); // ChangeSets need to be processed from newest to oldest changesets.reverse(); // Close briefcase before doing processing and rolling briefcase const dbFilename = briefcase.pathName; const dbGuid = briefcase.iModelId; briefcase.close(); // Process changesets const status = this.nativeDb.processChangesetsAndRoll(dbFilename, dbGuid, changesets, options.rulesetId, options.filterSpatial, options.wantParents, options.wantPropertyChecksums, options.rulesetDir, options.tempDir, options.wantRelationshipCaching, options.relationshipCacheSize, options.wantChunkTraversal, options.wantBoundingBoxes); if (status !== DbResult.BE_SQLITE_OK) throw new IModelError(status, "Failed to process changesets"); return status; } /** Get changed elements between two changesets * @param startChangesetId Start Changeset Id * @param endChangesetId End Changeset Id * @returns Returns the changed elements between the changesets provided * @throws [IModelError]($common) if the operation failed. */ getChangedElements(startChangesetId, endChangesetId) { const result = this.nativeDb.getChangedElements(startChangesetId, endChangesetId); if (result.error || !result.result) throw new IModelError(result.error ? result.error.status : -1, result.error ? result.error.message : "Problem getting changed elements"); return (result.result.changedElements); } /** Get changed models between two changesets * @param startChangesetId Start Changeset Id * @param endChangesetId End Changeset Id * @returns Returns the changed models between the changesets provided * @throws [IModelError]($common) if the operation failed. */ getChangedModels(startChangesetId, endChangesetId) { const result = this.nativeDb.getChangedElements(startChangesetId, endChangesetId); if (result.error || !result.result) throw new IModelError(result.error ? result.error.status : -1, result.error ? result.error.message : "Problem getting changed models"); return (result.result.changedModels); } /** Get changed models between two changesets * @param startChangesetId Start Changeset Id * @param endChangesetId End Changeset Id * @returns Returns the changed models between the changesets provided * @throws [IModelError]($common) if the operation failed. */ getChangeData(startChangesetId, endChangesetId) { const result = this.nativeDb.getChangedElements(startChangesetId, endChangesetId); if (result.error) throw new IModelError(result.error.status, result.error.message); return result.result; } /** Returns true if the Changed Elements Db is open */ get isOpen() { return this.nativeDb.isOpen(); } /** Returns true if the cache already contains this changeset Id */ isProcessed(changesetId) { return this.nativeDb.isProcessed(changesetId); } /** Close the Db after saving any uncommitted changes. * @throws [IModelError]($common) if the database is not open. */ closeDb() { this.nativeDb.closeDb(); } cleanCaches() { this.nativeDb.cleanCaches(); } /** @internal */ get nativeDb() { if (!this._nativeDb) throw new IModelError(IModelStatus.BadRequest, "ChangedElementsDb object has already been disposed."); return this._nativeDb; } } //# sourceMappingURL=ChangedElementsDb.js.map