Skip to content

Commit a24dc70

Browse files
author
Gordon B. McMillan
committed
Add Number and Boolean types to hyperdb.
Add conversion cases to web, mail & admin interfaces. Add storage/serialization cases to back_anydbm & back_metakit.
1 parent 654ecf3 commit a24dc70

File tree

8 files changed

+149
-14
lines changed

8 files changed

+149
-14
lines changed

roundup/admin.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1717
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1818
#
19-
# $Id: admin.py,v 1.17 2002-07-14 06:05:50 richard Exp $
19+
# $Id: admin.py,v 1.18 2002-07-18 11:17:30 gmcm Exp $
2020

2121
import sys, os, getpass, getopt, re, UserDict, shlex, shutil
2222
try:
@@ -439,6 +439,10 @@ def do_set(self, args):
439439
props[key] = value
440440
elif isinstance(proptype, hyperdb.Multilink):
441441
props[key] = value.split(',')
442+
elif isinstance(proptype, hyperdb.Boolean):
443+
props[key] = value.lower() in ('yes', 'true', 'on', '1')
444+
elif isinstance(proptype, hyperdb.Number):
445+
props[key] = int(value)
442446

443447
# try the set
444448
try:
@@ -611,6 +615,10 @@ def do_create(self, args):
611615
props[propname] = password.Password(value)
612616
elif isinstance(proptype, hyperdb.Multilink):
613617
props[propname] = value.split(',')
618+
elif isinstance(proptype, hyperdb.Boolean):
619+
props[propname] = value.lower() in ('yes', 'true', 'on', '1')
620+
elif isinstance(proptype, hyperdb.Number):
621+
props[propname] = int(value)
614622

615623
# check for the key property
616624
propname = cl.getkey()
@@ -1123,6 +1131,9 @@ def main(self):
11231131

11241132
#
11251133
# $Log: not supported by cvs2svn $
1134+
# Revision 1.17 2002/07/14 06:05:50 richard
1135+
# . fixed the date module so that Date(". - 2d") works
1136+
#
11261137
# Revision 1.16 2002/07/09 04:19:09 richard
11271138
# Added reindex command to roundup-admin.
11281139
# Fixed reindex on first access.

roundup/backends/back_anydbm.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.47 2002-07-14 23:18:20 richard Exp $
18+
#$Id: back_anydbm.py,v 1.48 2002-07-18 11:17:31 gmcm Exp $
1919
'''
2020
This module defines a backend that saves the hyperdatabase in a database
2121
chosen by anydbm. It is guaranteed to always be available in python
@@ -29,7 +29,7 @@
2929
from roundup.indexer import Indexer
3030
from locking import acquire_lock, release_lock
3131
from roundup.hyperdb import String, Password, Date, Interval, Link, \
32-
Multilink, DatabaseError
32+
Multilink, DatabaseError, Boolean, Number
3333

3434
#
3535
# Now the database
@@ -730,6 +730,18 @@ def create(self, **propvalues):
730730
if value is not None and not isinstance(value, date.Interval):
731731
raise TypeError, 'new property "%s" not an Interval'%key
732732

733+
elif isinstance(prop, Number):
734+
try:
735+
int(value)
736+
except TypeError:
737+
raise TypeError, 'new property "%s" not numeric' % propname
738+
739+
elif isinstance(prop, Boolean):
740+
try:
741+
int(value)
742+
except TypeError:
743+
raise TypeError, 'new property "%s" is not boolean' % propname
744+
733745
# make sure there's data where there needs to be
734746
for key, prop in self.properties.items():
735747
if propvalues.has_key(key):
@@ -1011,6 +1023,18 @@ class or a KeyError is raised.
10111023
'Interval'%propname
10121024
propvalues[propname] = value
10131025

1026+
elif value is not None and isinstance(prop, Number):
1027+
try:
1028+
int(value)
1029+
except TypeError:
1030+
raise TypeError, 'new property "%s" not numeric' % propname
1031+
1032+
elif value is not None and isinstance(prop, Boolean):
1033+
try:
1034+
int(value)
1035+
except TypeError:
1036+
raise TypeError, 'new property "%s" not boolean' % propname
1037+
10141038
node[propname] = value
10151039

10161040
# nothing to do?
@@ -1291,6 +1315,14 @@ def filter(self, search_matches, filterspec, sort, group,
12911315
v = v.replace('?', '.')
12921316
v = v.replace('*', '.*?')
12931317
l.append((2, k, re.compile(v, re.I)))
1318+
elif isinstance(propclass, Boolean):
1319+
if type(v) is type(''):
1320+
bv = v.lower() in ('yes', 'true', 'on', '1')
1321+
else:
1322+
bv = v
1323+
l.append((6, k, bv))
1324+
elif isinstance(propclass, Number):
1325+
l.append((6, k, int(v)))
12941326
else:
12951327
l.append((6, k, v))
12961328
filterspec = l
@@ -1456,6 +1488,12 @@ def sortfun(a, b, sort=sort, group=group, properties=self.getprops(),
14561488
elif dir == '-':
14571489
r = cmp(len(bv), len(av))
14581490
if r != 0: return r
1491+
elif isinstance(propclass, Number) or isinstance(propclass, Boolean):
1492+
if dir == '+':
1493+
r = cmp(av, bv)
1494+
elif dir == '-':
1495+
r = cmp(bv, av)
1496+
14591497
# end for dir, prop in list:
14601498
# end for list in sort, group:
14611499
# if all else fails, compare the ids
@@ -1638,6 +1676,10 @@ def __init__(self, db, classname, **properties):
16381676

16391677
#
16401678
#$Log: not supported by cvs2svn $
1679+
#Revision 1.47 2002/07/14 23:18:20 richard
1680+
#. fixed the journal bloat from multilink changes - we just log the add or
1681+
# remove operations, not the whole list
1682+
#
16411683
#Revision 1.46 2002/07/14 06:06:34 richard
16421684
#Did some old TODOs
16431685
#

roundup/backends/back_metakit.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,17 @@ def set(self, nodeid, **propvalues):
455455
setattr(row, key, str(value))
456456
changes[key] = str(oldvalue)
457457
propvalues[key] = str(value)
458+
459+
elif value is not None and isinstance(prop, hyperdb.Number):
460+
setattr(row, key, int(value))
461+
changes[key] = oldvalue
462+
propvalues[key] = value
463+
464+
elif value is not None and isinstance(prop, hyperdb.Boolean):
465+
bv = value != 0
466+
setattr(row, key, bv)
467+
changes[key] = oldvalue
468+
propvalues[key] = value
458469

459470
oldnode[key] = oldvalue
460471

@@ -661,6 +672,14 @@ def filter(self, search_matches, filterspec, sort, group):
661672
regexes[propname] = re.compile(v, re.I)
662673
elif propname == 'id':
663674
where[propname] = int(value)
675+
elif isinstance(prop, hyperdb.Boolean):
676+
if type(value) is _STRINGTYPE:
677+
bv = value.lower() in ('yes', 'true', 'on', '1')
678+
else:
679+
bv = value
680+
where[propname] = bv
681+
elif isinstance(prop, hyperdb.Number):
682+
where[propname] = int(value)
664683
else:
665684
where[propname] = str(value)
666685
v = self.getview()
@@ -891,6 +910,8 @@ def _fetchDate(n):
891910
hyperdb.Multilink : _fetchML,
892911
hyperdb.Interval : date.Interval,
893912
hyperdb.Password : _fetchPW,
913+
hyperdb.Boolean : lambda n: n,
914+
hyperdb.Number : lambda n: n,
894915
}
895916

896917
class FileName(hyperdb.String):
@@ -904,6 +925,8 @@ class FileName(hyperdb.String):
904925
hyperdb.Multilink : 'V',
905926
hyperdb.Interval : 'S',
906927
hyperdb.Password : 'S',
928+
hyperdb.Boolean : 'I',
929+
hyperdb.Number : 'I',
907930
}
908931
class FileClass(Class):
909932
' like Class but with a content property '

roundup/cgi_client.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: cgi_client.py,v 1.141 2002-07-17 12:39:10 gmcm Exp $
18+
# $Id: cgi_client.py,v 1.142 2002-07-18 11:17:30 gmcm Exp $
1919

2020
__doc__ = """
2121
WWW request handler (also used in the stand-alone server).
@@ -1585,6 +1585,12 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
15851585
l.append(entry)
15861586
l.sort()
15871587
value = l
1588+
elif isinstance(proptype, hyperdb.Boolean):
1589+
value = form[key].value.strip()
1590+
props[key] = value = value.lower() in ('yes', 'true', 'on', '1')
1591+
elif isinstance(proptype, hyperdb.Number):
1592+
value = form[key].value.strip()
1593+
props[key] = value = int(value)
15881594

15891595
# get the old value
15901596
if nodeid:
@@ -1604,6 +1610,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
16041610

16051611
#
16061612
# $Log: not supported by cvs2svn $
1613+
# Revision 1.141 2002/07/17 12:39:10 gmcm
1614+
# Saving, running & editing queries.
1615+
#
16071616
# Revision 1.140 2002/07/14 23:17:15 richard
16081617
# cleaned up structure
16091618
#

roundup/htmltemplate.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: htmltemplate.py,v 1.100 2002-07-18 07:01:54 richard Exp $
18+
# $Id: htmltemplate.py,v 1.101 2002-07-18 11:17:30 gmcm Exp $
1919

2020
__doc__ = """
2121
Template engine.
@@ -107,6 +107,10 @@ def do_plain(self, property, escape=0, lookup=1):
107107
value = str(value)
108108
elif isinstance(propclass, hyperdb.Interval):
109109
value = str(value)
110+
elif isinstance(propclass, hyperdb.Number):
111+
value = str(value)
112+
elif isinstance(propclass, hyperdb.Boolean):
113+
value = value and "Yes" or "No"
110114
elif isinstance(propclass, hyperdb.Link):
111115
if value:
112116
if lookup:
@@ -199,6 +203,11 @@ def do_field(self, property, size=None, showid=0):
199203
value = cgi.escape(str(value))
200204
value = '"'.join(value.split('"'))
201205
s = '<input name="%s" value="%s" size="%s">'%(property, value, size)
206+
elif isinstance(propclass, hyperdb.Boolean):
207+
checked = value and "checked" or ""
208+
s = '<input type="checkbox" name="%s" %s>'%(property, checked)
209+
elif isinstance(propclass, hyperdb.Number):
210+
s = '<input name="%s" value="%s" size="%s">'%(property, value, size)
202211
elif isinstance(propclass, hyperdb.Password):
203212
s = '<input type="password" name="%s" size="%s">'%(property, size)
204213
elif isinstance(propclass, hyperdb.Link):
@@ -268,7 +277,7 @@ def do_multiline(self, property, rows=5, cols=40):
268277
property, rows, cols, value)
269278

270279
def do_menu(self, property, size=None, height=None, showid=0,
271-
additional=[]):
280+
additional=[], **conditions):
272281
''' For a Link/Multilink property, display a menu of the available
273282
choices
274283
@@ -297,8 +306,8 @@ def do_menu(self, property, size=None, height=None, showid=0,
297306
if linkcl.getprops().has_key('order'):
298307
sort_on = 'order'
299308
else:
300-
sort_on = linkcl.labelprop()
301-
options = linkcl.filter(None, {}, [sort_on], [])
309+
sort_on = linkcl.labelprop()
310+
options = linkcl.filter(None, conditions, [sort_on], [])
302311
height = height or min(len(options), 7)
303312
l = ['<select multiple name="%s" size="%s">'%(property, height)]
304313
k = linkcl.labelprop(1)
@@ -337,8 +346,8 @@ def do_menu(self, property, size=None, height=None, showid=0,
337346
if linkcl.getprops().has_key('order'):
338347
sort_on = 'order'
339348
else:
340-
sort_on = linkcl.labelprop()
341-
options = linkcl.filter(None, {}, [sort_on], [])
349+
sort_on = linkcl.labelprop()
350+
options = linkcl.filter(None, conditions, [sort_on], [])
342351
for optionid in options:
343352
option = linkcl.get(optionid, k)
344353
s = ''
@@ -1135,6 +1144,18 @@ def filter_form(self, search_text, filter, columns, group, all_columns, sort, fi
11351144
op = "equals&nbsp;"
11361145
xtra = ""
11371146
val = filterspec.get(nm, '')
1147+
elif isinstance(propdescr, hyperdb.Boolean):
1148+
op = "is&nbsp;"
1149+
xtra = ""
1150+
val = filterspec.get(nm, None)
1151+
if val is not None:
1152+
val = 'True' and val or 'False'
1153+
else:
1154+
val = ''
1155+
elif isinstance(propdescr, hyperdb.Number):
1156+
op = "equals&nbsp;"
1157+
xtra = ""
1158+
val = str(filterspec.get(nm, ''))
11381159
else:
11391160
w('<td></td><td></td><td></td></tr>')
11401161
continue
@@ -1341,6 +1362,9 @@ def render(self, form):
13411362

13421363
#
13431364
# $Log: not supported by cvs2svn $
1365+
# Revision 1.100 2002/07/18 07:01:54 richard
1366+
# minor bugfix
1367+
#
13441368
# Revision 1.99 2002/07/17 12:39:10 gmcm
13451369
# Saving, running & editing queries.
13461370
#

roundup/hyperdb.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: hyperdb.py,v 1.75 2002-07-14 02:05:53 richard Exp $
18+
# $Id: hyperdb.py,v 1.76 2002-07-18 11:17:30 gmcm Exp $
1919

2020
__doc__ = """
2121
Hyperdatabase implementation, especially field types.
@@ -110,6 +110,17 @@ def __repr__(self):
110110
' more useful for dumps '
111111
return '<%s to "%s">'%(self.__class__, self.classname)
112112

113+
class Boolean:
114+
"""An object designating a boolean property"""
115+
def __repr__(self):
116+
'more useful for dumps'
117+
return '<%s>' % self.__class__
118+
119+
class Number:
120+
"""An object designating a numeric property"""
121+
def __repr__(self):
122+
'more useful for dumps'
123+
return '<%s>' % self.__class__
113124
#
114125
# Support for splitting designators
115126
#
@@ -580,6 +591,9 @@ def Choice(name, db, *options):
580591

581592
#
582593
# $Log: not supported by cvs2svn $
594+
# Revision 1.75 2002/07/14 02:05:53 richard
595+
# . all storage-specific code (ie. backend) is now implemented by the backends
596+
#
583597
# Revision 1.74 2002/07/10 00:24:10 richard
584598
# braino
585599
#

roundup/indexer.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# that promote freedom, but obviously am giving up any rights
1515
# to compel such.
1616
#
17-
#$Id: indexer.py,v 1.10 2002-07-14 23:17:24 richard Exp $
17+
#$Id: indexer.py,v 1.11 2002-07-18 11:17:30 gmcm Exp $
1818
'''
1919
This module provides an indexer class, RoundupIndexer, that stores text
2020
indices in a roundup instance. This class makes searching the content of
@@ -49,7 +49,7 @@ def __init__(self, db_path):
4949
elif os.path.exists(version):
5050
version = open(version).read()
5151
# check the value and reindex if it's not the latest
52-
if version != '1':
52+
if version.strip() != '1':
5353
self.force_reindex()
5454

5555
def force_reindex(self):
@@ -333,6 +333,9 @@ def index_loaded(self):
333333

334334
#
335335
#$Log: not supported by cvs2svn $
336+
#Revision 1.10 2002/07/14 23:17:24 richard
337+
#oops
338+
#
336339
#Revision 1.9 2002/07/14 06:11:16 richard
337340
#Some TODOs
338341
#

0 commit comments

Comments
 (0)