@itwin/core-backend
Version:
iTwin.js backend components
296 lines • 15.7 kB
TypeScript
/** @packageDocumentation
* @module iModels
*/
import { BeEvent, DbConflictResolution, DbResult, Id64String, IModelStatus } from "@itwin/core-bentley";
import { EntityIdAndClassIdIterable, ModelGeometryChangesProps, ModelIdAndGeometryGuid } from "@itwin/core-common";
import { BriefcaseDb, StandaloneDb } from "./IModelDb";
import { RelationshipProps } from "./Relationship";
import { DbRebaseChangesetConflictArgs, RebaseChangesetConflictArgs, TxnArgs } from "./internal/ChangesetConflictArgs";
/** A string that identifies a Txn.
* @public @preview
*/
export type TxnIdString = string;
/** An error generated during dependency validation.
* @see [[TxnManager.validationErrors]].
* @public @preview
*/
export interface ValidationError {
/** If true, txn is aborted. */
fatal: boolean;
/** The type of error. */
errorType: string;
/** Optional description of what went wrong. */
message?: string;
}
/** Describes a set of [[Element]]s or [[Model]]s that changed as part of a transaction.
* @see [[TxnManager.onElementsChanged]] and [[TxnManager.onModelsChanged]].
* @public @preview
*/
export interface TxnChangedEntities {
/** The entities that were inserted by the transaction. */
readonly inserts: EntityIdAndClassIdIterable;
/** The entities that were deleted by the transaction. */
readonly deletes: EntityIdAndClassIdIterable;
/** The entities that were modified by the transaction, including any [[Element]]s for which one of their [[ElementAspect]]s was changed. */
readonly updates: EntityIdAndClassIdIterable;
}
/** Arguments supplied to [[TxnManager.queryLocalChanges]].
* @beta
*/
export interface QueryLocalChangesArgs {
/** If supplied and non-empty, restricts the results to include only EC instances belonging to the specified classes or subclasses thereof. */
readonly includedClasses?: string[];
/** If `true`, include changes that have not yet been saved. */
readonly includeUnsavedChanges?: boolean;
}
/** Represents a change (insertion, deletion, or modification) to a single EC instance made in a local [[BriefcaseDb]].
* @see [[TxnManager.queryLocalChanges]] to iterate all of the changed instances.
* @beta
*/
export interface ChangeInstanceKey {
/** ECInstanceId of the instance. */
id: Id64String;
/** Fully-qualified class name of the instance. */
classFullName: string;
/** The type of change. */
changeType: "inserted" | "updated" | "deleted";
}
/** Strictly for tests. @internal */
export declare function setMaxEntitiesPerEvent(max: number): number;
/**
* @internal
* Manages conflict resolution during a merge operation.
*/
export declare class ChangeMergeManager {
private _iModel;
private _conflictHandlers?;
constructor(_iModel: BriefcaseDb | StandaloneDb);
resume(): void;
inProgress(): boolean;
onConflict(args: RebaseChangesetConflictArgs): DbConflictResolution | undefined;
addConflictHandler(args: {
id: string;
handler: (args: RebaseChangesetConflictArgs) => DbConflictResolution | undefined;
}): void;
removeConflictHandler(id: string): void;
}
/** Manages local changes to a [[BriefcaseDb]] or [[StandaloneDb]] via [Txns]($docs/learning/InteractiveEditing.md)
* @public @preview
*/
export declare class TxnManager {
private _iModel;
/** @internal */
private _isDisposed;
/** @internal */
get isDisposed(): boolean;
/** @internal */
readonly changeMergeManager: ChangeMergeManager;
/** @internal */
constructor(_iModel: BriefcaseDb | StandaloneDb);
/** Array of errors from dependency propagation */
readonly validationErrors: ValidationError[];
private get _nativeDb();
private _getElementClass;
private _getRelationshipClass;
/** If a -watch file exists for this iModel, update its timestamp so watching processes can be
* notified that we've modified the briefcase.
* @internal Used by IModelDb on push/pull.
*/
touchWatchFile(): void;
/** @internal */
protected _onBeforeOutputsHandled(elClassName: string, elId: Id64String): void;
/** @internal */
protected _onAllInputsHandled(elClassName: string, elId: Id64String): void;
/** @internal */
protected _onRootChanged(props: RelationshipProps): void;
/** @internal */
protected _onDeletedDependency(props: RelationshipProps): void;
/** @internal */
protected _onBeginValidate(): void;
/** called from native code after validation of a Txn, either from saveChanges or apply changeset.
* @internal
*/
protected _onEndValidate(): void;
/** @internal */
protected _onGeometryChanged(modelProps: ModelGeometryChangesProps[]): void;
/** @internal */
protected _onGeometryGuidsChanged(changes: ModelIdAndGeometryGuid[]): void;
/** @internal */
protected _onCommit(): void;
/** @internal */
protected _onCommitted(): void;
/** @internal */
protected _onReplayExternalTxns(): void;
/** @internal */
protected _onReplayedExternalTxns(): void;
/** @internal */
protected _onChangesApplied(): void;
/** @internal */
protected _onBeforeUndoRedo(isUndo: boolean): void;
/** @internal */
protected _onAfterUndoRedo(isUndo: boolean): void;
private _onRebaseTxnBegin;
private _onRebaseTxnEnd;
private _onRebaseLocalTxnConflict;
/** Dependency handlers may call method this to report a validation error.
* @param error The error. If error.fatal === true, the transaction will cancel rather than commit.
*/
reportError(error: ValidationError): void;
/** Determine whether any fatal validation errors have occurred during dependency propagation. */
get hasFatalError(): boolean;
/** @internal */
readonly onEndValidation: BeEvent<() => void>;
/** Called after validation completes from [[IModelDb.saveChanges]].
* The argument to the event holds the list of elements that were inserted, updated, and deleted.
* @note If there are many changed elements in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
*/
readonly onElementsChanged: BeEvent<(changes: TxnChangedEntities) => void>;
/** Called after validation completes from [[IModelDb.saveChanges]].
* The argument to the event holds the list of models that were inserted, updated, and deleted.
* @note If there are many changed models in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
*/
readonly onModelsChanged: BeEvent<(changes: TxnChangedEntities) => void>;
/** Event raised after the geometry within one or more [[GeometricModel]]s is modified by applying a changeset or validation of a transaction.
* A model's geometry can change as a result of:
* - Insertion or deletion of a geometric element within the model; or
* - Modification of an existing element's geometric properties; or
* - An explicit request to flag it as changed via [[IModelDb.Models.updateModel]].
*/
readonly onModelGeometryChanged: BeEvent<(changes: ReadonlyArray<ModelIdAndGeometryGuid>) => void>;
readonly onGeometryChanged: BeEvent<(models: ModelGeometryChangesProps[]) => void>;
/** Event raised before a commit operation is performed. Initiated by a call to [[IModelDb.saveChanges]], unless there are no changes to save. */
readonly onCommit: BeEvent<() => void>;
/** Event raised after a commit operation has been performed. Initiated by a call to [[IModelDb.saveChanges]], even if there were no changes to save. */
readonly onCommitted: BeEvent<() => void>;
/** Event raised after a ChangeSet has been applied to this briefcase */
readonly onChangesApplied: BeEvent<() => void>;
/** Event raised before an undo/redo operation is performed. */
readonly onBeforeUndoRedo: BeEvent<(isUndo: boolean) => void>;
/** Event raised after an undo/redo operation has been performed.
* @param _action The action that was performed.
*/
readonly onAfterUndoRedo: BeEvent<(isUndo: boolean) => void>;
/** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
* @see [[onReplayedExternalTxns]] for the event raised after all such changes have been applied.
*/
readonly onReplayExternalTxns: BeEvent<() => void>;
/** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
* @see [[onReplayExternalTxns]] for the event raised before the changes are applied.
*/
readonly onReplayedExternalTxns: BeEvent<() => void>;
/** @internal */
readonly onRebaseTxnBegin: BeEvent<(txn: TxnArgs) => void>;
/** @internal */
readonly onRebaseTxnEnd: BeEvent<(txn: TxnArgs) => void>;
/**
* if handler is set and it does not return undefiend then default handler will not be called
* @internal
* */
appCustomConflictHandler?: (args: DbRebaseChangesetConflictArgs) => DbConflictResolution | undefined;
/**
* Restart the current TxnManager session. This causes all Txns in the current session to no longer be undoable (as if the file was closed
* and reopened.)
* @note This can be quite disconcerting to the user expecting to be able to undo previously made changes. It should only be used
* under extreme circumstances where damage to the file or session could happen if the currently committed are reversed. Use sparingly and with care.
* Probably a good idea to alert the user it happened.
*/
restartSession(): void;
/** Determine whether current txn is propagating indirect changes or not. */
get isIndirectChanges(): boolean;
/** Determine if there are currently any reversible (undoable) changes from this editing session. */
get isUndoPossible(): boolean;
/** Determine if there are currently any reinstatable (redoable) changes */
get isRedoPossible(): boolean;
/** Get the description of the operation that would be reversed by calling reverseTxns(1).
* This is useful for showing the operation that would be undone, for example in a menu.
*/
getUndoString(): string;
/** Get a description of the operation that would be reinstated by calling reinstateTxn.
* This is useful for showing the operation that would be redone, in a pull-down menu for example.
*/
getRedoString(): string;
/** Begin a new multi-Txn operation. This can be used to cause a series of Txns that would normally
* be considered separate actions for undo to be grouped into a single undoable operation. This means that when reverseTxns(1) is called,
* the entire group of changes are undone together. Multi-Txn operations can be nested and until the outermost operation is closed
* all changes constitute a single operation.
* @note This method must always be paired with a call to endMultiTxnAction.
*/
beginMultiTxnOperation(): DbResult;
/** End a multi-Txn operation */
endMultiTxnOperation(): DbResult;
/** Return the depth of the multi-Txn stack. Generally for diagnostic use only. */
getMultiTxnOperationDepth(): number;
/** Reverse (undo) the most recent operation(s) to this IModelDb.
* @param numOperations the number of operations to reverse. If this is greater than 1, the entire set of operations will
* be reinstated together when/if ReinstateTxn is called.
* @note If there are any outstanding uncommitted changes, they are reversed.
* @note The term "operation" is used rather than Txn, since multiple Txns can be grouped together via [[beginMultiTxnOperation]]. So,
* even if numOperations is 1, multiple Txns may be reversed if they were grouped together when they were made.
* @note If numOperations is too large only the operations are reversible are reversed.
*/
reverseTxns(numOperations: number): IModelStatus;
/** Reverse the most recent operation. */
reverseSingleTxn(): IModelStatus;
/** Reverse all changes back to the beginning of the session. */
reverseAll(): IModelStatus;
/** Reverse all changes back to a previously saved TxnId.
* @param txnId a TxnId obtained from a previous call to GetCurrentTxnId.
* @returns Success if the transactions were reversed, error status otherwise.
* @see [[getCurrentTxnId]] [[cancelTo]]
*/
reverseTo(txnId: TxnIdString): IModelStatus;
/** Reverse and then cancel (make non-reinstatable) all changes back to a previous TxnId.
* @param txnId a TxnId obtained from a previous call to [[getCurrentTxnId]]
* @returns Success if the transactions were reversed and cleared, error status otherwise.
*/
cancelTo(txnId: TxnIdString): IModelStatus;
/** Reinstate the most recently reversed transaction. Since at any time multiple transactions can be reversed, it
* may take multiple calls to this method to reinstate all reversed operations.
* @returns Success if a reversed transaction was reinstated, error status otherwise.
* @note If there are any outstanding uncommitted changes, they are canceled before the Txn is reinstated.
*/
reinstateTxn(): IModelStatus;
/** Get the Id of the first transaction, if any.
*/
queryFirstTxnId(): TxnIdString;
/** Get the successor of the specified TxnId */
queryNextTxnId(txnId: TxnIdString): TxnIdString;
/** Get the predecessor of the specified TxnId */
queryPreviousTxnId(txnId: TxnIdString): TxnIdString;
/** Get the Id of the current (tip) transaction. */
getCurrentTxnId(): TxnIdString;
/** Get the description that was supplied when the specified transaction was saved. */
getTxnDescription(txnId: TxnIdString): string;
/** Test if a TxnId is valid */
isTxnIdValid(txnId: TxnIdString): boolean;
/** Query if there are any pending Txns in this IModelDb that are waiting to be pushed.
* @see [[IModelDb.pushChanges]]
*/
get hasPendingTxns(): boolean;
/**
* Query if there are any changes in memory that have yet to be saved to the IModelDb.
* @see [[IModelDb.saveChanges]]
*/
get hasUnsavedChanges(): boolean;
/**
* Query if there are changes in memory that have not been saved to the iModelDb or if there are Txns that are waiting to be pushed.
* @see [[IModelDb.saveChanges]]
* @see [[IModelDb.pushChanges]]
*/
get hasLocalChanges(): boolean;
/** Destroy the record of all local changes that have yet to be saved and/or pushed.
* This permanently eradicates your changes - use with caution!
* Typically, callers will want to subsequently use [[LockControl.releaseAllLocks]].
* After calling this function, [[hasLocalChanges]], [[hasPendingTxns]], and [[hasUnsavedChanges]] will all be `false`.
*/
deleteAllTxns(): void;
/** Obtain a list of the EC instances that have been changed locally by the [[BriefcaseDb]] associated with this `TxnManager` and have not yet been pushed to the iModel.
* @beta
*/
queryLocalChanges(args?: QueryLocalChangesArgs): Iterable<ChangeInstanceKey>;
/** Query the number of bytes of memory currently allocated by SQLite to keep track of
* changes to the iModel, for debugging/diagnostic purposes, as reported by [sqlite3session_memory_used](https://www.sqlite.org/session/sqlite3session_memory_used.html).
*/
getChangeTrackingMemoryUsed(): number;
}
//# sourceMappingURL=TxnManager.d.ts.map