home · contact · privacy
Refactor from_table_row methods of core DB models.
[plomtask] / plomtask / todos.py
index ce83faddff55278c0efe44f604f6a5fddfaa5851..cfac5b536e91514f02d938fc760818d3d7278129 100644 (file)
@@ -1,25 +1,26 @@
 """Actionables."""
 from __future__ import annotations
 """Actionables."""
 from __future__ import annotations
-from sqlite3 import Row
-from plomtask.db import DatabaseConnection
-from plomtask.days import Day
+from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.processes import Process
 from plomtask.conditions import Condition
 from plomtask.exceptions import (NotFoundException, BadFormatException,
                                  HandledException)
 
 
 from plomtask.processes import Process
 from plomtask.conditions import Condition
 from plomtask.exceptions import (NotFoundException, BadFormatException,
                                  HandledException)
 
 
-class Todo:
+class Todo(BaseModel):
     """Individual actionable."""
 
     # pylint: disable=too-many-instance-attributes
 
     """Individual actionable."""
 
     # pylint: disable=too-many-instance-attributes
 
+    table_name = 'todos'
+    to_save = ['process_id', 'is_done', 'date']
+
     def __init__(self, id_: int | None, process: Process,
     def __init__(self, id_: int | None, process: Process,
-                 is_done: bool, day: Day) -> None:
-        self.id_ = id_
+                 is_done: bool, date: str) -> None:
+        self.set_int_id(id_)
         self.process = process
         self._is_done = is_done
         self.process = process
         self._is_done = is_done
-        self.day = day
+        self.date = date
         self.children: list[Todo] = []
         self.parents: list[Todo] = []
         self.conditions: list[Condition] = []
         self.children: list[Todo] = []
         self.parents: list[Todo] = []
         self.conditions: list[Condition] = []
@@ -30,17 +31,6 @@ class Todo:
             self.fulfills = process.fulfills[:]
             self.undoes = process.undoes[:]
 
             self.fulfills = process.fulfills[:]
             self.undoes = process.undoes[:]
 
-    @classmethod
-    def from_table_row(cls, db_conn: DatabaseConnection, row: Row) -> Todo:
-        """Make Todo from database row, write to DB cache."""
-        todo = cls(id_=row[0],
-                   process=Process.by_id(db_conn, row[1]),
-                   is_done=bool(row[2]),
-                   day=Day.by_date(db_conn, row[3]))
-        assert todo.id_ is not None
-        db_conn.cached_todos[todo.id_] = 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)."""
     @classmethod
     def by_id(cls, db_conn: DatabaseConnection, id_: int | None) -> Todo:
         """Get Todo of .id_=id_ and children (from DB cache if possible)."""
@@ -50,6 +40,11 @@ class Todo:
             todo = None
             for row in db_conn.exec('SELECT * FROM todos WHERE id = ?',
                                     (id_,)):
             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:
                 todo = cls.from_table_row(db_conn, row)
                 break
             if todo is None:
@@ -88,7 +83,7 @@ class Todo:
         for row in db_conn.exec('SELECT todo FROM todo_fulfills '
                                 'WHERE condition = ?', (condition.id_,)):
             todo = cls.by_id(db_conn, row[0])
         for row in db_conn.exec('SELECT todo FROM todo_fulfills '
                                 'WHERE condition = ?', (condition.id_,)):
             todo = cls.by_id(db_conn, row[0])
-            if todo.day.date == date:
+            if todo.date == date:
                 enablers += [todo]
         return enablers
 
                 enablers += [todo]
         return enablers
 
@@ -100,7 +95,7 @@ class Todo:
         for row in db_conn.exec('SELECT todo FROM todo_undoes '
                                 'WHERE condition = ?', (condition.id_,)):
             todo = cls.by_id(db_conn, row[0])
         for row in db_conn.exec('SELECT todo FROM todo_undoes '
                                 'WHERE condition = ?', (condition.id_,)):
             todo = cls.by_id(db_conn, row[0])
-            if todo.day.date == date:
+            if todo.date == date:
                 disablers += [todo]
         return disablers
 
                 disablers += [todo]
         return disablers
 
@@ -115,6 +110,11 @@ class Todo:
                 return False
         return True
 
                 return False
         return True
 
+    @property
+    def process_id(self) -> int | str | None:
+        """Return ID of tasked Process."""
+        return self.process.id_
+
     @property
     def is_done(self) -> bool:
         """Wrapper around self._is_done so we can control its setter."""
     @property
     def is_done(self) -> bool:
         """Wrapper around self._is_done so we can control its setter."""
@@ -171,11 +171,8 @@ class Todo:
         """Write self and children to DB and its cache."""
         if self.process.id_ is None:
             raise NotFoundException('Process of Todo without ID (not saved?)')
         """Write self and children to DB and its cache."""
         if self.process.id_ is None:
             raise NotFoundException('Process of Todo without ID (not saved?)')
-        cursor = db_conn.exec('REPLACE INTO todos VALUES (?,?,?,?)',
-                              (self.id_, self.process.id_,
-                               self.is_done, self.day.date))
-        self.id_ = cursor.lastrowid
-        assert self.id_ is not None
+        self.save_core(db_conn)
+        assert isinstance(self.id_, int)
         db_conn.cached_todos[self.id_] = self
         db_conn.exec('DELETE FROM todo_children WHERE parent = ?',
                      (self.id_,))
         db_conn.cached_todos[self.id_] = self
         db_conn.exec('DELETE FROM todo_children WHERE parent = ?',
                      (self.id_,))