from typing import Collection, Dict, Iterator, Optional
-from .proto import ConfigEntry, EntryKey, Simplified
+from .proto import ConfigEntry, ConfigStore, EntryKey, FindParams, Simplified
class MemConfigEntry:
@property
def full_key(self) -> EntryKey:
return self._base.full_key
+
+
+def find_in_store(
+ store: ConfigStore, ns: str, params: FindParams
+) -> Collection[ConfigEntry]:
+ """Given a ConfigStore and namespace within that store, search the stored
+ objects for matching parameters. Params is a dict that will be compared to
+ the same keys/attributes of the objects being searched. Only exact matches
+ will be returned.
+ If the store implements the FindingConfigStore protocol the operation
+ of finding
+ """
+ # is it a FindingConfigStore?
+ _find_entries = getattr(store, 'find_entries', None)
+ if _find_entries:
+ try:
+ return _find_entries(ns, params)
+ except NotImplementedError:
+ # Allow the store to reject any of the ns/params/whatnot with a
+ # NotImplementedError even if it implements the find_entries
+ # function. This will fall back to the simple-but-slow approach of
+ # deserializing and examining every object.
+ pass
+ return _find_in_store(store, ns, params)
+
+
+def _find_in_store(
+ store: ConfigStore, ns: str, params: FindParams
+) -> Collection[ConfigEntry]:
+ """Fallback mode for find_in_store."""
+ found = []
+ for sub_key in store.contents(ns):
+ entry = store[(ns, sub_key)]
+ obj = entry.get()
+ if all(obj[pkey] == pval for pkey, pval in params.items()):
+ found.append(ObjectCachingEntry(entry, obj=obj))
+ return found