emmental/emmental/db/decades.py

110 lines
4.0 KiB
Python

# Copyright 2022 (c) Anna Schumaker
"""A custom Gio.ListModel for working with decades."""
import sqlite3
from gi.repository import GObject
from .years import Year
from . import playlist
from . import tracks
class Decade(playlist.Playlist):
"""Our custom Decade object."""
decade = GObject.Property(type=int)
def __init__(self, **kwargs):
"""Initialize a Decade object."""
super().__init__(**kwargs)
self.add_children(self.table.sql.years,
self.table.get_yearids(self))
def add_year(self, year: Year) -> None:
"""Add a year to this decade."""
self.add_child(year)
def get_years(self) -> list[Year]:
"""Get a list of years for this decade."""
return self.table.get_years(self)
def has_year(self, year: Year) -> bool:
"""Check if the year is in this decade."""
return self.has_child(year)
def remove_year(self, year: Year) -> None:
"""Remove a year from this decade."""
self.remove_child(year)
@property
def primary_key(self) -> int:
"""Get the primary key of this Decade."""
return self.decade
class Table(playlist.Table):
"""Our Decade Table."""
def __init__(self, sql: GObject.TYPE_PYOBJECT, **kwargs):
"""Initialize the Decade table."""
super().__init__(sql=sql, autodelete=True,
system_tracks=False, **kwargs)
def do_add_track(self, decade: Decade, track: tracks.Track) -> bool:
"""Verify adding a Track to the Decade playlist."""
return (track.year // 10 * 10) == decade.decade
def do_construct(self, **kwargs) -> Decade:
"""Construct a new Decade playlist."""
return Decade(**kwargs)
def do_get_sort_key(self, decade: Decade) -> int:
"""Get the sort key for the requested decade."""
return decade.decade
def do_remove_track(self, decade: Decade, track: tracks.Track) -> bool:
"""Verify removing a Track from the Decade playlist."""
return True
def do_sql_delete(self, decade: Decade) -> sqlite3.Cursor:
"""Delete a decade."""
for year in decade.get_years():
year.delete()
return self.sql("DELETE FROM decades WHERE decade=?", decade.decade)
def do_sql_glob(self, glob: str) -> sqlite3.Cursor:
"""Search for decades matching the search text."""
return self.sql("""SELECT decade FROM decades_view
WHERE CASEFOLD(name) GLOB :glob
UNION SELECT (year / 10 * 10) AS decade
FROM years WHERE year GLOB :glob""", glob=glob)
def do_sql_insert(self, year: int) -> sqlite3.Cursor | None:
"""Create a new Decade playlist."""
decade = year // 10 * 10
if self.sql("INSERT INTO decades (decade) VALUES (?)", decade):
return self.sql("SELECT * FROM decades_view WHERE decade=?",
decade)
def do_sql_select_all(self) -> sqlite3.Cursor:
"""Load Decades from the database."""
return self.sql("SELECT * FROM decades_view")
def do_sql_select_one(self, year: int) -> sqlite3.Cursor:
"""Look up an decade by year."""
return self.sql("SELECT decade FROM decades WHERE decade=?",
year // 10 * 10)
def do_sql_select_trackids(self, decade: Decade) -> sqlite3.Cursor:
"""Load a Decade's Tracks from the database."""
return self.sql("""SELECT trackid FROM decade_tracks_view
WHERE decade=?""", decade.decade)
def get_yearids(self, decade: Decade) -> set[int]:
"""Get the set of years for this decade."""
rows = self.sql("SELECT year FROM years WHERE (year / 10 * 10)=?",
decade.decade)
return {row["year"] for row in rows}
def get_years(self, decade: Decade) -> list[Year]:
"""Get the list of years for this decade."""
return [self.sql.years.rows.get(yr) for yr in self.get_yearids(decade)]