FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

DecimalStringValidator now supports quantization, · sqlobject/sqlobject@7f62525 · GitHub

Commit 7f62525

Browse files
committed
DecimalStringValidator now supports quantization,
thanks to Christopher Singley <csingley at gmail.com>. git-svn-id: http://svn.colorstudy.com/SQLObject/trunk@3504 95a46c32-92d2-0310-94a5-8d71aeb3d4b3
1 parent bc38dda commit 7f62525

3 files changed

Lines changed: 64 additions & 28 deletions

File tree

‎docs/Authors.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Contributions have been made by:
2121
* David Turner, The Open Planning Project
2222
* Dan Pascu <dan at ag-projects.com>
2323
* Diez B. Roggisch <deets at web.de>
24+
* Christopher Singley <csingley at gmail.com>
2425
* Oleg Broytmann <phd@phd.pp.ru>
2526

2627
.. image:: http://sourceforge.net/sflogo.php?group_id=74338&type=4

‎sqlobject/col.py‎

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,38 +1347,48 @@ class CurrencyCol(DecimalCol):
13471347

13481348

13491349
class DecimalStringValidator(DecimalValidator):
1350+
def to_python(self, value, state):
1351+
value = super(DecimalStringValidator, self).to_python(value, state)
1352+
if self.precision and isinstance(value, Decimal):
1353+
assert value < self.max, \
1354+
"Value must be less than %s" % int(self.max)
1355+
value = value.quantize(self.precision)
1356+
return value
1357+
13501358
def from_python(self, value, state):
1351-
if value is None:
1352-
return None
1353-
if isinstance(value, sqlbuilder.SQLExpression):
1354-
return value
1355-
if not isinstance(value, basestring):
1359+
value = super(DecimalStringValidator, self).from_python(value, state)
1360+
if isinstance(value, Decimal):
1361+
if self.precision:
1362+
assert value < self.max, \
1363+
"Value must be less than %s" % int(self.max)
1364+
value = value.quantize(self.precision)
1365+
value = value.to_eng_string()
1366+
elif isinstance(value, (int, long)):
13561367
value = str(value)
1357-
connection = state.soObject._connection
1358-
if hasattr(connection, "decimalSeparator"):
1359-
value = value.replace(connection.decimalSeparator, ".")
1360-
try:
1361-
Decimal(value) # Test if the value is valid
1362-
except:
1363-
raise validators.Invalid("can not parse Decimal value '%s' in the DecimalCol from '%s'" %
1364-
(value, getattr(state, 'soObject', '(unknown)')), value, state)
1365-
else:
1366-
return value
1368+
return value
13671369

13681370
class SODecimalStringCol(SOStringCol):
13691371
def __init__(self, **kw):
1370-
size = kw.pop('size', NoDefault)
1371-
assert size is not NoDefault, \
1372-
"You must give a size argument"
1373-
precision = kw.pop('precision', NoDefault)
1374-
assert precision is not NoDefault, \
1375-
"You must give a precision argument"
1376-
kw['length'] = size + precision
1372+
self.size = kw.pop('size', NoDefault)
1373+
assert (self.size is not NoDefault) and (self.size >= 0), \
1374+
"You must give a size argument as a positive integer"
1375+
self.precision = kw.pop('precision', NoDefault)
1376+
assert (self.precision is not NoDefault) and (self.precision >= 0), \
1377+
"You must give a precision argument as a positive integer"
1378+
kw['length'] = int(self.size) + int(self.precision)
1379+
self.quantize = kw.pop('quantize', False)
1380+
assert isinstance(self.quantize, bool), \
1381+
"quantize argument must be Boolean True/False"
13771382
super(SODecimalStringCol, self).__init__(**kw)
13781383

13791384
def createValidators(self):
1380-
return [DecimalStringValidator()] + \
1381-
super(SODecimalStringCol, self).createValidators()
1385+
if self.quantize:
1386+
v = DecimalStringValidator(
1387+
precision=Decimal(10) ** (-1 * int(self.precision)),
1388+
max=Decimal(10) ** (int(self.size) - int(self.precision)))
1389+
else:
1390+
v = DecimalStringValidator(precision=0)
1391+
return [v] + super(SODecimalStringCol, self).createValidators()
13821392

13831393
class DecimalStringCol(StringCol):
13841394
baseClass = SODecimalStringCol

‎sqlobject/tests/test_decimal.py‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,52 @@
1111
class DecimalTable(SQLObject):
1212
name = UnicodeCol(length=255)
1313
col1 = DecimalCol(size=6, precision=4)
14+
col2 = DecimalStringCol(size=6, precision=4)
15+
col3 = DecimalStringCol(size=6, precision=4, quantize=True)
1416

1517
if supports('decimalColumn'):
1618
def test_1_decimal():
1719
setupClass(DecimalTable)
18-
d = DecimalTable(name='test', col1=21.12)
20+
d = DecimalTable(name='test', col1=21.12, col2='10.01', col3='10.01')
1921
# psycopg2 returns float as Decimal
2022
if isinstance(d.col1, Decimal):
2123
assert d.col1 == Decimal("21.12")
2224
else:
2325
assert d.col1 == 21.12
26+
assert d.col2 == Decimal("10.01")
27+
assert DecimalTable.sqlmeta.columns['col2'].to_python('10.01',
28+
d._SO_validatorState) == Decimal("10.01")
29+
assert DecimalTable.sqlmeta.columns['col2'].from_python('10.01',
30+
d._SO_validatorState) == "10.01"
31+
assert d.col3 == Decimal("10.01")
32+
assert DecimalTable.sqlmeta.columns['col3'].to_python('10.01',
33+
d._SO_validatorState) == Decimal("10.01")
34+
assert DecimalTable.sqlmeta.columns['col3'].from_python('10.01',
35+
d._SO_validatorState) == "10.0100"
2436

2537
def test_2_decimal():
2638
setupClass(DecimalTable)
27-
d = DecimalTable(name='test', col1=Decimal("21.12"))
39+
d = DecimalTable(name='test', col1=Decimal("21.12"),
40+
col2=Decimal('10.01'), col3=Decimal('10.01'))
2841
assert d.col1 == Decimal("21.12")
42+
assert d.col2 == Decimal("10.01")
43+
assert DecimalTable.sqlmeta.columns['col2'].to_python(Decimal('10.01'),
44+
d._SO_validatorState) == Decimal("10.01")
45+
assert DecimalTable.sqlmeta.columns['col2'].from_python(Decimal('10.01'),
46+
d._SO_validatorState) == "10.01"
47+
assert d.col3 == Decimal("10.01")
48+
assert DecimalTable.sqlmeta.columns['col3'].to_python(Decimal('10.01'),
49+
d._SO_validatorState) == Decimal("10.01")
50+
assert DecimalTable.sqlmeta.columns['col3'].from_python(Decimal('10.01'),
51+
d._SO_validatorState) == "10.0100"
2952

3053
# See http://mail.python.org/pipermail/python-dev/2008-March/078189.html
3154
if isinstance(Decimal(u'123').to_eng_string(), unicode): # a bug in Python 2.5.2
3255
def test_3_unicode():
3356
setupClass(DecimalTable)
34-
d = DecimalTable(name='test', col1=Decimal(u"21.12"))
57+
d = DecimalTable(name='test', col1=Decimal(u"21.12"),
58+
col2='10.01', col3='10.01')
3559
assert d.col1 == Decimal("21.12")
36-
d = DecimalTable(name=unicode('ÔÅÓÔ', 'koi8-r'), col1=Decimal(u"21.12"))
60+
d = DecimalTable(name=unicode('ÔÅÓÔ', 'koi8-r'), col1=Decimal(u"21.12"),
61+
col2='10.01', col3='10.01')
3762
assert d.col1 == Decimal("21.12")

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL