-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathlocal.py
More file actions
145 lines (110 loc) · 4.96 KB
/
local.py
File metadata and controls
145 lines (110 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""LocalStore module."""
from collections import defaultdict
from typing import TYPE_CHECKING, Any, Dict, List, Set, Type, Union
from diffsync.exceptions import ObjectAlreadyExists, ObjectNotFound
from diffsync.store import BaseStore
if TYPE_CHECKING:
from diffsync import DiffSyncModel
class LocalStore(BaseStore):
"""LocalStore class."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Init method for LocalStore."""
super().__init__(*args, **kwargs)
self._data: Dict = defaultdict(dict)
def get_all_model_names(self) -> Set[str]:
"""Get all the model names stored.
Return:
Set of all the model names.
"""
return set(self._data.keys())
def get(
self, *, model: Union[str, "DiffSyncModel", Type["DiffSyncModel"]], identifier: Union[str, Dict]
) -> "DiffSyncModel":
"""Get one object from the data store based on its unique id.
Args:
model: DiffSyncModel class or instance, or modelname string, that defines the type of the object to retrieve
identifier: Unique ID of the object to retrieve, or dict of unique identifier keys/values
Raises:
ValueError: if obj is a str and identifier is a dict (can't convert dict into a uid str without a model class)
ObjectNotFound: if the requested object is not present
"""
object_class, modelname = self._get_object_class_and_model(model)
uid = self._get_uid(model, object_class, identifier)
if uid not in self._data[modelname]:
raise ObjectNotFound(f"{modelname} {uid} not present in {str(self)}")
return self._data[modelname][uid]
def get_all(self, *, model: Union[str, "DiffSyncModel", Type["DiffSyncModel"]]) -> List["DiffSyncModel"]:
"""Get all objects of a given type.
Args:
model: DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve
Returns:
List of Object
"""
if isinstance(model, str):
modelname = model
else:
modelname = model.get_type()
return list(self._data[modelname].values())
def get_by_uids(
self, *, uids: List[str], model: Union[str, "DiffSyncModel", Type["DiffSyncModel"]]
) -> List["DiffSyncModel"]:
"""Get multiple objects from the store by their unique IDs/Keys and type.
Args:
uids: List of unique id / key identifying object in the database.
model: DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve
Raises:
ObjectNotFound: if any of the requested UIDs are not found in the store
"""
if isinstance(model, str):
modelname = model
else:
modelname = model.get_type()
results = []
for uid in uids:
if uid not in self._data[modelname]:
raise ObjectNotFound(f"{modelname} {uid} not present in {str(self)}")
results.append(self._data[modelname][uid])
return results
def add(self, *, obj: "DiffSyncModel") -> None:
"""Add a DiffSyncModel object to the store.
Args:
obj: Object to store
Raises:
ObjectAlreadyExists: if a different object with the same uid is already present.
"""
modelname = obj.get_type()
uid = obj.get_unique_id()
existing_obj = self._data[modelname].get(uid)
if existing_obj:
if existing_obj is not obj:
raise ObjectAlreadyExists(f"Object {uid} already present", obj)
# Return so we don't have to change anything on the existing object and underlying data
return
if not obj.adapter:
obj.adapter = self.adapter
self._data[modelname][uid] = obj
def update(self, *, obj: "DiffSyncModel") -> None:
"""Update a DiffSyncModel object to the store.
Args:
obj: Object to update
"""
modelname = obj.get_type()
uid = obj.get_unique_id()
existing_obj = self._data[modelname].get(uid)
if existing_obj is obj:
return
self._data[modelname][uid] = obj
def remove_item(self, modelname: str, uid: str) -> None:
"""Remove one item from store."""
if uid not in self._data[modelname]:
raise ObjectNotFound(f"{modelname} {uid} not present in {str(self)}")
del self._data[modelname][uid]
def count(self, *, model: Union[str, "DiffSyncModel", Type["DiffSyncModel"], None] = None) -> int:
"""Returns the number of elements of a specific model, or all elements in the store if unspecified."""
if not model:
return sum(len(entries) for entries in self._data.values())
if isinstance(model, str):
modelname = model
else:
modelname = model.get_type()
return len(self._data[modelname])