import { O_CREATE_TABLE_CREATE_DEFINITION , O_CREATE_TABLE_CREATE_DEFINITION_FOREIGN_KEY , ForeignKeyInterface , } from '../../../../typings' ; import { isDefined } from '../../../../shared/utils' ; import { ColumnReference } from './column-reference' ; import { IndexColumn } from './index-column' ; import { ForeignKeyModelInterface , IndexColumnModelInterface , ColumnReferenceModelInterface , ColumnModelInterface , TableModelInterface , } from './typings' ; /**
 * Foreign key of a table.
 */ export class ForeignKey implements ForeignKeyModelInterface { name ? : string ; columns : IndexColumnModelInterface [ ] = [ ] ; reference ! : ColumnReferenceModelInterface ; param json static fromDef ( json ) { if ( json . id === 'O_CREATE_TABLE_CREATE_DEFINITION' ) { if ( isDefined ( json . def . foreignKey ) ) { return ForeignKey . fromObject ( json . def . foreignKey ) ; } throw new TypeError ( `Statement ${ json . id } has undefined foreignKey. Cannot format foreignKey.` ) ; } throw new TypeError ( `Unknown json id to build foreign key from: ${ json . id }` ) ; } param json static fromObject ( json ) { const foreignKey = new ForeignKey ( ) ; foreignKey . columns = json . columns . map ( IndexColumn . fromDef ) ; foreignKey . reference = ColumnReference . fromDef ( json . reference ) ; if ( json . name ) { foreignKey . name = json . name ; } return foreignKey ; } /**
     * JSON casting of this object calls this method.
     */ toJSON ( ) { const json = { columns : this . columns . map ( ( c ) => c . toJSON ( ) ) , reference : this . reference . toJSON ( ) , } ; if ( isDefined ( this . name ) ) { json . name = this . name ; } return json ; } /**
     * Create a deep clone of this model.
     */ clone ( ) { const key = new ForeignKey ( ) ; key . columns = this . columns . map ( ( c ) => c . clone ( ) ) ; key . reference = this . reference . clone ( ) ; if ( isDefined ( this . name ) ) { key . name = this . name ; } return key ; } param indexColumn pushColumn ( indexColumn ) { this . columns . push ( indexColumn ) ; } param name dropColumn ( name ) { let pos = - 1 ; const found = this . columns . some ( ( c , i ) => { pos = i ; return c . column === name ; } ) ; if ( ! found || pos < 0 ) { return false ; } const end = this . columns . splice ( pos ) ; end . shift ( ) ; this . columns = this . columns . concat ( end ) ; return true ; } param table getColumnsFromTable ( table ) { return ( table . columns ?? [ ] ) . filter ( ( tableColumn ) => this . columns . some ( ( indexColumn ) => indexColumn . column === tableColumn . name ) ) ; } /**
     * Get whether the given table has all of this foreign key's owner table columns.
     */ hasAllColumnsFromTable ( table ) { return ( ( table . columns ?? [ ] ) . filter ( ( tableColumn ) => this . columns . some ( ( indexColumn ) => indexColumn . column === tableColumn . name ) ) . length === this . columns . length ) ; } /**
     * Set size of this index to the size of index's column in given
     * table, if the size of this index is not already set.
     */ setIndexSizeFromTable ( table ) { this . columns . filter ( ( i ) => ! isDefined ( i . length ) ) . forEach ( ( indexColumn ) => { const column = ( table . columns ?? [ ] ) . find ( ( c ) => c . name === indexColumn . column ) ; if ( ! column ) { return ; } const indexableSize = column . type . getMaxIndexableSize ( ) ; if ( indexableSize > 0 ) { indexColumn . length = indexableSize ; } } ) ; } /**
     * Get whether the given table has all of this foreign key's referenced table columns.
     */ hasAllColumnsFromRefTable ( table ) { return ( ( table . columns ?? [ ] ) . filter ( ( tableColumn ) => this . reference . columns ?. some ( ( indexColumn ) => indexColumn . column === tableColumn . name ) ) . length === this . reference . columns ?. length ) ; } param tables getReferencedTable ( tables ) { return tables . find ( ( t ) => t . name === this . reference . table ) ?? undefined ; } param table param column referencesTableAndColumn ( table , column ) { return ( this . reference . table === table . name && ( this . reference . columns ?? [ ] ) . some ( ( indexColumn ) => indexColumn . column === column . name ) ) ; } param table referencesTable ( table ) { return this . reference . table === table . name ; } param column param newName renameColumn ( column , newName ) { return this . reference . columns ?. filter ( ( c ) => c . column === column . name ) . forEach ( ( c ) => { c . column = newName ; } ) ; } param newName updateReferencedTableName ( newName ) { this . reference . table = newName ; } }