From cd7a81d8289b2589eb44fda424d3e630b742e6f2 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Fri, 6 Sep 2024 15:33:20 +0200 Subject: [PATCH] Reservoir: Add scenario support. --- src/Model/REPLine/REPLine.py | 2 +- src/Model/Reservoir/Reservoir.py | 161 ++++++++++++++++++++------- src/Model/Reservoir/ReservoirList.py | 12 +- 3 files changed, 132 insertions(+), 43 deletions(-) diff --git a/src/Model/REPLine/REPLine.py b/src/Model/REPLine/REPLine.py index c67165b4..4a5844b2 100644 --- a/src/Model/REPLine/REPLine.py +++ b/src/Model/REPLine/REPLine.py @@ -171,7 +171,7 @@ class REPLine(SQLSubModel): return new table = execute( - "SELECT pamhyr_id, enabled, deleted, name, line, "+ + "SELECT pamhyr_id, enabled, deleted, name, line, " + "solvers, scenario " + "FROM rep_lines " + f"WHERE scenario = {scenario.id} " + diff --git a/src/Model/Reservoir/Reservoir.py b/src/Model/Reservoir/Reservoir.py index d4e7a60b..8b44625c 100644 --- a/src/Model/Reservoir/Reservoir.py +++ b/src/Model/Reservoir/Reservoir.py @@ -27,9 +27,12 @@ logger = logging.getLogger() class Data(SQLSubModel): _sub_classes = [] - def __init__(self, id: int = -1, status=None): - super(Data, self).__init__(id) - self._status = status + def __init__(self, id: int = -1, + status=None, owner_scenario=-1): + super(Data, self).__init__( + id=id, status=status, + owner_scenario=owner_scenario + ) self._data = [] @@ -38,6 +41,7 @@ class Data(SQLSubModel): execute(f""" CREATE TABLE reservoir_data{ext}( {cls.create_db_add_pamhyr_id()}, + deleted BOOLEAN NOT NULL DEFAULT FALSE, ind INTEGER NOT NULL, elevation REAL NOT NULL, surface REAL NOT NULL, @@ -62,6 +66,13 @@ class Data(SQLSubModel): if int(release) > 5: cls._db_update_to_0_1_0(execute, data) + if major == "0" and minor == "1": + if release < 2: + execute( + "ALTER TABLE reservoir_data " + + "ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE" + ) + return cls._update_submodel(execute, version, data) @classmethod @@ -112,12 +123,20 @@ class Data(SQLSubModel): @classmethod def _db_load(cls, execute, data=None): new = [] + scenario = data["scenario"] + if scenario is None: + return new + + loaded = data['loaded_pid'] reseroire = data["reservoir"] values = execute( - "SELECT pamhyr_id, ind, elevation, surface " + + "SELECT pamhyr_id, deleted, ind, " + + "elevation, surface, scenario " + "FROM reservoir_data " + f"WHERE reservoir = {reseroire.pamhyr_id} " + + f"AND scenario = {scenario.id} " + + f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) " + "ORDER BY ind ASC" ) @@ -125,20 +144,34 @@ class Data(SQLSubModel): it = iter(v) pid = next(it) + deleted = (next(it) == 1) ind = next(it) elevation = next(it) surface = next(it) + owner_scenario = next(it) nd = cls( - id=pid, status=data['status'] + id=pid, status=data['status'], + owner_scenario=owner_scenario ) + if deleted: + f.set_as_deleted() + nd._data = [elevation, surface] + loaded.add(pid) new.append(nd) + data["scenario"] = scenario.parent + new += cls._db_load(execute, data) + data["scenario"] = scenario + return new def _db_save(self, execute, data=None): + if not self.must_be_saved(): + return True + pid = self._pamhyr_id ind = data["ind"] elevation = self._db_format(str(self[0])) @@ -146,12 +179,15 @@ class Data(SQLSubModel): reservoir = data["reservoir"] execute( - "INSERT INTO " + - "reservoir_data " + - "(pamhyr_id, ind, elevation, surface, reservoir) " + + "INSERT INTO reservoir_data " + + "(pamhyr_id, deleted, ind, " + + "elevation, surface, reservoir, scenario) " + "VALUES (" + - f"{pid}, {ind}, '{elevation}', {surface}, " + - f"{reservoir._pamhyr_id}" + + f"{pid}, " + + f"{self._db_format(self.is_deleted())}, " + + f"{ind}, '{elevation}', {surface}, " + + f"{reservoir._pamhyr_id}, " + + f"{self._status.scenario_id}" + ")" ) @@ -167,10 +203,11 @@ class Reservoir(SQLSubModel): def __init__(self, id: int = -1, name: str = "", - status=None): - super(Reservoir, self).__init__(id) - - self._status = status + status=None, owner_scenario=-1): + super(Reservoir, self).__init__( + id=id, status=status, + owner_scenario=owner_scenario + ) self._name = name self._node = None @@ -181,6 +218,7 @@ class Reservoir(SQLSubModel): execute(f""" CREATE TABLE reservoir{ext} ( {cls.create_db_add_pamhyr_id()}, + deleted BOOLEAN NOT NULL DEFAULT FALSE, name TEXT NOT NULL, node INTEGER, {Scenario.create_db_add_scenario()}, @@ -205,6 +243,13 @@ class Reservoir(SQLSubModel): cls._db_update_to_0_1_0(execute, data) + if major == "0" and minor == "1": + if release < 2: + execute( + "ALTER TABLE additional_files " + + "ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE" + ) + return cls._update_submodel(execute, version, data) @classmethod @@ -232,20 +277,35 @@ class Reservoir(SQLSubModel): @classmethod def _db_load(cls, execute, data=None): new = [] + scenario = data["scenario"] + loaded = data['loaded_pid'] + + if scenario is None: + return new table = execute( - "SELECT pamhyr_id, name, node " + - "FROM reservoir " + "SELECT pamhyr_id, deleted, name, node, scenario " + + "FROM reservoir " + + f"WHERE scenario = {scenario.id} " + + f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))})" ) for row in table: it = iter(row) id = next(it) + deleted = (next(it) == 1) name = next(it) node_id = next(it) + owner_scenario = next(it) - new_reservoir = cls(id, name, status=data["status"]) + new_reservoir = cls( + id, name, + status=data["status"], + owner_scenario=owner_scenario + ) + if deleted: + f.set_as_deleted() new_reservoir._node = None if node_id != -1: @@ -260,18 +320,28 @@ class Reservoir(SQLSubModel): execute, data=data ) + loaded.add(id) new.append(new_reservoir) + data["scenario"] = scenario.parent + new += cls._db_load(execute, data) + data["scenario"] = scenario + return new def _db_save(self, execute, data=None): + if not self.must_be_saved(): + return True + execute( "DELETE FROM reservoir " + - f"WHERE pamhyr_id = {self.pamhyr_id}" + f"WHERE pamhyr_id = {self.pamhyr_id}" + + f"AND scenario = {self._status.scenario_id}" ) execute( "DELETE FROM reservoir_data " + - f"WHERE reservoir = {self.pamhyr_id}" + f"WHERE reservoir = {self.pamhyr_id}" + + f"AND scenario = {self._status.scenario_id}" ) node_id = 'NULL' @@ -280,10 +350,13 @@ class Reservoir(SQLSubModel): sql = ( "INSERT INTO " + - "reservoir(pamhyr_id, name, node) " + + "reservoir(pamhyr_id, deleted, name, node, scenario) " + "VALUES (" + - f"{self.pamhyr_id}, '{self._db_format(self._name)}', " + - f"{node_id}" + + f"{self.pamhyr_id}, " + + f"{self._db_format(self.is_deleted())}, " + + f"'{self._db_format(self._name)}', " + + f"{node_id}, " + + f"{self._status.scenario_id}" + ")" ) execute(sql) @@ -313,7 +386,7 @@ class Reservoir(SQLSubModel): @name.setter def name(self, name): self._name = name - self._status.modified() + self.modified() @property def node(self): @@ -322,7 +395,7 @@ class Reservoir(SQLSubModel): @node.setter def node(self, node): self._node = node - self._status.modified() + self.modified() def has_node(self): return self._node is not None @@ -357,40 +430,50 @@ class Reservoir(SQLSubModel): def add(self, index: int): value = (self._default_elevation, self._default_surface) self._data.insert(index, value) - self._status.modified() + self.modified() return value def insert(self, index: int, value): self._data.insert(index, value) - self._status.modified() + self.modified() - def delete_i(self, indexes): + def hard_delete_i(self, indexes): self._data = list( map( lambda e: e[1], filter( lambda e: e[0] not in indexes, - enumerate(self.data) + enumerate(self._data) ) ) ) - self._status.modified() + self.modified() - def delete(self, els): - self._data = list( - filter( - lambda e: e not in els, - self.data + def delete_i(self, indexes): + list( + map( + lambda e: e[1].set_as_deleted(), + filter( + lambda e: e[0] in indexes, + enumerate(self.lst) + ) ) ) - self._status.modified() + self.modified() + + def delete(self, els): + for el in els: + el.set_as_deleted() + + self.modified() def sort(self, _reverse=False, key=None): if key is None: self._data.sort(reverse=_reverse, key=lambda d: d[0]) else: self._data.sort(reverse=_reverse, key=key) - self._status.modified() + + self.modified() def get_i(self, index): return self.data[index] @@ -405,7 +488,7 @@ class Reservoir(SQLSubModel): v = list(self._data[index]) v[column] = value self._data[index] = tuple(v) - self._status.modified() + self.modified() def set_i_elevation(self, index: int, value): self._set_i_c_v(index, 0, value) @@ -418,11 +501,11 @@ class Reservoir(SQLSubModel): next = index - 1 d = self._data d[index], d[next] = d[next], d[index] - self._status.modified() + self.modified() def move_down(self, index): if index >= 0: prev = index + 1 d = self._data d[index], d[prev] = d[prev], d[index] - self._status.modified() + self.modified() diff --git a/src/Model/Reservoir/ReservoirList.py b/src/Model/Reservoir/ReservoirList.py index a341e239..a090d217 100644 --- a/src/Model/Reservoir/ReservoirList.py +++ b/src/Model/Reservoir/ReservoirList.py @@ -19,7 +19,7 @@ from copy import copy from tools import trace, timer -from Model.Tools.PamhyrList import PamhyrModelList +from Model.Tools.PamhyrListExt import PamhyrModelList from Model.Reservoir.Reservoir import Reservoir @@ -39,8 +39,14 @@ class ReservoirList(PamhyrModelList): return new def _db_save(self, execute, data=None): - execute("DELETE FROM reservoir") - execute("DELETE FROM reservoir_data") + execute( + "DELETE FROM reservoir " + + f"WHERE scenario = {self._status.scenario_id}" + ) + execute( + "DELETE FROM reservoir_data " + + f"WHERE scenario = {self._status.scenario_id}" + ) if data is None: data = {}