2017-11-22 02:28:14 +00:00
package fic
import (
2018-12-02 03:52:15 +00:00
"fmt"
2017-12-16 00:16:30 +00:00
"time"
2017-11-22 02:28:14 +00:00
)
2018-03-09 18:07:08 +00:00
// MCQ represents a flag's challenge, in the form of checkbox.
2017-11-22 02:28:14 +00:00
type MCQ struct {
Id int64 ` json:"id" `
2018-03-09 18:07:08 +00:00
// IdExercice is the identifier of the underlying challenge
2017-11-22 02:28:14 +00:00
IdExercice int64 ` json:"idExercice" `
2018-03-09 18:07:08 +00:00
// Title is the label of the question
2017-11-22 02:28:14 +00:00
Title string ` json:"title" `
2018-03-09 18:07:08 +00:00
// Entries stores the set of proposed answers
2017-11-22 02:28:14 +00:00
Entries [ ] MCQ_entry ` json:"entries" `
}
2018-03-09 18:07:08 +00:00
// MCQ_entry represents a proposed response for a given MCQ.
2017-11-22 02:28:14 +00:00
type MCQ_entry struct {
Id int64 ` json:"id" `
2018-03-09 18:07:08 +00:00
// Label is the text displayed to players as proposed answer
2017-11-22 02:28:14 +00:00
Label string ` json:"label" `
2018-03-09 18:07:08 +00:00
// Response stores if expected checked state.
2017-11-22 02:28:14 +00:00
Response bool ` json:"response" `
}
2018-03-09 18:07:08 +00:00
// GetMCQ returns the MCQs coming with the challenge.
2017-11-22 02:28:14 +00:00
func ( e Exercice ) GetMCQ ( ) ( [ ] MCQ , error ) {
2017-12-17 15:28:31 +00:00
if rows , err := DBQuery ( "SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_exercice = ?" , e . Id ) ; err != nil {
2017-11-22 02:28:14 +00:00
return nil , err
} else {
defer rows . Close ( )
var mcqs = make ( [ ] MCQ , 0 )
for rows . Next ( ) {
var m MCQ
m . IdExercice = e . Id
2017-12-17 15:28:31 +00:00
if err := rows . Scan ( & m . Id , & m . IdExercice , & m . Title ) ; err != nil {
2017-11-22 02:28:14 +00:00
return nil , err
}
2017-12-16 00:16:30 +00:00
if entries_rows , err := DBQuery ( "SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?" , m . Id ) ; err != nil {
2017-11-22 02:28:14 +00:00
return nil , err
} else {
defer entries_rows . Close ( )
2017-12-16 00:16:30 +00:00
for entries_rows . Next ( ) {
var e MCQ_entry
if err := entries_rows . Scan ( & e . Id , & e . Label , & e . Response ) ; err != nil {
return nil , err
}
m . Entries = append ( m . Entries , e )
}
2017-11-22 02:28:14 +00:00
}
2017-12-16 00:16:30 +00:00
mcqs = append ( mcqs , m )
2017-11-22 02:28:14 +00:00
}
if err := rows . Err ( ) ; err != nil {
return nil , err
}
return mcqs , nil
}
}
2018-11-28 06:39:50 +00:00
// GetMCQbyChoice returns the MCQ corresponding to a choice ID.
func GetMCQbyChoice ( cid int64 ) ( m MCQ , c MCQ_entry , err error ) {
if errr := DBQueryRow ( "SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_mcq = (SELECT id_mcq FROM mcq_entries WHERE id_mcq_entry = ?)" , cid ) . Scan ( & m . Id , & m . IdExercice , & m . Title ) ; err != nil {
return MCQ { } , MCQ_entry { } , errr
}
if entries_rows , errr := DBQuery ( "SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?" , m . Id ) ; err != nil {
return MCQ { } , MCQ_entry { } , errr
} else {
defer entries_rows . Close ( )
for entries_rows . Next ( ) {
var e MCQ_entry
if err = entries_rows . Scan ( & e . Id , & e . Label , & e . Response ) ; err != nil {
return
}
if e . Id == cid {
c = e
}
m . Entries = append ( m . Entries , e )
}
}
return
}
2018-03-09 18:07:08 +00:00
// AddMCQ creates and fills a new struct MCQ and registers it into the database.
2017-12-17 15:28:31 +00:00
func ( e Exercice ) AddMCQ ( title string ) ( MCQ , error ) {
if res , err := DBExec ( "INSERT INTO exercice_mcq (id_exercice, title) VALUES (?, ?)" , e . Id , title ) ; err != nil {
2017-11-22 02:28:14 +00:00
return MCQ { } , err
} else if qid , err := res . LastInsertId ( ) ; err != nil {
return MCQ { } , err
} else {
2017-12-17 15:28:31 +00:00
return MCQ { qid , e . Id , title , [ ] MCQ_entry { } } , nil
2017-11-22 02:28:14 +00:00
}
}
2018-03-09 18:07:08 +00:00
// Update applies modifications back to the database.
2017-11-22 02:28:14 +00:00
func ( m MCQ ) Update ( ) ( int64 , error ) {
2017-12-17 15:28:31 +00:00
if res , err := DBExec ( "UPDATE exercice_mcq SET id_exercice = ?, title = ? WHERE id_mcq = ?" , m . IdExercice , m . Title , m . Id ) ; err != nil {
2017-11-22 02:28:14 +00:00
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
2018-03-09 18:07:08 +00:00
// Delete the MCQ from the database.
2017-11-22 02:28:14 +00:00
func ( m MCQ ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM exercice_mcq WHERE id_mcq = ?" , m . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
2018-03-09 18:07:08 +00:00
// AddEntry creates and fills a new struct MCQ_entry and registers it into the database.
2017-11-22 02:28:14 +00:00
func ( m MCQ ) AddEntry ( label string , response bool ) ( MCQ_entry , error ) {
if res , err := DBExec ( "INSERT INTO mcq_entries (id_mcq, label, response) VALUES (?, ?, ?)" , m . Id , label , response ) ; err != nil {
return MCQ_entry { } , err
} else if nid , err := res . LastInsertId ( ) ; err != nil {
return MCQ_entry { } , err
} else {
return MCQ_entry { nid , label , response } , nil
}
}
2018-03-09 18:07:08 +00:00
// Update applies modifications back to the database.
2017-11-22 02:28:14 +00:00
func ( n MCQ_entry ) Update ( ) ( int64 , error ) {
if res , err := DBExec ( "UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq = ?" , n . Label , n . Response , n . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
2018-03-09 18:07:08 +00:00
// Delete the MCQ entry from the database.
2017-11-22 02:28:14 +00:00
func ( n MCQ_entry ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM mcq_entries WHERE id_mcq_entry = ?" , n . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
2018-03-09 18:07:08 +00:00
// WipeMCQs deletes MCQs coming with the challenge.
2017-12-16 02:39:57 +00:00
func ( e Exercice ) WipeMCQs ( ) ( int64 , error ) {
2018-06-24 17:09:34 +00:00
if _ , err := DBExec ( "DELETE FROM mcq_entries WHERE id_mcq IN (SELECT id_mcq FROM exercice_mcq WHERE id_exercice = ?);" , e . Id ) ; err != nil {
return 0 , err
} else if res , err := DBExec ( "DELETE FROM exercice_mcq WHERE id_exercice = ?;" , e . Id ) ; err != nil {
2017-12-16 02:39:57 +00:00
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
2018-11-28 06:39:50 +00:00
// GetJustifiedFlag searchs for a flag in the scope of the given exercice.
2018-12-02 03:52:15 +00:00
func ( c MCQ_entry ) GetJustifiedFlag ( e Exercice ) ( Flag , error ) {
return e . GetFlagByLabel ( fmt . Sprintf ( "\\%%%d\\%%%%" , c . Id ) )
2018-11-28 06:39:50 +00:00
}
2018-03-09 18:07:08 +00:00
// Check if the given vals are the expected ones to validate this flag.
2017-11-22 02:28:14 +00:00
func ( m MCQ ) Check ( vals map [ int64 ] bool ) int {
diff := 0
2017-12-16 00:16:30 +00:00
2017-11-22 02:28:14 +00:00
for _ , n := range m . Entries {
2017-12-16 02:39:57 +00:00
if v , ok := vals [ n . Id ] ; ( ok || ! n . Response ) && v == n . Response {
2017-11-22 02:28:14 +00:00
continue
}
diff += 1
}
return diff
}
2017-12-16 00:16:30 +00:00
2018-03-09 18:07:08 +00:00
// FoundBy registers in the database that the given Team solved the MCQ.
2017-12-16 00:16:30 +00:00
func ( m MCQ ) FoundBy ( t Team ) {
DBExec ( "INSERT INTO mcq_found (id_mcq, id_team, time) VALUES (?, ?, ?)" , m . Id , t . Id , time . Now ( ) )
}