Remove use of dpath in query projection

This commit is contained in:
allegroai 2022-07-08 18:04:02 +03:00
parent 3695f25a5f
commit d760cf5835

View File

@ -3,14 +3,10 @@ from concurrent.futures import ThreadPoolExecutor
from itertools import groupby, chain from itertools import groupby, chain
from typing import Sequence, Dict, Callable, Tuple, Any, Type from typing import Sequence, Dict, Callable, Tuple, Any, Type
import dpath.path
import dpath.options
from apiserver.apierrors import errors from apiserver.apierrors import errors
from apiserver.database.props import PropsMixin from apiserver.database.props import PropsMixin
SEP = "." SEP = "."
dpath.options.ALLOW_EMPTY_STRING_KEYS = True
def project_dict(data, projection, separator=SEP): def project_dict(data, projection, separator=SEP):
@ -277,25 +273,26 @@ class ProjectionHelper(object):
norm_path = doc_cls.get_dpath_translated_path(path) norm_path = doc_cls.get_dpath_translated_path(path)
globlist = norm_path.strip(SEP).split(SEP) globlist = norm_path.strip(SEP).split(SEP)
obj_paths = self._cached_results_paths.get(id(obj)) def _search_and_replace(target: dict, p: Sequence[str]) -> Sequence[str]:
if obj_paths is None:
obj_paths = self._cached_results_paths[id(obj)] = list(
dpath.path.paths(obj, dirs=True, skip=True)
)
paths = [p for p in obj_paths if dpath.path.match(p, globlist)]
def search_and_replace(p: Sequence[Tuple[str, Type]]) -> Any:
parent = None parent = None
target = obj for idx, part in enumerate(p):
for part in p: if isinstance(target, dict) and part in target:
parent = target parent = target
target = target[part[0]] target = target[part]
if parent and factory: elif isinstance(target, list) and part == "*":
parent[p[-1][0]] = factory(target) return list(
return target chain.from_iterable(
_search_and_replace(t, p[idx + 1 :]) for t in target
)
)
else:
return []
return [search_and_replace(p) for p in paths] if parent and factory:
parent[p[-1]] = factory(target)
return [target]
return _search_and_replace(obj, globlist)
def project(self, results, projection_func): def project(self, results, projection_func):
""" """