Files can now depends on MCQ

This commit is contained in:
nemunaire 2020-01-20 17:28:37 +01:00
parent 823328ead2
commit e937073588
8 changed files with 91 additions and 29 deletions

View file

@ -69,6 +69,13 @@ func genFileList(in []fic.EFile, e error) (out []APIFile, err error) {
}
g.Depends = append(g.Depends, k)
} else if m, ok := d.(fic.MCQ); ok {
m, err = fic.GetMCQ(m.Id)
if err != nil {
return
}
g.Depends = append(g.Depends, m)
} else {
err = errors.New(fmt.Sprintf("Unknown type %T to handle file dependancy", k))
return

View file

@ -76,7 +76,8 @@
<span ng-if="!file.depends">aucun flag</span>
<ul ng-if="file.depends">
<li ng-repeat="dep in file.depends">
{{ dep.label }}
<span ng-if="dep.label">Flag {{ dep.label }}</span>
<span ng-if="dep.title">QCM {{ dep.title }}</span>
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteFileDep()"><span class="glyphicon glyphicon-trash"></span></button>
</li>
</ul>

View file

@ -215,7 +215,7 @@ CREATE TABLE IF NOT EXISTS flag_choices(
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_files_deps(
CREATE TABLE IF NOT EXISTS exercice_files_okey_deps(
id_file INTEGER NOT NULL,
id_flag INTEGER NOT NULL,
FOREIGN KEY(id_file) REFERENCES exercice_files(id_file),
@ -231,6 +231,16 @@ CREATE TABLE IF NOT EXISTS exercice_mcq(
title VARCHAR(255) NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil {
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_files_omcq_deps(
id_file INTEGER NOT NULL,
id_mcq INTEGER NOT NULL,
FOREIGN KEY(id_file) REFERENCES exercice_files(id_file),
FOREIGN KEY(id_mcq) REFERENCES exercice_mcq(id_mcq)
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin;
`); err != nil {
return err
}

View file

@ -263,7 +263,9 @@ func (f EFile) Delete() (int64, error) {
// WipeFiles deletes (only in the database, not on disk) files coming with the challenge.
func (e Exercice) WipeFiles() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_files_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
if _, err := DBExec("DELETE FROM exercice_files_okey_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_files_omcq_deps 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_files WHERE id_exercice = ?", e.Id); err != nil {
return 0, err
@ -293,7 +295,9 @@ func (f EFile) GetOrigin() string {
// AddDepend insert a new dependency to a given flag.
func (f EFile) AddDepend(j Flag) (err error) {
if k, ok := j.(FlagKey); ok {
_, err = DBExec("INSERT INTO exercice_files_deps (id_file, id_flag) VALUES (?, ?)", f.Id, k.Id)
_, err = DBExec("INSERT INTO exercice_files_okey_deps (id_file, id_flag) VALUES (?, ?)", f.Id, k.Id)
} else if m, ok := j.(MCQ); ok {
_, err = DBExec("INSERT INTO exercice_files_omcq_deps (id_file, id_mcq) VALUES (?, ?)", f.Id, m.Id)
} else {
err = errors.New("Dependancy type not implemented for this file.")
}
@ -303,7 +307,9 @@ func (f EFile) AddDepend(j Flag) (err error) {
// DeleteDepend insert a new dependency to a given flag.
func (f EFile) DeleteDepend(j Flag) (err error) {
if k, ok := j.(FlagKey); ok {
_, err = DBExec("DELETE FROM exercice_files_deps WHERE id_file = ? AND id_flag = ?", f.Id, k.Id)
_, err = DBExec("DELETE FROM exercice_files_okey_deps WHERE id_file = ? AND id_flag = ?", f.Id, k.Id)
} else if m, ok := j.(MCQ); ok {
_, err = DBExec("DELETE FROM exercice_files_omcq_deps WHERE id_file = ? AND id_mcq = ?", f.Id, m.Id)
} else {
err = errors.New("Dependancy type not implemented for this file.")
}
@ -312,12 +318,13 @@ func (f EFile) DeleteDepend(j Flag) (err error) {
// GetDepends retrieve the flag's dependency list.
func (f EFile) GetDepends() ([]Flag, error) {
if rows, err := DBQuery("SELECT id_flag FROM exercice_files_deps WHERE id_file = ?", f.Id); err != nil {
var deps = make([]Flag, 0)
if rows, err := DBQuery("SELECT id_flag FROM exercice_files_okey_deps WHERE id_file = ?", f.Id); err != nil {
return nil, err
} else {
defer rows.Close()
var deps = make([]Flag, 0)
for rows.Next() {
var d int64
if err := rows.Scan(&d); err != nil {
@ -328,9 +335,26 @@ func (f EFile) GetDepends() ([]Flag, error) {
if err := rows.Err(); err != nil {
return nil, err
}
return deps, nil
}
if rows, err := DBQuery("SELECT id_mcq FROM exercice_files_omcq_deps WHERE id_file = ?", f.Id); err != nil {
return nil, err
} else {
defer rows.Close()
for rows.Next() {
var d int64
if err := rows.Scan(&d); err != nil {
return nil, err
}
deps = append(deps, MCQ{d, f.IdExercice, "", []MCQ_entry{}})
}
if err := rows.Err(); err != nil {
return nil, err
}
}
return deps, nil
}
// CheckFileOnDisk recalculates the hash of the file on disk.

View file

@ -44,7 +44,9 @@ func (e Exercice) AddFlag(flag Flag) (f Flag, err error) {
// WipeFlags deletes flags coming with the challenge.
func (e Exercice) WipeFlags() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_files_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
if _, err := DBExec("DELETE FROM exercice_files_okey_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_files_omcq_deps WHERE id_mcq IN (SELECT id_mcq FROM exercice_mcq WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_flags_deps WHERE id_flag IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?) OR id_flag_dep IN (SELECT id_flag FROM exercice_flags WHERE id_exercice = ?)", e.Id, e.Id); err != nil {
return 0, err

View file

@ -184,7 +184,7 @@ func (k FlagKey) Update() (int64, error) {
// Delete the flag from the database.
func (k FlagKey) Delete() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_files_deps WHERE id_flag = ?", k.Id); err != nil {
if _, err := DBExec("DELETE FROM exercice_files_okey_deps WHERE id_flag = ?", k.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_mcq_okey_deps WHERE id_flag_dep = ?", k.Id); err != nil {
return 0, err

View file

@ -26,6 +26,33 @@ type MCQ_entry struct {
Response bool `json:"response"`
}
// GetMCQ returns a list of flags comming with the challenge.
func GetMCQ(id int64) (m MCQ, err error) {
err = DBQueryRow("SELECT id_mcq, id_exercice, title FROM exercice_mcq WHERE id_mcq = ?", id).Scan(&m.Id, &m.IdExercice, &m.Title)
m.fillEntries()
return
}
func (m *MCQ) fillEntries() ([]MCQ_entry, error) {
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)
}
}
return m.Entries, nil
}
// 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 {
@ -42,21 +69,7 @@ func (e Exercice) GetMCQ() ([]MCQ, error) {
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)
}
}
m.fillEntries()
mcqs = append(mcqs, m)
}
@ -147,7 +160,9 @@ func (m MCQ) Update() (int64, error) {
// Delete the MCQ from the database.
func (m MCQ) Delete() (int64, error) {
if _, err := DBExec("DELETE FROM exercice_mcq_okey_deps WHERE id_mcq = ?", m.Id); err != nil {
if _, err := DBExec("DELETE FROM exercice_files_omcq_deps WHERE id_mcq = ?", m.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_mcq_okey_deps WHERE id_mcq = ?", m.Id); err != nil {
return 0, err
} else if _, err := DBExec("DELETE FROM exercice_flags_omcq_deps WHERE id_mcq_dep = ?", m.Id); err != nil {
return 0, err
@ -196,7 +211,9 @@ func (n MCQ_entry) Delete() (int64, error) {
// 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 {
if _, err := DBExec("DELETE FROM exercice_files_omcq_deps WHERE id_mcq IN (SELECT id_mcq FROM exercice_mcq WHERE id_exercice = ?)", e.Id); err != nil {
return 0, err
} else 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 _, err := DBExec("DELETE FROM exercice_flags_omcq_deps WHERE id_mcq_dep IN (SELECT id_mcq FROM exercice_mcq WHERE id_exercice = ?);", e.Id); err != nil {
return 0, err

View file

@ -44,7 +44,8 @@ func ResetExercices() (error) {
return truncateTable(
"team_wchoices",
"team_hints",
"exercice_files_deps",
"exercice_files_okey_deps",
"exercice_files_omcq_deps",
"exercice_files",
"flag_found",
"exercice_flags_omcq_deps",