Skip to content

Commit

Permalink
Adds support for the _index endpoint on databases
Browse files Browse the repository at this point in the history
  • Loading branch information
bmario committed Jan 18, 2022
1 parent 49c0486 commit 95eca75
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
15 changes: 15 additions & 0 deletions aiocouch/database.py
Expand Up @@ -221,6 +221,21 @@ async def find(
async for doc in FindRequest(self, selector, limit, **params):
yield doc

async def index(self, index: JsonDict, **kwargs: Any) -> JsonDict:
"""Create a new index on the database
This method allows to use the :ref:`_find<couchdb:api/db/_index>`
endpoint of the database.
This method supports all request paramters listed in
:ref:`_find<couchdb:api/db/_index>`.
:param index: JSON description of the index
:param kwargs: additional parameters, refer to the CouchDB documentation
:return: The response of the CouchDB _index endpoint
"""
return await self._index(index, **kwargs)

@_returns_async_context_manager
def update_docs(
self, ids: List[str] = [], create: bool = False
Expand Down
24 changes: 17 additions & 7 deletions aiocouch/remote.py
Expand Up @@ -211,7 +211,7 @@ async def _put(self, **params: Any) -> JsonDict:

@raises(400, "Invalid database name or forgotten document id by accident")
@raises(401, "CouchDB Server Administrator privileges required")
@raises(404, "Database doesnt exist or invalid database name ({id})")
@raises(404, "Database doesn't exist or invalid database name ({id})")
async def _delete(self) -> None:
await self._remote._delete(self.endpoint)

Expand Down Expand Up @@ -247,6 +247,16 @@ async def _find(self, selector: Any, **data: Any) -> JsonDict:
assert not isinstance(json, bytes)
return json

@raises(400, "Invalid request")
@raises(401, "Admin permission required")
@raises(404, "Database not found")
@raises(500, "Execution error")
async def _index(self, index: JsonDict, **data: Any) -> JsonDict:
data["index"] = index
_, json = await self._remote._post(f"{self.endpoint}/_index", data)
assert not isinstance(json, bytes)
return json

@raises(401, "Invalid credentials")
@raises(403, "Permission required")
async def _get_security(self) -> JsonDict:
Expand Down Expand Up @@ -305,7 +315,7 @@ async def _get(self, **params: Any) -> JsonDict:
@raises(400, "The format of the request or revision was invalid")
@raises(401, "Write privilege required for document '{id}'")
@raises(403, "Write privilege required for document '{id}'")
@raises(404, "Specified database or document ID doesnt exists ({endpoint})")
@raises(404, "Specified database or document ID doesn't exists ({endpoint})")
@raises(
409,
"Document with the specified ID ({id}) already exists or specified revision "
Expand All @@ -319,7 +329,7 @@ async def _put(self, data: JsonDict, **params: Any) -> JsonDict:
@raises(400, "Invalid request body or parameters")
@raises(401, "Write privilege required for document '{id}'")
@raises(403, "Write privilege required for document '{id}'")
@raises(404, "Specified database or document ID doesnt exists ({endpoint})")
@raises(404, "Specified database or document ID doesn't exists ({endpoint})")
@raises(
409, "Specified revision ({rev}) is not the latest for target document '{id}'"
)
Expand All @@ -333,7 +343,7 @@ async def _delete(self, rev: str, **params: Any) -> JsonDict:
@raises(401, "Read or write privileges required")
@raises(403, "Read or write privileges required")
@raises(
404, "Specified database, document ID or revision doesnt exists ({endpoint})"
404, "Specified database, document ID or revision doesn't exists ({endpoint})"
)
@raises(
409,
Expand Down Expand Up @@ -376,7 +386,7 @@ async def _exists(self) -> bool:
@raises(400, "Invalid request parameters")
@raises(401, "Read privilege required for document '{document_id}'")
@raises(403, "Read privilege required for document '{document_id}'")
@raises(404, "Document '{document_id}' or attachment '{id}' doesnt exists")
@raises(404, "Document '{document_id}' or attachment '{id}' doesn't exists")
async def _get(self, **params: Any) -> bytes:
headers, data = await self._document._database._remote._get_bytes(
self.endpoint, params
Expand All @@ -388,7 +398,7 @@ async def _get(self, **params: Any) -> bytes:
@raises(400, "Invalid request body or parameters")
@raises(401, "Write privilege required for document '{document_id}'")
@raises(403, "Write privilege required for document '{document_id}'")
@raises(404, "Document '{document_id}' doesnt exists")
@raises(404, "Document '{document_id}' doesn't exists")
@raises(
409, "Specified revision {document_rev} is not the latest for target document"
)
Expand All @@ -406,7 +416,7 @@ async def _put(
@raises(400, "Invalid request body or parameters")
@raises(401, "Write privilege required for document '{document_id}'")
@raises(403, "Write privilege required for document '{document_id}'")
@raises(404, "Specified database or document ID doesnt exists ({endpoint})")
@raises(404, "Specified database or document ID doesn't exists ({endpoint})")
@raises(
409, "Specified revision {document_rev} is not the latest for target document"
)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_database.py
Expand Up @@ -245,6 +245,19 @@ async def test_find_fields_parameter_gets_rejected(database: Database) -> None:
[doc async for doc in database.find({"bar": True}, fields="anything")]


async def test_find_sorted(filled_database: Database) -> None:
await filled_database.index({"fields": ["bar2"]})

matching_docs = [
doc async for doc in filled_database.find({"bar": True}, sort=["bar2"])
]

assert len(matching_docs) == 3
assert matching_docs[0]["bar2"] == 1
assert matching_docs[1]["bar2"] == 2
assert matching_docs[2]["bar2"] == 3


async def test_alldocs_values(filled_database: Database) -> None:
values = [key async for key, value in filled_database.all_docs.aitems()]

Expand Down

0 comments on commit 95eca75

Please sign in to comment.