# Copyright 2016 Eficent Business and IT Consulting Services S.L. # Copyright 2016 Serpent Consulting Services Pvt. Ltd. # Copyright 2017 LasLabs Inc. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging from odoo import _, api, models from odoo.osv import expression _logger = logging.getLogger(__name__) def patch_leaf_trgm(method): def decorate_leaf_to_sql(self, eleaf): model = eleaf.model leaf = eleaf.leaf left, operator, right = leaf table_alias = '"%s"' % (eleaf.generate_alias()) if operator == '%': sql_operator = '%%' params = [] if left in model._fields: column = '%s.%s' % (table_alias, expression._quote(left)) query = '(%s %s %s)' % ( column, sql_operator, model._fields[left].column_format, ) elif left in models.MAGIC_COLUMNS: query = "(%s.\"%s\" %s %%s)" % ( table_alias, left, sql_operator) params = right else: # Must not happen raise ValueError(_( "Invalid field %r in domain term %r" % (left, leaf) )) if left in model._fields: params = str(right) if isinstance(params, str): params = [params] return query, params elif operator == 'inselect': right = (right[0].replace(' % ', ' %% '), right[1]) eleaf.leaf = (left, operator, right) return method(self, eleaf) decorate_leaf_to_sql.__decorated__ = True return decorate_leaf_to_sql def patch_generate_order_by(method): @api.model def decorate_generate_order_by(self, order_spec, query): if order_spec and order_spec.startswith('similarity('): return ' ORDER BY ' + order_spec return method(self, order_spec, query) decorate_generate_order_by.__decorated__ = True return decorate_generate_order_by class IrModel(models.Model): _inherit = 'ir.model' @api.model_cr def _register_hook(self): # We have to prevent wrapping the function twice to avoid recursion # errors if not hasattr(expression.expression._expression__leaf_to_sql, '__decorated__'): expression.expression._expression__leaf_to_sql = patch_leaf_trgm( expression.expression._expression__leaf_to_sql) if '%' not in expression.TERM_OPERATORS: expression.TERM_OPERATORS += ('%',) if not hasattr(models.BaseModel._generate_order_by, '__decorated__'): models.BaseModel._generate_order_by = patch_generate_order_by( models.BaseModel._generate_order_by) return super(IrModel, self)._register_hook()