From c57b6122055b75880f5ab5cf29db0139e6d4177c Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 27 Dec 2016 21:12:17 +0100 Subject: [PATCH] Split team.go into multiple files --- libfic/stats.go | 109 ++++++++++++++++++++ libfic/team.go | 228 ++---------------------------------------- libfic/team_export.go | 36 +++++++ libfic/team_stats.go | 98 ++++++++++++++++++ 4 files changed, 249 insertions(+), 222 deletions(-) create mode 100644 libfic/stats.go create mode 100644 libfic/team_export.go create mode 100644 libfic/team_stats.go diff --git a/libfic/stats.go b/libfic/stats.go new file mode 100644 index 00000000..3ebac29f --- /dev/null +++ b/libfic/stats.go @@ -0,0 +1,109 @@ +package fic + +import ( + "database/sql" + "time" +) + +// Points + +func (t Team) GetPoints() (int64, error) { + var nb *int64 + err := DBQueryRow("SELECT SUM(E.gain) AS gains FROM exercice_solved S INNER JOIN exercices E ON E.id_exercice = S.id_exercice WHERE id_team = ?", t.Id).Scan(&nb) + if nb != nil { + return *nb, err + } else { + return 0, err + } +} + +func GetRank() (map[int64]int, error) { + if rows, err := DBQuery("SELECT id_team, SUM(E.gain) AS score, MAX(S.time) FROM exercice_solved S INNER JOIN exercices E ON E.id_exercice = S.id_exercice GROUP BY id_team HAVING score > 0 ORDER BY score DESC, time ASC"); err != nil { + return nil, err + } else { + defer rows.Close() + + rank := map[int64]int{} + nteam := 0 + for rows.Next() { + nteam += 1 + var tid int64 + var score int64 + var tzzz time.Time + if err := rows.Scan(&tid, &score, &tzzz); err != nil { + return nil, err + } + rank[tid] = nteam + } + if err := rows.Err(); err != nil { + return nil, err + } + + return rank, nil + } +} + + +// Tries + +func GetTries(t *Team, e *Exercice) ([]time.Time, error) { + var rows *sql.Rows + var err error + + if t == nil { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries ORDER BY time ASC") + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_exercice = ? ORDER BY time ASC", e.Id) + } + } else { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? ORDER BY time ASC", t.Id) + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? AND id_exercice = ? ORDER BY time ASC", t.Id, e.Id) + } + } + + if err != nil { + return nil, err + } else { + defer rows.Close() + + times := make([]time.Time, 0) + for rows.Next() { + var tm time.Time + if err := rows.Scan(&tm); err != nil { + return nil, err + } + times = append(times, tm) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return times, nil + } +} + +func GetTryRank() ([]int64, error) { + if rows, err := DBQuery("SELECT id_team, COUNT(*) AS score FROM exercice_tries GROUP BY id_team HAVING score > 0 ORDER BY score DESC"); err != nil { + return nil, err + } else { + defer rows.Close() + + rank := make([]int64, 0) + for rows.Next() { + var tid int64 + var score int64 + if err := rows.Scan(&tid, &score); err != nil { + return nil, err + } + rank = append(rank, tid) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return rank, nil + } +} diff --git a/libfic/team.go b/libfic/team.go index 03d7a3db..bb3622c0 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -1,8 +1,6 @@ package fic import ( - "database/sql" - "fmt" "time" ) @@ -15,6 +13,8 @@ type Team struct { Color uint32 `json:"color"` } +// Access functions + func GetTeams() ([]Team, error) { if rows, err := DBQuery("SELECT id_team, initial_name, name, color FROM teams"); err != nil { return nil, err @@ -55,6 +55,9 @@ func GetTeamByInitialName(initialName string) (Team, error) { return t, nil } + +// CRUD method + func CreateTeam(name string, color uint32) (Team, error) { if res, err := DBExec("INSERT INTO teams (initial_name, name, color) VALUES (?, ?, ?)", name, name, color); err != nil { return Team{}, err @@ -85,64 +88,8 @@ func (t Team) Delete() (int64, error) { } } -func (t Team) GetPoints() (int64, error) { - var nb *int64 - err := DBQueryRow("SELECT SUM(E.gain) FROM exercice_solved S INNER JOIN exercices E ON E.id_exercice = S.id_exercice WHERE id_team = ?", t.Id).Scan(&nb) - if nb != nil { - return *nb, err - } else { - return 0, err - } -} -func GetRank() (map[int64]int, error) { - if rows, err := DBQuery("SELECT id_team, SUM(E.gain) AS score, MAX(S.time) FROM exercice_solved S INNER JOIN exercices E ON E.id_exercice = S.id_exercice GROUP BY id_team HAVING score > 0 ORDER BY score DESC, time ASC"); err != nil { - return nil, err - } else { - defer rows.Close() - - rank := map[int64]int{} - nteam := 0 - for rows.Next() { - nteam += 1 - var tid int64 - var score int64 - var tzzz time.Time - if err := rows.Scan(&tid, &score, &tzzz); err != nil { - return nil, err - } - rank[tid] = nteam - } - if err := rows.Err(); err != nil { - return nil, err - } - - return rank, nil - } -} - -func GetTryRank() ([]int64, error) { - if rows, err := DBQuery("SELECT id_team, COUNT(*) AS score FROM exercice_tries GROUP BY id_team HAVING score > 0 ORDER BY score DESC"); err != nil { - return nil, err - } else { - defer rows.Close() - - rank := make([]int64, 0) - for rows.Next() { - var tid int64 - var score int64 - if err := rows.Scan(&tid, &score); err != nil { - return nil, err - } - rank = append(rank, tid) - } - if err := rows.Err(); err != nil { - return nil, err - } - - return rank, nil - } -} +// Exercice related functions func (t Team) HasAccess(e Exercice) bool { if e.Depend == nil || UnlockedChallenges { @@ -171,45 +118,6 @@ func NbTry(t *Team, e Exercice) int { } } -func GetTries(t *Team, e *Exercice) ([]time.Time, error) { - var rows *sql.Rows - var err error - - if t == nil { - if e == nil { - rows, err = DBQuery("SELECT time FROM exercice_tries ORDER BY time ASC") - } else { - rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_exercice = ? ORDER BY time ASC", e.Id) - } - } else { - if e == nil { - rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? ORDER BY time ASC", t.Id) - } else { - rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? AND id_exercice = ? ORDER BY time ASC", t.Id, e.Id) - } - } - - if err != nil { - return nil, err - } else { - defer rows.Close() - - times := make([]time.Time, 0) - for rows.Next() { - var tm time.Time - if err := rows.Scan(&tm); err != nil { - return nil, err - } - times = append(times, tm) - } - if err := rows.Err(); err != nil { - return nil, err - } - - return times, nil - } -} - func (t Team) HasHint(h EHint) (bool) { var tm *time.Time DBQueryRow("SELECT MIN(time) FROM team_hints WHERE id_team = ? AND id_hint = ?", t.Id, h.Id).Scan(&tm) @@ -254,127 +162,3 @@ func (t Team) HasPartiallySolved(k Key) (*time.Time) { DBQueryRow("SELECT MIN(time) FROM key_found WHERE id_team = ? AND id_key = ?", t.Id, k.Id).Scan(&tm) return tm } - -type statLine struct { - Tip string `json:"tip"` - Total int `json:"total"` - Solved int `json:"solved"` - Tried int `json:"tried"` - Tries int `json:"tries"` -} - -type teamStats struct { - Levels []statLine `json:"levels"` - Themes []statLine `json:"themes"` -} - -func (s *teamStats) GetLevel(level int) *statLine { - level -= 1 - - for len(s.Levels) <= level { - s.Levels = append(s.Levels, statLine{ - fmt.Sprintf("Level %d", (len(s.Levels) + 1)), - 0, - 0, - 0, - 0, - }) - } - - return &s.Levels[level] -} - -func (t Team) GetStats() (interface{}, error) { - return GetTeamsStats(&t) -} - -func GetTeamsStats(t *Team) (interface{}, error) { - stat := teamStats{} - - if themes, err := GetThemes(); err != nil { - return nil, err - } else { - for _, theme := range themes { - total := 0 - solved := 0 - tried := 0 - tries := 0 - - if exercices, err := theme.GetExercices(); err != nil { - return nil, err - } else { - for _, exercice := range exercices { - var lvl int - if lvl, err = exercice.GetLevel(); err != nil { - return nil, err - } - sLvl := stat.GetLevel(lvl) - - total += 1 - sLvl.Total += 1 - - if t != nil { - if b, _, _ := t.HasSolved(exercice); b { - solved += 1 - sLvl.Solved += 1 - } - } else { - if n, _ := IsSolved(exercice); n > 0 { - solved += 1 - sLvl.Solved += 1 - } - } - - try := NbTry(t, exercice) - if try > 0 { - tried += 1 - tries += try - sLvl.Tried += 1 - sLvl.Tries += try - } - } - } - - stat.Themes = append(stat.Themes, statLine{ - theme.Name, - total, - solved, - tried, - tries, - }) - } - - return stat, nil - } -} - -type exportedTeam struct { - Name string `json:"name"` - Color string `json:"color"` - Rank int `json:"rank"` - Points int64 `json:"score"` -} - -func ExportTeams() (interface{}, error) { - if teams, err := GetTeams(); err != nil { - return nil, err - } else if rank, err := GetRank(); err != nil { - return nil, err - } else { - ret := map[string]exportedTeam{} - for _, team := range teams { - if points, err := team.GetPoints(); err != nil { - return nil, err - } else { - ret[fmt.Sprintf("%d", team.Id)] = exportedTeam{ - team.Name, - fmt.Sprintf("#%x", team.Color), - rank[team.Id], - points, - } - } - } - - return ret, nil - } -} diff --git a/libfic/team_export.go b/libfic/team_export.go new file mode 100644 index 00000000..e25f7307 --- /dev/null +++ b/libfic/team_export.go @@ -0,0 +1,36 @@ +package fic + +import ( + "fmt" +) + +type exportedTeam struct { + Name string `json:"name"` + Color string `json:"color"` + Rank int `json:"rank"` + Points int64 `json:"score"` +} + +func ExportTeams() (interface{}, error) { + if teams, err := GetTeams(); err != nil { + return nil, err + } else if rank, err := GetRank(); err != nil { + return nil, err + } else { + ret := map[string]exportedTeam{} + for _, team := range teams { + if points, err := team.GetPoints(); err != nil { + return nil, err + } else { + ret[fmt.Sprintf("%d", team.Id)] = exportedTeam{ + team.Name, + fmt.Sprintf("#%x", team.Color), + rank[team.Id], + points, + } + } + } + + return ret, nil + } +} diff --git a/libfic/team_stats.go b/libfic/team_stats.go new file mode 100644 index 00000000..a9ef4112 --- /dev/null +++ b/libfic/team_stats.go @@ -0,0 +1,98 @@ +package fic + +import ( + "fmt" +) + +type statLine struct { + Tip string `json:"tip"` + Total int `json:"total"` + Solved int `json:"solved"` + Tried int `json:"tried"` + Tries int `json:"tries"` +} + +type teamStats struct { + Levels []statLine `json:"levels"` + Themes []statLine `json:"themes"` +} + +func (s *teamStats) GetLevel(level int) *statLine { + level -= 1 + + for len(s.Levels) <= level { + s.Levels = append(s.Levels, statLine{ + fmt.Sprintf("Level %d", (len(s.Levels) + 1)), + 0, + 0, + 0, + 0, + }) + } + + return &s.Levels[level] +} + +func (t Team) GetStats() (interface{}, error) { + return GetTeamsStats(&t) +} + +func GetTeamsStats(t *Team) (interface{}, error) { + stat := teamStats{} + + if themes, err := GetThemes(); err != nil { + return nil, err + } else { + for _, theme := range themes { + total := 0 + solved := 0 + tried := 0 + tries := 0 + + if exercices, err := theme.GetExercices(); err != nil { + return nil, err + } else { + for _, exercice := range exercices { + var lvl int + if lvl, err = exercice.GetLevel(); err != nil { + return nil, err + } + sLvl := stat.GetLevel(lvl) + + total += 1 + sLvl.Total += 1 + + if t != nil { + if b, _, _ := t.HasSolved(exercice); b { + solved += 1 + sLvl.Solved += 1 + } + } else { + if n, _ := IsSolved(exercice); n > 0 { + solved += 1 + sLvl.Solved += 1 + } + } + + try := NbTry(t, exercice) + if try > 0 { + tried += 1 + tries += try + sLvl.Tried += 1 + sLvl.Tries += try + } + } + } + + stat.Themes = append(stat.Themes, statLine{ + theme.Name, + total, + solved, + tried, + tries, + }) + } + + return stat, nil + } +}