@itwin/core-backend 3.0.0-dev.100
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.
- package/CHANGELOG.md +1525 -0
- package/LICENSE.md +9 -0
- package/README.md +11 -0
- package/lib/cjs/AliCloudStorageService.d.ts +12 -0
- package/lib/cjs/AliCloudStorageService.d.ts.map +1 -0
- package/lib/cjs/AliCloudStorageService.js +70 -0
- package/lib/cjs/AliCloudStorageService.js.map +1 -0
- package/lib/cjs/BackendHubAccess.d.ts +208 -0
- package/lib/cjs/BackendHubAccess.d.ts.map +1 -0
- package/lib/cjs/BackendHubAccess.js +42 -0
- package/lib/cjs/BackendHubAccess.js.map +1 -0
- package/lib/cjs/BackendLoggerCategory.d.ts +83 -0
- package/lib/cjs/BackendLoggerCategory.d.ts.map +1 -0
- package/lib/cjs/BackendLoggerCategory.js +91 -0
- package/lib/cjs/BackendLoggerCategory.js.map +1 -0
- package/lib/cjs/BisCoreSchema.d.ts +22 -0
- package/lib/cjs/BisCoreSchema.d.ts.map +1 -0
- package/lib/cjs/BisCoreSchema.js +61 -0
- package/lib/cjs/BisCoreSchema.js.map +1 -0
- package/lib/cjs/BriefcaseManager.d.ts +167 -0
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -0
- package/lib/cjs/BriefcaseManager.js +406 -0
- package/lib/cjs/BriefcaseManager.js.map +1 -0
- package/lib/cjs/Category.d.ts +154 -0
- package/lib/cjs/Category.d.ts.map +1 -0
- package/lib/cjs/Category.js +244 -0
- package/lib/cjs/Category.js.map +1 -0
- package/lib/cjs/ChangeSummaryManager.d.ts +188 -0
- package/lib/cjs/ChangeSummaryManager.d.ts.map +1 -0
- package/lib/cjs/ChangeSummaryManager.js +444 -0
- package/lib/cjs/ChangeSummaryManager.js.map +1 -0
- package/lib/cjs/ChangedElementsDb.d.ts +97 -0
- package/lib/cjs/ChangedElementsDb.d.ts.map +1 -0
- package/lib/cjs/ChangedElementsDb.js +166 -0
- package/lib/cjs/ChangedElementsDb.js.map +1 -0
- package/lib/cjs/ChangedElementsManager.d.ts +40 -0
- package/lib/cjs/ChangedElementsManager.d.ts.map +1 -0
- package/lib/cjs/ChangedElementsManager.js +89 -0
- package/lib/cjs/ChangedElementsManager.js.map +1 -0
- package/lib/cjs/CheckpointManager.d.ts +101 -0
- package/lib/cjs/CheckpointManager.d.ts.map +1 -0
- package/lib/cjs/CheckpointManager.js +257 -0
- package/lib/cjs/CheckpointManager.js.map +1 -0
- package/lib/cjs/ClassRegistry.d.ts +72 -0
- package/lib/cjs/ClassRegistry.d.ts.map +1 -0
- package/lib/cjs/ClassRegistry.js +154 -0
- package/lib/cjs/ClassRegistry.js.map +1 -0
- package/lib/cjs/CloudStorageBackend.d.ts +46 -0
- package/lib/cjs/CloudStorageBackend.d.ts.map +1 -0
- package/lib/cjs/CloudStorageBackend.js +157 -0
- package/lib/cjs/CloudStorageBackend.js.map +1 -0
- package/lib/cjs/CodeSpecs.d.ts +51 -0
- package/lib/cjs/CodeSpecs.d.ts.map +1 -0
- package/lib/cjs/CodeSpecs.js +113 -0
- package/lib/cjs/CodeSpecs.js.map +1 -0
- package/lib/cjs/ConcurrentQuery.d.ts +12 -0
- package/lib/cjs/ConcurrentQuery.d.ts.map +1 -0
- package/lib/cjs/ConcurrentQuery.js +24 -0
- package/lib/cjs/ConcurrentQuery.js.map +1 -0
- package/lib/cjs/DevTools.d.ts +72 -0
- package/lib/cjs/DevTools.d.ts.map +1 -0
- package/lib/cjs/DevTools.js +155 -0
- package/lib/cjs/DevTools.js.map +1 -0
- package/lib/cjs/DisplayStyle.d.ts +107 -0
- package/lib/cjs/DisplayStyle.d.ts.map +1 -0
- package/lib/cjs/DisplayStyle.js +292 -0
- package/lib/cjs/DisplayStyle.js.map +1 -0
- package/lib/cjs/ECDb.d.ts +196 -0
- package/lib/cjs/ECDb.d.ts.map +1 -0
- package/lib/cjs/ECDb.js +354 -0
- package/lib/cjs/ECDb.js.map +1 -0
- package/lib/cjs/ECSchemaXmlContext.d.ts +18 -0
- package/lib/cjs/ECSchemaXmlContext.d.ts.map +1 -0
- package/lib/cjs/ECSchemaXmlContext.js +36 -0
- package/lib/cjs/ECSchemaXmlContext.js.map +1 -0
- package/lib/cjs/ECSqlStatement.d.ts +467 -0
- package/lib/cjs/ECSqlStatement.d.ts.map +1 -0
- package/lib/cjs/ECSqlStatement.js +783 -0
- package/lib/cjs/ECSqlStatement.js.map +1 -0
- package/lib/cjs/Element.d.ts +1082 -0
- package/lib/cjs/Element.d.ts.map +1 -0
- package/lib/cjs/Element.js +1392 -0
- package/lib/cjs/Element.js.map +1 -0
- package/lib/cjs/ElementAspect.d.ts +157 -0
- package/lib/cjs/ElementAspect.d.ts.map +1 -0
- package/lib/cjs/ElementAspect.js +179 -0
- package/lib/cjs/ElementAspect.js.map +1 -0
- package/lib/cjs/ElementGraphics.d.ts +10 -0
- package/lib/cjs/ElementGraphics.d.ts.map +1 -0
- package/lib/cjs/ElementGraphics.js +42 -0
- package/lib/cjs/ElementGraphics.js.map +1 -0
- package/lib/cjs/Entity.d.ts +57 -0
- package/lib/cjs/Entity.d.ts.map +1 -0
- package/lib/cjs/Entity.js +63 -0
- package/lib/cjs/Entity.js.map +1 -0
- package/lib/cjs/ExportGraphics.d.ts +302 -0
- package/lib/cjs/ExportGraphics.d.ts.map +1 -0
- package/lib/cjs/ExportGraphics.js +206 -0
- package/lib/cjs/ExportGraphics.js.map +1 -0
- package/lib/cjs/ExternalSource.d.ts +95 -0
- package/lib/cjs/ExternalSource.d.ts.map +1 -0
- package/lib/cjs/ExternalSource.js +126 -0
- package/lib/cjs/ExternalSource.js.map +1 -0
- package/lib/cjs/GeometrySummary.d.ts +5 -0
- package/lib/cjs/GeometrySummary.d.ts.map +1 -0
- package/lib/cjs/GeometrySummary.js +378 -0
- package/lib/cjs/GeometrySummary.js.map +1 -0
- package/lib/cjs/IModelCloneContext.d.ts +74 -0
- package/lib/cjs/IModelCloneContext.d.ts.map +1 -0
- package/lib/cjs/IModelCloneContext.js +130 -0
- package/lib/cjs/IModelCloneContext.js.map +1 -0
- package/lib/cjs/IModelDb.d.ts +1107 -0
- package/lib/cjs/IModelDb.d.ts.map +1 -0
- package/lib/cjs/IModelDb.js +2161 -0
- package/lib/cjs/IModelDb.js.map +1 -0
- package/lib/cjs/IModelHost.d.ts +284 -0
- package/lib/cjs/IModelHost.d.ts.map +1 -0
- package/lib/cjs/IModelHost.js +411 -0
- package/lib/cjs/IModelHost.js.map +1 -0
- package/lib/cjs/IModelJsFs.d.ts +63 -0
- package/lib/cjs/IModelJsFs.d.ts.map +1 -0
- package/lib/cjs/IModelJsFs.js +141 -0
- package/lib/cjs/IModelJsFs.js.map +1 -0
- package/lib/cjs/IModelSchemaLoader.d.ts +26 -0
- package/lib/cjs/IModelSchemaLoader.d.ts.map +1 -0
- package/lib/cjs/IModelSchemaLoader.js +95 -0
- package/lib/cjs/IModelSchemaLoader.js.map +1 -0
- package/lib/cjs/IpcHost.d.ts +99 -0
- package/lib/cjs/IpcHost.d.ts.map +1 -0
- package/lib/cjs/IpcHost.js +234 -0
- package/lib/cjs/IpcHost.js.map +1 -0
- package/lib/cjs/LineStyle.d.ts +312 -0
- package/lib/cjs/LineStyle.d.ts.map +1 -0
- package/lib/cjs/LineStyle.js +296 -0
- package/lib/cjs/LineStyle.js.map +1 -0
- package/lib/cjs/LocalhostIpcHost.d.ts +19 -0
- package/lib/cjs/LocalhostIpcHost.d.ts.map +1 -0
- package/lib/cjs/LocalhostIpcHost.js +52 -0
- package/lib/cjs/LocalhostIpcHost.js.map +1 -0
- package/lib/cjs/Material.d.ts +102 -0
- package/lib/cjs/Material.d.ts.map +1 -0
- package/lib/cjs/Material.js +146 -0
- package/lib/cjs/Material.js.map +1 -0
- package/lib/cjs/Model.d.ts +387 -0
- package/lib/cjs/Model.d.ts.map +1 -0
- package/lib/cjs/Model.js +469 -0
- package/lib/cjs/Model.js.map +1 -0
- package/lib/cjs/NativeAppStorage.d.ts +52 -0
- package/lib/cjs/NativeAppStorage.d.ts.map +1 -0
- package/lib/cjs/NativeAppStorage.js +203 -0
- package/lib/cjs/NativeAppStorage.js.map +1 -0
- package/lib/cjs/NativeHost.d.ts +71 -0
- package/lib/cjs/NativeHost.d.ts.map +1 -0
- package/lib/cjs/NativeHost.js +221 -0
- package/lib/cjs/NativeHost.js.map +1 -0
- package/lib/cjs/NavigationRelationship.d.ts +157 -0
- package/lib/cjs/NavigationRelationship.d.ts.map +1 -0
- package/lib/cjs/NavigationRelationship.js +226 -0
- package/lib/cjs/NavigationRelationship.js.map +1 -0
- package/lib/cjs/PromiseMemoizer.d.ts +52 -0
- package/lib/cjs/PromiseMemoizer.d.ts.map +1 -0
- package/lib/cjs/PromiseMemoizer.js +93 -0
- package/lib/cjs/PromiseMemoizer.js.map +1 -0
- package/lib/cjs/Relationship.d.ts +400 -0
- package/lib/cjs/Relationship.d.ts.map +1 -0
- package/lib/cjs/Relationship.js +460 -0
- package/lib/cjs/Relationship.js.map +1 -0
- package/lib/cjs/RpcBackend.d.ts +23 -0
- package/lib/cjs/RpcBackend.d.ts.map +1 -0
- package/lib/cjs/RpcBackend.js +94 -0
- package/lib/cjs/RpcBackend.js.map +1 -0
- package/lib/cjs/SQLiteDb.d.ts +66 -0
- package/lib/cjs/SQLiteDb.d.ts.map +1 -0
- package/lib/cjs/SQLiteDb.js +140 -0
- package/lib/cjs/SQLiteDb.js.map +1 -0
- package/lib/cjs/Schema.d.ts +56 -0
- package/lib/cjs/Schema.d.ts.map +1 -0
- package/lib/cjs/Schema.js +84 -0
- package/lib/cjs/Schema.js.map +1 -0
- package/lib/cjs/ServerBasedLocks.d.ts +64 -0
- package/lib/cjs/ServerBasedLocks.d.ts.map +1 -0
- package/lib/cjs/ServerBasedLocks.js +177 -0
- package/lib/cjs/ServerBasedLocks.js.map +1 -0
- package/lib/cjs/SqliteStatement.d.ts +264 -0
- package/lib/cjs/SqliteStatement.d.ts.map +1 -0
- package/lib/cjs/SqliteStatement.js +417 -0
- package/lib/cjs/SqliteStatement.js.map +1 -0
- package/lib/cjs/Texture.d.ts +59 -0
- package/lib/cjs/Texture.d.ts.map +1 -0
- package/lib/cjs/Texture.js +83 -0
- package/lib/cjs/Texture.js.map +1 -0
- package/lib/cjs/TxnManager.d.ts +203 -0
- package/lib/cjs/TxnManager.d.ts.map +1 -0
- package/lib/cjs/TxnManager.js +354 -0
- package/lib/cjs/TxnManager.js.map +1 -0
- package/lib/cjs/ViewDefinition.d.ts +432 -0
- package/lib/cjs/ViewDefinition.d.ts.map +1 -0
- package/lib/cjs/ViewDefinition.js +623 -0
- package/lib/cjs/ViewDefinition.js.map +1 -0
- package/lib/cjs/assets/IModelChange.02.00.00.ecschema.xml +90 -0
- package/lib/cjs/core-backend.d.ts +162 -0
- package/lib/cjs/core-backend.d.ts.map +1 -0
- package/lib/cjs/core-backend.js +181 -0
- package/lib/cjs/core-backend.js.map +1 -0
- package/lib/cjs/domains/FunctionalElements.d.ts +102 -0
- package/lib/cjs/domains/FunctionalElements.d.ts.map +1 -0
- package/lib/cjs/domains/FunctionalElements.js +146 -0
- package/lib/cjs/domains/FunctionalElements.js.map +1 -0
- package/lib/cjs/domains/FunctionalSchema.d.ts +14 -0
- package/lib/cjs/domains/FunctionalSchema.d.ts.map +1 -0
- package/lib/cjs/domains/FunctionalSchema.js +41 -0
- package/lib/cjs/domains/FunctionalSchema.js.map +1 -0
- package/lib/cjs/domains/GenericElements.d.ts +178 -0
- package/lib/cjs/domains/GenericElements.d.ts.map +1 -0
- package/lib/cjs/domains/GenericElements.js +264 -0
- package/lib/cjs/domains/GenericElements.js.map +1 -0
- package/lib/cjs/domains/GenericSchema.d.ts +11 -0
- package/lib/cjs/domains/GenericSchema.d.ts.map +1 -0
- package/lib/cjs/domains/GenericSchema.js +29 -0
- package/lib/cjs/domains/GenericSchema.js.map +1 -0
- package/lib/cjs/rpc-impl/DevToolsRpcImpl.d.ts +16 -0
- package/lib/cjs/rpc-impl/DevToolsRpcImpl.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/DevToolsRpcImpl.js +33 -0
- package/lib/cjs/rpc-impl/DevToolsRpcImpl.js.map +1 -0
- package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts +40 -0
- package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/IModelReadRpcImpl.js +207 -0
- package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -0
- package/lib/cjs/rpc-impl/IModelTileRpcImpl.d.ts +21 -0
- package/lib/cjs/rpc-impl/IModelTileRpcImpl.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/IModelTileRpcImpl.js +193 -0
- package/lib/cjs/rpc-impl/IModelTileRpcImpl.js.map +1 -0
- package/lib/cjs/rpc-impl/RpcBriefcaseUtility.d.ts +37 -0
- package/lib/cjs/rpc-impl/RpcBriefcaseUtility.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js +162 -0
- package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js.map +1 -0
- package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.d.ts +17 -0
- package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js +44 -0
- package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -0
- package/lib/cjs/rpc-impl/WipRpcImpl.d.ts +16 -0
- package/lib/cjs/rpc-impl/WipRpcImpl.d.ts.map +1 -0
- package/lib/cjs/rpc-impl/WipRpcImpl.js +35 -0
- package/lib/cjs/rpc-impl/WipRpcImpl.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module iModels
|
|
3
|
+
*/
|
|
4
|
+
import { BeEvent, GuidString } from "@itwin/core-bentley";
|
|
5
|
+
import { ChangesetId, ChangesetIdWithIndex, LocalDirName, LocalFileName } from "@itwin/core-common";
|
|
6
|
+
import { IModelJsNative } from "@bentley/imodeljs-native";
|
|
7
|
+
import { SnapshotDb, TokenArg } from "./IModelDb";
|
|
8
|
+
/**
|
|
9
|
+
* Properties of a checkpoint
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export interface CheckpointProps extends TokenArg {
|
|
13
|
+
readonly expectV2?: boolean;
|
|
14
|
+
/** iTwin that the iModel belongs to */
|
|
15
|
+
readonly iTwinId: GuidString;
|
|
16
|
+
/** Id of the iModel */
|
|
17
|
+
readonly iModelId: GuidString;
|
|
18
|
+
/** changeset for the checkpoint */
|
|
19
|
+
readonly changeset: ChangesetIdWithIndex;
|
|
20
|
+
/** The number of seconds before the current token expires to attempt to reacquire a new token. Default is 1 hour. */
|
|
21
|
+
readonly reattachSafetySeconds?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Called to show progress during a download. If this function returns non-zero, the download is aborted.
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export declare type ProgressFunction = (loaded: number, total: number) => number;
|
|
27
|
+
/** The parameters that specify a request to download a checkpoint file from iModelHub.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export interface DownloadRequest {
|
|
31
|
+
/** name of local file to hold the downloaded data. */
|
|
32
|
+
localFile: LocalFileName;
|
|
33
|
+
/** A list of full fileName paths to test before downloading. If a valid file exists by one of these names,
|
|
34
|
+
* no download is performed and `localFile` is updated to reflect the fact that the file exists with that name.
|
|
35
|
+
* This can be used, for example, to look for checkpoints from previous versions if the naming strategy changes.
|
|
36
|
+
*/
|
|
37
|
+
readonly aliasFiles?: ReadonlyArray<string>;
|
|
38
|
+
/** Properties of the checkpoint to be downloaded */
|
|
39
|
+
readonly checkpoint: CheckpointProps;
|
|
40
|
+
/** If present, this function will be called to indicate progress as the briefcase is downloaded. If this
|
|
41
|
+
* function returns a non-zero value, the download is aborted.
|
|
42
|
+
*/
|
|
43
|
+
readonly onProgress?: ProgressFunction;
|
|
44
|
+
}
|
|
45
|
+
/** @internal */
|
|
46
|
+
export interface DownloadJob {
|
|
47
|
+
request: DownloadRequest;
|
|
48
|
+
promise?: Promise<any>;
|
|
49
|
+
}
|
|
50
|
+
/** @internal */
|
|
51
|
+
export declare class Downloads {
|
|
52
|
+
private static _active;
|
|
53
|
+
private static process;
|
|
54
|
+
static isInProgress(pathName: LocalFileName): DownloadJob | undefined;
|
|
55
|
+
static download<T>(request: DownloadRequest, downloadFn: (job: DownloadJob) => Promise<T>): Promise<any>;
|
|
56
|
+
}
|
|
57
|
+
/** Utility class for attaching to Daemon, opening V2 checkpoints, and downloading them.
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export declare class V2CheckpointManager {
|
|
61
|
+
private static getCommandArgs;
|
|
62
|
+
static attach(checkpoint: CheckpointProps): Promise<{
|
|
63
|
+
filePath: LocalFileName;
|
|
64
|
+
expiryTimestamp: number;
|
|
65
|
+
}>;
|
|
66
|
+
private static performDownload;
|
|
67
|
+
/** Fully download a V2 checkpoint to a local file that can be used to create a briefcase or to work offline.
|
|
68
|
+
* @returns a Promise that is resolved when the download completes with the changesetId of the downloaded checkpoint (which will
|
|
69
|
+
* be the same as the requested changesetId or the most recent checkpoint before it.)
|
|
70
|
+
*/
|
|
71
|
+
static downloadCheckpoint(request: DownloadRequest): Promise<ChangesetId>;
|
|
72
|
+
}
|
|
73
|
+
/** Utility class to deal with downloading V1 checkpoints from iModelHub.
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
export declare class V1CheckpointManager {
|
|
77
|
+
static getFolder(iModelId: GuidString): LocalDirName;
|
|
78
|
+
static getFileName(checkpoint: CheckpointProps): LocalFileName;
|
|
79
|
+
static getCheckpointDb(request: DownloadRequest): Promise<SnapshotDb>;
|
|
80
|
+
/** Download a V1 checkpoint */
|
|
81
|
+
static downloadCheckpoint(request: DownloadRequest): Promise<ChangesetId>;
|
|
82
|
+
private static downloadAndOpen;
|
|
83
|
+
private static performDownload;
|
|
84
|
+
}
|
|
85
|
+
/** @internal */
|
|
86
|
+
export declare class CheckpointManager {
|
|
87
|
+
static readonly onDownloadV1: BeEvent<(job: DownloadJob) => void>;
|
|
88
|
+
static readonly onDownloadV2: BeEvent<(job: DownloadJob) => void>;
|
|
89
|
+
static getKey(checkpoint: CheckpointProps): string;
|
|
90
|
+
private static doDownload;
|
|
91
|
+
static updateToRequestedVersion(request: DownloadRequest): Promise<void>;
|
|
92
|
+
/** Download a checkpoint file from iModelHub into a local file specified in the request parameters. */
|
|
93
|
+
static downloadCheckpoint(request: DownloadRequest): Promise<void>;
|
|
94
|
+
/** checks a file's dbGuid & iTwinId for consistency, and updates the dbGuid when possible */
|
|
95
|
+
static validateCheckpointGuids(checkpoint: CheckpointProps, nativeDb: IModelJsNative.DgnDb): void;
|
|
96
|
+
/** @returns true if the file is the checkpoint requested */
|
|
97
|
+
static verifyCheckpoint(checkpoint: CheckpointProps, fileName: LocalFileName): boolean;
|
|
98
|
+
/** try to open an existing local file to satisfy a download request */
|
|
99
|
+
static tryOpenLocalFile(request: DownloadRequest): SnapshotDb | undefined;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=CheckpointManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckpointManager.d.ts","sourceRoot":"","sources":["../../src/CheckpointManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
/** @packageDocumentation
|
|
7
|
+
* @module iModels
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CheckpointManager = exports.V1CheckpointManager = exports.V2CheckpointManager = exports.Downloads = void 0;
|
|
11
|
+
// cspell:ignore BLOCKCACHE
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
14
|
+
const core_common_1 = require("@itwin/core-common");
|
|
15
|
+
const imodeljs_native_1 = require("@bentley/imodeljs-native");
|
|
16
|
+
const BackendLoggerCategory_1 = require("./BackendLoggerCategory");
|
|
17
|
+
const BriefcaseManager_1 = require("./BriefcaseManager");
|
|
18
|
+
const IModelDb_1 = require("./IModelDb");
|
|
19
|
+
const IModelHost_1 = require("./IModelHost");
|
|
20
|
+
const IModelJsFs_1 = require("./IModelJsFs");
|
|
21
|
+
const loggerCategory = BackendLoggerCategory_1.BackendLoggerCategory.IModelDb;
|
|
22
|
+
/** @internal */
|
|
23
|
+
class Downloads {
|
|
24
|
+
static async process(job, fn) {
|
|
25
|
+
const jobName = job.request.localFile; // save this, it can change inside call to `fn`!
|
|
26
|
+
this._active.set(jobName, job);
|
|
27
|
+
try {
|
|
28
|
+
return await fn(job);
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
this._active.delete(jobName);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
static isInProgress(pathName) {
|
|
35
|
+
return this._active.get(pathName);
|
|
36
|
+
}
|
|
37
|
+
static async download(request, downloadFn) {
|
|
38
|
+
const pathName = request.localFile;
|
|
39
|
+
let job = this.isInProgress(pathName);
|
|
40
|
+
if (undefined !== job)
|
|
41
|
+
return job.promise;
|
|
42
|
+
IModelJsFs_1.IModelJsFs.recursiveMkDirSync(path.dirname(pathName));
|
|
43
|
+
job = { request };
|
|
44
|
+
return job.promise = this.process(job, downloadFn);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.Downloads = Downloads;
|
|
48
|
+
Downloads._active = new Map();
|
|
49
|
+
/** Utility class for attaching to Daemon, opening V2 checkpoints, and downloading them.
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
class V2CheckpointManager {
|
|
53
|
+
static async getCommandArgs(checkpoint) {
|
|
54
|
+
try {
|
|
55
|
+
const v2props = await IModelHost_1.IModelHost.hubAccess.queryV2Checkpoint(checkpoint);
|
|
56
|
+
if (!v2props)
|
|
57
|
+
throw new Error("no checkpoint");
|
|
58
|
+
return { ...v2props, daemonDir: process.env.BLOCKCACHE_DIR, writeable: false };
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `V2 checkpoint not found: err: ${err.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
static async attach(checkpoint) {
|
|
65
|
+
const args = await this.getCommandArgs(checkpoint);
|
|
66
|
+
if (undefined === args.daemonDir || args.daemonDir === "")
|
|
67
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Invalid config: BLOCKCACHE_DIR is not set");
|
|
68
|
+
// We can assume that a BCVDaemon process is already started if BLOCKCACHE_DIR was set, so we need to just tell the daemon to attach to the Storage Container
|
|
69
|
+
const attachResult = await imodeljs_native_1.BlobDaemon.command("attach", args);
|
|
70
|
+
if (attachResult.result !== core_bentley_1.DbResult.BE_SQLITE_OK) {
|
|
71
|
+
const error = `Daemon attach failed: ${attachResult.errMsg}`;
|
|
72
|
+
if (checkpoint.expectV2)
|
|
73
|
+
core_bentley_1.Logger.logError(loggerCategory, error);
|
|
74
|
+
throw new core_common_1.IModelError(attachResult.result, error);
|
|
75
|
+
}
|
|
76
|
+
const sasTokenExpiry = new URLSearchParams(args.auth).get("se");
|
|
77
|
+
return { filePath: imodeljs_native_1.BlobDaemon.getDbFileName(args), expiryTimestamp: sasTokenExpiry ? Date.parse(sasTokenExpiry) : 0 };
|
|
78
|
+
}
|
|
79
|
+
static async performDownload(job) {
|
|
80
|
+
CheckpointManager.onDownloadV2.raiseEvent(job);
|
|
81
|
+
return IModelHost_1.IModelHost.hubAccess.downloadV2Checkpoint(job.request);
|
|
82
|
+
}
|
|
83
|
+
/** Fully download a V2 checkpoint to a local file that can be used to create a briefcase or to work offline.
|
|
84
|
+
* @returns a Promise that is resolved when the download completes with the changesetId of the downloaded checkpoint (which will
|
|
85
|
+
* be the same as the requested changesetId or the most recent checkpoint before it.)
|
|
86
|
+
*/
|
|
87
|
+
static async downloadCheckpoint(request) {
|
|
88
|
+
return Downloads.download(request, async (job) => this.performDownload(job));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.V2CheckpointManager = V2CheckpointManager;
|
|
92
|
+
/** Utility class to deal with downloading V1 checkpoints from iModelHub.
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
class V1CheckpointManager {
|
|
96
|
+
static getFolder(iModelId) {
|
|
97
|
+
return path.join(BriefcaseManager_1.BriefcaseManager.getIModelPath(iModelId), "checkpoints");
|
|
98
|
+
}
|
|
99
|
+
static getFileName(checkpoint) {
|
|
100
|
+
const changesetId = checkpoint.changeset.id || "first";
|
|
101
|
+
return path.join(this.getFolder(checkpoint.iModelId), `${changesetId}.bim`);
|
|
102
|
+
}
|
|
103
|
+
static async getCheckpointDb(request) {
|
|
104
|
+
const db = IModelDb_1.SnapshotDb.tryFindByKey(CheckpointManager.getKey(request.checkpoint));
|
|
105
|
+
return (undefined !== db) ? db : Downloads.download(request, async (job) => this.downloadAndOpen(job));
|
|
106
|
+
}
|
|
107
|
+
/** Download a V1 checkpoint */
|
|
108
|
+
static async downloadCheckpoint(request) {
|
|
109
|
+
return Downloads.download(request, async (job) => this.performDownload(job));
|
|
110
|
+
}
|
|
111
|
+
static async downloadAndOpen(job) {
|
|
112
|
+
const db = CheckpointManager.tryOpenLocalFile(job.request);
|
|
113
|
+
if (db)
|
|
114
|
+
return db;
|
|
115
|
+
await this.performDownload(job);
|
|
116
|
+
await CheckpointManager.updateToRequestedVersion(job.request);
|
|
117
|
+
return IModelDb_1.SnapshotDb.openCheckpointV1(job.request.localFile, job.request.checkpoint);
|
|
118
|
+
}
|
|
119
|
+
static async performDownload(job) {
|
|
120
|
+
CheckpointManager.onDownloadV1.raiseEvent(job);
|
|
121
|
+
return IModelHost_1.IModelHost.hubAccess.downloadV1Checkpoint(job.request);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.V1CheckpointManager = V1CheckpointManager;
|
|
125
|
+
/** @internal */
|
|
126
|
+
class CheckpointManager {
|
|
127
|
+
static getKey(checkpoint) { return `${checkpoint.iModelId}:${checkpoint.changeset.id}`; }
|
|
128
|
+
static async doDownload(request) {
|
|
129
|
+
try {
|
|
130
|
+
// first see if there's a V2 checkpoint available.
|
|
131
|
+
const changesetId = await V2CheckpointManager.downloadCheckpoint(request);
|
|
132
|
+
core_bentley_1.Logger.logInfo(loggerCategory, `Downloaded v2 checkpoint: IModel=${request.checkpoint.iModelId}, changeset=${request.checkpoint.changeset.id}`);
|
|
133
|
+
return changesetId;
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error instanceof core_common_1.IModelError && error.errorNumber === core_bentley_1.IModelStatus.NotFound) // No V2 checkpoint available, try a v1 checkpoint
|
|
137
|
+
return V1CheckpointManager.downloadCheckpoint(request);
|
|
138
|
+
throw (error); // most likely, was aborted
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
static async updateToRequestedVersion(request) {
|
|
142
|
+
var _a;
|
|
143
|
+
const checkpoint = request.checkpoint;
|
|
144
|
+
const targetFile = request.localFile;
|
|
145
|
+
const traceInfo = { iTwinId: checkpoint.iTwinId, iModelId: checkpoint.iModelId, changeset: checkpoint.changeset };
|
|
146
|
+
try {
|
|
147
|
+
// Open checkpoint for write
|
|
148
|
+
const db = IModelDb_1.SnapshotDb.openForApplyChangesets(targetFile);
|
|
149
|
+
const nativeDb = db.nativeDb;
|
|
150
|
+
try {
|
|
151
|
+
if (nativeDb.hasPendingTxns()) {
|
|
152
|
+
core_bentley_1.Logger.logWarning(loggerCategory, "Checkpoint with Txns found - deleting them", () => traceInfo);
|
|
153
|
+
nativeDb.deleteAllTxns();
|
|
154
|
+
}
|
|
155
|
+
if (nativeDb.getBriefcaseId() !== core_common_1.BriefcaseIdValue.Unassigned)
|
|
156
|
+
nativeDb.resetBriefcaseId(core_common_1.BriefcaseIdValue.Unassigned);
|
|
157
|
+
CheckpointManager.validateCheckpointGuids(checkpoint, nativeDb);
|
|
158
|
+
// Apply change sets if necessary
|
|
159
|
+
const currentChangeset = nativeDb.getCurrentChangeset();
|
|
160
|
+
if (currentChangeset.id !== checkpoint.changeset.id) {
|
|
161
|
+
const accessToken = checkpoint.accessToken;
|
|
162
|
+
const toIndex = (_a = checkpoint.changeset.index) !== null && _a !== void 0 ? _a : (await IModelHost_1.IModelHost.hubAccess.getChangesetFromVersion({ accessToken, iModelId: checkpoint.iModelId, version: core_common_1.IModelVersion.asOfChangeSet(checkpoint.changeset.id) })).index;
|
|
163
|
+
await BriefcaseManager_1.BriefcaseManager.pullAndApplyChangesets(db, { accessToken, toIndex });
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// make sure the parent changeset index is saved in the file - old versions didn't have it.
|
|
167
|
+
currentChangeset.index = checkpoint.changeset.index;
|
|
168
|
+
nativeDb.saveLocalValue("parentChangeSet", JSON.stringify(currentChangeset));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
db.saveChanges();
|
|
173
|
+
db.close();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
core_bentley_1.Logger.logError(loggerCategory, "Error downloading checkpoint - deleting it", () => traceInfo);
|
|
178
|
+
IModelJsFs_1.IModelJsFs.removeSync(targetFile);
|
|
179
|
+
if (error.errorNumber === core_bentley_1.ChangeSetStatus.CorruptedChangeStream || error.errorNumber === core_bentley_1.ChangeSetStatus.InvalidId || error.errorNumber === core_bentley_1.ChangeSetStatus.InvalidVersion) {
|
|
180
|
+
core_bentley_1.Logger.logError(loggerCategory, "Detected potential corruption of change sets. Deleting them to enable retries", () => traceInfo);
|
|
181
|
+
BriefcaseManager_1.BriefcaseManager.deleteChangeSetsFromLocalDisk(checkpoint.iModelId);
|
|
182
|
+
}
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** Download a checkpoint file from iModelHub into a local file specified in the request parameters. */
|
|
187
|
+
static async downloadCheckpoint(request) {
|
|
188
|
+
if (this.verifyCheckpoint(request.checkpoint, request.localFile))
|
|
189
|
+
return;
|
|
190
|
+
if (request.aliasFiles) {
|
|
191
|
+
for (const alias of request.aliasFiles) {
|
|
192
|
+
if (this.verifyCheckpoint(request.checkpoint, alias)) {
|
|
193
|
+
request.localFile = alias;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
await this.doDownload(request);
|
|
199
|
+
return this.updateToRequestedVersion(request);
|
|
200
|
+
}
|
|
201
|
+
/** checks a file's dbGuid & iTwinId for consistency, and updates the dbGuid when possible */
|
|
202
|
+
static validateCheckpointGuids(checkpoint, nativeDb) {
|
|
203
|
+
const traceInfo = { iTwinId: checkpoint.iTwinId, iModelId: checkpoint.iModelId };
|
|
204
|
+
const dbChangeset = nativeDb.getCurrentChangeset();
|
|
205
|
+
const iModelId = core_bentley_1.Guid.normalize(nativeDb.getIModelId());
|
|
206
|
+
if (iModelId !== core_bentley_1.Guid.normalize(checkpoint.iModelId)) {
|
|
207
|
+
if (nativeDb.isReadonly())
|
|
208
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.ValidationFailed, "iModelId is not properly set up in the checkpoint");
|
|
209
|
+
core_bentley_1.Logger.logWarning(loggerCategory, "iModelId is not properly set up in the checkpoint. Updated checkpoint to the correct iModelId.", () => ({ ...traceInfo, dbGuid: iModelId }));
|
|
210
|
+
nativeDb.setIModelId(core_bentley_1.Guid.normalize(checkpoint.iModelId));
|
|
211
|
+
// Required to reset the ChangeSetId because setDbGuid clears the value.
|
|
212
|
+
nativeDb.saveLocalValue("ParentChangeSetId", dbChangeset.id);
|
|
213
|
+
if (undefined !== dbChangeset.index)
|
|
214
|
+
nativeDb.saveLocalValue("parentChangeSet", JSON.stringify(dbChangeset));
|
|
215
|
+
}
|
|
216
|
+
const iTwinId = core_bentley_1.Guid.normalize(nativeDb.getITwinId());
|
|
217
|
+
if (iTwinId !== core_bentley_1.Guid.normalize(checkpoint.iTwinId))
|
|
218
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.ValidationFailed, "iTwinId was not properly set up in the checkpoint");
|
|
219
|
+
}
|
|
220
|
+
/** @returns true if the file is the checkpoint requested */
|
|
221
|
+
static verifyCheckpoint(checkpoint, fileName) {
|
|
222
|
+
if (!IModelJsFs_1.IModelJsFs.existsSync(fileName))
|
|
223
|
+
return false;
|
|
224
|
+
const nativeDb = new IModelHost_1.IModelHost.platform.DgnDb();
|
|
225
|
+
try {
|
|
226
|
+
nativeDb.openIModel(fileName, core_bentley_1.OpenMode.Readonly);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
const isValid = checkpoint.iModelId === nativeDb.getIModelId() && checkpoint.changeset.id === nativeDb.getCurrentChangeset().id;
|
|
232
|
+
nativeDb.closeIModel();
|
|
233
|
+
if (!isValid)
|
|
234
|
+
IModelJsFs_1.IModelJsFs.removeSync(fileName);
|
|
235
|
+
return isValid;
|
|
236
|
+
}
|
|
237
|
+
/** try to open an existing local file to satisfy a download request */
|
|
238
|
+
static tryOpenLocalFile(request) {
|
|
239
|
+
const checkpoint = request.checkpoint;
|
|
240
|
+
if (this.verifyCheckpoint(checkpoint, request.localFile))
|
|
241
|
+
return IModelDb_1.SnapshotDb.openCheckpointV1(request.localFile, checkpoint);
|
|
242
|
+
// check a list of aliases for finding checkpoints downloaded to non-default locations (e.g. from older versions)
|
|
243
|
+
if (request.aliasFiles) {
|
|
244
|
+
for (const alias of request.aliasFiles) {
|
|
245
|
+
if (this.verifyCheckpoint(checkpoint, alias)) {
|
|
246
|
+
request.localFile = alias;
|
|
247
|
+
return IModelDb_1.SnapshotDb.openCheckpointV1(alias, checkpoint);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.CheckpointManager = CheckpointManager;
|
|
255
|
+
CheckpointManager.onDownloadV1 = new core_bentley_1.BeEvent();
|
|
256
|
+
CheckpointManager.onDownloadV2 = new core_bentley_1.BeEvent();
|
|
257
|
+
//# sourceMappingURL=CheckpointManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckpointManager.js","sourceRoot":"","sources":["../../src/CheckpointManager.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\n// cspell:ignore BLOCKCACHE\r\n\r\nimport * as path from \"path\";\r\nimport { BeEvent, ChangeSetStatus, DbResult, Guid, GuidString, IModelStatus, Logger, Mutable, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, ChangesetId, ChangesetIdWithIndex, ChangesetIndexAndId, IModelError, IModelVersion, LocalDirName, LocalFileName } from \"@itwin/core-common\";\r\nimport { BlobDaemon, BlobDaemonCommandArg, IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { SnapshotDb, TokenArg } from \"./IModelDb\";\r\nimport { IModelHost } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\n\r\nconst loggerCategory = BackendLoggerCategory.IModelDb;\r\n\r\n/**\r\n * Properties of a checkpoint\r\n * @public\r\n */\r\nexport interface CheckpointProps extends TokenArg {\r\n readonly expectV2?: boolean;\r\n\r\n /** iTwin that the iModel belongs to */\r\n readonly iTwinId: GuidString;\r\n\r\n /** Id of the iModel */\r\n readonly iModelId: GuidString;\r\n\r\n /** changeset for the checkpoint */\r\n readonly changeset: ChangesetIdWithIndex;\r\n\r\n /** The number of seconds before the current token expires to attempt to reacquire a new token. Default is 1 hour. */\r\n readonly reattachSafetySeconds?: number;\r\n}\r\n\r\n/** Called to show progress during a download. If this function returns non-zero, the download is aborted.\r\n * @public\r\n */\r\nexport type ProgressFunction = (loaded: number, total: number) => number;\r\n\r\n/** The parameters that specify a request to download a checkpoint file from iModelHub.\r\n * @internal\r\n */\r\nexport interface DownloadRequest {\r\n /** name of local file to hold the downloaded data. */\r\n localFile: LocalFileName;\r\n\r\n /** A list of full fileName paths to test before downloading. If a valid file exists by one of these names,\r\n * no download is performed and `localFile` is updated to reflect the fact that the file exists with that name.\r\n * This can be used, for example, to look for checkpoints from previous versions if the naming strategy changes.\r\n */\r\n readonly aliasFiles?: ReadonlyArray<string>;\r\n\r\n /** Properties of the checkpoint to be downloaded */\r\n readonly checkpoint: CheckpointProps;\r\n\r\n /** If present, this function will be called to indicate progress as the briefcase is downloaded. If this\r\n * function returns a non-zero value, the download is aborted.\r\n */\r\n readonly onProgress?: ProgressFunction;\r\n}\r\n\r\n/** @internal */\r\nexport interface DownloadJob {\r\n request: DownloadRequest;\r\n promise?: Promise<any>;\r\n}\r\n\r\n/** @internal */\r\nexport class Downloads {\r\n private static _active = new Map<string, DownloadJob>();\r\n\r\n private static async process<T>(job: DownloadJob, fn: (job: DownloadJob) => Promise<T>) {\r\n const jobName = job.request.localFile; // save this, it can change inside call to `fn`!\r\n this._active.set(jobName, job);\r\n try {\r\n return await fn(job);\r\n } finally {\r\n this._active.delete(jobName);\r\n }\r\n }\r\n\r\n public static isInProgress(pathName: LocalFileName): DownloadJob | undefined {\r\n return this._active.get(pathName);\r\n }\r\n\r\n public static async download<T>(request: DownloadRequest, downloadFn: (job: DownloadJob) => Promise<T>) {\r\n const pathName = request.localFile;\r\n let job = this.isInProgress(pathName);\r\n if (undefined !== job)\r\n return job.promise;\r\n\r\n IModelJsFs.recursiveMkDirSync(path.dirname(pathName));\r\n job = { request };\r\n return job.promise = this.process(job, downloadFn);\r\n }\r\n}\r\n\r\n/** Utility class for attaching to Daemon, opening V2 checkpoints, and downloading them.\r\n * @internal\r\n*/\r\nexport class V2CheckpointManager {\r\n private static async getCommandArgs(checkpoint: CheckpointProps): Promise<BlobDaemonCommandArg> {\r\n try {\r\n const v2props = await IModelHost.hubAccess.queryV2Checkpoint(checkpoint);\r\n if (!v2props)\r\n throw new Error(\"no checkpoint\");\r\n\r\n return { ...v2props, daemonDir: process.env.BLOCKCACHE_DIR, writeable: false };\r\n } catch (err: any) {\r\n throw new IModelError(IModelStatus.NotFound, `V2 checkpoint not found: err: ${err.message}`);\r\n }\r\n }\r\n\r\n public static async attach(checkpoint: CheckpointProps): Promise<{ filePath: LocalFileName, expiryTimestamp: number }> {\r\n const args = await this.getCommandArgs(checkpoint);\r\n if (undefined === args.daemonDir || args.daemonDir === \"\")\r\n throw new IModelError(IModelStatus.BadRequest, \"Invalid config: BLOCKCACHE_DIR is not set\");\r\n\r\n // We can assume that a BCVDaemon process is already started if BLOCKCACHE_DIR was set, so we need to just tell the daemon to attach to the Storage Container\r\n const attachResult = await BlobDaemon.command(\"attach\", args);\r\n if (attachResult.result !== DbResult.BE_SQLITE_OK) {\r\n const error = `Daemon attach failed: ${attachResult.errMsg}`;\r\n if (checkpoint.expectV2)\r\n Logger.logError(loggerCategory, error);\r\n\r\n throw new IModelError(attachResult.result, error);\r\n }\r\n const sasTokenExpiry = new URLSearchParams(args.auth).get(\"se\");\r\n\r\n return { filePath: BlobDaemon.getDbFileName(args), expiryTimestamp: sasTokenExpiry ? Date.parse(sasTokenExpiry) : 0 };\r\n }\r\n\r\n private static async performDownload(job: DownloadJob): Promise<ChangesetId> {\r\n CheckpointManager.onDownloadV2.raiseEvent(job);\r\n return IModelHost.hubAccess.downloadV2Checkpoint(job.request);\r\n }\r\n\r\n /** Fully download a V2 checkpoint to a local file that can be used to create a briefcase or to work offline.\r\n * @returns a Promise that is resolved when the download completes with the changesetId of the downloaded checkpoint (which will\r\n * be the same as the requested changesetId or the most recent checkpoint before it.)\r\n */\r\n public static async downloadCheckpoint(request: DownloadRequest): Promise<ChangesetId> {\r\n return Downloads.download(request, async (job: DownloadJob) => this.performDownload(job));\r\n }\r\n}\r\n\r\n/** Utility class to deal with downloading V1 checkpoints from iModelHub.\r\n * @internal\r\n */\r\nexport class V1CheckpointManager {\r\n public static getFolder(iModelId: GuidString): LocalDirName {\r\n return path.join(BriefcaseManager.getIModelPath(iModelId), \"checkpoints\");\r\n }\r\n\r\n public static getFileName(checkpoint: CheckpointProps): LocalFileName {\r\n const changesetId = checkpoint.changeset.id || \"first\";\r\n return path.join(this.getFolder(checkpoint.iModelId), `${changesetId}.bim`);\r\n }\r\n\r\n public static async getCheckpointDb(request: DownloadRequest): Promise<SnapshotDb> {\r\n const db = SnapshotDb.tryFindByKey(CheckpointManager.getKey(request.checkpoint));\r\n return (undefined !== db) ? db : Downloads.download(request, async (job: DownloadJob) => this.downloadAndOpen(job));\r\n }\r\n\r\n /** Download a V1 checkpoint */\r\n public static async downloadCheckpoint(request: DownloadRequest): Promise<ChangesetId> {\r\n return Downloads.download(request, async (job: DownloadJob) => this.performDownload(job));\r\n }\r\n\r\n private static async downloadAndOpen(job: DownloadJob) {\r\n const db = CheckpointManager.tryOpenLocalFile(job.request);\r\n if (db)\r\n return db;\r\n await this.performDownload(job);\r\n await CheckpointManager.updateToRequestedVersion(job.request);\r\n return SnapshotDb.openCheckpointV1(job.request.localFile, job.request.checkpoint);\r\n }\r\n\r\n private static async performDownload(job: DownloadJob): Promise<ChangesetId> {\r\n CheckpointManager.onDownloadV1.raiseEvent(job);\r\n return IModelHost.hubAccess.downloadV1Checkpoint(job.request);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class CheckpointManager {\r\n public static readonly onDownloadV1 = new BeEvent<(job: DownloadJob) => void>();\r\n public static readonly onDownloadV2 = new BeEvent<(job: DownloadJob) => void>();\r\n public static getKey(checkpoint: CheckpointProps) { return `${checkpoint.iModelId}:${checkpoint.changeset.id}`; }\r\n\r\n private static async doDownload(request: DownloadRequest): Promise<ChangesetId> {\r\n try {\r\n // first see if there's a V2 checkpoint available.\r\n const changesetId = await V2CheckpointManager.downloadCheckpoint(request);\r\n Logger.logInfo(loggerCategory, `Downloaded v2 checkpoint: IModel=${request.checkpoint.iModelId}, changeset=${request.checkpoint.changeset.id}`);\r\n return changesetId;\r\n } catch (error) {\r\n if (error instanceof IModelError && error.errorNumber === IModelStatus.NotFound) // No V2 checkpoint available, try a v1 checkpoint\r\n return V1CheckpointManager.downloadCheckpoint(request);\r\n\r\n throw (error); // most likely, was aborted\r\n }\r\n }\r\n\r\n public static async updateToRequestedVersion(request: DownloadRequest) {\r\n const checkpoint = request.checkpoint;\r\n const targetFile = request.localFile;\r\n const traceInfo = { iTwinId: checkpoint.iTwinId, iModelId: checkpoint.iModelId, changeset: checkpoint.changeset };\r\n try {\r\n // Open checkpoint for write\r\n const db = SnapshotDb.openForApplyChangesets(targetFile);\r\n const nativeDb = db.nativeDb;\r\n\r\n try {\r\n if (nativeDb.hasPendingTxns()) {\r\n Logger.logWarning(loggerCategory, \"Checkpoint with Txns found - deleting them\", () => traceInfo);\r\n nativeDb.deleteAllTxns();\r\n }\r\n\r\n if (nativeDb.getBriefcaseId() !== BriefcaseIdValue.Unassigned)\r\n nativeDb.resetBriefcaseId(BriefcaseIdValue.Unassigned);\r\n\r\n CheckpointManager.validateCheckpointGuids(checkpoint, nativeDb);\r\n // Apply change sets if necessary\r\n const currentChangeset: Mutable<ChangesetIndexAndId> = nativeDb.getCurrentChangeset();\r\n if (currentChangeset.id !== checkpoint.changeset.id) {\r\n const accessToken = checkpoint.accessToken;\r\n const toIndex = checkpoint.changeset.index ??\r\n (await IModelHost.hubAccess.getChangesetFromVersion({ accessToken, iModelId: checkpoint.iModelId, version: IModelVersion.asOfChangeSet(checkpoint.changeset.id) })).index;\r\n await BriefcaseManager.pullAndApplyChangesets(db, { accessToken, toIndex });\r\n } else {\r\n // make sure the parent changeset index is saved in the file - old versions didn't have it.\r\n currentChangeset.index = checkpoint.changeset.index!;\r\n nativeDb.saveLocalValue(\"parentChangeSet\", JSON.stringify(currentChangeset));\r\n }\r\n } finally {\r\n db.saveChanges();\r\n db.close();\r\n }\r\n } catch (error: any) {\r\n\r\n Logger.logError(loggerCategory, \"Error downloading checkpoint - deleting it\", () => traceInfo);\r\n IModelJsFs.removeSync(targetFile);\r\n\r\n if (error.errorNumber === ChangeSetStatus.CorruptedChangeStream || error.errorNumber === ChangeSetStatus.InvalidId || error.errorNumber === ChangeSetStatus.InvalidVersion) {\r\n Logger.logError(loggerCategory, \"Detected potential corruption of change sets. Deleting them to enable retries\", () => traceInfo);\r\n BriefcaseManager.deleteChangeSetsFromLocalDisk(checkpoint.iModelId);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /** Download a checkpoint file from iModelHub into a local file specified in the request parameters. */\r\n public static async downloadCheckpoint(request: DownloadRequest): Promise<void> {\r\n if (this.verifyCheckpoint(request.checkpoint, request.localFile))\r\n return;\r\n\r\n if (request.aliasFiles) {\r\n for (const alias of request.aliasFiles) {\r\n if (this.verifyCheckpoint(request.checkpoint, alias)) {\r\n request.localFile = alias;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n await this.doDownload(request);\r\n return this.updateToRequestedVersion(request);\r\n }\r\n\r\n /** checks a file's dbGuid & iTwinId for consistency, and updates the dbGuid when possible */\r\n public static validateCheckpointGuids(checkpoint: CheckpointProps, nativeDb: IModelJsNative.DgnDb) {\r\n const traceInfo = { iTwinId: checkpoint.iTwinId, iModelId: checkpoint.iModelId };\r\n\r\n const dbChangeset = nativeDb.getCurrentChangeset();\r\n const iModelId = Guid.normalize(nativeDb.getIModelId());\r\n if (iModelId !== Guid.normalize(checkpoint.iModelId)) {\r\n if (nativeDb.isReadonly())\r\n throw new IModelError(IModelStatus.ValidationFailed, \"iModelId is not properly set up in the checkpoint\");\r\n\r\n Logger.logWarning(loggerCategory, \"iModelId is not properly set up in the checkpoint. Updated checkpoint to the correct iModelId.\", () => ({ ...traceInfo, dbGuid: iModelId }));\r\n nativeDb.setIModelId(Guid.normalize(checkpoint.iModelId));\r\n // Required to reset the ChangeSetId because setDbGuid clears the value.\r\n nativeDb.saveLocalValue(\"ParentChangeSetId\", dbChangeset.id);\r\n if (undefined !== dbChangeset.index)\r\n nativeDb.saveLocalValue(\"parentChangeSet\", JSON.stringify(dbChangeset));\r\n }\r\n\r\n const iTwinId = Guid.normalize(nativeDb.getITwinId());\r\n if (iTwinId !== Guid.normalize(checkpoint.iTwinId))\r\n throw new IModelError(IModelStatus.ValidationFailed, \"iTwinId was not properly set up in the checkpoint\");\r\n }\r\n\r\n /** @returns true if the file is the checkpoint requested */\r\n public static verifyCheckpoint(checkpoint: CheckpointProps, fileName: LocalFileName): boolean {\r\n if (!IModelJsFs.existsSync(fileName))\r\n return false;\r\n\r\n const nativeDb = new IModelHost.platform.DgnDb();\r\n try {\r\n nativeDb.openIModel(fileName, OpenMode.Readonly);\r\n } catch (error) {\r\n return false;\r\n }\r\n\r\n const isValid = checkpoint.iModelId === nativeDb.getIModelId() && checkpoint.changeset.id === nativeDb.getCurrentChangeset().id;\r\n nativeDb.closeIModel();\r\n if (!isValid)\r\n IModelJsFs.removeSync(fileName);\r\n\r\n return isValid;\r\n }\r\n\r\n /** try to open an existing local file to satisfy a download request */\r\n public static tryOpenLocalFile(request: DownloadRequest): SnapshotDb | undefined {\r\n const checkpoint = request.checkpoint;\r\n if (this.verifyCheckpoint(checkpoint, request.localFile))\r\n return SnapshotDb.openCheckpointV1(request.localFile, checkpoint);\r\n\r\n // check a list of aliases for finding checkpoints downloaded to non-default locations (e.g. from older versions)\r\n if (request.aliasFiles) {\r\n for (const alias of request.aliasFiles) {\r\n if (this.verifyCheckpoint(checkpoint, alias)) {\r\n request.localFile = alias;\r\n return SnapshotDb.openCheckpointV1(alias, checkpoint);\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Schema
|
|
3
|
+
*/
|
|
4
|
+
import { EntityMetaData, IModelError } from "@itwin/core-common";
|
|
5
|
+
import { Entity } from "./Entity";
|
|
6
|
+
import { IModelDb } from "./IModelDb";
|
|
7
|
+
import { Schema } from "./Schema";
|
|
8
|
+
/** The mapping between a BIS class name (in the form "schema:class") and its JavaScript constructor function
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare class ClassRegistry {
|
|
12
|
+
private static readonly _classMap;
|
|
13
|
+
/** @internal */
|
|
14
|
+
static isNotFoundError(err: any): boolean;
|
|
15
|
+
/** @internal */
|
|
16
|
+
static makeMetaDataNotFoundError(className: string): IModelError;
|
|
17
|
+
/** @internal */
|
|
18
|
+
static register(entityClass: typeof Entity, schema: typeof Schema): void;
|
|
19
|
+
/** Generate a proxy Schema for a domain that has not been registered. */
|
|
20
|
+
private static generateProxySchema;
|
|
21
|
+
/** Generate a JavaScript class from Entity metadata.
|
|
22
|
+
* @param entityMetaData The Entity metadata that defines the class
|
|
23
|
+
*/
|
|
24
|
+
private static generateClassForEntity;
|
|
25
|
+
/** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]
|
|
26
|
+
* @param moduleObj The module to search for subclasses of Entity
|
|
27
|
+
* @param schema The schema for all found classes
|
|
28
|
+
*/
|
|
29
|
+
static registerModule(moduleObj: any, schema: typeof Schema): void;
|
|
30
|
+
/**
|
|
31
|
+
* This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated
|
|
32
|
+
* class. This function also ensures that all of the base classes of the Entity exist and are registered.
|
|
33
|
+
*/
|
|
34
|
+
private static generateClass;
|
|
35
|
+
/** Find a registered class by classFullName.
|
|
36
|
+
* @param classFullName class to find
|
|
37
|
+
* @param iModel The IModel that contains the class definitions
|
|
38
|
+
* @returns The Entity class or undefined
|
|
39
|
+
*/
|
|
40
|
+
static findRegisteredClass(classFullName: string): typeof Entity | undefined;
|
|
41
|
+
/** Get the Entity class for the specified Entity className.
|
|
42
|
+
* @param classFullName The full BIS class name of the Entity
|
|
43
|
+
* @param iModel The IModel that contains the class definitions
|
|
44
|
+
* @returns The Entity class
|
|
45
|
+
*/
|
|
46
|
+
static getClass(classFullName: string, iModel: IModelDb): typeof Entity;
|
|
47
|
+
/** Unregister a class, by name, if one is already registered.
|
|
48
|
+
* This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.
|
|
49
|
+
* @param classFullName Name of the class to unregister
|
|
50
|
+
* @return true if the class was unregistered
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
static unregisterCLass(classFullName: string): boolean;
|
|
54
|
+
/** Unregister all classes from a schema.
|
|
55
|
+
* This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.
|
|
56
|
+
* @param schema Name of the schema to unregister
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
static unregisterClassesFrom(schema: typeof Schema): void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A cache that records the mapping between class names and class metadata
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export declare class MetaDataRegistry {
|
|
66
|
+
private _registry;
|
|
67
|
+
/** Get the specified Entity metadata */
|
|
68
|
+
find(classFullName: string): EntityMetaData | undefined;
|
|
69
|
+
/** Add metadata to the cache */
|
|
70
|
+
add(classFullName: string, metaData: EntityMetaData): void;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=ClassRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClassRegistry.d.ts","sourceRoot":"","sources":["../../src/ClassRegistry.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,MAAM,EAAW,MAAM,UAAU,CAAC;AAG3C;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAoC;IACrE,gBAAgB;WACF,eAAe,CAAC,GAAG,EAAE,GAAG;IACtC,gBAAgB;WACF,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW;IACvE,gBAAgB;WACF,QAAQ,CAAC,WAAW,EAAE,OAAO,MAAM,EAAE,MAAM,EAAE,OAAO,MAAM;IAYxE,yEAAyE;IACzE,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAWlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAgCrC;;;OAGG;WACW,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,MAAM;IAQlE;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAa5B;;;;OAIG;WACW,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,MAAM,GAAG,SAAS;IAInF;;;;OAIG;WACW,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,MAAM;IAM9E;;;;;OAKG;WACW,eAAe,CAAC,aAAa,EAAE,MAAM;IACnD;;;;OAIG;WACW,qBAAqB,CAAC,MAAM,EAAE,OAAO,MAAM;CAM1D;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkE;IAEnF,wCAAwC;IACjC,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAE9D,gCAAgC;IACzB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI;CAClE"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
/** @packageDocumentation
|
|
7
|
+
* @module Schema
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MetaDataRegistry = exports.ClassRegistry = void 0;
|
|
11
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
12
|
+
const core_common_1 = require("@itwin/core-common");
|
|
13
|
+
const Entity_1 = require("./Entity");
|
|
14
|
+
const Schema_1 = require("./Schema");
|
|
15
|
+
const IModelSchemaLoader_1 = require("./IModelSchemaLoader");
|
|
16
|
+
/** The mapping between a BIS class name (in the form "schema:class") and its JavaScript constructor function
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
class ClassRegistry {
|
|
20
|
+
/** @internal */
|
|
21
|
+
static isNotFoundError(err) { return (err instanceof core_common_1.IModelError) && (err.errorNumber === core_bentley_1.IModelStatus.NotFound); }
|
|
22
|
+
/** @internal */
|
|
23
|
+
static makeMetaDataNotFoundError(className) { return new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `metadata not found for ${className}`); }
|
|
24
|
+
/** @internal */
|
|
25
|
+
static register(entityClass, schema) {
|
|
26
|
+
entityClass.schema = schema;
|
|
27
|
+
const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();
|
|
28
|
+
if (this._classMap.has(key)) {
|
|
29
|
+
const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;
|
|
30
|
+
core_bentley_1.Logger.logError("core-frontend.classRegistry", errMsg);
|
|
31
|
+
throw new Error(errMsg);
|
|
32
|
+
}
|
|
33
|
+
this._classMap.set(key, entityClass);
|
|
34
|
+
}
|
|
35
|
+
/** Generate a proxy Schema for a domain that has not been registered. */
|
|
36
|
+
static generateProxySchema(domain, iModel) {
|
|
37
|
+
var _a;
|
|
38
|
+
const hasBehavior = undefined !== ((_a = new IModelSchemaLoader_1.IModelSchemaLoader(iModel).getSchema(domain).customAttributes) === null || _a === void 0 ? void 0 : _a.get("BisCore.SchemaHasBehavior"));
|
|
39
|
+
const schemaClass = class extends Schema_1.Schema {
|
|
40
|
+
static get schemaName() { return domain; }
|
|
41
|
+
static get missingRequiredBehavior() { return hasBehavior; }
|
|
42
|
+
};
|
|
43
|
+
Schema_1.Schemas.registerSchema(schemaClass); // register the class before we return it.
|
|
44
|
+
return schemaClass;
|
|
45
|
+
}
|
|
46
|
+
/** Generate a JavaScript class from Entity metadata.
|
|
47
|
+
* @param entityMetaData The Entity metadata that defines the class
|
|
48
|
+
*/
|
|
49
|
+
static generateClassForEntity(entityMetaData, iModel) {
|
|
50
|
+
const name = entityMetaData.ecclass.split(":");
|
|
51
|
+
const domainName = name[0];
|
|
52
|
+
const className = name[1];
|
|
53
|
+
if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass
|
|
54
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadArg, `class ${name} has no superclass`);
|
|
55
|
+
// make sure schema exists
|
|
56
|
+
let schema = Schema_1.Schemas.getRegisteredSchema(domainName);
|
|
57
|
+
if (undefined === schema)
|
|
58
|
+
schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too
|
|
59
|
+
// this method relies on the caller having previously created/registered all superclasses
|
|
60
|
+
const superclass = this._classMap.get(entityMetaData.baseClasses[0].toLowerCase());
|
|
61
|
+
if (undefined === superclass)
|
|
62
|
+
throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `cannot find superclass for class ${name}`);
|
|
63
|
+
const generatedClass = class extends superclass {
|
|
64
|
+
static get className() { return className; }
|
|
65
|
+
};
|
|
66
|
+
// the above line creates an anonymous class. For help debugging, set the "constructor.name" property to be the same as the bisClassName.
|
|
67
|
+
Object.defineProperty(generatedClass, "name", { get: () => className }); // this is the (only) way to change that readonly property.
|
|
68
|
+
// if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations
|
|
69
|
+
if (schema.missingRequiredBehavior) {
|
|
70
|
+
const throwError = () => { throw new core_common_1.IModelError(core_bentley_1.IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`); };
|
|
71
|
+
superclass.protectedOperations.forEach((operation) => generatedClass[operation] = throwError);
|
|
72
|
+
}
|
|
73
|
+
this.register(generatedClass, schema); // register it before returning
|
|
74
|
+
return generatedClass;
|
|
75
|
+
}
|
|
76
|
+
/** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]
|
|
77
|
+
* @param moduleObj The module to search for subclasses of Entity
|
|
78
|
+
* @param schema The schema for all found classes
|
|
79
|
+
*/
|
|
80
|
+
static registerModule(moduleObj, schema) {
|
|
81
|
+
for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in
|
|
82
|
+
const thisClass = moduleObj[thisMember];
|
|
83
|
+
if (thisClass.prototype instanceof Entity_1.Entity)
|
|
84
|
+
this.register(thisClass, schema);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated
|
|
89
|
+
* class. This function also ensures that all of the base classes of the Entity exist and are registered.
|
|
90
|
+
*/
|
|
91
|
+
static generateClass(classFullName, iModel) {
|
|
92
|
+
const metadata = iModel.classMetaDataRegistry.find(classFullName);
|
|
93
|
+
if (metadata === undefined || metadata.ecclass === undefined)
|
|
94
|
+
throw this.makeMetaDataNotFoundError(classFullName);
|
|
95
|
+
// Make sure we have all base classes registered.
|
|
96
|
+
if (metadata.baseClasses && (0 !== metadata.baseClasses.length))
|
|
97
|
+
this.getClass(metadata.baseClasses[0], iModel);
|
|
98
|
+
// Now we can generate the class from the classDef.
|
|
99
|
+
return this.generateClassForEntity(metadata, iModel);
|
|
100
|
+
}
|
|
101
|
+
/** Find a registered class by classFullName.
|
|
102
|
+
* @param classFullName class to find
|
|
103
|
+
* @param iModel The IModel that contains the class definitions
|
|
104
|
+
* @returns The Entity class or undefined
|
|
105
|
+
*/
|
|
106
|
+
static findRegisteredClass(classFullName) {
|
|
107
|
+
return this._classMap.get(classFullName.toLowerCase());
|
|
108
|
+
}
|
|
109
|
+
/** Get the Entity class for the specified Entity className.
|
|
110
|
+
* @param classFullName The full BIS class name of the Entity
|
|
111
|
+
* @param iModel The IModel that contains the class definitions
|
|
112
|
+
* @returns The Entity class
|
|
113
|
+
*/
|
|
114
|
+
static getClass(classFullName, iModel) {
|
|
115
|
+
const key = classFullName.toLowerCase();
|
|
116
|
+
const ctor = this._classMap.get(key);
|
|
117
|
+
return ctor ? ctor : this.generateClass(key, iModel);
|
|
118
|
+
}
|
|
119
|
+
/** Unregister a class, by name, if one is already registered.
|
|
120
|
+
* This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.
|
|
121
|
+
* @param classFullName Name of the class to unregister
|
|
122
|
+
* @return true if the class was unregistered
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
static unregisterCLass(classFullName) { return this._classMap.delete(classFullName.toLowerCase()); }
|
|
126
|
+
/** Unregister all classes from a schema.
|
|
127
|
+
* This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.
|
|
128
|
+
* @param schema Name of the schema to unregister
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
static unregisterClassesFrom(schema) {
|
|
132
|
+
for (const entry of Array.from(this._classMap)) {
|
|
133
|
+
if (entry[1].schema === schema)
|
|
134
|
+
this.unregisterCLass(entry[0]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.ClassRegistry = ClassRegistry;
|
|
139
|
+
ClassRegistry._classMap = new Map();
|
|
140
|
+
/**
|
|
141
|
+
* A cache that records the mapping between class names and class metadata
|
|
142
|
+
* @internal
|
|
143
|
+
*/
|
|
144
|
+
class MetaDataRegistry {
|
|
145
|
+
constructor() {
|
|
146
|
+
this._registry = new Map();
|
|
147
|
+
}
|
|
148
|
+
/** Get the specified Entity metadata */
|
|
149
|
+
find(classFullName) { return this._registry.get(classFullName.toLowerCase()); }
|
|
150
|
+
/** Add metadata to the cache */
|
|
151
|
+
add(classFullName, metaData) { this._registry.set(classFullName.toLowerCase(), metaData); }
|
|
152
|
+
}
|
|
153
|
+
exports.MetaDataRegistry = MetaDataRegistry;
|
|
154
|
+
//# sourceMappingURL=ClassRegistry.js.map
|