/** @packageDocumentation
 * @module iModels
 */
import { DbResult, Id64Arg, Id64Array, Id64Set, Id64String } from "@itwin/core-bentley";
import { EcefLocationProps, ElementAspectProps, ElementProps, FilePropertyProps, ModelProps, RelationshipProps, SaveChangesArgs } from "@itwin/core-common";
import { Range3dProps } from "@itwin/core-geometry";
import type { CloudSqlite } from "./CloudSqlite";
import type { ImplicitWriteEnforcement } from "./IModelHost";
import type { ChangeElementModelProps, ChangeElementParentProps, IModelDb, InsertElementOptions, UpdateModelOptions } from "./IModelDb";
import type { SettingsContainer } from "./workspace/Settings";
/** Options for bulk deleting elements from an iModelDb.
 * @beta
 */
export interface BulkDeleteElementsArgs {
    /**
     * Skips pre-deletion **NO ACTION** foreign key constraint validation checks, which may improve performance for large deletions.
     * This will improve performance, but if the user supplies elements which have FK constraint violations, it will result in the delete failing and an eventual rollback.
     */
    skipFKConstraintValidations?: boolean;
}
/**
 * Result of a bulk element delete operation.
 * @beta
 */
export interface BulkDeleteElementsResult {
    /**
     * Overall status of the bulk delete operation.
     * - `Success`: All elements were deleted successfully. `failedIds` will be empty.
     * - `PartialSuccess`: Some elements were deleted, but others failed. `failedIds` contains the ids that could not be deleted.
     * - `DeletionFailed`: The delete operation failed entirely (e.g. due to an FK constraint violation). `failedIds` contains the ids that could not be deleted.
     */
    status: BulkDeleteElementsStatus;
    /**
     * The raw SQLite result code from the underlying SQL DELETE statement.
     * `DbResult.BE_SQLITE_OK` on success; a non-OK code indicates a database-level error such as a constraint violation.
     */
    sqlDeleteStatus: DbResult;
    /**
     * The set of element ids that could not be deleted.
     * Empty when `status` is `Success`. Non-empty when `status` is `PartialSuccess` or `DeletionFailed`.
     */
    failedIds: Id64Set;
}
/**
 * Status of a bulk element delete operation, mirroring the C++ `BulkDeleteStatus` enum.
 * @beta
 */
export declare enum BulkDeleteElementsStatus {
    /** All supplied elements were deleted successfully. */
    Success = 0,
    /** Some elements were deleted but others could not be, typically due to foreign key constraints on the elements not being deleted. */
    PartialSuccess = 1,
    /** No elements were deleted. This occurs when the SQL DELETE statement itself fails, e.g. due to a FK constraint violation that prevents the entire batch from being processed. */
    DeletionFailed = 2
}
/**
 * Represents an explicit editing transaction for an iModel.
 *
 * An explicit EditTxn lets callers define a deliberate unit of work by choosing when editing
 * starts (`start`) and how it ends (`end()` / `end("save")` or `end("abandon")`). This avoids mixing
 * unrelated edits into one implicit unit of work and makes save/rollback boundaries explicit.
 *
 * Explicit EditTxn instances must be active before mutating operations are performed, regardless of enforcement level.
 * In other words, explicit transaction behavior is independent of `implicitWriteEnforcement`.
 *
 * @see [EditTxn transaction model and migration guidance]($docs/learning/backend/EditTxn.md)
 *
 * *During indirect changes (commit processing):* Use callback args (`indirectEditTxn`) in callbacks like
 * [[Relationship.onRootChangedArg]] and [[Relationship.onDeletedDependencyArg]] that fire during indirect processing.
 *
 * @beta
 */
export declare class EditTxn {
    /** Controls how writes through the implicit transaction are handled.
     *
     * This does not relax activation requirements for explicit transactions: explicit EditTxn writes
     * must always come from the active EditTxn.
     *
     * - `allow`: allow implicit writes for backwards compatibility, even while an explicit EditTxn is active.
     * - `log`: allow implicit writes but log `implicit-txn-write-disallowed` errors.
     * - `throw`: reject implicit writes with `implicit-txn-write-disallowed`.
     *
     * This is initialized from [[IModelHostOptions.implicitWriteEnforcement]] during [[IModelHost.startup]].
     *
     * Defaults to `allow` for backwards compatibility.
     * @beta
     */
    static implicitWriteEnforcement: ImplicitWriteEnforcement;
    /** The iModel this EditTxn may modify. */
    readonly iModel: IModelDb;
    /** Default description passed to [[saveChanges]] when saving this transaction. */
    description: string;
    /** True if this transaction currently owns the iModel write surface. */
    get isActive(): boolean;
    constructor(iModel: IModelDb, description: string);
    verifyWriteable(): void;
    /** Start this EditTxn, making it the active transaction for the iModel.
     * @throws EditTxnError if this EditTxn is already active, another EditTxn is already active, or if unsaved changes are present.
     */
    start(): void;
    /** End this EditTxn, either by saving or abandoning the changes.
     * @param mode Whether to "save" or "abandon" the changes. Defaults to "save".
     * @param args Save changes arguments when saving.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if saving changes fails.
     */
    end(): void;
    end(mode: "save" | "abandon", args?: string | SaveChangesArgs): void;
    /** Invoked when the owning iModel is closing.
     * The base implementation commits unsaved changes. Subclasses may override to customize how
     * their changes are handled before the iModel closes.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if saving on close fails.
     */
    onClose(): void;
    /** Abandon database changes while keeping this EditTxn active.
     * @throws EditTxnError if this EditTxn is not active.
     */
    abandonChanges(): void;
    /** Save changes with additional arguments.
     * @param args Save changes arguments.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if the iModel is readonly, if indirect changes are active, or if the native save fails.
     */
    saveChanges(args?: string | SaveChangesArgs): void;
    /** Insert a new element into the iModel.
     * @param elProps The properties of the new element.
     * @returns The newly inserted element's Id.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws [[ITwinError]] if insertion fails.
     */
    insertElement(elProps: ElementProps, options?: InsertElementOptions): Id64String;
    /** Update an existing element in the iModel.
     * @param elProps The properties to update.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws [[ITwinError]] if update fails.
     */
    updateElement<T extends ElementProps>(elProps: Partial<T>): void;
    /** Delete elements from the iModel.
     * @param ids The Ids of the elements to delete.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws [[ITwinError]] if deletion fails.
     */
    deleteElement(ids: Id64Arg): void;
    /** Change the parent of an element within its model.
     *
     * The new parent must be in the same model as the element. Cross-model reparenting is not allowed;
     * use [[changeElementModel]] only to move root elements between models.
     * Only the target element is reparented — its children and their model membership are unaffected.
     *
     * **Blocked cases** (will throw):
     * - The new parent is in a different model than the element.
     * - Element has a `ParentElement`-scoped code (code uniqueness is tied to the parent; use delete+insert instead).
     *
     * **Allowed cases**:
     * - Element has a `Repository`-scoped code (unique across entire iModel — unaffected by the parent change).
     * - Element has a `RelatedElement`-scoped code (scope element is independent of the parent).
     * - Element has a `Model`-scoped code (the model does not change, so the code remains valid).
     * - Element has no meaningful code (empty code).
     *
     * Channel verification is performed on the element's model.
     * Lock enforcement: requires an exclusive lock on the element, and a shared lock on the new parent.
     * @param props The reparent parameters: element id and new parent id.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws [[ITwinError]] if the operation fails.
     * @beta
     */
    changeElementParent(props: ChangeElementParentProps): void;
    /** Change the model of a root element, making it a root element in the new model.
     *
     * The element must not have a parent.
     * The element's entire subtree moves with it: BIS requires a parent and all of its children to reside
     * in the same model, so every descendant of the element is relocated into the target model as well.
     * The parent-child hierarchy is preserved. The whole subtree is validated before anything is moved, so
     * a rejected change leaves the iModel untouched.
     *
     * **Blocked cases** (will throw):
     * - Element has a parent (only root elements can be moved between models).
     * - Any element in the subtree has a `Model`-scoped code (code uniqueness is tied to the source model; use delete+insert instead).
     * - The moved (root) element has a `ParentElement`-scoped code (use delete+insert instead). A descendant's `ParentElement`-scoped code is allowed, because its parent moves with it.
     *
     * **Allowed cases** (for any element in the subtree):
     * - A `Repository`-scoped code (unique across entire iModel — unaffected by the model change).
     * - A `RelatedElement`-scoped code (scope element is independent of the model).
     * - No meaningful code (empty code).
     *
     * The source and target models must be of the same class (classFullName must match exactly).
     * Channel verification is performed on both the source and target models.
     * Lock enforcement: requires an exclusive lock on every element in the moved subtree, and a shared lock on the target model.
     * @param props The model change parameters: element id and target model id.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws [[ITwinError]] if the operation fails.
     * @beta
     */
    changeElementModel(props: ChangeElementModelProps): void;
    /** Collect an element together with all of its descendants by walking the `ElementOwnsChildElements`
     * hierarchy depth-first. Used to invalidate the cached props of every element affected by a subtree move.
     */
    private collectSubtreeIds;
    /**
     * Delete multiple elements from the iModel.
     * @param ids The ids of the elements to delete. All ids must be well-formed and valid [[Id64String]]s.
     * @param deleteOptions Options for the delete operation.
     * @returns A result object containing information about the deletion operation success and the element ids that failed to delete (if any).
     * @throws [[ITwinError]] if any of the supplied ids are not well-formed/valid [[Id64String]]s.
     * @beta
     */
    deleteElements(ids: Id64Array, deleteOptions?: BulkDeleteElementsArgs): BulkDeleteElementsResult;
    /** Insert a new aspect into the iModel.
     * @param aspectProps The properties of the new aspect.
     * @returns The newly inserted aspect Id.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if insertion fails.
     */
    insertAspect(aspectProps: ElementAspectProps): Id64String;
    /** Update an existing aspect in the iModel.
     * @param aspectProps The properties of the aspect to update.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if update fails.
     */
    updateAspect(aspectProps: ElementAspectProps): void;
    /** Delete one or more aspects from the iModel.
     * @param aspectInstanceIds The Ids of the aspects to delete.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if deletion fails.
     */
    deleteAspect(aspectInstanceIds: Id64Arg): void;
    /** Delete definition elements from the iModel when they are not referenced.
     * @param definitionElementIds The Ids of the definition elements to attempt to delete.
     * @returns The set of definition elements that were still in use and therefore not deleted.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if usage queries fail.
     */
    deleteDefinitionElements(definitionElementIds: Id64Array): Id64Set;
    /** Insert a new model into the iModel.
     * @param props The data for the new model.
     * @returns The newly inserted model's Id.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if insertion fails.
     */
    insertModel(props: ModelProps): Id64String;
    /** Update an existing model in the iModel.
     * @param props the properties of the model to change
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if update fails.
     */
    updateModel(props: UpdateModelOptions): void;
    /** Update the geometry guid of a model.
     * @param modelId The Id of the model to update.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if the update fails.
     */
    updateGeometryGuid(modelId: Id64String): void;
    /** Delete models from the iModel.
     * @param ids The Ids of the models to delete.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if deletion fails.
     */
    deleteModel(ids: Id64Arg): void;
    /** Insert a new relationship into the iModel.
     * @param props The properties of the new relationship.
     * @returns The Id of the newly inserted relationship.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if the class is invalid for link-table insertion.
     */
    insertRelationship(props: RelationshipProps): Id64String;
    /** Update an existing relationship in the iModel.
     * @param props the properties of the relationship to update.
     * @throws EditTxnError if this EditTxn is not active.
     */
    updateRelationship(props: RelationshipProps): void;
    /** Delete a relationship from the iModel.
     * @param props The properties of the relationship to delete.
     * @throws EditTxnError if this EditTxn is not active.
     */
    deleteRelationship(props: RelationshipProps): void;
    /** Delete multiple relationships from the iModel.
     * @param props The properties of the relationships to delete.
     * @throws EditTxnError if this EditTxn is not active.
     */
    deleteRelationships(props: ReadonlyArray<RelationshipProps>): void;
    /** Save a file property to the iModel.
     * @param prop The file property to save.
     * @param strValue String value.
     * @param blobVal Blob value.
     * @throws EditTxnError if this EditTxn is not active.
     */
    saveFileProperty(prop: FilePropertyProps, strValue: string | undefined, blobVal?: Uint8Array): void;
    /** Delete a file property from the iModel.
     * @param prop The file property to delete.
     * @throws EditTxnError if this EditTxn is not active.
     */
    deleteFileProperty(prop: FilePropertyProps): void;
    /** Update the project extents of the iModel.
     * @param newExtents The new project extents.
     * @throws EditTxnError if this EditTxn is not active.
     * @throws IModelError if extents are invalid.
     */
    updateProjectExtents(newExtents: Range3dProps): void;
    /** Update the ECEF location of the iModel.
     * @param ecef The new ECEF location.
     * @throws EditTxnError if this EditTxn is not active.
     */
    updateEcefLocation(ecef: EcefLocationProps): void;
    /** Update the iModel props in the database from the current in-memory state.
     * @throws EditTxnError if this EditTxn is not active.
     */
    updateIModelProps(): void;
    private static readonly _settingPropNamespace;
    private static readonly _viewStoreProperty;
    /** Save a `SettingDictionary` in this iModel.
     * @param name The name for the SettingDictionary. If a dictionary by that name already exists, its value is replaced.
     * @param dict The SettingDictionary object to stringify and save.
     * @throws EditTxnError if this EditTxn is not active.
     * @beta
     */
    saveSettingDictionary(name: string, dict: SettingsContainer): void;
    /** Delete a SettingDictionary from this iModel.
     * @param name The name of the dictionary to delete.
     * @throws EditTxnError if this EditTxn is not active.
     * @beta
     */
    deleteSettingDictionary(name: string): void;
    /** Save a default ViewStore container reference in this iModel.
     * @param arg The cloud container properties for the ViewStore.
     * @throws EditTxnError if this EditTxn is not active.
     * @beta
     */
    saveDefaultViewStore(arg: CloudSqlite.ContainerProps): void;
}
/** Execute a callback within an explicit editing transaction. A new [[EditTxn]] is created, started,
 * and passed to `fn`. If `fn` returns normally (or its returned Promise resolves), the transaction
 * is committed. If `fn` throws (or its returned Promise rejects), the transaction is abandoned —
 * none of the changes made during the callback are saved — and the error is re-thrown.
 *
 * This is the recommended way to perform a scoped unit of work on an iModel. It ensures that
 * edits are committed atomically on success and rolled back on failure, without the caller needing
 * to manage `start` / `end` manually.
 *
 * @param iModel The iModel to edit.
 * @param fn A callback that receives the active [[EditTxn]] and performs edits.
 * @returns The value returned by `fn`.
 * @throws EditTxnError if the transaction cannot be started (e.g. unsaved changes or another EditTxn is active).
 * @throws Re-throws any error thrown by `fn` after abandoning the transaction.
 * @beta
 */
export declare function withEditTxn<T>(iModel: IModelDb, fn: (txn: EditTxn) => T): T;
/** Execute a callback within an explicit editing transaction, supplying commit arguments.
 * @param iModel The iModel to edit.
 * @param saveArgs Description or structured arguments passed to [[EditTxn.saveChanges]] on save.
 * @param fn A callback that receives the active [[EditTxn]] and performs edits.
 * @returns The value returned by `fn`.
 * @beta
 */
export declare function withEditTxn<T>(iModel: IModelDb, saveArgs: string | SaveChangesArgs, fn: (txn: EditTxn) => T): T;
/** Execute an async callback within an explicit editing transaction.
 * @param iModel The iModel to edit.
 * @param fn An async callback that receives the active [[EditTxn]] and performs edits.
 * @returns A Promise that resolves to the value returned by `fn`.
 * @beta
 */
export declare function withEditTxn<T>(iModel: IModelDb, fn: (txn: EditTxn) => Promise<T>): Promise<T>;
/** Execute an async callback within an explicit editing transaction, supplying commit arguments.
 * @param iModel The iModel to edit.
 * @param saveArgs Description or structured arguments passed to [[EditTxn.saveChanges]] on save.
 * @param fn An async callback that receives the active [[EditTxn]] and performs edits.
 * @returns A Promise that resolves to the value returned by `fn`.
 * @beta
 */
export declare function withEditTxn<T>(iModel: IModelDb, saveArgs: string | SaveChangesArgs, fn: (txn: EditTxn) => Promise<T>): Promise<T>;
//# sourceMappingURL=EditTxn.d.ts.map