Fix watchlist migration dropping profile_id & fix profile delete dialog hidden behind overlay

- Watchlist nullable migration now preserves profile_id column and composite
  UNIQUE constraints when rebuilding the table
- Profile support migration always repairs missing profile_id columns on all
  tables, even if the migration metadata key already exists (handles tables
  rebuilt by other migrations)
- Confirm dialog z-index raised to 100000 to appear above profile picker
  overlay (99999), fixing invisible delete confirmation
pull/253/head
Broque Thomas 2 months ago
parent 219f453b74
commit 078b1130f8

@ -1128,31 +1128,60 @@ class MusicDatabase:
if has_not_null:
logger.info("Migrating watchlist_artists table to make spotify_artist_id nullable...")
# Check if old table already has profile_id (from profile migration)
old_has_profile = 'profile_id' in columns
# Drop leftover temp table from any previous failed migration
cursor.execute("DROP TABLE IF EXISTS watchlist_artists_new")
# Create new table with nullable spotify_artist_id
cursor.execute("""
CREATE TABLE watchlist_artists_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
spotify_artist_id TEXT UNIQUE,
artist_name TEXT NOT NULL,
date_added TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_scan_timestamp TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
image_url TEXT,
include_albums INTEGER DEFAULT 1,
include_eps INTEGER DEFAULT 1,
include_singles INTEGER DEFAULT 1,
include_live INTEGER DEFAULT 0,
include_remixes INTEGER DEFAULT 0,
include_acoustic INTEGER DEFAULT 0,
include_compilations INTEGER DEFAULT 0,
itunes_artist_id TEXT
)
""")
# Include profile_id + composite UNIQUE if old table had profile support
if old_has_profile:
cursor.execute("""
CREATE TABLE watchlist_artists_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
spotify_artist_id TEXT,
artist_name TEXT NOT NULL,
date_added TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_scan_timestamp TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
image_url TEXT,
include_albums INTEGER DEFAULT 1,
include_eps INTEGER DEFAULT 1,
include_singles INTEGER DEFAULT 1,
include_live INTEGER DEFAULT 0,
include_remixes INTEGER DEFAULT 0,
include_acoustic INTEGER DEFAULT 0,
include_compilations INTEGER DEFAULT 0,
itunes_artist_id TEXT,
profile_id INTEGER DEFAULT 1,
UNIQUE(profile_id, spotify_artist_id),
UNIQUE(profile_id, itunes_artist_id)
)
""")
else:
cursor.execute("""
CREATE TABLE watchlist_artists_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
spotify_artist_id TEXT UNIQUE,
artist_name TEXT NOT NULL,
date_added TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_scan_timestamp TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
image_url TEXT,
include_albums INTEGER DEFAULT 1,
include_eps INTEGER DEFAULT 1,
include_singles INTEGER DEFAULT 1,
include_live INTEGER DEFAULT 0,
include_remixes INTEGER DEFAULT 0,
include_acoustic INTEGER DEFAULT 0,
include_compilations INTEGER DEFAULT 0,
itunes_artist_id TEXT
)
""")
# Copy data from old table (only columns that exist in both)
cursor.execute("PRAGMA table_info(watchlist_artists)")
old_cols = [col[1] for col in cursor.fetchall()]
@ -1160,19 +1189,21 @@ class MusicDatabase:
'last_scan_timestamp', 'created_at', 'updated_at', 'image_url',
'include_albums', 'include_eps', 'include_singles', 'include_live',
'include_remixes', 'include_acoustic', 'include_compilations',
'itunes_artist_id']
'itunes_artist_id', 'profile_id']
shared_cols = [c for c in new_cols if c in old_cols]
cols_str = ', '.join(shared_cols)
cursor.execute(f"INSERT INTO watchlist_artists_new ({cols_str}) SELECT {cols_str} FROM watchlist_artists")
# Drop old table
cursor.execute("DROP TABLE watchlist_artists")
# Rename new table
cursor.execute("ALTER TABLE watchlist_artists_new RENAME TO watchlist_artists")
# Recreate indexes
cursor.execute("CREATE INDEX IF NOT EXISTS idx_watchlist_spotify_id ON watchlist_artists (spotify_artist_id)")
if old_has_profile:
cursor.execute("CREATE INDEX IF NOT EXISTS idx_watchlist_profile ON watchlist_artists (profile_id)")
logger.info("Successfully migrated watchlist_artists table - spotify_artist_id is now nullable")
else:
@ -1767,8 +1798,27 @@ class MusicDatabase:
try:
# Check if migration already applied
cursor.execute("SELECT value FROM metadata WHERE key = 'profiles_migration_v1' LIMIT 1")
if cursor.fetchone():
return # Already migrated
already_migrated = cursor.fetchone() is not None
# Even if already migrated, ensure profile_id columns exist on all tables
# (another migration may have rebuilt a table without profile_id)
tables_needing_profile_id = [
'watchlist_artists', 'wishlist_tracks', 'similar_artists',
'discovery_pool', 'discovery_recent_albums', 'discovery_curated_playlists',
'bubble_snapshots', 'recent_releases'
]
for table in tables_needing_profile_id:
try:
cursor.execute(f"PRAGMA table_info({table})")
columns = [col[1] for col in cursor.fetchall()]
if 'profile_id' not in columns:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN profile_id INTEGER DEFAULT 1")
logger.info(f"Repaired missing profile_id column on {table}")
except Exception:
pass
if already_migrated:
return # Rest of migration already done
logger.info("Adding multi-profile support...")
@ -1791,22 +1841,7 @@ class MusicDatabase:
VALUES (1, 'Admin', 1)
""")
# 3. Add profile_id column to per-profile tables
tables_needing_profile_id = [
'watchlist_artists', 'wishlist_tracks', 'similar_artists',
'discovery_pool', 'discovery_recent_albums', 'discovery_curated_playlists',
'bubble_snapshots', 'recent_releases'
]
for table in tables_needing_profile_id:
try:
cursor.execute(f"PRAGMA table_info({table})")
columns = [col[1] for col in cursor.fetchall()]
if 'profile_id' not in columns:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN profile_id INTEGER DEFAULT 1")
logger.info(f"Added profile_id column to {table}")
except Exception as e:
logger.warning(f"Could not add profile_id to {table}: {e}")
# 3. profile_id columns already ensured above (before early-return guard)
# 4. Rebuild watchlist_artists to change UNIQUE constraint
# Old: UNIQUE(spotify_artist_id)

@ -4337,7 +4337,7 @@ body {
/* Confirm Dialog Modal */
/* Confirm dialog must sit above all other modals (playlist, download, etc.) */
#confirm-modal-overlay {
z-index: 11000;
z-index: 100000;
}
.confirm-modal {

Loading…
Cancel
Save