From: Christian Heller Date: Sun, 28 Apr 2024 20:00:24 +0000 (+0200) Subject: Enable deletion of Processes. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bprefix%7D%7D/tasks?a=commitdiff_plain;h=ee18435127ad396c24dbee2c7efcdbe6810d5a91;p=plomtask Enable deletion of Processes. --- diff --git a/plomtask/conditions.py b/plomtask/conditions.py index 6696125..a452600 100644 --- a/plomtask/conditions.py +++ b/plomtask/conditions.py @@ -7,7 +7,7 @@ from plomtask.misc import VersionedAttribute class Condition(BaseModel[int]): - """Non Process-dependency for ProcessSteps and Todos.""" + """Non-Process dependency for ProcessSteps and Todos.""" table_name = 'conditions' to_save = ['is_active'] diff --git a/plomtask/db.py b/plomtask/db.py index ebd8c6c..deeb748 100644 --- a/plomtask/db.py +++ b/plomtask/db.py @@ -102,7 +102,8 @@ class DatabaseConnection: return [row[0] for row in self.exec(f'SELECT {column} FROM {table_name}')] - def delete_where(self, table_name: str, key: str, target: int) -> None: + def delete_where(self, table_name: str, key: str, + target: int | str) -> None: """Delete from table where key == target.""" self.exec(f'DELETE FROM {table_name} WHERE {key} = ?', (target,)) @@ -234,3 +235,9 @@ class BaseModel(Generic[BaseModelId]): if update_with_lastrowid: self.id_ = cursor.lastrowid # type: ignore[assignment] self.cache() + + def remove(self, db_conn: DatabaseConnection) -> None: + """Remove from DB.""" + assert isinstance(self.id_, int | str) + self.uncache() + db_conn.delete_where(self.table_name, 'id', self.id_) diff --git a/plomtask/http.py b/plomtask/http.py index c848600..b4c2b08 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -236,6 +236,10 @@ class TaskHandler(BaseHTTPRequestHandler): def do_POST_process(self) -> None: """Update or insert Process of ?id= and fields defined in postvars.""" id_ = self.params.get_int_or_none('id') + for _ in self.form_data.get_all_str('delete'): + process = Process.by_id(self.conn, id_) + process.remove(self.conn) + return process = Process.by_id(self.conn, id_, create=True) process.title.set(self.form_data.get_str('title')) process.description.set(self.form_data.get_str('description')) diff --git a/plomtask/processes.py b/plomtask/processes.py index c0b13b5..e67b134 100644 --- a/plomtask/processes.py +++ b/plomtask/processes.py @@ -169,6 +169,16 @@ class Process(BaseModel[int], ConditionsRelations): for step in self.explicit_steps: step.save(db_conn) + def remove(self, db_conn: DatabaseConnection) -> None: + """Remove from DB, with dependencies.""" + 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 step in self.explicit_steps: + step.remove(db_conn) + super().remove(db_conn) + class ProcessStep(BaseModel[int]): """Sub-unit of Processes.""" @@ -185,3 +195,9 @@ class ProcessStep(BaseModel[int]): 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) + owner.explicit_steps.remove(self) + super().remove(db_conn) diff --git a/templates/process.html b/templates/process.html index ec06d3a..8c219c6 100644 --- a/templates/process.html +++ b/templates/process.html @@ -33,10 +33,22 @@ add step: -title: -description: -default effort: -

conditions

+ + + + + + + + + + + + + + + +
title
default effort
description
conditions {% for condition in process.conditions %} @@ -50,12 +62,11 @@ default effort: add condition: - -{% for condition_candidate in condition_candidates %} - -{% endfor %} - -

enables

+ + + + +
enables {% for condition in process.enables %} @@ -69,7 +80,11 @@ add condition: add enables: -

disables

+ + + + +
disables {% for condition in process.disables %} @@ -83,20 +98,32 @@ add enables: -

steps

+ + + + + + +
steps {% for step_id, step_node in steps.items() %} {{ step_with_steps(step_id, step_node, 0) }} {% endfor %}
add step: +
+ +{% for condition_candidate in condition_candidates %} + +{% endfor %} + {% for candidate in step_candidates %} {% endfor %} -

save

- + +

step of

    diff --git a/tests/processes.py b/tests/processes.py index c718677..6695f78 100644 --- a/tests/processes.py +++ b/tests/processes.py @@ -157,6 +157,22 @@ class TestsWithDB(TestCaseWithDB): p_loaded = Process.by_id(self.db_conn, self.proc1.id_) self.assertEqual(self.proc1.title.history, p_loaded.title.history) + def test_Process_removal(self) -> None: + """Test removal of Processes.""" + assert isinstance(self.proc3.id_, int) + self.proc1.remove(self.db_conn) + self.assertEqual({self.proc2.id_, self.proc3.id_}, + set(p.id_ for p in Process.all(self.db_conn))) + self.proc2.set_steps(self.db_conn, [(None, self.proc3.id_, None)]) + self.proc2.explicit_steps[0].remove(self.db_conn) + retrieved = Process.by_id(self.db_conn, self.proc2.id_) + self.assertEqual(retrieved.explicit_steps, []) + self.proc2.set_steps(self.db_conn, [(None, self.proc3.id_, None)]) + step = retrieved.explicit_steps[0] + self.proc2.remove(self.db_conn) + with self.assertRaises(NotFoundException): + ProcessStep.by_id(self.db_conn, step.id_) + class TestsWithServer(TestCaseWithServer): """Module tests against our HTTP server/handler (and database)."""