From 2e7b4f2027a1147ca28301e4f88adf8274b39a1f Mon Sep 17 00:00:00 2001 From: DUVAL Thomas Date: Thu, 9 Jun 2016 09:11:50 +0200 Subject: Update Keystone core to Mitaka. Change-Id: Ia10d6add16f4a9d25d1f42d420661c46332e69db --- keystone-moon/keystone/common/driver_hints.py | 47 ++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'keystone-moon/keystone/common/driver_hints.py') diff --git a/keystone-moon/keystone/common/driver_hints.py b/keystone-moon/keystone/common/driver_hints.py index ff0a774c..e7c2f2ef 100644 --- a/keystone-moon/keystone/common/driver_hints.py +++ b/keystone-moon/keystone/common/driver_hints.py @@ -13,6 +13,50 @@ # License for the specific language governing permissions and limitations # under the License. +import functools + +from keystone import exception +from keystone.i18n import _ + + +def truncated(f): + """Ensure list truncation is detected in Driver list entity methods. + + This is designed to wrap Driver list_{entity} methods in order to + calculate if the resultant list has been truncated. Provided a limit dict + is found in the hints list, we increment the limit by one so as to ask the + wrapped function for one more entity than the limit, and then once the list + has been generated, we check to see if the original limit has been + exceeded, in which case we truncate back to that limit and set the + 'truncated' boolean to 'true' in the hints limit dict. + + """ + @functools.wraps(f) + def wrapper(self, hints, *args, **kwargs): + if not hasattr(hints, 'limit'): + raise exception.UnexpectedError( + _('Cannot truncate a driver call without hints list as ' + 'first parameter after self ')) + + if hints.limit is None: + return f(self, hints, *args, **kwargs) + + # A limit is set, so ask for one more entry than we need + list_limit = hints.limit['limit'] + hints.set_limit(list_limit + 1) + ref_list = f(self, hints, *args, **kwargs) + + # If we got more than the original limit then trim back the list and + # mark it truncated. In both cases, make sure we set the limit back + # to its original value. + if len(ref_list) > list_limit: + hints.set_limit(list_limit, truncated=True) + return ref_list[:list_limit] + else: + hints.set_limit(list_limit) + return ref_list + return wrapper + class Hints(object): """Encapsulate driver hints for listing entities. @@ -39,12 +83,13 @@ class Hints(object): * ``name``: the name of the attribute being matched * ``value``: the value against which it is being matched * ``comparator``: the operation, which can be one of ``equals``, - ``startswith`` or ``endswith`` + ``contains``, ``startswith`` or ``endswith`` * ``case_sensitive``: whether any comparison should take account of case * ``type``: will always be 'filter' """ + def __init__(self): self.limit = None self.filters = list() -- cgit 1.2.3-korg