package fic import ( "time" ) // MCQ represents a flag's challenge, in the form of checkbox. type MCQ struct { Id int64 `json:"id"` // IdExercice is the identifier of the underlying challenge IdExercice int64 `json:"idExercice"` // Title is the label of the question Title string `json:"title"` // Entries stores the set of proposed answers Entries []MCQ_entry `json:"entries"` } // MCQ_entry represents a proposed response for a given MCQ. type MCQ_entry struct { Id int64 `json:"id"` // Label is the text displayed to players as proposed answer Label string `json:"label"` // Response stores if expected checked state. Response bool `json:"response"` } // GetMCQ returns the MCQs coming with the challenge. func (e Exercice) GetMCQ() ([]MCQ, error) { if rows, err := DBQuery("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() var mcqs = make([]MCQ, 0) for rows.Next() { var m MCQ m.IdExercice = e.Id if err := rows.Scan(&m.Id, &m.IdExercice, &m.Title); err != nil { return nil, err } if entries_rows, err := DBQuery("SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?", m.Id); err != nil { return nil, err } 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 nil, err } m.Entries = append(m.Entries, e) } } mcqs = append(mcqs, m) } if err := rows.Err(); err != nil { return nil, err } return mcqs, nil } } // AddMCQ creates and fills a new struct MCQ and registers it into the database. 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 { return MCQ{}, err } else if qid, err := res.LastInsertId(); err != nil { return MCQ{}, err } else { return MCQ{qid, e.Id, title, []MCQ_entry{}}, nil } } // Update applies modifications back to the database. func (m MCQ) Update() (int64, error) { if res, err := DBExec("UPDATE exercice_mcq SET id_exercice = ?, title = ? WHERE id_mcq = ?", m.IdExercice, m.Title, m.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } // Delete the MCQ from the database. 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 } } // AddEntry creates and fills a new struct MCQ_entry and registers it into the database. 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 } } // Update applies modifications back to the database. 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 } } // Delete the MCQ entry from the database. 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 } } // WipeMCQs deletes MCQs coming with the challenge. func (e Exercice) WipeMCQs() (int64, error) { 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 { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } // Check if the given vals are the expected ones to validate this flag. func (m MCQ) Check(vals map[int64]bool) int { diff := 0 for _, n := range m.Entries { if v, ok := vals[n.Id]; (ok || !n.Response) && v == n.Response { continue } diff += 1 } return diff } // FoundBy registers in the database that the given Team solved the MCQ. func (m MCQ) FoundBy(t Team) { DBExec("INSERT INTO mcq_found (id_mcq, id_team, time) VALUES (?, ?, ?)", m.Id, t.Id, time.Now()) }