You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.9 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Eficent Business and IT Consulting Services S.L.
  3. # © 2016 Serpent Consulting Services Pvt. Ltd.
  4. # Copyright 2017 LasLabs Inc.
  5. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  6. import logging
  7. from odoo import _, api, models
  8. from odoo.osv import expression
  9. _logger = logging.getLogger(__name__)
  10. def patch_leaf_trgm(method):
  11. def decorate_leaf_to_sql(self, eleaf):
  12. model = eleaf.model
  13. leaf = eleaf.leaf
  14. left, operator, right = leaf
  15. table_alias = '"%s"' % (eleaf.generate_alias())
  16. if operator == '%':
  17. sql_operator = '%%'
  18. params = []
  19. if left in model._fields:
  20. column = '%s.%s' % (table_alias, expression._quote(left))
  21. query = '(%s %s %s)' % (
  22. column,
  23. sql_operator,
  24. model._fields[left].column_format,
  25. )
  26. elif left in models.MAGIC_COLUMNS:
  27. query = "(%s.\"%s\" %s %%s)" % (
  28. table_alias, left, sql_operator)
  29. params = right
  30. else: # Must not happen
  31. raise ValueError(_(
  32. "Invalid field %r in domain term %r" % (left, leaf)
  33. ))
  34. if left in model._fields:
  35. params = str(right)
  36. if isinstance(params, basestring):
  37. params = [params]
  38. return query, params
  39. elif operator == 'inselect':
  40. right = (right[0].replace(' % ', ' %% '), right[1])
  41. eleaf.leaf = (left, operator, right)
  42. return method(self, eleaf)
  43. decorate_leaf_to_sql.__decorated__ = True
  44. return decorate_leaf_to_sql
  45. def patch_generate_order_by(method):
  46. @api.model
  47. def decorate_generate_order_by(self, order_spec, query):
  48. if order_spec and order_spec.startswith('similarity('):
  49. return ' ORDER BY ' + order_spec
  50. return method(self, order_spec, query)
  51. decorate_generate_order_by.__decorated__ = True
  52. return decorate_generate_order_by
  53. class IrModel(models.Model):
  54. _inherit = 'ir.model'
  55. @api.model_cr
  56. def _register_hook(self):
  57. # We have to prevent wrapping the function twice to avoid recursion
  58. # errors
  59. if not hasattr(expression.expression._expression__leaf_to_sql,
  60. '__decorated__'):
  61. expression.expression._expression__leaf_to_sql = patch_leaf_trgm(
  62. expression.expression._expression__leaf_to_sql)
  63. if '%' not in expression.TERM_OPERATORS:
  64. expression.TERM_OPERATORS += ('%',)
  65. if not hasattr(models.BaseModel._generate_order_by,
  66. '__decorated__'):
  67. models.BaseModel._generate_order_by = patch_generate_order_by(
  68. models.BaseModel._generate_order_by)
  69. return super(IrModel, self)._register_hook()