userver: en/testsuite/databases/mongo/mongo_schema.py Source File
Loading...
Searching...
No Matches
mongo_schema.py
2import pathlib
3import typing
4
5from testsuite import types
6from testsuite.utils import yaml_util
7
8
9class MongoSchema(collections.abc.Mapping):
10 _directory: pathlib.Path
11 _loaded: dict[str, dict]
12 _paths: dict[str, pathlib.Path]
13
14 def __init__(self, directory: types.PathOrStr) -> None:
15 self._directory = pathlib.Path(directory)
16 self._loaded = {}
17 self._paths = _get_paths(self._directory)
18
19 def __getitem__(self, name: str) -> dict:
20 if name not in self._paths:
21 raise KeyError(f'Missing schema file for collection {name}')
22 if name not in self._loaded:
23 self._loaded[name] = yaml_util.load_file(self._paths[name])
24 return self._loaded[name]
25
26 def __iter__(self) -> typing.Iterator[str]:
27 return iter(self._paths)
28
29 def __len__(self) -> int:
30 return len(self._paths)
31
32 @property
33 def directory(self) -> pathlib.Path:
34 return self._directory
35
36
38 def __init__(self) -> None:
39 self._cache: dict[pathlib.Path, MongoSchema] = {}
40
41 def get_schema(self, directory: types.PathOrStr) -> MongoSchema:
42 directory = pathlib.Path(directory)
43 if directory not in self._cache:
44 self._cache[directory] = MongoSchema(directory)
45 return self._cache[directory]
46
47
48class MongoSchemas(collections.abc.Mapping):
49 def __init__(
50 self,
51 cache: MongoSchemaCache,
52 directories: typing.Iterable[types.PathOrStr],
53 ):
54 self._cache = cache
55 self._directories = [
56 pathlib.Path(directory) for directory in directories
57 ]
58 self._schema_by_collection: dict[str, MongoSchema] = {}
59 for directory in self._directories:
60 schema = cache.get_schema(directory)
61 for name in schema:
62 if name in self._schema_by_collection:
63 raise RuntimeError(
64 f'Duplicate definition of collection {name}:\n'
65 f' at {self._schema_by_collection[name].directory}\n'
66 f' at {directory}',
67 )
68 self._schema_by_collection[name] = schema
69
70 def __getitem__(self, name):
71 if name not in self._schema_by_collection:
72 raise KeyError(f'Missing schema file for collection {name}')
73 return self._schema_by_collection[name][name]
74
75 def __iter__(self):
76 for directory in self._directories:
77 yield from self._cache.get_schema(directory)
78
79 def __len__(self) -> int:
80 return sum(
81 len(self._cache.get_schema(directory))
82 for directory in self._directories
83 )
84
85
86def _get_paths(directory: pathlib.Path) -> dict[str, pathlib.Path]:
87 return {path.stem: path for path in directory.glob('*.yaml')}