[FIX] groups: fix implementation of trans_implied_ids
bzr revid: rco@openerp.com-20111205111609-3ll31ozf871zrtly
This commit is contained in:
parent
ac62aebefc
commit
4fdf1ab805
|
@ -554,25 +554,45 @@ users()
|
||||||
# to the implied groups (transitively).
|
# to the implied groups (transitively).
|
||||||
#
|
#
|
||||||
|
|
||||||
|
class cset(object):
|
||||||
|
""" A cset (constrained set) is a set of elements that may be constrained to
|
||||||
|
be a subset of other csets. Elements added to a cset are automatically
|
||||||
|
added to its supersets. Cycles in the subset constraints are supported.
|
||||||
|
"""
|
||||||
|
def __init__(self, xs):
|
||||||
|
self.supersets = set()
|
||||||
|
self.elements = set(xs)
|
||||||
|
def subsetof(self, other):
|
||||||
|
if other is not self:
|
||||||
|
self.supersets.add(other)
|
||||||
|
other.update(self.elements)
|
||||||
|
def update(self, xs):
|
||||||
|
xs = set(xs) - self.elements
|
||||||
|
if xs: # xs will eventually be empty in case of a cycle
|
||||||
|
self.elements.update(xs)
|
||||||
|
for s in self.supersets:
|
||||||
|
s.update(xs)
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.elements)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class groups_implied(osv.osv):
|
class groups_implied(osv.osv):
|
||||||
_inherit = 'res.groups'
|
_inherit = 'res.groups'
|
||||||
|
|
||||||
def _get_trans_implied(self, cr, uid, ids, field, arg, context=None):
|
def _get_trans_implied(self, cr, uid, ids, field, arg, context=None):
|
||||||
"computes the transitive closure of relation implied_ids"
|
"computes the transitive closure of relation implied_ids"
|
||||||
trans_memo = {}
|
memo = {} # use a memo for performance and cycle avoidance
|
||||||
def compute_trans(g):
|
def computed_set(g):
|
||||||
"computes the list of group ids transitively implied by g"
|
if g not in memo:
|
||||||
# use a memo for performance and cycle avoidance
|
memo[g] = cset(g.implied_ids)
|
||||||
if g.id in trans_memo:
|
for h in g.implied_ids:
|
||||||
return trans_memo[g.id]
|
computed_set(h).subsetof(memo[g])
|
||||||
trans_memo[g.id] = set()
|
return memo[g]
|
||||||
for h in g.implied_ids:
|
|
||||||
trans_memo[g.id].add(h.id)
|
|
||||||
trans_memo[g.id].update(compute_trans(h))
|
|
||||||
return trans_memo[g.id]
|
|
||||||
res = {}
|
res = {}
|
||||||
for g in self.browse(cr, 1, ids, context):
|
for g in self.browse(cr, 1, ids, context):
|
||||||
res[g.id] = list(compute_trans(g))
|
res[g.id] = map(int, computed_set(g))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -584,9 +604,9 @@ class groups_implied(osv.osv):
|
||||||
|
|
||||||
def get_closure(self, cr, uid, ids, context=None):
|
def get_closure(self, cr, uid, ids, context=None):
|
||||||
"return the reflexive transitive closure of implied_ids for group ids"
|
"return the reflexive transitive closure of implied_ids for group ids"
|
||||||
res = set()
|
res = set(ids)
|
||||||
for g in self.browse(cr, 1, ids):
|
for g in self.browse(cr, 1, ids):
|
||||||
res.update(map(int, [g] + g.trans_implied_ids))
|
res.update(map(int, g.trans_implied_ids))
|
||||||
return list(res)
|
return list(res)
|
||||||
|
|
||||||
def create(self, cr, uid, values, context=None):
|
def create(self, cr, uid, values, context=None):
|
||||||
|
|
Loading…
Reference in New Issue