Ejemplo n.º 1
0
    def test_find_nested_dotted_path_value(self):
        obj = {"a": {"b.c": 42}}
        obtained = find_nested_value(obj, "a.b.c")
        self.assertEqual(obtained, 42)

        obj = {"a.b": {"c.d": 42}}
        obtained = find_nested_value(obj, "a.b.c.d")
        self.assertEqual(obtained, 42)

        obj = {"a": {"b": {"a": {"b": 42}}}}
        obtained = find_nested_value(obj, "a.b.a.b")
        self.assertEqual(obtained, 42)
Ejemplo n.º 2
0
    def test_find_nested_dotted_path_value(self):
        record = {"a": {"b.c": 42}}
        obtained = find_nested_value(record, "a.b.c")
        self.assertEqual(obtained, 42)

        record = {"a.b": {"c.d": 42}}
        obtained = find_nested_value(record, "a.b.c.d")
        self.assertEqual(obtained, 42)

        record = {"a": {"b": {"a": {"b": 42}}}}
        obtained = find_nested_value(record, "a.b.a.b")
        self.assertEqual(obtained, 42)
Ejemplo n.º 3
0
 def test_find_disambiguated_dotted_path_values(self):
     # XXX: To be honest, this is a really scary use case. Probably a
     # limitation of the dotted path notation we may want to document.
     # At least this test acts as documentation for now.
     record = {"a": {"b": 0}, "a.b": 42}
     obtained = find_nested_value(record, "a.b")
     self.assertEqual(obtained, 42)
Ejemplo n.º 4
0
    def _build_pagination_token(self, sorting, last_record, offset):
        """Build a pagination token.

        It is a base64 JSON object with the sorting fields values of
        the last_record.

        """
        nonce = 'pagination-token-{}'.format(uuid4())
        if self.request.method.lower() == 'delete':
            registry = self.request.registry
            validity = registry.settings['pagination_token_validity_seconds']
            registry.cache.set(nonce, '', validity)

        token = {
            'last_record': {},
            'offset': offset,
            'nonce': nonce,
        }

        for field, _ in sorting:
            last_value = find_nested_value(last_record, field, MISSING)
            if last_value is not MISSING:
                token['last_record'][field] = last_value

        return encode64(json.dumps(token))
Ejemplo n.º 5
0
 def test_find_disambiguated_dotted_path_values(self):
     # XXX: To be honest, this is a really scary use case. Probably a
     # limitation of the dotted path notation we may want to document.
     # At least this test acts as documentation for now.
     obj = {"a": {"b": 0}, "a.b": 42}
     obtained = find_nested_value(obj, "a.b")
     self.assertEqual(obtained, 42)
Ejemplo n.º 6
0
    def _build_pagination_token(self, sorting, last_record, offset):
        """Build a pagination token.

        It is a base64 JSON object with the sorting fields values of
        the last_record.

        """
        nonce = "pagination-token-{}".format(uuid4())
        if self.request.method.lower() == "delete":
            registry = self.request.registry
            validity = registry.settings["pagination_token_validity_seconds"]
            registry.cache.set(nonce, "", validity)

        token = {
            'last_record': {},
            'offset': offset,
            'nonce': nonce,
        }

        for field, _ in sorting:
            last_value = find_nested_value(last_record, field)
            if last_value is not None:
                token['last_record'][field] = last_value

        return encode64(json.dumps(token))
Ejemplo n.º 7
0
    def _build_pagination_token(self, sorting, last_record, offset):
        """Build a pagination token.

        It is a base64 JSON object with the sorting fields values of
        the last_record.

        """
        token = {'last_record': {}, 'offset': offset}

        for field, _ in sorting:
            last_value = find_nested_value(last_record, field)
            if last_value is not None:
                token['last_record'][field] = last_value

        return encode64(json.dumps(token))
Ejemplo n.º 8
0
def apply_filters(records, filters):
    """Filter the specified records, using basic iteration.
    """
    operators = {
        COMPARISON.LT: operator.lt,
        COMPARISON.MAX: operator.le,
        COMPARISON.EQ: operator.eq,
        COMPARISON.NOT: operator.ne,
        COMPARISON.MIN: operator.ge,
        COMPARISON.GT: operator.gt,
        COMPARISON.IN: operator.contains,
        COMPARISON.EXCLUDE: lambda x, y: not operator.contains(x, y),
        COMPARISON.LIKE: lambda x, y: re.search(y, x, re.IGNORECASE),
    }
    for record in records:
        matches = True
        for f in filters:
            right = f.value
            if f.field == DEFAULT_ID_FIELD:
                if isinstance(right, int):
                    right = str(right)

            left = find_nested_value(record, f.field, MISSING)

            if f.operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
                right, left = left, right
            elif f.operator == COMPARISON.LIKE:
                # Add implicit start/end wildchars if none is specified.
                if '*' not in right:
                    right = '*{}*'.format(right)
                right = '^{}$'.format(right.replace('*', '.*'))
            elif f.operator != COMPARISON.HAS:
                left = schwartzian_transform(left)
                right = schwartzian_transform(right)

            if f.operator == COMPARISON.HAS:
                matches = left != MISSING if f.value else left == MISSING
            else:
                matches = matches and operators[f.operator](left, right)
        if matches:
            yield record
Ejemplo n.º 9
0
    def _build_pagination_token(self, sorting, last_object, offset):
        """Build a pagination token.

        It is a base64 JSON object with the sorting fields values of
        the last_object.

        """
        nonce = f"pagination-token-{uuid4()}"
        if self.request.method.lower() == "delete":
            registry = self.request.registry
            validity = registry.settings["pagination_token_validity_seconds"]
            registry.cache.set(nonce, "", validity)

        token = {"last_object": {}, "offset": offset, "nonce": nonce}

        for field, _ in sorting:
            last_value = find_nested_value(last_object, field, MISSING)
            if last_value is not MISSING:
                token["last_object"][field] = last_value

        return encode64(json.dumps(token))
Ejemplo n.º 10
0
def apply_filters(records, filters):
    """Filter the specified records, using basic iteration.
    """
    operators = {
        COMPARISON.LT: operator.lt,
        COMPARISON.MAX: operator.le,
        COMPARISON.EQ: operator.eq,
        COMPARISON.NOT: operator.ne,
        COMPARISON.MIN: operator.ge,
        COMPARISON.GT: operator.gt,
        COMPARISON.IN: operator.contains,
        COMPARISON.EXCLUDE: lambda x, y: not operator.contains(x, y),
        COMPARISON.LIKE: lambda x, y: re.search(y, x, re.IGNORECASE),
    }
    for record in records:
        matches = True
        for f in filters:
            right = f.value
            if f.field == DEFAULT_ID_FIELD:
                if isinstance(right, int):
                    right = str(right)

            left = find_nested_value(record, f.field)

            if f.operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
                right, left = left, right
            else:
                if left is None:
                    right_is_number = (isinstance(right, (int, float))
                                       and right not in (True, False))
                    if right_is_number:
                        # Python3 cannot compare None to a number.
                        matches = False
                        continue
                    else:
                        left = ''  # To mimic what we do for postgresql.
            matches = matches and operators[f.operator](left, right)
        if matches:
            yield record
Ejemplo n.º 11
0
def apply_filters(records, filters):
    """Filter the specified records, using basic iteration.
    """
    def contains_filtering(record_value, search_term):
        if record_value == MISSING:
            return False
        try:
            search_set = set([canonical_json(v) for v in search_term])
            record_value_set = set([canonical_json(v) for v in record_value])
        except TypeError:
            return False
        return record_value_set.intersection(search_set) == search_set

    def contains_any_filtering(record_value, search_term):
        if record_value == MISSING:
            return False
        try:
            search_set = set([canonical_json(v) for v in search_term])
            record_value_set = set([canonical_json(v) for v in record_value])
        except TypeError:
            return False
        return record_value_set.intersection(search_set)

    operators = {
        COMPARISON.LT: operator.lt,
        COMPARISON.MAX: operator.le,
        COMPARISON.EQ: operator.eq,
        COMPARISON.NOT: operator.ne,
        COMPARISON.MIN: operator.ge,
        COMPARISON.GT: operator.gt,
        COMPARISON.IN: operator.contains,
        COMPARISON.EXCLUDE: lambda x, y: not operator.contains(x, y),
        COMPARISON.LIKE: lambda x, y: re.search(y, x, re.IGNORECASE),
        COMPARISON.CONTAINS: contains_filtering,
        COMPARISON.CONTAINS_ANY: contains_any_filtering,
    }
    for record in records:
        matches = True
        for f in filters:
            right = f.value
            if f.field == DEFAULT_ID_FIELD:
                if isinstance(right, int):
                    right = str(right)

            left = find_nested_value(record, f.field, MISSING)

            if f.operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
                right, left = left, right
            elif f.operator == COMPARISON.LIKE:
                # Add implicit start/end wildchars if none is specified.
                if "*" not in right:
                    right = f"*{right}*"
                right = f"^{right.replace('*', '.*')}$"
            elif f.operator in (
                    COMPARISON.LT,
                    COMPARISON.MAX,
                    COMPARISON.EQ,
                    COMPARISON.NOT,
                    COMPARISON.MIN,
                    COMPARISON.GT,
            ):
                left = schwartzian_transform(left)
                right = schwartzian_transform(right)

            if f.operator == COMPARISON.HAS:
                matches = left != MISSING if f.value else left == MISSING
            else:
                matches = matches and operators[f.operator](left, right)
        if matches:
            yield record
Ejemplo n.º 12
0
 def test_fallback_default_value(self):
     obj = {"a": {"c": 42}}
     self.assertEqual(find_nested_value(obj, "x", 1337), 1337)
     self.assertEqual(find_nested_value(obj, "a.b", 1337), 1337)
     self.assertEqual(find_nested_value(obj, "x.a", 1337), 1337)
     self.assertEqual(find_nested_value(obj, "a.c.d", 1337), 1337)
Ejemplo n.º 13
0
 def test_unmatched_path_returns_none(self):
     obj = {"a": 42}
     self.assertIsNone(find_nested_value(obj, "x"))
     self.assertIsNone(find_nested_value(obj, "a.b"))
     self.assertIsNone(find_nested_value(obj, "x.a"))
Ejemplo n.º 14
0
 def test_find_dotted_path_value(self):
     obj = {"a.b": 42}
     obtained = find_nested_value(obj, "a.b")
     self.assertEqual(obtained, 42)
Ejemplo n.º 15
0
 def column(first, record, name):
     return find_nested_value(record, name, default=float('inf'))
Ejemplo n.º 16
0
 def test_find_flat_value(self):
     obj = {"a": 42}
     obtained = find_nested_value(obj, "a")
     self.assertEqual(obtained, 42)
Ejemplo n.º 17
0
 def test_unmatched_path_returns_none(self):
     record = {"a": 42}
     self.assertIsNone(find_nested_value(record, "x"))
     self.assertIsNone(find_nested_value(record, "a.b"))
     self.assertIsNone(find_nested_value(record, "x.a"))
Ejemplo n.º 18
0
 def test_find_deeply_nested_value(self):
     record = {"a": {"b": {"c": 42}}}
     obtained = find_nested_value(record, "a.b.c")
     self.assertEqual(obtained, 42)
Ejemplo n.º 19
0
 def test_find_flat_value(self):
     record = {"a": 42}
     obtained = find_nested_value(record, "a")
     self.assertEqual(obtained, 42)
Ejemplo n.º 20
0
 def column(record, name):
     return schwartzian_transform(find_nested_value(record, name, default=MISSING))
Ejemplo n.º 21
0
 def test_find_nested_value(self):
     record = {"a": {"b": 42}}
     obtained = find_nested_value(record, "a.b")
     self.assertEqual(obtained, 42)
Ejemplo n.º 22
0
 def test_fallback_default_value(self):
     record = {"a": {"c": 42}}
     self.assertEqual(find_nested_value(record, "x", 1337), 1337)
     self.assertEqual(find_nested_value(record, "a.b", 1337), 1337)
     self.assertEqual(find_nested_value(record, "x.a", 1337), 1337)
     self.assertEqual(find_nested_value(record, "a.c.d", 1337), 1337)
Ejemplo n.º 23
0
 def column(record, name):
     return schwartzian_transform(
         find_nested_value(record, name, default=MISSING))
Ejemplo n.º 24
0
 def test_find_deeply_nested_value(self):
     obj = {"a": {"b": {"c": 42}}}
     obtained = find_nested_value(obj, "a.b.c")
     self.assertEqual(obtained, 42)
Ejemplo n.º 25
0
def apply_filters(records, filters):
    """Filter the specified records, using basic iteration.
    """

    def contains_filtering(record_value, search_term):
        if record_value == MISSING:
            return False
        try:
            search_set = set([canonical_json(v) for v in search_term])
            record_value_set = set([canonical_json(v) for v in record_value])
        except TypeError:
            return False
        return record_value_set.intersection(search_set) == search_set

    def contains_any_filtering(record_value, search_term):
        if record_value == MISSING:
            return False
        try:
            search_set = set([canonical_json(v) for v in search_term])
            record_value_set = set([canonical_json(v) for v in record_value])
        except TypeError:
            return False
        return record_value_set.intersection(search_set)

    operators = {
        COMPARISON.LT: operator.lt,
        COMPARISON.MAX: operator.le,
        COMPARISON.EQ: operator.eq,
        COMPARISON.NOT: operator.ne,
        COMPARISON.MIN: operator.ge,
        COMPARISON.GT: operator.gt,
        COMPARISON.IN: operator.contains,
        COMPARISON.EXCLUDE: lambda x, y: not operator.contains(x, y),
        COMPARISON.LIKE: lambda x, y: re.search(y, x, re.IGNORECASE),
        COMPARISON.CONTAINS: contains_filtering,
        COMPARISON.CONTAINS_ANY: contains_any_filtering,
    }
    for record in records:
        matches = True
        for f in filters:
            right = f.value
            if f.field == DEFAULT_ID_FIELD:
                if isinstance(right, int):
                    right = str(right)

            left = find_nested_value(record, f.field, MISSING)

            if f.operator in (COMPARISON.IN, COMPARISON.EXCLUDE):
                right, left = left, right
            elif f.operator == COMPARISON.LIKE:
                # Add implicit start/end wildchars if none is specified.
                if '*' not in right:
                    right = '*{}*'.format(right)
                right = '^{}$'.format(right.replace('*', '.*'))
            elif f.operator in (COMPARISON.LT, COMPARISON.MAX, COMPARISON.EQ,
                                COMPARISON.NOT, COMPARISON.MIN, COMPARISON.GT):
                left = schwartzian_transform(left)
                right = schwartzian_transform(right)

            if f.operator == COMPARISON.HAS:
                matches = left != MISSING if f.value else left == MISSING
            else:
                matches = matches and operators[f.operator](left, right)
        if matches:
            yield record
Ejemplo n.º 26
0
 def test_find_dotted_path_value(self):
     record = {"a.b": 42}
     obtained = find_nested_value(record, "a.b")
     self.assertEqual(obtained, 42)