@@ -3827,6 +3827,91 @@ def getFileCounts(self, run_ids, report_filter, cmp_data, limit, offset):
38273827 results [fp ] = count
38283828 return results
38293829
3830+ @exc_to_thrift_reqfail
3831+ @timeit
3832+ def getFileCountsSummary (self , run_ids , report_filter , cmp_data ,
3833+ limit , offset ):
3834+ """
3835+ Returns detailed report statistics grouped by file.
3836+ The inner map contains total report count ("reports") and
3837+ counts per severity, review status and detection status.
3838+ """
3839+ self .__require_view ()
3840+
3841+ limit = verify_limit_range (limit )
3842+
3843+ results = {}
3844+ with DBSession (self ._Session ) as session :
3845+ filter_expression , join_tables = process_report_filter (
3846+ session , run_ids , report_filter , cmp_data )
3847+
3848+ distinct_file_path = session .query (File .filepath .distinct ()) \
3849+ .join (Report , Report .file_id == File .id )
3850+
3851+ if report_filter .annotations is not None :
3852+ distinct_file_path = distinct_file_path .outerjoin (
3853+ ReportAnnotations ,
3854+ ReportAnnotations .report_id == Report .id )
3855+ distinct_file_path = distinct_file_path .group_by (
3856+ Report .id )
3857+
3858+ distinct_file_path = apply_report_filter (
3859+ distinct_file_path , filter_expression , join_tables , [File ])
3860+
3861+ if limit :
3862+ distinct_file_path = distinct_file_path .limit (limit ) \
3863+ .offset (offset )
3864+
3865+ count_col = Report .bug_id .distinct () if \
3866+ report_filter .isUnique else Report .bug_id
3867+
3868+ stmt = session .query (
3869+ File .filepath ,
3870+ Checker .severity ,
3871+ Report .review_status ,
3872+ Report .detection_status ,
3873+ func .count (count_col ).label ('cnt' )) \
3874+ .join (Report , Report .file_id == File .id ) \
3875+ .join (Checker , Report .checker_id == Checker .id ) \
3876+ .filter (File .filepath .in_ (distinct_file_path ))
3877+
3878+ stmt = apply_report_filter (
3879+ stmt , filter_expression , join_tables , [File , Checker ])
3880+
3881+ stmt = stmt .group_by (
3882+ File .filepath ,
3883+ Checker .severity ,
3884+ Report .review_status ,
3885+ Report .detection_status )
3886+
3887+ severity_names = ttypes .Severity ._VALUES_TO_NAMES
3888+
3889+ for fp , sev , review_st , detect_st , cnt in stmt :
3890+ if fp not in results :
3891+ results [fp ] = {}
3892+
3893+ file_summary = results [fp ]
3894+
3895+ file_summary ["reports" ] = \
3896+ file_summary .get ("reports" , 0 ) + cnt
3897+
3898+ sev_name = severity_names .get (sev , str (sev ))
3899+ sev_key = f"severity:{ sev_name } "
3900+ file_summary [sev_key ] = \
3901+ file_summary .get (sev_key , 0 ) + cnt
3902+
3903+ if review_st :
3904+ rs_key = f"review_status:{ review_st } "
3905+ file_summary [rs_key ] = \
3906+ file_summary .get (rs_key , 0 ) + cnt
3907+
3908+ if detect_st :
3909+ ds_key = f"detection_status:{ detect_st } "
3910+ file_summary [ds_key ] = \
3911+ file_summary .get (ds_key , 0 ) + cnt
3912+
3913+ return results
3914+
38303915 @exc_to_thrift_reqfail
38313916 @timeit
38323917 def getRunHistoryTagCounts (self , run_ids , report_filter , cmp_data , limit ,
0 commit comments