X-Git-Url: https://plomlompom.com/repos/berlin_corona.txt?a=blobdiff_plain;ds=sidebyside;f=plomtask%2Fprocesses.py;h=089a7105fddcd9228dbaebcfd3c6313e3ff57f6b;hb=c39bd250d747d2dd0bebee8c2f99f2c0fac6926c;hp=e67b13414e26d40a87e77545ce57d238bc050028;hpb=ee18435127ad396c24dbee2c7efcdbe6810d5a91;p=plomtask diff --git a/plomtask/processes.py b/plomtask/processes.py index e67b134..089a710 100644 --- a/plomtask/processes.py +++ b/plomtask/processes.py @@ -4,9 +4,10 @@ from dataclasses import dataclass from typing import Set, Any from sqlite3 import Row from plomtask.db import DatabaseConnection, BaseModel -from plomtask.misc import VersionedAttribute +from plomtask.versioned_attributes import VersionedAttribute from plomtask.conditions import Condition, ConditionsRelations -from plomtask.exceptions import NotFoundException, BadFormatException +from plomtask.exceptions import (NotFoundException, BadFormatException, + HandledException) @dataclass @@ -21,19 +22,24 @@ class ProcessStepsNode: class Process(BaseModel[int], ConditionsRelations): """Template for, and metadata for, Todos, and their arrangements.""" - table_name = 'processes' - # pylint: disable=too-many-instance-attributes - - def __init__(self, id_: int | None) -> None: - super().__init__(id_) + table_name = 'processes' + to_save = ['calendarize'] + to_save_versioned = ['title', 'description', 'effort'] + to_save_relations = [('process_conditions', 'process', 'conditions', 0), + ('process_blockers', 'process', 'blockers', 0), + ('process_enables', 'process', 'enables', 0), + ('process_disables', 'process', 'disables', 0)] + to_search = ['title.newest', 'description.newest'] + + def __init__(self, id_: int | None, calendarize: bool = False) -> None: + BaseModel.__init__(self, id_) + ConditionsRelations.__init__(self) self.title = VersionedAttribute(self, 'process_titles', 'UNNAMED') self.description = VersionedAttribute(self, 'process_descriptions', '') self.effort = VersionedAttribute(self, 'process_efforts', 1.0) self.explicit_steps: list[ProcessStep] = [] - self.conditions: list[Condition] = [] - self.enables: list[Condition] = [] - self.disables: list[Condition] = [] + self.calendarize = calendarize @classmethod def from_table_row(cls, db_conn: DatabaseConnection, @@ -49,7 +55,7 @@ class Process(BaseModel[int], ConditionsRelations): process.id_): step = ProcessStep.from_table_row(db_conn, row_) process.explicit_steps += [step] # pylint: disable=no-member - for name in ('conditions', 'enables', 'disables'): + for name in ('conditions', 'blockers', 'enables', 'disables'): table = f'process_{name}' assert isinstance(process.id_, int) for c_id in db_conn.column_where(table, 'condition', @@ -87,6 +93,13 @@ class Process(BaseModel[int], ConditionsRelations): for child in explicit_children: assert isinstance(child.id_, int) node.steps[child.id_] = make_node(child) + # ensure that one (!) explicit step of process replaces + # one (!) implicit step of same process + for i in [i for i, s in node.steps.items() + if not s.is_explicit + and s.process.id_ == child.step_process_id]: + del node.steps[i] + break node.seen = node_id in seen_step_ids seen_step_ids.add(node_id) for id_, step in node.steps.items(): @@ -118,7 +131,6 @@ class Process(BaseModel[int], ConditionsRelations): just deleted under its feet), or if the parent step would not be owned by the current Process. """ - def walk_steps(node: ProcessStep) -> None: if node.step_process_id == self.id_: raise BadFormatException('bad step selection causes recursion') @@ -154,27 +166,22 @@ class Process(BaseModel[int], ConditionsRelations): def save(self, db_conn: DatabaseConnection) -> None: """Add (or re-write) self and connected items to DB.""" - self.save_core(db_conn) + super().save(db_conn) assert isinstance(self.id_, int) - self.title.save(db_conn) - self.description.save(db_conn) - self.effort.save(db_conn) - db_conn.rewrite_relations('process_conditions', 'process', self.id_, - [[c.id_] for c in self.conditions]) - db_conn.rewrite_relations('process_enables', 'process', self.id_, - [[c.id_] for c in self.enables]) - db_conn.rewrite_relations('process_disables', 'process', self.id_, - [[c.id_] for c in self.disables]) db_conn.delete_where('process_steps', 'owner', self.id_) for step in self.explicit_steps: step.save(db_conn) def remove(self, db_conn: DatabaseConnection) -> None: - """Remove from DB, with dependencies.""" + """Remove from DB, with dependencies. + + Guard against removal of Processes in use. + """ assert isinstance(self.id_, int) - db_conn.delete_where('process_conditions', 'process', self.id_) - db_conn.delete_where('process_enables', 'process', self.id_) - db_conn.delete_where('process_disables', 'process', self.id_) + for _ in db_conn.row_where('process_steps', 'step_process', self.id_): + raise HandledException('cannot remove Process in use') + for _ in db_conn.row_where('todos', 'process', self.id_): + raise HandledException('cannot remove Process in use') for step in self.explicit_steps: step.remove(db_conn) super().remove(db_conn) @@ -192,10 +199,6 @@ class ProcessStep(BaseModel[int]): self.step_process_id = step_process_id self.parent_step_id = parent_step_id - def save(self, db_conn: DatabaseConnection) -> None: - """Default to simply calling self.save_core for simple cases.""" - self.save_core(db_conn) - def remove(self, db_conn: DatabaseConnection) -> None: """Remove from DB, and owner's .explicit_steps.""" owner = Process.by_id(db_conn, self.owner_id)