from typing import Any, Self
from sqlite3 import Row
from datetime import date as dt_date, timedelta
-from plomtask.db import DatabaseConnection, BaseModel, BaseModelId
+from plomtask.db import DatabaseConnection, BaseModel
from plomtask.todos import Todo
from plomtask.dating import dt_date_from_days_n, days_n_from_dt_date
return day
@classmethod
- def by_id(cls, db_conn: DatabaseConnection, id_: BaseModelId) -> Self:
+ def by_id(cls, db_conn: DatabaseConnection, id_: int) -> Self:
"""Checks Todo.days_to_update if we need to a retrieved Day's .todos"""
day = super().by_id(db_conn, id_)
assert isinstance(day.id_, int)
self.exec(f'DELETE FROM {table_name} WHERE {key} =', (target,))
-BaseModelId = int | str
-
-
class BaseModel:
"""Template for most of the models we use/derive from the DB."""
table_name = ''
to_save_relations: list[tuple[str, str, str, int]] = []
versioned_defaults: dict[str, str | float] = {}
add_to_dict: list[str] = []
- id_: None | BaseModelId
- cache_: dict[BaseModelId, Self]
+ id_: None | int
+ cache_: dict[int, Self]
to_search: list[str] = []
can_create_by_id = False
_exists = True
sorters: dict[str, Callable[..., Any]] = {}
- def __init__(self, id_: BaseModelId | None) -> None:
+ def __init__(self, id_: int | None) -> None:
if isinstance(id_, int) and id_ < 1:
msg = f'illegal {self.__class__.__name__} ID, must be >=1: {id_}'
raise BadFormatException(msg)
- if isinstance(id_, str) and "" == id_:
- msg = f'illegal {self.__class__.__name__} ID, must be non-empty'
- raise BadFormatException(msg)
self.id_ = id_
def __hash__(self) -> int:
return list(cls.versioned_defaults.keys())
@property
- def as_dict_and_refs(self) -> tuple[dict[str, object], list[BaseModel]]:
+ def as_dict_and_refs(self) -> tuple[dict[str, object], list[Self]]:
"""Return self as json.dumps-ready dict, list of referenced objects."""
d: dict[str, object] = {'id': self.id_}
- refs: list[BaseModel] = []
+ refs: list[Self] = []
for to_save in self.to_save_simples:
d[to_save] = getattr(self, to_save)
if len(self.to_save_versioned()) > 0:
cls.cache_ = {}
@classmethod
- def get_cache(cls) -> dict[BaseModelId, Self]:
+ def get_cache(cls) -> dict[int, Self]:
"""Get cache dictionary, create it if not yet existing."""
if not hasattr(cls, 'cache_'):
- d: dict[BaseModelId, BaseModel] = {}
+ d: dict[int, Self] = {}
cls.cache_ = d
return cls.cache_
@classmethod
- def _get_cached(cls, id_: BaseModelId) -> Self | None:
+ def _get_cached(cls, id_: int) -> Self | None:
"""Get object of id_ from class's cache, or None if not found."""
cache = cls.get_cache()
if id_ in cache:
return obj
@classmethod
- def by_id(cls, db_conn: DatabaseConnection, id_: BaseModelId) -> Self:
+ def by_id(cls, db_conn: DatabaseConnection, id_: int) -> Self:
"""Retrieve by id_, on failure throw NotFoundException.
First try to get from cls.cache_, only then check DB; if found,
raise NotFoundException(f'found no object of ID {id_}')
@classmethod
- def by_id_or_create(cls, db_conn: DatabaseConnection,
- id_: BaseModelId | None
+ def by_id_or_create(cls, db_conn: DatabaseConnection, id_: int | None
) -> Self:
"""Wrapper around .by_id, creating (not caching/saving) if no find."""
if not cls.can_create_by_id:
cache is always instantly cleaned of any items that would be removed
from the DB.
"""
- items: dict[BaseModelId, Self] = {}
+ items: dict[int, Self] = {}
for k, v in cls.get_cache().items():
items[k] = v
already_recorded = items.keys()
for attr_name in self.to_save_versioned():
getattr(self, attr_name).save(db_conn)
for table, column, attr_name, key_index in self.to_save_relations:
- assert isinstance(self.id_, (int, str))
+ assert isinstance(self.id_, int)
db_conn.rewrite_relations(table, column, self.id_,
[[i.id_] for i
in getattr(self, attr_name)], key_index)