2016-01-13 19:25:25 +00:00
package fic
2016-01-07 17:28:16 +00:00
import (
"database/sql"
2022-07-12 16:39:23 +00:00
"errors"
2023-04-01 15:11:40 +00:00
"fmt"
2024-03-23 17:03:08 +00:00
"io/ioutil"
2018-01-17 16:05:08 +00:00
"log"
2017-10-17 04:47:10 +00:00
"os"
2021-07-21 08:42:33 +00:00
"strings"
2018-01-17 16:05:08 +00:00
"time"
2022-07-12 16:39:23 +00:00
"github.com/go-sql-driver/mysql"
2016-01-07 17:28:16 +00:00
)
2018-03-09 18:07:08 +00:00
// db stores the connection to the database
2016-01-07 17:28:16 +00:00
var db * sql . DB
2018-03-09 18:07:08 +00:00
// DSNGenerator returns DSN filed with values from environment
2017-10-17 04:47:10 +00:00
func DSNGenerator ( ) string {
db_user := "fic"
db_password := "fic"
db_host := ""
db_db := "fic"
if v , exists := os . LookupEnv ( "MYSQL_HOST" ) ; exists {
2021-07-21 08:42:33 +00:00
if strings . HasPrefix ( v , "/" ) {
db_host = "unix(" + v + ")"
2019-07-30 15:13:55 +00:00
} else {
2021-07-21 08:42:33 +00:00
db_host = "tcp(" + v + ":"
if p , exists := os . LookupEnv ( "MYSQL_PORT" ) ; exists {
db_host += p + ")"
} else {
db_host += "3306)"
}
2019-07-30 15:13:55 +00:00
}
2017-10-17 04:47:10 +00:00
}
if v , exists := os . LookupEnv ( "MYSQL_PASSWORD" ) ; exists {
db_password = v
2024-03-23 17:03:08 +00:00
} else if v , exists := os . LookupEnv ( "MYSQL_PASSWORD_FILE" ) ; exists {
fd , err := os . Open ( v )
if err != nil {
log . Fatal ( "Unable to open MYSQL_PASSWORD_FILE:" , err )
}
b , _ := ioutil . ReadAll ( fd )
db_password = strings . TrimSpace ( string ( b ) )
fd . Close ( )
2017-10-17 04:47:10 +00:00
} else if v , exists := os . LookupEnv ( "MYSQL_ROOT_PASSWORD" ) ; exists {
db_user = "root"
db_password = v
}
if v , exists := os . LookupEnv ( "MYSQL_USER" ) ; exists {
db_user = v
}
if v , exists := os . LookupEnv ( "MYSQL_DATABASE" ) ; exists {
db_db = v
}
return db_user + ":" + db_password + "@" + db_host + "/" + db_db
}
2022-07-12 16:39:23 +00:00
func DBIsDuplicateKeyError ( err error ) bool {
var mysqlErr * mysql . MySQLError
return errors . As ( err , & mysqlErr ) && mysqlErr . Number == 1062
}
2018-03-09 18:07:08 +00:00
// DBInit establishes the connection to the database
2018-01-17 16:05:08 +00:00
func DBInit ( dsn string ) ( err error ) {
2020-05-16 01:49:27 +00:00
if db , err = sql . Open ( "mysql" , dsn + "?parseTime=true&foreign_key_checks=1" ) ; err != nil {
2018-01-17 16:05:08 +00:00
return
2016-01-07 17:28:16 +00:00
}
2018-01-17 16:05:08 +00:00
2018-05-12 00:01:49 +00:00
_ , err = db . Exec ( ` SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO'; ` )
2019-01-20 19:00:45 +00:00
for i := 0 ; err != nil && i < 45 ; i += 1 {
if _ , err = db . Exec ( ` SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO'; ` ) ; err != nil && i <= 45 {
2018-01-17 16:05:08 +00:00
log . Println ( "An error occurs when trying to connect to DB, will retry in 2 seconds: " , err )
time . Sleep ( 2 * time . Second )
}
2017-11-04 14:15:54 +00:00
}
2018-01-17 16:05:08 +00:00
return
2016-01-07 17:28:16 +00:00
}
2018-03-09 18:07:08 +00:00
// DBCreate creates all necessary tables used by the package
2016-01-07 17:28:16 +00:00
func DBCreate ( ) error {
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-25 02:09:22 +00:00
CREATE TABLE IF NOT EXISTS events (
id_event INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2018-01-23 00:27:31 +00:00
txt VARCHAR ( 255 ) NOT NULL ,
2018-12-09 17:35:28 +00:00
kind ENUM ( ' primary ' , ' secondary ' , ' success ' , ' danger ' , ' warning ' , ' info ' , ' light ' , ' dark ' ) NOT NULL ,
2016-01-25 02:09:22 +00:00
time TIMESTAMP NOT NULL
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-25 02:09:22 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS themes (
2016-01-23 12:16:31 +00:00
id_theme INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2018-07-13 05:25:21 +00:00
name VARCHAR ( 255 ) NOT NULL ,
2023-03-20 14:20:20 +00:00
locked BOOLEAN NOT NULL DEFAULT 0 ,
2018-08-27 16:37:36 +00:00
url_id VARCHAR ( 191 ) NOT NULL UNIQUE ,
path VARCHAR ( 191 ) NOT NULL UNIQUE ,
2018-12-02 10:43:24 +00:00
headline TEXT NOT NULL ,
2017-12-21 21:17:41 +00:00
intro TEXT NOT NULL ,
2018-11-25 02:20:03 +00:00
image VARCHAR ( 255 ) NOT NULL ,
2024-03-18 10:26:01 +00:00
background_color INTEGER UNSIGNED NOT NULL ,
2021-09-01 08:15:26 +00:00
authors TEXT NOT NULL ,
partner_img VARCHAR ( 255 ) NOT NULL ,
partner_href VARCHAR ( 255 ) NOT NULL ,
partner_text TEXT NOT NULL
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS teams (
2016-01-23 12:16:31 +00:00
id_team INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
name VARCHAR ( 255 ) NOT NULL ,
2024-03-18 10:26:01 +00:00
color INTEGER UNSIGNED NOT NULL ,
2021-09-03 15:23:00 +00:00
active BOOLEAN NOT NULL DEFAULT 1 ,
2023-03-20 09:46:47 +00:00
external_id TEXT NOT NULL ,
2021-09-09 09:20:45 +00:00
password VARCHAR ( 255 ) NULL
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-01-21 13:18:26 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS certificates (
2018-02-02 19:29:16 +00:00
id_cert BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2018-01-21 13:18:26 +00:00
creation TIMESTAMP NOT NULL ,
password VARCHAR ( 255 ) NOT NULL ,
2018-04-13 18:59:03 +00:00
revoked TIMESTAMP NULL
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS team_members (
2016-01-23 12:16:31 +00:00
id_member INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2016-01-07 17:28:16 +00:00
id_team INTEGER ,
2016-01-23 12:16:31 +00:00
firstname VARCHAR ( 255 ) NOT NULL ,
lastname VARCHAR ( 255 ) NOT NULL ,
nickname VARCHAR ( 255 ) NOT NULL ,
company VARCHAR ( 255 ) NOT NULL ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS exercices (
2016-01-23 12:16:31 +00:00
id_exercice INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2024-03-12 09:12:40 +00:00
id_theme INTEGER NULL ,
2016-01-23 12:16:31 +00:00
title VARCHAR ( 255 ) NOT NULL ,
2023-06-14 19:04:56 +00:00
authors TEXT NOT NULL ,
2023-06-14 15:34:18 +00:00
image VARCHAR ( 255 ) NOT NULL ,
2024-03-18 10:26:01 +00:00
background_color INTEGER UNSIGNED NOT NULL ,
2023-03-20 10:23:03 +00:00
disabled BOOLEAN NOT NULL DEFAULT 0 ,
2018-12-02 10:43:24 +00:00
headline TEXT NOT NULL ,
2018-01-18 10:07:50 +00:00
url_id VARCHAR ( 255 ) NOT NULL ,
2018-08-27 16:37:36 +00:00
path VARCHAR ( 191 ) NOT NULL UNIQUE ,
2016-01-07 17:28:16 +00:00
statement TEXT NOT NULL ,
2017-12-17 13:30:48 +00:00
overview TEXT NOT NULL ,
2018-11-21 01:20:37 +00:00
issue TEXT NOT NULL ,
issue_kind ENUM ( ' primary ' , ' secondary ' , ' success ' , ' danger ' , ' warning ' , ' info ' , ' light ' , ' dark ' ) NOT NULL DEFAULT ' info ' ,
2016-01-07 17:28:16 +00:00
depend INTEGER ,
gain INTEGER NOT NULL ,
2017-01-15 22:40:58 +00:00
coefficient_cur FLOAT NOT NULL DEFAULT 1.0 ,
2018-12-02 16:53:26 +00:00
finished TEXT NOT NULL ,
2021-12-10 17:55:47 +00:00
video_uri VARCHAR ( 255 ) NOT NULL ,
2022-05-24 19:30:11 +00:00
resolution MEDIUMTEXT NOT NULL ,
2021-12-10 17:55:47 +00:00
seealso TEXT NOT NULL ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_theme ) REFERENCES themes ( id_theme ) ,
FOREIGN KEY ( depend ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS exercice_files (
2016-01-23 12:16:31 +00:00
id_file INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
origin VARCHAR ( 255 ) NOT NULL ,
2018-08-27 16:37:36 +00:00
path VARCHAR ( 191 ) NOT NULL UNIQUE ,
2016-01-07 17:28:16 +00:00
id_exercice INTEGER NOT NULL ,
2016-01-23 12:16:31 +00:00
name VARCHAR ( 255 ) NOT NULL ,
2017-11-24 19:08:14 +00:00
cksum BINARY ( 64 ) NOT NULL ,
2022-10-31 17:29:41 +00:00
cksum_shown BINARY ( 64 ) ,
2020-01-20 14:58:30 +00:00
size BIGINT UNSIGNED NOT NULL ,
2022-11-23 15:55:49 +00:00
disclaimer VARCHAR ( 255 ) NOT NULL ,
2022-10-31 17:52:29 +00:00
published BOOLEAN NOT NULL DEFAULT 1 ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-12-04 18:15:39 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_hints (
id_hint INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_exercice INTEGER NOT NULL ,
title VARCHAR ( 255 ) NOT NULL ,
content TEXT NOT NULL ,
cost INTEGER NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2018-09-24 08:00:17 +00:00
CREATE TABLE IF NOT EXISTS exercice_flags (
id_flag INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2016-01-07 17:28:16 +00:00
id_exercice INTEGER NOT NULL ,
2021-08-30 16:33:14 +00:00
ordre TINYINT NOT NULL ,
label VARCHAR ( 255 ) NOT NULL ,
2016-01-23 12:16:31 +00:00
type VARCHAR ( 255 ) NOT NULL ,
2021-08-30 16:33:14 +00:00
placeholder VARCHAR ( 255 ) NOT NULL ,
2018-09-09 20:28:39 +00:00
help VARCHAR ( 255 ) NOT NULL ,
2021-11-12 22:52:22 +00:00
unit VARCHAR ( 255 ) NOT NULL ,
2018-09-24 07:23:09 +00:00
ignorecase BOOLEAN NOT NULL DEFAULT 0 ,
2021-12-07 15:33:30 +00:00
notrim BOOLEAN NOT NULL DEFAULT 0 ,
2020-01-16 14:33:28 +00:00
multiline BOOLEAN NOT NULL DEFAULT 0 ,
2018-11-16 19:46:19 +00:00
validator_regexp VARCHAR ( 255 ) NULL ,
2022-01-21 07:28:39 +00:00
sort_re_grps BOOLEAN NOT NULL DEFAULT 0 ,
2017-11-24 19:08:14 +00:00
cksum BINARY ( 64 ) NOT NULL ,
2022-05-31 20:03:51 +00:00
choices_cost MEDIUMINT NOT NULL ,
bonus_gain MEDIUMINT NOT NULL ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2022-01-21 12:06:37 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_flag_labels (
id_label INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_exercice INTEGER NOT NULL ,
ordre TINYINT NOT NULL ,
2023-07-16 17:00:10 +00:00
label TEXT NOT NULL ,
2022-01-21 12:06:37 +00:00
variant VARCHAR ( 255 ) NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2019-10-26 09:33:30 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2020-01-23 11:39:53 +00:00
CREATE TABLE IF NOT EXISTS exercice_hints_okey_deps (
2019-10-26 09:33:30 +00:00
id_hint INTEGER NOT NULL ,
id_flag_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_hint ) REFERENCES exercice_hints ( id_hint ) ,
FOREIGN KEY ( id_flag_dep ) REFERENCES exercice_flags ( id_flag )
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2018-12-02 18:21:07 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_flags_deps (
id_flag INTEGER NOT NULL ,
id_flag_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag ) ,
FOREIGN KEY ( id_flag_dep ) REFERENCES exercice_flags ( id_flag )
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2022-01-21 12:06:37 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_flag_labels_deps (
id_label INTEGER NOT NULL ,
id_flag_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_label ) REFERENCES exercice_flag_labels ( id_label ) ,
FOREIGN KEY ( id_flag_dep ) REFERENCES exercice_flags ( id_flag )
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2018-11-21 03:10:22 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS flag_choices (
id_choice INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_flag INTEGER NOT NULL ,
label VARCHAR ( 255 ) NOT NULL ,
response VARCHAR ( 255 ) NOT NULL ,
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-09-07 18:53:08 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2020-01-20 16:28:37 +00:00
CREATE TABLE IF NOT EXISTS exercice_files_okey_deps (
2018-09-07 18:53:08 +00:00
id_file INTEGER NOT NULL ,
2018-09-24 08:00:17 +00:00
id_flag INTEGER NOT NULL ,
2018-09-07 18:53:08 +00:00
FOREIGN KEY ( id_file ) REFERENCES exercice_files ( id_file ) ,
2018-09-24 08:00:17 +00:00
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag )
2018-09-07 18:53:08 +00:00
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2017-11-22 02:28:14 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_mcq (
id_mcq INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_exercice INTEGER NOT NULL ,
2021-08-30 16:33:14 +00:00
ordre TINYINT NOT NULL ,
2017-11-22 02:28:14 +00:00
title VARCHAR ( 255 ) NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2020-01-20 16:28:37 +00:00
` ) ; 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 ;
2020-01-23 11:39:53 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_hints_omcq_deps (
id_hint INTEGER NOT NULL ,
id_mcq_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_hint ) REFERENCES exercice_hints ( id_hint ) ,
2021-09-02 00:25:18 +00:00
FOREIGN KEY ( id_mcq_dep ) REFERENCES exercice_mcq ( id_mcq )
2020-01-23 11:39:53 +00:00
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2017-11-22 02:28:14 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2019-01-16 05:02:06 +00:00
CREATE TABLE IF NOT EXISTS exercice_mcq_okey_deps (
id_mcq INTEGER NOT NULL ,
id_flag_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_mcq ) REFERENCES exercice_mcq ( id_mcq ) ,
FOREIGN KEY ( id_flag_dep ) REFERENCES exercice_flags ( id_flag )
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_flags_omcq_deps (
id_flag INTEGER NOT NULL ,
id_mcq_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag ) ,
FOREIGN KEY ( id_mcq_dep ) REFERENCES exercice_mcq ( id_mcq )
2022-01-21 12:06:37 +00:00
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_flag_labels_omcq_deps (
id_label INTEGER NOT NULL ,
id_mcq_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_label ) REFERENCES exercice_flag_labels ( id_label ) ,
FOREIGN KEY ( id_mcq_dep ) REFERENCES exercice_mcq ( id_mcq )
2019-01-16 05:02:06 +00:00
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2020-01-20 16:29:34 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_mcq_omcq_deps (
id_mcq INTEGER NOT NULL ,
id_mcq_dep INTEGER NOT NULL ,
FOREIGN KEY ( id_mcq ) REFERENCES exercice_mcq ( id_mcq ) ,
FOREIGN KEY ( id_mcq_dep ) REFERENCES exercice_mcq ( id_mcq )
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin ;
2019-01-16 05:02:06 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2017-11-22 02:28:14 +00:00
CREATE TABLE IF NOT EXISTS mcq_entries (
id_mcq_entry INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_mcq INTEGER NOT NULL ,
label VARCHAR ( 255 ) NOT NULL ,
response BOOLEAN NOT NULL ,
FOREIGN KEY ( id_mcq ) REFERENCES exercice_mcq ( id_mcq )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2017-12-16 00:16:30 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS mcq_found (
id_mcq INTEGER NOT NULL ,
id_team INTEGER NOT NULL ,
time TIMESTAMP NOT NULL ,
CONSTRAINT uq_found UNIQUE ( id_mcq , id_team ) ,
FOREIGN KEY ( id_mcq ) REFERENCES exercice_mcq ( id_mcq ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-12-04 18:08:46 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
2018-09-24 08:00:17 +00:00
CREATE TABLE IF NOT EXISTS flag_found (
id_flag INTEGER NOT NULL ,
2016-12-04 18:08:46 +00:00
id_team INTEGER NOT NULL ,
time TIMESTAMP NOT NULL ,
2018-09-24 08:00:17 +00:00
CONSTRAINT uc_found UNIQUE ( id_flag , id_team ) ,
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag ) ,
2016-12-04 18:08:46 +00:00
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS exercice_solved (
id_exercice INTEGER NOT NULL ,
id_team INTEGER NOT NULL ,
time TIMESTAMP NOT NULL ,
2017-01-15 22:40:58 +00:00
coefficient FLOAT NOT NULL DEFAULT 1.0 ,
2017-01-29 17:12:21 +00:00
CONSTRAINT uc_solved UNIQUE ( id_exercice , id_team ) ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
}
2016-01-23 12:16:31 +00:00
if _ , err := db . Exec ( `
2016-01-07 17:28:16 +00:00
CREATE TABLE IF NOT EXISTS exercice_tries (
id_exercice INTEGER NOT NULL ,
id_team INTEGER NOT NULL ,
time TIMESTAMP NOT NULL ,
2018-11-21 02:22:42 +00:00
cksum BINARY ( 64 ) NOT NULL ,
2017-12-17 01:48:02 +00:00
nbdiff INTEGER NOT NULL DEFAULT 0 ,
2021-09-08 01:34:48 +00:00
onegood BOOLEAN NOT NULL DEFAULT 0 ,
2016-01-07 17:28:16 +00:00
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-11-18 21:44:23 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercice_tags (
id_exercice INTEGER NOT NULL ,
tag VARCHAR ( 255 ) NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2020-01-23 11:39:53 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-12-04 18:15:39 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS team_hints (
id_team INTEGER ,
id_hint INTEGER ,
time TIMESTAMP NOT NULL ,
2019-01-17 11:03:18 +00:00
coefficient FLOAT NOT NULL DEFAULT 1.0 ,
2017-01-29 17:12:21 +00:00
CONSTRAINT uc_displayed UNIQUE ( id_team , id_hint ) ,
2016-12-04 18:15:39 +00:00
FOREIGN KEY ( id_hint ) REFERENCES exercice_hints ( id_hint ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-12-02 22:18:32 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS team_wchoices (
id_team INTEGER ,
id_flag INTEGER ,
time TIMESTAMP NOT NULL ,
2019-01-17 11:03:18 +00:00
coefficient FLOAT NOT NULL DEFAULT 1.0 ,
2018-12-02 22:18:32 +00:00
CONSTRAINT uc_displayed UNIQUE ( id_team , id_flag ) ,
FOREIGN KEY ( id_flag ) REFERENCES exercice_flags ( id_flag ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-01-17 00:21:32 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS claim_assignees (
id_assignee INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2018-08-27 16:37:36 +00:00
name VARCHAR ( 191 ) NOT NULL UNIQUE
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-01-17 00:21:32 +00:00
` ) ; err != nil {
return err
}
2021-09-03 10:18:02 +00:00
db . Exec ( ` INSERT INTO claim_assignees VALUES (0, "$team"); ` )
db . Exec ( ` UPDATE claim_assignees SET id_assignee = 0 WHERE name = "$team"; ` )
2018-01-17 00:21:32 +00:00
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS claims (
id_claim INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
subject VARCHAR ( 255 ) NOT NULL ,
id_team INTEGER ,
2020-01-20 08:24:24 +00:00
id_exercice INTEGER ,
2018-01-17 00:21:32 +00:00
id_assignee INTEGER ,
creation TIMESTAMP NOT NULL ,
state ENUM ( ' new ' , ' need - info ' , ' confirmed ' , ' in - progress ' , ' need - review ' , ' closed ' , ' invalid ' ) NOT NULL ,
priority ENUM ( ' low ' , ' medium ' , ' high ' , ' critical ' ) NOT NULL ,
FOREIGN KEY ( id_assignee ) REFERENCES claim_assignees ( id_assignee ) ,
2020-01-20 08:24:24 +00:00
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team ) ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2018-01-17 00:21:32 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS claim_descriptions (
id_description INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_claim INTEGER NOT NULL ,
2020-05-16 01:49:27 +00:00
id_assignee INTEGER ,
2018-01-17 00:21:32 +00:00
date TIMESTAMP NOT NULL ,
content TEXT NOT NULL ,
2020-01-23 15:03:31 +00:00
publish BOOLEAN NOT NULL DEFAULT 0 ,
2018-01-17 00:21:32 +00:00
FOREIGN KEY ( id_claim ) REFERENCES claims ( id_claim )
2018-08-27 16:37:36 +00:00
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2020-09-08 10:50:41 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS exercices_qa (
id_qa INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_exercice INTEGER NOT NULL ,
2021-02-05 15:56:27 +00:00
id_team INTEGER NULL ,
2020-09-08 10:50:41 +00:00
authuser VARCHAR ( 255 ) NOT NULL ,
subject VARCHAR ( 255 ) NOT NULL ,
creation TIMESTAMP NOT NULL ,
state VARCHAR ( 255 ) NOT NULL ,
solved TIMESTAMP NULL ,
closed TIMESTAMP NULL ,
2023-11-26 11:15:51 +00:00
exported INTEGER NULL ,
2020-09-08 10:50:41 +00:00
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS qa_comments (
id_comment INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
id_qa INTEGER NOT NULL ,
2021-02-05 15:56:27 +00:00
id_team INTEGER NULL ,
2020-09-08 10:50:41 +00:00
authuser VARCHAR ( 255 ) NOT NULL ,
date TIMESTAMP NOT NULL ,
content TEXT NOT NULL ,
FOREIGN KEY ( id_qa ) REFERENCES exercices_qa ( id_qa ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2020-09-08 11:30:28 +00:00
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS teams_qa_todo (
id_todo INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2020-11-13 12:11:58 +00:00
id_team INTEGER NOT NULL ,
id_exercice INTEGER NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
` ) ; err != nil {
return err
}
if _ , err := db . Exec ( `
CREATE TABLE IF NOT EXISTS teams_qa_view (
id_view INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT ,
2020-09-08 11:30:28 +00:00
id_team INTEGER NOT NULL ,
id_exercice INTEGER NOT NULL ,
FOREIGN KEY ( id_exercice ) REFERENCES exercices ( id_exercice ) ,
FOREIGN KEY ( id_team ) REFERENCES teams ( id_team )
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ;
2016-01-23 12:16:31 +00:00
` ) ; err != nil {
2016-01-23 12:19:28 +00:00
return err
2020-05-16 01:49:27 +00:00
}
2018-12-06 21:18:08 +00:00
2022-02-03 16:37:10 +00:00
if _ , err := db . Exec ( "CREATE OR REPLACE VIEW exercice_distinct_tries AS SELECT id_exercice, id_team, MAX(time) AS time, cksum, nbdiff, MAX(onegood) AS onegood FROM exercice_tries GROUP BY id_team, id_exercice, cksum;" ) ; err != nil {
2021-09-08 01:34:48 +00:00
return err
}
if _ , err := db . Exec ( "CREATE OR REPLACE VIEW exercice_tries_notgood AS SELECT id_exercice, id_team, time, cksum, nbdiff, onegood FROM exercice_tries WHERE onegood = 0;" ) ; err != nil {
return err
}
2022-02-03 16:37:10 +00:00
if _ , err := db . Exec ( "CREATE OR REPLACE VIEW exercice_distinct_tries_notgood AS SELECT id_exercice, id_team, MAX(time) AS time, cksum, nbdiff, MAX(onegood) AS onegood FROM exercice_tries_notgood GROUP BY id_team, id_exercice, cksum;" ) ; err != nil {
2018-12-06 21:18:08 +00:00
return err
2016-01-23 12:19:28 +00:00
}
2023-04-01 15:11:40 +00:00
if err := DBRecreateDiscountedView ( ) ; err != nil {
return err
}
2018-12-06 21:18:08 +00:00
2016-01-23 12:16:31 +00:00
return nil
}
2016-01-07 17:28:16 +00:00
2023-04-01 15:11:40 +00:00
func DBRecreateDiscountedView ( ) ( err error ) {
if db == nil {
return
}
2024-03-18 10:26:01 +00:00
_ , err = db . Exec ( "CREATE OR REPLACE VIEW exercices_discounted AS SELECT E.id_exercice, E.id_theme, E.title, E.authors, E.image, E.background_color, E.disabled, E.headline, E.url_id, E.path, E.statement, E.overview, E.issue, E.issue_kind, E.depend, E.gain - " + fmt . Sprintf ( "%f" , DiscountedFactor ) + " * E.gain * (COUNT(*) - 1) AS gain, E.coefficient_cur, E.finished, E.video_uri, E.resolution, E.seealso FROM exercices E LEFT OUTER JOIN exercice_solved S ON S.id_exercice = E.id_exercice GROUP BY E.id_exercice;" )
2023-04-01 15:11:40 +00:00
return
}
2018-03-09 18:07:08 +00:00
// DBClose closes the connection to the database
2016-01-07 17:28:16 +00:00
func DBClose ( ) error {
return db . Close ( )
}
func DBQuery ( query string , args ... interface { } ) ( * sql . Rows , error ) {
return db . Query ( query , args ... )
}
func DBExec ( query string , args ... interface { } ) ( sql . Result , error ) {
return db . Exec ( query , args ... )
}
func DBQueryRow ( query string , args ... interface { } ) * sql . Row {
return db . QueryRow ( query , args ... )
}