2019-02-03 21:30:29 +00:00
package fic
import (
2024-03-17 09:19:35 +00:00
"encoding/binary"
2019-02-03 21:30:29 +00:00
"fmt"
2024-03-17 09:19:35 +00:00
"math/rand"
2019-02-03 21:30:29 +00:00
"time"
)
// GetHistory aggregates all sources of events or actions for an Exercice
2021-11-22 14:35:07 +00:00
func ( e * Exercice ) GetHistory ( ) ( [ ] map [ string ] interface { } , error ) {
2019-02-03 21:30:29 +00:00
hist := make ( [ ] map [ string ] interface { } , 0 )
2019-02-03 21:40:44 +00:00
if rows , err := DBQuery ( ` SELECT id_team , U . name , U . color , "tries" AS kind , time , 0 , id_exercice , NULL , NULL FROM exercice_tries NATURAL JOIN teams U WHERE id_exercice = ? UNION
SELECT id_team , U . name , U . color , "solved" AS kind , time , coefficient , id_exercice , NULL , NULL FROM exercice_solved S NATURAL JOIN teams U WHERE id_exercice = ? UNION
SELECT id_team , U . name , U . color , "hint" AS kind , time , coefficient , id_exercice , H . id_hint , H . title FROM team_hints T INNER JOIN exercice_hints H ON H . id_hint = T . id_hint NATURAL JOIN teams U WHERE id_exercice = ? UNION
SELECT id_team , U . name , U . color , "wchoices" AS kind , time , coefficient , id_exercice , F . id_flag , F . type FROM team_wchoices W INNER JOIN exercice_flags F ON F . id_flag = W . id_flag NATURAL JOIN teams U WHERE id_exercice = ? UNION
SELECT id_team , U . name , U . color , "flag_found" AS kind , time , 0 , id_exercice , K . id_flag , K . type FROM flag_found F INNER JOIN exercice_flags K ON K . id_flag = F . id_flag NATURAL JOIN teams U WHERE id_exercice = ? UNION
SELECT id_team , U . name , U . color , "mcq_found" AS kind , time , 0 , id_exercice , Q . id_mcq , Q . title FROM mcq_found F INNER JOIN exercice_mcq Q ON Q . id_mcq = F . id_mcq NATURAL JOIN teams U WHERE id_exercice = ?
2019-02-03 21:30:29 +00:00
ORDER BY time DESC ` , e . Id , e . Id , e . Id , e . Id , e . Id , e . Id ) ; err != nil {
return nil , err
} else {
defer rows . Close ( )
for rows . Next ( ) {
var id_team int64
var team_name string
var team_color uint32
var kind string
var time time . Time
2019-02-03 21:40:44 +00:00
var coeff float32
2019-02-03 21:30:29 +00:00
var exercice int64
var secondary * int64
var secondary_title * string
2019-02-03 21:40:44 +00:00
if err := rows . Scan ( & id_team , & team_name , & team_color , & kind , & time , & coeff , & exercice , & secondary , & secondary_title ) ; err != nil {
2019-02-03 21:30:29 +00:00
return nil , err
}
h := map [ string ] interface { } { }
h [ "team_id" ] = id_team
h [ "team_name" ] = team_name
h [ "team_color" ] = fmt . Sprintf ( "#%x" , team_color )
h [ "kind" ] = kind
h [ "time" ] = time
2019-02-03 21:40:44 +00:00
h [ "coefficient" ] = coeff
2019-02-03 21:30:29 +00:00
h [ "primary" ] = e . Id
if secondary != nil {
h [ "secondary" ] = secondary
h [ "secondary_title" ] = secondary_title
}
hist = append ( hist , h )
}
}
return hist , nil
}
2024-03-17 09:19:35 +00:00
// AppendHistoryItem sets values an entry from the history.
func ( e * Exercice ) AppendHistoryItem ( tId int64 , kind string , secondary * int64 ) error {
team , err := GetTeam ( tId )
if err != nil {
return err
}
if kind == "tries" {
bid := make ( [ ] byte , 5 )
binary . LittleEndian . PutUint32 ( bid , rand . Uint32 ( ) )
return ( & Exercice { Id : e . Id } ) . NewTry ( team , bid )
} else if kind == "hint" && secondary != nil {
return team . OpenHint ( & EHint { Id : * secondary } )
} else if kind == "wchoices" && secondary != nil {
return team . DisplayChoices ( & FlagKey { Id : int ( * secondary ) } )
} else if kind == "flag_found" && secondary != nil {
return ( & FlagKey { Id : int ( * secondary ) } ) . FoundBy ( team )
} else if kind == "mcq_found" && secondary != nil {
return ( & MCQ { Id : int ( * secondary ) } ) . FoundBy ( team )
} else if kind == "solved" {
return ( & Exercice { Id : e . Id } ) . Solved ( team )
} else {
return nil
}
}
2019-07-12 17:17:17 +00:00
// UpdateHistoryItem sets values an entry from the history.
2021-11-22 14:35:07 +00:00
func ( e * Exercice ) UpdateHistoryItem ( coeff float32 , tId int64 , kind string , h time . Time , secondary * int64 ) ( interface { } , error ) {
2019-07-12 17:17:17 +00:00
if kind == "hint" && secondary != nil {
if res , err := DBExec ( "UPDATE team_hints SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_hint = ?" , coeff , h , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "wchoices" && secondary != nil {
if res , err := DBExec ( "UPDATE team_wchoices SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_flag = ?" , coeff , h , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "solved" {
if res , err := DBExec ( "UPDATE exercice_solved SET coefficient = ?, time = ? WHERE id_team = ? AND time = ? AND id_exercice = ?" , coeff , h , tId , h , e . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else {
return nil , nil
}
}
2019-02-03 21:30:29 +00:00
// DelHistoryItem removes from the database an entry from the history.
2021-11-22 14:35:07 +00:00
func ( e * Exercice ) DelHistoryItem ( tId int64 , kind string , h time . Time , secondary * int64 ) ( interface { } , error ) {
2019-02-03 21:30:29 +00:00
if kind == "tries" {
if res , err := DBExec ( "DELETE FROM exercice_tries WHERE id_team = ? AND time = ? AND id_exercice = ?" , tId , h , e . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "hint" && secondary != nil {
if res , err := DBExec ( "DELETE FROM team_hints WHERE id_team = ? AND time = ? AND id_hint = ?" , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "wchoices" && secondary != nil {
if res , err := DBExec ( "DELETE FROM team_wchoices WHERE id_team = ? AND time = ? AND id_flag = ?" , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "flag_found" && secondary != nil {
if res , err := DBExec ( "DELETE FROM flag_found WHERE id_team = ? AND time = ? AND id_flag = ?" , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "mcq_found" && secondary != nil {
if res , err := DBExec ( "DELETE FROM mcq_found WHERE id_team = ? AND time = ? AND id_mcq = ?" , tId , h , * secondary ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else if kind == "solved" {
if res , err := DBExec ( "DELETE FROM exercice_solved WHERE id_team = ? AND time = ? AND id_exercice = ?" , tId , h , e . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
} else {
return nil , nil
}
}