@itwin/core-backend
Version:
iTwin.js backend components
885 lines • 80.3 kB
TypeScript
/** @packageDocumentation
* @module iModels
*/
import { IModelJsNative } from "@bentley/imodeljs-native";
import { AccessToken, BeEvent, BentleyStatus, DbResult, GuidString, Id64Arg, Id64Array, Id64Set, Id64String, IModelStatus, LRUMap, OpenMode } from "@itwin/core-bentley";
import { AxisAlignedBox3d, BRepGeometryCreate, BriefcaseId, ChangesetHealthStats, ChangesetIdWithIndex, Code, CodeProps, CreateEmptySnapshotIModelProps, CreateEmptyStandaloneIModelProps, CreateSnapshotIModelProps, EcefLocation, ECSchemaProps, ECSqlReader, ElementAspectProps, ElementGeometryCacheOperationRequestProps, ElementGeometryCacheRequestProps, ElementGeometryCacheResponseProps, ElementGeometryRequest, ElementGraphicsRequestProps, ElementLoadProps, ElementProps, EntityMetaData, EntityProps, EntityQueryParams, FilePropertyProps, FontMap, GeoCoordinatesRequestProps, GeoCoordinatesResponseProps, GeometryContainmentRequestProps, GeometryContainmentResponseProps, IModel, IModelCoordinatesRequestProps, IModelCoordinatesResponseProps, IModelTileTreeProps, LocalFileName, MassPropertiesRequestProps, MassPropertiesResponseProps, ModelExtentsProps, ModelProps, OpenBriefcaseProps, OpenCheckpointArgs, OpenSqliteArgs, PropertyCallback, QueryBinder, QueryOptions, SchemaState, SnapRequestProps, SnapResponseProps, SnapshotOpenOptions, SubCategoryResultRow, TextureData, TextureLoadProps, ThumbnailProps, UpgradeOptions, ViewDefinitionProps, ViewIdString, ViewQueryParams, ViewStateLoadProps, ViewStateProps } from "@itwin/core-common";
import { Range3d } from "@itwin/core-geometry";
import { PullChangesArgs, PushChangesArgs, RevertChangesArgs } from "./BriefcaseManager";
import { ChannelControl } from "./ChannelControl";
import { CheckpointProps } from "./CheckpointManager";
import { EntityJsClassMap, MetaDataRegistry } from "./ClassRegistry";
import { CloudSqlite } from "./CloudSqlite";
import { CodeService } from "./CodeService";
import { CodeSpecs } from "./CodeSpecs";
import { ECSchemaXmlContext } from "./ECSchemaXmlContext";
import { ECSqlStatement } from "./ECSqlStatement";
import { Element, Subject } from "./Element";
import { ElementAspect } from "./ElementAspect";
import { Entity, EntityClassType } from "./Entity";
import { ExportGraphicsOptions, ExportPartGraphicsOptions } from "./ExportGraphics";
import { Model } from "./Model";
import { Relationships } from "./Relationship";
import { SqliteStatement } from "./SqliteStatement";
import { ComputeRangesForTextLayoutArgs, TextLayoutRanges } from "./annotations/TextBlockLayout";
import { TxnManager } from "./TxnManager";
import { ViewDefinition } from "./ViewDefinition";
import { ViewStore } from "./ViewStore";
import { SettingsContainer } from "./workspace/Settings";
import { Workspace } from "./workspace/Workspace";
import { LockControl } from "./LockControl";
import type { BlobContainer } from "./BlobContainerService";
import { IModelDbFonts } from "./IModelDbFonts";
import { _cache, _instanceKeyCache, _nativeDb } from "./internal/Symbols";
import { ECVersion, SchemaContext } from "@itwin/ecschema-metadata";
import { SchemaMap } from "./Schema";
import { ElementLRUCache, InstanceKeyLRUCache } from "./internal/ElementLRUCache";
/** Options for [[IModelDb.Models.updateModel]]
* @note To mark *only* the geometry as changed, use [[IModelDb.Models.updateGeometryGuid]] instead.
* @public
*/
export interface UpdateModelOptions extends ModelProps {
/** If defined, update the last modify time of the Model */
updateLastMod?: boolean;
/** If defined, update the GeometryGuid of the Model */
geometryChanged?: boolean;
}
/** Options supposed to [[IModelDb.Elements.insertElement]].
* @public
*/
export interface InsertElementOptions {
/** If true, instead of assigning a new, unique Id to the inserted element, the inserted element will use the Id specified by the supplied [ElementProps]($common).
* This is chiefly useful when applying a filtering transformation - i.e., copying some elements from a source iModel to a target iModel and adding no new elements.
* If this option is `true` then [ElementProps.id]($common) must be a valid Id that is not already used by an element in the iModel.
* @beta
*/
forceUseId?: boolean;
}
/** Options supplied to [[IModelDb.computeProjectExtents]].
* @public
*/
export interface ComputeProjectExtentsOptions {
/** If true, the result will include `extentsWithOutliers`. */
reportExtentsWithOutliers?: boolean;
/** If true, the result will include `outliers`. */
reportOutliers?: boolean;
}
/** The result of [[IModelDb.computeProjectExtents]].
* @public
*/
export interface ComputedProjectExtents {
/** The computed extents, excluding any outlier elements. */
extents: Range3d;
/** If requested by caller, the computed extents, *including* any outlier elements. */
extentsWithOutliers?: Range3d;
/** If requested by caller, the Ids of outlier elements excluded from the computed extents. */
outliers?: Id64Array;
}
/**
* Options for the importing of schemas
* @public
*/
export interface SchemaImportOptions {
/**
* An [[ECSchemaXmlContext]] to use instead of building a default one.
* This can be useful in rare cases where custom schema location logic is necessary
* @internal
*/
ecSchemaXmlContext?: ECSchemaXmlContext;
}
/** @internal */
export declare enum BriefcaseLocalValue {
StandaloneEdit = "StandaloneEdit",
NoLocking = "NoLocking"
}
/** Arguments supplied to [[IModelDb.exportSchema]] specifying which ECSchema to write to what location on the local file system.
* @beta
*/
export interface ExportSchemaArgs {
/** The name of the ECSchema to export. */
schemaName: string;
/** The directory in which to place the created schema file. */
outputDirectory: LocalFileName;
/** Optionally, the name of the file to create in [[outputDirectory]].
* Defaults to <SchemaName>.<SchemaVersion>.ecschema.xml
*/
outputFileName?: string;
}
/** Arguments supplied to [[IModelDb.simplifyElementGeometry]].
* @beta
*/
export interface SimplifyElementGeometryArgs {
/** The Id of the [[GeometricElement]] or [[GeometryPart]] whose geometry is to be simplified. */
id: Id64String;
/** If true, simplify by converting each [BRepEntity]($common) in the element's geometry stream to a high-resolution
* mesh or curve geometry.
*/
convertBReps?: boolean;
}
/** The output of [[IModelDb.inlineGeometryParts]].
* If [[numCandidateParts]], [[numRefsInlined]], and [[numPartsDeleted ]] are all the same, the operation was fully successful.
* Otherwise, some errors occurred inlining and/or deleting one or more parts.
* A part will not be deleted unless it is first successfully inlined.
* @beta
*/
export interface InlineGeometryPartsResult {
/** The number of parts that were determined to have exactly one reference, making them candidates for inlining. */
numCandidateParts: number;
/** The number of part references successfully inlined. */
numRefsInlined: number;
/** The number of candidate parts that were successfully deleted after inlining. */
numPartsDeleted: number;
}
/** An iModel database file. The database file can either be a briefcase or a snapshot.
* @see [Accessing iModels]($docs/learning/backend/AccessingIModels.md)
* @see [About IModelDb]($docs/learning/backend/IModelDb.md)
* @public
*/
export declare abstract class IModelDb extends IModel {
private _initialized;
/** Keep track of open imodels to support `tryFind` for RPC purposes */
private static readonly _openDbs;
static readonly defaultLimit = 1000;
static readonly maxLimit = 10000;
readonly models: IModelDb.Models;
readonly elements: IModelDb.Elements;
readonly views: IModelDb.Views;
readonly tiles: IModelDb.Tiles;
/** @beta */
readonly channels: ChannelControl;
private _relationships?;
private readonly _statementCache;
private readonly _sqliteStatementCache;
private _codeSpecs?;
private _classMetaDataRegistry?;
private _jsClassMap?;
private _schemaMap?;
private _schemaContext?;
/** @deprecated in 5.0.0 - will not be removed until after 2026-06-13. Use [[fonts]]. */
protected _fontMap?: FontMap;
private readonly _fonts;
private _workspace?;
private readonly _snaps;
private static _shutdownListener;
/** @internal */
protected _locks?: LockControl;
/** @internal */
protected _codeService?: CodeService;
/** @alpha */
get codeService(): CodeService | undefined;
/** The [[LockControl]] that orchestrates [concurrent editing]($docs/learning/backend/ConcurrencyControl.md) of this iModel. */
get locks(): LockControl;
/** Provides methods for interacting with [font-related information]($docs/learning/backend/Fonts.md) stored in this iModel.
* @beta
*/
get fonts(): IModelDbFonts;
/**
* Get the [[Workspace]] for this iModel.
* @beta
*/
get workspace(): Workspace;
/**
* get the cloud container for this iModel, if it was opened from one
* @beta
*/
get cloudContainer(): CloudSqlite.CloudContainer | undefined;
/** Acquire the exclusive schema lock on this iModel.
* @note: To acquire the schema lock, all other briefcases must first release *all* their locks. No other briefcases
* will be able to acquire *any* locks while the schema lock is held.
*/
acquireSchemaLock(): Promise<void>;
/** determine whether the schema lock is currently held for this iModel. */
get holdsSchemaLock(): boolean;
/** Event called after a changeset is applied to this IModelDb. */
readonly onChangesetApplied: BeEvent<() => void>;
/** @internal */
notifyChangesetApplied(): void;
/** @internal */
restartDefaultTxn(): void;
/** @deprecated in 5.0.0 - will not be removed until after 2026-06-13. Use [[fonts]]. */
get fontMap(): FontMap;
/** @internal */
clearFontMap(): void;
/** Check if this iModel has been opened read-only or not. */
get isReadonly(): boolean;
/** The Guid that identifies this iModel. */
get iModelId(): GuidString;
/** @internal*/
readonly [_nativeDb]: IModelJsNative.DgnDb;
/** Get the full path fileName of this iModelDb
* @note this member is only valid while the iModel is opened.
*/
get pathName(): LocalFileName;
/** Get the full path to this iModel's "watch file".
* A read-only briefcase opened with `watchForChanges: true` creates this file next to the briefcase file on open, if it doesn't already exist.
* A writable briefcase "touches" this file if it exists whenever it commits changes to the briefcase.
* The read-only briefcase can use a file watcher to react when the writable briefcase makes changes to the briefcase.
* This is more reliable than watching the sqlite WAL file.
* @internal
*/
get watchFilePathName(): LocalFileName;
/** @internal */
protected constructor(args: {
nativeDb: IModelJsNative.DgnDb;
key: string;
changeset?: ChangesetIdWithIndex;
});
/**
* Attach an iModel file to this connection and load and register its schemas.
* @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'
* @param fileName IModel file name
* @param alias identifier for the attached file. This identifer is used to access schema from the attached file. e.g. if alias is 'abc' then schema can be accessed using 'abc.MySchema.MyClass'
*
* *Example:*
* ``` ts
* [[include:IModelDb_attachDb.code]]
* ```
*/
attachDb(fileName: string, alias: string): void;
/**
* Detach the attached file from this connection. The attached file is closed and its schemas are unregistered.
* @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'
* @param alias identifer that was used in the call to [[attachDb]]
*
* *Example:*
* ``` ts
* [[include:IModelDb_attachDb.code]]
* ```
*/
detachDb(alias: string): void;
/** Close this IModel, if it is currently open, and save changes if it was opened in ReadWrite mode. */
close(): void;
/** @internal */
refreshContainerForRpc(_userAccessToken: AccessToken): Promise<void>;
/** Event called when the iModel is about to be closed. */
readonly onBeforeClose: BeEvent<() => void>;
/**
* Called by derived classes before closing the connection
* @internal
*/
protected beforeClose(): void;
/** @internal */
protected initializeIModelDb(when?: "pullMerge"): void;
/** Returns true if this is a BriefcaseDb
* @see [[BriefcaseDb.open]]
*/
get isBriefcase(): boolean;
/** Type guard for instanceof [[BriefcaseDb]] */
isBriefcaseDb(): this is BriefcaseDb;
/** Returns true if this is a SnapshotDb
* @see [[SnapshotDb.open]]
*/
get isSnapshot(): boolean;
/** Type guard for instanceof [[SnapshotDb]] */
isSnapshotDb(): this is SnapshotDb;
/** Returns true if this is a *standalone* iModel
* @see [[StandaloneDb.open]]
* @internal
*/
get isStandalone(): boolean;
/** Type guard for instanceof [[StandaloneDb]]. */
isStandaloneDb(): this is StandaloneDb;
/** Return `true` if the underlying nativeDb is open and valid.
* @internal
*/
get isOpen(): boolean;
/** Get the briefcase Id of this iModel */
getBriefcaseId(): BriefcaseId;
/**
* Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist
* in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved
* in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be
* reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding
* the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].
* @param sql The SQLite SQL statement to execute
* @param callback the callback to invoke on the prepared statement
* @param logErrors Determines if error will be logged if statement fail to prepare
* @returns the value returned by `callback`.
* @see [[withStatement]]
* @public
* @deprecated in 4.11 - will not be removed until after 2026-06-13. Use [[createQueryReader]] instead.
*/
withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors?: boolean): T;
/**
* Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.
* Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.
* For statements that will be reused often, instead use [[withPreparedStatement]].
* @param sql The SQLite SQL statement to execute
* @param callback the callback to invoke on the prepared statement
* @param logErrors Determines if error will be logged if statement fail to prepare
* @returns the value returned by `callback`.
* @see [[withPreparedStatement]]
* @public
* @deprecated in 4.11 - will not be removed until after 2026-06-13. Use [[createQueryReader]] instead.
*/
withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors?: boolean): T;
/** Allow to execute query and read results along with meta data. The result are streamed.
*
* See also:
* - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)
* - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)
* - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)
*
* @param params The values to bind to the parameters (if the ECSQL has any).
* @param config Allow to specify certain flags which control how query is executed.
* @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.
* @public
* */
createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader;
/**
* Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist
* in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved
* in the statement cache so it can be reused in the future. Use this method for SQL statements that will be
* reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding
* the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].
* @param sql The SQLite SQL statement to execute
* @param callback the callback to invoke on the prepared statement
* @param logErrors Determine if errors are logged or not
* @returns the value returned by `callback`.
* @see [[withPreparedStatement]]
* @public
*/
withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors?: boolean): T;
/**
* Prepared and execute a callback on a SQL statement. After the callback completes the statement is disposed.
* Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.
* For statements that will be reused often, instead use [[withPreparedSqliteStatement]].
* @param sql The SQLite SQL statement to execute
* @param callback the callback to invoke on the prepared statement
* @param logErrors Determine if errors are logged or not
* @returns the value returned by `callback`.
* @public
*/
withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors?: boolean): T;
/** Prepare an SQL statement.
* @param sql The SQL statement to prepare
* @throws [[IModelError]] if there is a problem preparing the statement.
* @internal
*/
prepareSqliteStatement(sql: string, logErrors?: boolean): SqliteStatement;
/**
* queries the BisCore.SubCategory table for entries that are children of used spatial categories and 3D elements.
* @returns array of SubCategoryResultRow
* @internal
*/
queryAllUsedSpatialSubCategories(): Promise<SubCategoryResultRow[]>;
/**
* queries the BisCore.SubCategory table for the entries that are children of the passed categoryIds.
* @param categoryIds categoryIds to query
* @returns array of SubCategoryResultRow
* @internal
*/
querySubCategories(categoryIds: Iterable<Id64String>): Promise<SubCategoryResultRow[]>;
/** Query for a set of entity ids, given an EntityQueryParams
* @param params The query parameters. The `limit` and `offset` members should be used to page results.
* @returns an Id64Set with results of query
* @throws [[IModelError]] if the generated statement is invalid or [IModelDb.maxLimit]($backend) exceeded when collecting ids.
*
* *Example:*
* ``` ts
* [[include:ECSQL-backend-queries.select-element-by-code-value-using-queryEntityIds]]
* ```
*/
queryEntityIds(params: EntityQueryParams): Id64Set;
/** Clear all in-memory caches held in this IModelDb. */
clearCaches(): void;
/** Update the project extents for this iModel.
* <p><em>Example:</em>
* ``` ts
* [[include:IModelDb.updateProjectExtents]]
* ```
*/
updateProjectExtents(newExtents: AxisAlignedBox3d): void;
/** Compute an appropriate project extents for this iModel based on the ranges of all spatial elements.
* Typically, the result is simply the union of the ranges of all spatial elements. However, the algorithm also detects "outlier elements",
* whose placements locate them so far from the rest of the spatial geometry that they are considered statistically insignificant. The
* range of an outlier element does not contribute to the computed extents.
* @param options Specifies the level of detail desired in the return value.
* @returns the computed extents.
* @note This method does not modify the IModel's stored project extents. @see [[updateProjectExtents]].
*/
computeProjectExtents(options?: ComputeProjectExtentsOptions): ComputedProjectExtents;
/** Update the [EcefLocation]($docs/learning/glossary#eceflocation) of this iModel. */
updateEcefLocation(ecef: EcefLocation): void;
/** Update the IModelProps of this iModel in the database. */
updateIModelProps(): void;
/** Commit unsaved changes in memory as a Txn to this iModelDb.
* @param description Optional description of the changes
* @throws [[IModelError]] if there is a problem saving changes or if there are pending, un-processed lock or code requests.
* @note This will not push changes to the iModelHub.
* @see [[IModelDb.pushChanges]] to push changes to the iModelHub.
*/
saveChanges(description?: string): void;
/** Abandon changes in memory that have not been saved as a Txn to this iModelDb.
* @note This will not delete Txns that have already been saved, even if they have not yet been pushed.
*/
abandonChanges(): void;
/**
* Save all changes and perform a [checkpoint](https://www.sqlite.org/c3ref/wal_checkpoint_v2.html) on this IModelDb.
* This ensures that all changes to the database since it was opened are saved to its file and the WAL file is truncated.
* @note Checkpoint automatically happens when IModelDbs are closed. However, the checkpoint
* operation itself can take some time. It may be useful to call this method prior to closing so that the checkpoint "penalty" is paid earlier.
* @note Another use for this function is to permit the file to be copied while it is open for write. iModel files should
* rarely be copied, and even less so while they're opened. But this scenario is sometimes encountered for tests.
*/
performCheckpoint(): void;
/** @internal
* @deprecated in 4.8 - will not be removed until after 2026-06-13. Use `txns.reverseTxns`.
*/
reverseTxns(numOperations: number): IModelStatus;
/** @internal */
reinstateTxn(): IModelStatus;
/** @internal */
restartTxnSession(): void;
/** Import an ECSchema. On success, the schema definition is stored in the iModel.
* This method is asynchronous (must be awaited) because, in the case where this IModelDb is a briefcase, this method first obtains the schema lock from the iModel server.
* You must import a schema into an iModel before you can insert instances of the classes in that schema. See [[Element]]
* @param schemaFileName array of Full paths to ECSchema.xml files to be imported.
* @param {SchemaImportOptions} options - options during schema import.
* @throws [[IModelError]] if the schema lock cannot be obtained or there is a problem importing the schema.
* @note Changes are saved if importSchemas is successful and abandoned if not successful.
* - You can use NativeLoggerCategory to turn on the native logs. You can also control [what exactly is logged by the loggers](https://www.itwinjs.org/learning/common/logging/#controlling-what-is-logged).
* - See [Schema Versioning]($docs/bis/guide/schema-evolution/schema-versioning-and-generations.md) for more information on acceptable changes to schemas.
* @see querySchemaVersion
*/
importSchemas(schemaFileNames: LocalFileName[], options?: SchemaImportOptions): Promise<void>;
/** Import ECSchema(s) serialized to XML. On success, the schema definition is stored in the iModel.
* This method is asynchronous (must be awaited) because, in the case where this IModelDb is a briefcase, this method first obtains the schema lock from the iModel server.
* You must import a schema into an iModel before you can insert instances of the classes in that schema. See [[Element]]
* @param serializedXmlSchemas The xml string(s) created from a serialized ECSchema.
* @throws [[IModelError]] if the schema lock cannot be obtained or there is a problem importing the schema.
* @note Changes are saved if importSchemaStrings is successful and abandoned if not successful.
* @see querySchemaVersion
* @alpha
*/
importSchemaStrings(serializedXmlSchemas: string[]): Promise<void>;
/** Find an opened instance of any subclass of IModelDb, by filename
* @note this method returns an IModelDb if the filename is open for *any* subclass of IModelDb
*/
static findByFilename(fileName: LocalFileName): IModelDb | undefined;
/** Find an open IModelDb by its key.
* @note This method is mainly for use by RPC implementations.
* @throws [[IModelNotFoundResponse]] if an open IModelDb matching the key is not found.
* @see [IModel.key]($common)
*/
static findByKey(key: string): IModelDb;
/** Attempt to find an open IModelDb by key.
* @returns The matching IModelDb or `undefined`.
*/
static tryFindByKey(key: string): IModelDb | undefined;
/** @internal */
static openDgnDb(file: {
path: LocalFileName;
key?: string;
}, openMode: OpenMode, upgradeOptions?: UpgradeOptions, props?: SnapshotOpenOptions & CloudContainerArgs & OpenSqliteArgs): IModelJsNative.DgnDb;
/**
* Determines if the schemas in the Db must or can be upgraded by comparing them with those included in the
* current version of the software.
* @param filePath Full name of the briefcase including path
* @param forReadWrite Pass true if validating for read-write scenarios - note that the schema version requirements
* for opening the DgnDb read-write is more stringent than when opening the database read-only
* @throws [[IModelError]] If the Db was in an invalid state and that causes a problem with validating schemas
* @see [[BriefcaseDb.upgradeSchemas]] or [[StandaloneDb.upgradeSchemas]]
* @see ($docs/learning/backend/IModelDb.md#upgrading-schemas-in-an-imodel)
*/
static validateSchemas(filePath: LocalFileName, forReadWrite: boolean): SchemaState;
/** The registry of entity metadata for this iModel.
* @internal
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from the `iModel` instead.
*
* @example
* ```typescript
* // Current usage:
* const classMetaData: EntityMetaData | undefined = iModel.classMetaDataRegistry.find("SchemaName:ClassName");
*
* // Replacement:
* const metaData: EntityClass | undefined = imodel.schemaContext.getSchemaItemSync("SchemaName.ClassName", EntityClass);
* ```
*/
get classMetaDataRegistry(): MetaDataRegistry;
/**
* Allows registering js classes mapped to ECClasses
*/
get jsClassMap(): EntityJsClassMap;
/**
* Allows locally registering a schema for this imodel, in constrast to [Schemas.registerSchema] which is a global operation
*/
get schemaMap(): SchemaMap;
/**
* Gets the context that allows accessing the metadata (ecschema-metadata package) of this iModel
* @public @preview
*/
get schemaContext(): SchemaContext;
/** Get the linkTableRelationships for this IModel */
get relationships(): Relationships;
/** Get the CodeSpecs in this IModel. */
get codeSpecs(): CodeSpecs;
/** Prepare an ECSQL statement.
* @param sql The ECSQL statement to prepare
* @param logErrors Determines if error will be logged if statement fail to prepare
* @throws [[IModelError]] if there is a problem preparing the statement.
* @deprecated in 4.11 - will not be removed until after 2026-06-13. Use [IModelDb.createQueryReader]($backend) or [ECDb.createQueryReader]($backend) to query.
*/
prepareStatement(sql: string, logErrors?: boolean): ECSqlStatement;
/** Prepare an ECSQL statement.
* @param sql The ECSQL statement to prepare
* @returns `undefined` if there is a problem preparing the statement.
* @deprecated in 4.11 - will not be removed until after 2026-06-13. Use [IModelDb.createQueryReader]($backend) or [ECDb.createQueryReader]($backend) to query.
*/
tryPrepareStatement(sql: string): ECSqlStatement | undefined;
/** Construct an entity (Element or Model) from an iModel.
* @throws [[IModelError]] if the entity cannot be constructed.
*/
constructEntity<T extends Entity, P extends EntityProps = EntityProps>(props: P): T;
/** Get the JavaScript class that handles a given entity class. */
getJsClass<T extends typeof Entity>(classFullName: string): T;
/** Constructs a ResolveInstanceKeyArgs from given parameters
* @throws [[IModelError]] if the combination of supplied parameters is invalid.
* @internal
*/
getInstanceArgs(instanceId?: Id64String, baseClassName?: string, federationGuid?: GuidString, code?: CodeProps): IModelJsNative.ResolveInstanceKeyArgs;
/** Get metadata for a class. This method will load the metadata from the iModel into the cache as a side-effect, if necessary.
* @throws [[IModelError]] if the metadata cannot be found nor loaded.
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `getSchemaItem` from `SchemaContext` class instead.
*
* @example
* * ```typescript
* // Current usage:
* const metaData: EntityMetaData = imodel.getMetaData("SchemaName:ClassName");
*
* // Replacement:
* const metaData: EntityClass | undefined = imodel.schemaContext.getSchemaItemSync("SchemaName", "ClassName", EntityClass);
* ```
*/
getMetaData(classFullName: string): EntityMetaData;
/** Identical to [[getMetaData]], except it returns `undefined` instead of throwing an error if the metadata cannot be found nor loaded.
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `getSchemaItem` from `SchemaContext` class instead.
*
* @example
* * ```typescript
* // Current usage:
* const metaData: EntityMetaData | undefined = imodel.tryGetMetaData("SchemaName:ClassName");
*
* // Replacement:
* const metaData: EntityClass | undefined = imodel.schemaContext.getSchemaItemSync("SchemaName.ClassName", EntityClass);
* ```
*/
tryGetMetaData(classFullName: string): EntityMetaData | undefined;
/** Invoke a callback on each property of the specified class, optionally including superclass properties.
* @param iModel The IModel that contains the schema
* @param classFullName The full class name to load the metadata, if necessary
* @param wantSuper If true, superclass properties will also be processed
* @param func The callback to be invoked on each property
* @param includeCustom If true (default), include custom-handled properties in the iteration. Otherwise, skip custom-handled properties.
* @note Custom-handled properties are core properties that have behavior enforced by C++ handlers.
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `forEachProperty` instead.
*
* @example
* ```typescript
* // Current usage:
* IModelDb.forEachMetaData(imodel, "BisCore:Element", true, (name: string, propMetaData: PropertyMetaData) => {
* console.log(`Property name: ${name}, Property type: ${propMetaData.primitiveType}`);
* }, false);
*
* // Replacement:
* await IModelDb.forEachProperty(imodel, "TestDomain.TestDomainClass", true, (propName: string, property: Property) => {
* console.log(`Property name: ${propName}, Property type: ${property.propertyType}`);
* }, false);
* ```
*/
static forEachMetaData(iModel: IModelDb, classFullName: string, wantSuper: boolean, func: PropertyCallback, includeCustom?: boolean): void;
/** Invoke a callback on each property of the specified class, optionally including superclass properties.
* @param classFullName The full class name to load the metadata, if necessary
* @param wantSuper If true, superclass properties will also be processed
* @param func The callback to be invoked on each property
* @param includeCustom If true (default), include custom-handled properties in the iteration. Otherwise, skip custom-handled properties.
* @note Custom-handled properties are core properties that have behavior enforced by C++ handlers.
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Use `forEachProperty` from `SchemaContext` class instead.
*
* @example
* ```typescript
* // Current usage:
* iModel.forEachMetaData("BisCore:Element", true, (name: string, propMetaData: PropertyMetaData) => {
* console.log(`Property name: ${name}, Property type: ${propMetaData.primitiveType}`);
* });
*
* // Replacement:
* imodel.schemaContext.forEachProperty("BisCore:Element", true, (propName: string, property: Property) => {
* console.log(`Property name: ${propName}, Property type: ${property.propertyType}`);
* });
* ```
*/
forEachMetaData(classFullName: string, wantSuper: boolean, func: PropertyCallback, includeCustom?: boolean): void;
/**
* @internal
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `schemaContext` from `iModel` instead to get metadata.
*/
private loadMetaData;
/** Returns the full schema for the input name.
* @param name The name of the schema e.g. 'BisCore'
* @returns The SchemaProps for the requested schema
* @throws if the schema can not be found or loaded.
*/
getSchemaProps(name: string): ECSchemaProps;
/** Query if this iModel contains the definition of the specified class.
* @param classFullName The full name of the class, for example, SomeSchema:SomeClass
* @returns true if the iModel contains the class definition or false if not.
* @see querySchemaVersion
* @see importSchema
*/
containsClass(classFullName: string): boolean;
/** Query the version of a schema of the specified name in this iModel.
* @returns The schema version as a semver-compatible string or `undefined` if the schema has not been imported.
*/
querySchemaVersion(schemaName: string): string | undefined;
/** Query the version of a schema of the specified name in this iModel.
* @returns the version numbers, or `undefined` if the schema has not been imported.
*/
querySchemaVersionNumbers(schemaName: string): ECVersion | undefined;
/** Retrieve a named texture image from this iModel, as a TextureData.
* @param props the texture load properties which must include the name of the texture to load
* @returns the TextureData or undefined if the texture image is not present.
* @alpha
*/
queryTextureData(props: TextureLoadProps): Promise<TextureData | undefined>;
/** Query a "file property" from this iModel, as a string.
* @returns the property string or undefined if the property is not present.
*/
queryFilePropertyString(prop: FilePropertyProps): string | undefined;
/** Query a "file property" from this iModel, as a blob.
* @returns the property blob or undefined if the property is not present.
*/
queryFilePropertyBlob(prop: FilePropertyProps): Uint8Array | undefined;
/** Save a "file property" to this iModel
* @param prop the FilePropertyProps that describes the new property
* @param value either a string or a blob to save as the file property
*/
saveFileProperty(prop: FilePropertyProps, strValue: string | undefined, blobVal?: Uint8Array): void;
/** delete a "file property" from this iModel
* @param prop the FilePropertyProps that describes the property
*/
deleteFileProperty(prop: FilePropertyProps): void;
/** Query for the next available major id for a "file property" from this iModel.
* @param prop the FilePropertyProps that describes the property
* @returns the next available (that is, an unused) id for prop. If none are present, will return 0.
*/
queryNextAvailableFileProperty(prop: FilePropertyProps): number;
/** @internal */
requestSnap(sessionId: string, props: SnapRequestProps): Promise<SnapResponseProps>;
/** Cancel a previously requested snap.
* @internal
*/
cancelSnap(sessionId: string): void;
/** Get the clip containment status for the supplied elements. */
getGeometryContainment(props: GeometryContainmentRequestProps): Promise<GeometryContainmentResponseProps>;
/** Get the mass properties for the supplied elements. */
getMassProperties(props: MassPropertiesRequestProps): Promise<MassPropertiesResponseProps>;
/** Get the IModel coordinate corresponding to each GeoCoordinate point in the input */
getIModelCoordinatesFromGeoCoordinates(props: IModelCoordinatesRequestProps): Promise<IModelCoordinatesResponseProps>;
/** Get the GeoCoordinate (longitude, latitude, elevation) corresponding to each IModel Coordinate point in the input */
getGeoCoordinatesFromIModelCoordinates(props: GeoCoordinatesRequestProps): Promise<GeoCoordinatesResponseProps>;
/** Export meshes suitable for graphics APIs from arbitrary geometry in elements in this IModelDb.
* * Requests can be slow when processing many elements so it is expected that this function be used on a dedicated backend,
* or that shared backends export a limited number of elements at a time.
* * Vertices are exported in the IModelDb's world coordinate system, which is right-handed with Z pointing up.
* * The results of changing [ExportGraphicsOptions]($core-backend) during the [ExportGraphicsOptions.onGraphics]($core-backend) callback are not defined.
*
* Example that prints the mesh for element 1 to stdout in [OBJ format](https://en.wikipedia.org/wiki/Wavefront_.obj_file)
* ```ts
* const onGraphics: ExportGraphicsFunction = (info: ExportGraphicsInfo) => {
* const mesh: ExportGraphicsMesh = info.mesh;
* for (let i = 0; i < mesh.points.length; i += 3) {
* process.stdout.write(`v ${mesh.points[i]} ${mesh.points[i + 1]} ${mesh.points[i + 2]}\n`);
* process.stdout.write(`vn ${mesh.normals[i]} ${mesh.normals[i + 1]} ${mesh.normals[i + 2]}\n`);
* }
*
* for (let i = 0; i < mesh.params.length; i += 2) {
* process.stdout.write(`vt ${mesh.params[i]} ${mesh.params[i + 1]}\n`);
* }
*
* for (let i = 0; i < mesh.indices.length; i += 3) {
* const p1 = mesh.indices[i];
* const p2 = mesh.indices[i + 1];
* const p3 = mesh.indices[i + 2];
* process.stdout.write(`f ${p1}/${p1}/${p1} ${p2}/${p2}/${p2} ${p3}/${p3}/${p3}\n`);
* }
* };
*
* iModel.exportGraphics(({ onGraphics, elementIdArray: ["0x1"] }));
* ```
* @returns 0 if successful, status otherwise
* @public
*/
exportGraphics(exportProps: ExportGraphicsOptions): DbResult;
/**
* Exports meshes suitable for graphics APIs from a specified [GeometryPart]($core-backend)
* in this IModelDb.
* The expected use case is to call [IModelDb.exportGraphics]($core-backend) and supply the
* optional partInstanceArray argument, then call this function for each unique GeometryPart from
* that list.
* * The results of changing [ExportPartGraphicsOptions]($core-backend) during the
* [ExportPartGraphicsOptions.onPartGraphics]($core-backend) callback are not defined.
* * See export-gltf under test-apps in the iTwin.js monorepo for a working reference.
* @returns 0 is successful, status otherwise
* @public
*/
exportPartGraphics(exportProps: ExportPartGraphicsOptions): DbResult;
/** Request geometry stream information from an element in binary format instead of json.
* @returns IModelStatus.Success if successful
* @beta
*/
elementGeometryRequest(requestProps: ElementGeometryRequest): IModelStatus;
/** Request the creation of a backend geometry cache for the specified geometric element.
* @returns ElementGeometryCacheResponseProps
* @beta
*/
updateElementGeometryCache(requestProps: ElementGeometryCacheRequestProps): Promise<ElementGeometryCacheResponseProps>;
/** Request operation using the backend geometry cache populated by first calling elementGeometryRequest.
* @returns SUCCESS if requested operation could be applied.
* @beta
*/
elementGeometryCacheOperation(requestProps: ElementGeometryCacheOperationRequestProps): BentleyStatus;
/** Create brep geometry for inclusion in an element's geometry stream.
* @returns IModelStatus.Success if successful
* @throws [[IModelError]] to report issues with input geometry or parameters
* @alpha
*/
createBRepGeometry(createProps: BRepGeometryCreate): IModelStatus;
/** Generate graphics for an element or geometry stream.
* @see [readElementGraphics]($frontend) to convert the result to a [RenderGraphic]($frontend) for display.
*/
generateElementGraphics(request: ElementGraphicsRequestProps): Promise<Uint8Array | undefined>;
private static _settingPropNamespace;
/** Save a `SettingDictionary` in this iModel that will be loaded into [[workspace.settings]] every time this iModel is opened in future sessions.
* @param name The name for the SettingDictionary. If a dictionary by that name already exists in the iModel, its value is replaced.
* @param dict The SettingDictionary object to stringify and save.
* @note All saved `SettingDictionary`s are loaded into [[workspace.settings]] every time an iModel is opened.
* @beta
*/
saveSettingDictionary(name: string, dict: SettingsContainer): void;
/** Delete a SettingDictionary, previously added with [[saveSettingDictionary]], from this iModel.
* @param name The name of the dictionary to delete.
* @beta
*/
deleteSettingDictionary(name: string): void;
/** Load all setting dictionaries in this iModel into `this.workspace.settings` */
private loadIModelSettings;
/** @internal */
protected loadWorkspaceSettings(): Promise<void>;
/**
* Controls how [Code]($common)s are copied from this iModel into another iModel, to work around problems with iModels
* created by older connectors. The [imodel-transformer](https://github.com/iTwin/imodel-transformer) sets this appropriately
* on your behalf - you should never need to set or interrogate this property yourself.
* @public
*/
get codeValueBehavior(): "exact" | "trim-unicode-whitespace";
set codeValueBehavior(newBehavior: "exact" | "trim-unicode-whitespace");
/** @internal */
computeRangesForText(args: ComputeRangesForTextLayoutArgs): TextLayoutRanges;
/** Writes the contents of a single ECSchema to a file on the local file system.
* @beta
*/
exportSchema(args: ExportSchemaArgs): void;
/** Writes the contents of all ECSchemas in this iModel to files in a directory on the local file system.
* @beta
*/
exportSchemas(outputDirectory: LocalFileName): void;
/** Attempt to simplify the geometry stream of a single [[GeometricElement]] or [[GeometryPart]] as specified by `args`.
* @beta
*/
simplifyElementGeometry(args: SimplifyElementGeometryArgs): IModelStatus;
/** Attempts to optimize all of the geometry in this iModel by identifying [[GeometryPart]]s that are referenced by exactly one
* element's geometry stream. Each such reference is replaced by inserting the part's geometry directly into the element's geometry stream.
* Then, the no-longer-used geometry part is deleted.
* This can improve performance when a connector inadvertently creates large numbers of parts that are each only used once.
* @beta
*/
inlineGeometryParts(): InlineGeometryPartsResult;
/** Returns a string representation of the error that most recently arose during an operation on the underlying SQLite database.
* If no errors have occurred, an empty string is returned.
* Otherwise, a string of the format `message (code)` is returned, where `message` is a human-readable diagnostic string and `code` is an integer status code.
* See [SQLite error codes and messages](https://www.sqlite.org/c3ref/errcode.html)
* @note Do not rely upon this value or its specific contents in error handling logic. It is only intended for use in debugging.
*/
getLastError(): string;
}
/** @public */
export declare namespace IModelDb {
/** The collection of models in an [[IModelDb]].
* @public @preview
*/
class Models {
private _iModel;
private readonly _modelCacheSize;
/** @internal */
readonly [_cache]: LRUMap<string, ModelProps>;
/** @internal */
readonly [_instanceKeyCache]: InstanceKeyLRUCache;
/** @internal */
constructor(_iModel: IModelDb);
/** Get the ModelProps with the specified identifier.
* @param modelId The Model identifier.
* @throws [[IModelError]] if the model is not found or cannot be loaded.
* @see tryGetModelProps
*/
getModelProps<T extends ModelProps>(id: Id64String): T;
/** Get the ModelProps with the specified identifier.
* @param modelId The Model identifier.
* @returns The ModelProps or `undefined` if the model is not found.
* @throws [[IModelError]] if the model cannot be loaded.
* @note Useful for cases when a model may or may not exist and throwing an `Error` would be overkill.
* @see getModelProps
*/
tryGetModelProps<T extends ModelProps>(id: Id64String): T | undefined;
/** Query for the last modified time for a [[Model]].
* @param modelId The Id of the model.
* @throws IModelError if `modelId` does not identify a model in the iModel.
*/
queryLastModifiedTime(modelId: Id64String): string;
/** Get the Model with the specified identifier.
* @param modelId The Model identifier.
* @param modelClass Optional class to validate instance against. This parameter can accept abstract or concrete classes, but should be the same as the template (`T`) parameter.
* @throws [[IModelError]] if the model is not found, cannot be loaded, or fails validation when `modelClass` is specified.
* @see tryGetModel
*/
getModel<T extends Model>(modelId: Id64String, modelClass?: EntityClassType<Model>): T;
/** Get the Model with the specified identifier.
* @param modelId The Model identifier.
* @param modelClass Optional class to validate instance against. This parameter can accept abstract or concrete classes, but should be the same as the template (`T`) parameter.
* @returns The Model or `undefined` if the model is not found or fails validation when `modelClass` is specified.
* @throws [[IModelError]] if the model cannot be loaded.
* @note Useful for cases when a model may or may not exist and throwing an `Error` would be overkill.
* @see getModel
*/
tryGetModel<T extends Model>(modelId: Id64String, modelClass?: EntityClassType<Model>): T | undefined;
private resolveModelKey;
/** Get the sub-model of the specified Element.
* See [[IModelDb.Elements.queryElementIdByCode]] for more on how to find an element by Code.
* @param modeledElementId Identifies the modeled element.
* @param modelClass Optional class to validate instance against. This parameter can accept abstract or concrete classes, but should be the same as the template (`T`) parameter.
* @throws [[IModelError]] if the sub-model is not found, cannot be loaded, or fails validation when `modelClass` is specified.
* @see tryGetSubModel
*/
getSubModel<T extends Model>(modeledElementId: Id64String | GuidString | Code, modelClass?: EntityClassType<Model>): T;
/** Get the sub-model of the specified Element.
* See [[IModelDb.Elements.queryElementIdByCode]] for more on how to find an element by Code.
* @param modeledElementId Identifies the modeled element.
* @param modelClass Optional class to validate instance against. This parameter can accept abstract or concrete classes, but should be the same as the template (`T`) parameter.
* @returns The sub-model or `undefined` if the specified element does not have a sub-model or fails validation when `modelClass` is specified.
* @see getSubModel
*/
tryGetSubModel<T extends Model>(modeledElementId: Id64String | GuidString | Code, modelClass?: EntityClassType<Model>): T | undefined;
/** Create a new model in memory.
* See the example in [[InformationPartitionElement]].
* @param modelProps The properties to use when creating the model.
* @throws [[IModelError]] if there is a problem creating the model.
*/
createModel<T extends Model>(modelProps: ModelProps): T;
/** Insert a new model.
* @param props The data for the new model.
* @returns The newly inserted model's Id.
* @throws [[IModelError]] if unable to insert the model.
*/
insertModel(props: ModelProps): Id64String;
/** Update an existing model.
* @param props