@@ -127,8 +127,9 @@ func (repo *SeriesRepository) Count(ctx context.Context) (int, error) {
127127}
128128
129129type SeriesWithSession struct {
130- Series * Series
131- Session * Session
130+ Series * Series
131+ Session * Session
132+ Findings int
132133}
133134
134135type SeriesFilter struct {
@@ -191,37 +192,96 @@ func (repo *SeriesRepository) ListLatest(ctx context.Context, filter SeriesFilte
191192 }
192193
193194 // Now query Sessions.
194- var keys []string
195195 var ret []* SeriesWithSession
196- idToSeries := map [string ]* SeriesWithSession {}
197196 for _ , series := range seriesList {
197+ obj := & SeriesWithSession {Series : series }
198+ ret = append (ret , obj )
199+ }
200+
201+ // And the rest of the data.
202+ err = repo .querySessions (ctx , ro , ret )
203+ if err != nil {
204+ return nil , fmt .Errorf ("failed to query sessions: %w" , err )
205+ }
206+ err = repo .queryFindingCounts (ctx , ro , ret )
207+ if err != nil {
208+ return nil , fmt .Errorf ("failed to query finding counts: %w" , err )
209+ }
210+ return ret , nil
211+ }
212+
213+ func (repo * SeriesRepository ) querySessions (ctx context.Context , ro * spanner.ReadOnlyTransaction ,
214+ seriesList []* SeriesWithSession ) error {
215+ idToSeries := map [string ]* SeriesWithSession {}
216+ var keys []string
217+ for _ , item := range seriesList {
218+ series := item .Series
219+ idToSeries [series .ID ] = item
198220 if ! series .LatestSessionID .IsNull () {
199221 keys = append (keys , series .LatestSessionID .String ())
200222 }
201- obj := & SeriesWithSession {Series : series }
202- ret = append (ret , obj )
203- idToSeries [series .ID ] = obj
204- }
205- if len (keys ) > 0 {
206- iter := ro .Query (ctx , spanner.Statement {
207- SQL : "SELECT * FROM Sessions WHERE ID IN UNNEST(@ids)" ,
208- Params : map [string ]interface {}{
209- "ids" : keys ,
210- },
211- })
212- defer iter .Stop ()
213- sessions , err := readEntities [Session ](iter )
214- if err != nil {
215- return nil , err
223+ }
224+ if len (keys ) == 0 {
225+ return nil
226+ }
227+ iter := ro .Query (ctx , spanner.Statement {
228+ SQL : "SELECT * FROM Sessions WHERE ID IN UNNEST(@ids)" ,
229+ Params : map [string ]interface {}{
230+ "ids" : keys ,
231+ },
232+ })
233+ defer iter .Stop ()
234+ sessions , err := readEntities [Session ](iter )
235+ if err != nil {
236+ return err
237+ }
238+ for _ , session := range sessions {
239+ obj := idToSeries [session .SeriesID ]
240+ if obj != nil {
241+ obj .Session = session
216242 }
217- for _ , session := range sessions {
218- obj := idToSeries [session .SeriesID ]
219- if obj != nil {
220- obj .Session = session
221- }
243+ }
244+ return nil
245+ }
246+
247+ func (repo * SeriesRepository ) queryFindingCounts (ctx context.Context , ro * spanner.ReadOnlyTransaction ,
248+ seriesList []* SeriesWithSession ) error {
249+ var keys []string
250+ sessionToSeries := map [string ]* SeriesWithSession {}
251+ for _ , series := range seriesList {
252+ if series .Session == nil || series .Session .Status () != SessionStatusFinished {
253+ continue
222254 }
255+ keys = append (keys , series .Session .ID )
256+ sessionToSeries [series .Session .ID ] = series
223257 }
224- return ret , nil
258+ if len (keys ) == 0 {
259+ return nil
260+ }
261+
262+ type findingCount struct {
263+ SessionID string `spanner:"SessionID"`
264+ Count int64 `spanner:"Count"`
265+ }
266+
267+ stmt := spanner.Statement {
268+ SQL : "SELECT `SessionID`, COUNT(`ID`) as `Count` FROM `Findings` " +
269+ "WHERE `SessionID` IN UNNEST(@ids) GROUP BY `SessionID`" ,
270+ Params : map [string ]interface {}{
271+ "ids" : keys ,
272+ },
273+ }
274+ iter := repo .client .Single ().Query (ctx , stmt )
275+ defer iter .Stop ()
276+
277+ list , err := readEntities [findingCount ](iter )
278+ if err != nil {
279+ return err
280+ }
281+ for _ , item := range list {
282+ sessionToSeries [item .SessionID ].Findings = int (item .Count )
283+ }
284+ return nil
225285}
226286
227287// golint sees too much similarity with SessionRepository's ListForSeries, but in reality there's not.
0 commit comments