@@ -411,6 +411,92 @@ def filter(self, search_matches, filterspec, sort=(None,None),
411411 # return the IDs (the first column)
412412 return [row [0 ] for row in l ]
413413
414+ # mysql doesn't implement INTERSECT
415+ def find (self , ** propspec ):
416+ '''Get the ids of nodes in this class which link to the given nodes.
417+
418+ 'propspec' consists of keyword args propname=nodeid or
419+ propname={nodeid:1, }
420+ 'propname' must be the name of a property in this class, or a
421+ KeyError is raised. That property must be a Link or
422+ Multilink property, or a TypeError is raised.
423+
424+ Any node in this class whose 'propname' property links to any of the
425+ nodeids will be returned. Used by the full text indexing, which knows
426+ that "foo" occurs in msg1, msg3 and file7, so we have hits on these
427+ issues:
428+
429+ db.issue.find(messages={'1':1,'3':1}, files={'7':1})
430+ '''
431+ if __debug__ :
432+ print >> hyperdb .DEBUG , 'find' , (self , propspec )
433+
434+ # shortcut
435+ if not propspec :
436+ return []
437+
438+ # validate the args
439+ props = self .getprops ()
440+ propspec = propspec .items ()
441+ for propname , nodeids in propspec :
442+ # check the prop is OK
443+ prop = props [propname ]
444+ if not isinstance (prop , Link ) and not isinstance (prop , Multilink ):
445+ raise TypeError , "'%s' not a Link/Multilink property" % propname
446+
447+ # first, links
448+ a = self .db .arg
449+ where = ['__retired__ <> %s' % a ]
450+ allvalues = (1 ,)
451+ for prop , values in propspec :
452+ if not isinstance (props [prop ], hyperdb .Link ):
453+ continue
454+ if type (values ) is type ({}) and len (values ) == 1 :
455+ values = values .keys ()[0 ]
456+ if type (values ) is type ('' ):
457+ allvalues += (values ,)
458+ where .append ('_%s = %s' % (prop , a ))
459+ elif values is None :
460+ where .append ('_%s is NULL' % prop )
461+ else :
462+ allvalues += tuple (values .keys ())
463+ where .append ('_%s in (%s)' % (prop , ',' .join ([a ]* len (values ))))
464+ tables = []
465+ if where :
466+ tables .append ('select id as nodeid from _%s where %s' % (
467+ self .classname , ' and ' .join (where )))
468+
469+ # now multilinks
470+ for prop , values in propspec :
471+ if not isinstance (props [prop ], hyperdb .Multilink ):
472+ continue
473+ if type (values ) is type ('' ):
474+ allvalues += (values ,)
475+ s = a
476+ else :
477+ allvalues += tuple (values .keys ())
478+ s = ',' .join ([a ]* len (values ))
479+ tables .append ('select nodeid from %s_%s where linkid in (%s)' % (
480+ self .classname , prop , s ))
481+
482+ raise NotImplemented , "XXX this code's farked"
483+ d = {}
484+ self .db .sql (sql , allvalues )
485+ for result in self .db .sql_fetchall ():
486+ d [result [0 ]] = 1
487+
488+ for query in tables [1 :]:
489+ self .db .sql (sql , allvalues )
490+ for result in self .db .sql_fetchall ():
491+ if not d .has_key (result [0 ]):
492+ continue
493+
494+ if __debug__ :
495+ print >> hyperdb .DEBUG , 'find ... ' , l
496+ l = d .keys ()
497+ l .sort ()
498+ return l
499+
414500class Class (MysqlClass , rdbms_common .Class ):
415501 pass
416502class IssueClass (MysqlClass , rdbms_common .IssueClass ):
0 commit comments