define struct for all api params

This commit is contained in:
Danny van Kooten 2018-05-07 18:59:52 +02:00
parent 7597de951b
commit 872bdd6141
6 changed files with 46 additions and 73 deletions

View File

@ -8,9 +8,8 @@ import (
// URL: /api/stats/page
var GetPageStatsHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
startDate, endDate := getRequestedDatePeriods(r)
limit := getRequestedLimit(r)
result, err := datastore.GetAggregatedPageStats(startDate, endDate, limit)
params := GetRequestParams(r)
result, err := datastore.GetAggregatedPageStats(params.StartDate, params.EndDate, params.Limit)
if err != nil {
return err
}

View File

@ -7,39 +7,33 @@ import (
"time"
)
// TODO: Move params into Params struct (with defaults)
const defaultPeriod = 7
const defaultLimit = 10
func getRequestedLimit(r *http.Request) int64 {
limit, err := strconv.ParseInt(r.URL.Query().Get("limit"), 10, 64)
if err != nil || limit == 0 {
limit = defaultLimit
type Params struct {
Limit int
StartDate time.Time
EndDate time.Time
}
return limit
func GetRequestParams(r *http.Request) *Params {
params := &Params{
Limit: 20,
StartDate: time.Now(),
EndDate: time.Now().AddDate(0, 0, -7),
}
func getRequestedDatePeriods(r *http.Request) (time.Time, time.Time) {
var startDate, endDate time.Time
var err error
beforeUnix, err := strconv.ParseInt(r.URL.Query().Get("before"), 10, 64)
if err != nil || beforeUnix == 0 {
endDate = time.Now()
} else {
endDate = time.Unix(beforeUnix, 0)
q := r.URL.Query()
if after, err := strconv.ParseInt(q.Get("after"), 10, 64); err == nil && after > 0 {
params.StartDate = time.Unix(after, 0)
}
afterUnix, err := strconv.ParseInt(r.URL.Query().Get("after"), 10, 64)
if err != nil || afterUnix == 0 {
startDate = endDate.AddDate(0, 0, -defaultPeriod)
} else {
startDate = time.Unix(afterUnix, 0)
if before, err := strconv.ParseInt(q.Get("before"), 10, 64); err == nil && before > 0 {
params.EndDate = time.Unix(before, 0)
}
return startDate, endDate
if limit, err := strconv.Atoi(q.Get("limit")); err == nil && limit > 0 {
params.Limit = limit
}
return params
}
func parseMajorMinor(v string) string {

View File

@ -7,28 +7,8 @@ import (
"testing"
)
func TestGetRequestedLimit(t *testing.T) {
r, _ := http.NewRequest("GET", "", nil)
limit := getRequestedLimit(r)
if limit != defaultLimit {
t.Errorf("Expected limit of %d does not match %d", defaultLimit, limit)
}
r, _ = http.NewRequest("GET", "?limit=50", nil)
limit = getRequestedLimit(r)
if limit != 50 {
t.Errorf("Expected limit of %d does not match %d", defaultLimit, limit)
}
}
func TestGetRequestedPeriods(t *testing.T) {
r, _ := http.NewRequest("GET", "?before=500&after=100", nil)
before, after := getRequestedPeriods(r)
if before != 500 || after != 100 {
t.Error("Expected URl argument for `before` or `after` does not match")
}
func TestGetRequestParams(t *testing.T) {
// TODO: Implement this
}
func TestParseMajorMinor(t *testing.T) {

View File

@ -18,8 +18,8 @@ var GetSiteStatsHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Reques
// URL: /api/stats/site/pageviews
var GetSiteStatsPageviewsHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
startDate, endDate := getRequestedDatePeriods(r)
result, err := datastore.GetTotalSiteViews(startDate, endDate)
params := GetRequestParams(r)
result, err := datastore.GetTotalSiteViews(params.StartDate, params.EndDate)
if err != nil {
return err
}
@ -28,8 +28,8 @@ var GetSiteStatsPageviewsHandler = HandlerFunc(func(w http.ResponseWriter, r *ht
// URL: /api/stats/site/visitors
var GetSiteStatsVisitorsHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
startDate, endDate := getRequestedDatePeriods(r)
result, err := datastore.GetTotalSiteVisitors(startDate, endDate)
params := GetRequestParams(r)
result, err := datastore.GetTotalSiteVisitors(params.StartDate, params.EndDate)
if err != nil {
return err
}
@ -38,8 +38,8 @@ var GetSiteStatsVisitorsHandler = HandlerFunc(func(w http.ResponseWriter, r *htt
// URL: /api/stats/site/duration
var GetSiteStatsDurationHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
startDate, endDate := getRequestedDatePeriods(r)
result, err := datastore.GetAverageSiteDuration(startDate, endDate)
params := GetRequestParams(r)
result, err := datastore.GetAverageSiteDuration(params.StartDate, params.EndDate)
if err != nil {
return err
}
@ -48,8 +48,8 @@ var GetSiteStatsDurationHandler = HandlerFunc(func(w http.ResponseWriter, r *htt
// URL: /api/stats/site/bounces
var GetSiteStatsBouncesHandler = HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
startDate, endDate := getRequestedDatePeriods(r)
result, err := datastore.GetAverageSiteBounceRate(startDate, endDate)
params := GetRequestParams(r)
result, err := datastore.GetAverageSiteBounceRate(params.StartDate, params.EndDate)
if err != nil {
return err
}

View File

@ -28,7 +28,7 @@ func UpdatePageStats(s *models.PageStats) error {
return err
}
func GetAggregatedPageStats(startDate time.Time, endDate time.Time, limit int64) ([]*models.PageStats, error) {
func GetAggregatedPageStats(startDate time.Time, endDate time.Time, limit int) ([]*models.PageStats, error) {
var result []*models.PageStats
query := dbx.Rebind(`SELECT pathname, SUM(views) AS views, SUM(unique_views) AS unique_views, SUM(entries) AS entries, ROUND(AVG(bounces), 0) AS bounces FROM daily_page_stats WHERE date >= ? AND date <= ? GROUP BY pathname, views, unique_views, entries, bounces ORDER BY views DESC LIMIT ?`)
err := dbx.Select(&result, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"), limit)

View File

@ -28,50 +28,50 @@ func UpdateSiteStats(s *models.SiteStats) error {
return err
}
func GetTotalSiteViews(startDate time.Time, endDate time.Time) (int64, error) {
func GetTotalSiteViews(startDate time.Time, endDate time.Time) (int, error) {
sql := `SELECT COALESCE(SUM(pageviews), 0) FROM daily_site_stats WHERE date >= ? AND date <= ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"))
return total, err
}
func GetTotalSiteVisitors(startDate time.Time, endDate time.Time) (int64, error) {
func GetTotalSiteVisitors(startDate time.Time, endDate time.Time) (int, error) {
sql := `SELECT COALESCE(SUM(visitors), 0) FROM daily_site_stats WHERE date >= ? AND date <= ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"))
return total, err
}
func GetTotalSiteSessions(startDate time.Time, endDate time.Time) (int64, error) {
func GetTotalSiteSessions(startDate time.Time, endDate time.Time) (int, error) {
sql := `SELECT COALESCE(SUM(sessions), 0) FROM daily_site_stats WHERE date >= ? AND date <= ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"))
return total, err
}
func GetAverageSiteDuration(startDate time.Time, endDate time.Time) (int64, error) {
func GetAverageSiteDuration(startDate time.Time, endDate time.Time) (int, error) {
sql := `SELECT COALESCE(ROUND(AVG(avg_duration), 0), 0) FROM daily_site_stats WHERE date >= ? AND date <= ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"))
return total, err
}
func GetAverageSiteBounceRate(startDate time.Time, endDate time.Time) (int64, error) {
func GetAverageSiteBounceRate(startDate time.Time, endDate time.Time) (int, error) {
sql := `SELECT COALESCE(ROUND(AVG(bounces), 0), 0) FROM daily_site_stats WHERE date >= ? AND date <= ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, startDate.Format("2006-01-02"), endDate.Format("2006-01-02"))
return total, err
}
func GetRealtimeVisitorCount() (int64, error) {
func GetRealtimeVisitorCount() (int, error) {
sql := `SELECT COUNT(DISTINCT(session_id)) FROM pageviews WHERE timestamp > ?`
query := dbx.Rebind(sql)
var total int64
var total int
err := dbx.Get(&total, query, time.Now().Add(-5*time.Minute))
return total, err
}