Skip to content

Commit 19307d5

Browse files
committed
Adding truncate and count operations
1 parent 1cd09d3 commit 19307d5

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

arangoasync/collection.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
)
1212
from arangoasync.exceptions import (
1313
CollectionPropertiesError,
14+
CollectionTruncateError,
15+
DocumentCountError,
1416
DocumentDeleteError,
1517
DocumentGetError,
1618
DocumentInsertError,
@@ -392,6 +394,66 @@ def response_handler(resp: Response) -> CollectionProperties:
392394

393395
return await self._executor.execute(request, response_handler)
394396

397+
async def truncate(
398+
self,
399+
wait_for_sync: Optional[bool] = None,
400+
compact: Optional[bool] = None,
401+
) -> None:
402+
"""Removes all documents, but leaves indexes intact.
403+
404+
Args:
405+
wait_for_sync (bool | None): If set to `True`, the data is synchronized
406+
to disk before returning from the truncate operation.
407+
compact (bool | None): If set to `True`, the storage engine is told to
408+
start a compaction in order to free up disk space. This can be
409+
resource intensive. If the only intention is to start over with an
410+
empty collection, specify `False`.
411+
412+
Raises:
413+
CollectionTruncateError: If truncation fails.
414+
415+
References:
416+
- `truncate-a-collection <https://docs.arangodb.com/stable/develop/http-api/collections/#truncate-a-collection>`__
417+
""" # noqa: E501
418+
params: Params = {}
419+
if wait_for_sync is not None:
420+
params["waitForSync"] = wait_for_sync
421+
if compact is not None:
422+
params["compact"] = compact
423+
424+
request = Request(
425+
method=Method.PUT,
426+
endpoint=f"/_api/collection/{self.name}/truncate",
427+
params=params,
428+
)
429+
430+
def response_handler(resp: Response) -> None:
431+
if not resp.is_success:
432+
raise CollectionTruncateError(resp, request)
433+
434+
await self._executor.execute(request, response_handler)
435+
436+
async def count(self) -> Result[int]:
437+
"""Return the total document count.
438+
439+
Returns:
440+
int: Total document count.
441+
442+
Raises:
443+
DocumentCountError: If retrieval fails.
444+
"""
445+
request = Request(
446+
method=Method.GET, endpoint=f"/_api/collection/{self.name}/count"
447+
)
448+
449+
def response_handler(resp: Response) -> int:
450+
if resp.is_success:
451+
result: int = self.deserializer.loads(resp.raw_body)["count"]
452+
return result
453+
raise DocumentCountError(resp, request)
454+
455+
return await self._executor.execute(request, response_handler)
456+
395457
async def get(
396458
self,
397459
document: str | Json,

arangoasync/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ class ClientConnectionError(ArangoClientError):
187187
"""The request was unable to reach the server."""
188188

189189

190+
class CollectionTruncateError(ArangoServerError):
191+
"""Failed to truncate collection."""
192+
193+
190194
class CursorCloseError(ArangoServerError):
191195
"""Failed to delete the cursor result from server."""
192196

@@ -227,6 +231,10 @@ class DeserializationError(ArangoClientError):
227231
"""Failed to deserialize the server response."""
228232

229233

234+
class DocumentCountError(ArangoServerError):
235+
"""Failed to retrieve document count."""
236+
237+
230238
class DocumentDeleteError(ArangoServerError):
231239
"""Failed to delete document."""
232240

tests/test_collection.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from arangoasync.errno import DATA_SOURCE_NOT_FOUND, INDEX_NOT_FOUND
66
from arangoasync.exceptions import (
77
CollectionPropertiesError,
8+
CollectionTruncateError,
9+
DocumentCountError,
810
IndexCreateError,
911
IndexDeleteError,
1012
IndexGetError,
@@ -157,3 +159,26 @@ async def test_collection_index(doc_col, bad_col, cluster):
157159
await doc_col.delete_index(idx1.id)
158160
assert err.value.error_code == INDEX_NOT_FOUND
159161
assert await doc_col.delete_index(idx2.id, ignore_missing=True) is False
162+
163+
164+
@pytest.mark.asyncio
165+
async def test_collection_truncate_count(docs, doc_col, bad_col):
166+
# Test errors
167+
with pytest.raises(CollectionTruncateError):
168+
await bad_col.truncate()
169+
with pytest.raises(DocumentCountError):
170+
await bad_col.count()
171+
172+
# Test regular operations
173+
await asyncio.gather(*[doc_col.insert(doc) for doc in docs])
174+
cnt = await doc_col.count()
175+
assert cnt == len(docs)
176+
177+
await doc_col.truncate()
178+
cnt = await doc_col.count()
179+
assert cnt == 0
180+
181+
await asyncio.gather(*[doc_col.insert(doc) for doc in docs])
182+
await doc_col.truncate(wait_for_sync=True, compact=True)
183+
cnt = await doc_col.count()
184+
assert cnt == 0

0 commit comments

Comments
 (0)