db: Add a PlaylistMap

And create both permanent and temporary maps for tracks. The temporary
map is intended to be used for the New Tracks and Previous playlists,
since we don't store the state across restarts.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-08-22 09:38:14 -04:00
parent 2b87707f16
commit 0fd1069484
3 changed files with 135 additions and 0 deletions

View File

@ -39,3 +39,5 @@ def reset():
for mod in mods: mod.Table.do_create()
genre.Map.reset()
playlist.Map.reset()
playlist.TempMap.reset()

View File

@ -44,6 +44,8 @@ class PlaylistTable(objects.Table):
"VALUES (?, ?)", (name, name.casefold()))
def do_delete(self, playlist):
Map.delete_playlist(playlist)
TempMap.delete_playlist(playlist)
return execute("DELETE FROM playlists WHERE playlistid=?", [ int(playlist) ])
def do_get(self, rowid):
@ -55,4 +57,50 @@ class PlaylistTable(objects.Table):
"WHERE name=?", [ name ])
class PlaylistMap(objects.Map):
def __init__(self, temp=False):
name = "playlist_map" if temp==False else "temp_playlist_map"
self.temporary = temp
objects.Map.__init__(self, name, Playlist, track.Track)
self.lookup_tracks = self.lookup_rhs
self.lookup_playlists = self.lookup_lhs
def do_create(self):
temp = "" if self.temporary == False else "TEMPORARY"
execute(f"CREATE {temp} TABLE IF NOT EXISTS {self.map_name} "
"(playlistid INTEGER, "
" trackid INTEGER, "
" FOREIGN KEY(playlistid) REFERENCES playlists(playlistid), "
" FOREIGN KEY(trackid) REFERENCES tracks(trackid), "
" UNIQUE(playlistid, trackid))")
def do_insert(self, playlist, track):
execute(f"INSERT INTO {self.map_name} (playlistid, trackid) "
"VALUES (?, ?)", [ int(playlist), int(track) ])
def do_delete(self, playlist, track):
return execute(f"DELETE FROM {self.map_name} "
"WHERE playlistid=? AND trackid=?",
[ int(playlist), int(track) ])
def do_lookup_rhs(self, playlist):
return execute(f"SELECT trackid FROM {self.map_name} "
"WHERE playlistid=?", [ int(playlist) ])
def do_lookup_lhs(self, track):
return execute(f"SELECT playlistid FROM {self.map_name} "
"WHERE trackid=?", [ int(track) ])
def delete_track(self, track):
for playlist in self.lookup_playlists(track):
self.delete(playlist, track)
def delete_playlist(self, playlist):
for track in self.lookup_tracks(playlist):
self.delete(playlist, track)
Table = PlaylistTable()
Map = PlaylistMap(temp=False)
TempMap = PlaylistMap(temp=True)

View File

@ -41,8 +41,15 @@ class TestPlaylistTable(unittest.TestCase):
def test_playlist_table_delete(self):
playlist = db.playlist.Table.find("Test Playlist")
track = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
db.playlist.Map.insert(playlist, track)
db.playlist.TempMap.insert(playlist, track)
db.playlist.Table.delete(playlist)
self.assertIsNone(db.playlist.Table.lookup("Test Playlist"))
self.assertEqual(db.playlist.Map.lookup_playlists(track), [ ])
self.assertEqual(db.playlist.TempMap.lookup_playlists(track), [ ])
def test_playlist_table_get(self):
playlist = db.playlist.Playlist(1)
@ -53,3 +60,81 @@ class TestPlaylistTable(unittest.TestCase):
playlist = db.playlist.Table.insert("Test Playlist")
self.assertEqual(db.playlist.Table.lookup("Test Playlist"), playlist)
self.assertIsNone(db.playlist.Table.lookup("none"))
class TestPlaylistMap(unittest.TestCase):
def setUp(self):
db.reset()
def test_playlist_map_init(self):
self.assertIsInstance(db.playlist.Map, db.playlist.PlaylistMap)
self.assertIsInstance(db.playlist.TempMap, db.playlist.PlaylistMap)
self.assertEqual(db.playlist.Map.map_lhs, db.playlist.Playlist)
self.assertEqual(db.playlist.Map.map_rhs, db.track.Track)
self.assertFalse(db.playlist.Map.temporary)
self.assertTrue( db.playlist.TempMap.temporary)
db.execute("SELECT playlistid,trackid FROM playlist_map")
db.execute("SELECT playlistid,trackid FROM temp_playlist_map")
def test_playlist_map_insert(self):
track = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
collection = db.playlist.Table.find("Collection")
db.playlist.Map.insert(collection, track)
with self.assertRaises(sqlite3.IntegrityError):
db.playlist.Map.insert(collection, track)
def test_playlist_map_delete(self):
track = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
playlist = db.playlist.Table.find("Test Playlist")
db.playlist.Map.insert(playlist, track)
db.playlist.Map.delete(playlist, track)
self.assertEqual(db.playlist.Map.lookup_tracks(playlist), [ ])
def test_playlist_map_lookup_tracks(self):
track1 = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
track2 = db.make_fake_track(2, 2.345, "Test Title 2", "/a/c.def")
playlist = db.playlist.Table.find("Collection")
db.playlist.Map.insert(playlist, track1)
db.playlist.Map.insert(playlist, track2)
lookup_res = db.playlist.Map.lookup_tracks(playlist)
self.assertEqual(lookup_res, [ track1, track2 ])
def test_playlist_map_lookup_playlists(self):
track = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
collection = db.playlist.Table.find("Collection")
favorites = db.playlist.Table.find("Favorites")
db.playlist.Map.insert(collection, track)
db.playlist.Map.insert(favorites, track)
lookup_res = db.playlist.Map.lookup_playlists(track)
self.assertEqual(lookup_res, [ collection, favorites ])
def test_playlist_map_delete_track(self):
track = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
collection = db.playlist.Table.find("Collection")
favorites = db.playlist.Table.find("Favorites")
db.playlist.Map.insert(collection, track)
db.playlist.Map.insert(favorites, track)
db.playlist.Map.delete_track(track)
self.assertEqual(db.playlist.Map.lookup_playlists(track), [ ])
def test_playlist_map_delete_playlist(self):
track1 = db.make_fake_track(1, 1.234, "Test Title", "/a/b.cde")
track2 = db.make_fake_track(2, 2.345, "Test Title 2", "/a/c.def")
playlist = db.playlist.Table.find("Collection")
db.playlist.Map.insert(playlist, track1)
db.playlist.Map.insert(playlist, track2)
db.playlist.Map.delete_playlist(playlist)
self.assertEqual(db.playlist.Map.lookup_tracks(playlist), [ ])