home · contact · privacy
Base core models on BaseModel providing sensible defaults.
[plomtask] / plomtask / days.py
index afdea33760b41df3149c857b306c6e2b447b7df8..553579e35ee694989433cab6cc0d01310847b180 100644 (file)
@@ -3,7 +3,7 @@ from __future__ import annotations
 from datetime import datetime, timedelta
 from sqlite3 import Row
 from plomtask.exceptions import BadFormatException, NotFoundException
 from datetime import datetime, timedelta
 from sqlite3 import Row
 from plomtask.exceptions import BadFormatException, NotFoundException
-from plomtask.db import DatabaseConnection
+from plomtask.db import DatabaseConnection, BaseModel
 
 DATE_FORMAT = '%Y-%m-%d'
 
 
 DATE_FORMAT = '%Y-%m-%d'
 
@@ -25,11 +25,13 @@ def todays_date() -> str:
     return datetime.now().strftime(DATE_FORMAT)
 
 
     return datetime.now().strftime(DATE_FORMAT)
 
 
-class Day:
+class Day(BaseModel):
     """Individual days defined by their dates."""
     """Individual days defined by their dates."""
+    table_name = 'days'
+    to_save = ['comment']
 
     def __init__(self, date: str, comment: str = '') -> None:
 
     def __init__(self, date: str, comment: str = '') -> None:
-        self.date = valid_date(date)
+        self.id_: str = valid_date(date)
         self.datetime = datetime.strptime(self.date, DATE_FORMAT)
         self.comment = comment
 
         self.datetime = datetime.strptime(self.date, DATE_FORMAT)
         self.comment = comment
 
@@ -40,9 +42,11 @@ class Day:
         return self.date < other.date
 
     @classmethod
         return self.date < other.date
 
     @classmethod
-    def from_table_row(cls, row: Row) -> Day:
-        """Make Day from database row."""
-        return cls(row[0], row[1])
+    def from_table_row(cls, db_conn: DatabaseConnection, row: Row) -> Day:
+        """Make Day from database row, write to cache."""
+        day = cls(row[0], row[1])
+        db_conn.cached_days[day.date] = day
+        return day
 
     @classmethod
     def all(cls, db_conn: DatabaseConnection,
 
     @classmethod
     def all(cls, db_conn: DatabaseConnection,
@@ -54,9 +58,9 @@ class Day:
         start_date = valid_date(date_range[0] if date_range[0] else min_date)
         end_date = valid_date(date_range[1] if date_range[1] else max_date)
         days = []
         start_date = valid_date(date_range[0] if date_range[0] else min_date)
         end_date = valid_date(date_range[1] if date_range[1] else max_date)
         days = []
-        sql = 'SELECT * FROM days WHERE date >= ? AND date <= ?'
+        sql = 'SELECT date FROM days WHERE date >= ? AND date <= ?'
         for row in db_conn.exec(sql, (start_date, end_date)):
         for row in db_conn.exec(sql, (start_date, end_date)):
-            days += [cls.from_table_row(row)]
+            days += [cls.by_date(db_conn, row[0])]
         days.sort()
         if fill_gaps and len(days) > 1:
             gapless_days = []
         days.sort()
         if fill_gaps and len(days) > 1:
             gapless_days = []
@@ -72,12 +76,24 @@ class Day:
     @classmethod
     def by_date(cls, db_conn: DatabaseConnection,
                 date: str, create: bool = False) -> Day:
     @classmethod
     def by_date(cls, db_conn: DatabaseConnection,
                 date: str, create: bool = False) -> Day:
-        """Retrieve Day by date if in DB, else return None."""
+        """Retrieve Day by date if in DB (prefer cache), else return None."""
+        if date in db_conn.cached_days.keys():
+            day = db_conn.cached_days[date]
+            assert isinstance(day, Day)
+            return day
         for row in db_conn.exec('SELECT * FROM days WHERE date = ?', (date,)):
         for row in db_conn.exec('SELECT * FROM days WHERE date = ?', (date,)):
-            return cls.from_table_row(row)
+            return cls.from_table_row(db_conn, row)
         if not create:
             raise NotFoundException(f'Day not found for date: {date}')
         if not create:
             raise NotFoundException(f'Day not found for date: {date}')
-        return cls(date)
+        day = cls(date)
+        db_conn.cached_days[date] = day
+        assert isinstance(day, Day)
+        return day
+
+    @property
+    def date(self) -> str:
+        """Return self.id_ under the assumption it's a date string."""
+        return self.id_
 
     @property
     def weekday(self) -> str:
 
     @property
     def weekday(self) -> str:
@@ -97,6 +113,5 @@ class Day:
         return next_datetime.strftime(DATE_FORMAT)
 
     def save(self, db_conn: DatabaseConnection) -> None:
         return next_datetime.strftime(DATE_FORMAT)
 
     def save(self, db_conn: DatabaseConnection) -> None:
-        """Add (or re-write) self to database."""
-        db_conn.exec('REPLACE INTO days VALUES (?, ?)',
-                     (self.date, self.comment))
+        """Add (or re-write) self to DB and cache."""
+        self.save_core(db_conn, update_with_lastrowid=False)