// Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later package forgejo_migrations import ( "fmt" "forgejo.org/modules/log" "xorm.io/builder" "xorm.io/xorm" ) // syncForeignKeyWithDelete will delete any records that match `cond`, and if present, log and warn to the // administrator; then it will perform an `xorm.Sync()` in order to create foreign keys on the table definition. func syncForeignKeyWithDelete(x *xorm.Engine, bean any, cond builder.Cond) error { rowsDeleted, err := x.Where(cond).Delete(bean) if err != nil { return fmt.Errorf("failure to delete inconsistent records before foreign key sync: %w", err) } if rowsDeleted > 0 { tableName := x.TableName(bean) log.Warn( "Foreign key creation on table %s required deleting %d records with inconsistent foreign key values.", tableName, rowsDeleted) } // Sync() drops indexes by default, which will cause unnecessary rebuilding of indexes when syncForeignKeyWithDelete // is used with partial bean definitions; so we disable that option _, err = x.SyncWithOptions(xorm.SyncOptions{IgnoreDropIndices: true}, bean) return err }