Example #1
0
 def test_exceptions_on_complex_calls(self):
     for daterange in [
             choice for choice in get_all_daterange_choices()
             if not choice.simple
     ]:
         with self.assertRaises(InvalidDaterangeException):
             get_daterange_start_end_dates(daterange.slug)
Example #2
0
class PreFilterValue(FilterValue):

    # All dynamic date operators use BasicBetweenFilter
    dyn_date_operators = [c.slug for c in get_all_daterange_choices()]
    null_operator_filters = {
        '=': ISNULLFilter,
        '!=': NOTNULLFilter,
        'is': ISNULLFilter,
        'is not': NOTNULLFilter,
    }
    array_operator_filters = {
        'in': INFilter,
        'between': BasicBetweenFilter,
    }
    scalar_operator_filters = NumericFilterValue.operators_to_filters

    def _is_dyn_date(self):
        return self.value.get('operator') in self.dyn_date_operators

    def _is_null(self):
        return self.value['operand'] is None

    def _is_list(self):
        """
        Returns true if operand should be treated like an array when building
        the query.
        """
        return isinstance(self.value['operand'], list)

    @property
    def _null_filter(self):
        operator = self.value.get('operator') or 'is'
        try:
            return self.null_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Null value does not support "{}" operator'.format(operator))

    @property
    def _array_filter(self):
        operator = self.value.get('operator') or 'in'
        try:
            return self.array_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Array value does not support "{}" operator'.format(operator))

    @property
    def _scalar_filter(self):
        operator = self.value.get('operator') or '='
        try:
            return self.scalar_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Scalar value does not support "{}" operator'.format(operator))

    def to_sql_filter(self):
        if self._is_dyn_date():
            return BasicBetweenFilter(
                self.filter.field,
                get_INFilter_bindparams(self.filter.slug,
                                        ['start_date', 'end_date']))
        elif self._is_null():
            return self._null_filter(self.filter.field)
        elif self._is_list():
            return self._array_filter(
                self.filter.field,
                get_INFilter_bindparams(self.filter.slug,
                                        self.value['operand']))
        else:
            return self._scalar_filter.sql(self.filter.field, self.filter.slug)

    def to_sql_values(self):
        if self._is_dyn_date():
            start_date, end_date = get_daterange_start_end_dates(
                self.value['operator'], *self.value['operand'])
            return {
                get_INFilter_element_bindparam(self.filter.slug, i): str(v)
                for i, v in enumerate([start_date, end_date])
            }
        elif self._is_null():
            return {}
        elif self._is_list():
            # Array params work like IN bind params
            return {
                get_INFilter_element_bindparam(self.filter.slug, i): v
                for i, v in enumerate(self.value['operand'])
            }
        else:
            return {self.filter.slug: self.value['operand']}

    def to_es_filter(self):
        # TODO: support the array and null operators defined at top of class
        if self._is_dyn_date():
            start_date, end_date = get_daterange_start_end_dates(
                self.value['operator'], *self.value['operand'])
            return filters.date_range(self.filter.field,
                                      gt=start_date,
                                      lt=end_date)
        elif self._is_null():
            return filters.missing(self.filter.field)
        elif self._is_list():
            terms = [v.value for v in self.value['operand']]
            return filters.term(self.filter.field, terms)
        else:
            return self._scalar_filter.es(self.filter.field,
                                          self.value['operand'])
Example #3
0
 def test_exceptions_on_complex_calls(self):
     for daterange in [choice for choice in get_all_daterange_choices() if not choice.simple]:
         with self.assertRaises(InvalidDaterangeException):
             get_daterange_start_end_dates(daterange.slug)
Example #4
0
 def test_exceptions_on_complex_calls(self):
     for daterange in filter(lambda choice: not choice.simple,
                             get_all_daterange_choices()):
         with self.assertRaises(InvalidDaterangeException):
             get_daterange_start_end_dates(daterange.slug)
Example #5
0
class PreFilterValue(FilterValue):

    # All dynamic date operators use BasicBetweenFilter
    dyn_date_operators = [c.slug for c in get_all_daterange_choices()]
    null_operator_filters = {
        '=': ISNULLFilter,
        '!=': NOTNULLFilter,
        'is': ISNULLFilter,
        'is not': NOTNULLFilter,
    }
    array_operator_filters = {
        'in': INFilter,
        'between': BasicBetweenFilter,
    }
    scalar_operator_filters = NumericFilterValue.operators_to_filters

    def _is_dyn_date(self):
        return self.value.get('operator') in self.dyn_date_operators

    def _is_null(self):
        return self.value['operand'] is None

    def _is_list(self):
        """
        Returns true if operand should be treated like an array when building
        the query.
        """
        return isinstance(self.value['operand'], list)

    def _is_empty(self):
        """
        Returns true if operand has no value.
        """
        return self.value['operand'] == '' or self._is_null()

    @property
    def _array_filter(self):
        operator = self.value.get('operator') or 'in'
        try:
            return self.array_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Array value does not support "{}" operator'.format(operator))

    @property
    def _scalar_filter(self):
        operator = self.value.get('operator') or '='
        try:
            return self.scalar_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Scalar value does not support "{}" operator'.format(operator))

    def to_sql_filter(self):
        if self._is_dyn_date():
            return BasicBetweenFilter(
                self.filter['field'],
                get_INFilter_bindparams(self.filter['slug'],
                                        ['start_date', 'end_date']))
        elif self._is_empty():
            return ORFilter([
                EQFilter(self.filter['field'], self.filter['slug']),
                ISNULLFilter(self.filter['field']),
            ])
        elif self._is_list():
            return self._array_filter(
                self.filter['field'],
                get_INFilter_bindparams(self.filter['slug'],
                                        self.value['operand']))
        else:
            return self._scalar_filter(self.filter['field'],
                                       self.filter['slug'])

    def to_sql_values(self):
        if self._is_dyn_date():
            start_date, end_date = get_daterange_start_end_dates(
                self.value['operator'], *self.value['operand'])
            return {
                get_INFilter_element_bindparam(self.filter['slug'], i): str(v)
                for i, v in enumerate([start_date, end_date])
            }
        elif self._is_empty():
            return {
                self.filter['slug']: '',
            }
        elif self._is_list():
            # Array params work like IN bind params
            return {
                get_INFilter_element_bindparam(self.filter['slug'], i): v
                for i, v in enumerate(self.value['operand'])
            }
        else:
            return {self.filter['slug']: self.value['operand']}
Example #6
0
class PreFilterValue(FilterValue):

    # All dynamic date operators use BasicBetweenFilter
    dyn_date_operators = [c.slug for c in get_all_daterange_choices()]
    null_operator_filters = {
        '=': ISNULLFilter,
        '!=': NOTNULLFilter,
        'is': ISNULLFilter,
        'is not': NOTNULLFilter,
    }
    array_operator_filters = {
        'in': INFilter,
        'between': BasicBetweenFilter,
    }
    scalar_operator_filters = NumericFilterValue.operators_to_filters

    def _is_dyn_date(self):
        return self.value.get('operator') in self.dyn_date_operators

    def _is_list(self):
        """
        Returns true if operand should be treated like an array when building
        the query.
        """
        return isinstance(self.value['operand'], list)

    def _has_empty_value(self):
        """
        Returns true if operand has no value.
        """
        return self.value['operand'] == '' or self.value['operand'] is None

    def _is_empty(self):
        """
        Returns true if the value should be treated as a filter to show only empty data
        """
        operator = self.value.get('operator') or '='
        return self._has_empty_value() and operator == '='

    def _is_exists(self):
        """
        Returns true if the value should be treated as a filter to show non-empty data
        """
        return self._has_empty_value() and self.value.get('operator') == '!='

    @property
    def _array_filter(self):
        operator = self.value.get('operator') or 'in'
        try:
            return self.array_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Array value does not support "{}" operator'.format(operator))

    @property
    def _scalar_filter(self):
        operator = self.value.get('operator') or '='
        try:
            return self.scalar_operator_filters[operator]
        except KeyError:
            raise TypeError(
                'Scalar value does not support "{}" operator'.format(operator))

    def to_sql_filter(self):
        if self._is_dyn_date():
            return BasicBetweenFilter(
                self.filter['field'],
                get_INFilter_bindparams(self.filter['slug'],
                                        ['start_date', 'end_date']))
        elif self._is_empty():
            if self.filter.get('datatype') in [
                    DATA_TYPE_DATE, DATA_TYPE_DATETIME
            ]:
                return ISNULLFilter(self.filter['field'])
            else:
                return ORFilter([
                    EQFilter(self.filter['field'], self.filter['slug']),
                    ISNULLFilter(self.filter['field']),
                ])
        elif self._is_exists():
            if self.filter.get('datatype') in [
                    DATA_TYPE_DATE, DATA_TYPE_DATETIME
            ]:
                return NOTNULLFilter(self.filter['field'])
            else:
                # this resolves to != '', which also filters out null data in postgres
                return NOTEQFilter(self.filter['field'], self.filter['slug'])
        elif self._is_list():
            return self._array_filter(
                self.filter['field'],
                get_INFilter_bindparams(self.filter['slug'],
                                        self.value['operand']))
        else:
            return self._scalar_filter(self.filter['field'],
                                       self.filter['slug'])

    def to_sql_values(self):
        if self._is_dyn_date():
            start_date, end_date = get_daterange_start_end_dates(
                self.value['operator'], *self.value['operand'])
            return {
                get_INFilter_element_bindparam(self.filter['slug'], i): str(v)
                for i, v in enumerate([start_date, end_date])
            }
        elif self._is_empty() or self._is_exists():
            if self.filter.get('datatype') in [
                    DATA_TYPE_DATE, DATA_TYPE_DATETIME
            ]:
                # Both == '' and != '' do not work for dates in postgres so the expression should only be for NULL
                # checks that get added later. Hence don't return any comparison for value here
                return {}
            else:
                return {
                    self.filter['slug']: '',
                }
        elif self._is_list():
            # Array params work like IN bind params
            return {
                get_INFilter_element_bindparam(self.filter['slug'], i): v
                for i, v in enumerate(self.value['operand'])
            }
        else:
            return {self.filter['slug']: self.value['operand']}
Example #7
0
 def test_exceptions_on_complex_calls(self):
     for daterange in filter(lambda choice: not choice.simple, get_all_daterange_choices()):
         with self.assertRaises(InvalidDaterangeException):
             get_daterange_start_end_dates(daterange.slug)