From: gmcm Date: Thu, 18 Jul 2002 11:17:31 +0000 (+0000) Subject: Add Number and Boolean types to hyperdb. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=369fb117ee3618ba00b5386cbaa4b4f19c2db4a4;p=roundup.git Add Number and Boolean types to hyperdb. Add conversion cases to web, mail & admin interfaces. Add storage/serialization cases to back_anydbm & back_metakit. git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@892 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/roundup/admin.py b/roundup/admin.py index b8cfb84..b213c14 100644 --- a/roundup/admin.py +++ b/roundup/admin.py @@ -16,7 +16,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: admin.py,v 1.17 2002-07-14 06:05:50 richard Exp $ +# $Id: admin.py,v 1.18 2002-07-18 11:17:30 gmcm Exp $ import sys, os, getpass, getopt, re, UserDict, shlex, shutil try: @@ -439,6 +439,10 @@ Command help: props[key] = value elif isinstance(proptype, hyperdb.Multilink): props[key] = value.split(',') + elif isinstance(proptype, hyperdb.Boolean): + props[key] = value.lower() in ('yes', 'true', 'on', '1') + elif isinstance(proptype, hyperdb.Number): + props[key] = int(value) # try the set try: @@ -611,6 +615,10 @@ Command help: props[propname] = password.Password(value) elif isinstance(proptype, hyperdb.Multilink): props[propname] = value.split(',') + elif isinstance(proptype, hyperdb.Boolean): + props[propname] = value.lower() in ('yes', 'true', 'on', '1') + elif isinstance(proptype, hyperdb.Number): + props[propname] = int(value) # check for the key property propname = cl.getkey() @@ -1123,6 +1131,9 @@ if __name__ == '__main__': # # $Log: not supported by cvs2svn $ +# Revision 1.17 2002/07/14 06:05:50 richard +# . fixed the date module so that Date(". - 2d") works +# # Revision 1.16 2002/07/09 04:19:09 richard # Added reindex command to roundup-admin. # Fixed reindex on first access. diff --git a/roundup/backends/back_anydbm.py b/roundup/backends/back_anydbm.py index 29bae6e..0e56bcc 100644 --- a/roundup/backends/back_anydbm.py +++ b/roundup/backends/back_anydbm.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -#$Id: back_anydbm.py,v 1.47 2002-07-14 23:18:20 richard Exp $ +#$Id: back_anydbm.py,v 1.48 2002-07-18 11:17:31 gmcm Exp $ ''' This module defines a backend that saves the hyperdatabase in a database chosen by anydbm. It is guaranteed to always be available in python @@ -29,7 +29,7 @@ from blobfiles import FileStorage from roundup.indexer import Indexer from locking import acquire_lock, release_lock from roundup.hyperdb import String, Password, Date, Interval, Link, \ - Multilink, DatabaseError + Multilink, DatabaseError, Boolean, Number # # Now the database @@ -730,6 +730,18 @@ class Class(hyperdb.Class): if value is not None and not isinstance(value, date.Interval): raise TypeError, 'new property "%s" not an Interval'%key + elif isinstance(prop, Number): + try: + int(value) + except TypeError: + raise TypeError, 'new property "%s" not numeric' % propname + + elif isinstance(prop, Boolean): + try: + int(value) + except TypeError: + raise TypeError, 'new property "%s" is not boolean' % propname + # make sure there's data where there needs to be for key, prop in self.properties.items(): if propvalues.has_key(key): @@ -1011,6 +1023,18 @@ class Class(hyperdb.Class): 'Interval'%propname propvalues[propname] = value + elif value is not None and isinstance(prop, Number): + try: + int(value) + except TypeError: + raise TypeError, 'new property "%s" not numeric' % propname + + elif value is not None and isinstance(prop, Boolean): + try: + int(value) + except TypeError: + raise TypeError, 'new property "%s" not boolean' % propname + node[propname] = value # nothing to do? @@ -1291,6 +1315,14 @@ class Class(hyperdb.Class): v = v.replace('?', '.') v = v.replace('*', '.*?') l.append((2, k, re.compile(v, re.I))) + elif isinstance(propclass, Boolean): + if type(v) is type(''): + bv = v.lower() in ('yes', 'true', 'on', '1') + else: + bv = v + l.append((6, k, bv)) + elif isinstance(propclass, Number): + l.append((6, k, int(v))) else: l.append((6, k, v)) filterspec = l @@ -1456,6 +1488,12 @@ class Class(hyperdb.Class): elif dir == '-': r = cmp(len(bv), len(av)) if r != 0: return r + elif isinstance(propclass, Number) or isinstance(propclass, Boolean): + if dir == '+': + r = cmp(av, bv) + elif dir == '-': + r = cmp(bv, av) + # end for dir, prop in list: # end for list in sort, group: # if all else fails, compare the ids @@ -1638,6 +1676,10 @@ class IssueClass(Class, roundupdb.IssueClass): # #$Log: not supported by cvs2svn $ +#Revision 1.47 2002/07/14 23:18:20 richard +#. fixed the journal bloat from multilink changes - we just log the add or +# remove operations, not the whole list +# #Revision 1.46 2002/07/14 06:06:34 richard #Did some old TODOs # diff --git a/roundup/backends/back_metakit.py b/roundup/backends/back_metakit.py index 1c93af7..6936ea2 100755 --- a/roundup/backends/back_metakit.py +++ b/roundup/backends/back_metakit.py @@ -455,6 +455,17 @@ class Class: setattr(row, key, str(value)) changes[key] = str(oldvalue) propvalues[key] = str(value) + + elif value is not None and isinstance(prop, hyperdb.Number): + setattr(row, key, int(value)) + changes[key] = oldvalue + propvalues[key] = value + + elif value is not None and isinstance(prop, hyperdb.Boolean): + bv = value != 0 + setattr(row, key, bv) + changes[key] = oldvalue + propvalues[key] = value oldnode[key] = oldvalue @@ -661,6 +672,14 @@ class Class: regexes[propname] = re.compile(v, re.I) elif propname == 'id': where[propname] = int(value) + elif isinstance(prop, hyperdb.Boolean): + if type(value) is _STRINGTYPE: + bv = value.lower() in ('yes', 'true', 'on', '1') + else: + bv = value + where[propname] = bv + elif isinstance(prop, hyperdb.Number): + where[propname] = int(value) else: where[propname] = str(value) v = self.getview() @@ -891,6 +910,8 @@ _converters = { hyperdb.Multilink : _fetchML, hyperdb.Interval : date.Interval, hyperdb.Password : _fetchPW, + hyperdb.Boolean : lambda n: n, + hyperdb.Number : lambda n: n, } class FileName(hyperdb.String): @@ -904,6 +925,8 @@ _typmap = { hyperdb.Multilink : 'V', hyperdb.Interval : 'S', hyperdb.Password : 'S', + hyperdb.Boolean : 'I', + hyperdb.Number : 'I', } class FileClass(Class): ' like Class but with a content property ' diff --git a/roundup/cgi_client.py b/roundup/cgi_client.py index 2bc7922..715d02d 100644 --- a/roundup/cgi_client.py +++ b/roundup/cgi_client.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: cgi_client.py,v 1.141 2002-07-17 12:39:10 gmcm Exp $ +# $Id: cgi_client.py,v 1.142 2002-07-18 11:17:30 gmcm Exp $ __doc__ = """ 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+$')): l.append(entry) l.sort() value = l + elif isinstance(proptype, hyperdb.Boolean): + value = form[key].value.strip() + props[key] = value = value.lower() in ('yes', 'true', 'on', '1') + elif isinstance(proptype, hyperdb.Number): + value = form[key].value.strip() + props[key] = value = int(value) # get the old value if nodeid: @@ -1604,6 +1610,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')): # # $Log: not supported by cvs2svn $ +# Revision 1.141 2002/07/17 12:39:10 gmcm +# Saving, running & editing queries. +# # Revision 1.140 2002/07/14 23:17:15 richard # cleaned up structure # diff --git a/roundup/htmltemplate.py b/roundup/htmltemplate.py index e886901..0b930c5 100644 --- a/roundup/htmltemplate.py +++ b/roundup/htmltemplate.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: htmltemplate.py,v 1.100 2002-07-18 07:01:54 richard Exp $ +# $Id: htmltemplate.py,v 1.101 2002-07-18 11:17:30 gmcm Exp $ __doc__ = """ Template engine. @@ -107,6 +107,10 @@ class TemplateFunctions: value = str(value) elif isinstance(propclass, hyperdb.Interval): value = str(value) + elif isinstance(propclass, hyperdb.Number): + value = str(value) + elif isinstance(propclass, hyperdb.Boolean): + value = value and "Yes" or "No" elif isinstance(propclass, hyperdb.Link): if value: if lookup: @@ -199,6 +203,11 @@ class TemplateFunctions: value = cgi.escape(str(value)) value = '"'.join(value.split('"')) s = ''%(property, value, size) + elif isinstance(propclass, hyperdb.Boolean): + checked = value and "checked" or "" + s = ''%(property, checked) + elif isinstance(propclass, hyperdb.Number): + s = ''%(property, value, size) elif isinstance(propclass, hyperdb.Password): s = ''%(property, size) elif isinstance(propclass, hyperdb.Link): @@ -268,7 +277,7 @@ class TemplateFunctions: property, rows, cols, value) def do_menu(self, property, size=None, height=None, showid=0, - additional=[]): + additional=[], **conditions): ''' For a Link/Multilink property, display a menu of the available choices @@ -297,8 +306,8 @@ class TemplateFunctions: if linkcl.getprops().has_key('order'): sort_on = 'order' else: - sort_on = linkcl.labelprop() - options = linkcl.filter(None, {}, [sort_on], []) + sort_on = linkcl.labelprop() + options = linkcl.filter(None, conditions, [sort_on], []) height = height or min(len(options), 7) l = ['