db: Create a database Row base class
This will be shared between settings, playlists, and tracks so we have a common interface for working with database rows. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
8c8135fc23
commit
2eef68f76f
|
@ -0,0 +1,33 @@
|
|||
# Copyright 2022 (c) Anna Schumaker
|
||||
"""Base classes for database objects."""
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
|
||||
|
||||
class Row(GObject.GObject):
|
||||
"""A single row in a database table."""
|
||||
|
||||
table = GObject.Property(type=Gio.ListModel)
|
||||
|
||||
def __init__(self, table: Gio.ListModel, **kwargs):
|
||||
"""Initialize a database Row."""
|
||||
super().__init__(table=table, **kwargs)
|
||||
self.connect("notify", self.__notify)
|
||||
|
||||
def __notify(self, row: GObject.GObject, param: GObject.ParamSpec) -> None:
|
||||
match param.name:
|
||||
case "table": pass
|
||||
case _: self.do_update(param.name)
|
||||
|
||||
def do_update(self, column: str) -> bool:
|
||||
"""Update a Row in the database."""
|
||||
return self.table.update(self, column, self.get_property(column))
|
||||
|
||||
def delete(self) -> bool:
|
||||
"""Delete this Row."""
|
||||
return self.table.delete(self)
|
||||
|
||||
@property
|
||||
def primary_key(self) -> None:
|
||||
"""Get the primary key for this row."""
|
||||
raise NotImplementedError
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2022 (c) Anna Schumaker
|
||||
"""Tests our database object base classes."""
|
||||
import unittest
|
||||
import unittest.mock
|
||||
import emmental.db.table
|
||||
import tests.util.table
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
|
||||
|
||||
class TestRow(unittest.TestCase):
|
||||
"""Tests our common database Row object."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.table = Gio.ListStore()
|
||||
self.table.delete = unittest.mock.Mock(return_value=True)
|
||||
self.table.update = unittest.mock.Mock(return_value=True)
|
||||
self.row = tests.util.table.MockRow(table=self.table)
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the database Row is configured correctly."""
|
||||
self.assertIsInstance(self.row, emmental.db.table.Row)
|
||||
self.assertIsInstance(self.row, GObject.GObject)
|
||||
self.assertEqual(self.row.table, self.table)
|
||||
|
||||
def test_primary_key(self):
|
||||
"""Test the primary_key property."""
|
||||
with self.assertRaises(NotImplementedError):
|
||||
emmental.db.table.Row(self.table).primary_key
|
||||
|
||||
self.row.number = 2
|
||||
self.assertEqual(self.row.primary_key, 2)
|
||||
|
||||
def test_do_update(self):
|
||||
"""Test updating a Row attribute."""
|
||||
self.row.number = 1
|
||||
self.table.update.assert_called_with(self.row, "number", 1)
|
||||
|
||||
self.table.update.reset_mock()
|
||||
self.row.table = None
|
||||
self.table.update.assert_not_called()
|
||||
|
||||
def test_delete(self):
|
||||
"""Test deleting a Row."""
|
||||
self.assertTrue(self.row.delete())
|
||||
self.table.delete.assert_called_with(self.row)
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2023 (c) Anna Schumaker.
|
||||
"""Mock Row and Table objects for testing."""
|
||||
import emmental.db.table
|
||||
from gi.repository import GObject
|
||||
|
||||
|
||||
class MockRow(emmental.db.table.Row):
|
||||
"""A fake Row customized for testing."""
|
||||
|
||||
number = GObject.Property(type=int)
|
||||
|
||||
@property
|
||||
def primary_key(self) -> int:
|
||||
"""Get the primary key for this MockRow."""
|
||||
return self.number
|
Loading…
Reference in New Issue