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;
  /**
   * 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;
}
