db: Give playlists a get_track_index() function

So we can send an "items-changed" signal once Playlists have been
converted to a Gio.ListModel

Implements: Issue #3 (Sort playlists through SQLite)
Implements: Issue #15 (Convert Playlists into Gio.ListModels)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-10-17 21:48:17 -04:00
parent 1d5f88f080
commit 847f182173
10 changed files with 58 additions and 0 deletions

View File

@ -33,6 +33,18 @@ class Playlist(GObject.GObject):
[ self.rowid, n ]).fetchone()
return track.Table.factory(row)
def get_track_index(self, track):
order = ', '.join(self.plist_state.sort)
cur = sql.execute(f"SELECT * FROM (SELECT trackid,ROW_NUMBER() "
f"OVER (ORDER BY {order}) "
f"FROM tracks "
f"INNER JOIN artists USING(artistid) "
f"INNER JOIN albums USING(albumid) "
f"INNER JOIN discs USING(discid) "
f"INNER JOIN years USING(yearid)) "
f"WHERE trackid=?", [ track.rowid ])
return cur.fetchone()[1] - 1
@GObject.Property
def name(self): raise NotImplementedError
@ -84,6 +96,20 @@ class MappedPlaylist(Playlist):
[ self._rowid, n ]).fetchone()
return track.Table.factory(row)
def get_track_index(self, track):
order = ', '.join(self.plist_state.sort)
cur = sql.execute(f"SELECT * FROM (SELECT trackid,{self._rowkey},ROW_NUMBER() "
f"OVER (ORDER BY {order}) "
f"FROM tracks "
f"INNER JOIN {self.map_table} USING (trackid) "
f"INNER JOIN artists USING(artistid) "
f"INNER JOIN albums USING(albumid) "
f"INNER JOIN discs USING(discid) "
f"INNER JOIN years USING(yearid)) "
f"WHERE {self._rowkey}=? AND trackid=?",
[ self.rowid, track.rowid ])
return cur.fetchone()[2] - 1
def remove_track(self, track):
return sql.execute(f"DELETE FROM {self.map_table} "
f"WHERE {self.rowkey}=? AND trackid=?",

View File

@ -35,6 +35,7 @@ class TestAlbum(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(album.get_n_tracks(), 1)
self.assertEqual(album.get_track(0), track)
self.assertEqual(album.get_track_index(track), 0)
class TestAlbumTable(unittest.TestCase):

View File

@ -31,6 +31,7 @@ class TestArtist(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(artist.get_n_tracks(), 1)
self.assertEqual(artist.get_track(0), track)
self.assertEqual(artist.get_track_index(track), 0)
class TestArtistTable(unittest.TestCase):

View File

@ -42,6 +42,7 @@ class TestDecade(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(decade.get_n_tracks(), 1)
self.assertEqual(decade.get_track(0), track)
self.assertEqual(decade.get_track_index(track), 0)
class TestDecadeTable(unittest.TestCase):

View File

@ -49,6 +49,7 @@ class TestDisc(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(disc.get_n_tracks(), 1)
self.assertEqual(disc.get_track(0), track)
self.assertEqual(disc.get_track_index(track), 0)
class TestDiscTable(unittest.TestCase):

View File

@ -34,6 +34,7 @@ class TestGenre(unittest.TestCase):
self.assertTrue(genre.add_track(track))
self.assertEqual(genre.get_n_tracks(), 1)
self.assertEqual(genre.get_track(0), track)
self.assertEqual(genre.get_track_index(track), 0)
self.assertTrue(genre.remove_track(track))
self.assertFalse(genre.remove_track(track))

View File

@ -40,6 +40,7 @@ class TestLibrary(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(library.get_n_tracks(), 1)
self.assertEqual(library.get_track(0), track)
self.assertEqual(library.get_track_index(track), 0)
class TestLibraryTable(unittest.TestCase):

View File

@ -22,6 +22,7 @@ class TestCollection(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(collection.get_n_tracks(), 1)
self.assertEqual(collection.get_track(0), track)
self.assertEqual(collection.get_track_index(track), 0)
track.library.enabled = False
self.assertEqual(collection.get_n_tracks(), 0)
@ -47,6 +48,7 @@ class TestFavorites(unittest.TestCase):
self.assertFalse(favorites.add_track(track))
self.assertEqual(favorites.get_n_tracks(), 1)
self.assertEqual(favorites.get_track(0), track)
self.assertEqual(favorites.get_track_index(track), 0)
self.assertTrue(favorites.remove_track(track))
self.assertFalse(favorites.remove_track(track))
@ -72,6 +74,7 @@ class TestNewTracks(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(new.get_n_tracks(), 1)
self.assertEqual(new.get_track(0), track)
self.assertEqual(new.get_track_index(track), 0)
self.assertTrue(new.remove_track(track))
self.assertFalse(new.remove_track(track))
@ -100,20 +103,26 @@ class TestPrevious(unittest.TestCase):
self.assertTrue(previous.add_track(track1))
self.assertEqual(previous.get_n_tracks(), 1)
self.assertEqual(previous.get_track(0), track1)
self.assertEqual(previous.get_track_index(track1), 0)
self.assertTrue(previous.add_track(track2))
self.assertEqual(previous.get_n_tracks(), 2)
self.assertEqual(previous.get_track(0), track2)
self.assertEqual(previous.get_track(1), track1)
self.assertEqual(previous.get_track_index(track2), 0)
self.assertEqual(previous.get_track_index(track1), 1)
self.assertTrue(previous.add_track(track1))
self.assertEqual(previous.get_n_tracks(), 2)
self.assertEqual(previous.get_track(0), track1)
self.assertEqual(previous.get_track(1), track2)
self.assertEqual(previous.get_track_index(track1), 0)
self.assertEqual(previous.get_track_index(track2), 1)
self.assertTrue(previous.remove_track(track1))
self.assertFalse(previous.remove_track(track1))
self.assertEqual(previous.get_n_tracks(), 1)
self.assertEqual(previous.get_track_index(track2), 0)
class TestQueuedTracks(unittest.TestCase):
@ -138,6 +147,7 @@ class TestQueuedTracks(unittest.TestCase):
self.assertFalse(queued.add_track(track))
self.assertEqual(queued.get_n_tracks(), 1)
self.assertEqual(queued.get_track(0), track)
self.assertEqual(queued.get_track_index(track), 0)
self.assertTrue(queued.remove_track(track))
self.assertFalse(queued.remove_track(track))
@ -173,6 +183,7 @@ class TestUserPlaylist(unittest.TestCase):
self.assertFalse(plist.add_track(track))
self.assertEqual(plist.get_n_tracks(), 1)
self.assertEqual(plist.get_track(0), track)
self.assertEqual(plist.get_track_index(track), 0)
self.assertTrue(plist.remove_track(track))
self.assertFalse(plist.remove_track(track))

View File

@ -29,6 +29,7 @@ class TestYear(unittest.TestCase):
track = db.make_fake_track(1, 1, "Test Track", "/a/b/c/1.ogg")
self.assertEqual(year.get_n_tracks(), 1)
self.assertEqual(year.get_track(0), track)
self.assertEqual(year.get_track_index(track), 0)
class TestYearTable(unittest.TestCase):

View File

@ -40,6 +40,20 @@ class Collection(playlist.Playlist):
[ n ]).fetchone()
return track.Table.factory(row)
def get_track_index(self, track):
order = ', '.join(self.plist_state.sort)
cur = sql.execute(f"SELECT * FROM (SELECT trackid,ROW_NUMBER() "
f"OVER (ORDER BY {order}) "
f"FROM tracks "
f"INNER JOIN artists USING(artistid) "
f"INNER JOIN albums USING(albumid) "
f"INNER JOIN discs USING(discid) "
f"INNER JOIN years USING(yearid) "
f"INNER JOIN libraries USING(libraryid) "
f"WHERE libraries.enabled=1) "
f"WHERE trackid=?", [ track.rowid ])
return cur.fetchone()[1] - 1
@GObject.Property
def name(self): return self._name