Commit 2952ec6f authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Common ORM library fully functional.

parent be7f4145
Loading
Loading
Loading
Loading
+1 −20
Original line number Diff line number Diff line
import logging
from typing import List, Set
from .backend._Backend import _Backend
from .model.Model import Model
from .Exceptions import MutexException

LOGGER = logging.getLogger(__name__)

class _Database(Model):
class Database:
    def __init__(self, backend : _Backend):
        if not isinstance(backend, _Backend):
            str_class_path = '{}.{}'.format(_Backend.__module__, _Backend.__name__)
            raise AttributeError('backend must inherit from {}'.format(str_class_path))
        self._backend = backend
        super().__init__(self)
        self._acquired = False
        self._owner_key = None

    @property
    def parent(self) -> '_Database': return self

    @property
    def backend(self) -> _Backend: return self._backend

    @property
    def backend_key(self) -> str: return ''

    #def __enter__(self) -> '_Database':
    #    self._acquired, self._owner_key = self._backend.lock()
    #    if not self._acquired: raise MutexException('Unable to acquire database lock')
    #    return self

    #def __exit__(self, exc_type, exc_val, exc_tb) -> None:
    #    self._backend.unlock(self._owner_key)

    def clear_all(self, keep_keys : Set[str] = set()) -> None:
        for key in self._backend.keys():
            if key in keep_keys: continue
+3 −0
Original line number Diff line number Diff line
class ConstraintException(Exception):
    pass

class MutexException(Exception):
    pass
+6 −3
Original line number Diff line number Diff line
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, Optional, Set, Tuple

class _Backend:
    def __init__(self, **settings) -> None:
@@ -43,8 +43,11 @@ class _Backend:
    def set_has(self, key : List[str], item : str) -> bool:
        raise NotImplementedError()

    def set_get_all(self, key : List[str]) -> Set[str]:
        raise NotImplementedError()

    def set_remove(self, key : List[str], item : str) -> None:
        raise NotImplementedError()

    def dump(self) -> List[str]:
    def dump(self) -> List[Tuple[str, str, str]]:
        raise NotImplementedError()
+20 −8
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ import copy, logging, threading, uuid
from typing import Dict, List, Optional, Set, Tuple, Union
from .._Backend import _Backend
from ..Tools import key_to_str
from .Tools import get_or_create_dict, get_or_create_list, get_or_create_set
from .Tools import get_dict, get_list, get_or_create_dict, get_or_create_list, get_or_create_set, get_set

LOGGER = logging.getLogger(__name__)

@@ -32,7 +32,7 @@ class InMemoryBackend(_Backend):
                        if str_key not in self._keys: continue
                        del self._keys[str_key]
                    return False, None
                else:

                # lock available, temporarily acquire it; locks will be released if some of them for a requested
                # key is not available
                self._keys[str_key] = owner_key
@@ -69,7 +69,8 @@ class InMemoryBackend(_Backend):
    def dict_get(self, key : List[str], fields : List[str] = []) -> Dict[str, str]:
        str_key = key_to_str(key)
        with self._lock:
            container = get_or_create_dict(self._keys, str_key)
            container = get_dict(self._keys, str_key)
            if container is None: return None
            if len(fields) == 0: fields = container.keys()
            return copy.deepcopy({
                field_name : field_value for field_name,field_value in container.items() if field_name in fields
@@ -90,11 +91,13 @@ class InMemoryBackend(_Backend):
            else:
                container = get_or_create_dict(self._keys, str_key)
                for field in list(fields): container.pop(field, None)
                if len(container) == 0: self._keys.pop(str_key)

    def list_get_all(self, key : List[str]) -> List[str]:
        str_key = key_to_str(key)
        with self._lock:
            container = get_or_create_list(self._keys, str_key)
            container = get_list(self._keys, str_key)
            if container is None: return None
            return copy.deepcopy(container)

    def list_push_last(self, key : List[str], item : str) -> None:
@@ -108,6 +111,7 @@ class InMemoryBackend(_Backend):
        with self._lock:
            container = get_or_create_list(self._keys, str_key)
            container.remove(item)
            if len(container) == 0: self._keys.pop(str_key)

    def set_add(self, key : List[str], item : str) -> None:
        str_key = key_to_str(key)
@@ -121,11 +125,19 @@ class InMemoryBackend(_Backend):
            container = get_or_create_set(self._keys, str_key)
            return item in container

    def set_get_all(self, key : List[str]) -> Set[str]:
        str_key = key_to_str(key)
        with self._lock:
            container = get_set(self._keys, str_key)
            if container is None: return None
            return copy.deepcopy(container)

    def set_remove(self, key : List[str], item : str) -> None:
        str_key = key_to_str(key)
        with self._lock:
            container = get_or_create_set(self._keys, str_key)
            container.discard(item)
            if len(container) == 0: self._keys.pop(str_key)

    def dump(self) -> List[Tuple[str, str, str]]:
        with self._lock:
+9 −0
Original line number Diff line number Diff line
from typing import Dict, List, Set, Union

def get_dict(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> Dict:
    return keys.get(str_key, None)

def get_or_create_dict(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> Dict:
    container = keys.get(str_key, None)
    if container is None: container = keys.setdefault(str_key, dict())
@@ -7,6 +10,9 @@ def get_or_create_dict(keys : Dict[str, Union[Dict, List, Set]], str_key : str)
        raise Exception('Key({:s}, {:s}) is not a dict'.format(str(type(container).__name__), str(str_key)))
    return container

def get_list(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> List:
    return keys.get(str_key, None)

def get_or_create_list(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> List:
    container = keys.get(str_key, None)
    if container is None: container = keys.setdefault(str_key, list())
@@ -14,6 +20,9 @@ def get_or_create_list(keys : Dict[str, Union[Dict, List, Set]], str_key : str)
        raise Exception('Key({:s}, {:s}) is not a list'.format(str(type(container).__name__), str(str_key)))
    return container

def get_set(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> Set:
    return keys.get(str_key, None)

def get_or_create_set(keys : Dict[str, Union[Dict, List, Set]], str_key : str) -> Set:
    container = keys.get(str_key, None)
    if container is None: container = keys.setdefault(str_key, set())
Loading