Esempio n. 1
0
    def process_queried_field(
        self, field: str, value
    ) -> typing.Optional[typing.Tuple[typing.Any, typing.List[typing.Any],
                                      typing.List[str]]]:
        # compound field support
        if field.endswith("__or"):
            return self.process_compound_field(field, value, " OR ")
        elif field.endswith("__and"):
            field = field[:-len("__and")]
            return self.process_compound_field(field, value, " AND ")

        result: typing.Any = value
        operator = "="
        if field.endswith("__not"):
            operator = "!="
            field = field[:-len("__not")]
        elif field.endswith("__in"):
            operator = "?|"
            field = field[:-len("__in")]
        elif field.endswith("__eq"):
            operator = "="
            field = field[:-len("__eq")]
        elif field.endswith("__gt"):
            operator = ">"
            field = field[:-len("__gt")]
        elif field.endswith("__lt"):
            operator = "<"
            field = field[:-len("__lt")]
        elif field.endswith("__gte"):
            operator = ">="
            field = field[:-len("__gte")]
        elif field.endswith("__lte"):
            operator = "<="
            field = field[:-len("__lte")]
        elif field.endswith("__starts"):
            operator = "starts"
            field = field[:-len("__starts")]

        index = get_index_definition(field)
        if index is None:
            return None

        _type = index["type"]
        if _type in _type_mapping:
            try:
                result = _type_mapping[_type](value)
            except ValueError:
                # invalid, can't continue... We could throw query parse error?
                return None
        elif _type == "date":
            result = parse(value).replace(tzinfo=None)
        elif _type == "boolean":
            if value in ("true", "True", "yes", "1"):
                result = True
            else:
                result = False
        elif _type == "keyword" and operator not in ("?", "?|"):
            operator = "?"
        elif _type in ("text", "searchabletext"):
            operator = "="
            value = "&".join(to_list(value))
        if _type == "path":
            if operator != "starts":
                # we do not currently support other search types
                logger.warning(f"Unsupported search {field}: {value}")
            operator = "="

        if operator == "?|":
            result = to_list(value)

        if operator == "?" and isinstance(result, list):
            operator = "?|"

        pg_index = get_pg_index(field)
        return pg_index.where(result, operator), [result], pg_index.select()
Esempio n. 2
0
    def process_queried_field(
        self, field: str, value
    ) -> typing.Optional[typing.Tuple[typing.Any, typing.List[typing.Any],
                                      typing.List[str]]]:
        # compound field support
        if field.endswith('__or'):
            return self.process_compound_field(field, value, ' OR ')
        elif field.endswith('__and'):
            field = field[:-len('__and')]
            return self.process_compound_field(field, value, ' AND ')

        result: typing.Any = value

        operator = '='
        if field.endswith('__not'):
            operator = '!='
            field = field[:-len('__not')]
        elif field.endswith('__in'):
            operator = '?|'
            field = field[:-len('__in')]
        elif field.endswith('__eq'):
            operator = '='
            field = field[:-len('__eq')]
        elif field.endswith('__gt'):
            operator = '>'
            field = field[:-len('__gt')]
        elif field.endswith('__lt'):
            operator = '<'
            field = field[:-len('__lt')]
        elif field.endswith('__gte'):
            operator = '>='
            field = field[:-len('__gte')]
        elif field.endswith('__lte'):
            operator = '<='
            field = field[:-len('__lte')]
        elif field.endswith('__starts'):
            operator = 'starts'
            field = field[:-len('__starts')]

        index = get_index_definition(field)
        if index is None:
            return None

        _type = index['type']
        if _type in _type_mapping:
            try:
                result = _type_mapping[_type](value)
            except ValueError:
                # invalid, can't continue... We could throw query parse error?
                return None
        elif _type == 'date':
            result = parse(value).replace(tzinfo=None)
        elif _type == 'boolean':
            if value in ('true', 'True', 'yes', '1'):
                result = True
            else:
                result = False
        elif _type == 'keyword' and operator not in ('?', '?|'):
            operator = '?'
        elif _type in ('text', 'searchabletext'):
            operator = '='
            value = '&'.join(to_list(value))
        if _type == 'path':
            if operator != 'starts':
                # we do not currently support other search types
                logger.warning(f'Unsupported search {field}: {value}')
            operator = '='

        if operator == '?|':
            result = to_list(value)

        if operator == '?' and isinstance(result, list):
            operator = '?|'

        pg_index = get_pg_index(field)
        return pg_index.where(result, operator), [result], pg_index.select()