another fix to aggregation reports
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-01-23 10:11:14 +11:00
parent 3e2d95d3b9
commit 3671860b7d
3 changed files with 19 additions and 10 deletions

View File

@@ -1088,6 +1088,16 @@ WHERE %s
func buildDailyTotals(ctx context.Context, dbConn *sqlx.DB, records []SnapshotRecord, prorateByAvg bool) ([]totalsPoint, error) { func buildDailyTotals(ctx context.Context, dbConn *sqlx.DB, records []SnapshotRecord, prorateByAvg bool) ([]totalsPoint, error) {
points := make([]totalsPoint, 0, len(records)) points := make([]totalsPoint, 0, len(records))
tinExpr := `COALESCE(SUM(CASE WHEN "Tin" IS NOT NULL THEN "Tin" ELSE 0 END) / 100.0, 0)`
bronzeExpr := `COALESCE(SUM(CASE WHEN "Bronze" IS NOT NULL THEN "Bronze" ELSE 0 END) / 100.0, 0)`
silverExpr := `COALESCE(SUM(CASE WHEN "Silver" IS NOT NULL THEN "Silver" ELSE 0 END) / 100.0, 0)`
goldExpr := `COALESCE(SUM(CASE WHEN "Gold" IS NOT NULL THEN "Gold" ELSE 0 END) / 100.0, 0)`
if prorateByAvg {
tinExpr = `COALESCE(SUM(CASE WHEN "Tin" IS NOT NULL THEN "Tin" * COALESCE("AvgIsPresent", 0) ELSE 0 END) / 100.0, 0)`
bronzeExpr = `COALESCE(SUM(CASE WHEN "Bronze" IS NOT NULL THEN "Bronze" * COALESCE("AvgIsPresent", 0) ELSE 0 END) / 100.0, 0)`
silverExpr = `COALESCE(SUM(CASE WHEN "Silver" IS NOT NULL THEN "Silver" * COALESCE("AvgIsPresent", 0) ELSE 0 END) / 100.0, 0)`
goldExpr = `COALESCE(SUM(CASE WHEN "Gold" IS NOT NULL THEN "Gold" * COALESCE("AvgIsPresent", 0) ELSE 0 END) / 100.0, 0)`
}
for _, record := range records { for _, record := range records {
if err := db.ValidateTableName(record.TableName); err != nil { if err := db.ValidateTableName(record.TableName); err != nil {
return nil, err return nil, err
@@ -1101,13 +1111,13 @@ SELECT
COALESCE(SUM(CASE WHEN "AvgVcpuCount" IS NOT NULL THEN "AvgVcpuCount" ELSE 0 END), 0) AS vcpu_total, COALESCE(SUM(CASE WHEN "AvgVcpuCount" IS NOT NULL THEN "AvgVcpuCount" ELSE 0 END), 0) AS vcpu_total,
COALESCE(SUM(CASE WHEN "AvgRamGB" IS NOT NULL THEN "AvgRamGB" ELSE 0 END), 0) AS ram_total, COALESCE(SUM(CASE WHEN "AvgRamGB" IS NOT NULL THEN "AvgRamGB" ELSE 0 END), 0) AS ram_total,
COALESCE(AVG(CASE WHEN "AvgIsPresent" IS NOT NULL THEN "AvgIsPresent" ELSE 0 END), 0) AS presence_ratio, COALESCE(AVG(CASE WHEN "AvgIsPresent" IS NOT NULL THEN "AvgIsPresent" ELSE 0 END), 0) AS presence_ratio,
COALESCE(SUM(CASE WHEN "Tin" IS NOT NULL THEN "Tin" ELSE 0 END) / 100.0, 0) AS tin_total, %s AS tin_total,
COALESCE(SUM(CASE WHEN "Bronze" IS NOT NULL THEN "Bronze" ELSE 0 END) / 100.0, 0) AS bronze_total, %s AS bronze_total,
COALESCE(SUM(CASE WHEN "Silver" IS NOT NULL THEN "Silver" ELSE 0 END) / 100.0, 0) AS silver_total, %s AS silver_total,
COALESCE(SUM(CASE WHEN "Gold" IS NOT NULL THEN "Gold" ELSE 0 END) / 100.0, 0) AS gold_total %s AS gold_total
FROM %s FROM %s
WHERE %s WHERE %s
`, record.TableName, templateExclusionFilter()) `, tinExpr, bronzeExpr, silverExpr, goldExpr, record.TableName, templateExclusionFilter())
var row struct { var row struct {
VmCount int64 `db:"vm_count"` VmCount int64 `db:"vm_count"`
VcpuTotal float64 `db:"vcpu_total"` VcpuTotal float64 `db:"vcpu_total"`

View File

@@ -913,7 +913,7 @@ INSERT INTO %s (
avgDisk, avgDisk,
avgPresent, avgPresent,
tinPct, bronzePct, silverPct, goldPct, tinPct, bronzePct, silverPct, goldPct,
float64(v.tinHits), float64(v.bronzeHits), float64(v.silverHits), float64(v.goldHits), tinPct, bronzePct, silverPct, goldPct,
} }
if driver != "sqlite" { if driver != "sqlite" {
// Postgres expects primitive types, nulls are handled by pq via nil. // Postgres expects primitive types, nulls are handled by pq via nil.

View File

@@ -40,14 +40,13 @@ func (h *Handler) SnapshotAggregateForce(w http.ResponseWriter, r *http.Request)
} }
if granularity != "" && snapshotType != "monthly" { if granularity != "" && snapshotType != "monthly" {
h.Logger.Warn("Snapshot aggregation granularity supplied for non-monthly request", h.Logger.Debug("Snapshot aggregation ignoring granularity for non-monthly request",
"type", snapshotType, "type", snapshotType,
"granularity", granularity, "granularity", granularity,
) )
writeJSONError(w, http.StatusBadRequest, "granularity is only supported for monthly aggregation") granularity = ""
return
} }
if granularity != "" && granularity != "hourly" && granularity != "daily" { if snapshotType == "monthly" && granularity != "" && granularity != "hourly" && granularity != "daily" {
h.Logger.Warn("Snapshot aggregation invalid granularity", "granularity", granularity) h.Logger.Warn("Snapshot aggregation invalid granularity", "granularity", granularity)
writeJSONError(w, http.StatusBadRequest, "granularity must be hourly or daily") writeJSONError(w, http.StatusBadRequest, "granularity must be hourly or daily")
return return