@@ -149,7 +149,6 @@ func parseAPIParameters(r *http.Request) (APIParameters, error) {
149149 EndYear : 1750 ,
150150 Parish : []int {},
151151 Sort : "year, week_no, canonical_name" ,
152- Limit : 25 , // Set a default limit
153152 }
154153
155154 // Log raw query parameters for debugging
@@ -298,16 +297,12 @@ func buildBillsQuery(params APIParameters) (string, error) {
298297 }
299298
300299 // Handle pagination
301- queryPart := " LIMIT %d"
302300 if params .Page > 0 {
303- // If using page-based pagination
304301 limit := 25
305302 offset := (params .Page - 1 ) * limit
306- baseQuery += fmt .Sprintf (queryPart + " OFFSET %d" , limit , offset )
307- } else {
308- // Always apply the limit (default or specified)
309- baseQuery += fmt .Sprintf (queryPart , params .Limit )
310- // Add offset if specified
303+ baseQuery += fmt .Sprintf (" LIMIT %d OFFSET %d" , limit , offset )
304+ } else if params .Limit > 0 {
305+ baseQuery += fmt .Sprintf (" LIMIT %d" , params .Limit )
311306 if params .Offset > 0 {
312307 baseQuery += fmt .Sprintf (" OFFSET %d" , params .Offset )
313308 }
@@ -414,3 +409,126 @@ func (s *Server) TotalBillsHandler() http.HandlerFunc {
414409 fmt .Fprint (w , string (response ))
415410 }
416411}
412+
413+ // Statistics
414+ type YearlySummary struct {
415+ Year int `json:"year"`
416+ WeeksCompleted int `json:"weeksCompleted"`
417+ RowsCount int `json:"rowsCount"`
418+ TotalCount int `json:"totalCount"`
419+ }
420+
421+ type WeeklySummary struct {
422+ Year int `json:"year"`
423+ WeekNo int `json:"weekNo"`
424+ RowsCount int `json:"rowsCount"`
425+ }
426+
427+ func buildYearlyStatsQuery () string {
428+ return `
429+ WITH year_range AS (
430+ SELECT generate_series(1636, 1754) AS year
431+ ),
432+ weekly_stats AS (
433+ SELECT
434+ b.year_id as year,
435+ COUNT(DISTINCT b.week_id) as weeks_completed,
436+ COUNT(*) as rows_count
437+ FROM bom.bill_of_mortality b
438+ WHERE b.bill_type = 'Weekly'
439+ GROUP BY b.year_id
440+ )
441+ SELECT
442+ yr.year,
443+ COALESCE(ws.weeks_completed, 0) as weeks_completed,
444+ COALESCE(ws.rows_count, 0) as rows_count,
445+ 53 as total_count
446+ FROM year_range yr
447+ LEFT JOIN weekly_stats ws ON yr.year = ws.year
448+ ORDER BY yr.year;
449+ `
450+ }
451+
452+ func buildWeeklyStatsQuery () string {
453+ return `
454+ WITH year_week_range AS (
455+ SELECT
456+ y.year,
457+ w.number as week_no
458+ FROM generate_series(1636, 1754) y(year)
459+ CROSS JOIN generate_series(1, 53) w(number)
460+ ),
461+ weekly_stats AS (
462+ SELECT
463+ b.year_id as year,
464+ w.week_no,
465+ COUNT(*) as rows_count
466+ FROM bom.bill_of_mortality b
467+ JOIN bom.week w ON w.joinid = b.week_id
468+ WHERE b.bill_type = 'Weekly'
469+ GROUP BY b.year_id, w.week_no
470+ )
471+ SELECT
472+ yr.year,
473+ yr.week_no,
474+ COALESCE(ws.rows_count, 0) as rows_count
475+ FROM year_week_range yr
476+ LEFT JOIN weekly_stats ws ON yr.year = ws.year AND yr.week_no = ws.week_no
477+ ORDER BY yr.year, yr.week_no;
478+ `
479+ }
480+
481+ func (s * Server ) StatisticsHandler () http.HandlerFunc {
482+ return func (w http.ResponseWriter , r * http.Request ) {
483+ statType := r .URL .Query ().Get ("type" )
484+
485+ var query string
486+ switch statType {
487+ case "weekly" :
488+ query = buildWeeklyStatsQuery ()
489+ case "yearly" :
490+ query = buildYearlyStatsQuery ()
491+ default :
492+ http .Error (w , "Invalid type parameter. Must be 'weekly' or 'yearly'" , http .StatusBadRequest )
493+ return
494+ }
495+
496+ rows , err := s .DB .Query (context .TODO (), query )
497+ if err != nil {
498+ http .Error (w , "Database error" , http .StatusInternalServerError )
499+ return
500+ }
501+ defer rows .Close ()
502+
503+ if statType == "weekly" {
504+ stats := []WeeklySummary {}
505+ for rows .Next () {
506+ var summary WeeklySummary
507+ err := rows .Scan (& summary .Year , & summary .WeekNo , & summary .RowsCount )
508+ if err != nil {
509+ http .Error (w , "Error processing results" , http .StatusInternalServerError )
510+ return
511+ }
512+ stats = append (stats , summary )
513+ }
514+ w .Header ().Set ("Content-Type" , "application/json" )
515+ json .NewEncoder (w ).Encode (stats )
516+ return
517+ }
518+
519+ stats := []YearlySummary {}
520+ for rows .Next () {
521+ var summary YearlySummary
522+ err := rows .Scan (& summary .Year , & summary .WeeksCompleted ,
523+ & summary .RowsCount , & summary .TotalCount )
524+ if err != nil {
525+ http .Error (w , "Error processing results" , http .StatusInternalServerError )
526+ return
527+ }
528+ stats = append (stats , summary )
529+ }
530+
531+ w .Header ().Set ("Content-Type" , "application/json" )
532+ json .NewEncoder (w ).Encode (stats )
533+ }
534+ }
0 commit comments