fic: Add team's external_id to allow team and score synchronisation

This commit is contained in:
nemunaire 2021-09-03 17:23:00 +02:00
parent 342d216b3e
commit 5c12963da8
5 changed files with 30 additions and 26 deletions

View File

@ -155,7 +155,7 @@ func createTeam(_ httprouter.Params, body []byte) (interface{}, error) {
return nil, err return nil, err
} }
return fic.CreateTeam(strings.TrimSpace(ut.Name), ut.Color) return fic.CreateTeam(strings.TrimSpace(ut.Name), ut.Color, ut.ExternalId)
} }
func updateTeam(team fic.Team, body []byte) (interface{}, error) { func updateTeam(team fic.Team, body []byte) (interface{}, error) {

View File

@ -1997,7 +1997,7 @@ angular.module("FICApp")
if ($scope.team && $scope.team.id) if ($scope.team && $scope.team.id)
$routeParams.teamId = $scope.team.id; $routeParams.teamId = $scope.team.id;
$scope.team = Team.get({ teamId: $routeParams.teamId }); $scope.team = Team.get({ teamId: $routeParams.teamId });
$scope.fields = ["name", "color"]; $scope.fields = ["name", "color", "external_id"];
$scope.saveTeam = function() { $scope.saveTeam = function() {
if (this.team.id) { if (this.team.id) {

View File

@ -98,7 +98,8 @@ CREATE TABLE IF NOT EXISTS teams(
id_team INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, id_team INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
color INTEGER NOT NULL, color INTEGER NOT NULL,
active BOOLEAN NOT NULL DEFAULT 1 active BOOLEAN NOT NULL DEFAULT 1,
external_id VARCHAR(255) NOT NULL
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil { `); err != nil {
return err return err

View File

@ -14,14 +14,15 @@ var WChoiceCoefficient = 1.0
// Team represents a group of players, come to solve our challenges. // Team represents a group of players, come to solve our challenges.
type Team struct { type Team struct {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Color uint32 `json:"color"` Color uint32 `json:"color"`
Active bool `json:"active"` Active bool `json:"active"`
ExternalId string `json:"external_id"`
} }
func getTeams(filter string) ([]Team, error) { func getTeams(filter string) ([]Team, error) {
if rows, err := DBQuery("SELECT id_team, name, color, active FROM teams " + filter); err != nil { if rows, err := DBQuery("SELECT id_team, name, color, active, external_id FROM teams " + filter); err != nil {
return nil, err return nil, err
} else { } else {
defer rows.Close() defer rows.Close()
@ -29,7 +30,7 @@ func getTeams(filter string) ([]Team, error) {
var teams = make([]Team, 0) var teams = make([]Team, 0)
for rows.Next() { for rows.Next() {
var t Team var t Team
if err := rows.Scan(&t.Id, &t.Name, &t.Color, &t.Active); err != nil { if err := rows.Scan(&t.Id, &t.Name, &t.Color, &t.Active, &t.ExternalId); err != nil {
return nil, err return nil, err
} }
teams = append(teams, t) teams = append(teams, t)
@ -55,7 +56,7 @@ func GetActiveTeams() ([]Team, error) {
// GetTeam retrieves a Team from its identifier. // GetTeam retrieves a Team from its identifier.
func GetTeam(id int64) (Team, error) { func GetTeam(id int64) (Team, error) {
var t Team var t Team
if err := DBQueryRow("SELECT id_team, name, color, active FROM teams WHERE id_team = ?", id).Scan(&t.Id, &t.Name, &t.Color, &t.Active); err != nil { if err := DBQueryRow("SELECT id_team, name, color, active, external_id FROM teams WHERE id_team = ?", id).Scan(&t.Id, &t.Name, &t.Color, &t.Active, &t.ExternalId); err != nil {
return t, err return t, err
} }
@ -65,7 +66,7 @@ func GetTeam(id int64) (Team, error) {
// GetTeamBySerial retrieves a Team from one of its associated certificates. // GetTeamBySerial retrieves a Team from one of its associated certificates.
func GetTeamBySerial(serial int64) (Team, error) { func GetTeamBySerial(serial int64) (Team, error) {
var t Team var t Team
if err := DBQueryRow("SELECT T.id_team, T.name, T.color, T.active FROM certificates C INNER JOIN teams T ON T.id_team = C.id_team WHERE id_cert = ?", serial).Scan(&t.Id, &t.Name, &t.Color, &t.Active); err != nil { if err := DBQueryRow("SELECT T.id_team, T.name, T.color, T.active, T.external_id FROM certificates C INNER JOIN teams T ON T.id_team = C.id_team WHERE id_cert = ?", serial).Scan(&t.Id, &t.Name, &t.Color, &t.Active, &t.ExternalId); err != nil {
return t, err return t, err
} }
@ -73,19 +74,19 @@ func GetTeamBySerial(serial int64) (Team, error) {
} }
// CreateTeam creates and fills a new struct Team and registers it into the database. // CreateTeam creates and fills a new struct Team and registers it into the database.
func CreateTeam(name string, color uint32) (Team, error) { func CreateTeam(name string, color uint32, externalId string) (Team, error) {
if res, err := DBExec("INSERT INTO teams (name, color) VALUES (?, ?)", name, color); err != nil { if res, err := DBExec("INSERT INTO teams (name, color, external_id) VALUES (?, ?, ?)", name, color, externalId); err != nil {
return Team{}, err return Team{}, err
} else if tid, err := res.LastInsertId(); err != nil { } else if tid, err := res.LastInsertId(); err != nil {
return Team{}, err return Team{}, err
} else { } else {
return Team{tid, name, color, true}, nil return Team{tid, name, color, true, ""}, nil
} }
} }
// Update applies modifications back to the database. // Update applies modifications back to the database.
func (t Team) Update() (int64, error) { func (t Team) Update() (int64, error) {
if res, err := DBExec("UPDATE teams SET name = ?, color = ?, active = ? WHERE id_team = ?", t.Name, t.Color, t.Active, t.Id); err != nil { if res, err := DBExec("UPDATE teams SET name = ?, color = ?, active = ?, external_id = ? WHERE id_team = ?", t.Name, t.Color, t.Active, t.ExternalId, t.Id); err != nil {
return 0, err return 0, err
} else if nb, err := res.RowsAffected(); err != nil { } else if nb, err := res.RowsAffected(); err != nil {
return 0, err return 0, err
@ -203,9 +204,9 @@ func NbTry(t *Team, e Exercice) int {
var cnt *int var cnt *int
if t != nil { if t != nil {
DBQueryRow("SELECT COUNT(*) FROM " + tries_table + " WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt) DBQueryRow("SELECT COUNT(*) FROM "+tries_table+" WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt)
} else { } else {
DBQueryRow("SELECT COUNT(*) FROM " + tries_table + " WHERE id_exercice = ?", e.Id).Scan(&cnt) DBQueryRow("SELECT COUNT(*) FROM "+tries_table+" WHERE id_exercice = ?", e.Id).Scan(&cnt)
} }
if cnt == nil { if cnt == nil {
@ -216,27 +217,27 @@ func NbTry(t *Team, e Exercice) int {
} }
// HasHint checks if the Team has revealed the given Hint. // HasHint checks if the Team has revealed the given Hint.
func (t Team) HasHint(h EHint) (bool) { func (t Team) HasHint(h EHint) bool {
var tm *time.Time var tm *time.Time
DBQueryRow("SELECT MIN(time) FROM team_hints WHERE id_team = ? AND id_hint = ?", t.Id, h.Id).Scan(&tm) DBQueryRow("SELECT MIN(time) FROM team_hints WHERE id_team = ? AND id_hint = ?", t.Id, h.Id).Scan(&tm)
return tm != nil return tm != nil
} }
// OpenHint registers to the database that the Team has now revealed. // OpenHint registers to the database that the Team has now revealed.
func (t Team) OpenHint(h EHint) (error) { func (t Team) OpenHint(h EHint) error {
_, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, h.Id, time.Now(), math.Max(HintCoefficient, 0.0)) _, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, h.Id, time.Now(), math.Max(HintCoefficient, 0.0))
return err return err
} }
// SeeChoices checks if the Team has revealed the given choices. // SeeChoices checks if the Team has revealed the given choices.
func (t Team) SeeChoices(k FlagKey) (bool) { func (t Team) SeeChoices(k FlagKey) bool {
var tm *time.Time var tm *time.Time
DBQueryRow("SELECT MIN(time) FROM team_wchoices WHERE id_team = ? AND id_flag = ?", t.Id, k.Id).Scan(&tm) DBQueryRow("SELECT MIN(time) FROM team_wchoices WHERE id_team = ? AND id_flag = ?", t.Id, k.Id).Scan(&tm)
return tm != nil return tm != nil
} }
// DisplayChoices registers to the database that the Team has now revealed. // DisplayChoices registers to the database that the Team has now revealed.
func (t Team) DisplayChoices(k FlagKey) (error) { func (t Team) DisplayChoices(k FlagKey) error {
_, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, k.Id, time.Now(), math.Max(WChoiceCoefficient, 0.0)) _, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, k.Id, time.Now(), math.Max(WChoiceCoefficient, 0.0))
return err return err
} }

View File

@ -6,11 +6,12 @@ import (
// exportedTeam is a structure representing a Team, as exposed to players. // exportedTeam is a structure representing a Team, as exposed to players.
type exportedTeam struct { type exportedTeam struct {
Name string `json:"name"` Name string `json:"name"`
Color string `json:"color"` Color string `json:"color"`
Rank int `json:"rank"` Rank int `json:"rank"`
Points float64 `json:"score"` Points float64 `json:"score"`
Members []Member `json:"members,omitempty"` Members []Member `json:"members,omitempty"`
ExternalId string `json:"external_id,omitempty"`
} }
// Exportedteam creates the structure to respond as teams.json. // Exportedteam creates the structure to respond as teams.json.
@ -38,6 +39,7 @@ func ExportTeams(includeMembers bool) (ret map[string]exportedTeam, err error) {
rank[team.Id], rank[team.Id],
points, points,
members, members,
team.ExternalId,
} }
} }