Skip to content

Commit 39d368f

Browse files
committed
Add support for an integer type to join the existing number type.
Commit patch supplied for issue2550886. This can be used for properties used for ordering, counts etc. where a decimal point isn't needed. Developed by Anthony (antmail). Doc updates written by John Rouillard.
1 parent 67c5f72 commit 39d368f

17 files changed

+211
-16
lines changed

CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Features:
2828
- Allow multiple file uploads: If the html template specifies
2929
multiple="multiple" for a file upload the user can attach multiple
3030
files and the form parser now handles this. (Ralf Schlatterbeck)
31+
- issue2550886: Add support for an integer type to join the existing
32+
number type. This can be used for properties used for ordering,
33+
counts etc. where a decimal point isn't needed. Developed by
34+
Anthony (antmail). Doc updates written by John Rouillard. (applied
35+
by John Rouillard)
3136

3237
Fixed:
3338

doc/FAQ.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ How is sorting performed, and why does it seem to fail sometimes?
204204
When we sort items in the hyperdb, we use one of a number of methods,
205205
depending on the properties being sorted on:
206206

207-
1. If it's a String, Number, Date or Interval property, we just sort the
208-
scalar value of the property. Strings are sorted case-sensitively.
207+
1. If it's a String, Integer, Number, Date or Interval property, we
208+
just sort the scalar value of the property. Strings are sorted
209+
case-sensitively.
209210
2. If it's a Link property, we sort by either the linked item's "order"
210211
property (if it has one) or the linked item's "id".
211212
3. Mulitlinks sort similar to #2, but we start with the first

doc/customizing.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ A Class is comprised of one or more properties of the following types:
655655
class.
656656
* Date properties store date-and-time stamps. Their values are Timestamp
657657
objects.
658+
* Integer properties store integer values. (Number can store real/float values.)
658659
* Number properties store numeric values.
659660
* Boolean properties store on/off, yes/no, true/false values.
660661
* A Link property refers to a single other item selected from a
@@ -814,8 +815,9 @@ A note about ordering
814815
When we sort items in the hyperdb, we use one of a number of methods,
815816
depending on the properties being sorted on:
816817

817-
1. If it's a String, Number, Date or Interval property, we just sort the
818-
scalar value of the property. Strings are sorted case-sensitively.
818+
1. If it's a String, Integer, Number, Date or Interval property, we
819+
just sort the scalar value of the property. Strings are sorted
820+
case-sensitively.
819821
2. If it's a Link property, we sort by either the linked item's "order"
820822
property (if it has one) or the linked item's "id".
821823
3. Mulitlinks sort similar to #2, but we start with the first Multilink
@@ -1660,7 +1662,7 @@ None of the above (ie. just a simple form value)
16601662
they are valid for the class). Otherwise, the property
16611663
is set to the form value.
16621664

1663-
For Date(), Interval(), Boolean(), and Number()
1665+
For Date(), Interval(), Boolean(), Integer() and Number()
16641666
properties, the form value is converted to the
16651667
appropriate
16661668

doc/design.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ A property may be one of five basic types:
227227

228228
- Boolean properties are for storing true/false, or yes/no values.
229229

230+
- Integer properties are for storing Integer (non real) numeric values.
231+
230232
- Number properties are for storing numeric values.
231233

232234
- Date properties store date-and-time stamps. Their values are Timestamp
@@ -263,6 +265,10 @@ properties belong in classes::
263265
def __init__(self):
264266
"""An object designating a Boolean property."""
265267

268+
class Integer:
269+
def __init__(self):
270+
"""An object designating an Integer property."""
271+
266272
class Number:
267273
def __init__(self):
268274
"""An object designating a Number property."""
@@ -1024,7 +1030,7 @@ the printed results:
10241030

10251031
- Strings are, well, strings.
10261032

1027-
- Numbers are displayed the same as strings.
1033+
- Integers/Numbers are displayed the same as strings.
10281034

10291035
- Booleans are displayed as 'Yes' or 'No'.
10301036

@@ -1646,7 +1652,7 @@ and Dean Tribble for their assistance with the first-round submission.
16461652
Changes to this document
16471653
------------------------
16481654

1649-
- Added Boolean and Number types
1655+
- Added Boolean, Integer and Number types
16501656
- Added section Hyperdatabase Implementations
16511657
- "Item" has been renamed to "Issue" to account for the more specific
16521658
nature of the Class.

roundup/backends/back_anydbm.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,12 @@ def create_inner(self, **propvalues):
10011001
except ValueError:
10021002
raise TypeError('new property "%s" not numeric'%key)
10031003

1004+
elif value is not None and isinstance(prop, hyperdb.Integer):
1005+
try:
1006+
int(value)
1007+
except ValueError:
1008+
raise TypeError('new property "%s" not an integer'%key)
1009+
10041010
elif value is not None and isinstance(prop, hyperdb.Boolean):
10051011
try:
10061012
int(value)
@@ -1342,6 +1348,13 @@ def set_inner(self, nodeid, **propvalues):
13421348
raise TypeError('new property "%s" not '
13431349
'numeric'%propname)
13441350

1351+
elif value is not None and isinstance(prop, hyperdb.Integer):
1352+
try:
1353+
int(value)
1354+
except ValueError:
1355+
raise TypeError('new property "%s" not '
1356+
'numeric'%propname)
1357+
13451358
elif value is not None and isinstance(prop, hyperdb.Boolean):
13461359
try:
13471360
int(value)
@@ -1748,6 +1761,14 @@ def _filter(self, search_matches, filterspec, proptree,
17481761
v = [v]
17491762
l.append((OTHER, k, [float(val) for val in v]))
17501763

1764+
elif isinstance(propclass, hyperdb.Integer):
1765+
if type(v) != type([]):
1766+
try :
1767+
v = v.split(',')
1768+
except AttributeError :
1769+
v = [v]
1770+
l.append((OTHER, k, [int(val) for val in v]))
1771+
17511772
filterspec = l
17521773

17531774
# now, find all the nodes that are active and pass filtering

roundup/backends/back_mysql.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class Database(Database):
129129
hyperdb.Password : 'VARCHAR(255)',
130130
hyperdb.Boolean : 'BOOL',
131131
hyperdb.Number : 'REAL',
132+
hyperdb.Integer : 'INTEGER',
132133
}
133134

134135
hyperdb_to_sql_value = {
@@ -140,6 +141,7 @@ class Database(Database):
140141
hyperdb.Password : str,
141142
hyperdb.Boolean : int,
142143
hyperdb.Number : lambda x: x,
144+
hyperdb.Integer : int,
143145
hyperdb.Multilink : lambda x: x, # used in journal marshalling
144146
}
145147

@@ -299,6 +301,8 @@ def add_new_columns_v2(self):
299301
v = date.Interval(v)
300302
elif isinstance(prop, Password) and v is not None:
301303
v = password.Password(encrypted=v)
304+
elif isinstance(prop, Integer) and v is not None:
305+
v = int(v)
302306
elif (isinstance(prop, Boolean) or
303307
isinstance(prop, Number)) and v is not None:
304308
v = float(v)

roundup/backends/back_sqlite.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Database(rdbms_common.Database):
5151
hyperdb.Password : 'VARCHAR(255)',
5252
hyperdb.Boolean : 'BOOLEAN',
5353
hyperdb.Number : 'REAL',
54+
hyperdb.Integer : 'INTEGER',
5455
}
5556
hyperdb_to_sql_value = {
5657
hyperdb.String : str,
@@ -59,6 +60,7 @@ class Database(rdbms_common.Database):
5960
hyperdb.Interval : str,
6061
hyperdb.Password : str,
6162
hyperdb.Boolean : int,
63+
hyperdb.Integer : int,
6264
hyperdb.Number : lambda x: x,
6365
hyperdb.Multilink : lambda x: x, # used in journal marshalling
6466
}
@@ -69,6 +71,7 @@ class Database(rdbms_common.Database):
6971
hyperdb.Interval : date.Interval,
7072
hyperdb.Password : lambda x: password.Password(encrypted=x),
7173
hyperdb.Boolean : int,
74+
hyperdb.Integer : int,
7275
hyperdb.Number : rdbms_common._num_cvt,
7376
hyperdb.Multilink : lambda x: x, # used in journal marshalling
7477
}

roundup/backends/rdbms_common.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
# roundup modules
5858
from roundup import hyperdb, date, password, roundupdb, security, support
5959
from roundup.hyperdb import String, Password, Date, Interval, Link, \
60-
Multilink, DatabaseError, Boolean, Number, Node
60+
Multilink, DatabaseError, Boolean, Number, Integer, Node
6161
from roundup.backends import locking
6262
from roundup.i18n import _
6363

@@ -464,6 +464,7 @@ def reindex(self, classname=None, show_progress=False):
464464
hyperdb.Password : 'VARCHAR(255)',
465465
hyperdb.Boolean : 'BOOLEAN',
466466
hyperdb.Number : 'REAL',
467+
hyperdb.Integer : 'INTEGER',
467468
}
468469

469470
def hyperdb_to_sql_datatype(self, propclass):
@@ -871,6 +872,7 @@ def clear(self):
871872
hyperdb.Password : str,
872873
hyperdb.Boolean : lambda x: x and 'TRUE' or 'FALSE',
873874
hyperdb.Number : lambda x: x,
875+
hyperdb.Integer : lambda x: x,
874876
hyperdb.Multilink : lambda x: x, # used in journal marshalling
875877
}
876878

@@ -1084,6 +1086,7 @@ def setnode(self, classname, nodeid, values, multilink_changes={}):
10841086
hyperdb.Password : lambda x: password.Password(encrypted=x),
10851087
hyperdb.Boolean : _bool_cvt,
10861088
hyperdb.Number : _num_cvt,
1089+
hyperdb.Integer : int,
10871090
hyperdb.Multilink : lambda x: x, # used in journal marshalling
10881091
}
10891092

@@ -1632,6 +1635,12 @@ def create_inner(self, **propvalues):
16321635
except ValueError:
16331636
raise TypeError('new property "%s" not numeric'%key)
16341637

1638+
elif value is not None and isinstance(prop, Integer):
1639+
try:
1640+
int(value)
1641+
except ValueError:
1642+
raise TypeError('new property "%s" not integer'%key)
1643+
16351644
elif value is not None and isinstance(prop, Boolean):
16361645
try:
16371646
int(value)
@@ -1931,6 +1940,12 @@ def set_inner(self, nodeid, **propvalues):
19311940
except ValueError:
19321941
raise TypeError('new property "%s" not numeric'%propname)
19331942

1943+
elif value is not None and isinstance(prop, Integer):
1944+
try:
1945+
int(value)
1946+
except ValueError:
1947+
raise TypeError('new property "%s" not integer'%propname)
1948+
19341949
elif value is not None and isinstance(prop, Boolean):
19351950
try:
19361951
int(value)

roundup/cgi/actions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ def handle(self):
363363
value = value.lower() in ('yes', 'true', 'on', '1')
364364
elif isinstance(prop, hyperdb.Number):
365365
value = float(value)
366+
elif isinstance(prop, hyperdb.Integer):
367+
value = int(value)
366368
d[name] = value
367369
elif exists:
368370
# nuke the existing value

roundup/cgi/form_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def parse(self, create=0, num_re=re.compile('^\d+$')):
135135
they are valid for the class). Otherwise, the property
136136
is set to the form value.
137137
138-
For Date(), Interval(), Boolean(), and Number()
138+
For Date(), Interval(), Boolean(), and Number(), Integer()
139139
properties, the form value is converted to the
140140
appropriate
141141
@@ -519,7 +519,7 @@ def parse(self, create=0, num_re=re.compile('^\d+$')):
519519
# some backends store "missing" Strings as empty strings
520520
if existing == self.db.BACKEND_MISSING_STRING:
521521
existing = None
522-
elif isinstance(proptype, hyperdb.Number):
522+
elif isinstance(proptype, hyperdb.Number) or isinstance(proptype, hyperdb.Integer):
523523
# some backends store "missing" Numbers as 0 :(
524524
if existing == self.db.BACKEND_MISSING_NUMBER:
525525
existing = None

0 commit comments

Comments
 (0)