def convert_domain(self, domain, tables, Model): name, operator, value = domain[:3] if '.' not in name: return super().convert_domain(domain, tables, Model) database = Transaction().database table, _ = tables[None] name, key = name.split('.', 1) Operator = SQL_OPERATORS[operator] column = self.sql_column(table) column = self._domain_column(operator, column, key) expression = Operator(column, self._domain_value(operator, value)) if operator in {'=', '!='}: # Try to use custom operators in case there is indexes raw_column = self.sql_column(table) try: if value is None: expression = database.json_key_exists(raw_column, key) if operator == '=': expression = operators.Not(expression) return expression else: expression = database.json_contains( raw_column, dumps({key: value})) if operator == '!=': expression = operators.Not(expression) expression &= database.json_key_exists(raw_column, key) return expression except NotImplementedError: pass if isinstance(expression, operators.In) and not expression.right: expression = Literal(False) elif isinstance(expression, operators.NotIn) and not expression.right: expression = Literal(True) expression = self._domain_add_null(column, operator, value, expression) return expression
def convert_domain(self, domain, tables, Model): name, operator, value = domain[:3] if '.' not in name: return super().convert_domain(domain, tables, Model) database = Transaction().database table, _ = tables[None] name, key = name.split('.', 1) Operator = SQL_OPERATORS[operator] raw_column = self.sql_column(table) column = self._domain_column(operator, raw_column, key) expression = Operator(column, self._domain_value(operator, value)) if operator in {'=', '!='}: # Try to use custom operators in case there is indexes try: if value is None: expression = database.json_key_exists( raw_column, key) if operator == '=': expression = operators.Not(expression) # we compare on multi-selection by doing an equality check and # not a contain check elif not isinstance(value, (list, tuple)): expression = database.json_contains( raw_column, dumps({key: value})) if operator == '!=': expression = operators.Not(expression) expression &= database.json_key_exists( raw_column, key) return expression except NotImplementedError: pass elif operator.endswith('in'): # Try to use custom operators in case there is indexes if operator == 'in': none_value = False op = '=' else: none_value = True op = '!=' if not expression.right: expression = Literal(none_value) elif isinstance(value, (list, tuple)): try: expression = Literal(not bool(value)) for v in value: expression |= database.json_contains( self._domain_column(op, raw_column, key), dumps(v)) if operator.startswith('not'): expression = ~expression except NotImplementedError: pass expression = self._domain_add_null(column, operator, value, expression) return expression
def convert_domain(self, domain, tables, Model): name, operator, value = domain[:3] if operator not in {'in', 'not in'}: return super().convert_domain(domain, tables, Model) database = Transaction().database table, _ = tables[None] raw_column = self.sql_column(table) if isinstance(value, str): try: expression = database.json_key_exists(raw_column, value) except NotImplementedError: expression = operators.Like(raw_column, '%' + dumps(value) + '%') else: try: expression = database.json_any_keys_exist( raw_column, list(value)) except NotImplementedError: expression = Literal(False) for item in value: expression |= operators.Like(raw_column, '%' + dumps(item) + '%') if operator == 'not in': expression = operators.Not(expression) return expression