|
15 | 15 | # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, |
16 | 16 | # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
17 | 17 | # |
18 | | -# $Id: hyperdb.py,v 1.113 2006-01-20 02:40:56 richard Exp $ |
| 18 | +# $Id: hyperdb.py,v 1.114 2006-01-24 08:22:42 a1s Exp $ |
19 | 19 |
|
20 | 20 | """Hyperdatabase implementation, especially field types. |
21 | 21 | """ |
22 | 22 | __docformat__ = 'restructuredtext' |
23 | 23 |
|
24 | 24 | # standard python modules |
25 | | -import sys, os, time, re, shutil |
| 25 | +import sys, os, time, re, shutil, weakref |
26 | 26 |
|
27 | 27 | # roundup modules |
28 | 28 | import date, password |
29 | | -from support import ensureParentsExist |
| 29 | +from support import ensureParentsExist, PrioList |
30 | 30 |
|
31 | 31 | # |
32 | 32 | # Types |
@@ -441,7 +441,25 @@ def __init__(self, db, classname, **properties): |
441 | 441 | or a ValueError is raised. The keyword arguments in 'properties' |
442 | 442 | must map names to property objects, or a TypeError is raised. |
443 | 443 | """ |
444 | | - raise NotImplementedError |
| 444 | + for name in 'creation activity creator actor'.split(): |
| 445 | + if properties.has_key(name): |
| 446 | + raise ValueError, '"creation", "activity", "creator" and '\ |
| 447 | + '"actor" are reserved' |
| 448 | + |
| 449 | + self.classname = classname |
| 450 | + self.properties = properties |
| 451 | + self.db = weakref.proxy(db) # use a weak ref to avoid circularity |
| 452 | + self.key = '' |
| 453 | + |
| 454 | + # should we journal changes (default yes) |
| 455 | + self.do_journal = 1 |
| 456 | + |
| 457 | + # do the db-related init stuff |
| 458 | + db.addclass(self) |
| 459 | + |
| 460 | + actions = "create set retire restore".split () |
| 461 | + self.auditors = dict ([(a, PrioList ()) for a in actions]) |
| 462 | + self.reactors = dict ([(a, PrioList ()) for a in actions]) |
445 | 463 |
|
446 | 464 | def __repr__(self): |
447 | 465 | '''Slightly more useful representation |
@@ -642,7 +660,7 @@ def labelprop(self, default_to_id=0): |
642 | 660 | def orderprop (self): |
643 | 661 | """Return the property name to use for sorting for the given node. |
644 | 662 |
|
645 | | - This method computes the property for sorting. |
| 663 | + This method computes the property for sorting. |
646 | 664 | It tries the following in order: |
647 | 665 |
|
648 | 666 | 0. self._orderprop if set |
@@ -733,12 +751,35 @@ def addprop(self, **properties): |
733 | 751 | raise NotImplementedError |
734 | 752 |
|
735 | 753 | def index(self, nodeid): |
736 | | - '''Add (or refresh) the node to search indexes |
737 | | - ''' |
| 754 | + """Add (or refresh) the node to search indexes""" |
738 | 755 | raise NotImplementedError |
739 | 756 |
|
| 757 | + # |
| 758 | + # Detector interface |
| 759 | + # |
| 760 | + def audit(self, event, detector, priority = 100): |
| 761 | + """Register an auditor detector""" |
| 762 | + self.auditors[event].append((priority, detector)) |
| 763 | + |
| 764 | + def fireAuditors(self, event, nodeid, newvalues): |
| 765 | + """Fire all registered auditors""" |
| 766 | + for prio, audit in self.auditors[event]: |
| 767 | + audit(self.db, self, nodeid, newvalues) |
| 768 | + |
| 769 | + def react(self, event, detector, priority = 100): |
| 770 | + """Register a reactor detector""" |
| 771 | + self.reactors[event].append((priority, detector)) |
| 772 | + |
| 773 | + def fireReactors(self, event, nodeid, oldvalues): |
| 774 | + """Fire all registered reactors""" |
| 775 | + for prio, react in self.reactors[event]: |
| 776 | + react(self.db, self, nodeid, oldvalues) |
| 777 | + |
| 778 | + # |
| 779 | + # import / export support |
| 780 | + # |
740 | 781 | def export_propnames(self): |
741 | | - '''List the property names for export from this Class.''' |
| 782 | + """List the property names for export from this Class""" |
742 | 783 | propnames = self.getprops().keys() |
743 | 784 | propnames.sort() |
744 | 785 | return propnames |
@@ -829,7 +870,7 @@ def export_files(self, dirname, nodeid): |
829 | 870 |
|
830 | 871 | dest = self.exportFilename(dirname, nodeid) |
831 | 872 | ensureParentsExist(dest) |
832 | | - shutil.copyfile(source, dest) |
| 873 | + shutil.copyfile(source, dest) |
833 | 874 |
|
834 | 875 | def import_files(self, dirname, nodeid): |
835 | 876 | ''' Import the "content" property as a file |
|
0 commit comments