Skip to content
Snippets Groups Projects
EntityAttributes.py 2.58 KiB
Newer Older
  • Learn to ignore specific revisions
  • Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from __future__ import annotations
    import copy
    from typing import Any, Dict, TYPE_CHECKING
    from ...engines._DatabaseEngine import _DatabaseEngine
    from .Tools import format_key
    
    if TYPE_CHECKING:
        from ._Entity import _Entity
    
    class EntityAttributes:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        def __init__(self, parent : '_Entity', entity_key : str, validators : Dict, transcoders : Dict = {}):
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            self._parent = parent
            self._database_engine : _DatabaseEngine = self._parent.database_engine
            self._entity_key = format_key(entity_key, self._parent)
            self._validators = validators
            self._transcoders = transcoders
    
        def validate(self, update_attributes, remove_attributes, attribute_name):
            remove_attributes.discard(attribute_name)
            value = update_attributes.pop(attribute_name, None)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            if value is None: return
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            validator = self._validators.get(attribute_name)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            if validator is None: return
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            if not validator(value): raise AttributeError('{} is invalid'.format(attribute_name))
    
        def transcode(self, attribute_name, attribute_value):
            transcoder_set = self._transcoders.get(attribute_name, {})
            transcoder = transcoder_set.get(type(attribute_value))
            return attribute_value if transcoder is None else transcoder(attribute_value)
    
        def get(self, attributes=[]) -> Dict[str, Any]:
            return {
                k:self.transcode(k, v)
                for k,v in self._database_engine.dict_get(self._entity_key, fields=attributes).items()
            }
    
        def update(self, update_attributes={}, remove_attributes=[]):
            remove_attributes = set(remove_attributes)
            copy_update_attributes = copy.deepcopy(update_attributes)
            copy_remove_attributes = copy.deepcopy(remove_attributes)
    
            for attribute_name in self._validators.keys():
                self.validate(copy_update_attributes, copy_remove_attributes, attribute_name)
                attribute_value = update_attributes.get(attribute_name)
                if attribute_value is None: continue
                update_attributes[attribute_name] = self.transcode(attribute_name, attribute_value)
    
            if len(copy_update_attributes) > 0:
                raise AttributeError('Unexpected update_attributes: {}'.format(str(copy_update_attributes)))
    
            if len(copy_remove_attributes) > 0:
                raise AttributeError('Unexpected remove_attributes: {}'.format(str(copy_remove_attributes)))
    
            self._database_engine.dict_update(self._entity_key, update_attributes, remove_attributes)
            return self
    
        def delete(self, attributes=[]):
            self._database_engine.dict_delete(self._entity_key, attributes)