diff --git a/api/browsers.go b/api/browsers.go index 21d180d..631d1c5 100644 --- a/api/browsers.go +++ b/api/browsers.go @@ -2,8 +2,9 @@ package api import ( "encoding/json" - "github.com/dannyvankooten/ana/count" "net/http" + + "github.com/dannyvankooten/ana/count" ) // URL: /api/browsers @@ -14,16 +15,7 @@ var GetBrowsersHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Re total := count.Visitors(before, after) // get rows - results := count.Custom(` - SELECT - v.browser_name, - COUNT(DISTINCT(pv.visitor_id)) AS count - FROM pageviews pv - LEFT JOIN visitors v ON v.id = pv.visitor_id - WHERE UNIX_TIMESTAMP(pv.timestamp) <= ? AND UNIX_TIMESTAMP(pv.timestamp) >= ? AND v.browser_name IS NOT NULL - GROUP BY v.browser_name - ORDER BY count DESC - LIMIT ?`, before, after, getRequestedLimit(r), total) + results := count.Browsers(before, after, getRequestedLimit(r), total) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(results) diff --git a/count/browsers.go b/count/browsers.go new file mode 100644 index 0000000..088291a --- /dev/null +++ b/count/browsers.go @@ -0,0 +1,60 @@ +package count + +import ( + "github.com/dannyvankooten/ana/db" +) + +// Browsers returns a point slice containing browser data per browser name +func Browsers(before int64, after int64, limit int, total float64) []Point { + // TODO: Calculate total instead of requiring it as a parameter. + stmt, err := db.Conn.Prepare(` + SELECT + a.value, + SUM(a.count) AS count + FROM archive a + WHERE a.metric = 'browsers' AND UNIX_TIMESTAMP(a.date) <= ? AND UNIX_TIMESTAMP(a.date) >= ? + GROUP BY a.value + ORDER BY count DESC + LIMIT ?`) + checkError(err) + defer stmt.Close() + + rows, err := stmt.Query(before, after, limit) + checkError(err) + + return newPointSlice(rows, total) +} + +// CreateBrowserArchives aggregates screen data into daily totals +func CreateBrowserArchives() { + stmt, err := db.Conn.Prepare(` + SELECT + v.browser_name, + COUNT(DISTINCT(pv.visitor_id)) AS count, + DATE_FORMAT(pv.timestamp, "%Y-%m-%d") AS date_group + FROM pageviews pv + LEFT JOIN visitors v ON v.id = pv.visitor_id + WHERE NOT EXISTS( + SELECT a.id + FROM archive a + WHERE a.metric = 'browsers' AND a.date = DATE_FORMAT(pv.timestamp, "%Y-%m-%d") + ) + GROUP BY date_group, v.browser_name`) + checkError(err) + defer stmt.Close() + + rows, err := stmt.Query() + checkError(err) + defer rows.Close() + + db.Conn.Exec("START TRANSACTION") + for rows.Next() { + a := Archive{ + Metric: "browsers", + } + err = rows.Scan(&a.Value, &a.Count, &a.Date) + checkError(err) + a.Save(db.Conn) + } + db.Conn.Exec("COMMIT") +} diff --git a/count/count.go b/count/count.go index 4943e02..ab64acf 100644 --- a/count/count.go +++ b/count/count.go @@ -55,6 +55,7 @@ func CreateArchives() { CreatePageviewArchivesPerPage() CreateScreenArchives() CreateLanguageArchives() + CreateBrowserArchives() } func checkError(err error) { @@ -78,7 +79,8 @@ func Custom(sql string, before int64, after int64, limit int, total float64) []P } func newPointSlice(rows *sql.Rows, total float64) []Point { - var results []Point + results := make([]Point, 0) + for rows.Next() { var d Point err := rows.Scan(&d.Label, &d.Value)