diff --git a/src/Model/BoundaryCondition/BoundaryCondition.py b/src/Model/BoundaryCondition/BoundaryCondition.py index cfb33fca723e66286ef12dfe596b36b07de1f4fd..e88a4f8f4781198568a2c4551f85967bcf24a8d4 100644 --- a/src/Model/BoundaryCondition/BoundaryCondition.py +++ b/src/Model/BoundaryCondition/BoundaryCondition.py @@ -2,15 +2,24 @@ from tools import trace, timer, old_pamhyr_date_to_timestamp +from Model.DB import SQLSubModel from Model.Except import NotImplementedMethodeError -class BoundaryCondition(object): - def __init__(self, name:str = "", +class BoundaryCondition(SQLSubModel): + _sub_classes = [] + _id_cnt = 0 + + def __init__(self, id:int = -1, name:str = "", status = None): super(BoundaryCondition, self).__init__() self._status = status + if id == -1: + self.id = type(self)._id_cnt + else: + self.id = id + self._name = name self._type = "" self._node = None @@ -18,6 +27,131 @@ class BoundaryCondition(object): self._header = [] self._types = [float, float] + type(self)._id_cnt = max(type(self)._id_cnt + 1, self.id) + + @classmethod + def _sql_create(cls, execute): + execute(""" + CREATE TABLE boundary_condition( + id INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + tab TEXT NOT NULL, + node INTEGER, + FOREIGN KEY(node) REFERENCES river_node(id) + ) + """) + + execute(""" + CREATE TABLE boundary_condition_data( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + ind INTEGER NOT NULL, + data0 TEXT NOT NULL, + data1 TEXT NOT NULL, + bc INTEGER, + FOREIGN KEY(bc) REFERENCES boundary_condition(id) + ) + """) + + return cls._create_submodel(execute) + + @classmethod + def _sql_update(cls, execute, version): + return True + + @classmethod + def _get_ctor_from_type(cls, t): + from Model.BoundaryCondition.BoundaryConditionTypes import ( + NotDefined, PonctualContribution, + TimeOverZ, TimeOverDischarge, ZOverDischarge + ) + + res = NotDefined + if t == "PC": + res = PonctualContribution + elif t == "TZ": + res = TimeOverZ + elif t == "TD": + res = TimeOverDischarge + elif t == "ZD": + res = ZOverDischarge + return res + + @classmethod + def _sql_load(cls, execute, data = None): + new = [] + tab = data["tab"] + + table = execute( + "SELECT id, name, type, node " + + "FROM boundary_condition " + + f"WHERE tab = '{tab}'" + ) + + for row in table: + t = row[2] + ctor = cls._get_ctor_from_type(t) + bc = ctor( + id = row[0], + name = row[1], + status = data['status'] + ) + bc.node = next(filter(lambda n: n.id == row[3], data["nodes"])) + + values = execute( + "SELECT ind, data0, data1 FROM boundary_condition_data " + + f"WHERE bc = '{bc.id}'" + ) + # Create dummy data list + for _ in values: + bc.add(0) + # Write data + for v in values: + ind = v[0] + data0 = bc._types[0](v[1]) + data1 = bc._types[1](v[2]) + # Replace data at pos ind + bc._data[ind] = (data0, data1) + + new.append(bc) + + return new + + def _sql_save(self, execute, data = None): + tab = data["tab"] + + execute(f"DELETE FROM boundary_condition WHERE id = {self.id}") + execute(f"DELETE FROM boundary_condition_data WHERE bc = {self.id}") + + node = -1 + if self._node is not None: + node = self._node.id + + sql = ( + "INSERT INTO " + + "boundary_condition(id, name, type, tab, node) "+ + "VALUES (" + + f"{self.id}, '{self._sql_format(self._name)}', " + + f"'{self._sql_format(self._type)}', '{tab}', {node}" + + ")" + ) + execute(sql) + + ind = 0 + for d in self._data: + data0 = self._sql_format(str(d[0])) + data1 = self._sql_format(str(d[1])) + + sql = ( + "INSERT INTO " + + "boundary_condition_data(ind, data0, data1, bc) "+ + f"VALUES ({ind}, '{data0}', {data1}, {self.id})" + ) + execute(sql) + ind += 1 + + return True + def __len__(self): return len(self._data) diff --git a/src/Model/BoundaryCondition/BoundaryConditionList.py b/src/Model/BoundaryCondition/BoundaryConditionList.py index 5f2857da71b519fcbf71b6dccfadaa5a5ff7df9b..c59f97b09f064f295a3af6d7f918654f0cc5ee3c 100644 --- a/src/Model/BoundaryCondition/BoundaryConditionList.py +++ b/src/Model/BoundaryCondition/BoundaryConditionList.py @@ -3,15 +3,21 @@ from copy import copy from tools import trace, timer +from Model.DB import SQLSubModel from Model.Except import NotImplementedMethodeError +from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition from Model.BoundaryCondition.BoundaryConditionTypes import ( NotDefined, PonctualContribution, TimeOverZ, TimeOverDischarge, ZOverDischarge ) -class BoundaryConditionList(object): +class BoundaryConditionList(SQLSubModel): + _sub_classes = [ + BoundaryCondition, + ] + def __init__(self, status = None): super(BoundaryConditionList, self).__init__() @@ -23,6 +29,40 @@ class BoundaryConditionList(object): "suspenssion" : [] } + @classmethod + def _sql_create(cls, execute): + return cls._create_submodel(execute) + + @classmethod + def _sql_update(cls, execute, version): + return True + + @classmethod + def _sql_load(cls, execute, data = None): + new = cls(status = data['status']) + + if data is None: + data = {} + + for tab in new._tabs: + data["tab"] = tab + new._tabs[tab] = BoundaryCondition._sql_load( + execute, data + ) + + return new + + def _sql_save(self, execute, data = None): + if data is None: + data = {} + + for tab in self._tabs: + data["tab"] = tab + for bc in self._tabs[tab]: + bc._sql_save(execute, data = data) + + return True + def len(self, lst): return len(self._tabs[lst]) diff --git a/src/Model/BoundaryCondition/BoundaryConditionTypes.py b/src/Model/BoundaryCondition/BoundaryConditionTypes.py index 98a488435711d56afac9219bd60172f80b2a0b41..c87e5b83d3ad1922a53056e3471a39130a5f806b 100644 --- a/src/Model/BoundaryCondition/BoundaryConditionTypes.py +++ b/src/Model/BoundaryCondition/BoundaryConditionTypes.py @@ -6,8 +6,8 @@ from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition class NotDefined(BoundaryCondition): - def __init__(self, name:str = "", status = None): - super(NotDefined, self).__init__(name=name, status=status) + def __init__(self, id:int = -1, name:str = "", status = None): + super(NotDefined, self).__init__(id=id, name=name, status=status) self._type = "ND" self._header = ["x", "y"] @@ -17,8 +17,8 @@ class NotDefined(BoundaryCondition): return 0.0 class PonctualContribution(BoundaryCondition): - def __init__(self, name:str = "", status = None): - super(PonctualContribution, self).__init__(name=name, status=status) + def __init__(self, id:int = -1, name:str = "", status = None): + super(PonctualContribution, self).__init__(id=id, name=name, status=status) self._type = "PC" self._header = ["time", "discharge"] @@ -29,8 +29,8 @@ class PonctualContribution(BoundaryCondition): return ["liquid"] class TimeOverZ(BoundaryCondition): - def __init__(self, name:str = "", status = None): - super(TimeOverZ, self).__init__(name=name, status=status) + def __init__(self, id:int = -1, name:str = "", status = None): + super(TimeOverZ, self).__init__(id=id, name=name, status=status) self._type = "TZ" self._header = ["time", "z"] @@ -41,8 +41,8 @@ class TimeOverZ(BoundaryCondition): return ["liquid"] class TimeOverDischarge(BoundaryCondition): - def __init__(self, name:str = "", status = None): - super(TimeOverDischarge, self).__init__(name=name, status=status) + def __init__(self, id:int = -1, name:str = "", status = None): + super(TimeOverDischarge, self).__init__(id=id, name=name, status=status) self._type = "TD" self._header = ["time", "discharge"] @@ -53,8 +53,8 @@ class TimeOverDischarge(BoundaryCondition): return ["liquid"] class ZOverDischarge(BoundaryCondition): - def __init__(self, name:str = "", status = None): - super(ZOverDischarge, self).__init__(name=name, status=status) + def __init__(self, id:int = -1, name:str = "", status = None): + super(ZOverDischarge, self).__init__(id=id, name=name, status=status) self._type = "ZD" self._header = ["z", "discharge"] diff --git a/src/Model/River.py b/src/Model/River.py index 09ce95c13a1b4b543afc01a6b78a53de3995a32c..5316f8922409f3356098428325248081a1e12c46 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -48,7 +48,7 @@ class RiverNode(Node, SQLSubModel): @classmethod def _sql_update(cls, execute, version): - return None + return True @classmethod def _sql_load(cls, execute, data = None): @@ -171,7 +171,7 @@ class River(Graph, SQLSubModel): _sub_classes = [ RiverNode, RiverReach, - # BoundaryConditionList, + BoundaryConditionList, # LateralContributionList, # InitialConditionsDict, # StricklersList, @@ -204,21 +204,32 @@ class River(Graph, SQLSubModel): @classmethod def _sql_load(cls, execute, data = None): + # Network new = cls(data["status"]) new._nodes = RiverNode._sql_load( execute, data ) data["nodes"] = new.nodes() + new._edges = RiverReach._sql_load( execute, data ) + data["edges"] = new.edges() + + # Boundary Condition + new._boundary_condition = BoundaryConditionList._sql_load( + execute, + data + ) return new def _sql_save(self, execute, data = None): - objs = self._nodes + self._edges + objs = (self._nodes + self._edges) + objs.append(self._boundary_condition) + self._save_submodel(execute, objs, data) return True diff --git a/src/tools.py b/src/tools.py index 17d24b4e931487962013ec05d64ba054ab8fcfd0..b54616d1e709f565b97970b6c033ed528261a12f 100644 --- a/src/tools.py +++ b/src/tools.py @@ -232,6 +232,7 @@ class SQL(object): return value def execute(self, cmd, fetch_one = True, commit = False): + print(f"[SQL] {cmd}") res = self._cur.execute(cmd) if commit: