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.46 2002-07-14 06:06:34 richard Exp $
18+ #$Id: back_anydbm.py,v 1.47 2002-07-14 23:18:20 richard Exp $
1919'''
2020This module defines a backend that saves the hyperdatabase in a database
2121chosen by anydbm. It is guaranteed to always be available in python
@@ -876,9 +876,13 @@ class or a KeyError is raised.
876876 if node .has_key (self .db .RETIRED_FLAG ):
877877 raise IndexError
878878 num_re = re .compile ('^\d+$' )
879- for key , value in propvalues .items ():
879+
880+ # if the journal value is to be different, store it in here
881+ journalvalues = {}
882+
883+ for propname , value in propvalues .items ():
880884 # check to make sure we're not duplicating an existing key
881- if key == self .key and node [key ] != value :
885+ if propname == self .key and node [propname ] != value :
882886 try :
883887 self .lookup (value )
884888 except KeyError :
@@ -889,17 +893,17 @@ class or a KeyError is raised.
889893 # this will raise the KeyError if the property isn't valid
890894 # ... we don't use getprops() here because we only care about
891895 # the writeable properties.
892- prop = self .properties [key ]
896+ prop = self .properties [propname ]
893897
894898 # if the value's the same as the existing value, no sense in
895899 # doing anything
896- if node .has_key (key ) and value == node [key ]:
897- del propvalues [key ]
900+ if node .has_key (propname ) and value == node [propname ]:
901+ del propvalues [propname ]
898902 continue
899903
900904 # do stuff based on the prop type
901905 if isinstance (prop , Link ):
902- link_class = self .properties [key ].classname
906+ link_class = self .properties [propname ].classname
903907 # if it isn't a number, it's a key
904908 if type (value ) != type ('' ):
905909 raise ValueError , 'link value must be String'
@@ -908,97 +912,116 @@ class or a KeyError is raised.
908912 value = self .db .classes [link_class ].lookup (value )
909913 except (TypeError , KeyError ):
910914 raise IndexError , 'new property "%s": %s not a %s' % (
911- key , value , self .properties [key ].classname )
915+ propname , value , self .properties [propname ].classname )
912916
913917 if not self .db .hasnode (link_class , value ):
914918 raise IndexError , '%s has no node %s' % (link_class , value )
915919
916- if self .do_journal and self .properties [key ].do_journal :
920+ if self .do_journal and self .properties [propname ].do_journal :
917921 # register the unlink with the old linked node
918- if node [key ] is not None :
919- self .db .addjournal (link_class , node [key ], 'unlink' ,
920- (self .classname , nodeid , key ))
922+ if node [propname ] is not None :
923+ self .db .addjournal (link_class , node [propname ], 'unlink' ,
924+ (self .classname , nodeid , propname ))
921925
922926 # register the link with the newly linked node
923927 if value is not None :
924928 self .db .addjournal (link_class , value , 'link' ,
925- (self .classname , nodeid , key ))
929+ (self .classname , nodeid , propname ))
926930
927931 elif isinstance (prop , Multilink ):
928932 if type (value ) != type ([]):
929- raise TypeError , 'new property "%s" not a list of ids' % key
930- link_class = self .properties [key ].classname
933+ raise TypeError , 'new property "%s" not a list of' \
934+ ' ids' % propname
935+ link_class = self .properties [propname ].classname
931936 l = []
932937 for entry in value :
933938 # if it isn't a number, it's a key
934939 if type (entry ) != type ('' ):
935940 raise ValueError , 'new property "%s" link value ' \
936- 'must be a string' % key
941+ 'must be a string' % propname
937942 if not num_re .match (entry ):
938943 try :
939944 entry = self .db .classes [link_class ].lookup (entry )
940945 except (TypeError , KeyError ):
941946 raise IndexError , 'new property "%s": %s not a %s' % (
942- key , entry , self .properties [key ].classname )
947+ propname , entry ,
948+ self .properties [propname ].classname )
943949 l .append (entry )
944950 value = l
945- propvalues [key ] = value
951+ propvalues [propname ] = value
952+
953+ # figure the journal entry for this property
954+ add = []
955+ remove = []
946956
947957 # handle removals
948- if node .has_key (key ):
949- l = node [key ]
958+ if node .has_key (propname ):
959+ l = node [propname ]
950960 else :
951961 l = []
952962 for id in l [:]:
953963 if id in value :
954964 continue
955965 # register the unlink with the old linked node
956- if self .do_journal and self .properties [key ].do_journal :
966+ if self .do_journal and self .properties [propname ].do_journal :
957967 self .db .addjournal (link_class , id , 'unlink' ,
958- (self .classname , nodeid , key ))
968+ (self .classname , nodeid , propname ))
959969 l .remove (id )
970+ remove .append (id )
960971
961972 # handle additions
962973 for id in value :
963974 if not self .db .hasnode (link_class , id ):
964- raise IndexError , '%s has no node %s' % (
965- link_class , id )
975+ raise IndexError , '%s has no node %s' % (link_class , id )
966976 if id in l :
967977 continue
968978 # register the link with the newly linked node
969- if self .do_journal and self .properties [key ].do_journal :
979+ if self .do_journal and self .properties [propname ].do_journal :
970980 self .db .addjournal (link_class , id , 'link' ,
971- (self .classname , nodeid , key ))
981+ (self .classname , nodeid , propname ))
972982 l .append (id )
983+ add .append (id )
984+
985+ # figure the journal entry
986+ l = []
987+ if add :
988+ l .append (('add' , add ))
989+ if remove :
990+ l .append (('remove' , remove ))
991+ if l :
992+ journalvalues [propname ] = tuple (l )
973993
974994 elif isinstance (prop , String ):
975995 if value is not None and type (value ) != type ('' ):
976- raise TypeError , 'new property "%s" not a string' % key
996+ raise TypeError , 'new property "%s" not a string' % propname
977997
978998 elif isinstance (prop , Password ):
979999 if not isinstance (value , password .Password ):
980- raise TypeError , 'new property "%s" not a Password' % key
981- propvalues [key ] = value
1000+ raise TypeError , 'new property "%s" not a Password' % propname
1001+ propvalues [propname ] = value
9821002
9831003 elif value is not None and isinstance (prop , Date ):
9841004 if not isinstance (value , date .Date ):
985- raise TypeError , 'new property "%s" not a Date' % key
986- propvalues [key ] = value
1005+ raise TypeError , 'new property "%s" not a Date' % propname
1006+ propvalues [propname ] = value
9871007
9881008 elif value is not None and isinstance (prop , Interval ):
9891009 if not isinstance (value , date .Interval ):
990- raise TypeError , 'new property "%s" not an Interval' % key
991- propvalues [key ] = value
1010+ raise TypeError , 'new property "%s" not an ' \
1011+ 'Interval' % propname
1012+ propvalues [propname ] = value
9921013
993- node [key ] = value
1014+ node [propname ] = value
9941015
9951016 # nothing to do?
9961017 if not propvalues :
9971018 return
9981019
9991020 # do the set, and journal it
10001021 self .db .setnode (self .classname , nodeid , node )
1022+
10011023 if self .do_journal :
1024+ propvalues .update (journalvalues )
10021025 self .db .addjournal (self .classname , nodeid , 'set' , propvalues )
10031026
10041027 self .fireReactors ('set' , nodeid , oldvalues )
@@ -1615,6 +1638,9 @@ def __init__(self, db, classname, **properties):
16151638
16161639#
16171640#$Log: not supported by cvs2svn $
1641+ #Revision 1.46 2002/07/14 06:06:34 richard
1642+ #Did some old TODOs
1643+ #
16181644#Revision 1.45 2002/07/14 04:03:14 richard
16191645#Implemented a switch to disable journalling for a Class. CGI session
16201646#database now uses it.
0 commit comments