Author: phd
Date: 2008-07-11 10:37:56 -0600 (Fri, 11 Jul 2008)
New Revision: 3504
Modified:
SQLObject/trunk/docs/Authors.txt
SQLObject/trunk/sqlobject/col.py
SQLObject/trunk/sqlobject/tests/test_decimal.py
Log:
DecimalStringValidator now supports quantization,
thanks to Christopher Singley <csingley at gmail.com>.
Modified: SQLObject/trunk/docs/Authors.txt
===================================================================
--- SQLObject/trunk/docs/Authors.txt 2008-07-11 15:29:51 UTC (rev 3503)
+++ SQLObject/trunk/docs/Authors.txt 2008-07-11 16:37:56 UTC (rev 3504)
@@ -21,6 +21,7 @@
* David Turner, The Open Planning Project
* Dan Pascu <dan at ag-projects.com>
* Diez B. Roggisch <deets at web.de>
+* Christopher Singley <csingley at gmail.com>
* Oleg Broytmann <ph...@ph...>
.. image:: http://sourceforge.net/sflogo.php?group_id=74338&type=4
Modified: SQLObject/trunk/sqlobject/col.py
===================================================================
--- SQLObject/trunk/sqlobject/col.py 2008-07-11 15:29:51 UTC (rev 3503)
+++ SQLObject/trunk/sqlobject/col.py 2008-07-11 16:37:56 UTC (rev 3504)
@@ -1347,38 +1347,48 @@
class DecimalStringValidator(DecimalValidator):
+ def to_python(self, value, state):
+ value = super(DecimalStringValidator, self).to_python(value, state)
+ if self.precision and isinstance(value, Decimal):
+ assert value < self.max, \
+ "Value must be less than %s" % int(self.max)
+ value = value.quantize(self.precision)
+ return value
+
def from_python(self, value, state):
- if value is None:
- return None
- if isinstance(value, sqlbuilder.SQLExpression):
- return value
- if not isinstance(value, basestring):
+ value = super(DecimalStringValidator, self).from_python(value, state)
+ if isinstance(value, Decimal):
+ if self.precision:
+ assert value < self.max, \
+ "Value must be less than %s" % int(self.max)
+ value = value.quantize(self.precision)
+ value = value.to_eng_string()
+ elif isinstance(value, (int, long)):
value = str(value)
- connection = state.soObject._connection
- if hasattr(connection, "decimalSeparator"):
- value = value.replace(connection.decimalSeparator, ".")
- try:
- Decimal(value) # Test if the value is valid
- except:
- raise validators.Invalid("can not parse Decimal value '%s' in the DecimalCol from '%s'" %
- (value, getattr(state, 'soObject', '(unknown)')), value, state)
- else:
- return value
+ return value
class SODecimalStringCol(SOStringCol):
def __init__(self, **kw):
- size = kw.pop('size', NoDefault)
- assert size is not NoDefault, \
- "You must give a size argument"
- precision = kw.pop('precision', NoDefault)
- assert precision is not NoDefault, \
- "You must give a precision argument"
- kw['length'] = size + precision
+ self.size = kw.pop('size', NoDefault)
+ assert (self.size is not NoDefault) and (self.size >= 0), \
+ "You must give a size argument as a positive integer"
+ self.precision = kw.pop('precision', NoDefault)
+ assert (self.precision is not NoDefault) and (self.precision >= 0), \
+ "You must give a precision argument as a positive integer"
+ kw['length'] = int(self.size) + int(self.precision)
+ self.quantize = kw.pop('quantize', False)
+ assert isinstance(self.quantize, bool), \
+ "quantize argument must be Boolean True/False"
super(SODecimalStringCol, self).__init__(**kw)
def createValidators(self):
- return [DecimalStringValidator()] + \
- super(SODecimalStringCol, self).createValidators()
+ if self.quantize:
+ v = DecimalStringValidator(
+ precision=Decimal(10) ** (-1 * int(self.precision)),
+ max=Decimal(10) ** (int(self.size) - int(self.precision)))
+ else:
+ v = DecimalStringValidator(precision=0)
+ return [v] + super(SODecimalStringCol, self).createValidators()
class DecimalStringCol(StringCol):
baseClass = SODecimalStringCol
Modified: SQLObject/trunk/sqlobject/tests/test_decimal.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_decimal.py 2008-07-11 15:29:51 UTC (rev 3503)
+++ SQLObject/trunk/sqlobject/tests/test_decimal.py 2008-07-11 16:37:56 UTC (rev 3504)
@@ -11,27 +11,52 @@
class DecimalTable(SQLObject):
name = UnicodeCol(length=255)
col1 = DecimalCol(size=6, precision=4)
+ col2 = DecimalStringCol(size=6, precision=4)
+ col3 = DecimalStringCol(size=6, precision=4, quantize=True)
if supports('decimalColumn'):
def test_1_decimal():
setupClass(DecimalTable)
- d = DecimalTable(name='test', col1=21.12)
+ d = DecimalTable(name='test', col1=21.12, col2='10.01', col3='10.01')
# psycopg2 returns float as Decimal
if isinstance(d.col1, Decimal):
assert d.col1 == Decimal("21.12")
else:
assert d.col1 == 21.12
+ assert d.col2 == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col2'].to_python('10.01',
+ d._SO_validatorState) == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col2'].from_python('10.01',
+ d._SO_validatorState) == "10.01"
+ assert d.col3 == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col3'].to_python('10.01',
+ d._SO_validatorState) == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col3'].from_python('10.01',
+ d._SO_validatorState) == "10.0100"
def test_2_decimal():
setupClass(DecimalTable)
- d = DecimalTable(name='test', col1=Decimal("21.12"))
+ d = DecimalTable(name='test', col1=Decimal("21.12"),
+ col2=Decimal('10.01'), col3=Decimal('10.01'))
assert d.col1 == Decimal("21.12")
+ assert d.col2 == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col2'].to_python(Decimal('10.01'),
+ d._SO_validatorState) == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col2'].from_python(Decimal('10.01'),
+ d._SO_validatorState) == "10.01"
+ assert d.col3 == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col3'].to_python(Decimal('10.01'),
+ d._SO_validatorState) == Decimal("10.01")
+ assert DecimalTable.sqlmeta.columns['col3'].from_python(Decimal('10.01'),
+ d._SO_validatorState) == "10.0100"
# See http://mail.python.org/pipermail/python-dev/2008-March/078189.html
if isinstance(Decimal(u'123').to_eng_string(), unicode): # a bug in Python 2.5.2
def test_3_unicode():
setupClass(DecimalTable)
- d = DecimalTable(name='test', col1=Decimal(u"21.12"))
+ d = DecimalTable(name='test', col1=Decimal(u"21.12"),
+ col2='10.01', col3='10.01')
assert d.col1 == Decimal("21.12")
- d = DecimalTable(name=unicode('', 'koi8-r'), col1=Decimal(u"21.12"))
+ d = DecimalTable(name=unicode('', 'koi8-r'), col1=Decimal(u"21.12"),
+ col2='10.01', col3='10.01')
assert d.col1 == Decimal("21.12")
|