github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/analytics.go (about)

     1  package common
     2  
     3  import (
     4  	"database/sql"
     5  	"log"
     6  	"time"
     7  
     8  	qgen "github.com/Azareal/Gosora/query_gen"
     9  )
    10  
    11  var Analytics AnalyticsStore
    12  
    13  type AnalyticsTimeRange struct {
    14  	Quantity   int
    15  	Unit       string
    16  	Slices     int
    17  	SliceWidth int
    18  	Range      string
    19  }
    20  
    21  type AnalyticsStore interface {
    22  	FillViewMap(tbl string, tr *AnalyticsTimeRange, labelList []int64, viewMap map[int64]int64, param string, args ...interface{}) (map[int64]int64, error)
    23  }
    24  
    25  type DefaultAnalytics struct {
    26  }
    27  
    28  func NewDefaultAnalytics() *DefaultAnalytics {
    29  	return &DefaultAnalytics{}
    30  }
    31  
    32  /*
    33  	rows, e := qgen.NewAcc().Select("viewchunks_systems").Columns("count,createdAt").Where("system=?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(system)
    34  	if e != nil && e != sql.ErrNoRows {
    35  		return c.InternalError(e, w, r)
    36  	}
    37  	viewMap, e = c.AnalyticsRowsToViewMap(rows, labelList, viewMap)
    38  	if e != nil {
    39  		return c.InternalError(e, w, r)
    40  	}
    41  */
    42  
    43  func (s *DefaultAnalytics) FillViewMap(tbl string, tr *AnalyticsTimeRange, labelList []int64, viewMap map[int64]int64, param string, args ...interface{}) (map[int64]int64, error) {
    44  	ac := qgen.NewAcc().Select(tbl).Columns("count,createdAt")
    45  	if param != "" {
    46  		ac = ac.Where(param + "=?")
    47  	}
    48  	rows, e := ac.DateCutoff("createdAt", tr.Quantity, tr.Unit).Query(args...)
    49  	if e != nil && e != sql.ErrNoRows {
    50  		return nil, e
    51  	}
    52  	return AnalyticsRowsToViewMap(rows, labelList, viewMap)
    53  }
    54  
    55  // TODO: Clamp it rather than using an offset off the current time to avoid chaotic changes in stats as adjacent sets converge and diverge?
    56  func AnalyticsTimeRangeToLabelList(tr *AnalyticsTimeRange) (revLabelList []int64, labelList []int64, viewMap map[int64]int64) {
    57  	viewMap = make(map[int64]int64)
    58  	currentTime := time.Now().Unix()
    59  	for i := 1; i <= tr.Slices; i++ {
    60  		label := currentTime - int64(i*tr.SliceWidth)
    61  		revLabelList = append(revLabelList, label)
    62  		viewMap[label] = 0
    63  	}
    64  	labelList = append(labelList, revLabelList...)
    65  	return revLabelList, labelList, viewMap
    66  }
    67  
    68  func AnalyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64]int64) (map[int64]int64, error) {
    69  	defer rows.Close()
    70  	for rows.Next() {
    71  		var count int64
    72  		var createdAt time.Time
    73  		e := rows.Scan(&count, &createdAt)
    74  		if e != nil {
    75  			return viewMap, e
    76  		}
    77  		unixCreatedAt := createdAt.Unix()
    78  		// TODO: Bulk log this
    79  		if Dev.SuperDebug {
    80  			log.Print("count: ", count)
    81  			log.Print("createdAt: ", createdAt, " - ", unixCreatedAt)
    82  		}
    83  		for _, value := range labelList {
    84  			if unixCreatedAt > value {
    85  				viewMap[value] += count
    86  				break
    87  			}
    88  		}
    89  	}
    90  	return viewMap, rows.Err()
    91  }