| 201 | ` |
| 202 | |
| 203 | func (s *sqlDatabase) cascadeMigrationSQLite(model interface{}, name string, justDrop bool) error { |
| 204 | if !s.conn.Migrator().HasTable(name) { |
| 205 | return nil |
| 206 | } |
| 207 | defer s.conn.Exec("PRAGMA foreign_keys = ON;") |
| 208 | |
| 209 | var data string |
| 210 | var indexes []string |
| 211 | if err := s.conn.Raw(fmt.Sprintf("select sql from sqlite_master where type='table' and tbl_name='%s'", name)).Scan(&data).Error; err != nil { |
| 212 | if !errors.Is(err, gorm.ErrRecordNotFound) { |
| 213 | return fmt.Errorf("failed to get table %s: %w", name, err) |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | if err := s.conn.Raw(fmt.Sprintf("SELECT name FROM sqlite_master WHERE type == 'index' AND tbl_name == '%s' and name not like 'sqlite_%%'", name)).Scan(&indexes).Error; err != nil { |
| 218 | if !errors.Is(err, gorm.ErrRecordNotFound) { |
| 219 | return fmt.Errorf("failed to get table indexes %s: %w", name, err) |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | if strings.Contains(data, "ON DELETE") { |
| 224 | return nil |
| 225 | } |
| 226 | |
| 227 | if justDrop { |
| 228 | if err := s.conn.Migrator().DropTable(model); err != nil { |
| 229 | return fmt.Errorf("failed to drop table %s: %w", name, err) |
| 230 | } |
| 231 | return nil |
| 232 | } |
| 233 | |
| 234 | for _, index := range indexes { |
| 235 | if err := s.conn.Migrator().DropIndex(model, index); err != nil { |
| 236 | return fmt.Errorf("failed to drop index %s: %w", index, err) |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | err := s.conn.Exec(fmt.Sprintf(renameTemplate, name, name)).Error |
| 241 | if err != nil { |
| 242 | return fmt.Errorf("failed to rename table %s: %w", name, err) |
| 243 | } |
| 244 | |
| 245 | if model != nil { |
| 246 | if err := s.conn.Migrator().AutoMigrate(model); err != nil { |
| 247 | if err := s.conn.Exec(fmt.Sprintf(restoreNameTemplate, name, name, name)).Error; err != nil { |
| 248 | slog.With(slog.Any("error", err)).Error("failed to restore table", "table", name) |
| 249 | } |
| 250 | return fmt.Errorf("failed to create table %s: %w", name, err) |
| 251 | } |
| 252 | } |
| 253 | err = s.conn.Exec(fmt.Sprintf(copyContentsTemplate, name, name, name)).Error |
| 254 | if err != nil { |
| 255 | return fmt.Errorf("failed to copy contents to table %s: %w", name, err) |
| 256 | } |
| 257 | |
| 258 | return nil |
| 259 | } |
| 260 | |