summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c69d7a9)
raw | patch | inline | side by side (parent: c69d7a9)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Wed, 3 Apr 2002 05:54:31 +0000 (05:54 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Wed, 3 Apr 2002 05:54:31 +0000 (05:54 +0000) |
hyperdb.Class (get, set) into the hyperdb.Database.
Also fixed htmltemplate after the showid changes I made yesterday.
Unit tests for all of the above written.
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@690 57a73879-2fb5-44c3-a270-3262357dd7e2
Also fixed htmltemplate after the showid changes I made yesterday.
Unit tests for all of the above written.
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@690 57a73879-2fb5-44c3-a270-3262357dd7e2
diff --git a/CHANGES.txt b/CHANGES.txt
index 1f3b81b93fcbd153dbeb2723aefb6bf9379ac848..fe640b13a82c0a1dd200486d94e9c93fd3d208fc 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
This file contains the changes to the Roundup system over time. The entries
are given with the most recent entry first.
-0.4.2
+2002-04-?? 0.4.2
Feature:
. link() htmltemplate function now has a "showid" option for links and
multilinks. When true, it only displays the linked node id as the anchor
Fixed:
. stop sending blank (whitespace-only) notes
+ . cleanup of serialisation for database storage
2002-03-25 - 0.4.1
index df287d8295a3df930643ec6db4a093465ca3ad08..65607c8e1c619db9bca4a093abf6d8994b665a1c 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_anydbm.py,v 1.30 2002-02-27 03:40:59 richard Exp $
+#$Id: back_anydbm.py,v 1.31 2002-04-03 05:54:31 richard 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
if hyperdb.DEBUG:
print 'setnode', (self, classname, nodeid, node)
self.dirtynodes.setdefault(classname, {})[nodeid] = 1
+
# can't set without having already loaded the node
self.cache[classname][nodeid] = node
self.savenode(classname, nodeid, node)
db = self.getclassdb(classname)
if not db.has_key(nodeid):
raise IndexError, "no such %s %s"%(classname, nodeid)
+
+ # decode
res = marshal.loads(db[nodeid])
+
+ # reverse the serialisation
+ res = self.unserialise(classname, res)
+
+ # store off in the cache
if cache:
cache[nodeid] = res
+
return res
def hasnode(self, classname, nodeid, db=None):
db = self.databases[db_name] = self.getclassdb(classname, 'c')
# now save the marshalled data
- db[nodeid] = marshal.dumps(node)
+ db[nodeid] = marshal.dumps(self.serialise(classname, node))
def _doSaveJournal(self, classname, nodeid, action, params):
+ # serialise first
+ if action in ('set', 'create'):
+ params = self.serialise(classname, params)
+
+ # create the journal entry
entry = (nodeid, date.Date().get_tuple(), self.journaltag, action,
params)
+
if hyperdb.DEBUG:
print '_doSaveJournal', entry
# now insert the journal entry
if db.has_key(nodeid):
+ # append to existing
s = db[nodeid]
l = marshal.loads(s)
l.append(entry)
else:
l = [entry]
+
db[nodeid] = marshal.dumps(l)
def _doStoreFile(self, name, **databases):
#
#$Log: not supported by cvs2svn $
+#Revision 1.30 2002/02/27 03:40:59 richard
+#Ran it through pychecker, made fixes
+#
#Revision 1.29 2002/02/25 14:34:31 grubert
# . use blobfiles in back_anydbm which is used in back_bsddb.
# change test_db as dirlist does not work for subdirectories.
index 973e7bc8cb8e47728a427e4ce6177c4abd62a48d..ea5e1b7cc34714b634e6460c3fc9b0fb805fe169 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_bsddb.py,v 1.16 2002-02-27 03:40:59 richard Exp $
+#$Id: back_bsddb.py,v 1.17 2002-04-03 05:54:31 richard Exp $
'''
This module defines a backend that saves the hyperdatabase in BSDDB.
'''
return res
def _doSaveJournal(self, classname, nodeid, action, params):
+ # serialise first
+ if action in ('set', 'create'):
+ params = self.serialise(classname, params)
+
entry = (nodeid, date.Date().get_tuple(), self.journaltag, action,
params)
+
+ if hyperdb.DEBUG:
+ print '_doSaveJournal', entry
+
db = bsddb.btopen(os.path.join(self.dir, 'journals.%s'%classname), 'c')
+
if db.has_key(nodeid):
s = db[nodeid]
l = marshal.loads(s)
l.append(entry)
else:
l = [entry]
+
db[nodeid] = marshal.dumps(l)
db.close()
#
#$Log: not supported by cvs2svn $
+#Revision 1.16 2002/02/27 03:40:59 richard
+#Ran it through pychecker, made fixes
+#
#Revision 1.15 2002/02/16 09:15:33 richard
#forgot to patch bsddb backend too
#
index 59ce26cc19cf92fd964d59f47e7e4eaa2aa6e7de..03553280b4ba90916432cd3354231f8338ee29cd 100644 (file)
--- a/roundup/htmltemplate.py
+++ b/roundup/htmltemplate.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: htmltemplate.py,v 1.85 2002-04-02 01:40:58 richard Exp $
+# $Id: htmltemplate.py,v 1.86 2002-04-03 05:54:31 richard Exp $
__doc__ = """
Template engine.
linkvalue = cgi.escape(linkcl.get(value, k))
if showid:
label = value
- title = ' title="%s"'%linkvalue
- # note ... this should be urllib.quote(linkcl.get(value, k))
+ title = ' title="%s"'%linkvalue
+ # note ... this should be urllib.quote(linkcl.get(value, k))
else:
label = linkvalue
+ title = ''
if is_download:
return '<a href="%s%s/%s"%s>%s</a>'%(linkname, value,
linkvalue, title, label)
if showid:
label = value
title = ' title="%s"'%linkvalue
- # note ... this should be urllib.quote(linkcl.get(value, k))
+ # note ... this should be urllib.quote(linkcl.get(value, k))
else:
label = linkvalue
+ title = ''
if is_download:
l.append('<a href="%s%s/%s"%s>%s</a>'%(linkname, value,
linkvalue, title, label))
#
# $Log: not supported by cvs2svn $
+# Revision 1.85 2002/04/02 01:40:58 richard
+# . link() htmltemplate function now has a "showid" option for links and
+# multilinks. When true, it only displays the linked node id as the anchor
+# text. The link value is displayed as a tooltip using the title anchor
+# attribute.
+#
# Revision 1.84 2002/03/29 19:41:48 rochecompaan
# . Fixed display of mutlilink properties when using the template
# functions, menu and plain.
diff --git a/roundup/hyperdb.py b/roundup/hyperdb.py
index 3d3c97bbae48ce7552b9f6de5ec83bbead7ef603..7319f1a227b010f77e7eacf9c00d322229381bc8 100644 (file)
--- a/roundup/hyperdb.py
+++ b/roundup/hyperdb.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: hyperdb.py,v 1.59 2002-03-12 22:52:26 richard Exp $
+# $Id: hyperdb.py,v 1.60 2002-04-03 05:54:31 richard Exp $
__doc__ = """
Hyperdatabase implementation, especially field types.
'''
raise NotImplementedError
+ def serialise(self, classname, node):
+ '''Copy the node contents, converting non-marshallable data into
+ marshallable data.
+ '''
+ if DEBUG: print 'serialise', classname, node
+ properties = self.getclass(classname).getprops()
+ d = {}
+ for k, v in node.items():
+ prop = properties[k]
+
+ if isinstance(prop, Password):
+ d[k] = str(v)
+ elif isinstance(prop, Date) and v is not None:
+ d[k] = v.get_tuple()
+ elif isinstance(prop, Interval) and v is not None:
+ d[k] = v.get_tuple()
+ else:
+ d[k] = v
+ return d
+
def setnode(self, classname, nodeid, node):
'''Change the specified node.
'''
raise NotImplementedError
+ def unserialise(self, classname, node):
+ '''Decode the marshalled node data
+ '''
+ if DEBUG: print 'unserialise', classname, node
+ properties = self.getclass(classname).getprops()
+ d = {}
+ for k, v in node.items():
+ prop = properties[k]
+ if isinstance(prop, Date) and v is not None:
+ d[k] = date.Date(v)
+ elif isinstance(prop, Interval) and v is not None:
+ d[k] = date.Interval(v)
+ elif isinstance(prop, Password):
+ p = password.Password()
+ p.unpack(v)
+ d[k] = p
+ else:
+ d[k] = v
+ return d
+
def getnode(self, classname, nodeid, db=None, cache=1):
'''Get a node from the database.
'''
# TODO: None isn't right here, I think...
propvalues[key] = None
- # convert all data to strings
- for key, prop in self.properties.items():
- if isinstance(prop, Date):
- if propvalues[key] is not None:
- propvalues[key] = propvalues[key].get_tuple()
- elif isinstance(prop, Interval):
- if propvalues[key] is not None:
- propvalues[key] = propvalues[key].get_tuple()
- elif isinstance(prop, Password):
- propvalues[key] = str(propvalues[key])
-
# done
self.db.addnode(self.classname, newid, propvalues)
self.db.addjournal(self.classname, newid, 'create', propvalues)
else:
return default
- # possibly convert the marshalled data to instances
- if isinstance(prop, Date):
- if d[propname] is None:
- return None
- return date.Date(d[propname])
- elif isinstance(prop, Interval):
- if d[propname] is None:
- return None
- return date.Interval(d[propname])
- elif isinstance(prop, Password):
- p = password.Password()
- p.unpack(d[propname])
- return p
-
return d[propname]
# XXX not in spec
elif isinstance(prop, Password):
if not isinstance(value, password.Password):
raise TypeError, 'new property "%s" not a Password'% key
- propvalues[key] = value = str(value)
+ propvalues[key] = value
elif value is not None and isinstance(prop, Date):
if not isinstance(value, date.Date):
raise TypeError, 'new property "%s" not a Date'% key
- propvalues[key] = value = value.get_tuple()
+ propvalues[key] = value
elif value is not None and isinstance(prop, Interval):
if not isinstance(value, date.Interval):
raise TypeError, 'new property "%s" not an Interval'% key
- propvalues[key] = value = value.get_tuple()
+ propvalues[key] = value
node[key] = value
#
# $Log: not supported by cvs2svn $
+# Revision 1.59 2002/03/12 22:52:26 richard
+# more pychecker warnings removed
+#
# Revision 1.58 2002/02/27 03:23:16 richard
# Ran it through pychecker, made fixes
#
diff --git a/test/test_db.py b/test/test_db.py
index dc08709cc447092623c9c99610f39281eb5e5b74..19dcd1682393729e1ed6482803638ad226018043 100644 (file)
--- a/test/test_db.py
+++ b/test/test_db.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_db.py,v 1.19 2002-02-25 14:34:31 grubert Exp $
+# $Id: test_db.py,v 1.20 2002-04-03 05:54:31 richard Exp $
import unittest, os, shutil
from roundup.hyperdb import String, Password, Link, Multilink, Date, \
Interval, Class, DatabaseError
from roundup.roundupdb import FileClass
-from roundup import date
+from roundup import date, password
def setupSchema(db, create):
status = Class(db, "status", name=String())
a = self.db.issue.get('5', "deadline")
self.db.issue.set('5', deadline=date.Date())
- self.assertNotEqual(a, self.db.issue.get('5', "deadline"))
+ b = self.db.issue.get('5', "deadline")
+ self.db.commit()
+ self.assertNotEqual(a, b)
+ self.assertNotEqual(b, date.Date('1970-1-1 00:00:00'))
+ self.db.issue.set('5', deadline=date.Date())
a = self.db.issue.get('5', "foo")
self.db.issue.set('5', foo=date.Interval('-1d'))
self.db.status.history('1')
self.db.status.history('2')
+ def testSerialisation(self):
+ self.db.issue.create(title="spam", status='1',
+ deadline=date.Date(), foo=date.Interval('-1d'))
+ self.db.commit()
+ assert isinstance(self.db.issue.get('1', 'deadline'), date.Date)
+ assert isinstance(self.db.issue.get('1', 'foo'), date.Interval)
+ self.db.user.create(username="fozzy",
+ password=password.Password('t. bear'))
+ self.db.commit()
+ assert isinstance(self.db.user.get('1', 'password'), password.Password)
+
def testTransactions(self):
# remember the number of items we started
num_issues = len(self.db.issue.list())
def suite():
- l = [unittest.makeSuite(anydbmDBTestCase, 'test'),
+ l = [
+ unittest.makeSuite(anydbmDBTestCase, 'test'),
unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
]
#
# $Log: not supported by cvs2svn $
+# Revision 1.19 2002/02/25 14:34:31 grubert
+# . use blobfiles in back_anydbm which is used in back_bsddb.
+# change test_db as dirlist does not work for subdirectories.
+# ATTENTION: blobfiles now creates subdirectories for files.
+#
# Revision 1.18 2002/01/22 07:21:13 richard
# . fixed back_bsddb so it passed the journal tests
#
index 3fd109c5edf7f1bf067d0898cfccb1e876cf2a07..f216db7e23cf15583b3423d9797f13bab97c78de 100644 (file)
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
-# $Id: test_htmltemplate.py,v 1.12 2002-03-29 19:41:48 rochecompaan Exp $
+# $Id: test_htmltemplate.py,v 1.13 2002-04-03 05:54:31 richard Exp $
import unittest, cgi, time
self.assertEqual(self.tf.do_link('link'),
'<a href="other1">the key1</a>')
+ def testLink_link_id(self):
+ self.assertEqual(self.tf.do_link('link', showid=1),
+ '<a href="other1" title="the key1">1</a>')
+
def testLink_multilink(self):
self.assertEqual(self.tf.do_link('multilink'),
'<a href="other1">the key1</a>, <a href="other2">the key2</a>')
+ def testLink_multilink_id(self):
+ self.assertEqual(self.tf.do_link('multilink', showid=1),
+ '<a href="other1" title="the key1">1</a>, <a href="other2" title="the key2">2</a>')
+
# def do_count(self, property, **args):
def testCount_nonlinks(self):
s = _('[Count: not a Multilink]')
#
# $Log: not supported by cvs2svn $
+# Revision 1.12 2002/03/29 19:41:48 rochecompaan
+# . Fixed display of mutlilink properties when using the template
+# functions, menu and plain.
+#
# Revision 1.11 2002/02/21 23:11:45 richard
# . fixed some problems in date calculations (calendar.py doesn't handle over-
# and under-flow). Also, hour/minute/second intervals may now be more than