|
|
# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging
from openerp import models from openerp.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._columns: format = model._columns[left]._symbol_set[0] column = '%s.%s' % (table_alias, expression._quote(left)) query = '(%s %s %s)' % (column, sql_operator, format) elif left in expression.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._columns: params = model._columns[left]._symbol_set[1](right)
if isinstance(params, basestring): 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): 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'
def _register_hook(self, cr, ids=None): # 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(cr)
|