home · contact · privacy
Refactor models' .by_id().
[plomtask] / plomtask / todos.py
index cfac5b536e91514f02d938fc760818d3d7278129..840c2985b846de2241def493be68b58939f34657 100644 (file)
@@ -1,5 +1,7 @@
 """Actionables."""
 from __future__ import annotations
+from typing import Any
+from sqlite3 import Row
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.processes import Process
 from plomtask.conditions import Condition
@@ -31,24 +33,29 @@ class Todo(BaseModel):
             self.fulfills = process.fulfills[:]
             self.undoes = process.undoes[:]
 
+    @classmethod
+    def from_table_row(cls, db_conn: DatabaseConnection,
+                       row: Row | list[Any]) -> Todo:
+        """Make from DB row, write to DB cache."""
+        if row[1] == 0:
+            raise NotFoundException('calling Todo of '
+                                    'unsaved Process')
+        row_as_list = list(row)
+        row_as_list[1] = Process.by_id(db_conn, row[1])
+        todo = super().from_table_row(db_conn, row_as_list)
+        assert isinstance(todo, Todo)
+        return todo
+
     @classmethod
     def by_id(cls, db_conn: DatabaseConnection, id_: int | None) -> Todo:
         """Get Todo of .id_=id_ and children (from DB cache if possible)."""
-        if id_ in db_conn.cached_todos.keys():
-            todo = db_conn.cached_todos[id_]
+        if id_:
+            todo, from_cache = super()._by_id(db_conn, id_)
         else:
-            todo = None
-            for row in db_conn.exec('SELECT * FROM todos WHERE id = ?',
-                                    (id_,)):
-                row = list(row)
-                if row[1] == 0:
-                    raise NotFoundException('calling Todo of '
-                                            'unsaved Process')
-                row[1] = Process.by_id(db_conn, row[1])
-                todo = cls.from_table_row(db_conn, row)
-                break
-            if todo is None:
-                raise NotFoundException(f'Todo of ID not found: {id_}')
+            todo, from_cache = None, False
+        if todo is None:
+            raise NotFoundException(f'Todo of ID not found: {id_}')
+        if not from_cache:
             for row in db_conn.exec('SELECT child FROM todo_children '
                                     'WHERE parent = ?', (id_,)):
                 todo.children += [cls.by_id(db_conn, row[0])]