Skip to content

Commit 1dc4dc7

Browse files
committed
Adding /figures support
1 parent 52493cb commit 1dc4dc7

File tree

5 files changed

+244
-7
lines changed

5 files changed

+244
-7
lines changed

arangoasync/collection.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
)
1818
from arangoasync.exceptions import (
1919
CollectionPropertiesError,
20+
CollectionStatisticsError,
2021
CollectionTruncateError,
2122
DocumentCountError,
2223
DocumentDeleteError,
@@ -41,6 +42,7 @@
4142
from arangoasync.serialization import Deserializer, Serializer
4243
from arangoasync.typings import (
4344
CollectionProperties,
45+
CollectionStatistics,
4446
IndexProperties,
4547
Json,
4648
Jsons,
@@ -552,7 +554,10 @@ async def count(self) -> Result[int]:
552554
553555
Raises:
554556
DocumentCountError: If retrieval fails.
555-
"""
557+
558+
References:
559+
- `get-the-document-count-of-a-collection <https://docs.arangodb.com/stable/develop/http-api/collections/#get-the-document-count-of-a-collection>`__
560+
""" # noqa: E501
556561
request = Request(
557562
method=Method.GET, endpoint=f"/_api/collection/{self.name}/count"
558563
)
@@ -565,6 +570,30 @@ def response_handler(resp: Response) -> int:
565570

566571
return await self._executor.execute(request, response_handler)
567572

573+
async def statistics(self) -> Result[CollectionStatistics]:
574+
"""Get additional statistical information about the collection.
575+
576+
Returns:
577+
CollectionStatistics: Collection statistics.
578+
579+
Raises:
580+
CollectionStatisticsError: If retrieval fails.
581+
582+
References:
583+
- `get-the-collection-statistics <https://docs.arangodb.com/stable/develop/http-api/collections/#get-the-collection-statistics>`__
584+
""" # noqa: E501
585+
request = Request(
586+
method=Method.GET,
587+
endpoint=f"/_api/collection/{self.name}/figures",
588+
)
589+
590+
def response_handler(resp: Response) -> CollectionStatistics:
591+
if not resp.is_success:
592+
raise CollectionStatisticsError(resp, request)
593+
return CollectionStatistics(self.deserializer.loads(resp.raw_body))
594+
595+
return await self._executor.execute(request, response_handler)
596+
568597
async def has(
569598
self,
570599
document: str | Json,

arangoasync/exceptions.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ class CollectionPropertiesError(ArangoServerError):
195195
"""Failed to retrieve collection properties."""
196196

197197

198+
class CollectionStatisticsError(ArangoServerError):
199+
"""Failed to retrieve collection statistics."""
200+
201+
202+
class CollectionTruncateError(ArangoServerError):
203+
"""Failed to truncate collection."""
204+
205+
198206
class ClientConnectionAbortedError(ArangoClientError):
199207
"""The connection was aborted."""
200208

@@ -203,10 +211,6 @@ class ClientConnectionError(ArangoClientError):
203211
"""The request was unable to reach the server."""
204212

205213

206-
class CollectionTruncateError(ArangoServerError):
207-
"""Failed to truncate collection."""
208-
209-
210214
class CursorCloseError(ArangoServerError):
211215
"""Failed to delete the cursor result from server."""
212216

arangoasync/typings.py

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,6 @@ def compatibility_formatter(data: Json) -> Json:
791791
result["deleted"] = data["deleted"]
792792
if "syncByRevision" in data:
793793
result["sync_by_revision"] = data["syncByRevision"]
794-
if "tempObjectId" in data:
795-
result["temp_object_id"] = data["tempObjectId"]
796794
if "usesRevisionsAsDocumentIds" in data:
797795
result["rev_as_id"] = data["usesRevisionsAsDocumentIds"]
798796
if "isDisjoint" in data:
@@ -819,6 +817,146 @@ def format(self, formatter: Optional[Formatter] = None) -> Json:
819817
return self.compatibility_formatter(self._data)
820818

821819

820+
class CollectionStatistics(JsonWrapper):
821+
"""Statistical information about the collection.
822+
823+
Example:
824+
.. code-block:: json
825+
826+
{
827+
"figures" : {
828+
"indexes" : {
829+
"count" : 1,
830+
"size" : 1234
831+
},
832+
"documentsSize" : 5601,
833+
"cacheInUse" : false,
834+
"cacheSize" : 0,
835+
"cacheUsage" : 0,
836+
"engine" : {
837+
"documents" : 1,
838+
"indexes" : [
839+
{
840+
"type" : "primary",
841+
"id" : 0,
842+
"count" : 1
843+
}
844+
]
845+
}
846+
},
847+
"writeConcern" : 1,
848+
"waitForSync" : false,
849+
"usesRevisionsAsDocumentIds" : true,
850+
"syncByRevision" : true,
851+
"statusString" : "loaded",
852+
"id" : "69123",
853+
"isSmartChild" : false,
854+
"schema" : null,
855+
"name" : "products",
856+
"type" : 2,
857+
"status" : 3,
858+
"count" : 1,
859+
"cacheEnabled" : false,
860+
"isSystem" : false,
861+
"internalValidatorType" : 0,
862+
"globallyUniqueId" : "hB7C02EE43DCE/69123",
863+
"keyOptions" : {
864+
"allowUserKeys" : true,
865+
"type" : "traditional",
866+
"lastValue" : 69129
867+
},
868+
"computedValues" : null,
869+
"objectId" : "69124"
870+
}
871+
872+
References:
873+
- `get-the-collection-statistics <https://docs.arangodb.com/stable/develop/http-api/collections/#get-the-collection-statistics>`__
874+
""" # noqa: E501
875+
876+
def __init__(self, data: Json) -> None:
877+
super().__init__(data)
878+
879+
@property
880+
def figures(self) -> Json:
881+
return cast(Json, self._data.get("figures"))
882+
883+
@property
884+
def write_concern(self) -> Optional[int]:
885+
return self._data.get("writeConcern")
886+
887+
@property
888+
def wait_for_sync(self) -> Optional[bool]:
889+
return self._data.get("waitForSync")
890+
891+
@property
892+
def use_revisions_as_document_ids(self) -> Optional[bool]:
893+
return self._data.get("usesRevisionsAsDocumentIds")
894+
895+
@property
896+
def sync_by_revision(self) -> Optional[bool]:
897+
return self._data.get("syncByRevision")
898+
899+
@property
900+
def status_string(self) -> Optional[str]:
901+
return self._data.get("statusString")
902+
903+
@property
904+
def id(self) -> str:
905+
return self._data["id"] # type: ignore[no-any-return]
906+
907+
@property
908+
def is_smart_child(self) -> bool:
909+
return self._data["isSmartChild"] # type: ignore[no-any-return]
910+
911+
@property
912+
def schema(self) -> Optional[Json]:
913+
return self._data.get("schema")
914+
915+
@property
916+
def name(self) -> str:
917+
return self._data["name"] # type: ignore[no-any-return]
918+
919+
@property
920+
def type(self) -> CollectionType:
921+
return CollectionType.from_int(self._data["type"])
922+
923+
@property
924+
def status(self) -> CollectionStatus:
925+
return CollectionStatus.from_int(self._data["status"])
926+
927+
@property
928+
def count(self) -> int:
929+
return self._data["count"] # type: ignore[no-any-return]
930+
931+
@property
932+
def cache_enabled(self) -> Optional[bool]:
933+
return self._data.get("cacheEnabled")
934+
935+
@property
936+
def is_system(self) -> bool:
937+
return self._data["isSystem"] # type: ignore[no-any-return]
938+
939+
@property
940+
def internal_validator_type(self) -> Optional[int]:
941+
return self._data.get("internalValidatorType")
942+
943+
@property
944+
def globally_unique_id(self) -> str:
945+
return self._data["globallyUniqueId"] # type: ignore[no-any-return]
946+
947+
@property
948+
def key_options(self) -> KeyOptions:
949+
return KeyOptions(self._data["keyOptions"])
950+
951+
@property
952+
def computed_values(self) -> Optional[Json]:
953+
return self._data.get("computedValues")
954+
955+
@property
956+
def object_id(self) -> str:
957+
return self._data["objectId"] # type: ignore[no-any-return]
958+
959+
822960
class IndexProperties(JsonWrapper):
823961
"""Properties of an index.
824962

tests/test_collection.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from arangoasync.errno import DATA_SOURCE_NOT_FOUND, INDEX_NOT_FOUND
66
from arangoasync.exceptions import (
77
CollectionPropertiesError,
8+
CollectionStatisticsError,
89
CollectionTruncateError,
910
DocumentCountError,
1011
IndexCreateError,
@@ -30,6 +31,11 @@ async def test_collection_misc_methods(doc_col, bad_col):
3031
assert len(properties.format()) > 1
3132
with pytest.raises(CollectionPropertiesError):
3233
await bad_col.properties()
34+
statistics = await doc_col.statistics()
35+
assert statistics.name == doc_col.name
36+
assert "figures" in statistics
37+
with pytest.raises(CollectionStatisticsError):
38+
await bad_col.statistics()
3339

3440

3541
@pytest.mark.asyncio

tests/test_typings.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from arangoasync.typings import (
44
CollectionInfo,
5+
CollectionStatistics,
56
CollectionStatus,
67
CollectionType,
78
EdgeDefinitionOptions,
@@ -386,3 +387,62 @@ def test_EdgeDefinitionOptions():
386387
)
387388

388389
assert options.satellites == ["col1", "col2"]
390+
391+
392+
def test_CollectionStatistics():
393+
data = {
394+
"figures": {
395+
"indexes": {"count": 1, "size": 1234},
396+
"documentsSize": 5601,
397+
"cacheInUse": False,
398+
"cacheSize": 0,
399+
"cacheUsage": 0,
400+
},
401+
"writeConcern": 1,
402+
"waitForSync": False,
403+
"usesRevisionsAsDocumentIds": True,
404+
"syncByRevision": True,
405+
"statusString": "loaded",
406+
"id": "69123",
407+
"isSmartChild": False,
408+
"schema": None,
409+
"name": "products",
410+
"type": 2,
411+
"status": 3,
412+
"count": 1,
413+
"cacheEnabled": False,
414+
"isSystem": False,
415+
"internalValidatorType": 0,
416+
"globallyUniqueId": "hB7C02EE43DCE/69123",
417+
"keyOptions": {
418+
"allowUserKeys": True,
419+
"type": "traditional",
420+
"lastValue": 69129,
421+
},
422+
"computedValues": None,
423+
"objectId": "69124",
424+
}
425+
426+
stats = CollectionStatistics(data)
427+
428+
assert stats.figures == data["figures"]
429+
assert stats.write_concern == 1
430+
assert stats.wait_for_sync is False
431+
assert stats.use_revisions_as_document_ids is True
432+
assert stats.sync_by_revision is True
433+
assert stats.status_string == "loaded"
434+
assert stats.id == "69123"
435+
assert stats.is_smart_child is False
436+
assert stats.schema is None
437+
assert stats.name == "products"
438+
assert stats.type == CollectionType.DOCUMENT
439+
assert stats.status == CollectionStatus.LOADED
440+
assert stats.count == 1
441+
assert stats.cache_enabled is False
442+
assert stats.is_system is False
443+
assert stats.internal_validator_type == 0
444+
assert stats.globally_unique_id == "hB7C02EE43DCE/69123"
445+
assert isinstance(stats.key_options, KeyOptions)
446+
assert stats.key_options["type"] == "traditional"
447+
assert stats.computed_values is None
448+
assert stats.object_id == "69124"

0 commit comments

Comments
 (0)