index fa3c6d4ccb97f50d947083bd5159e05066885105..7ead40200d1ca568ead60ad320728171f6593339 100644 (file)
# return the IDs (the first column)
return [row[0] for row in l]
+ # mysql doesn't implement INTERSECT
+ def find(self, **propspec):
+ '''Get the ids of nodes in this class which link to the given nodes.
+
+ 'propspec' consists of keyword args propname=nodeid or
+ propname={nodeid:1, }
+ 'propname' must be the name of a property in this class, or a
+ KeyError is raised. That property must be a Link or
+ Multilink property, or a TypeError is raised.
+
+ Any node in this class whose 'propname' property links to any of the
+ nodeids will be returned. Used by the full text indexing, which knows
+ that "foo" occurs in msg1, msg3 and file7, so we have hits on these
+ issues:
+
+ db.issue.find(messages={'1':1,'3':1}, files={'7':1})
+ '''
+ if __debug__:
+ print >>hyperdb.DEBUG, 'find', (self, propspec)
+
+ # shortcut
+ if not propspec:
+ return []
+
+ # validate the args
+ props = self.getprops()
+ propspec = propspec.items()
+ for propname, nodeids in propspec:
+ # check the prop is OK
+ prop = props[propname]
+ if not isinstance(prop, Link) and not isinstance(prop, Multilink):
+ raise TypeError, "'%s' not a Link/Multilink property"%propname
+
+ # first, links
+ a = self.db.arg
+ where = ['__retired__ <> %s'%a]
+ allvalues = (1,)
+ for prop, values in propspec:
+ if not isinstance(props[prop], hyperdb.Link):
+ continue
+ if type(values) is type({}) and len(values) == 1:
+ values = values.keys()[0]
+ if type(values) is type(''):
+ allvalues += (values,)
+ where.append('_%s = %s'%(prop, a))
+ elif values is None:
+ where.append('_%s is NULL'%prop)
+ else:
+ allvalues += tuple(values.keys())
+ where.append('_%s in (%s)'%(prop, ','.join([a]*len(values))))
+ tables = []
+ if where:
+ tables.append('select id as nodeid from _%s where %s'%(
+ self.classname, ' and '.join(where)))
+
+ # now multilinks
+ for prop, values in propspec:
+ if not isinstance(props[prop], hyperdb.Multilink):
+ continue
+ if type(values) is type(''):
+ allvalues += (values,)
+ s = a
+ else:
+ allvalues += tuple(values.keys())
+ s = ','.join([a]*len(values))
+ tables.append('select nodeid from %s_%s where linkid in (%s)'%(
+ self.classname, prop, s))
+
+ raise NotImplemented, "XXX this code's farked"
+ d = {}
+ self.db.sql(sql, allvalues)
+ for result in self.db.sql_fetchall():
+ d[result[0]] = 1
+
+ for query in tables[1:]:
+ self.db.sql(sql, allvalues)
+ for result in self.db.sql_fetchall():
+ if not d.has_key(result[0]):
+ continue
+
+ if __debug__:
+ print >>hyperdb.DEBUG, 'find ... ', l
+ l = d.keys()
+ l.sort()
+ return l
+
class Class(MysqlClass, rdbms_common.Class):
pass
class IssueClass(MysqlClass, rdbms_common.IssueClass):