@@ -1080,8 +1080,34 @@ def to_hyperdb_value(self, propklass):
10801080
10811081 raise ValueError ('%r is not a hyperdb property class' % propklass )
10821082
1083- def getnode (self , classname , nodeid ):
1083+ def _materialize_multilink (self , classname , nodeid , node , propname ):
1084+ """ evaluation of single Multilink (lazy eval may have skipped this)
1085+ """
1086+ if propname not in node :
1087+ sql = 'select linkid from %s_%s where nodeid=%s' % (classname ,
1088+ propname , self .arg )
1089+ self .sql (sql , (nodeid ,))
1090+ # extract the first column from the result
1091+ # XXX numeric ids
1092+ items = [int (x [0 ]) for x in self .cursor .fetchall ()]
1093+ items .sort ()
1094+ node [propname ] = [str (x ) for x in items ]
1095+
1096+ def _materialize_multilinks (self , classname , nodeid , node , props = None ):
1097+ """ get all Multilinks of a node (lazy eval may have skipped this)
1098+ """
1099+ cl = self .classes [classname ]
1100+ props = props or [pn for (pn , p ) in cl .properties .iteritems ()
1101+ if isinstance (p , Multilink )]
1102+ for propname in props :
1103+ if propname not in node :
1104+ self ._materialize_multilink (classname , nodeid , node , propname )
1105+
1106+ def getnode (self , classname , nodeid , fetch_multilinks = True ):
10841107 """ Get a node from the database.
1108+ For optimisation optionally we don't fetch multilinks
1109+ (lazy Multilinks).
1110+ But for internal database operations we need them.
10851111 """
10861112 # see if we have this node cached
10871113 key = (classname , nodeid )
@@ -1091,6 +1117,8 @@ def getnode(self, classname, nodeid):
10911117 if __debug__ :
10921118 self .stats ['cache_hits' ] += 1
10931119 # return the cached information
1120+ if fetch_multilinks :
1121+ self ._materialize_multilinks (classname , nodeid , self .cache [key ])
10941122 return self .cache [key ]
10951123
10961124 if __debug__ :
@@ -1124,6 +1152,9 @@ def getnode(self, classname, nodeid):
11241152 value = self .to_hyperdb_value (props [name ].__class__ )(value )
11251153 node [name ] = value
11261154
1155+ if fetch_multilinks and mls :
1156+ self ._materialize_multilinks (classname , nodeid , node , mls )
1157+
11271158 # save off in the cache
11281159 key = (classname , nodeid )
11291160 self ._cache_save (key , node )
@@ -1616,7 +1647,7 @@ def get(self, nodeid, propname, default=_marker, cache=1):
16161647 return nodeid
16171648
16181649 # get the node's dict
1619- d = self .db .getnode (self .classname , nodeid )
1650+ d = self .db .getnode (self .classname , nodeid , fetch_multilinks = False )
16201651 # handle common case -- that property is in dict -- first
16211652 # if None and one of creator/creation actor/activity return None
16221653 if propname in d :
@@ -1640,14 +1671,7 @@ def get(self, nodeid, propname, default=_marker, cache=1):
16401671
16411672 # lazy evaluation of Multilink
16421673 if propname not in d and isinstance (prop , Multilink ):
1643- sql = 'select linkid from %s_%s where nodeid=%s' % (self .classname ,
1644- propname , self .db .arg )
1645- self .db .sql (sql , (nodeid ,))
1646- # extract the first column from the result
1647- # XXX numeric ids
1648- items = [int (x [0 ]) for x in self .db .cursor .fetchall ()]
1649- items .sort ()
1650- d [propname ] = [str (x ) for x in items ]
1674+ self .db ._materialize_multilink (self .classname , nodeid , d , propname )
16511675
16521676 # handle there being no value in the table for the property
16531677 if propname not in d or d [propname ] is None :
0 commit comments