package migrations import ( "database/sql" ) func init() { RegisterMigration( 3, "Add metadata fields and timestamps", migrateAddMetadataUp, migrateAddMetadataDown, ) } func migrateAddMetadataUp(tx *sql.Tx) error { // Add timestamps to libraries _, err := tx.Exec(` ALTER TABLE libraries ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE libraries ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP `) if err != nil { return err } // Add metadata and timestamps to media_files _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN file_size INTEGER DEFAULT 0 `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN format TEXT DEFAULT '' `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN bit_rate INTEGER DEFAULT 0 `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN sample_rate INTEGER DEFAULT 0 `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE media_files ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP `) if err != nil { return err } // Add fields to albums _, err = tx.Exec(` ALTER TABLE albums ADD COLUMN cover TEXT DEFAULT '' `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE albums ADD COLUMN year INTEGER DEFAULT 0 `) if err != nil { return err } // Add fields to songs _, err = tx.Exec(` ALTER TABLE songs ADD COLUMN track_number INTEGER DEFAULT 0 `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE songs ADD COLUMN disc_number INTEGER DEFAULT 0 `) if err != nil { return err } _, err = tx.Exec(` ALTER TABLE songs ADD COLUMN genre TEXT DEFAULT '' `) if err != nil { return err } return nil } func migrateAddMetadataDown(tx *sql.Tx) error { // SQLite doesn't support DROP COLUMN in older versions, so we need to rebuild tables // Rebuild libraries _, err := tx.Exec(` CREATE TABLE libraries_old ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, path TEXT NOT NULL ) `) if err != nil { return err } _, err = tx.Exec(`INSERT INTO libraries_old SELECT id, name, path FROM libraries`) if err != nil { return err } _, err = tx.Exec("DROP TABLE libraries") if err != nil { return err } _, err = tx.Exec("ALTER TABLE libraries_old RENAME TO libraries") if err != nil { return err } // Rebuild media_files _, err = tx.Exec(` CREATE TABLE media_files_old ( 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_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 } // Rebuild albums _, err = tx.Exec(` CREATE TABLE albums_old ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, artist_id INTEGER, FOREIGN KEY (artist_id) REFERENCES artists(id), UNIQUE(title, artist_id) ) `) if err != nil { return err } _, err = tx.Exec(`INSERT INTO albums_old SELECT id, title, artist_id FROM albums`) if err != nil { return err } _, err = tx.Exec("DROP TABLE albums") if err != nil { return err } _, err = tx.Exec("ALTER TABLE albums_old RENAME TO albums") if err != nil { return err } // Rebuild 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) ON DELETE CASCADE ) `) 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 } return nil }