From d78d9167a0561fa167da8f628de9ea2901aedcf3 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Mon, 22 Jul 2024 15:31:32 +0200 Subject: [PATCH] BC: Prepare db version 0.1.0, add pamhyr_id and scenario. --- .../BoundaryCondition/BoundaryCondition.py | 221 +++++++++++++----- 1 file changed, 163 insertions(+), 58 deletions(-) diff --git a/src/Model/BoundaryCondition/BoundaryCondition.py b/src/Model/BoundaryCondition/BoundaryCondition.py index eddc52b1..986a9219 100644 --- a/src/Model/BoundaryCondition/BoundaryCondition.py +++ b/src/Model/BoundaryCondition/BoundaryCondition.py @@ -27,24 +27,128 @@ from tools import ( from Model.Tools.PamhyrDB import SQLSubModel from Model.Except import NotImplementedMethodeError +from Model.Scenario import Scenario logger = logging.getLogger() -class BoundaryCondition(SQLSubModel): +class Data(SQLSubMode): _sub_classes = [] - _id_cnt = 0 - def __init__(self, id: int = -1, name: str = "", + def __init__(self, id: int = -1, + types=[float, float], status=None): - super(BoundaryCondition, self).__init__() - + super(Data, self).__init__(id) self._status = status - if id == -1: - self.id = BoundaryCondition._id_cnt - else: - self.id = id + self._types = types + self._data = [] + + @classmethod + def _db_create(cls, execute, ext=""): + execute(f""" + CREATE TABLE boundary_condition_data{ext}( + {cls.create_db_add_pamhyr_id()}, + ind INTEGER NOT NULL, + data0 TEXT NOT NULL, + data1 TEXT NOT NULL, + bc INTEGER, + {Scenario.create_db_add_scenario()}, + {Scenario.create_db_add_scenario_fk()}, + FOREIGN KEY(bc) REFERENCES boundary_condition(pamhyr_id), + PRIMARY KEY(pamhyr_id, scenario) + ) + """) + + return cls._create_submodel(execute) + + @classmethod + def _db_update(cls, execute, version): + major, minor, release = version.strip().split(".") + + if major == "0" and int(minor) < 1: + cls._db_update_to_0_1_0(execute) + + return True + + @classmethod + def _db_update_to_0_1_0(cls, execute): + table = "boundary_condition_data" + + cls.update_db_add_pamhyr_id(execute, table) + Scenario.update_db_add_scenario(execute, table) + + cls._db_create(execute, ext="_tmp") + execute( + f"INSERT INTO {table} " + + "(pamhyr_id, ind, data0, data1, bc, scenario) " + + "SELECT pamhyr_id, ind, data0, data1, bc, scenario " + + f"FROM {table}" + ) + + execute(f"DROP TABLE {table}") + execute(f"ALTER TABLE {table}_tmp RENAME TO {table}") + + @classmethod + def _db_load(cls, execute, data=None): + new = [] + bc = data["bc"] + + values = execute( + "SELECT pamhyr_id, ind, data0, data1 " + + "FROM boundary_condition_data " + + f"WHERE bc = {bc._pamhyr_id} " + + "ORDER BY ind ASC" + ) + + for v in values: + it = iter(v) + + pid = next(it) + ind = next(it) + data0 = bc._types[0](next(it)) + data1 = bc._types[1](next(it)) + + nd = cls( + id=pid, + types=bc._types, + status=data['status'] + ) + nd._data = [data0, data1] + + new.append((ind, nd)) + + return new + + def _db_save(self, execute, data=None): + pid = self._pamhyr_id + ind = data["ind"] + data0 = self._db_format(str(self[0])) + data1 = self._db_format(str(self[1])) + bc = data["bc"] + + sql = ( + "INSERT INTO " + + "boundary_condition_data(pamhyr_id, ind, data0, data1, bc) " + + f"VALUES ({pid}, {ind}, '{data0}', {data1}, {bc._pamhyr_id})" + ) + execute(sql) + + def __getitem__(self, key): + return self._types[key](self._data[key]) + + def __setitem__(self, key, value): + self._data[key] = self._types[key](value) + + +class BoundaryCondition(SQLSubModel): + _sub_classes = [Data] + + def __init__(self, id: int = -1, + name: str = "", status=None): + super(BoundaryCondition, self).__init__(id) + + self._status = status self._name = name self._type = "" @@ -53,37 +157,49 @@ class BoundaryCondition(SQLSubModel): self._header = [] self._types = [float, float] - BoundaryCondition._id_cnt = max(BoundaryCondition._id_cnt + 1, self.id) - @classmethod - def _db_create(cls, execute): - execute(""" - CREATE TABLE boundary_condition( - id INTEGER NOT NULL PRIMARY KEY, + def _db_create(cls, execute, ext=""): + execute(f""" + CREATE TABLE boundary_condition{ext}( + {cls.create_db_add_pamhyr_id()}, 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) + {Scenario.create_db_add_scenario()}, + {Scenario.create_db_add_scenario_fk()}, + FOREIGN KEY(node) REFERENCES river_node(pamhyr_id), + PRIMARY KEY(pamhyr_id, scenario) ) """) return cls._create_submodel(execute) - @classmethod def _db_update(cls, execute, version): - return True + major, minor, release = version.strip().split(".") + + if major == "0" and int(minor) < 1: + cls._db_update_to_0_1_0(execute) + + return cls._update_submodel(execute, version) + + @classmethod + def _db_update_to_0_1_0(cls, execute): + table = "boundary_condition" + + cls.update_db_add_pamhyr_id(execute, table) + Scenario.update_db_add_scenario(execute, table) + + cls._db_create(execute, ext="_tmp") + execute( + f"INSERT INTO {table} " + + "(pamhyr_id, name, type, tab, node, scenario) " + + "SELECT pamhyr_id, name, type, tab, node, scenario " + + f"FROM {table}" + ) + + execute(f"DROP TABLE {table}") + execute(f"ALTER TABLE {table}_tmp RENAME TO {table}") @classmethod def _get_ctor_from_type(cls, t): @@ -112,7 +228,7 @@ class BoundaryCondition(SQLSubModel): tab = data["tab"] table = execute( - "SELECT id, name, type, node " + + "SELECT pamhyr_id, name, type, node " + "FROM boundary_condition " + f"WHERE tab = '{tab}'" ) @@ -130,30 +246,22 @@ class BoundaryCondition(SQLSubModel): if row[3] != -1: 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) + data["bc"] = bc + bc._data = Data._db_load(execute, data=data) return new def _db_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}") + execute( + "DELETE FROM boundary_condition " + + f"WHERE pamhyr_id = {self._pamhyr_id}" + ) + execute( + "DELETE FROM boundary_condition_data " + + f"WHERE bc = {self._pamhyr_id}" + ) node = -1 if self._node is not None: @@ -161,25 +269,22 @@ class BoundaryCondition(SQLSubModel): sql = ( "INSERT INTO " + - "boundary_condition(id, name, type, tab, node) " + + "boundary_condition(pamhyr_id, name, type, tab, node) " + "VALUES (" + - f"{self.id}, '{self._db_format(self._name)}', " + + f"{self._pamhyr_id}, '{self._db_format(self._name)}', " + f"'{self._db_format(self._type)}', '{tab}', {node}" + ")" ) execute(sql) + data["bc"] = self + ind = 0 for d in self._data: - data0 = self._db_format(str(d[0])) - data1 = self._db_format(str(d[1])) + data["ind"] = ind + + d._db_save(execute, data) - sql = ( - "INSERT INTO " + - "boundary_condition_data(ind, data0, data1, bc) " + - f"VALUES ({ind}, '{data0}', {data1}, {self.id})" - ) - execute(sql) ind += 1 return True