db: Reload Playlists before deleting a Library path

This is much faster than removing tracks from their playlists one at a
time. I also clear and reload the Tracks table to clear out pointers to
old Tracks.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-04-10 10:23:14 -04:00
parent eea763f133
commit 1aec9df0a8
2 changed files with 42 additions and 3 deletions

View File

@ -37,6 +37,7 @@ class Library(playlist.Playlist):
def __queue_delete(self) -> bool:
self.table.delete(self)
self.table.sql.tracks.load()
return True
def __queue_tracks(self) -> bool:
@ -48,6 +49,10 @@ class Library(playlist.Playlist):
self.queue.push_many(self.__tag_track, [(f,) for f in files])
return False
def __reload_playlist_tracks(self, playlist: playlist.Playlist) -> bool:
playlist.reload_tracks(idle=False)
return True
def __tag_track(self, path: pathlib.Path) -> bool:
if self.tagger.ready.is_set():
(file, tags) = self.tagger.get_result(self.table.sql, self)
@ -88,6 +93,12 @@ class Library(playlist.Playlist):
if self.deleting is False:
self.stop()
self.deleting = True
self.table.sql.tracks.clear()
for tbl in self.table.sql.playlist_tables():
if tbl is not self:
self.queue.push_many(self.__reload_playlist_tracks,
[(plist,) for plist in tbl.store])
self.queue.push(self.__queue_delete)
return True
return False

View File

@ -47,19 +47,47 @@ class TestLibraryObject(tests.util.TestCase):
def test_delete(self):
"""Test deleting a Library path."""
self.assertFalse(self.library.deleting)
artist = self.sql.artists.create("Test Artist")
album = self.sql.albums.create("Test Album", "Test Artist", "2023")
medium = self.sql.media.create(album, "", number=1)
genre = self.sql.genres.create("Test Genre")
decade = self.sql.decades.create(1980)
year = self.sql.years.create(1988)
playlists = [plist for plist in self.sql.playlists.store] + \
[artist, album, medium, genre, decade, year]
for playlist in playlists:
playlist.reload_tracks = unittest.mock.Mock()
self.table.delete = unittest.mock.Mock()
self.sql.tracks.clear = unittest.mock.Mock()
self.sql.tracks.load = unittest.mock.Mock()
with unittest.mock.patch.object(self.table, "delete") as mock_delete:
with unittest.mock.patch.object(self.table, "update"):
self.assertTrue(self.library.delete())
self.assertTrue(self.library.deleting)
mock_delete.assert_not_called()
self.assertEqual(self.library.queue[0],
(self.library._Library__queue_delete,))
tasks = [(self.library._Library__reload_playlist_tracks, plist)
for plist in playlists]
tasks.append((self.library._Library__queue_delete,))
self.assertListEqual(self.library.queue._tasks, tasks)
self.sql.tracks.clear.assert_called()
self.sql.tracks.load.assert_not_called()
self.library.queue.cancel()
self.assertFalse(self.library.delete())
self.assertEqual(self.library.queue.total, 1)
self.assertListEqual(self.library.queue._tasks, [])
self.library.deleting = False
self.assertTrue(self.library.delete())
self.library.queue.complete()
for plist in playlists:
plist.reload_tracks.assert_called_with(idle=False)
mock_delete.assert_called_with(self.library)
self.sql.tracks.load.assert_called()
def test_online(self):
"""Test that changing the online property notifies the table."""