+ @classmethod
+ def all(cls: type[BaseModelInstance],
+ db_conn: DatabaseConnection) -> list[BaseModelInstance]:
+ """Collect all objects of class."""
+ items: dict[BaseModelId, BaseModelInstance] = {}
+ for k, v in cls.get_cache().items():
+ assert isinstance(v, cls)
+ items[k] = v
+ already_recorded = items.keys()
+ for id_ in db_conn.column_all(cls.table_name, 'id'):
+ if id_ not in already_recorded:
+ item = cls.by_id(db_conn, id_)
+ assert item.id_ is not None
+ items[item.id_] = item
+ return list(items.values())
+
+ def __eq__(self, other: object) -> bool:
+ if not isinstance(other, self.__class__):
+ msg = 'cannot compare to object of different class'
+ raise HandledException(msg)
+ to_hash_me = tuple([self.id_] +
+ [getattr(self, name) for name in self.to_save])
+ to_hash_other = tuple([other.id_] +
+ [getattr(other, name) for name in other.to_save])
+ return hash(to_hash_me) == hash(to_hash_other)
+
+ def save_core(self, db_conn: DatabaseConnection) -> None:
+ """Write bare-bones self (sans connected items), ensuring self.id_.
+
+ Write both to DB, and to cache. To DB, write .id_ and attributes
+ listed in cls.to_save.
+
+ Ensure self.id_ by setting it to what the DB command returns as the
+ last saved row's ID (cursor.lastrowid), EXCEPT if self.id_ already
+ exists as a 'str', which implies we do our own ID creation (so far
+ only the case with the Day class, where it's to be a date string.
+ """