From fa85d46af0b91477cf354947df628af0dc0d2800 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 28 Mar 2019 16:38:50 +0100 Subject: ee.xsd: o Renaming to . o Adding on , removing from . A part can have exactly one part. create-order: o Creating anonymous part objects, with two references, one schematic reference and one part-uri reference to the selected part. o Redoing how the order is calculated with the new ObjDb structure. ee.part.Part: o Absorbing bom_file_utils into Part. Much better wrapper object around the xml goop. --- src/ee/db.py | 117 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 20 deletions(-) (limited to 'src/ee/db.py') diff --git a/src/ee/db.py b/src/ee/db.py index e471278..57533ef 100644 --- a/src/ee/db.py +++ b/src/ee/db.py @@ -1,4 +1,4 @@ -from typing import TypeVar, Generic, Callable, MutableMapping, List, Iterable, Union, Any +from typing import TypeVar, Generic, Callable, MutableMapping, List, Iterable, Union, Any, Mapping K = TypeVar('K') V = TypeVar('V') @@ -34,9 +34,11 @@ class Index(Generic[K, V]): class ListIndex(Index[K, V]): - def __init__(self, key_callable: KeyCallable): + def __init__(self, name, key_callable: KeyCallable, multiple=False): + self.name = name self.idx: MutableMapping[K, V] = {} self.key_callable = key_callable + self.multiple = multiple def add(self, value: V): keys = self.key_callable(value) @@ -44,6 +46,9 @@ class ListIndex(Index[K, V]): if keys is None: return + if not self.multiple: + keys = [keys] + for key in keys: if key is None: continue @@ -54,8 +59,9 @@ class ListIndex(Index[K, V]): else: self.idx[key] = [value] - def get(self, key: K) -> Iterable[V]: - return [self.idx[key]] + def get(self, key: K) -> List[V]: + items = self.idx.get(key, None) + return self.idx[key] if items is not None else [] def clear(self): return self.idx.clear() @@ -71,12 +77,15 @@ class ListIndex(Index[K, V]): class UniqueIndex(Index[K, V]): - def __init__(self, key_callable: KeyCallable): + def __init__(self, name, key_callable: KeyCallable, multiple=False): + self.name = name self.idx: MutableMapping[K, V] = {} self.key_callable = key_callable + self.multiple = multiple def get(self, key: K) -> Iterable[V]: - return [self.idx[key]] + items = self.idx.get(key, None) + return [self.idx[key]] if items is not None else [] def get_single(self, key: K) -> V: return self.idx[key] @@ -84,16 +93,75 @@ class UniqueIndex(Index[K, V]): def add(self, value: V): keys = self.key_callable(value) - if not isinstance(keys, Iterable): + if keys is None: + return + + if not self.multiple: keys = [keys] for key in keys: - key = self.key_callable(value) present = self.idx.get(key, None) if present is not None: - raise KeyError("Duplicate part in index: {}".format(key)) + raise KeyError("Duplicate key in index '{}': key={}, value={}".format(self.name, key, repr(value))) + + self.idx[key] = value + + def clear(self): + return self.idx.clear() + + def __iter__(self): + return self.idx.__iter__() + + def items(self): + return self.idx.items() + + def values(self): + return self.idx.values() + + +class MultiIndex(Index[K, V]): + def __init__(self, name, key_callable: KeyCallable, multiple=False): + self.name = name + self.idx: MutableMapping[K, V] = {} + self.key_callable = key_callable + self.multiple = multiple + + # TODO: this should return a new index + def get(self, key: K) -> Mapping[K, V]: + items = self.idx.get(key, None) + return self.idx[key] if items is not None else {} - self.idx[key] = True + def get_single(self, key: K) -> V: + return self.idx[key] + + def add(self, value: V): + keys = self.key_callable(value) + + if keys is None: + return + + if not self.multiple: + keys = [keys] + + for tpl in keys: + if not isinstance(tpl, tuple): + raise KeyError("The key must be a tuple, index='{}', key='{}'".format(self.name, repr(tpl))) + + parent_idx = self.idx + for sub_key in tpl[0:-1]: + if sub_key is None: + raise KeyError("Got None sub-key: index='{}', key='{}'".format(self.name, repr(tpl))) + idx = parent_idx.get(sub_key, None) + if idx is None: + idx = {} + parent_idx[sub_key] = idx + parent_idx = idx + + values = parent_idx.get(tpl[-1], None) + if values is None: + values = [] + parent_idx[tpl[-1]] = values + values.append(value) def clear(self): return self.idx.clear() @@ -125,19 +193,28 @@ class ObjDb(Generic[V]): def __len__(self) -> int: return len(self.values) - def add_index(self, name, key_callable: KeyCallable) -> ListIndex[Any, V]: - idx = ListIndex(key_callable) - self._indexes[name] = idx + def add_index(self, name, key_callable: KeyCallable, **kwargs) -> ListIndex[Any, V]: + idx = ListIndex(name, key_callable, **kwargs) + return self._add(name, idx) + + def add_unique_index(self, name, key_callable: KeyCallable, **kwargs) -> UniqueIndex[Any, V]: + idx = UniqueIndex(name, key_callable, **kwargs) + return self._add(name, idx) + + def add_multi_index(self, name, key_callable: KeyCallable, **kwargs) -> MultiIndex[Any, V]: + idx = MultiIndex(name, key_callable, **kwargs) + return self._add(name, idx) + + def index(self, name) -> Index: + return self._indexes[name] + + def _add(self, name, idx): + if name in self._indexes: + raise KeyError("Index already exist: {}".format(name)) for value in self.values: idx.add(value) - return idx - - def add_unique_index(self, name, key_callable: KeyCallable) -> UniqueIndex[Any, V]: - idx = UniqueIndex(key_callable) self._indexes[name] = idx - return idx - def index(self, name) -> Index: - return self._indexes[name] + return idx -- cgit v1.2.3