SL: Add scenario support.

scenarios
Pierre-Antoine Rouby 2024-09-18 11:13:42 +02:00
parent c01effbf4c
commit 7857a2ea61
5 changed files with 167 additions and 65 deletions

View File

@ -341,7 +341,7 @@ class BoundaryCondition(SQLSubModel):
owner_scenario=owner_scenario owner_scenario=owner_scenario
) )
if deleted: if deleted:
f.set_as_deleted() bc.set_as_deleted()
bc.node = None bc.node = None
if node != -1: if node != -1:
@ -549,6 +549,12 @@ class BoundaryCondition(SQLSubModel):
self.modified() self.modified()
def undelete(self, els):
for el in els:
el.set_as_not_deleted()
self.modified()
def sort(self, _reverse=False, key=None): def sort(self, _reverse=False, key=None):
if key is None: if key is None:
self._data.sort(reverse=_reverse) self._data.sort(reverse=_reverse)

View File

@ -33,10 +33,12 @@ class Layer(SQLSubModel):
type="", type="",
height=0.0, d50=0.0, sigma=0.0, height=0.0, d50=0.0, sigma=0.0,
critical_constraint=0.0, critical_constraint=0.0,
sl=None, status=None): sl=None, status=None,
super(Layer, self).__init__(id) owner_scenario=-1):
super(Layer, self).__init__(
self._status = status id=id, status=status,
owner_scenario=owner_scenario
)
self._name = name self._name = name
self._type = type self._type = type
@ -102,6 +104,7 @@ class Layer(SQLSubModel):
execute(f""" execute(f"""
CREATE TABLE sedimentary_layer_layer{ext} ( CREATE TABLE sedimentary_layer_layer{ext} (
{cls.create_db_add_pamhyr_id()}, {cls.create_db_add_pamhyr_id()},
deleted BOOLEAN NOT NULL DEFAULT FALSE,
ind INTEGER NOT NULL, ind INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
type TEXT NOT NULL, type TEXT NOT NULL,
@ -129,6 +132,13 @@ class Layer(SQLSubModel):
else: else:
cls._db_update_to_0_1_0(execute, data) cls._db_update_to_0_1_0(execute, data)
if major == "0" and minor == "1":
if int(release) < 2:
execute(
"ALTER TABLE sedimentary_layer_layer " +
"ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE"
)
return cls._update_submodel(execute, version, data) return cls._update_submodel(execute, version, data)
@classmethod @classmethod
@ -176,12 +186,19 @@ class Layer(SQLSubModel):
def _db_load(cls, execute, data=None): def _db_load(cls, execute, data=None):
new = [] new = []
sl = data["sl"] sl = data["sl"]
scenario = data["scenario"]
loaded = data['loaded_pid']
if scenario is None:
return new
table = execute( table = execute(
"SELECT pamhyr_id, name, type, height, " + "SELECT pamhyr_id, deleted, name, type, height, " +
"d50, sigma, critical_constraint " + "d50, sigma, critical_constraint, scenario " +
"FROM sedimentary_layer_layer " + "FROM sedimentary_layer_layer " +
f"WHERE sl = {sl} " + f"WHERE sl = {sl} " +
f"AND scenario = {scenario.id} " +
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) " +
"ORDER BY ind ASC" "ORDER BY ind ASC"
) )
@ -189,38 +206,55 @@ class Layer(SQLSubModel):
it = iter(row) it = iter(row)
pid = next(it) pid = next(it)
deleted = (next(it) == 1)
name = next(it) name = next(it)
type = next(it) type = next(it)
height = next(it) height = next(it)
d50 = next(it) d50 = next(it)
sigma = next(it) sigma = next(it)
critical_constraint = next(it) critical_constraint = next(it)
owner_scenario = next(it)
layer = cls( layer = cls(
id=pid, name=name, id=pid, name=name,
type=type, height=height, type=type, height=height,
d50=d50, sigma=sigma, d50=d50, sigma=sigma,
critical_constraint=critical_constraint, critical_constraint=critical_constraint,
sl=sl, status=data['status'] sl=sl, status=data['status'],
owner_scenario=owner_scenario
) )
if deleted:
layer.set_as_deleted()
loaded.add(pid)
new.append(layer) new.append(layer)
data["scenario"] = scenario.parent
new += cls._db_load(execute, data)
data["scenario"] = scenario
return new return new
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
if not self.must_be_saved():
return True
ind = data["ind"] ind = data["ind"]
sl = data["sl"] sl = data["sl"]
execute( execute(
"INSERT INTO " + "INSERT INTO " +
"sedimentary_layer_layer(pamhyr_id, ind, name, type, height, " + "sedimentary_layer_layer(" +
"d50, sigma, critical_constraint, sl) " + "pamhyr_id, deleted, ind, name, type, height, " +
"d50, sigma, critical_constraint, sl, scenario" +
") " +
"VALUES (" + "VALUES (" +
f"{self.pamhyr_id}, {ind}, '{self._db_format(self._name)}', " + f"{self.pamhyr_id}, {self._db_format(self.is_deleted())}, " +
f"{ind}, '{self._db_format(self._name)}', " +
f"'{self._db_format(self._type)}', {self._height}, " + f"'{self._db_format(self._type)}', {self._height}, " +
f"{self._d50}, {self._sigma}, {self._critical_constraint}, " + f"{self._d50}, {self._sigma}, {self._critical_constraint}, " +
f"{sl.pamhyr_id}" + f"{sl.pamhyr_id}, " +
f"{self._status.scenario_id}" +
")" ")"
) )
@ -232,10 +266,12 @@ class SedimentLayer(SQLSubModel):
def __init__(self, id: int = -1, def __init__(self, id: int = -1,
name: str = "", comment: str = "", name: str = "", comment: str = "",
status=None): status=None, owner_scenario=-1):
super(SedimentLayer, self).__init__(id) super(SedimentLayer, self).__init__(
id=id, status=status,
owner_scenario=owner_scenario
)
self._status = status
self._name = name self._name = name
self._comment = comment self._comment = comment
self._layers = [] self._layers = []
@ -249,15 +285,28 @@ class SedimentLayer(SQLSubModel):
return s return s
def __len__(self): def __len__(self):
return len(self._layers) return len(
list(
filter(
lambda el: not el.is_deleted(),
self._layers
)
)
)
@property @property
def layers(self): def layers(self):
return self._layers.copy() return list(
filter(
lambda el: not el.is_deleted(),
self._layers
)
)
def height(self): def height(self):
return list( return list(
map(lambda layer: layer.height, self._layers) map(lambda layer: layer.height,
self.layers)
) )
@property @property
@ -273,7 +322,10 @@ class SedimentLayer(SQLSubModel):
def names(self): def names(self):
return list( return list(
map(lambda layer: layer.name, self._layers) map(
lambda layer: layer.name,
self.layers
)
) )
@property @property
@ -289,6 +341,7 @@ class SedimentLayer(SQLSubModel):
execute(f""" execute(f"""
CREATE TABLE sedimentary_layer{ext} ( CREATE TABLE sedimentary_layer{ext} (
{cls.create_db_add_pamhyr_id()}, {cls.create_db_add_pamhyr_id()},
deleted BOOLEAN NOT NULL DEFAULT FALSE,
name TEXT NOT NULL, name TEXT NOT NULL,
comment TEXT NOT NULL, comment TEXT NOT NULL,
{Scenario.create_db_add_scenario()}, {Scenario.create_db_add_scenario()},
@ -312,6 +365,13 @@ class SedimentLayer(SQLSubModel):
else: else:
cls._db_update_to_0_1_0(execute, data) cls._db_update_to_0_1_0(execute, data)
if major == "0" and minor == "1":
if int(release) < 2:
execute(
"ALTER TABLE sedimentary_layer " +
"ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE"
)
return cls._update_submodel(execute, version, data) return cls._update_submodel(execute, version, data)
@classmethod @classmethod
@ -336,36 +396,64 @@ class SedimentLayer(SQLSubModel):
@classmethod @classmethod
def _db_load(cls, execute, data=None): def _db_load(cls, execute, data=None):
new = [] new = []
scenario = data["scenario"]
loaded = data['loaded_pid']
if scenario is None:
return new
table = execute( table = execute(
"SELECT pamhyr_id, name, comment " + "SELECT pamhyr_id, deleted, name, comment, scenario " +
"FROM sedimentary_layer " "FROM sedimentary_layer " +
f"WHERE scenario = {scenario.id} " +
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) "
) )
for row in table: for row in table:
it = iter(row)
pid = next(it)
deleted = (next(it) == 1)
name = next(it)
comment = next(it)
owner_scenario = next(it)
sl = cls( sl = cls(
id=row[0], id=pid,
name=row[1], name=name,
comment=row[2], comment=comment,
status=data['status'] status=data['status'],
owner_scenario=owner_scenario
) )
if deleted:
sl.set_as_deleted()
data["sl"] = sl.id data["sl"] = sl.id
sl._layers = Layer._db_load(execute, data) sl._layers = Layer._db_load(execute, data)
loaded.add(pid)
new.append(sl) new.append(sl)
data["scenario"] = scenario.parent
new += cls._db_load(execute, data)
data["scenario"] = scenario
return new return new
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
if data is None: if not self.must_be_saved():
data = {} return True
execute( execute(
"INSERT INTO sedimentary_layer (pamhyr_id, name, comment) " + "INSERT INTO sedimentary_layer (" +
f"VALUES ({self.pamhyr_id}, " + "pamhyr_id, deleted, name, comment, scenario" +
") " +
"VALUES (" +
f"{self._pamhyr_id}, {self._db_format(self.is_deleted())}, " +
f"'{self._db_format(self._name)}', " + f"'{self._db_format(self._name)}', " +
f"'{self._db_format(self._comment)}')" f"'{self._db_format(self._comment)}', " +
f"{self._status.scenario_id}" +
")"
) )
data["sl"] = self data["sl"] = self
@ -379,38 +467,45 @@ class SedimentLayer(SQLSubModel):
return True return True
def get(self, index): def get(self, index):
return self._layers[index] return self.layers[index]
def set(self, index, new): # def set(self, index, new):
self._layers[index] = new # self._layers[index] = new
self._status.modified() # self.modified()
def insert(self, index, new): def insert(self, index, new):
self._layers.insert(index, new) self._layers.insert(index, new)
self._status.modified() self.modified()
def new(self, index): def new(self, index):
n = Layer(sl=self, status=self._status) n = Layer(sl=self, status=self._status)
self.insert(index, n) self.insert(index, n)
self._status.modified() self.modified()
return n return n
def undelete(self, els):
for el in els:
el.set_as_not_deleted()
self.modified()
def delete(self, els): def delete(self, els):
for el in els: for el in els:
self._layers.remove(el) el.set_as_deleted()
self._status.modified()
self.modified()
def delete_i(self, indexes): def delete_i(self, indexes):
els = list( list(
map( map(
lambda x: x[1], lambda e: e[1].set_as_deleted(),
filter( filter(
lambda x: x[0] in indexes, lambda e: e[0] in indexes,
enumerate(self._layers) enumerate(self._layers)
) )
) )
) )
self.delete(els) self.modified()
def move_up(self, index): def move_up(self, index):
if index >= 0: if index >= 0:
@ -419,7 +514,7 @@ class SedimentLayer(SQLSubModel):
lst = self._layers lst = self._layers
lst[index], lst[next] = lst[next], lst[index] lst[index], lst[next] = lst[next], lst[index]
self._status.modified() self.modified()
def move_down(self, index): def move_down(self, index):
if index + 1 < len(self._layers): if index + 1 < len(self._layers):
@ -428,7 +523,7 @@ class SedimentLayer(SQLSubModel):
lst = self._layers lst = self._layers
lst[index], lst[prev] = lst[prev], lst[index] lst[index], lst[prev] = lst[prev], lst[index]
self._status.modified() self.modified()
def compute_height_from_bottom(self, bottom_elevation: list): def compute_height_from_bottom(self, bottom_elevation: list):
sl_height = self.height() sl_height = self.height()

View File

@ -19,7 +19,7 @@
from tools import trace, timer from tools import trace, timer
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
from Model.Tools.PamhyrList import PamhyrModelList from Model.Tools.PamhyrListExt import PamhyrModelList
from Model.SedimentLayer.SedimentLayer import SedimentLayer from Model.SedimentLayer.SedimentLayer import SedimentLayer
@ -35,11 +35,16 @@ class SedimentLayerList(PamhyrModelList):
return new return new
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
ok = True execute(
"DELETE FROM sedimentary_layer" +
f"WHERE scenario = {self._status.scenario_id}"
)
execute(
"DELETE FROM sedimentary_layer_layer" +
f"WHERE scenario = {self._status.scenario_id}"
)
# Delete previous data ok = True
execute("DELETE FROM sedimentary_layer")
execute("DELETE FROM sedimentary_layer_layer")
for sl in self._lst: for sl in self._lst:
ok &= sl._db_save(execute, data) ok &= sl._db_save(execute, data)

View File

@ -132,13 +132,13 @@ class AddCommand(QUndoCommand):
self._new = None self._new = None
def undo(self): def undo(self):
self._sediment_layers.delete_i([self._index]) self._sediment_layers.delete([self._new])
def redo(self): def redo(self):
if self._new is None: if self._new is None:
self._new = self._sediment_layers.new(self._index) self._new = self._sediment_layers.new(self._index)
else: else:
self._sediment_layers.insert(self._index, self._new) self._sediment_layers.undelete([self._new])
class DelCommand(QUndoCommand): class DelCommand(QUndoCommand):
@ -148,17 +148,15 @@ class DelCommand(QUndoCommand):
self._sediment_layers = sediment_layers self._sediment_layers = sediment_layers
self._rows = rows self._rows = rows
self._sl_pos = [] self._sl = []
for row in rows: for row in rows:
self._sl_pos.append((row, self._sediment_layers.get(row))) self._sl.append(self._sediment_layers.get(row))
self._sl_pos.sort()
def undo(self): def undo(self):
for row, el in self._sl_pos: self._sediment_layers.undelete(self._sl)
self._sediment_layers.insert(row, el)
def redo(self): def redo(self):
self._sediment_layers.delete_i(self._rows) self._sediment_layers.delete(self._sl)
class MoveCommand(QUndoCommand): class MoveCommand(QUndoCommand):

View File

@ -68,13 +68,13 @@ class AddCommand(QUndoCommand):
self._new = None self._new = None
def undo(self): def undo(self):
self._sediment_layers_list.delete_i([self._index]) self._sediment_layers_list.delete([self._new])
def redo(self): def redo(self):
if self._new is None: if self._new is None:
self._new = self._sediment_layers_list.new(self._index) self._new = self._sediment_layers_list.new(self._index)
else: else:
self._sediment_layers_list.insert(self._index, self._new) self._sediment_layers_list.undelete([self._new])
class DelCommand(QUndoCommand): class DelCommand(QUndoCommand):
@ -84,17 +84,15 @@ class DelCommand(QUndoCommand):
self._sediment_layers_list = sediment_layers_list self._sediment_layers_list = sediment_layers_list
self._rows = rows self._rows = rows
self._sl_pos = [] self._sl = []
for row in rows: for row in rows:
self._sl_pos.append((row, self._sediment_layers_list.get(row))) self._sl.append(self._sediment_layers_list.get(row))
self._sl_pos.sort()
def undo(self): def undo(self):
for row, el in self._sl_pos: self._sediment_layers_list.undelete(self._sl)
self._sediment_layers_list.insert(row, el)
def redo(self): def redo(self):
self._sediment_layers_list.delete_i(self._rows) self._sediment_layers_list.delete(self._sl)
class MoveCommand(QUndoCommand): class MoveCommand(QUndoCommand):