diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ea01d37e5eda76fb668039c2ae615e0f5891da..35e9e9b26ae97f062bb9adfd80ccf31755b2aa78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### +* Added `cache` paramter to `execute_query` and `Query.execute` which indicates + whether server may use the cache for the query execution. +* Added `cached` property to the `Query` class which indicates whether the + server used the cache for the execution of the last query. + ### Changed ### ### Deprecated ### @@ -19,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security ### -## [0.4.1] 2021-02-10 ## +## [0.4.1] - 2021-02-10 ## ### Added ### @@ -93,7 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * import bugs in apiutils -## [0.2.4] -- 2020-04-23 +## [0.2.4] - 2020-04-23 ### Added diff --git a/README.md b/README.md index ef26a604905d5140ae9a775065002af35ffe2121..e44702a3a22c28af986d641b5d7e454f915326c8 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ project](https://gitlab.com/caosdb/caosdb) for more information. # License -Copyright (C) 2018 Research Group Biomedical Physics, Max Planck Institute for -Dynamics and Self-Organization Göttingen. -Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> +* Copyright (C) 2018 Research Group Biomedical Physics, Max Planck Institute + for Dynamics and Self-Organization Göttingen. +* Copyright (C) 2020-2021 Indiscale GmbH <info@indiscale.com> All files in this repository are licensed under a [GNU Affero General Public License](LICENCE.md) (version 3 or later). diff --git a/release.sh b/release.sh index a5f3654291743e5ac22fd3b938719e294b3a1e90..1af097f014de6cd9eb3d3e8ba5da34aea0fe1671 100755 --- a/release.sh +++ b/release.sh @@ -1,4 +1,4 @@ #!/bin/bash -rm -r dist/ build/ .eggs/ +rm -rf dist/ build/ .eggs/ python setup.py sdist bdist_wheel python -m twine upload -s dist/* diff --git a/setup.py b/setup.py index c1c6b287a3044399403db810e851abb3a9b36985..9c638fbc88eed39f263d4d90652685ba4db984af 100755 --- a/setup.py +++ b/setup.py @@ -46,10 +46,10 @@ from setuptools import find_packages, setup ######################################################################## MAJOR = 0 -MINOR = 4 -MICRO = 1 +MINOR = 5 +MICRO = 0 PRE = "" # e.g. rc0, alpha.1, 0.beta-23 -ISRELEASED = True +ISRELEASED = False if PRE: VERSION = "{}.{}.{}-{}".format(MAJOR, MINOR, MICRO, PRE) diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py index d857d5c90097442c1e8527618d4afa963af0e755..5800e5cc929daf101cec4a599732d64dd6e9cbd2 100644 --- a/src/caosdb/common/models.py +++ b/src/caosdb/common/models.py @@ -3611,6 +3611,23 @@ class ACL(): class Query(): + """Query + + Attributes + ---------- + q : str + The query string. + flags : dict of str + A dictionary of flags to be send with the query request. + messages : _Messages() + A container of messages included in the last query response. + cached : bool + indicates whether the server used the query cache for the execution of + this query. + results : int or Container + The number of results (when this was a count query) or the container + with the resulting entities. + """ def putFlag(self, key, value=None): self.flags[key] = value @@ -3626,10 +3643,12 @@ class Query(): def __init__(self, q): self.flags = dict() self.messages = _Messages() + self.cached = None if isinstance(q, etree._Element): self.q = q.get("string") self.results = int(q.get("results")) + self.cached = q.get("cached").lower() == "true" for m in q: if m.tag.lower() == 'warning' or m.tag.lower() == 'error': @@ -3637,17 +3656,43 @@ class Query(): else: self.q = q - def execute(self, unique=False, raise_exception_on_error=True, - **kwargs): + def execute(self, unique=False, raise_exception_on_error=True, cache=True): + """Execute a query (via a server-requests) and return the results. + + Parameters + ---------- + + unique : bool + Whether the query is expected to have only one entity as result. + Defaults to False. + raise_exception_on_error : bool + Whether an exception should be raises when there are errors in the + resulting entities. Defaults to True. + cache : bool + Whether to use the query cache (equivalent to adding a "cache" + flag) to the Query object. Defaults to True. + + Returns + ------- + results : Container or integer + Returns an integer when it was a `COUNT` query. Otherwise, returns a + Container with the resulting entities. + """ connection = get_connection() - query_dict = dict(self.flags) + + flags = self.flags + if cache is False: + flags["cache"] = "false" + query_dict = dict(flags) query_dict["query"] = str(self.q) + _log_request("GET Entity?" + str(query_dict), None) http_response = connection.retrieve( entity_uri_segments=["Entity"], - query_dict=query_dict, **kwargs) + query_dict=query_dict) cresp = Container._response_to_entities(http_response) self.results = cresp.query.results + self.cached = cresp.query.cached if self.q.lower().startswith('count') and len(cresp) == 0: # this was a count query @@ -3672,8 +3717,32 @@ class Query(): return cresp -def execute_query(q, unique=False, raise_exception_on_error=True, flags=None, - **kwargs): +def execute_query(q, unique=False, raise_exception_on_error=True, cache=True, flags=None): + """Execute a query (via a server-requests) and return the results. + + Parameters + ---------- + + q : str + The query string. + unique : bool + Whether the query is expected to have only one entity as result. + Defaults to False. + raise_exception_on_error : bool + Whether an exception should be raises when there are errors in the + resulting entities. Defaults to True. + cache : bool + Whether to use the query cache (equivalent to adding a "cache" flag). + Defaults to True. + flags : dict of str + Flags to be added to the request. + + Returns + ------- + results : Container or integer + Returns an integer when it was a `COUNT` query. Otherwise, returns a + Container with the resulting entities. + """ query = Query(q) if flags is not None: @@ -3681,7 +3750,7 @@ def execute_query(q, unique=False, raise_exception_on_error=True, flags=None, return query.execute(unique=unique, raise_exception_on_error=raise_exception_on_error, - **kwargs) + cache=cache) class DropOffBox(list):