db: Convert the AlbumTable into a playlist.ChildModel
Implements: Issue #11 (Cache database items fields) Implements: Issue #14 (Convert Tables into Gio.ListModels) Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
0728579cc4
commit
a1f54839bb
|
@ -18,7 +18,10 @@ def make_fake_track(trackno, length, title, path, lib="/a/b/c", art="Test Artist
|
|||
alb="Test Album", disk=1, subtitle=None, yeer=2021):
|
||||
lib = library.Table.find(pathlib.Path(lib))
|
||||
art = artist.Table.find(art, art)
|
||||
alb = album.Table.find(art, alb)
|
||||
if (album.Table.lookup(art, alb)) == None:
|
||||
alb = album.Table.insert(art, alb)
|
||||
else:
|
||||
alb = album.Table.lookup(art, alb)
|
||||
disk = disc.Table.find(alb, disk, subtitle)
|
||||
dec = decade.Table.find((yeer // 10) * 10)
|
||||
yeer = dec.find_year(yeer)
|
||||
|
@ -26,11 +29,11 @@ def make_fake_track(trackno, length, title, path, lib="/a/b/c", art="Test Artist
|
|||
length, title, pathlib.Path(path))
|
||||
|
||||
def reset():
|
||||
mods = [ artist, genre, decade, year, library, state ]
|
||||
mods = [ artist, album, genre, decade, year, library, state ]
|
||||
|
||||
for mod in mods: mod.Table.reset()
|
||||
|
||||
mods = [ album, disc, track, user ]
|
||||
mods = [ disc, track, user ]
|
||||
|
||||
for mod in mods: mod.Table.drop()
|
||||
for mod in mods: mod.Table.do_create()
|
||||
|
|
73
db/album.py
73
db/album.py
|
@ -10,65 +10,48 @@
|
|||
# | (artistid, name) -> albumid |
|
||||
# +-----------------------------+
|
||||
from gi.repository import GObject
|
||||
from .sql import execute
|
||||
from . import artist
|
||||
from . import disc
|
||||
from . import objects
|
||||
from . import state
|
||||
from . import playlist
|
||||
from . import sql
|
||||
|
||||
class Album(objects.Tag):
|
||||
def do_get_column(self, column):
|
||||
return execute(f"SELECT {column} FROM albums "
|
||||
"WHERE albumid=?", [ self.rowid ])
|
||||
class Album(playlist.ParentPlaylist):
|
||||
def __init__(self, row):
|
||||
playlist.ParentPlaylist.__init__(self, row)
|
||||
self._name = row["name"]
|
||||
|
||||
@GObject.Property
|
||||
def artist(self):
|
||||
return artist.Table.get(self.get_column("artistid"))
|
||||
def name(self): return self._name
|
||||
|
||||
@GObject.Property
|
||||
def playlist_state(self):
|
||||
return state.Table.get(self.get_column("plstateid"))
|
||||
|
||||
def discs(self):
|
||||
cursor = execute(f"SELECT discid FROM discs "
|
||||
"WHERE albumid=?", [ self.rowid ])
|
||||
return [ disc.Disc(row["discid"]) for row in cursor.fetchall() ]
|
||||
def get_child_table(self): return disc.Table
|
||||
|
||||
|
||||
class AlbumTable(objects.Table):
|
||||
class AlbumTable(playlist.ChildModel):
|
||||
def __init__(self):
|
||||
objects.Table.__init__(self, "albums", Album)
|
||||
playlist.ChildModel.__init__(self, "albums", "artistid", "sort")
|
||||
|
||||
def do_create(self):
|
||||
execute("CREATE TABLE IF NOT EXISTS albums "
|
||||
"(albumid INTEGER PRIMARY KEY, "
|
||||
" artistid INTEGER, "
|
||||
" plstateid INTEGER NOT NULL, "
|
||||
" name TEXT, "
|
||||
" sort TEXT, "
|
||||
" FOREIGN KEY(artistid) REFERENCES artists(artistid), "
|
||||
" FOREIGN KEY(plstateid) REFERENCES playlist_states(plstateid), "
|
||||
" UNIQUE(artistid, name))")
|
||||
execute("CREATE INDEX IF NOT EXISTS artist_index "
|
||||
"ON albums(artistid, name)")
|
||||
sql.execute("CREATE TABLE IF NOT EXISTS albums "
|
||||
"(albumid INTEGER PRIMARY KEY, "
|
||||
" artistid INTEGER, "
|
||||
" plstateid INTEGER NOT NULL, "
|
||||
" name TEXT, "
|
||||
" sort TEXT, "
|
||||
" FOREIGN KEY(artistid) REFERENCES artists(artistid), "
|
||||
" FOREIGN KEY(plstateid) REFERENCES playlist_states(plstateid), "
|
||||
" UNIQUE(artistid, name))")
|
||||
sql.execute("CREATE INDEX IF NOT EXISTS artist_index ON albums(artistid, name)")
|
||||
|
||||
def do_insert(self, artist, name):
|
||||
plstate = state.Table.insert(random=False, loop=False)
|
||||
return execute("INSERT INTO albums (artistid, plstateid, name, sort) "
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
[ artist.rowid, plstate.rowid, name, name.casefold() ])
|
||||
def do_factory(self, row):
|
||||
return Album(row)
|
||||
|
||||
def do_delete(self, album):
|
||||
state.Table.delete(album.playlist_state)
|
||||
return execute("DELETE FROM albums WHERE albumid=?", [ int(album) ])
|
||||
|
||||
def do_get(self, rowid):
|
||||
return execute("SELECT albumid FROM albums "
|
||||
"WHERE albumid=?", [ rowid ])
|
||||
def do_insert(self, plstate, artist, name):
|
||||
return sql.execute("INSERT INTO albums (artistid, plstateid, name, sort) "
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
[ artist.rowid, plstate.rowid, name, name.casefold() ])
|
||||
|
||||
def do_lookup(self, artist, name):
|
||||
return execute("SELECT albumid FROM albums "
|
||||
"WHERE (artistid=? AND name=?)", [ artist.rowid, name ])
|
||||
return sql.execute("SELECT * FROM albums WHERE (artistid=? AND name=?)",
|
||||
[ artist.rowid, name ])
|
||||
|
||||
|
||||
Table = AlbumTable()
|
||||
|
|
10
db/disc.py
10
db/disc.py
|
@ -15,8 +15,8 @@ class Disc(objects.Row):
|
|||
def __lt__(self, rhs): return self.number < rhs.number
|
||||
def __str__(self):
|
||||
if self.subtitle:
|
||||
return f"{str(self.album)}: {self.subtitle}"
|
||||
return f"{str(self.album)}"
|
||||
return f"{self.album.name}: {self.subtitle}"
|
||||
return f"{self.album.name}"
|
||||
|
||||
def do_get_column(self, column):
|
||||
return execute(f"SELECT {column} FROM discs "
|
||||
|
@ -24,7 +24,7 @@ class Disc(objects.Row):
|
|||
|
||||
@GObject.Property
|
||||
def album(self):
|
||||
return album.Album(self.get_column("albumid"))
|
||||
return album.Table.get(self.get_column("albumid"))
|
||||
|
||||
@GObject.Property
|
||||
def number(self):
|
||||
|
@ -59,7 +59,7 @@ class DiscTable(objects.Table):
|
|||
plstate = state.Table.insert(random=False, loop=False)
|
||||
return execute("INSERT INTO discs (albumid, plstateid, number, subtitle) "
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
[ int(album), plstate.rowid, number, subtitle ])
|
||||
[ album.rowid, plstate.rowid, number, subtitle ])
|
||||
|
||||
def do_delete(self, disc):
|
||||
state.Table.delete(disc.playlist_state)
|
||||
|
@ -71,7 +71,7 @@ class DiscTable(objects.Table):
|
|||
|
||||
def do_lookup(self, album, number, subtitle=None):
|
||||
return execute("SELECT discid FROM discs "
|
||||
"WHERE (albumid=? AND number=?)", [ int(album), number ])
|
||||
"WHERE (albumid=? AND number=?)", [ album.rowid, number ])
|
||||
|
||||
|
||||
Table = DiscTable()
|
||||
|
|
|
@ -4,60 +4,44 @@ import sqlite3
|
|||
import unittest
|
||||
from gi.repository import GObject
|
||||
|
||||
|
||||
class TestAlbumTable(unittest.TestCase):
|
||||
def on_row_inserted(self, table, row):
|
||||
self.row_inserted = row
|
||||
|
||||
class TestAlbum(unittest.TestCase):
|
||||
def setUp(self):
|
||||
db.reset()
|
||||
|
||||
def test_album_table_init(self):
|
||||
def test_init(self):
|
||||
artist = db.artist.Table.find("Test Artist", "Test Sort")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
self.assertIsInstance(album, db.playlist.ParentPlaylist)
|
||||
self.assertEqual(album.get_property("name"), "Test Album")
|
||||
self.assertEqual(album.get_child_table(), db.disc.Table)
|
||||
|
||||
|
||||
class TestAlbumTable(unittest.TestCase):
|
||||
def setUp(self):
|
||||
db.reset()
|
||||
|
||||
def test_init(self):
|
||||
table = db.album.AlbumTable()
|
||||
self.assertIsInstance(table, db.playlist.ChildModel)
|
||||
self.assertEqual(table.table, "albums")
|
||||
self.assertEqual(table.parent, "artistid")
|
||||
self.assertEqual(table.order, "sort")
|
||||
|
||||
self.assertIsInstance(db.album.Table, db.album.AlbumTable)
|
||||
db.sql.execute("SELECT albumid,artistid,plstateid,name,sort FROM albums")
|
||||
|
||||
def test_album_table_insert(self):
|
||||
db.album.Table.connect("row-inserted", self.on_row_inserted)
|
||||
|
||||
def test_insert(self):
|
||||
artist = db.artist.Table.insert("Test Artist", "Test Sort")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
|
||||
self.assertIsInstance(album, db.album.Album)
|
||||
self.assertIsInstance(album, db.objects.Tag)
|
||||
self.assertEqual(self.row_inserted, album)
|
||||
|
||||
self.assertEqual(album.name, "Test Album")
|
||||
self.assertEqual(album.sort, "test album")
|
||||
self.assertEqual(album.get_property("artist"), artist)
|
||||
self.assertIsInstance(album.playlist_state, db.state.PlaylistState)
|
||||
self.assertEqual(album._name, "Test Album")
|
||||
|
||||
with self.assertRaises(sqlite3.IntegrityError):
|
||||
db.album.Table.insert(artist, "Test Album")
|
||||
|
||||
def test_album_table_delete(self):
|
||||
artist = db.artist.Table.find("Test Artist", "Test Sort")
|
||||
album = db.album.Table.find(artist, "Test Album")
|
||||
state = album.playlist_state
|
||||
|
||||
db.album.Table.delete(album)
|
||||
self.assertIsNone(db.album.Table.lookup(artist, "Test Album"))
|
||||
self.assertIsNone(db.state.Table.get(state.rowid))
|
||||
|
||||
def test_album_table_get(self):
|
||||
artist = db.artist.Table.insert("Test Artist", "Test Sort")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
self.assertEqual(db.album.Table.get(1), album)
|
||||
self.assertIsNone(db.album.Table.get(2))
|
||||
|
||||
def test_album_table_lookup(self):
|
||||
def test_lookup(self):
|
||||
artist = db.artist.Table.insert("Test Artist", "Test Sort")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
self.assertEqual(db.album.Table.lookup(artist, "Test Album"), album)
|
||||
self.assertIsNone(db.album.Table.lookup(artist, "none"))
|
||||
|
||||
def test_album_discs(self):
|
||||
artist = db.artist.Table.find("Test Artist", "Test Sort")
|
||||
album = db.album.Table.find(artist, "Test Album")
|
||||
disc1 = db.disc.Table.find(album, 1, None)
|
||||
disc2 = db.disc.Table.find(album, 2, None)
|
||||
self.assertEqual(album.discs(), [ disc1, disc2 ])
|
||||
|
|
|
@ -40,7 +40,7 @@ class TestDiscTable(unittest.TestCase):
|
|||
|
||||
def test_disc_table_delete(self):
|
||||
artist = db.artist.Table.find("Test Artist", "Test Sort")
|
||||
album = db.album.Table.find(artist, "Test Album")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
disc = db.disc.Table.find(album, 1, "subtitle")
|
||||
state = disc.playlist_state
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class TestTrackTable(unittest.TestCase):
|
|||
def test_track_table_insert(self):
|
||||
library = db.library.Table.find(pathlib.Path("/a/b/c"))
|
||||
artist = db.artist.Table.find("Test Artist", "test artist")
|
||||
album = db.album.Table.find(artist, "Test Album")
|
||||
album = db.album.Table.insert(artist, "Test Album")
|
||||
disc = db.disc.Table.find(album, 1, None)
|
||||
decade = db.decade.Table.find(2020)
|
||||
year = decade.find_year(2021)
|
||||
|
|
|
@ -39,7 +39,7 @@ class Track(objects.Row):
|
|||
|
||||
@GObject.Property
|
||||
def album(self):
|
||||
return album.Album(self.get_column("albumid"))
|
||||
return album.Table.get(self.get_column("albumid"))
|
||||
|
||||
@GObject.Property
|
||||
def disc(self):
|
||||
|
@ -124,7 +124,7 @@ class TrackTable(objects.Table):
|
|||
return execute("INSERT INTO tracks (libraryid, artistid, albumid, discid, "
|
||||
"decadeid, yearid, number, length, title, path) "
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?)",
|
||||
[ library.rowid, artist.rowid, int(album), int(disc),
|
||||
[ library.rowid, artist.rowid, album.rowid, int(disc),
|
||||
decade.rowid, year.rowid, number, length, title, str(path) ])
|
||||
|
||||
def do_delete(self, track):
|
||||
|
|
|
@ -23,7 +23,8 @@ class FileTask(Task):
|
|||
|
||||
with metadata.Metadata(self.filepath) as meta:
|
||||
artist = db.artist.Table.find(meta.artist(), meta.artistsort())
|
||||
album = db.album.Table.find(artist, meta.album())
|
||||
if (album := db.album.Table.lookup(artist, meta.album())) == None:
|
||||
album = db.album.Table.insert(artist, meta.album())
|
||||
disc = db.disc.Table.find(album, meta.discnumber(), meta.discsubtitle())
|
||||
decade = db.decade.Table.find(meta.decade())
|
||||
year = decade.find_year(meta.year())
|
||||
|
|
Loading…
Reference in New Issue