db: Rename the Table.Filter to Table.KeySet

I'm going to expand on this and use it for more than just filtering
Gtk.FilterListModels. Renaming it to something more generic is the first
step.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-06-19 09:55:11 -04:00
parent 0c66b13209
commit f400366210
5 changed files with 85 additions and 85 deletions

View File

@ -19,7 +19,7 @@ class Artist(playlist.Playlist):
"""Initialize an Artist object."""
super().__init__(**kwargs)
self.add_children(self.table.sql.albums,
table.Filter(self.table.get_albumids(self)))
table.KeySet(self.table.get_albumids(self)))
def add_album(self, album: Album) -> None:
"""Add an Album to this Artist."""
@ -41,7 +41,7 @@ class Artist(playlist.Playlist):
return self.artistid
class Filter(table.Filter):
class Filter(table.KeySet):
"""Custom filter to hide artists without albums."""
show_all = GObject.Property(type=bool, default=False)
@ -51,7 +51,7 @@ class Filter(table.Filter):
super().__init__(show_all=show_all)
self.connect("notify::show-all", self.__notify_show_all)
def __notify_show_all(self, filter: table.Filter, param) -> None:
def __notify_show_all(self, filter: table.KeySet, param) -> None:
self.changed(Gtk.FilterChange.LESS_STRICT if self.show_all else
Gtk.FilterChange.MORE_STRICT)

View File

@ -37,19 +37,19 @@ class Row(GObject.GObject):
raise NotImplementedError
class Filter(Gtk.Filter):
"""A Filter that can be used to search playlists."""
class KeySet(Gtk.Filter):
"""A Gtk.Filter that also acts as a Python Set."""
n_keys = GObject.Property(type=int)
def __init__(self, keys: set | None = None, **kwargs):
"""Set up our Filter."""
"""Set up our KeySet."""
super().__init__(**kwargs)
self._keys = keys
self.n_keys = len(keys) if keys is not None else -1
def __sub__(self, rhs: Gtk.Filter) -> set[int]:
"""Subtract two Filters and return the result."""
"""Subtract two KeySets and return the result."""
match (self._keys, rhs._keys):
case (None, _): return None
case (_, None): return self._keys
@ -69,12 +69,12 @@ class Filter(Gtk.Filter):
return Gtk.FilterChange.DIFFERENT
def changed(self, how: Gtk.FilterChange) -> None:
"""Notify that the filter has changed."""
"""Notify that the KeySet has changed."""
self.n_keys = len(self._keys) if self._keys is not None else -1
super().changed(how)
def do_get_strictness(self) -> Gtk.FilterMatch:
"""Get the strictness of the filter."""
"""Get the strictness of the Gtk.Filter."""
if self._keys is None:
return Gtk.FilterMatch.ALL
if len(self._keys) == 0:
@ -82,17 +82,17 @@ class Filter(Gtk.Filter):
return Gtk.FilterMatch.SOME
def do_match(self, row: Row) -> bool:
"""Check if the Row matches the filter."""
"""Check if the Row is in the KeySet."""
return self._keys is None or row.primary_key in self._keys
def add_row(self, row: Row) -> None:
"""Add a Row to the Filter."""
"""Add a Row to the KeySet."""
if self._keys is not None:
self._keys.add(row.primary_key)
self.changed(Gtk.FilterChange.LESS_STRICT)
def remove_row(self, row: Row) -> None:
"""Remove a Row from the Filter."""
"""Remove a Row from the KeySet."""
if self._keys is not None:
self._keys.discard(row.primary_key)
self.changed(Gtk.FilterChange.MORE_STRICT)
@ -121,12 +121,12 @@ class Table(Gtk.FilterListModel):
loaded = GObject.Property(type=bool, default=False)
def __init__(self, sql: GObject.TYPE_PYOBJECT,
filter: Filter | None = None,
filter: KeySet | None = None,
queue: Queue | None = None, **kwargs):
"""Set up our Table object."""
super().__init__(sql=sql, rows=dict(), incremental=True,
store=store.SortedList(self.get_sort_key),
filter=(filter if filter else Filter()),
filter=(filter if filter else KeySet()),
queue=(queue if queue else Queue()), **kwargs)
self.set_model(self.store)

View File

@ -90,7 +90,7 @@ class Track(table.Row):
return self.trackid
class Filter(table.Filter):
class Filter(table.KeySet):
"""A customized Filter that never sets strictness to FilterMatch.All."""
def do_get_strictness(self) -> Gtk.FilterMatch:

View File

@ -53,7 +53,7 @@ class TestArtistObject(tests.util.TestCase):
"""Test that Albums have been added as Artist playlist children."""
self.assertIsInstance(self.artist.children, Gtk.FilterListModel)
self.assertIsInstance(self.artist.children.get_filter(),
emmental.db.table.Filter)
emmental.db.table.KeySet)
self.assertEqual(self.artist.children.get_model(), self.sql.albums)
@ -68,7 +68,7 @@ class TestFilter(tests.util.TestCase):
def test_init(self):
"""Test that the filter is initialized properly."""
self.assertIsInstance(self.filter, emmental.db.table.Filter)
self.assertIsInstance(self.filter, emmental.db.table.KeySet)
self.assertFalse(self.filter.show_all)
filter2 = emmental.db.artists.Filter(show_all=True)

View File

@ -50,119 +50,119 @@ class TestRow(unittest.TestCase):
@unittest.mock.patch("gi.repository.Gtk.Filter.changed")
class TestFilter(unittest.TestCase):
"""Tests our database row Filter."""
class TestKeySet(unittest.TestCase):
"""Tests our KeySet for holding database Rows."""
def setUp(self):
"""Set up common variables."""
self.filter = emmental.db.table.Filter()
self.keyset = emmental.db.table.KeySet()
self.table = Gio.ListStore()
self.row1 = tests.util.table.MockRow(number=1, table=self.table)
self.row2 = tests.util.table.MockRow(number=2, table=self.table)
def test_init(self, mock_changed: unittest.mock.Mock):
"""Test that the filter is created correctly."""
self.assertIsInstance(self.filter, Gtk.Filter)
self.assertIsNone(self.filter._keys, None)
self.assertEqual(self.filter.n_keys, -1)
"""Test that the KeySet is created correctly."""
self.assertIsInstance(self.keyset, Gtk.Filter)
self.assertIsNone(self.keyset._keys, None)
self.assertEqual(self.keyset.n_keys, -1)
filter2 = emmental.db.table.Filter(keys={1, 2, 3})
self.assertSetEqual(filter2._keys, {1, 2, 3})
self.assertEqual(filter2.n_keys, 3)
keyset2 = emmental.db.table.KeySet(keys={1, 2, 3})
self.assertSetEqual(keyset2._keys, {1, 2, 3})
self.assertEqual(keyset2.n_keys, 3)
def test_subtract(self, mock_changed: unittest.mock.Mock):
"""Test subtracting two filters."""
filter2 = emmental.db.table.Filter(keys={2, 3})
self.assertIsNone(self.filter - self.filter)
self.assertIsNone(self.filter - filter2)
self.assertSetEqual(filter2 - self.filter, {2, 3})
"""Test subtracting two KeySets."""
keyset2 = emmental.db.table.KeySet(keys={2, 3})
self.assertIsNone(self.keyset - self.keyset)
self.assertIsNone(self.keyset - keyset2)
self.assertSetEqual(keyset2 - self.keyset, {2, 3})
self.filter.keys = {1, 2, 3, 4, 5}
self.assertSetEqual(self.filter - filter2, {1, 4, 5})
self.assertSetEqual(filter2 - self.filter, set())
self.keyset.keys = {1, 2, 3, 4, 5}
self.assertSetEqual(self.keyset - keyset2, {1, 4, 5})
self.assertSetEqual(keyset2 - self.keyset, set())
def test_strictness(self, mock_changed: unittest.mock.Mock):
"""Test checking strictness."""
self.assertEqual(self.filter.get_strictness(), Gtk.FilterMatch.ALL)
self.filter._keys = set()
self.assertEqual(self.filter.get_strictness(), Gtk.FilterMatch.NONE)
self.filter._keys = {1, 2, 3}
self.assertEqual(self.filter.get_strictness(), Gtk.FilterMatch.SOME)
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.ALL)
self.keyset._keys = set()
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.NONE)
self.keyset._keys = {1, 2, 3}
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.SOME)
def test_add_row(self, mock_changed: unittest.mock.Mock):
"""Test adding Rows to the filter."""
self.filter.add_row(self.row1)
self.assertIsNone(self.filter.keys)
"""Test adding Rows to the KeySet."""
self.keyset.add_row(self.row1)
self.assertIsNone(self.keyset.keys)
self.filter.keys = set()
self.filter.add_row(self.row1)
self.assertSetEqual(self.filter.keys, {1})
self.keyset.keys = set()
self.keyset.add_row(self.row1)
self.assertSetEqual(self.keyset.keys, {1})
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
self.assertEqual(self.filter.n_keys, 1)
self.assertEqual(self.keyset.n_keys, 1)
self.filter.add_row(self.row2)
self.assertSetEqual(self.filter.keys, {1, 2})
self.keyset.add_row(self.row2)
self.assertSetEqual(self.keyset.keys, {1, 2})
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
self.assertEqual(self.filter.n_keys, 2)
self.assertEqual(self.keyset.n_keys, 2)
def test_remove_row(self, mock_changed: unittest.mock.Mock):
"""Test removing Rows from the filter."""
self.filter.remove_row(self.row1)
"""Test removing Rows from the KeySet."""
self.keyset.remove_row(self.row1)
mock_changed.assert_not_called()
self.filter.keys = {1, 2}
self.filter.remove_row(self.row1)
self.assertSetEqual(self.filter._keys, {2})
self.keyset.keys = {1, 2}
self.keyset.remove_row(self.row1)
self.assertSetEqual(self.keyset._keys, {2})
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
self.assertEqual(self.filter.n_keys, 1)
self.assertEqual(self.keyset.n_keys, 1)
mock_changed.reset_mock()
self.filter.remove_row(self.row2)
self.assertSetEqual(self.filter._keys, set())
self.keyset.remove_row(self.row2)
self.assertSetEqual(self.keyset._keys, set())
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
self.assertEqual(self.filter.n_keys, 0)
self.assertEqual(self.keyset.n_keys, 0)
def test_keys(self, mock_changed: unittest.mock.Mock):
"""Test setting and getting the filter keys property."""
self.assertIsNone(self.filter.keys)
"""Test setting and getting the KeySet keys property."""
self.assertIsNone(self.keyset.keys)
self.filter.keys = {1, 2, 3}
self.assertSetEqual(self.filter._keys, {1, 2, 3})
self.keyset.keys = {1, 2, 3}
self.assertSetEqual(self.keyset._keys, {1, 2, 3})
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
self.assertEqual(self.filter.n_keys, 3)
self.assertEqual(self.keyset.n_keys, 3)
mock_changed.reset_mock()
self.filter.keys = {1, 2}
self.assertSetEqual(self.filter.keys, {1, 2})
self.keyset.keys = {1, 2}
self.assertSetEqual(self.keyset.keys, {1, 2})
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
self.assertEqual(self.filter.n_keys, 2)
self.assertEqual(self.keyset.n_keys, 2)
mock_changed.reset_mock()
self.filter.keys = {1, 2}
self.keyset.keys = {1, 2}
mock_changed.assert_not_called()
self.filter.keys = {1, 2, 3}
self.assertSetEqual(self.filter.keys, {1, 2, 3})
self.keyset.keys = {1, 2, 3}
self.assertSetEqual(self.keyset.keys, {1, 2, 3})
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
self.filter.keys = {4, 5, 6}
self.assertSetEqual(self.filter._keys, {4, 5, 6})
self.keyset.keys = {4, 5, 6}
self.assertSetEqual(self.keyset._keys, {4, 5, 6})
mock_changed.assert_called_with(Gtk.FilterChange.DIFFERENT)
self.filter.keys = None
self.assertIsNone(self.filter._keys)
self.keyset.keys = None
self.assertIsNone(self.keyset._keys)
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
self.assertEqual(self.filter.n_keys, -1)
self.assertEqual(self.keyset.n_keys, -1)
def test_match(self, mock_changed: unittest.mock.Mock):
"""Test matching playlists."""
self.assertTrue(self.filter.match(self.row1))
self.filter.keys = {1, 2, 3}
self.assertTrue(self.filter.match(self.row1))
self.filter.keys = {4, 5, 6}
self.assertFalse(self.filter.match(self.row1))
self.filter.keys = set()
self.assertFalse(self.filter.match(self.row1))
"""Test matching Rows."""
self.assertTrue(self.keyset.match(self.row1))
self.keyset.keys = {1, 2, 3}
self.assertTrue(self.keyset.match(self.row1))
self.keyset.keys = {4, 5, 6}
self.assertFalse(self.keyset.match(self.row1))
self.keyset.keys = set()
self.assertFalse(self.keyset.match(self.row1))
class TestTable(tests.util.TestCase):
@ -178,7 +178,7 @@ class TestTable(tests.util.TestCase):
self.assertIsInstance(self.table, Gtk.FilterListModel)
self.assertIsInstance(self.table.queue, emmental.db.idle.Queue)
self.assertIsInstance(self.table.get_filter(),
emmental.db.table.Filter)
emmental.db.table.KeySet)
self.assertIsInstance(self.table.store, emmental.store.SortedList)
self.assertIsInstance(self.table.rows, dict)
@ -188,7 +188,7 @@ class TestTable(tests.util.TestCase):
self.assertDictEqual(self.table.rows, {})
self.assertTrue(self.table.get_incremental())
filter2 = emmental.db.table.Filter()
filter2 = emmental.db.table.KeySet()
queue2 = emmental.db.idle.Queue()
table2 = emmental.db.table.Table(self.sql, filter=filter2,
queue=queue2)