예제 #1
0
 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)
예제 #3
0
    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
예제 #4
0
        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)
예제 #5
0
        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)
예제 #6
0
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)