import type { Dictionary, EntityDictionary, EntityMetadata } from '../typings.js';
import { type ChangeSet } from './ChangeSet.js';
import type { DriverMethodOptions } from '../drivers/IDatabaseDriver.js';
import type { EntityManager } from '../EntityManager.js';
/** @internal Executes change sets against the database, handling inserts, updates, and deletes. */
export declare class ChangeSetPersister {
    #private;
    constructor(em: EntityManager);
    /** Executes all pending INSERT change sets, using batch inserts when possible. */
    executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
    /** Executes all pending UPDATE change sets, using batch updates when possible. */
    executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
    /** Executes all pending DELETE change sets in batches. */
    executeDeletes<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
    private runForEachSchema;
    private validateRequired;
    private processProperties;
    private persistNewEntity;
    private persistNewEntities;
    private prepareOptions;
    private persistNewEntitiesBatch;
    private persistManagedEntity;
    private persistManagedEntities;
    private checkConcurrencyKeys;
    private persistManagedEntitiesBatch;
    private mapPrimaryKey;
    /**
     * After INSERT + hydration, sync all EntityIdentifier placeholders in composite PK arrays
     * with the real values now present on the entity. This is needed because `mapPrimaryKey`
     * only handles the first PK column, but any scalar PK in a composite key may be auto-generated.
     */
    private syncCompositeIdentifiers;
    /**
     * Sets populate flag to new entities so they are serialized like if they were loaded from the db
     */
    private markAsPopulated;
    private updateEntity;
    private checkOptimisticLocks;
    private checkOptimisticLock;
    /**
     * This method also handles reloading of database default values for inserts and raw property updates,
     * so we use a single query in case of both versioning and default values is used.
     */
    private reloadVersionValues;
    /**
     * For TPT child tables, resolve EntityIdentifier values in PK fields.
     * The parent table insert assigns the actual PK value, which the child table references.
     */
    private resolveTPTIdentifiers;
    private processProperty;
    /**
     * Maps values returned via `returning` statement (postgres) or the inserted id (other sql drivers).
     * No need to handle composite keys here as they need to be set upfront.
     * We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
     */
    mapReturnedValues<T extends object>(entity: T | null | undefined, payload: EntityDictionary<T>, row: Dictionary | undefined, meta: EntityMetadata<T>, upsert?: boolean): void;
}
