scruby 2.0.2__py3-none-any.whl → 2.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scruby/cache.py +4 -3
- scruby/mixins/count.py +1 -1
- scruby/mixins/delete.py +3 -0
- scruby/mixins/find.py +3 -0
- scruby/mixins/keys.py +15 -0
- scruby/mixins/update.py +4 -1
- {scruby-2.0.2.dist-info → scruby-2.0.4.dist-info}/METADATA +33 -31
- {scruby-2.0.2.dist-info → scruby-2.0.4.dist-info}/RECORD +11 -11
- {scruby-2.0.2.dist-info → scruby-2.0.4.dist-info}/WHEEL +0 -0
- {scruby-2.0.2.dist-info → scruby-2.0.4.dist-info}/licenses/GPL-3.0-LICENSE +0 -0
- {scruby-2.0.2.dist-info → scruby-2.0.4.dist-info}/licenses/MIT-LICENSE +0 -0
scruby/cache.py
CHANGED
|
@@ -7,7 +7,7 @@ __all__ = ("DocCache",)
|
|
|
7
7
|
|
|
8
8
|
import string
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any, ClassVar, Literal,
|
|
10
|
+
from typing import Any, ClassVar, Literal, final
|
|
11
11
|
|
|
12
12
|
import orjson
|
|
13
13
|
|
|
@@ -35,8 +35,9 @@ class DocCache:
|
|
|
35
35
|
cls.cache[collection_name] = {
|
|
36
36
|
key: {key: {key: {} for key in hexdigits} for key in hexdigits} for key in hexdigits
|
|
37
37
|
}
|
|
38
|
-
case _
|
|
39
|
-
|
|
38
|
+
case _:
|
|
39
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
40
|
+
raise AssertionError(msg)
|
|
40
41
|
|
|
41
42
|
@classmethod
|
|
42
43
|
def load_cache(cls, subclasses: list[Any]) -> None:
|
scruby/mixins/count.py
CHANGED
scruby/mixins/delete.py
CHANGED
|
@@ -68,6 +68,9 @@ class Delete:
|
|
|
68
68
|
del DocCache.cache[collection_name][branch_number_as_hash[0]][branch_number_as_hash[1]][
|
|
69
69
|
branch_number_as_hash[2]
|
|
70
70
|
][doc_name]
|
|
71
|
+
case _:
|
|
72
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
73
|
+
raise AssertionError(msg)
|
|
71
74
|
else:
|
|
72
75
|
new_state[doc_name] = doc_json
|
|
73
76
|
await leaf_path.write_bytes(orjson.dumps(new_state))
|
scruby/mixins/find.py
CHANGED
|
@@ -68,6 +68,9 @@ class Find:
|
|
|
68
68
|
docs = DocCache.cache[collection_name][branch_number_as_hash[0]][branch_number_as_hash[1]][
|
|
69
69
|
branch_number_as_hash[2]
|
|
70
70
|
]
|
|
71
|
+
case _:
|
|
72
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
73
|
+
raise AssertionError(msg)
|
|
71
74
|
|
|
72
75
|
for _, doc in docs.items():
|
|
73
76
|
if stop_event.is_set():
|
scruby/mixins/keys.py
CHANGED
|
@@ -79,6 +79,9 @@ class Keys:
|
|
|
79
79
|
DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][prepared_key] = doc
|
|
80
80
|
case 5:
|
|
81
81
|
DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][key_as_hash[2]][prepared_key] = doc
|
|
82
|
+
case _:
|
|
83
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
84
|
+
raise AssertionError(msg)
|
|
82
85
|
|
|
83
86
|
@final
|
|
84
87
|
async def update_doc(self, doc: Any) -> None:
|
|
@@ -126,6 +129,9 @@ class Keys:
|
|
|
126
129
|
DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][key_as_hash[2]][
|
|
127
130
|
prepared_key
|
|
128
131
|
] = doc
|
|
132
|
+
case _:
|
|
133
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
134
|
+
raise AssertionError(msg)
|
|
129
135
|
else:
|
|
130
136
|
raise KeyNotExistsError()
|
|
131
137
|
else:
|
|
@@ -162,6 +168,9 @@ class Keys:
|
|
|
162
168
|
return DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]].get(prepared_key)
|
|
163
169
|
case 5:
|
|
164
170
|
return DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][key_as_hash[2]].get(prepared_key)
|
|
171
|
+
case _:
|
|
172
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
173
|
+
raise AssertionError(msg)
|
|
165
174
|
|
|
166
175
|
@final
|
|
167
176
|
def has_key(self, key: str) -> bool:
|
|
@@ -199,6 +208,9 @@ class Keys:
|
|
|
199
208
|
DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][key_as_hash[2]].get(prepared_key)
|
|
200
209
|
is not None
|
|
201
210
|
)
|
|
211
|
+
case _:
|
|
212
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
213
|
+
raise AssertionError(msg)
|
|
202
214
|
return is_exists
|
|
203
215
|
|
|
204
216
|
@final
|
|
@@ -234,6 +246,9 @@ class Keys:
|
|
|
234
246
|
del DocCache.cache[collection_name][key_as_hash[0]][key_as_hash[1]][key_as_hash[2]][
|
|
235
247
|
prepared_key
|
|
236
248
|
]
|
|
249
|
+
case _:
|
|
250
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
251
|
+
raise AssertionError(msg)
|
|
237
252
|
else:
|
|
238
253
|
raise KeyNotExistsError()
|
|
239
254
|
else:
|
scruby/mixins/update.py
CHANGED
|
@@ -74,6 +74,9 @@ class Update:
|
|
|
74
74
|
DocCache.cache[collection_name][branch_number_as_hash[0]][branch_number_as_hash[1]][
|
|
75
75
|
branch_number_as_hash[2]
|
|
76
76
|
][doc_name] = doc
|
|
77
|
+
case _:
|
|
78
|
+
msg = "Scruby.run() > Parameter: `hash_reduce_left` -> Valid values are Literal[7, 6, 5]."
|
|
79
|
+
raise AssertionError(msg)
|
|
77
80
|
# Update counter
|
|
78
81
|
counter += 1
|
|
79
82
|
else:
|
|
@@ -88,7 +91,7 @@ class Update:
|
|
|
88
91
|
new_data: dict[str, Any],
|
|
89
92
|
filter_fn: Callable = lambda _: True,
|
|
90
93
|
) -> int:
|
|
91
|
-
"""Asynchronous method for updates
|
|
94
|
+
"""Asynchronous method for updates one or more documents matching the filter.
|
|
92
95
|
|
|
93
96
|
Attention:
|
|
94
97
|
- For a complex case, a custom task may be needed.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scruby
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: Asynchronous library for building and managing a hybrid database, by scheme of key-value.
|
|
5
5
|
Project-URL: Bug Tracker, https://github.com/kebasyaty/scruby/issues
|
|
6
6
|
Project-URL: Changelog, https://github.com/kebasyaty/scruby/blob/v2/CHANGELOG.md
|
|
@@ -96,6 +96,10 @@ Description-Content-Type: text/markdown
|
|
|
96
96
|
6 = 256 branches in collection -> ~256000+ docs (for small projects).
|
|
97
97
|
<br>
|
|
98
98
|
5 = 4096 branches in collection -> ~4096000+ docs (for large projects).
|
|
99
|
+
<br>
|
|
100
|
+
<br>
|
|
101
|
+
<b>If you notice the production server slowing down,</b><br>
|
|
102
|
+
<b>you will need to add RAM and CPU.</b>
|
|
99
103
|
</p>
|
|
100
104
|
|
|
101
105
|
<br>
|
|
@@ -137,7 +141,6 @@ from typing import Annotated
|
|
|
137
141
|
from pydantic import EmailStr, Field
|
|
138
142
|
from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator
|
|
139
143
|
from scruby import Scruby, ScrubyModel, ScrubyConfig
|
|
140
|
-
from pprint import pprint as pp
|
|
141
144
|
|
|
142
145
|
|
|
143
146
|
class User(ScrubyModel):
|
|
@@ -180,7 +183,6 @@ async def main() -> None:
|
|
|
180
183
|
|
|
181
184
|
# Get user details
|
|
182
185
|
user = user_coll.get_doc("+447986123456")
|
|
183
|
-
pp(user)
|
|
184
186
|
user_coll.get_doc("key missing") # => None
|
|
185
187
|
|
|
186
188
|
# Check for the presence of a key in the collection
|
|
@@ -189,6 +191,21 @@ async def main() -> None:
|
|
|
189
191
|
# Delete a document by key
|
|
190
192
|
await user_coll.delete_doc("+447986123456")
|
|
191
193
|
|
|
194
|
+
# Get collection name
|
|
195
|
+
user_coll.collection_name() # => User
|
|
196
|
+
|
|
197
|
+
# Get collection list
|
|
198
|
+
coll_list = await Scruby.collection_list() # => ["User"]
|
|
199
|
+
|
|
200
|
+
# Get the number of documents in the collection from metadata
|
|
201
|
+
await user_coll.estimated_document_count() # => 1
|
|
202
|
+
|
|
203
|
+
# Get the number of documents comparable to the filter
|
|
204
|
+
user_coll.count_documents(filter_fn=lambda doc: doc.first_name == "John") == 1
|
|
205
|
+
|
|
206
|
+
# Delete collection
|
|
207
|
+
await Scruby.delete_collection("User")
|
|
208
|
+
|
|
192
209
|
# Full database deletion
|
|
193
210
|
# Hint: The main purpose is tests
|
|
194
211
|
Scruby.napalm()
|
|
@@ -208,7 +225,6 @@ The search effectiveness depends on the number of processor threads.
|
|
|
208
225
|
import anyio
|
|
209
226
|
from pydantic import Field
|
|
210
227
|
from scruby import ReturnType, Scruby, ScrubyConfig, ScrubyModel
|
|
211
|
-
from pprint import pprint as pp
|
|
212
228
|
|
|
213
229
|
|
|
214
230
|
class Phone(ScrubyModel):
|
|
@@ -248,19 +264,11 @@ async def main() -> None:
|
|
|
248
264
|
phone_details: Phone | None = phone_coll.find_one(
|
|
249
265
|
filter_fn=lambda doc: doc.brand == "Samsung",
|
|
250
266
|
)
|
|
251
|
-
if phone_details is not None:
|
|
252
|
-
pp(phone_details)
|
|
253
|
-
else:
|
|
254
|
-
print("No Phone!")
|
|
255
267
|
|
|
256
268
|
# Find phone by model
|
|
257
269
|
phone_details: Phone | None = phone_coll.find_one(
|
|
258
270
|
filter_fn=lambda doc: doc.model == "Galaxy A26",
|
|
259
271
|
)
|
|
260
|
-
if phone_details is not None:
|
|
261
|
-
pp(phone_details)
|
|
262
|
-
else:
|
|
263
|
-
print("No Phone!")
|
|
264
272
|
|
|
265
273
|
# Return phone in JSON format
|
|
266
274
|
phone_details: str | None = phone_coll.find_one(
|
|
@@ -268,7 +276,7 @@ async def main() -> None:
|
|
|
268
276
|
return_type=ReturnType.JSON,
|
|
269
277
|
)
|
|
270
278
|
|
|
271
|
-
# Return phone in
|
|
279
|
+
# Return phone in Dictionary format
|
|
272
280
|
phone_details: dict | None = phone_coll.find_one(
|
|
273
281
|
filter_fn=lambda doc: doc.model == "Galaxy A26",
|
|
274
282
|
return_type=ReturnType.DICT,
|
|
@@ -294,7 +302,6 @@ import anyio
|
|
|
294
302
|
from typing import Annotated
|
|
295
303
|
from pydantic import Field
|
|
296
304
|
from scruby import ReturnType, Scruby, ScrubyConfig, ScrubyModel
|
|
297
|
-
from pprint import pprint as pp
|
|
298
305
|
|
|
299
306
|
|
|
300
307
|
class Car(ScrubyModel):
|
|
@@ -331,19 +338,11 @@ async def main() -> None:
|
|
|
331
338
|
|
|
332
339
|
# Find all cars
|
|
333
340
|
car_list: list[Car] | None = car_coll.find_many()
|
|
334
|
-
if car_list is not None:
|
|
335
|
-
pp(car_list)
|
|
336
|
-
else:
|
|
337
|
-
print("No cars!")
|
|
338
341
|
|
|
339
342
|
# Find cars by brand and year
|
|
340
343
|
car_list: list[Car] | None = car_coll.find_many(
|
|
341
344
|
filter_fn=lambda doc: doc.brand == "Mazda" and doc.year == 2025,
|
|
342
345
|
)
|
|
343
|
-
if car_list is not None:
|
|
344
|
-
pp(car_list)
|
|
345
|
-
else:
|
|
346
|
-
print("No cars!")
|
|
347
346
|
|
|
348
347
|
# Pagination
|
|
349
348
|
car_list: list[Car] | None = car_coll.find_many(
|
|
@@ -351,10 +350,6 @@ async def main() -> None:
|
|
|
351
350
|
limit_docs=5,
|
|
352
351
|
page_number=2,
|
|
353
352
|
)
|
|
354
|
-
if car_list is not None:
|
|
355
|
-
pp(car_list)
|
|
356
|
-
else:
|
|
357
|
-
print("No cars!")
|
|
358
353
|
|
|
359
354
|
# Sorting
|
|
360
355
|
car_list: list[Car] | None = car_coll.find_many(
|
|
@@ -362,10 +357,6 @@ async def main() -> None:
|
|
|
362
357
|
sort_fn=lambda doc: (doc.brand, doc.updated_at),
|
|
363
358
|
sort_reverse=True,
|
|
364
359
|
)
|
|
365
|
-
if car_list is not None:
|
|
366
|
-
pp(car_list)
|
|
367
|
-
else:
|
|
368
|
-
print("No cars!")
|
|
369
360
|
|
|
370
361
|
# Return cars in JSON format
|
|
371
362
|
car_list: str | None = car_coll.find_many(
|
|
@@ -373,12 +364,23 @@ async def main() -> None:
|
|
|
373
364
|
return_type=ReturnType.JSON,
|
|
374
365
|
)
|
|
375
366
|
|
|
376
|
-
# Return cars in
|
|
367
|
+
# Return cars in Dictionary format
|
|
377
368
|
car_list: list[dict] | None = car_coll.find_many(
|
|
378
369
|
filter_fn=lambda doc: doc.brand == "Mazda",
|
|
379
370
|
return_type=ReturnType.DICT,
|
|
380
371
|
)
|
|
381
372
|
|
|
373
|
+
# Update one or more documents matching the filter
|
|
374
|
+
count_updated = await car_coll.update_many(
|
|
375
|
+
new_data={"brand": "BMW"},
|
|
376
|
+
filter_fn=lambda doc: doc.brand == "Mazda",
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# Delete one or more documents matching the filter
|
|
380
|
+
count_deleted = await car_coll.delete_many(
|
|
381
|
+
filter_fn=lambda doc: doc.brand == "BMW",
|
|
382
|
+
)
|
|
383
|
+
|
|
382
384
|
# Full database deletion
|
|
383
385
|
# Hint: The main purpose is tests
|
|
384
386
|
Scruby.napalm()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
scruby/__init__.py,sha256=40UhjME7WRJ-kHmqju4tMx9t1t6Sq6-EtL1LwgbTbcA,1280
|
|
2
2
|
scruby/aggregation.py,sha256=NBFxQqyRqUG2KIuD9fbl4uzSHJWTaskjiZ1YNBa-Zbo,3575
|
|
3
|
-
scruby/cache.py,sha256=
|
|
3
|
+
scruby/cache.py,sha256=Et3NpeMDCNHa2B8H1El4QwIrlW4Cysf3ODeqkR2rGO4,3387
|
|
4
4
|
scruby/config.py,sha256=RzCk4oLO4LeTQEuNljWKh9QxQ-6-mXmUpn9AmlpISCU,3514
|
|
5
5
|
scruby/db.py,sha256=np6WFjjlXrDnA5nwRDb7Nscwvvn4r2CXvydXnRWeSS0,10194
|
|
6
6
|
scruby/errors.py,sha256=lTWiHzyO5Es9Nkf7quODJjONGn6ifcL95qlpA4epQQM,1386
|
|
@@ -8,14 +8,14 @@ scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
8
8
|
scruby/utils.py,sha256=ZwWxSyh_BAOQkXlIqXFOlX2lHVk9rfYGQiVqtTk8PpE,1865
|
|
9
9
|
scruby/mixins/__init__.py,sha256=nT79e80zXliuTGhR9CFosI2-3PQUCKwXbR7wPiFwgrU,669
|
|
10
10
|
scruby/mixins/collection.py,sha256=VrFadQimpWLHaNcmS-dl6CC94CiOE2w_crxewOdZfvQ,1741
|
|
11
|
-
scruby/mixins/count.py,sha256=
|
|
11
|
+
scruby/mixins/count.py,sha256=1tcQVxIxjlMNDG2XbI9QHKNjo5FbMlezIA80l0UE3Ac,2390
|
|
12
12
|
scruby/mixins/custom_task.py,sha256=MCelgM8GNBkO6INaWQ5h5NX53zrgV90QWIZDl8Ygmrw,1412
|
|
13
|
-
scruby/mixins/delete.py,sha256=
|
|
14
|
-
scruby/mixins/find.py,sha256=
|
|
15
|
-
scruby/mixins/keys.py,sha256=
|
|
16
|
-
scruby/mixins/update.py,sha256
|
|
17
|
-
scruby-2.0.
|
|
18
|
-
scruby-2.0.
|
|
19
|
-
scruby-2.0.
|
|
20
|
-
scruby-2.0.
|
|
21
|
-
scruby-2.0.
|
|
13
|
+
scruby/mixins/delete.py,sha256=Q-FPJGm6pqJzoyEdd48M8o_kwYdYWLoceRuzcNXc_uw,4258
|
|
14
|
+
scruby/mixins/find.py,sha256=25LqXTHvzEIsB3KxUYGW-dOL_yYRBx7bVwcO5t9DPgo,8846
|
|
15
|
+
scruby/mixins/keys.py,sha256=kI8F_Q0q_V7FnyQUn7RatRMj4UaBuARY1qxsS8ey8oM,10588
|
|
16
|
+
scruby/mixins/update.py,sha256=syRUy2MvxKcUAjqn9ZTXzl3KGWO2PUbQoI0NeiAW-Bg,4839
|
|
17
|
+
scruby-2.0.4.dist-info/METADATA,sha256=WQQxRqWC5dS__uqQoUN1bdDEBUFsM0HWRim4H93oj2E,13335
|
|
18
|
+
scruby-2.0.4.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
19
|
+
scruby-2.0.4.dist-info/licenses/GPL-3.0-LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
20
|
+
scruby-2.0.4.dist-info/licenses/MIT-LICENSE,sha256=mS0Wz0yGNB63gEcWEnuIb_lldDYV0sjRaO-o_GL6CWE,1074
|
|
21
|
+
scruby-2.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|