db: Create a new Child class

This inherites from the Table, but takes a parent instance for some
functions and calculates offsets for items that descend from this
parent.

Implements: Issue #1 (Have SQLite sort our sidebar tables)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-10-07 22:01:50 -04:00
parent feeee8809d
commit 658be5bef1
2 changed files with 76 additions and 0 deletions

View File

@ -87,3 +87,31 @@ class Model(GObject.GObject, Gio.ListModel, Table):
n = self.get_n_items()
super().reset()
self.emit("items-changed", 0, n, self.get_n_items())
class Child(Table):
def __init__(self, table, parent, order):
Table.__init__(self, table)
self.parent = parent
self.order = order
def get_n_children(self, parent):
cur = sql.execute(f"SELECT COUNT(*) FROM {self.table} "
f"WHERE {self.parent}=?", [ parent.rowid ])
return cur.fetchone()[0]
def get_child(self, parent, n):
cur = sql.execute(f"SELECT * FROM {self.table} WHERE {self.parent}=? "
f"ORDER BY {self.order} LIMIT 1 OFFSET ?",
[ parent.rowid, n ])
return self.factory(cur.fetchone())
def get_child_index(self, parent, child):
cur = sql.execute(f"SELECT * FROM (SELECT rowid,ROW_NUMBER() "
f"OVER (ORDER BY {self.order}) "
f"FROM {self.table} "
f"WHERE {self.parent}=?)"
f"WHERE rowid=?", [ parent.rowid, child.rowid ])
return cur.fetchone()[1] - 1
def find(self, *args): raise NotImplementedError

View File

@ -34,6 +34,24 @@ class FakeModel(table.Model, FakeTable):
table.Model.__init__(self, "fake_table", "lower(name)")
self.reset()
class FakeChild(table.Child):
def __init__(self):
table.Child.__init__(self, "fake_child", "parentid", "lower(name)")
self.reset()
def do_create(self):
sql.execute("CREATE TABLE IF NOT EXISTS fake_child "
"(fakeid INTEGER PRIMARY KEY, "
"parentid INTEGER, "
"name TEXT UNIQUE, "
"FOREIGN KEY(parentid) REFERENCES fake_table(fakeid))")
def do_factory(self, row):
return FakeRow(row)
def do_insert(self, parent, name):
return sql.execute("INSERT INTO fake_child (parentid, name) "
"VALUES (?,?)", [ parent.rowid, name ])
class TestTable(unittest.TestCase):
@ -139,3 +157,33 @@ class TestModel(unittest.TestCase):
fake.connect("items-changed", self.items_changed)
fake.reset()
self.assertEqual(self.changed, (0, 2, 0))
class TestChild(unittest.TestCase):
def test_init(self):
child = FakeChild()
self.assertIsInstance(child, table.Table)
self.assertEqual(child.parent, "parentid")
self.assertEqual(child.order, "lower(name)")
def test_children(self):
model = FakeModel()
child = FakeChild()
parent = model.insert("Fake Parent")
self.assertEqual(child.get_n_children(parent), 0)
c = child.insert(parent, "C")
b = child.insert(parent, "B")
a = child.insert(parent, "A")
self.assertEqual(child.get_n_children(parent), 3)
self.assertEqual(child.get_child(parent, 0), a)
self.assertEqual(child.get_child(parent, 1), b)
self.assertEqual(child.get_child(parent, 2), c)
self.assertEqual(child.get_child_index(parent, a), 0)
self.assertEqual(child.get_child_index(parent, b), 1)
self.assertEqual(child.get_child_index(parent, c), 2)