def getFlattenedOverlayTree(self, derived_series): """See `IDistroSeriesParentSet`.""" self.getByDerivedSeries(derived_series) rec_overlay_query = ''' RECURSIVE t_parents(parent_series) AS ( SELECT parent_series FROM DistroSeriesParent WHERE derived_series=? AND is_overlay = True UNION ALL SELECT dsp.parent_series FROM DistroSeriesParent dsp, t_parents p WHERE dsp.derived_series = p.parent_series AND dsp.is_overlay = True ) ''' store = IStore(DistroSeriesParent) # XXX: rvb 2011-05-20 bug=785733: Order by DSD.id for now. # Once the ordering is specified in the database, it should # be used to sort the results. return store.with_( SQL(rec_overlay_query, (derived_series.id, ))).find( DistroSeriesParent, SQL('DistroSeriesParent.parent_series IN ' '(SELECT parent_series FROM t_parents)') ).order_by(DistroSeriesParent.id)
def getFlattenedOverlayTree(self, derived_series): """See `IDistroSeriesParentSet`.""" self.getByDerivedSeries(derived_series) rec_overlay_query = ''' RECURSIVE t_parents(parent_series) AS ( SELECT parent_series FROM DistroSeriesParent WHERE derived_series=? AND is_overlay = True UNION ALL SELECT dsp.parent_series FROM DistroSeriesParent dsp, t_parents p WHERE dsp.derived_series = p.parent_series AND dsp.is_overlay = True ) ''' store = IStore(DistroSeriesParent) # XXX: rvb 2011-05-20 bug=785733: Order by DSD.id for now. # Once the ordering is specified in the database, it should # be used to sort the results. return store.with_( SQL(rec_overlay_query, (derived_series.id, ))).find( DistroSeriesParent, SQL('DistroSeriesParent.parent_series IN ' '(SELECT parent_series FROM t_parents)') ).order_by(DistroSeriesParent.id)
def _getSharedPillars(self, person, user, pillar_class, extra_filter=None): """Helper method for getSharedProjects and getSharedDistributions. pillar_class is either Product or Distribution. Products define the owner foreign key attribute as _owner so we need to account for that, but otherwise the logic is the same for both pillar types. """ if user is None: return [] store = IStore(AccessPolicyGrantFlat) roles = IPersonRoles(user) if roles.in_admin: filter = True else: with_statement = With("teams", Select(TeamParticipation.teamID, tables=TeamParticipation, where=TeamParticipation.person == user.id)) teams_sql = SQL("SELECT team from teams") store = store.with_(with_statement) if IProduct.implementedBy(pillar_class): ownerID = pillar_class._ownerID else: ownerID = pillar_class.ownerID filter = Or( extra_filter or False, ownerID.is_in(teams_sql), pillar_class.driverID.is_in(teams_sql)) tables = [ AccessPolicyGrantFlat, Join( AccessPolicy, AccessPolicyGrantFlat.policy_id == AccessPolicy.id)] if IProduct.implementedBy(pillar_class): access_policy_column = AccessPolicy.product_id else: access_policy_column = AccessPolicy.distribution_id result_set = store.find( pillar_class, pillar_class.id.is_in( Select( columns=access_policy_column, tables=tables, where=(AccessPolicyGrantFlat.grantee_id == person.id)) ), filter) return result_set
def load_teams_and_permissions(grantees): # We now have the grantees we want in the result so load any # associated team memberships and permissions and cache them. if permissions_cache: return store = IStore(cls) for grantee in grantees: grantees_by_id[grantee[0].id] = grantee[0] # Find any teams associated with the grantees. If grantees is a # sliced list (for batching), it may contain indirect grantees but # not the team they belong to so that needs to be fixed below. with_expr = With( "grantees", store.find(cls.grantee_id, cls.policy_id.is_in(policies_by_id.keys())).config( distinct=True)._get_select()) result_set = store.with_(with_expr).find( (TeamParticipation.teamID, TeamParticipation.personID), TeamParticipation.personID.is_in(grantees_by_id.keys()), TeamParticipation.teamID.is_in( Select((SQL("grantees.grantee"), ), tables="grantees", distinct=True))) team_ids = set() direct_grantee_ids = set() for team_id, team_member_id in result_set: if team_member_id == team_id: direct_grantee_ids.add(team_member_id) else: via_teams_cache[team_member_id].append(team_id) team_ids.add(team_id) # Remove from the via_teams cache all the direct grantees. for direct_grantee_id in direct_grantee_ids: if direct_grantee_id in via_teams_cache: del via_teams_cache[direct_grantee_id] # Load and cache the additional required teams. persons = store.find(Person, Person.id.is_in(team_ids)) for person in persons: grantees_by_id[person.id] = person cls._populatePermissionsCache(permissions_cache, shared_artifact_info_types, grantees_by_id.keys(), policies_by_id, grantees_by_id)
def load_teams_and_permissions(grantees): # We now have the grantees we want in the result so load any # associated team memberships and permissions and cache them. if permissions_cache: return store = IStore(cls) for grantee in grantees: grantees_by_id[grantee[0].id] = grantee[0] # Find any teams associated with the grantees. If grantees is a # sliced list (for batching), it may contain indirect grantees but # not the team they belong to so that needs to be fixed below. with_expr = With("grantees", store.find( cls.grantee_id, cls.policy_id.is_in(policies_by_id.keys()) ).config(distinct=True)._get_select()) result_set = store.with_(with_expr).find( (TeamParticipation.teamID, TeamParticipation.personID), TeamParticipation.personID.is_in(grantees_by_id.keys()), TeamParticipation.teamID.is_in( Select( (SQL("grantees.grantee"),), tables="grantees", distinct=True))) team_ids = set() direct_grantee_ids = set() for team_id, team_member_id in result_set: if team_member_id == team_id: direct_grantee_ids.add(team_member_id) else: via_teams_cache[team_member_id].append(team_id) team_ids.add(team_id) # Remove from the via_teams cache all the direct grantees. for direct_grantee_id in direct_grantee_ids: if direct_grantee_id in via_teams_cache: del via_teams_cache[direct_grantee_id] # Load and cache the additional required teams. persons = store.find(Person, Person.id.is_in(team_ids)) for person in persons: grantees_by_id[person.id] = person cls._populatePermissionsCache( permissions_cache, shared_artifact_info_types, grantees_by_id.keys(), policies_by_id, grantees_by_id)
def search_specifications(context, base_clauses, user, sort=None, quantity=None, spec_filter=None, tables=[], default_acceptance=False, need_people=True, need_branches=True, need_workitems=False): store = IStore(Specification) if not default_acceptance: default = SpecificationFilter.INCOMPLETE options = set( [SpecificationFilter.COMPLETE, SpecificationFilter.INCOMPLETE]) else: default = SpecificationFilter.ACCEPTED options = set([ SpecificationFilter.ACCEPTED, SpecificationFilter.DECLINED, SpecificationFilter.PROPOSED ]) if not spec_filter: spec_filter = [default] if not set(spec_filter) & options: spec_filter.append(default) if not tables: tables = [Specification] clauses = base_clauses product_tables, product_clauses = get_specification_active_product_filter( context) tables.extend(product_tables) clauses.extend(product_clauses) # If there are any base or product clauses, they typically have good # selectivity, so use a CTE to force PostgreSQL to calculate them # up-front rather than doing a sequential scan for visible # specifications. if clauses: RelevantSpecification = Table('RelevantSpecification') relevant_specification_cte = With( RelevantSpecification.name, Select(Specification.id, And(clauses), tables=tables)) store = store.with_(relevant_specification_cte) tables = [Specification] clauses = [ Specification.id.is_in(Select(Column('id', RelevantSpecification))), ] clauses.extend(get_specification_privacy_filter(user)) clauses.extend(get_specification_filters(spec_filter)) # Sort by priority descending, by default. if sort is None or sort == SpecificationSort.PRIORITY: order = [ Desc(Specification.priority), Specification.definition_status, Specification.name ] elif sort == SpecificationSort.DATE: if SpecificationFilter.COMPLETE in spec_filter: # If we are showing completed, we care about date completed. order = [Desc(Specification.date_completed), Specification.id] else: # If not specially looking for complete, we care about date # registered. order = [] show_proposed = set( [SpecificationFilter.ALL, SpecificationFilter.PROPOSED]) if default_acceptance and not (set(spec_filter) & show_proposed): order.append(Desc(Specification.date_goal_decided)) order.extend([Desc(Specification.datecreated), Specification.id]) else: order = [sort] # Set the _known_viewers property for each specification, as well as # preloading the objects involved, if asked. def preload_hook(rows): person_ids = set() work_items_by_spec = defaultdict(list) for spec in rows: if need_people: person_ids |= set( [spec._assigneeID, spec._approverID, spec._drafterID]) if need_branches: get_property_cache(spec).linked_branches = [] if need_workitems: work_items = load_referencing( SpecificationWorkItem, rows, ['specification_id'], extra_conditions=[SpecificationWorkItem.deleted == False]) for workitem in work_items: person_ids.add(workitem.assignee_id) work_items_by_spec[workitem.specification_id].append(workitem) person_ids -= set([None]) if need_people: list( getUtility(IPersonSet).getPrecachedPersonsFromIDs( person_ids, need_validity=True)) if need_workitems: for spec in rows: get_property_cache(spec).work_items = sorted( work_items_by_spec[spec.id], key=lambda wi: wi.sequence) if need_branches: spec_branches = load_referencing(SpecificationBranch, rows, ['specificationID']) for sbranch in spec_branches: spec_cache = get_property_cache(sbranch.specification) spec_cache.linked_branches.append(sbranch) decorators = [] if user is not None and not IPersonRoles(user).in_admin: decorators.append(_make_cache_user_can_view_spec(user)) results = store.using(*tables).find( Specification, *clauses).order_by(*order).config(limit=quantity) return DecoratedResultSet( results, lambda row: reduce(lambda task, dec: dec(task), decorators, row), pre_iter_hook=preload_hook)