scruby 0.7.2__py3-none-any.whl → 0.8.1__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.
Potentially problematic release.
This version of scruby might be problematic. Click here for more details.
scruby/db.py
CHANGED
|
@@ -229,7 +229,54 @@ class Scruby[T]:
|
|
|
229
229
|
db_root,
|
|
230
230
|
class_model,
|
|
231
231
|
)
|
|
232
|
-
|
|
233
|
-
if
|
|
234
|
-
return
|
|
232
|
+
doc = future.result(timeout)
|
|
233
|
+
if doc is not None:
|
|
234
|
+
return doc
|
|
235
235
|
return None
|
|
236
|
+
|
|
237
|
+
def find_many(
|
|
238
|
+
self,
|
|
239
|
+
filter_fn: Callable,
|
|
240
|
+
db_query_docs_limit: int = 1000,
|
|
241
|
+
max_workers: int | None = None,
|
|
242
|
+
timeout: float | None = None,
|
|
243
|
+
) -> list[T] | None:
|
|
244
|
+
"""Find documents.
|
|
245
|
+
|
|
246
|
+
The search is based on the effect of a quantum loop.
|
|
247
|
+
The search effectiveness depends on the number of processor threads.
|
|
248
|
+
Ideally, hundreds and even thousands of threads are required.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
filter_fn: A function that execute the conditions of filtering.
|
|
252
|
+
db_query_docs_limit: Limiting the number of request results. By default = 1000.
|
|
253
|
+
max_workers: The maximum number of processes that can be used to
|
|
254
|
+
execute the given calls. If None or not given then as many
|
|
255
|
+
worker processes will be created as the machine has processors.
|
|
256
|
+
timeout: The number of seconds to wait for the result if the future isn't done.
|
|
257
|
+
If None, then there is no limit on the wait time.
|
|
258
|
+
"""
|
|
259
|
+
keys: range = range(1, self.__max_num_keys)
|
|
260
|
+
search_task_fn: Callable = self.search_task
|
|
261
|
+
length_reduction_hash: int = self.__length_reduction_hash
|
|
262
|
+
db_root: str = self.__db_root
|
|
263
|
+
class_model: T = self.__class_model
|
|
264
|
+
counter: int = 0
|
|
265
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers) as executor:
|
|
266
|
+
results = []
|
|
267
|
+
for key in keys:
|
|
268
|
+
if counter == db_query_docs_limit:
|
|
269
|
+
break
|
|
270
|
+
future = executor.submit(
|
|
271
|
+
search_task_fn,
|
|
272
|
+
key,
|
|
273
|
+
filter_fn,
|
|
274
|
+
length_reduction_hash,
|
|
275
|
+
db_root,
|
|
276
|
+
class_model,
|
|
277
|
+
)
|
|
278
|
+
doc = future.result(timeout)
|
|
279
|
+
if doc is not None:
|
|
280
|
+
results.append(doc)
|
|
281
|
+
counter += 1
|
|
282
|
+
return results or None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scruby
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: A fast key-value storage library.
|
|
5
5
|
Project-URL: Homepage, https://github.com/kebasyaty/scruby
|
|
6
6
|
Project-URL: Repository, https://github.com/kebasyaty/scruby
|
|
@@ -108,8 +108,9 @@ uv add scruby
|
|
|
108
108
|
|
|
109
109
|
import anyio
|
|
110
110
|
import datetime
|
|
111
|
+
from typing import Annotated
|
|
111
112
|
from pydantic import BaseModel, EmailStr
|
|
112
|
-
from pydantic_extra_types.phone_numbers import PhoneNumber
|
|
113
|
+
from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator
|
|
113
114
|
from scruby import Scruby, constants
|
|
114
115
|
|
|
115
116
|
constants.DB_ROOT = "ScrubyDB" # By default = "ScrubyDB"
|
|
@@ -120,7 +121,7 @@ class User(BaseModel):
|
|
|
120
121
|
last_name: str
|
|
121
122
|
birthday: datetime.datetime
|
|
122
123
|
email: EmailStr
|
|
123
|
-
phone: PhoneNumber
|
|
124
|
+
phone: Annotated[PhoneNumber, PhoneNumberValidator(number_format="E164")]
|
|
124
125
|
|
|
125
126
|
async def main() -> None:
|
|
126
127
|
"""Example."""
|
|
@@ -165,8 +166,9 @@ Ideally, hundreds and even thousands of threads are required.
|
|
|
165
166
|
|
|
166
167
|
import anyio
|
|
167
168
|
import datetime
|
|
169
|
+
from typing import Annotated
|
|
168
170
|
from pydantic import BaseModel, EmailStr
|
|
169
|
-
from pydantic_extra_types.phone_numbers import PhoneNumber
|
|
171
|
+
from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator
|
|
170
172
|
from scruby import Scruby, constants
|
|
171
173
|
from pprint import pprint as pp
|
|
172
174
|
|
|
@@ -180,7 +182,7 @@ class User(BaseModel):
|
|
|
180
182
|
last_name: str
|
|
181
183
|
birthday: datetime.datetime
|
|
182
184
|
email: EmailStr
|
|
183
|
-
phone: PhoneNumber
|
|
185
|
+
phone: Annotated[PhoneNumber, PhoneNumberValidator(number_format="E164")]
|
|
184
186
|
|
|
185
187
|
async def main() -> None:
|
|
186
188
|
"""Example."""
|
|
@@ -225,6 +227,67 @@ if __name__ == "__main__":
|
|
|
225
227
|
anyio.run(main)
|
|
226
228
|
```
|
|
227
229
|
|
|
230
|
+
```python
|
|
231
|
+
"""Find documents.
|
|
232
|
+
|
|
233
|
+
The search is based on the effect of a quantum loop.
|
|
234
|
+
The search effectiveness depends on the number of processor threads.
|
|
235
|
+
Ideally, hundreds and even thousands of threads are required.
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
import anyio
|
|
239
|
+
import datetime
|
|
240
|
+
from typing import Annotated
|
|
241
|
+
from pydantic import BaseModel, EmailStr
|
|
242
|
+
from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator
|
|
243
|
+
from scruby import Scruby, constants
|
|
244
|
+
from pprint import pprint as pp
|
|
245
|
+
|
|
246
|
+
constants.DB_ROOT = "ScrubyDB" # By default = "ScrubyDB"
|
|
247
|
+
constants.LENGTH_REDUCTION_HASH = 6 # 256 branches in collection
|
|
248
|
+
# (main purpose is tests).
|
|
249
|
+
|
|
250
|
+
class User(BaseModel):
|
|
251
|
+
"""Model of User."""
|
|
252
|
+
first_name: str
|
|
253
|
+
last_name: str
|
|
254
|
+
birthday: datetime.datetime
|
|
255
|
+
email: EmailStr
|
|
256
|
+
phone: Annotated[PhoneNumber, PhoneNumberValidator(number_format="E164")]
|
|
257
|
+
|
|
258
|
+
async def main() -> None:
|
|
259
|
+
"""Example."""
|
|
260
|
+
# Get collection of `User`.
|
|
261
|
+
user_coll = Scruby(User)
|
|
262
|
+
|
|
263
|
+
# Create users.
|
|
264
|
+
for num in range(1, 10):
|
|
265
|
+
user = User(
|
|
266
|
+
first_name="John",
|
|
267
|
+
last_name="Smith",
|
|
268
|
+
birthday=datetime.datetime(1970, 1, num),
|
|
269
|
+
email=f"John_Smith_{num}@gmail.com",
|
|
270
|
+
phone=f"+44798612345{num}",
|
|
271
|
+
)
|
|
272
|
+
await db.set_key(f"+44798612345{num}", user)
|
|
273
|
+
|
|
274
|
+
# Find users by email.
|
|
275
|
+
users: list[User] | None = user_coll.find_many(
|
|
276
|
+
filter_fn=lambda doc: doc.email == "John_Smith_5@gmail.com" or doc.email == "John_Smith_8@gmail.com",
|
|
277
|
+
)
|
|
278
|
+
if users is not None:
|
|
279
|
+
pp(users)
|
|
280
|
+
else:
|
|
281
|
+
print("No users!")
|
|
282
|
+
|
|
283
|
+
# Full database deletion.
|
|
284
|
+
# Hint: The main purpose is tests.
|
|
285
|
+
await Scruby.napalm()
|
|
286
|
+
|
|
287
|
+
if __name__ == "__main__":
|
|
288
|
+
anyio.run(main)
|
|
289
|
+
```
|
|
290
|
+
|
|
228
291
|
## Changelog
|
|
229
292
|
|
|
230
293
|
[View the change history](https://github.com/kebasyaty/scruby/blob/v0/CHANGELOG.md "Changelog").
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
scruby/__init__.py,sha256=myX7sG-7oAQZGdgfZtTGXYCCraTeuwi7SjBoltftpnM,648
|
|
2
|
+
scruby/constants.py,sha256=GbB-O0qaVdi5EHUp-zRAppFXLR-oHxpXUFVAOCpS0C8,1022
|
|
3
|
+
scruby/db.py,sha256=FWCrcpzP93V1fk7NXhp6x2UgGkwqvk7qXvphm38R0X8,10130
|
|
4
|
+
scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
scruby-0.8.1.dist-info/METADATA,sha256=TpqA2Ukl-TnolmTr-mRTRIFGE2KcKdzm8tLP1xRWKFM,10632
|
|
6
|
+
scruby-0.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
scruby-0.8.1.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
|
|
8
|
+
scruby-0.8.1.dist-info/RECORD,,
|
scruby-0.7.2.dist-info/RECORD
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
scruby/__init__.py,sha256=myX7sG-7oAQZGdgfZtTGXYCCraTeuwi7SjBoltftpnM,648
|
|
2
|
-
scruby/constants.py,sha256=GbB-O0qaVdi5EHUp-zRAppFXLR-oHxpXUFVAOCpS0C8,1022
|
|
3
|
-
scruby/db.py,sha256=84DRrw21jiAmEsxjOOJnAfFvfE8hNdaJ-TB9BQtM0CQ,8114
|
|
4
|
-
scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
scruby-0.7.2.dist-info/METADATA,sha256=b_02kOWP7dScGNwKtvVwQrv7CPiIHHIJ33OxMMz5Ink,8673
|
|
6
|
-
scruby-0.7.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
-
scruby-0.7.2.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
|
|
8
|
-
scruby-0.7.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|