diff --git a/marklogic/rows.py b/marklogic/rows.py index 65a74ef..22d657e 100644 --- a/marklogic/rows.py +++ b/marklogic/rows.py @@ -67,6 +67,61 @@ def query( not 2xx, then the entire response is always returned. """ path = "v1/rows/graphql" if graphql else "v1/rows" + return self.__send_request( + path, + dsl, + plan, + sql, + sparql, + graphql, + format, + tx, + return_response, + **kwargs, + ) + + def update( + self, + dsl: str = None, + format: str = "json", + tx: Transaction = None, + return_response: bool = False, + **kwargs, + ): + """ + Sends an update query to an endpoint at the MarkLogic rows service defined at + https://docs.marklogic.com/REST/client/row-management. Note that this feature + requires the use of MarkLogic version 11.2 or later. + + For more information about Optic Update and using the Optic DSL, + see https://docs.marklogic.com/guide/app-dev/OpticAPI. + TODO - add links for Optic Update. + + :param dsl: an Optic DSL query + :param tx: optional REST transaction in which to service this request. + :param return_response: boolean specifying if the entire original response + object should be returned (True) or if only the data should be returned (False) + upon a success (2xx) response. Note that if the status code of the response is + not 2xx, then the entire response is always returned. + """ + path = "v1/rows/update" + return self.__send_request( + path, dsl, None, None, None, None, format, tx, return_response, **kwargs + ) + + def __send_request( + self, + path: str = None, + dsl: str = None, + plan: dict = None, + sql: str = None, + sparql: str = None, + graphql: str = None, + format: str = "json", + tx: Transaction = None, + return_response: bool = False, + **kwargs, + ): headers = kwargs.pop("headers", {}) data = None if graphql: diff --git a/tests/test_rows_update.py b/tests/test_rows_update.py new file mode 100644 index 0000000..ee63e8b --- /dev/null +++ b/tests/test_rows_update.py @@ -0,0 +1,32 @@ +from marklogic.documents import DefaultMetadata, Document + + +def test_update_dsl_remove(admin_client): + DEFAULT_PERMS = {"python-tester": ["read", "update"]} + DOC_URI = "/temp/doc1.json" + response = admin_client.documents.write( + [Document(DOC_URI, {"doc": 1}, permissions=DEFAULT_PERMS)] + ) + + update_query_remove = 'op.fromDocUris("' + DOC_URI + '").lockForUpdate().remove()' + response = admin_client.rows.update(update_query_remove, return_response=True) + assert 200 == response.status_code + + docs = admin_client.documents.read([DOC_URI]) + assert 0 == len(docs) + + +def test_update_dsl_wrong_path(admin_client): + DEFAULT_PERMS = {"python-tester": ["read", "update"]} + DOC_URI = "/temp/doc1.json" + response = admin_client.documents.write( + [Document(DOC_URI, {"doc": 1}, permissions=DEFAULT_PERMS)] + ) + + update_query_remove = 'op.fromDocUris("' + DOC_URI + '").lockForUpdate().remove()' + response = admin_client.rows.query(update_query_remove, return_response=True) + assert 400 == response.status_code + assert ( + "Optic Update need to be run as update transaction" + in response.content.decode("utf-8") + )