from pathlib import Path class Uri: def __init__(self, layer=None, uri=''): if layer is not None or not isinstance(uri, Uri): self._uri = layer.dataProvider().dataSourceUri() if layer is not None else uri self._has_filter = False self._filter = None self._geometry_type = None self._database = None if layer is not None and self.is_memory_layer(): self._layer_name = layer.name() elif layer is not None and self.is_database(): self._layer_name = self.layer_name() else: self._layer_name = None if uri is not None and isinstance(uri, Uri): self._uri = uri._uri self._has_filter = uri._has_filter self._filter = uri._filter self._geometry_type = uri._geometry_type self._database = uri._database self._layer_name = uri._layer_name def database_layer_name_same(self): if self.database() is not None and self.layer_name() is not None: return Path(self.database().lower()).stem == self.layer_name().lower() return False def has_filter(self): return '|subset=' in self._uri def filter(self): if self.has_filter(): parts = self._uri.split('|') for p in parts: if 'subset=' in p: return p.split('subset=')[1] def strip_filter(self): if self.has_filter(): self._has_filter = True parts = self._uri.split('|') rebuild = [] for p in parts: if 'subset=' in p: self._filter = p.split('subset=')[1] else: rebuild.append(p) self._uri = '|'.join(rebuild) def is_database(self): return '|layername=' in self._uri def has_geometry_defn(self): return '|geometrytype=' in self._uri def geometry_type(self): if self.has_geometry_defn(): parts = self._uri.split('|') for p in parts: if 'geometrytype=' in p: return p.split('geometrytype=')[1] def database(self): return self._uri.split('|')[0] def layer_name(self): if self.is_database(): parts = self._uri.split('|') for p in parts: if 'layername=' in p: return p.split('layername=')[1] elif self.is_memory_layer(): return self._layer_name else: return Path(self.database()).stem def layer_uri(self): if self.is_database(): return f'{self.database()}|layername={self.layer_name()}' else: return self.database() def is_memory_layer(self): return self._uri[:6] == 'memory' def ext(self): if self.is_memory_layer(): return '.memory' else: return Path(self.database()).suffix def set_database(self, db): self._database = db def set_layer_name(self, lyr_name): self._layer_name = lyr_name def build(self, uri=None): self._uri = '' if self._database is not None: self._uri = f'{self._uri}{self._database}' if self._layer_name is not None: self._uri = f'{self._uri}|layername={self._layer_name}' if uri is not None and uri.has_geometry_defn(): self._uri = f'{self._uri}|geometrytype={uri.geometry_type()}' elif self._geometry_type is not None: self._uri = f'{self._uri}|geometrytype={self._geometry_type}' if uri is not None and uri.has_filter(): self._uri = f'{self._uri}|subset={uri.filter()}' elif self._filter is not None: self._uri = f'{self._uri}|subset={self._filter}' def uri(self): return self._uri