import { EntityRepository } from '../entity/EntityRepository.js';
import { type NamingStrategy } from '../naming-strategy/NamingStrategy.js';
import type { Constructor, EntityMetadata, EntityProperty, IPrimaryKey, ISchemaGenerator, PopulateOptions, Primary, SimpleColumnMeta, FilterQuery, EntityValue, EntityKey } from '../typings.js';
import { ExceptionConverter } from './ExceptionConverter.js';
import type { EntityManager } from '../EntityManager.js';
import type { Configuration } from '../utils/Configuration.js';
import type { IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
import { Type } from '../types/index.js';
import type { MikroORM } from '../MikroORM.js';
import type { TransformContext } from '../types/Type.js';
import { Raw } from '../utils/RawQueryFragment.js';
/** Symbol used to tag cloned embeddable data for JSON serialization handling. */
export declare const JsonProperty: unique symbol;
/** Abstract base class providing database-specific behavior and SQL dialect differences. */
export declare abstract class Platform {
    protected readonly exceptionConverter: ExceptionConverter;
    protected config: Configuration;
    protected namingStrategy: NamingStrategy;
    protected timezone?: string;
    /** Whether this driver uses pivot tables for M:N relations (SQL drivers do, MongoDB does not). */
    usesPivotTable(): boolean;
    /** Whether this driver supports database transactions. */
    supportsTransactions(): boolean;
    /** Whether the driver wraps operations in implicit transactions by default. */
    usesImplicitTransactions(): boolean;
    /** Returns the default naming strategy constructor for this platform. */
    getNamingStrategy(): {
        new (): NamingStrategy;
    };
    /** Whether the driver supports RETURNING clause (e.g. PostgreSQL). */
    usesReturningStatement(): boolean;
    /** Whether the driver supports OUTPUT clause (e.g. MSSQL). */
    usesOutputStatement(): boolean;
    /** Whether DELETE statements require explicit CASCADE keyword. */
    usesCascadeStatement(): boolean;
    /** for postgres native enums */
    supportsNativeEnums(): boolean;
    /** for postgres text enums (default) */
    usesEnumCheckConstraints(): boolean;
    /** Returns the check constraint expression for an enum column. */
    getEnumCheckConstraintExpression(column: string, items: string[]): string;
    /** Returns the check constraint expression for an enum array column, or null if unsupported. */
    getEnumArrayCheckConstraintExpression(column: string, items: string[]): string | null;
    /** Whether this platform supports materialized views. */
    supportsMaterializedViews(): boolean;
    /** Whether this platform supports declarative table partitioning in schema generation. */
    supportsPartitionedTables(): boolean;
    /** Returns the schema helper instance for this platform, or undefined if not supported. */
    getSchemaHelper(): unknown;
    /** Whether the platform automatically creates indexes on foreign key columns. */
    indexForeignKeys(): boolean;
    /**
     * Whether or not the driver supports retuning list of created PKs back when multi-inserting
     */
    usesBatchInserts(): boolean;
    /**
     * Whether or not the driver supports updating many records at once
     */
    usesBatchUpdates(): boolean;
    /** Whether the platform supports the DEFAULT keyword in INSERT statements. */
    usesDefaultKeyword(): boolean;
    /**
     * Normalizes primary key wrapper to scalar value (e.g. mongodb's ObjectId to string)
     */
    normalizePrimaryKey<T extends number | string = number | string>(data: Primary<T> | IPrimaryKey): T;
    /**
     * Converts scalar primary key representation to native driver wrapper (e.g. string to mongodb's ObjectId)
     */
    denormalizePrimaryKey(data: IPrimaryKey): IPrimaryKey;
    /**
     * Returns the SQL specific for the platform to get the current timestamp
     */
    getCurrentTimestampSQL(length?: number): string;
    /** Returns the SQL type declaration for datetime columns. */
    getDateTimeTypeDeclarationSQL(column: {
        length?: number;
    }): string;
    /** Returns the default fractional seconds precision for datetime columns. */
    getDefaultDateTimeLength(): number;
    /** Returns the default length for varchar columns. */
    getDefaultVarcharLength(): number;
    /** Returns the default length for char columns. */
    getDefaultCharLength(): number;
    /** Returns the SQL type declaration for date columns. */
    getDateTypeDeclarationSQL(length?: number): string;
    /** Returns the SQL type declaration for time columns. */
    getTimeTypeDeclarationSQL(length?: number): string;
    /** Returns the SQL operator used for regular expression matching. */
    getRegExpOperator(val?: unknown, flags?: string): string;
    /** Builds the SQL clause and parameters for a regular expression condition. */
    mapRegExpCondition(mappedKey: string, value: {
        $re: string;
        $flags?: string;
    }): {
        sql: string;
        params: unknown[];
    };
    /** Converts a JavaScript RegExp into a platform-specific regex representation. */
    getRegExpValue(val: RegExp): {
        $re: string;
        $flags?: string;
    };
    /** Whether the given operator is allowed at the top level of a query condition. */
    isAllowedTopLevelOperator(operator: string): boolean;
    /** Converts a version field value for comparison in optimistic locking queries. */
    convertVersionValue(value: Date | number, prop: EntityProperty): Date | string | number | {
        $in: (string | number)[];
    };
    /** Returns the default fractional seconds precision for version timestamp columns. */
    getDefaultVersionLength(): number;
    /** Whether the platform supports tuple comparison in WHERE clauses. */
    allowsComparingTuples(): boolean;
    /** Whether the given property maps to a bigint database column. */
    isBigIntProperty(prop: EntityProperty): boolean;
    /** Returns the default schema name for this platform (e.g. "public" for PostgreSQL). */
    getDefaultSchemaName(): string | undefined;
    /** Returns the SQL type declaration for boolean columns. */
    getBooleanTypeDeclarationSQL(): string;
    /** Returns the SQL type declaration for integer columns. */
    getIntegerTypeDeclarationSQL(column: {
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getSmallIntTypeDeclarationSQL(column: {
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getMediumIntTypeDeclarationSQL(column: {
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getTinyIntTypeDeclarationSQL(column: {
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getBigIntTypeDeclarationSQL(column: {
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getCharTypeDeclarationSQL(column: {
        length?: number;
    }): string;
    getVarcharTypeDeclarationSQL(column: {
        length?: number;
    }): string;
    getIntervalTypeDeclarationSQL(column: {
        length?: number;
    }): string;
    getTextTypeDeclarationSQL(_column: {
        length?: number;
    }): string;
    getEnumTypeDeclarationSQL(column: {
        items?: unknown[];
        fieldNames: string[];
        length?: number;
        unsigned?: boolean;
        autoincrement?: boolean;
    }): string;
    getFloatDeclarationSQL(): string;
    getDoubleDeclarationSQL(): string;
    getDecimalTypeDeclarationSQL(column: {
        precision?: number;
        scale?: number;
    }): string;
    getUuidTypeDeclarationSQL(column: {
        length?: number;
    }): string;
    /** Extracts the base type name from a full SQL type declaration (e.g. `varchar(255)` -> `varchar`). */
    extractSimpleType(type: string): string;
    /**
     * This should be used only to compare types, it can strip some information like the length.
     */
    normalizeColumnType(type: string, options: {
        length?: number;
        precision?: number;
        scale?: number;
    }): string;
    /** Returns the mapped Type instance for a given SQL/runtime type string. */
    getMappedType(type: string): Type<unknown>;
    /** Returns the default mapped Type for a given type string when no custom mapping is configured. */
    getDefaultMappedType(type: string): Type<unknown>;
    /** Whether the platform supports multiple cascade paths to the same table. */
    supportsMultipleCascadePaths(): boolean;
    /**
     * Returns true if the platform supports ON UPDATE foreign key rules.
     * Oracle doesn't support ON UPDATE rules.
     */
    supportsOnUpdate(): boolean;
    /** Whether the connection supports executing multiple SQL statements in a single call. */
    supportsMultipleStatements(): boolean;
    /** Whether the platform supports the UNION WHERE optimization for multi-branch queries. */
    supportsUnionWhere(): boolean;
    /** Returns the SQL type declaration used for array storage. */
    getArrayDeclarationSQL(): string;
    /** Serializes a string array into its database storage format. */
    marshallArray(values: string[]): string;
    /** Deserializes a database-stored array string back into a string array. */
    unmarshallArray(value: string): string[];
    getBlobDeclarationSQL(): string;
    getJsonDeclarationSQL(): string;
    getSearchJsonPropertySQL(path: string, type: string, aliased: boolean): string | Raw;
    getSearchJsonPropertyKey(path: string[], type: string, aliased: boolean, value?: unknown): string | Raw;
    processJsonCondition<T extends object>(o: FilterQuery<T>, value: EntityValue<T>, path: EntityKey<T>[], alias: boolean): FilterQuery<T>;
    protected getJsonValueType(value: unknown): string;
    getJsonIndexDefinition(index: {
        columnNames: string[];
    }): string[];
    getFullTextWhereClause(prop: EntityProperty): string;
    supportsCreatingFullTextIndex(): boolean;
    getFullTextIndexExpression(indexName: string, schemaName: string | undefined, tableName: string, columns: SimpleColumnMeta[]): string;
    /**
     * Generates the SQL index hint clause for the given index names.
     * Returns `undefined` when the platform does not support index hints (e.g. PostgreSQL, SQLite).
     */
    formatIndexHint(indexNames: string[]): string | undefined;
    /** Whether the driver automatically parses JSON columns into JS objects. */
    convertsJsonAutomatically(): boolean;
    /** Converts a JS value to its JSON database representation (typically JSON.stringify). */
    convertJsonToDatabaseValue(value: unknown, context?: TransformContext): unknown;
    /** Converts a database JSON value to its JS representation. */
    convertJsonToJSValue(value: unknown, context?: TransformContext): unknown;
    convertDateToJSValue(value: string | Date): string;
    convertIntervalToJSValue(value: string): unknown;
    convertIntervalToDatabaseValue(value: unknown): unknown;
    usesAsKeyword(): boolean;
    /**
     * Determines how UUID values are compared in the change set tracking.
     * Return `'string'` for inline string comparison (fast), or `'any'` for deep comparison via type methods.
     */
    compareUuids(): string;
    convertUuidToJSValue(value: unknown): unknown;
    convertUuidToDatabaseValue(value: unknown): unknown;
    /** Parses a string or numeric value into a Date object. */
    parseDate(value: string | number): Date;
    /** Returns the default EntityRepository class used by this platform. */
    getRepositoryClass<T extends object>(): Constructor<EntityRepository<T>>;
    /** Returns the default character set for this platform. */
    getDefaultCharset(): string;
    /** Returns the exception converter for translating native errors to driver exceptions. */
    getExceptionConverter(): ExceptionConverter;
    /**
     * Allows registering extensions of the driver automatically (e.g. `SchemaGenerator` extension in SQL drivers).
     */
    lookupExtensions(orm: MikroORM): void;
    /** @internal */
    init(orm: MikroORM): void;
    /** Retrieves a registered extension (e.g. SchemaGenerator, Migrator), throwing if not found. */
    getExtension<T>(extensionName: string, extensionKey: string, moduleName: string, em: EntityManager): T;
    getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): ISchemaGenerator;
    /** Processes a date value before persisting, applying timezone or format conversions. */
    processDateProperty(value: unknown): string | number | Date;
    /** Wraps a table or column identifier with the platform-specific quote character. */
    quoteIdentifier(id: string | {
        toString: () => string;
    }, quote?: string): string;
    /** Quotes a literal value for safe embedding in SQL. */
    quoteValue(value: any): string;
    escape(value: any): string;
    /** Replaces `?` placeholders in SQL with quoted parameter values. */
    formatQuery(sql: string, params: readonly any[]): string;
    /** Deep-clones embeddable data and tags it for JSON serialization. */
    cloneEmbeddable<T>(data: T): T;
    /** Initializes the platform with the ORM configuration. */
    setConfig(config: Configuration): void;
    /** Returns the current ORM configuration. */
    getConfig(): Configuration;
    /** Returns the configured timezone, or undefined if not set. */
    getTimezone(): string | undefined;
    /** Whether the given property represents a numeric database column. */
    isNumericProperty(prop: EntityProperty, ignoreCustomType?: boolean): boolean;
    /** Whether the given mapped type represents a numeric column. */
    isNumericColumn(mappedType: Type<unknown>): boolean;
    /** Whether the platform supports unsigned integer columns. */
    supportsUnsigned(): boolean;
    /**
     * Maximum length of identifiers (table, column, index, constraint, …) the platform supports.
     * Names produced by {@link getIndexName} above this limit are hash-truncated. Defaults to
     * `Infinity` (no truncation); SQL platforms override with their engine's limit
     * (PG 63, MySQL/MariaDB 64, MSSQL/Oracle 128).
     */
    getMaxIdentifierLength(): number;
    /**
     * Returns the default name of index for the given columns, hash-truncated if it would
     * exceed {@link getMaxIdentifierLength}.
     */
    getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence' | 'check'): string;
    /** Returns the default primary key constraint name. */
    getDefaultPrimaryName(tableName: string, columns: string[]): string;
    /** Whether the platform supports custom names for primary key constraints. */
    supportsCustomPrimaryKeyNames(): boolean;
    /** Whether the given property key is included in the populate hint. */
    isPopulated<T>(key: string, populate: readonly PopulateOptions<T>[] | boolean): boolean;
    /** Whether the given property should be included as a column in the SELECT query. */
    shouldHaveColumn<T>(prop: EntityProperty<T>, populate: readonly PopulateOptions<T>[] | boolean, exclude?: string[], includeFormulas?: boolean, ignoreInlineEmbeddables?: boolean): boolean;
    /**
     * Currently not supported due to how knex does complex sqlite diffing (always based on current schema)
     */
    /** Whether the platform supports generating down migrations. */
    supportsDownMigrations(): boolean;
    /** Whether the platform supports deferred unique constraints. */
    supportsDeferredUniqueConstraints(): boolean;
    /** Platform-specific validation of entity metadata. */
    validateMetadata(meta: EntityMetadata): void;
    /**
     * Generates a custom order by statement given a set of in order values, eg.
     * ORDER BY (CASE WHEN priority = 'low' THEN 1 WHEN priority = 'medium' THEN 2 ELSE NULL END)
     */
    generateCustomOrder(escapedColumn: string, values: unknown[]): void;
    /**
     * Returns default client url for given driver (e.g. mongodb://127.0.0.1:27017 for mongodb)
     */
    getDefaultClientUrl(): string;
    /**
     * @internal
     */
    castColumn(prop?: {
        columnTypes?: string[];
    }): string;
    /**
     * @internal
     */
    castJsonValue(prop?: {
        columnTypes?: string[];
    }): string;
    /**
     * @internal
     */
    clone(): this;
}
