import { type Connection, type Dictionary, type Options, RawQueryFragment } from '@mikro-orm/core';
import type { AbstractSqlConnection } from '../AbstractSqlConnection.js';
import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference } from '../typings.js';
import type { DatabaseSchema } from './DatabaseSchema.js';
import type { DatabaseTable } from './DatabaseTable.js';
/** Base class for database-specific schema helpers. Provides SQL generation for DDL operations. */
export declare abstract class SchemaHelper {
  protected readonly platform: AbstractSqlPlatform;
  constructor(platform: AbstractSqlPlatform);
  /** Returns SQL to prepend to schema migration scripts (e.g., disabling FK checks). */
  getSchemaBeginning(_charset: string, disableForeignKeys?: boolean): string;
  /** Returns SQL to disable foreign key checks. */
  disableForeignKeysSQL(): string;
  /** Returns SQL to re-enable foreign key checks. */
  enableForeignKeysSQL(): string;
  /** Returns SQL to append to schema migration scripts (e.g., re-enabling FK checks). */
  getSchemaEnd(disableForeignKeys?: boolean): string;
  finalizeTable(table: DatabaseTable, charset: string, collate?: string): string;
  appendComments(table: DatabaseTable): string[];
  supportsSchemaConstraints(): boolean;
  getPrimaryKeys(
    connection: AbstractSqlConnection,
    indexes: IndexDef[] | undefined,
    tableName: string,
    schemaName?: string,
  ): Promise<string[]>;
  inferLengthFromColumnType(type: string): number | undefined;
  protected getTableKey(t: Table): string;
  getCreateNativeEnumSQL(name: string, values: unknown[], schema?: string): string;
  getDropNativeEnumSQL(name: string, schema?: string): string;
  getAlterNativeEnumSQL(name: string, schema?: string, value?: string, items?: string[], oldItems?: string[]): string;
  /** Loads table metadata (columns, indexes, foreign keys) from the database information schema. */
  abstract loadInformationSchema(
    schema: DatabaseSchema,
    connection: AbstractSqlConnection,
    tables: Table[],
    schemas?: string[],
  ): Promise<void>;
  /** Returns the SQL query to list all tables in the database. */
  getListTablesSQL(): string;
  /** Retrieves all tables from the database. */
  getAllTables(connection: AbstractSqlConnection, schemas?: string[]): Promise<Table[]>;
  getListViewsSQL(): string;
  loadViews(schema: DatabaseSchema, connection: AbstractSqlConnection, schemaName?: string): Promise<void>;
  /** Returns SQL to rename a column in a table. */
  getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column, schemaName?: string): string;
  /** Returns SQL to create an index on a table. */
  getCreateIndexSQL(tableName: string, index: IndexDef): string;
  /**
   * Hook for adding driver-specific index options (e.g., fill factor for PostgreSQL).
   */
  protected getCreateIndexSuffix(_index: IndexDef): string;
  /**
   * Build the column list for an index, supporting advanced options like sort order, nulls ordering, and collation.
   * Note: Prefix length is only supported by MySQL/MariaDB which override this method.
   */
  protected getIndexColumns(index: IndexDef): string;
  /** Returns SQL to drop an index. */
  getDropIndexSQL(tableName: string, index: IndexDef): string;
  getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string[];
  /** Returns SQL statements to apply a table difference (add/drop/alter columns, indexes, foreign keys). */
  alterTable(diff: TableDifference, safe?: boolean): string[];
  /** Returns SQL to add columns to an existing table. */
  getAddColumnsSQL(table: DatabaseTable, columns: Column[]): string[];
  getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
  hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
  castColumn(name: string, type: string): string;
  alterTableColumn(column: Column, table: DatabaseTable, changedProperties: Set<string>): string[];
  createTableColumn(column: Column, table: DatabaseTable, changedProperties?: Set<string>): string | undefined;
  getPreAlterTable(tableDiff: TableDifference, safe: boolean): string[];
  getPostAlterTable(tableDiff: TableDifference, safe: boolean): string[];
  getChangeColumnCommentSQL(tableName: string, to: Column, schemaName?: string): string;
  getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
  protected mapIndexes(indexes: IndexDef[]): Promise<IndexDef[]>;
  mapForeignKeys(fks: any[], tableName: string, schemaName?: string): Dictionary;
  normalizeDefaultValue(
    defaultValue: string | RawQueryFragment,
    length?: number,
    defaultValues?: Dictionary<string[]>,
  ): string | number;
  getCreateDatabaseSQL(name: string): string;
  getDropDatabaseSQL(name: string): string;
  getCreateNamespaceSQL(name: string): string;
  getDropNamespaceSQL(name: string): string;
  getDatabaseExistsSQL(name: string): string;
  getDatabaseNotExistsError(dbName: string): string;
  getManagementDbName(): string;
  getDefaultEmptyString(): string;
  databaseExists(connection: Connection, name: string): Promise<boolean>;
  append(array: string[], sql: string | string[], pad?: boolean): void;
  /** Returns SQL statements to create a table with all its columns, primary key, indexes, and checks. */
  createTable(table: DatabaseTable, alter?: boolean): string[];
  alterTableComment(table: DatabaseTable, comment?: string): string;
  /** Returns SQL to create a foreign key constraint on a table. */
  createForeignKey(table: DatabaseTable, foreignKey: ForeignKey, alterTable?: boolean, inline?: boolean): string;
  splitTableName(name: string, skipDefaultSchema?: boolean): [string | undefined, string];
  getReferencedTableName(referencedTableName: string, schema?: string): string;
  createIndex(index: IndexDef, table: DatabaseTable, createPrimary?: boolean): string;
  createCheck(table: DatabaseTable, check: CheckDef): string;
  protected getTableName(table: string, schema?: string): string;
  getTablesGroupedBySchemas(tables: Table[]): Map<string | undefined, Table[]>;
  get options(): NonNullable<Options['schemaGenerator']>;
  protected processComment(comment: string): string;
  protected quote(...keys: (string | undefined)[]): string;
  dropForeignKey(tableName: string, constraintName: string): string;
  dropIndex(table: string, index: IndexDef, oldIndexName?: string): string;
  dropConstraint(table: string, name: string): string;
  /** Returns SQL to drop a table if it exists. */
  dropTableIfExists(name: string, schema?: string): string;
  createView(name: string, schema: string | undefined, definition: string): string;
  dropViewIfExists(name: string, schema?: string): string;
  createMaterializedView(name: string, schema: string | undefined, definition: string, withData?: boolean): string;
  dropMaterializedViewIfExists(name: string, schema?: string): string;
  refreshMaterializedView(name: string, schema?: string, concurrently?: boolean): string;
  getListMaterializedViewsSQL(): string;
  loadMaterializedViews(schema: DatabaseSchema, connection: AbstractSqlConnection, schemaName?: string): Promise<void>;
}
