A query instance. This is the object on which the actual query operations are performed. The :class:`~tinydb.queries.Query` class acts like a query builder and generates :class:`~tinydb.queries.QueryInstance` objects which will evaluate their query against a given document when
| 53 | |
| 54 | |
| 55 | class QueryInstance: |
| 56 | """ |
| 57 | A query instance. |
| 58 | |
| 59 | This is the object on which the actual query operations are performed. The |
| 60 | :class:`~tinydb.queries.Query` class acts like a query builder and |
| 61 | generates :class:`~tinydb.queries.QueryInstance` objects which will |
| 62 | evaluate their query against a given document when called. |
| 63 | |
| 64 | Query instances can be combined using logical OR and AND and inverted using |
| 65 | logical NOT. |
| 66 | |
| 67 | In order to be usable in a query cache, a query needs to have a stable hash |
| 68 | value with the same query always returning the same hash. That way a query |
| 69 | instance can be used as a key in a dictionary. |
| 70 | """ |
| 71 | |
| 72 | def __init__(self, test: Callable[[Mapping], bool], hashval: Optional[Tuple]): |
| 73 | self._test = test |
| 74 | self._hash = hashval |
| 75 | |
| 76 | def is_cacheable(self) -> bool: |
| 77 | return self._hash is not None |
| 78 | |
| 79 | def __call__(self, value: Mapping) -> bool: |
| 80 | """ |
| 81 | Evaluate the query to check if it matches a specified value. |
| 82 | |
| 83 | :param value: The value to check. |
| 84 | :return: Whether the value matches this query. |
| 85 | """ |
| 86 | return self._test(value) |
| 87 | |
| 88 | def __hash__(self) -> int: |
| 89 | # We calculate the query hash by using the ``hashval`` object which |
| 90 | # describes this query uniquely, so we can calculate a stable hash |
| 91 | # value by simply hashing it |
| 92 | return hash(self._hash) |
| 93 | |
| 94 | def __repr__(self): |
| 95 | return 'QueryImpl{}'.format(self._hash) |
| 96 | |
| 97 | def __eq__(self, other: object): |
| 98 | if isinstance(other, QueryInstance): |
| 99 | return self._hash == other._hash |
| 100 | |
| 101 | return False |
| 102 | |
| 103 | # --- Query modifiers ----------------------------------------------------- |
| 104 | |
| 105 | def __and__(self, other: 'QueryInstance') -> 'QueryInstance': |
| 106 | # We use a frozenset for the hash as the AND operation is commutative |
| 107 | # (a & b == b & a) and the frozenset does not consider the order of |
| 108 | # elements |
| 109 | if self.is_cacheable() and other.is_cacheable(): |
| 110 | hashval = ('and', frozenset([self._hash, other._hash])) |
| 111 | else: |
| 112 | hashval = None |
no outgoing calls
no test coverage detected
searching dependent graphs…