Files
tryton/trytond/model/fields/text.py
T
2021-12-11 17:58:45 +01:00

96 lines
3.3 KiB
Python

# 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
class Text(Char):
'''
Define a text field (``unicode``).
'''
_type = 'text'
_sql_type = 'TEXT'
forbidden_chars = ''
search_full_text = True
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
def convert_order(self, name, tables, Model):
method = getattr(Model, 'order_%s' % name, None)
if method:
return method(tables)
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 []