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
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
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()
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
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
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()
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()
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
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
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