2014-12-02 12:54:01 +01:00
|
|
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
|
|
|
# this repository contains the full copyright notices and license terms.
|
2013-09-06 22:32:37 +02:00
|
|
|
from decimal import Decimal
|
2017-03-31 12:44:22 +02:00
|
|
|
from sql import Cast, Literal, Select, CombiningQuery, As
|
2009-02-03 18:58:25 +01:00
|
|
|
|
2014-09-03 23:32:01 +02:00
|
|
|
from ... import backend
|
2013-09-06 22:32:37 +02:00
|
|
|
from .float import Float
|
2009-02-03 18:58:25 +01:00
|
|
|
|
|
|
|
|
|
2014-12-20 19:24:42 +01:00
|
|
|
class SQLite_Cast(Cast):
|
|
|
|
|
|
|
|
|
|
def as_(self, output_name):
|
|
|
|
|
# Use PARSE_COLNAMES instead of CAST for final column
|
|
|
|
|
return As(self.expression, '%s [NUMERIC]' % output_name)
|
|
|
|
|
|
|
|
|
|
|
2009-02-03 18:58:25 +01:00
|
|
|
class Numeric(Float):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2009-09-13 15:37:11 +02:00
|
|
|
Define a numeric field (``decimal``).
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2009-02-03 18:58:25 +01:00
|
|
|
_type = 'numeric'
|
2017-03-31 12:44:22 +02:00
|
|
|
_sql_type = 'NUMERIC'
|
2013-09-06 22:32:37 +02:00
|
|
|
|
2017-03-31 12:44:22 +02:00
|
|
|
def sql_format(self, value):
|
2013-09-06 22:32:37 +02:00
|
|
|
if value is None:
|
|
|
|
|
return None
|
2018-06-26 19:11:19 +02:00
|
|
|
if isinstance(value, int):
|
2013-09-06 22:32:37 +02:00
|
|
|
value = Decimal(str(value))
|
2018-02-02 00:04:19 +01:00
|
|
|
value = Decimal(value)
|
2013-09-06 22:32:37 +02:00
|
|
|
return value
|
|
|
|
|
|
2014-03-18 19:59:04 +01:00
|
|
|
def sql_column(self, table):
|
|
|
|
|
column = super(Numeric, self).sql_column(table)
|
2014-09-03 23:32:01 +02:00
|
|
|
db_type = backend.name()
|
2014-03-18 19:59:04 +01:00
|
|
|
if db_type == 'sqlite':
|
|
|
|
|
# Must be casted as Decimal is stored as bytes
|
2014-12-20 19:24:42 +01:00
|
|
|
column = SQLite_Cast(column, self.sql_type().base)
|
2014-03-18 19:59:04 +01:00
|
|
|
return column
|
|
|
|
|
|
|
|
|
|
def _domain_value(self, operator, value):
|
|
|
|
|
value = super(Numeric, self)._domain_value(operator, value)
|
2014-09-03 23:32:01 +02:00
|
|
|
db_type = backend.name()
|
2014-03-18 19:59:04 +01:00
|
|
|
if db_type == 'sqlite':
|
|
|
|
|
if isinstance(value, (Select, CombiningQuery)):
|
|
|
|
|
return value
|
|
|
|
|
# Must be casted as Decimal is adapted to bytes
|
|
|
|
|
type_ = self.sql_type().base
|
|
|
|
|
if operator in ('in', 'not in'):
|
|
|
|
|
return [Cast(Literal(v), type_) for v in value]
|
2014-06-13 19:11:44 +02:00
|
|
|
elif value is not None:
|
2014-03-18 19:59:04 +01:00
|
|
|
return Cast(Literal(value), type_)
|
|
|
|
|
return value
|