| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent bc38dda commit 7f62525
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,6 +21,7 @@ Contributions have been made by: | |||
| 21 | 21 | * David Turner, The Open Planning Project | |
| 22 | 22 | * Dan Pascu <dan at ag-projects.com> | |
| 23 | 23 | * Diez B. Roggisch <deets at web.de> | |
| 24 | + * Christopher Singley <csingley at gmail.com> | ||
| 24 | 25 | * Oleg Broytmann <phd@phd.pp.ru> | |
| 25 | 26 | ||
| 26 | 27 | .. image:: http://sourceforge.net/sflogo.php?group_id=74338&type=4 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1347,38 +1347,48 @@ class CurrencyCol(DecimalCol): | |||
| 1347 | 1347 | ||
| 1348 | 1348 | ||
| 1349 | 1349 | 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 | + | ||
| 1350 | 1358 | 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)): | ||
| 1356 | 1367 | 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 | ||
| 1367 | 1369 | ||
| 1368 | 1370 | class SODecimalStringCol(SOStringCol): | |
| 1369 | 1371 | 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" | ||
| 1377 | 1382 | super(SODecimalStringCol, self).__init__(**kw) | |
| 1378 | 1383 | ||
| 1379 | 1384 | 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() | ||
| 1382 | 1392 | ||
| 1383 | 1393 | class DecimalStringCol(StringCol): | |
| 1384 | 1394 | baseClass = SODecimalStringCol | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,27 +11,52 @@ | |||
| 11 | 11 | class DecimalTable(SQLObject): | |
| 12 | 12 | name = UnicodeCol(length=255) | |
| 13 | 13 | col1 = DecimalCol(size=6, precision=4) | |
| 14 | + col2 = DecimalStringCol(size=6, precision=4) | ||
| 15 | + col3 = DecimalStringCol(size=6, precision=4, quantize=True) | ||
| 14 | 16 | ||
| 15 | 17 | if supports('decimalColumn'): | |
| 16 | 18 | def test_1_decimal(): | |
| 17 | 19 | setupClass(DecimalTable) | |
| 18 | - d = DecimalTable(name='test', col1=21.12) | ||
| 20 | + d = DecimalTable(name='test', col1=21.12, col2='10.01', col3='10.01') | ||
| 19 | 21 | # psycopg2 returns float as Decimal | |
| 20 | 22 | if isinstance(d.col1, Decimal): | |
| 21 | 23 | assert d.col1 == Decimal("21.12") | |
| 22 | 24 | else: | |
| 23 | 25 | 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" | ||
| 24 | 36 | ||
| 25 | 37 | def test_2_decimal(): | |
| 26 | 38 | 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')) | ||
| 28 | 41 | 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" | ||
| 29 | 52 | ||
| 30 | 53 | # See http://mail.python.org/pipermail/python-dev/2008-March/078189.html | |
| 31 | 54 | if isinstance(Decimal(u'123').to_eng_string(), unicode): # a bug in Python 2.5.2 | |
| 32 | 55 | def test_3_unicode(): | |
| 33 | 56 | 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') | ||
| 35 | 59 | 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') | ||
| 37 | 62 | assert d.col1 == Decimal("21.12") | |
| Back | FazBrowse Home | New Git URL |
0 commit comments