-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser_store.py
More file actions
148 lines (102 loc) · 3.79 KB
/
user_store.py
File metadata and controls
148 lines (102 loc) · 3.79 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
146
"""
Thread-safe in-memory store for user data.
Invariants:
- name_key: name -> id
- db: id -> info (dict)
- All public methods acquire self.lock
"""
import threading
class Store:
def __init__(self):
self.next_id = 1
self.db = {} ##{id : info}
self.name_key={} ##{name : id}
self.lock = threading.Lock()
def count(self) -> int:
with self.lock:
return len(self.name_key)
def clear(self) -> None:
with self.lock:
self.next_id = 1
self.db.clear()
self.name_key.clear()
def exists(self, name) -> bool:
if not isinstance(name, str) or not name.strip():
return False
with self.lock:
return name in self.name_key
def _validate_name(self, name) -> None:
if not isinstance(name, str) or not name.strip():
raise TypeError("Name must be a non-empty string")
def get_user_info(self, name) -> dict:
with self.lock:
self._validate_name(name)
if name not in self.name_key:
raise KeyError("User not found.")
key = self.name_key[name]
return self.db[key]
def get_key(self, name) -> int:
with self.lock:
self._validate_name(name)
if name not in self.name_key:
raise KeyError("User not found.")
return self.name_key[name]
def post_user_info(self, name, info) -> int:
with self.lock:
self._validate_name(name)
if not isinstance(info, dict):
raise TypeError("User data must be a dictionary")
if name in self.name_key:
raise KeyError("User already exists.")
new_id = self.next_id
self.next_id += 1
self.name_key[name] = new_id
self.db[new_id] = info
return new_id
def put_user_info(self, name, replace) -> dict:
with self.lock:
self._validate_name(name)
if name not in self.name_key:
raise KeyError("User not found.")
key = self.name_key[name]
if not isinstance(replace, dict):
raise TypeError("User data must be a dictionary")
self.db[key] = replace
return self.db[key]
def patch_user_info(self, name, change) -> dict:
with self.lock:
self._validate_name(name)
if name not in self.name_key:
raise KeyError("User not found.")
key = self.name_key[name]
if not isinstance(change, dict):
raise TypeError("Patch data must be a dictionary")
self.db[key].update(change)
return self.db[key]
def delete_user_info(self, name) -> dict:
with self.lock:
self._validate_name(name)
if name not in self.name_key:
raise KeyError("User not found.")
delete_id = self.name_key[name]
delete_info = self.db[delete_id]
del self.db[delete_id]
del self.name_key[name]
return delete_info
def list_users(self) -> list[str]:
with self.lock:
return sorted(self.name_key.keys())
def _print_name_key(self):
with self.lock:
name_key_copy = self.name_key.copy()
print("\nName : Key Report:\n")
print("------------------\n")
for name in sorted(name_key_copy):
print(f"{name} : {name_key_copy[name]}\n")
def _print_db(self):
with self.lock:
db_copy = self.db.copy()
print("\nID : Info Report:\n")
print("------------------\n")
for user_id in sorted(db_copy):
print(f"{user_id} : {db_copy[user_id]}\n")