Loading src/common/orm/_Database.py→src/common/orm/Database.py +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 Loading src/common/orm/Exceptions.py +3 −0 Original line number Diff line number Diff line class ConstraintException(Exception): pass class MutexException(Exception): pass src/common/orm/backend/_Backend.py +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: Loading Loading @@ -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() src/common/orm/backend/inmemory/InMemoryBackend.py +20 −8 Original line number Diff line number Diff line Loading @@ -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__) Loading @@ -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 Loading Loading @@ -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 Loading @@ -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: Loading @@ -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) Loading @@ -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: Loading src/common/orm/backend/inmemory/Tools.py +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()) Loading @@ -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()) Loading @@ -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 Loading
src/common/orm/_Database.py→src/common/orm/Database.py +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 Loading
src/common/orm/Exceptions.py +3 −0 Original line number Diff line number Diff line class ConstraintException(Exception): pass class MutexException(Exception): pass
src/common/orm/backend/_Backend.py +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: Loading Loading @@ -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()
src/common/orm/backend/inmemory/InMemoryBackend.py +20 −8 Original line number Diff line number Diff line Loading @@ -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__) Loading @@ -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 Loading Loading @@ -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 Loading @@ -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: Loading @@ -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) Loading @@ -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: Loading
src/common/orm/backend/inmemory/Tools.py +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()) Loading @@ -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()) Loading @@ -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