143 lines
3.1 KiB
Go
143 lines
3.1 KiB
Go
package migrations
|
|
|
|
import (
|
|
"database/sql"
|
|
)
|
|
|
|
func init() {
|
|
RegisterMigration(
|
|
2,
|
|
"Add ON DELETE CASCADE to foreign keys",
|
|
migrateCascadeFKUp,
|
|
migrateCascadeFKDown,
|
|
)
|
|
}
|
|
|
|
func migrateCascadeFKUp(tx *sql.Tx) error {
|
|
// Enable foreign keys for this transaction
|
|
_, err := tx.Exec("PRAGMA foreign_keys = OFF")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 1. Rebuild media_files with FK + CASCADE
|
|
_, err = tx.Exec(`
|
|
CREATE TABLE media_files_new (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
path TEXT NOT NULL,
|
|
library_id INTEGER NOT NULL,
|
|
FOREIGN KEY (library_id) REFERENCES libraries(id) ON DELETE CASCADE
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(`INSERT INTO media_files_new SELECT id, path, library_id FROM media_files`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("DROP TABLE media_files")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("ALTER TABLE media_files_new RENAME TO media_files")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 2. Rebuild songs with FK + CASCADE on media_file_id
|
|
_, err = tx.Exec(`
|
|
CREATE TABLE songs_new (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
album_id INTEGER,
|
|
artist_id INTEGER,
|
|
duration INTEGER,
|
|
media_file_id INTEGER UNIQUE,
|
|
FOREIGN KEY (album_id) REFERENCES albums(id),
|
|
FOREIGN KEY (artist_id) REFERENCES artists(id),
|
|
FOREIGN KEY (media_file_id) REFERENCES media_files(id) ON DELETE CASCADE
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(`INSERT INTO songs_new SELECT id, title, album_id, artist_id, duration, media_file_id FROM songs`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("DROP TABLE songs")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("ALTER TABLE songs_new RENAME TO songs")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func migrateCascadeFKDown(tx *sql.Tx) error {
|
|
_, err := tx.Exec("PRAGMA foreign_keys = OFF")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Revert songs
|
|
_, err = tx.Exec(`
|
|
CREATE TABLE songs_old (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
album_id INTEGER,
|
|
artist_id INTEGER,
|
|
duration INTEGER,
|
|
media_file_id INTEGER UNIQUE,
|
|
FOREIGN KEY (album_id) REFERENCES albums(id),
|
|
FOREIGN KEY (artist_id) REFERENCES artists(id),
|
|
FOREIGN KEY (media_file_id) REFERENCES media_files(id)
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(`INSERT INTO songs_old SELECT id, title, album_id, artist_id, duration, media_file_id FROM songs`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("DROP TABLE songs")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("ALTER TABLE songs_old RENAME TO songs")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Revert media_files
|
|
_, err = tx.Exec(`
|
|
CREATE TABLE media_files_old (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
path TEXT NOT NULL,
|
|
library_id INTEGER NOT NULL
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(`INSERT INTO media_files_old SELECT id, path, library_id FROM media_files`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("DROP TABLE media_files")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec("ALTER TABLE media_files_old RENAME TO media_files")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|