From 617ca1316a57bb7c114a1ccc10b981d461620a84 Mon Sep 17 00:00:00 2001 From: Hellow Date: Thu, 9 Mar 2023 18:35:56 +0100 Subject: [PATCH] theoretically implemented append --- src/music_kraken/objects/collection.py | 40 +++++++++----------------- src/music_kraken/objects/parents.py | 8 +++--- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/music_kraken/objects/collection.py b/src/music_kraken/objects/collection.py index b3e87a2..2153c73 100644 --- a/src/music_kraken/objects/collection.py +++ b/src/music_kraken/objects/collection.py @@ -1,4 +1,5 @@ -from typing import List, Iterable, Dict +from typing import List, Iterable, Dict, DefaultDict +from collections import defaultdict from .source import SourceAttribute from .parents import DatabaseObject @@ -19,7 +20,7 @@ class Collection: # Attribute needs to point to self.element_type = element_type - self._data: list = list() + self._data: List[DatabaseObject] = list() """ example of attribute_to_object_map @@ -33,46 +34,33 @@ class Collection: } ``` """ - self.attribute_to_object_map: Dict[str, dict] = dict() + self._attribute_to_object_map: Dict[str, Dict[object, DatabaseObject]] = defaultdict(dict) self.extend(data, merge_on_conflict=True) def sort(self, reverse: bool = False, **kwargs): self._data.sort(reverse=reverse, **kwargs) - def map_element(self, element: SourceAttribute): - for source_url in element.source_url_map: - self._by_url[source_url] = element - - for attr in self.map_attributes: - value = element.__getattribute__(attr) - if type(value) != str: - # this also throws out all none values - continue - - self._by_attribute[attr][string_processing.unify(value)] = element + def map_element(self, element: DatabaseObject): + for name, value in element.indexing_values: + self._attribute_to_object_map[name][value] = element def append(self, element: DatabaseObject, merge_on_conflict: bool = True): + # if the element type has ben defide in the initializer it checks if the type maches if self.element_type is not None and isinstance(element, self.element_type): raise TypeError(f"{type(element)} is not the set type {self.element_type}") - for source_url in element.source_url_map: - if source_url in self._by_url: - if merge_on_conflict: - self._by_url[source_url].merge(element) - return - - for attr in self.map_attributes: - value = element.__getattribute__(attr) - if value in self._by_attribute[attr]: - if merge_on_conflict: - self._by_attribute[attr][value].merge(element) + for name, value in element.indexing_values: + if value in self._attribute_to_object_map[name]: + # if the object does already exist + # thus merging and don't add it afterwards + self._attribute_to_object_map[name][value].merge(element) return self._data.append(element) self.map_element(element) - def extend(self, element_list: Iterable, merge_on_conflict: bool = True): + def extend(self, element_list: Iterable[DatabaseObject], merge_on_conflict: bool = True): for element in element_list: self.append(element, merge_on_conflict=merge_on_conflict) diff --git a/src/music_kraken/objects/parents.py b/src/music_kraken/objects/parents.py index 3210228..0b352a2 100644 --- a/src/music_kraken/objects/parents.py +++ b/src/music_kraken/objects/parents.py @@ -1,4 +1,4 @@ -from typing import Optional, Dict, Type +from typing import Optional, Dict, Type, Tuple, List import uuid from ..utils.shared import ( @@ -25,16 +25,16 @@ class DatabaseObject: self.dynamic = dynamic @property - def indexing_values(self) -> Dict[str, object]: + def indexing_values(self) -> List[Tuple[str, object]]: """ returns a map of the name and values of the attributes. This helps in comparing classes for equal data (eg. being the same song but different attributes) Returns: - Dict[str, object]: the key is the name of the attribute, and the value its value + List[Tuple[str, object]]: the first element in the tuple is the name of the attribute, the second the value. """ - return dict() + return list() def merge(self, other, override: bool = False): if isinstance(other, type(self)):