Files can now depends on MCQ
This commit is contained in:
parent
823328ead2
commit
e937073588
8 changed files with 91 additions and 29 deletions
|
@ -69,6 +69,13 @@ func genFileList(in []fic.EFile, e error) (out []APIFile, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
g.Depends = append(g.Depends, k)
|
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 {
|
} else {
|
||||||
err = errors.New(fmt.Sprintf("Unknown type %T to handle file dependancy", k))
|
err = errors.New(fmt.Sprintf("Unknown type %T to handle file dependancy", k))
|
||||||
return
|
return
|
||||||
|
|
|
@ -76,7 +76,8 @@
|
||||||
<span ng-if="!file.depends">aucun flag</span>
|
<span ng-if="!file.depends">aucun flag</span>
|
||||||
<ul ng-if="file.depends">
|
<ul ng-if="file.depends">
|
||||||
<li ng-repeat="dep in 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>
|
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteFileDep()"><span class="glyphicon glyphicon-trash"></span></button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
12
libfic/db.go
12
libfic/db.go
|
@ -215,7 +215,7 @@ CREATE TABLE IF NOT EXISTS flag_choices(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := db.Exec(`
|
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_file INTEGER NOT NULL,
|
||||||
id_flag INTEGER NOT NULL,
|
id_flag INTEGER NOT NULL,
|
||||||
FOREIGN KEY(id_file) REFERENCES exercice_files(id_file),
|
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,
|
title VARCHAR(255) NOT NULL,
|
||||||
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
|
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
|
||||||
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
|
) 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 {
|
`); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,9 @@ func (f EFile) Delete() (int64, error) {
|
||||||
|
|
||||||
// WipeFiles deletes (only in the database, not on disk) files coming with the challenge.
|
// WipeFiles deletes (only in the database, not on disk) files coming with the challenge.
|
||||||
func (e Exercice) WipeFiles() (int64, error) {
|
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
|
return 0, err
|
||||||
} else if res, err := DBExec("DELETE FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil {
|
} else if res, err := DBExec("DELETE FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -293,7 +295,9 @@ func (f EFile) GetOrigin() string {
|
||||||
// AddDepend insert a new dependency to a given flag.
|
// AddDepend insert a new dependency to a given flag.
|
||||||
func (f EFile) AddDepend(j Flag) (err error) {
|
func (f EFile) AddDepend(j Flag) (err error) {
|
||||||
if k, ok := j.(FlagKey); ok {
|
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 {
|
} else {
|
||||||
err = errors.New("Dependancy type not implemented for this file.")
|
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.
|
// DeleteDepend insert a new dependency to a given flag.
|
||||||
func (f EFile) DeleteDepend(j Flag) (err error) {
|
func (f EFile) DeleteDepend(j Flag) (err error) {
|
||||||
if k, ok := j.(FlagKey); ok {
|
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 {
|
} else {
|
||||||
err = errors.New("Dependancy type not implemented for this file.")
|
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.
|
// GetDepends retrieve the flag's dependency list.
|
||||||
func (f EFile) GetDepends() ([]Flag, error) {
|
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
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var deps = make([]Flag, 0)
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var d int64
|
var d int64
|
||||||
if err := rows.Scan(&d); err != nil {
|
if err := rows.Scan(&d); err != nil {
|
||||||
|
@ -328,10 +335,27 @@ func (f EFile) GetDepends() ([]Flag, error) {
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
return deps, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// CheckFileOnDisk recalculates the hash of the file on disk.
|
// CheckFileOnDisk recalculates the hash of the file on disk.
|
||||||
func (f EFile) CheckFileOnDisk() error {
|
func (f EFile) CheckFileOnDisk() error {
|
||||||
|
|
|
@ -44,7 +44,9 @@ func (e Exercice) AddFlag(flag Flag) (f Flag, err error) {
|
||||||
|
|
||||||
// WipeFlags deletes flags coming with the challenge.
|
// WipeFlags deletes flags coming with the challenge.
|
||||||
func (e Exercice) WipeFlags() (int64, error) {
|
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
|
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 {
|
} 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
|
return 0, err
|
||||||
|
|
|
@ -184,7 +184,7 @@ func (k FlagKey) Update() (int64, error) {
|
||||||
|
|
||||||
// Delete the flag from the database.
|
// Delete the flag from the database.
|
||||||
func (k FlagKey) Delete() (int64, error) {
|
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
|
return 0, err
|
||||||
} else if _, err := DBExec("DELETE FROM exercice_mcq_okey_deps WHERE id_flag_dep = ?", k.Id); err != nil {
|
} else if _, err := DBExec("DELETE FROM exercice_mcq_okey_deps WHERE id_flag_dep = ?", k.Id); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -26,6 +26,33 @@ type MCQ_entry struct {
|
||||||
Response bool `json:"response"`
|
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.
|
// GetMCQ returns the MCQs coming with the challenge.
|
||||||
func (e Exercice) GetMCQ() ([]MCQ, error) {
|
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 {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if entries_rows, err := DBQuery("SELECT id_mcq_entry, label, response FROM mcq_entries WHERE id_mcq = ?", m.Id); err != nil {
|
m.fillEntries()
|
||||||
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)
|
mcqs = append(mcqs, m)
|
||||||
}
|
}
|
||||||
|
@ -147,7 +160,9 @@ func (m MCQ) Update() (int64, error) {
|
||||||
|
|
||||||
// Delete the MCQ from the database.
|
// Delete the MCQ from the database.
|
||||||
func (m MCQ) Delete() (int64, error) {
|
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
|
return 0, err
|
||||||
} else if _, err := DBExec("DELETE FROM exercice_flags_omcq_deps WHERE id_mcq_dep = ?", m.Id); err != nil {
|
} else if _, err := DBExec("DELETE FROM exercice_flags_omcq_deps WHERE id_mcq_dep = ?", m.Id); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -196,7 +211,9 @@ func (n MCQ_entry) Delete() (int64, error) {
|
||||||
|
|
||||||
// WipeMCQs deletes MCQs coming with the challenge.
|
// WipeMCQs deletes MCQs coming with the challenge.
|
||||||
func (e Exercice) WipeMCQs() (int64, error) {
|
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
|
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 {
|
} 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
|
return 0, err
|
||||||
|
|
|
@ -44,7 +44,8 @@ func ResetExercices() (error) {
|
||||||
return truncateTable(
|
return truncateTable(
|
||||||
"team_wchoices",
|
"team_wchoices",
|
||||||
"team_hints",
|
"team_hints",
|
||||||
"exercice_files_deps",
|
"exercice_files_okey_deps",
|
||||||
|
"exercice_files_omcq_deps",
|
||||||
"exercice_files",
|
"exercice_files",
|
||||||
"flag_found",
|
"flag_found",
|
||||||
"exercice_flags_omcq_deps",
|
"exercice_flags_omcq_deps",
|
||||||
|
|
Reference in a new issue