# -*- coding: utf-8 -*- from tools import trace, timer from Model.Tools.PamhyrDB import SQLSubModel from Model.Except import NotImplementedMethodeError class Layer(SQLSubModel): _sub_classes = [] _id_cnt = 0 def __init__(self, id: int = -1, name: str = "", type="", height=0.0, d50=0.0, sigma=0.0, critical_constraint=0.0, sl=None, status=None): super(Layer, self).__init__() self._status = status self._name = name self._type = type self._height = height self._d50 = d50 self._sigma = sigma self._critical_constraint = critical_constraint if id == -1: self.id = Layer._id_cnt else: self.id = id Layer._id_cnt = max(id, Layer._id_cnt+1) @property def name(self): return self._name @name.setter def name(self, name): self._name = name @property def type(self): return self._type @type.setter def type(self, type): self._type = type @property def height(self): return self._height @height.setter def height(self, height): self._height = float(height) @property def d50(self): return self._d50 @d50.setter def d50(self, d50): self._d50 = float(d50) @property def sigma(self): return self._sigma @sigma.setter def sigma(self, sigma): self._sigma = float(sigma) @property def critical_constraint(self): return self._critical_constraint @critical_constraint.setter def critical_constraint(self, critical_constraint): self._critical_constraint = float(critical_constraint) @classmethod def _sql_create(cls, execute): execute(""" CREATE TABLE sedimentary_layer_layer( id INTEGER NOT NULL PRIMARY KEY, ind INTEGER NOT NULL, name TEXT NOT NULL, type TEXT NOT NULL, height REAL NOT NULL, d50 REAL NOT NULL, sigma REAL NOT NULL, critical_constraint REAL NOT NULL, sl INTEGER, FOREIGN KEY(sl) REFERENCES sedimentary_layer(id) ) """) return cls._create_submodel(execute) @classmethod def _sql_update(cls, execute, version): major, minor, release = version.strip().split(".") if major == minor == "0": if int(release) < 2: cls._sql_create(execute) return True @classmethod def _sql_load(cls, execute, data=None): new = [] sl = data["sl"] table = execute( "SELECT id, ind, name, type, height, " + "d50, sigma, critical_constraint " + "FROM sedimentary_layer_layer " + f"WHERE sl = {sl}" ) for _ in table: new.append(None) for row in table: ind = row[1] layer = cls( id=row[0], name=row[2], type=row[3], height=row[4], d50=row[5], sigma=row[6], critical_constraint=row[7], sl=sl, status=data['status'] ) new[ind] = layer return new def _sql_save(self, execute, data=None): ind = data["ind"] sl = data["sl"] sql = ( "INSERT INTO " + "sedimentary_layer_layer(id, ind, name, type, height, " + "d50, sigma, critical_constraint, sl) " + "VALUES (" + f"{self.id}, {ind}, '{self._sql_format(self._name)}', " + f"'{self._sql_format(self._type)}', {self._height}, " + f"{self._d50}, {self._sigma}, {self._critical_constraint}, " + f"{sl.id}" + ")" ) execute(sql) return True class SedimentLayer(SQLSubModel): _sub_classes = [Layer] _id_cnt = 0 def __init__(self, id: int = -1, name: str = "", comment: str = "", status=None): super(SedimentLayer, self).__init__() self._status = status self._name = name self._comment = comment self._layers = [] if id == -1: self.id = SedimentLayer._id_cnt else: self.id = id SedimentLayer._id_cnt = max(id, SedimentLayer._id_cnt+1) def __str__(self): s = f"{self.name} ({len(self)})" if self.comment != "": s += f" - {self.comment}" return s def __len__(self): return len(self._layers) @property def layers(self): return self._layers.copy() def height(self): return list( map(lambda layer: layer.height, self._layers) ) @property def name(self): return self._name @name.setter def name(self, name): self._name = name def names(self): return list( map(lambda layer: layer.name, self._layers) ) @property def comment(self): return self._comment @comment.setter def comment(self, comment): self._comment = comment @classmethod def _sql_create(cls, execute): execute(""" CREATE TABLE sedimentary_layer( id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL, comment TEXT NOT NULL ) """) return cls._create_submodel(execute) @classmethod def _sql_update(cls, execute, version): major, minor, release = version.strip().split(".") if major == minor == "0": if int(release) < 2: cls._sql_create(execute) return True @classmethod def _sql_load(cls, execute, data=None): new = [] table = execute( "SELECT id, name, comment " + "FROM sedimentary_layer " ) for row in table: sl = cls( id=row[0], name=row[1], comment=row[2], status=data['status'] ) data["sl"] = sl.id sl._layers = Layer._sql_load(execute, data) new.append(sl) return new def _sql_save(self, execute, data=None): if data is None: data = {} sql = ( "INSERT INTO sedimentary_layer (id, name, comment) " + f"VALUES ({self.id}, '{self._sql_format(self._name)}', " + f"'{self._sql_format(self._comment)}')" ) execute(sql) data["sl"] = self ind = 0 for layer in self._layers: data["ind"] = ind layer._sql_save(execute, data) ind += 1 return True def get(self, index): return self._layers[index] def set(self, index, new): self._layers[index] = new self._status.modified() def insert(self, index, new): self._layers.insert(index, new) self._status.modified() def new(self, index): n = Layer(sl=self, status=self._status) self.insert(index, n) self._status.modified() return n def delete(self, els): for el in els: self._layers.remove(el) self._status.modified() def delete_i(self, indexes): els = list( map( lambda x: x[1], filter( lambda x: x[0] in indexes, enumerate(self._layers) ) ) ) self.delete(els) def move_up(self, index): if index >= 0: next = index - 1 lst = self._layers lst[index], lst[next] = lst[next], lst[index] self._status.modified() def move_down(self, index): if index + 1 < len(self._layers): prev = index + 1 lst = self._layers lst[index], lst[prev] = lst[prev], lst[index] self._status.modified()