1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql import Expression, Literal, Null, Query
from sql.operators import ILike, In, Not, NotIn
from trytond.transaction import Transaction
from .char import Char
from .field import SQL_OPERATORS, Field, order_method
class Text(Char):
'''
Define a text field (``unicode``).
'''
_type = 'text'
_sql_type = 'TEXT'
forbidden_chars = ''
search_full_text = True
def __init__(self, *args, strip=False, **kwarg):
super().__init__(*args, strip=strip, **kwarg)
class FullText(Field):
'''
Define a full text field.
'''
_type = 'full_text'
_sql_type = 'FULLTEXT'
_py_type = str
def sql_format(self, value):
if isinstance(value, (Query, Expression)):
return value
if not value:
return Null
if isinstance(value, (int, float)):
return value
transaction = Transaction()
database = transaction.database
if isinstance(value, str):
value = [value]
return database.format_full_text(*value, language=transaction.language)
def _rank_column(self, column, name, Model):
transaction = Transaction()
context = transaction.context
database = transaction.database
key = '%s.%s.order' % (Model.__name__, name)
value = context.get(key)
if value and database.has_search_full_text():
value = database.format_full_text_query(
value, language=transaction.language)
return database.rank_full_text(column, value, normalize=['rank'])
def convert_domain(self, domain, tables, Model):
transaction = Transaction()
database = transaction.database
table, _ = tables[None]
name, operator, value = domain
assert name == self.name
column = self.sql_column(table)
column = self._domain_column(operator, column)
if operator.endswith('like'):
if database.has_search_full_text():
value = database.format_full_text_query(
value, language=transaction.language)
expression = database.search_full_text(column, value)
else:
expression = Literal(True)
for v in value.split():
expression &= ILike(column, '%' + v + '%')
if operator.startswith('not'):
expression = Not(expression)
else:
Operator = SQL_OPERATORS[operator]
column = self._rank_column(column, name, Model)
expression = Operator(column, self._domain_value(operator, value))
if isinstance(expression, In) and not expression.right:
expression = Literal(False)
elif isinstance(expression, NotIn) and not expression.right:
expression = Literal(True)
expression = self._domain_add_null(
column, operator, value, expression)
return expression
@order_method
def convert_order(self, name, tables, Model):
table, _ = tables[None]
column = self.sql_column(table)
column = self._domain_column('ilike', column)
column = self._rank_column(column, name, Model)
if column:
return [column]
return []
|