示例#1
0
 def query(self, current_user_id: Optional[UserIDT], prj_id: int,
           for_managing: bool) -> ProjectBO:
     if current_user_id is None:
         RightsBO.anonymous_wants(self.session, Action.READ, prj_id)
         highest_right = ""
     else:
         current_user, project = RightsBO.user_wants(
             self.session, current_user_id,
             Action.ADMINISTRATE if for_managing else Action.READ, prj_id)
         highest_right = RightsBO.highest_right_on(current_user, prj_id)
     ret = ProjectBOSet.get_one(self.session, prj_id)
     assert ret is not None
     ret.highest_right = highest_right
     return ret
示例#2
0
 def query_history(self, current_user_id: Optional[int], object_id: ObjectIDT) \
         -> List[HistoricalClassification]:
     the_obj = ObjectBO(self.ro_session, object_id)
     if not the_obj.exists():
         return []
     # Security check
     # TODO: dup code
     projid = the_obj.header.acquisition.sample.projid
     if current_user_id is None:
         RightsBO.anonymous_wants(self.ro_session, Action.READ, projid)
     else:
         _user, project = RightsBO.user_wants(self.session, current_user_id, Action.READ, projid)
         assert project is not None
     ret = the_obj.get_history()
     return ret
示例#3
0
 def search(self, current_user_id: Optional[UserIDT], project_id: ProjectIDT) -> List[AcquisitionBO]:
     # Security check
     if current_user_id is None:
         project = RightsBO.anonymous_wants(self.ro_session, Action.READ, project_id)
     else:
         _user, project = RightsBO.user_wants(self.session, current_user_id, Action.READ, project_id)
     acquisition_set = DescribedAcquisitionSet(self.ro_session, project_id)
     # mappings = ProjectMapping().load_from_project(project)
     # ret.map_free_columns(mappings.sample_mappings)
     return acquisition_set.list()
示例#4
0
    def summary(self, current_user_id: Optional[UserIDT], proj_id: ProjectIDT, filters: ProjectFilters,
                only_total: bool) -> Tuple[int, Optional[int], Optional[int], Optional[int]]:
        """
            Query the given project with given filters, return classification summary, or just grand total if
            only_total is set.
        """
        # Security check
        if current_user_id is None:
            RightsBO.anonymous_wants(self.session, Action.READ, proj_id)
            # Anonymous can only see validated objects
            # TODO: Dup code
            # noinspection PyTypeHints
            filters.statusfilter = "V"  # type:ignore
            user_id = -1
        else:
            user, _project = RightsBO.user_wants(self.session, current_user_id, Action.READ, proj_id)
            user_id = user.id

        # Prepare a where clause and parameters from filter
        object_set: DescribedObjectSet = DescribedObjectSet(self.session, proj_id, filters)
        from_, where, params = object_set.get_sql(user_id)
        sql = """
    SET LOCAL enable_seqscan=FALSE;
    SELECT COUNT(*) nbr"""
        if only_total:
            sql += """, NULL nbr_v, NULL nbr_d, NULL nbr_p"""
        else:
            sql += """, 
           COUNT(CASE WHEN obh.classif_qual = 'V' THEN 1 END) nbr_v,
           COUNT(CASE WHEN obh.classif_qual = 'D' THEN 1 END) nbr_d, 
           COUNT(CASE WHEN obh.classif_qual = 'P' THEN 1 END) nbr_p"""
        sql += """
      FROM """ + from_.get_sql() + " " + where.get_sql()

        with CodeTimer("summary: V/D/P for %d using %s " % (proj_id, sql), logger):
            res: ResultProxy = self.session.execute(sql, params)

        nbr: int
        nbr_v: Optional[int]
        nbr_d: Optional[int]
        nbr_p: Optional[int]
        nbr, nbr_v, nbr_d, nbr_p = res.first()  # type:ignore
        return nbr, nbr_v, nbr_d, nbr_p
示例#5
0
 def query(self, current_user_id: Optional[int], acquisition_id: AcquisitionIDT) -> Optional[AcquisitionBO]:
     ret = AcquisitionBO(self.ro_session, acquisition_id)
     if not ret.exists():
         return None
     assert ret.acquis is not None
     # Security check
     if current_user_id is None:
         project = RightsBO.anonymous_wants(self.ro_session, Action.READ, ret.acquis.sample.projid)
     else:
         _user, project = RightsBO.user_wants(self.session, current_user_id, Action.READ, ret.acquis.sample.projid)
     mappings = ProjectMapping().load_from_project(project)
     ret.map_free_columns(mappings.acquisition_mappings)
     return ret
示例#6
0
 def read_taxo_stats(self, current_user_id: Optional[UserIDT],
                     sample_ids: SampleIDListT) -> List[SampleTaxoStats]:
     # Get project IDs for the samples and verify rights
     sample_set = EnumeratedSampleSet(self.ro_session, sample_ids)
     project_ids = sample_set.get_projects_ids()
     # Security check
     if current_user_id is None:
         [RightsBO.anonymous_wants(self.ro_session, Action.READ, project_id)
          for project_id in project_ids]
     else:
         [RightsBO.user_wants(self.session, current_user_id, Action.READ, project_id)
          for project_id in project_ids]
     return sample_set.read_taxo_stats()
示例#7
0
 def search(self, current_user_id: Optional[UserIDT],
            project_ids: ProjectIDListT,
            orig_id_pattern: str) -> List[SampleBO]:
     # Security check
     if current_user_id is None:
         [RightsBO.anonymous_wants(self.ro_session, Action.READ, project_id)
          for project_id in project_ids]
     else:
         [RightsBO.user_wants(self.session, current_user_id, Action.READ, project_id)
          for project_id in project_ids]
     sample_set = DescribedSampleSet(self.ro_session, project_ids, orig_id_pattern)
     # mappings = ProjectMapping().load_from_project(project)
     # ret.map_free_columns(mappings.sample_mappings)
     return sample_set.list()
示例#8
0
 def query(self, current_user_id: Optional[UserIDT], sample_id: SampleIDT) -> Optional[SampleBO]:
     ret = SampleBO(self.ro_session, sample_id)
     if not ret.exists():
         return None
     assert ret.sample is not None
     assert ret.sample.projid is not None  # TODO: Why need this?
     # Security check
     if current_user_id is None:
         project = RightsBO.anonymous_wants(self.ro_session, Action.READ, ret.sample.projid)
     else:
         _user, project = RightsBO.user_wants(self.session, current_user_id, Action.READ, ret.sample.projid)
     mappings = ProjectMapping().load_from_project(project)
     ret.map_free_columns(mappings.sample_mappings)
     return ret
示例#9
0
 def query(self, current_user_id: Optional[int], object_id: ObjectIDT) -> Optional[ObjectBO]:
     ret = ObjectBO(self.ro_session, object_id)
     if not ret.exists():
         return None
     # Security check
     projid = ret.header.acquisition.sample.projid
     if current_user_id is None:
         project = RightsBO.anonymous_wants(self.session, Action.READ, projid)
     else:
         _user, project = RightsBO.user_wants(self.session, current_user_id, Action.READ, projid)
     assert project is not None
     mappings = ProjectMapping().load_from_project(project)
     ret.map_free_columns(mappings.object_mappings)
     return ret
示例#10
0
    def query(self, current_user_id: Optional[UserIDT], proj_id: ProjectIDT,
              filters: ProjectFilters,
              order_field: Optional[str] = None,
              window_start: Optional[int] = None,
              window_size: Optional[int] = None) \
            -> Tuple[ObjectIDWithParentsListT, int]:
        """
            Query the given project with given filters, return all IDs.
            If provided order_field, the result is sorted by this field.
            Ambiguity is solved in a stable (over calls) way.
            window_start and window_size allow to select a window of data in the result.
        """
        # Security check
        if current_user_id is None:
            RightsBO.anonymous_wants(self.session, Action.READ, proj_id)
            # Anonymous can only see validated objects
            # noinspection PyTypeHints
            filters.statusfilter = "V"  # type:ignore
            user_id = -1
        else:
            user, _project = RightsBO.user_wants(self.session, current_user_id, Action.READ, proj_id)
            user_id = user.id

        # The order field has an impact on the query
        order_clause = self.cook_order_clause(order_field)

        # Prepare a where clause and parameters from filter
        object_set: DescribedObjectSet = DescribedObjectSet(self.session, proj_id, filters)

        from_, where, params = object_set.get_sql(user_id, order_clause)

        if "obf." in where.get_sql():
            # If the filter needs obj_field data it's more efficient to count with a window function
            # than issuing a second query.
            extra_col = ", COUNT(objid) OVER() AS total"
        else:
            # Otherwise, no need for obj_field in count, less DB buffers
            extra_col = ", 0 AS total"

        # The following hint is needed until we sort out why, time to time, there is a FTS on obj_head
        sql = """
    SET LOCAL enable_seqscan=FALSE;
    SELECT obh.objid, acq.acquisid, sam.sampleid %s
      FROM """ % extra_col + from_.get_sql() + " " + where.get_sql()

        # Add order & window if relevant
        if order_clause is not None:
            sql += order_clause.get_sql()
        if window_start is not None:
            sql += " OFFSET %d" % window_start
        if window_size is not None:
            sql += " LIMIT %d" % window_size

        with CodeTimer("query: for %d using %s " % (proj_id, sql), logger):
            res: ResultProxy = self.session.execute(sql, params)
        ids = []
        total = 0
        objid: int
        acquisid: int
        sampleid: int
        for objid, acquisid, sampleid, total in res:  # type:ignore
            ids.append((objid, acquisid, sampleid, proj_id))

        if total == 0:
            # Total was not computed or left to 0
            total, _nbr_v, _nbr_d, _nbr_p = self.summary(current_user_id, proj_id, filters, True)

        return ids, total