/** * Constraint Operations Module * Main orchestrator for constraint and index operations */ import type { ILegacySyncOptions, TArray, TNullable } from '../../types'; import { type SyncDbSide } from '../syncClient'; import type { Client } from 'pg'; import { type IIndexRow } from './indexes'; interface IConstraintRow { table_name: string; constraint_name: string; constraint_type: string; column_name: TNullable; foreign_table_name: TNullable; foreign_column_name: TNullable; update_rule: TNullable; delete_rule: TNullable; check_clause?: TNullable; } export declare class ConstraintOperations { private sourceClient; private targetClient; private options; private indexOperations; private constraintDefinitions; private constraintHandlers; constructor(sourceClient: Client, targetClient: Client, options: ILegacySyncOptions); /** * Get all constraints from a schema on the given database. * * Reads pg_constraint.conkey/confkey directly (via unnest ... WITH ORDINALITY) * instead of joining information_schema.key_column_usage x constraint_column_usage: * that join is keyed only on constraint_name, so composite constraints produce a * cross product of local x referenced column rows with no positional pairing, * silently corrupting which local column maps to which referenced column. * * A second branch replicates information_schema's synthesized "__not_null" * pseudo CHECK constraints (real Postgres behavior for information_schema.table_constraints, * but backed only by pg_attribute.attnotnull, not an actual pg_constraint row) — without * it, plain column-level NOT NULL never lines up against an equivalent explicit CHECK * constraint on the other side, and notNullCheckEquivalenceKey can't suppress the false * "constraint changed" it would otherwise report. */ getConstraints(side: SyncDbSide): Promise; /** * Get detailed constraint definition from the given database side. */ getConstraintDefinition(side: SyncDbSide, constraintName: string, tableName: string): Promise>>; /** * Generate constraint type specific clause */ generateConstraintClause(params: { constraintType: string; columns: string; foreignTableName?: string | null; foreignColumnName?: string | null; updateRule?: string | null; deleteRule?: string | null; targetSchema: string; }): string; /** * Compare two constraint definitions to detect changes */ compareConstraintDefinitions(sourceConstraint: IConstraintRow, targetConstraint: IConstraintRow): boolean; /** * Generate CREATE CONSTRAINT statement */ generateCreateConstraintStatement(constraintRows: TArray, targetSchema: string): string; /** * Get all indexes from a schema on the given database. */ getIndexes(side: SyncDbSide): Promise>; /** * Generate CREATE INDEX statement */ generateCreateIndexStatement(indexDef: string, targetSchema: string): string; /** * Generate index operations for schema sync */ generateIndexOperations(): Promise; /** * Handle constraints that have changed */ handleConstraintsToUpdate(sourceConstraints: TArray, targetConstraints: TArray, alterStatements: TArray): Promise; /** * Handle constraints to drop in target */ handleConstraintsToDrop(sourceConstraints: TArray, targetConstraints: TArray, alterStatements: TArray): Promise; /** * Handle constraints to create in target */ handleConstraintsToCreate(sourceConstraints: TArray, targetConstraints: TArray, alterStatements: TArray): Promise; /** * Generate constraint operations for schema sync */ generateConstraintOperations(): Promise>; } export {}; //# sourceMappingURL=constraints.d.ts.map