scruby 0.10.0__py3-none-any.whl → 0.10.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
@@ -6,13 +6,12 @@ __all__ = ("Scruby",)
6
6
 
7
7
  import concurrent.futures
8
8
  import contextlib
9
- import datetime
10
9
  import logging
11
10
  import zlib
12
11
  from collections.abc import Callable
13
12
  from pathlib import Path as SyncPath
14
13
  from shutil import rmtree
15
- from typing import Any, Never, TypeVar, assert_never
14
+ from typing import Any, Literal, Never, TypeVar, assert_never
16
15
 
17
16
  import orjson
18
17
  from anyio import Path, to_thread
@@ -26,11 +25,9 @@ T = TypeVar("T")
26
25
 
27
26
 
28
27
  class _Meta(BaseModel):
29
- """Metadata of collection."""
28
+ """Metadata of Collection."""
30
29
 
31
- count_documents: int
32
- created_at: datetime.datetime
33
- updated_at: datetime.datetime
30
+ counter_documents: int
34
31
 
35
32
 
36
33
  class Scruby[T]:
@@ -83,9 +80,7 @@ class Scruby[T]:
83
80
  if not branch_path.exists():
84
81
  branch_path.mkdir(parents=True)
85
82
  meta = _Meta(
86
- count_documents=0,
87
- created_at=datetime.datetime.now(), # noqa: DTZ005
88
- updated_at=datetime.datetime.now(), # noqa: DTZ005
83
+ counter_documents=0,
89
84
  )
90
85
  meta_json = meta.model_dump_json()
91
86
  meta_path = SyncPath(*(branch_path, "meta.json"))
@@ -127,6 +122,17 @@ class Scruby[T]:
127
122
  meta_json = meta.model_dump_json()
128
123
  await meta_path.write_text(meta_json, "utf-8")
129
124
 
125
+ async def _counter_documents(self, step: Literal[1, -1]) -> None:
126
+ """Management of documents in metadata of collection.
127
+
128
+ This method is for internal use.
129
+ """
130
+ meta = await self._get_meta()
131
+ meta.counter_documents += step
132
+ if meta.counter_documents < 0:
133
+ meta.counter_documents = 0
134
+ await self._set_meta(meta)
135
+
130
136
  async def _get_leaf_path(self, key: str) -> Path:
131
137
  """Asynchronous method for getting path to collection cell by key.
132
138
 
@@ -179,11 +185,14 @@ class Scruby[T]:
179
185
  # Add new key or update existing.
180
186
  data_json: bytes = await leaf_path.read_bytes()
181
187
  data: dict = orjson.loads(data_json) or {}
188
+ if data.get(key) is None:
189
+ await self._counter_documents(1)
182
190
  data[key] = value_json
183
191
  await leaf_path.write_bytes(orjson.dumps(data))
184
192
  else:
185
193
  # Add new key to a blank leaf.
186
194
  await leaf_path.write_bytes(orjson.dumps({key: value_json}))
195
+ await self._counter_documents(1)
187
196
 
188
197
  async def get_key(self, key: str) -> T:
189
198
  """Asynchronous method for getting value of key from collection.
@@ -236,6 +245,7 @@ class Scruby[T]:
236
245
  data: dict = orjson.loads(data_json) or {}
237
246
  del data[key]
238
247
  await leaf_path.write_bytes(orjson.dumps(data))
248
+ await self._counter_documents(-1)
239
249
  return
240
250
  msg: str = "`delete_key` - The unacceptable key value."
241
251
  logger.error(msg)
@@ -379,3 +389,8 @@ class Scruby[T]:
379
389
  def collection_full_name(self) -> str:
380
390
  """Get full name of collection."""
381
391
  return f"{self.__db_root}/{self.__class_model.__name__}"
392
+
393
+ async def estimated_document_count(self) -> int:
394
+ """Get an estimate of the number of documents in this collection using collection metadata."""
395
+ meta = await self._get_meta()
396
+ return meta.counter_documents
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scruby
3
- Version: 0.10.0
3
+ Version: 0.10.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
@@ -0,0 +1,8 @@
1
+ scruby/__init__.py,sha256=wFwUS1KcLxfIopXOVS8gPue9fNzIIU2cVj_RgK5drz4,849
2
+ scruby/constants.py,sha256=GbB-O0qaVdi5EHUp-zRAppFXLR-oHxpXUFVAOCpS0C8,1022
3
+ scruby/db.py,sha256=d4fVb4JhGaBU_YPxByT156UGHQPTwzSizBqOpCNhW8Y,14159
4
+ scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ scruby-0.10.1.dist-info/METADATA,sha256=k2AaJn-JijNceNIB7s13D1cB3jr4p4mW6R1z7IuXp4g,10829
6
+ scruby-0.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ scruby-0.10.1.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
8
+ scruby-0.10.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- scruby/__init__.py,sha256=wFwUS1KcLxfIopXOVS8gPue9fNzIIU2cVj_RgK5drz4,849
2
- scruby/constants.py,sha256=GbB-O0qaVdi5EHUp-zRAppFXLR-oHxpXUFVAOCpS0C8,1022
3
- scruby/db.py,sha256=kwF1X_HB2CaNGNY0DVrC6s8OQ5Iix1azQOmfA_10JBo,13563
4
- scruby/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- scruby-0.10.0.dist-info/METADATA,sha256=seuAAwZHI-iso9O4durUh4dSye1KQrSZ8MjTkyOvCq8,10829
6
- scruby-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- scruby-0.10.0.dist-info/licenses/LICENSE,sha256=2zZINd6m_jNYlowdQImlEizyhSui5cBAJZRhWQURcEc,1095
8
- scruby-0.10.0.dist-info/RECORD,,