diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py index c9f2866a..4b49a0f7 100644 --- a/src/Model/Geometry/PointXYZ.py +++ b/src/Model/Geometry/PointXYZ.py @@ -20,6 +20,7 @@ from math import dist import numpy as np from Model.Tools.PamhyrDB import SQLSubModel +from Model.Scenario import Scenario from Model.Geometry.Point import Point @@ -36,10 +37,10 @@ class PointXYZ(Point, SQLSubModel): self._z = float(z) @classmethod - def _db_create(cls, execute): - execute(""" - CREATE TABLE geometry_pointXYZ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + def _db_create(cls, execute, ext=""): + execute(f""" + CREATE TABLE geometry_pointXYZ{ext} ( + {cls.create_db_add_pamhyr_id()}, ind INTEGER NOT NULL, name TEXT, x INTEGER NOT NULL, @@ -47,8 +48,12 @@ class PointXYZ(Point, SQLSubModel): z INTEGER NOT NULL, profile INTEGER NOT NULL, sl INTEGER, - FOREIGN KEY(profile) REFERENCES geometry_profileXYZ(id), - FOREIGN KEY(sl) REFERENCES sedimentary_layer(id) + FOREIGN KEY(profile) + REFERENCES geometry_profileXYZ(pamhyr_id), + FOREIGN KEY(sl) REFERENCES sedimentary_layer(pamhyr_id), + {Scenario.create_db_add_scenario()}, + {Scenario.create_db_add_scenario_fk()}, + PRIMARY KEY(pamhyr_id, scenario) ) """) @@ -67,27 +72,50 @@ class PointXYZ(Point, SQLSubModel): """ ) + cls._db_update_to_0_1_0(execute, data) + return cls._update_submodel(execute, version, data) + + @classmethod + def _db_update_to_0_1_0(cls, execute, data): + table = "geometry_pointXYZ" + + cls.update_db_add_pamhyr_id(execute, table, data) + Scenario.update_db_add_scenario(execute, table) + + cls._db_create(execute, ext="_tmp") + + execute( + f"INSERT INTO {table}_tmp " + + "(pamhyr_id, name, comment, minor, medium, scenario) " + + "SELECT pamhyr_id, name, comment, minor, medium, 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): status = data["status"] profile = data["profile"] table = execute( - "SELECT ind, name, x, y, z, sl " + + "SELECT name, x, y, z, sl " + "FROM geometry_pointXYZ " + - f"WHERE profile = {profile.id}" + f"WHERE profile = {profile.id} " + + "ORDER BY ind ASC" ) - # Fill points list with new point for row in table: - ind = row[0] - name = row[1] - x = row[2] - y = row[3] - z = row[4] - sl = row[5] + it = iter(row) + + name = next(it) + x = next(it) + y = next(it) + z = next(it) + sl = next(it) new = cls( name=name, @@ -106,7 +134,7 @@ class PointXYZ(Point, SQLSubModel): ) ) - yield ind, new + yield new def _db_save(self, execute, data=None): profile = data["profile"] @@ -114,16 +142,15 @@ class PointXYZ(Point, SQLSubModel): sl = self._sl.id if self._sl is not None else -1 - sql = ( + execute( "INSERT INTO " + "geometry_pointXYZ(ind, name, x, y, z, profile, sl) " + "VALUES (" + f"{ind}, '{self._db_format(self._name)}', " + f"{self.x}, {self.y}, {self.z}, " + - f"{profile.id}, {sl}" + + f"{profile.pamhyr_id}, {sl}" + ")" ) - execute(sql) return True diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 833f5a49..a961edd3 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -26,6 +26,7 @@ from shapely import geometry from Model.Tools.PamhyrDB import SQLSubModel from Model.Except import ClipboardFormatError +from Model.Scenario import Scenario from Model.Geometry.Profile import Profile from Model.Geometry.PointXYZ import PointXYZ from Model.Geometry.Vector_1d import Vector1d @@ -71,10 +72,10 @@ class ProfileXYZ(Profile, SQLSubModel): ) @classmethod - def _db_create(cls, execute): - execute(""" - CREATE TABLE geometry_profileXYZ( - id INTEGER NOT NULL PRIMARY KEY, + def _db_create(cls, execute, ext=""): + execute(f""" + CREATE TABLE geometry_profileXYZ{ext} ( + {cls.create_db_add_pamhyr_id()}, ind INTEGER NOT NULL, name TEXT, reach INTEGER NOT NULL, @@ -83,8 +84,11 @@ class ProfileXYZ(Profile, SQLSubModel): code1 INTEGER NOT NULL, code2 INTEGER NOT NULL, sl INTEGER, - FOREIGN KEY(reach) REFERENCES river_reach(id), - FOREIGN KEY(sl) REFERENCES sedimentary_layer(id) + FOREIGN KEY(reach) REFERENCES river_reach(pamhyr_id), + FOREIGN KEY(sl) REFERENCES sedimentary_layer(pamhyr_id), + {Scenario.create_db_add_scenario()}, + {Scenario.create_db_add_scenario_fk()}, + PRIMARY KEY(pamhyr_id, scenario) ) """) @@ -112,8 +116,31 @@ class ProfileXYZ(Profile, SQLSubModel): """ ) + cls._db_update_to_0_1_0(execute, data) + return cls._update_submodel(execute, version, data) + @classmethod + def _db_update_to_0_1_0(cls, execute, data): + table = "stricklers" + + cls.update_db_add_pamhyr_id(execute, table, data) + Scenario.update_db_add_scenario(execute, table) + + cls._db_create(execute, ext="_tmp") + + execute( + f"INSERT INTO {table}_tmp " + + "(pamhyr_id, ind, name, reach, rk, " + + "num, code1, code2, sl, scenario) " + + "SELECT pamhyr_id, ind, name, reach, rk, " + + "num, code1, code2, sl, 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): profiles = [] @@ -121,20 +148,22 @@ class ProfileXYZ(Profile, SQLSubModel): reach = data["reach"] table = execute( - "SELECT id, ind, name, rk, num, code1, code2, sl " + + "SELECT id, name, rk, num, code1, code2, sl " + "FROM geometry_profileXYZ " + - f"WHERE reach = {reach.id}" + f"WHERE reach = {reach.id} " + + "ORDER BY ind ASC" ) for row in table: - id = row[0] - ind = row[1] - name = row[2] - rk = row[3] - num = row[5] - code1 = row[5] - code2 = row[6] - sl = row[7] + it = iter(row) + + id = next(it) + name = next(it) + rk = next(it) + num = next(it) + code1 = next(it) + code2 = next(it) + sl = next(it) new = cls( id=id, num=num, @@ -157,30 +186,32 @@ class ProfileXYZ(Profile, SQLSubModel): data["profile"] = new new._points = PointXYZ._db_load(execute, data.copy()) - yield ind, new + yield new def _db_save(self, execute, data=None): ok = True ind = data["ind"] - sl = self._sl.id if self._sl is not None else -1 + sl = self._sl.pamhyr_id if self._sl is not None else -1 - sql = ( + execute( "INSERT OR REPLACE INTO " + "geometry_profileXYZ(id, ind, name, reach, " + "rk, num, code1, code2, sl) " + "VALUES (" + - f"{self.id}, {ind}, '{self._db_format(self._name)}', " + - f"{self.reach.id}, {self.rk}, {self.num}, " + + f"{self.pamhyr_id}, {ind}, '{self._db_format(self._name)}', " + + f"{self.reach.pamhyr_id}, {self.rk}, {self.num}, " + f"{self.code1}, {self.code1}, {sl}" + ")" ) - execute(sql) points = self.points data["profile"] = self - execute(f"DELETE FROM geometry_pointXYZ WHERE profile = {self.id}") + execute( + "DELETE FROM geometry_pointXYZ " + + f"WHERE profile = {self.pamhyr_id}" + ) ind = 0 for point in points: diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py index bed6838a..7641b795 100644 --- a/src/Model/Geometry/Reach.py +++ b/src/Model/Geometry/Reach.py @@ -75,8 +75,10 @@ class Reach(SQLSubModel): def _db_save(self, execute, data=None): profiles = self.profiles - # Delete old data - execute(f"DELETE FROM geometry_profileXYZ WHERE reach = {self.id}") + execute( + "DELETE FROM geometry_profileXYZ " + + f"WHERE reach = {self.pamhyr_id}" + ) if data is None: data = {} @@ -111,18 +113,8 @@ class Reach(SQLSubModel): return self._parent.name def _get_profiles_list(self): - # Profiles list generator is type (int, Point) with the first - # element the index of the Point in list logger.debug(f"Load profiles from reach {self.name}") - return list( - map( - lambda p: p[1], - sorted( - self._profiles, - key=lambda p: p[0] - ) - ) - ) + return list(self._profiles) def __len__(self): if not isinstance(self._profiles, list): diff --git a/src/Model/Stricklers/Stricklers.py b/src/Model/Stricklers/Stricklers.py index 6ecf38f6..65f69ef2 100644 --- a/src/Model/Stricklers/Stricklers.py +++ b/src/Model/Stricklers/Stricklers.py @@ -45,7 +45,7 @@ class Stricklers(SQLSubModel): def _db_create(cls, execute, ext=""): execute(f""" CREATE TABLE stricklers{ext} ( - {cls.create_db_add_pamhyr_id()} + {cls.create_db_add_pamhyr_id()}, name TEXT, comment TEXT, minor REAL NOT NULL, @@ -120,7 +120,7 @@ class Stricklers(SQLSubModel): return stricklers def _db_save(self, execute, data=None): - sql = ( + execute( "INSERT INTO " + "stricklers(pamhyr_id, name, comment, minor, medium) " + "VALUES (" + @@ -130,7 +130,6 @@ class Stricklers(SQLSubModel): f"{float(self.minor)}, {float(self.medium)}" + ")" ) - execute(sql) return True