@@ -149,7 +149,6 @@ func parseAPIParameters(r *http.Request) (APIParameters, error) {
149
149
EndYear : 1750 ,
150
150
Parish : []int {},
151
151
Sort : "year, week_no, canonical_name" ,
152
- Limit : 25 , // Set a default limit
153
152
}
154
153
155
154
// Log raw query parameters for debugging
@@ -298,16 +297,12 @@ func buildBillsQuery(params APIParameters) (string, error) {
298
297
}
299
298
300
299
// Handle pagination
301
- queryPart := " LIMIT %d"
302
300
if params .Page > 0 {
303
- // If using page-based pagination
304
301
limit := 25
305
302
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 )
311
306
if params .Offset > 0 {
312
307
baseQuery += fmt .Sprintf (" OFFSET %d" , params .Offset )
313
308
}
@@ -414,3 +409,126 @@ func (s *Server) TotalBillsHandler() http.HandlerFunc {
414
409
fmt .Fprint (w , string (response ))
415
410
}
416
411
}
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