package fic import ( "path" "strings" ) // EHint represents a challenge hint. type EHint struct { Id int64 `json:"id"` // IdExercice is the identifier of the underlying challenge IdExercice int64 `json:"idExercice"` // Title is the hint name displayed to players Title string `json:"title"` // Content is the actual content of small text hints (mutually exclusive with File field) // When File is filled, Content contains the hexadecimal file's hash. Content string `json:"content"` // File is path, relative to FilesDir where the file hint is stored (mutually exclusive with Content field) File string `json:"file"` // Cost is the amount of points the player will loose if it unlocks the hint Cost int64 `json:"cost"` } // treatHintContent reads Content to detect if this is a hint file in order to convert to such hint. func treatHintContent(h *EHint) { if strings.HasPrefix(h.Content, "$FILES") { fpath := strings.TrimPrefix(h.Content, "$FILES") h.Content = fpath[:128] fpath = fpath[128:] h.File = path.Join(FilesDir, fpath) } } // GetHint retrieves the hint with the given id. func GetHint(id int64) (EHint, error) { var h EHint if err := DBQueryRow("SELECT id_hint, id_exercice, title, content, cost FROM exercice_hints WHERE id_hint = ?", id).Scan(&h.Id, &h.IdExercice, &h.Title, &h.Content, &h.Cost); err != nil { return h, err } treatHintContent(&h) return h, nil } // GetHints returns a list of hints comming with the challenge. func (e Exercice) GetHints() ([]EHint, error) { if rows, err := DBQuery("SELECT id_hint, title, content, cost FROM exercice_hints WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() var hints = make([]EHint, 0) for rows.Next() { var h EHint h.IdExercice = e.Id if err := rows.Scan(&h.Id, &h.Title, &h.Content, &h.Cost); err != nil { return nil, err } treatHintContent(&h) hints = append(hints, h) } if err := rows.Err(); err != nil { return nil, err } return hints, nil } } // AddHint creates and fills a new struct EHint and registers it into the database. func (e Exercice) AddHint(title string, content string, cost int64) (EHint, error) { if res, err := DBExec("INSERT INTO exercice_hints (id_exercice, title, content, cost) VALUES (?, ?, ?, ?)", e.Id, title, content, cost); err != nil { return EHint{}, err } else if hid, err := res.LastInsertId(); err != nil { return EHint{}, err } else { return EHint{hid, e.Id, title, content, "", cost}, nil } } // Update applies modifications back to the database. func (h EHint) Update() (int64, error) { if res, err := DBExec("UPDATE exercice_hints SET id_exercice = ?, title = ?, content = ?, cost = ? WHERE id_hint = ?", h.IdExercice, h.Title, h.Content, h.Cost, h.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } // Delete the hint from the database. func (h EHint) Delete() (int64, error) { if res, err := DBExec("DELETE FROM exercice_hints WHERE id_hint = ?", h.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } // WipeHints deletes (only in the database, not on disk) hints coming with the challenge. func (e Exercice) WipeHints() (int64, error) { if res, err := DBExec("DELETE FROM exercice_hints 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 } } // GetExercice returns the parent Exercice where this hint can be found. func (h EHint) GetExercice() (Exercice, error) { var eid int64 if err := DBQueryRow("SELECT id_exercice FROM exercice_hints WHERE id_hint = ?", h.Id).Scan(&eid); err != nil { return Exercice{}, err } return GetExercice(eid) }