diff --git a/db/migrations/v1_init.sql b/db/migrations/v1_init.sql index b70965f..4c8eabf 100644 --- a/db/migrations/v1_init.sql +++ b/db/migrations/v1_init.sql @@ -41,4 +41,144 @@ CREATE TABLE quiz_question_answer FOREIGN KEY (question_sha1) REFERENCES quiz_question (sha1), FOREIGN KEY (answer_sha1) REFERENCES quiz_answer (sha1) +); + +CREATE TABLE role +( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL +); + +INSERT INTO role (id, name) +VALUES (1, 'Admin'); +INSERT INTO role (id, name) +VALUES (2, 'Teacher'); +INSERT INTO role (id, name) +VALUES (3, 'Student'); + +CREATE TABLE student_class +( + uuid TEXT PRIMARY KEY, + name TEXT NOT NULL +); + +CREATE TABLE user +( + id TEXT PRIMARY KEY, + email TEXT NOT NULL, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL, + active INTEGER NOT NULL DEFAULT 1, + role_id INTEGER NOT NULL, + class_uuid TEXT, + + FOREIGN KEY (role_id) REFERENCES role (id), + FOREIGN KEY (class_uuid) REFERENCES student_class (uuid) ON DELETE SET NULL +); + +CREATE TABLE session +( + uuid TEXT PRIMARY KEY, + quiz_sha1 TEXT NOT NULL, + user_id TEXT NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + UNIQUE (quiz_sha1, user_id), + FOREIGN KEY (quiz_sha1) REFERENCES quiz (sha1), + FOREIGN KEY (user_id) REFERENCES user (id) +); + +CREATE TABLE session_answer +( + session_uuid TEXT NOT NULL, + user_id TEXT NOT NULL, + question_sha1 TEXT NOT NULL, + answer_sha1 TEXT NOT NULL, + checked INTEGER NOT NULL, + + PRIMARY KEY (session_uuid, question_sha1, answer_sha1), + FOREIGN KEY (session_uuid) REFERENCES session (uuid), + FOREIGN KEY (user_id) REFERENCES user (id), + FOREIGN KEY (question_sha1) REFERENCES quiz_question (sha1), + FOREIGN KEY (answer_sha1) REFERENCES quiz_answer (sha1) +); + +CREATE VIEW quiz_answer_count_view +AS +SELECT q.sha1 AS quiz_sha1, + COUNT(qa.valid) AS checked_answers +FROM quiz q + JOIN quiz_question_quiz qqq ON q.sha1 = qqq.quiz_sha1 + JOIN quiz_question_answer qqa ON qqq.question_sha1 = qqa.question_sha1 + JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 +GROUP BY q.sha1; + +CREATE VIEW session_response_view +AS +SELECT qqq.quiz_sha1, + qqq.question_sha1, + qqa.answer_sha1, + s.uuid AS session_uuid, + s.user_id, + sa.checked, + CASE + WHEN checked IS NOT NULL + THEN CASE + WHEN qa.valid == sa.checked + THEN 1 + ELSE 0 + END + END AS result +FROM quiz_question_quiz qqq + JOIN quiz_question_answer qqa ON qqq.question_sha1 = qqa.question_sha1 + JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 + LEFT JOIN session s ON qqq.quiz_sha1 = s.quiz_sha1 + LEFT JOIN session_answer sa ON qa.sha1 = sa.answer_sha1 AND sa.question_sha1 = qqq.question_sha1 AND + sa.answer_sha1 = qqa.answer_sha1; + +CREATE VIEW session_view +AS +SELECT s.uuid AS uuid, + q.sha1 AS quiz_sha1, + q.name AS quiz_name, + q.active AS quiz_active, + u.id AS user_id, + CAST(u.firstname || ' ' || u.lastname AS TEXT) AS user_name, + CAST(MAX(q.duration - (STRFTIME('%s', 'now') - STRFTIME('%s', s.created_at)), 0) AS INTEGER) AS remaining_sec, + checked_answers, + SUM(srv.result) AS results +FROM session s + JOIN quiz q ON q.sha1 = s.quiz_sha1 + JOIN user u ON u.id = s.user_id + JOIN quiz_answer_count_view qacv ON s.quiz_sha1 = qacv.quiz_sha1 + JOIN session_response_view srv ON s.uuid = srv.session_uuid; + +CREATE TRIGGER verify_remaining_time_create + BEFORE INSERT + ON session_answer +BEGIN + SELECT CASE + WHEN (SELECT remaining_sec FROM session_view sv WHERE sv.uuid = new.session_uuid) = 0 THEN + RAISE(ABORT, 'session is over') + END; +END; + +CREATE TRIGGER verify_remaining_time_update + BEFORE UPDATE + ON session_answer +BEGIN + SELECT CASE + WHEN (SELECT remaining_sec FROM session_view sv WHERE sv.uuid = new.session_uuid) = 0 THEN + RAISE(ABORT, 'session is over') + END; +END; + +CREATE TABLE quiz_class_visibility +( + class_uuid TEXT NOT NULL, + quiz_sha1 TEXT NOT NULL, + + PRIMARY KEY (class_uuid, quiz_sha1), + FOREIGN KEY (class_uuid) REFERENCES student_class (uuid) ON DELETE CASCADE, + FOREIGN KEY (quiz_sha1) REFERENCES quiz (sha1) ); \ No newline at end of file diff --git a/db/migrations/v2_auth.sql b/db/migrations/v2_auth.sql deleted file mode 100644 index f1563b7..0000000 --- a/db/migrations/v2_auth.sql +++ /dev/null @@ -1,24 +0,0 @@ -CREATE TABLE role -( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL -); - -INSERT INTO role (id, name) -VALUES (1, 'Admin'); -INSERT INTO role (id, name) -VALUES (2, 'Teacher'); -INSERT INTO role (id, name) -VALUES (3, 'Student'); - -CREATE TABLE user -( - id TEXT PRIMARY KEY, - email TEXT NOT NULL, - firstname TEXT NOT NULL, - lastname TEXT NOT NULL, - active INTEGER NOT NULL DEFAULT 1, - role_id INTEGER NOT NULL, - - FOREIGN KEY (role_id) REFERENCES role (id) -); diff --git a/db/migrations/v3_session.sql b/db/migrations/v3_session.sql deleted file mode 100644 index 80d5ddc..0000000 --- a/db/migrations/v3_session.sql +++ /dev/null @@ -1,96 +0,0 @@ -CREATE TABLE session -( - uuid TEXT PRIMARY KEY, - quiz_sha1 TEXT NOT NULL, - user_id TEXT NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - - UNIQUE (quiz_sha1, user_id), - FOREIGN KEY (quiz_sha1) REFERENCES quiz (sha1), - FOREIGN KEY (user_id) REFERENCES user (id) -); - -CREATE TABLE session_answer -( - session_uuid TEXT NOT NULL, - user_id TEXT NOT NULL, - question_sha1 TEXT NOT NULL, - answer_sha1 TEXT NOT NULL, - checked INTEGER NOT NULL, - - PRIMARY KEY (session_uuid, question_sha1, answer_sha1), - FOREIGN KEY (session_uuid) REFERENCES session (uuid), - FOREIGN KEY (user_id) REFERENCES user (id), - FOREIGN KEY (question_sha1) REFERENCES quiz_question (sha1), - FOREIGN KEY (answer_sha1) REFERENCES quiz_answer (sha1) -); - -CREATE VIEW quiz_answer_count_view -AS -SELECT q.sha1 AS quiz_sha1, - COUNT(qa.valid) AS checked_answers -FROM quiz q - JOIN quiz_question_quiz qqq ON q.sha1 = qqq.quiz_sha1 - JOIN quiz_question_answer qqa ON qqq.question_sha1 = qqa.question_sha1 - JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 -GROUP BY q.sha1; - -CREATE VIEW session_response_view -AS -SELECT qqq.quiz_sha1, - qqq.question_sha1, - qqa.answer_sha1, - s.uuid AS session_uuid, - s.user_id, - sa.checked, - CASE - WHEN checked IS NOT NULL - THEN CASE - WHEN qa.valid == sa.checked - THEN 1 - ELSE 0 - END - END AS result -FROM quiz_question_quiz qqq - JOIN quiz_question_answer qqa ON qqq.question_sha1 = qqa.question_sha1 - JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 - LEFT JOIN session s ON qqq.quiz_sha1 = s.quiz_sha1 - LEFT JOIN session_answer sa ON qa.sha1 = sa.answer_sha1 AND sa.question_sha1 = qqq.question_sha1 AND - sa.answer_sha1 = qqa.answer_sha1; - -CREATE VIEW session_view -AS -SELECT s.uuid AS uuid, - q.sha1 AS quiz_sha1, - q.name AS quiz_name, - q.active AS quiz_active, - u.id AS user_id, - CAST(u.firstname || ' ' || u.lastname AS TEXT) AS user_name, - CAST(MAX(q.duration - (STRFTIME('%s', 'now') - STRFTIME('%s', s.created_at)), 0) AS INTEGER) AS remaining_sec, - checked_answers, - SUM(srv.result) AS results -FROM session s - JOIN quiz q ON q.sha1 = s.quiz_sha1 - JOIN user u ON u.id = s.user_id - JOIN quiz_answer_count_view qacv ON s.quiz_sha1 = qacv.quiz_sha1 - JOIN session_response_view srv ON s.uuid = srv.session_uuid; - -CREATE TRIGGER verify_remaining_time_create - BEFORE INSERT - ON session_answer -BEGIN - SELECT CASE - WHEN (SELECT remaining_sec FROM session_view sv WHERE sv.uuid = new.session_uuid) = 0 THEN - RAISE(ABORT, 'session is over') - END; -END; - -CREATE TRIGGER verify_remaining_time_update - BEFORE UPDATE - ON session_answer -BEGIN - SELECT CASE - WHEN (SELECT remaining_sec FROM session_view sv WHERE sv.uuid = new.session_uuid) = 0 THEN - RAISE(ABORT, 'session is over') - END; -END; \ No newline at end of file diff --git a/db/queries/quiz.sql b/db/queries/quiz.sql index 821c058..8e6f572 100644 --- a/db/queries/quiz.sql +++ b/db/queries/quiz.sql @@ -49,6 +49,30 @@ FROM quiz q JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 WHERE q.sha1 = ?; +-- name: FindQuizFullBySha1RestrictedToClass :many +SELECT q.sha1 AS quiz_sha1, + q.filename AS quiz_filename, + q.name AS quiz_name, + q.version AS quiz_version, + q.created_at AS quiz_created_at, + q.duration AS quiz_duration, + q.active AS quiz_active, + qq.sha1 AS question_sha1, + qq.content AS question_content, + qa.sha1 AS answer_sha1, + qa.content AS answer_content, + qa.valid AS answer_valid +FROM quiz q + JOIN quiz_question_quiz qqq ON q.sha1 = qqq.quiz_sha1 + JOIN quiz_question qq ON qq.sha1 = qqq.question_sha1 + JOIN quiz_question_answer qqa ON qq.sha1 = qqa.question_sha1 + JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 + JOIN quiz_class_visibility qcv ON q.sha1 = qcv.quiz_sha1 + JOIN student_class sc ON sc.uuid = qcv.class_uuid + JOIN user u ON sc.uuid = u.class_uuid +WHERE q.sha1 = ? + AND u.id = ?; + -- name: FindQuizByFilenameAndLatestVersion :one SELECT * FROM quiz @@ -62,6 +86,16 @@ FROM quiz WHERE active = 1 LIMIT ? OFFSET ?; +-- name: FindAllActiveQuizRestrictedToClass :many +SELECT * +FROM quiz q + JOIN quiz_class_visibility qcv ON q.sha1 = qcv.quiz_sha1 + JOIN student_class sc ON sc.uuid = qcv.class_uuid + JOIN user u ON sc.uuid = u.class_uuid +WHERE q.active = 1 + AND u.id = ? +LIMIT ? OFFSET ?; + -- name: CountAllActiveQuiz :one SELECT COUNT(1) FROM quiz diff --git a/db/queries/student_class.sql b/db/queries/student_class.sql new file mode 100644 index 0000000..3c58e16 --- /dev/null +++ b/db/queries/student_class.sql @@ -0,0 +1,28 @@ +-- name: CreateOrReplaceClass :exec +REPLACE INTO student_class (uuid, name) +VALUES (?, ?); + +-- name: FindAllClasses :many +SELECT * +FROM student_class +LIMIT ? OFFSET ?; + +-- name: DeleteClassById :exec +DELETE +FROM student_class +WHERE uuid = ?; + +-- name: AssignUserToClass :exec +UPDATE user +SET class_uuid = ? +WHERE id = ?; + +-- name: CreateQuizClassVisibility :exec +REPLACE INTO quiz_class_visibility (class_uuid, quiz_sha1) +VALUES (?, ?); + +-- name: DeleteQuizClassVisibility :exec +DELETE +FROM quiz_class_visibility +WHERE class_uuid = ? + AND quiz_sha1 = ?; diff --git a/internal/back/infrastructure/db/migration.go b/internal/back/infrastructure/db/migration.go index 0849596..d09568b 100644 --- a/internal/back/infrastructure/db/migration.go +++ b/internal/back/infrastructure/db/migration.go @@ -76,9 +76,7 @@ CREATE TABLE quiz_question_answer FOREIGN KEY (question_sha1) REFERENCES quiz_question (sha1), FOREIGN KEY (answer_sha1) REFERENCES quiz_answer (sha1) ); -` -const v2Auth = ` CREATE TABLE role ( id INTEGER PRIMARY KEY, @@ -92,20 +90,26 @@ VALUES (2, 'Teacher'); INSERT INTO role (id, name) VALUES (3, 'Student'); +CREATE TABLE student_class +( + uuid TEXT PRIMARY KEY, + name TEXT NOT NULL +); + CREATE TABLE user ( - id TEXT PRIMARY KEY, - email TEXT NOT NULL, - firstname TEXT NOT NULL, - lastname TEXT NOT NULL, - active INTEGER NOT NULL DEFAULT 1, - role_id INTEGER NOT NULL, - - FOREIGN KEY (role_id) REFERENCES role (id) + id TEXT PRIMARY KEY, + email TEXT NOT NULL, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL, + active INTEGER NOT NULL DEFAULT 1, + role_id INTEGER NOT NULL, + class_uuid TEXT, + + FOREIGN KEY (role_id) REFERENCES role (id), + FOREIGN KEY (class_uuid) REFERENCES student_class (uuid) ON DELETE SET NULL ); -` -const v3Session = ` CREATE TABLE session ( uuid TEXT PRIMARY KEY, @@ -202,12 +206,20 @@ BEGIN RAISE(ABORT, 'session is over') END; END; + +CREATE TABLE quiz_class_visibility +( + class_uuid TEXT NOT NULL, + quiz_sha1 TEXT NOT NULL, + + PRIMARY KEY (class_uuid, quiz_sha1), + FOREIGN KEY (class_uuid) REFERENCES student_class (uuid) ON DELETE CASCADE, + FOREIGN KEY (quiz_sha1) REFERENCES quiz (sha1) +); ` var migrations = map[int]string{ 1: v1Init, - 2: v2Auth, - 3: v3Session, } type DB interface { diff --git a/internal/back/infrastructure/sqlc/auth.sql.go b/internal/back/infrastructure/sqlc/auth.sql.go index f280d07..6f5ac0e 100644 --- a/internal/back/infrastructure/sqlc/auth.sql.go +++ b/internal/back/infrastructure/sqlc/auth.sql.go @@ -34,7 +34,7 @@ func (q *Queries) CreateOrReplaceUser(ctx context.Context, arg CreateOrReplaceUs } const findAllUser = `-- name: FindAllUser :many -SELECT id, email, firstname, lastname, active, role_id +SELECT id, email, firstname, lastname, active, role_id, class_uuid FROM user ` @@ -54,6 +54,7 @@ func (q *Queries) FindAllUser(ctx context.Context) ([]User, error) { &i.Lastname, &i.Active, &i.RoleID, + &i.ClassUuid, ); err != nil { return nil, err } @@ -69,7 +70,7 @@ func (q *Queries) FindAllUser(ctx context.Context) ([]User, error) { } const findUserById = `-- name: FindUserById :one -SELECT id, email, firstname, lastname, active, role_id +SELECT id, email, firstname, lastname, active, role_id, class_uuid FROM user WHERE id = ? ` @@ -84,6 +85,7 @@ func (q *Queries) FindUserById(ctx context.Context, id string) (User, error) { &i.Lastname, &i.Active, &i.RoleID, + &i.ClassUuid, ) return i, err } diff --git a/internal/back/infrastructure/sqlc/models.go b/internal/back/infrastructure/sqlc/models.go index f86c194..ff75868 100644 --- a/internal/back/infrastructure/sqlc/models.go +++ b/internal/back/infrastructure/sqlc/models.go @@ -32,6 +32,11 @@ type QuizAnswerCountView struct { CheckedAnswers int64 `db:"checked_answers"` } +type QuizClassVisibility struct { + ClassUuid uuid.UUID `db:"class_uuid"` + QuizSha1 string `db:"quiz_sha1"` +} + type QuizQuestion struct { Sha1 string `db:"sha1"` Content string `db:"content"` @@ -89,11 +94,17 @@ type SessionView struct { Results sql.NullFloat64 `db:"results"` } +type StudentClass struct { + Uuid uuid.UUID `db:"uuid"` + Name string `db:"name"` +} + type User struct { - ID string `db:"id"` - Email string `db:"email"` - Firstname string `db:"firstname"` - Lastname string `db:"lastname"` - Active bool `db:"active"` - RoleID int64 `db:"role_id"` + ID string `db:"id"` + Email string `db:"email"` + Firstname string `db:"firstname"` + Lastname string `db:"lastname"` + Active bool `db:"active"` + RoleID int64 `db:"role_id"` + ClassUuid uuid.UUID `db:"class_uuid"` } diff --git a/internal/back/infrastructure/sqlc/quiz.sql.go b/internal/back/infrastructure/sqlc/quiz.sql.go index d363c23..009e52d 100644 --- a/internal/back/infrastructure/sqlc/quiz.sql.go +++ b/internal/back/infrastructure/sqlc/quiz.sql.go @@ -7,6 +7,8 @@ package sqlc import ( "context" + + "github.com/google/uuid" ) const activateOnlyVersion = `-- name: ActivateOnlyVersion :exec @@ -139,6 +141,86 @@ func (q *Queries) FindAllActiveQuiz(ctx context.Context, arg FindAllActiveQuizPa return items, nil } +const findAllActiveQuizRestrictedToClass = `-- name: FindAllActiveQuizRestrictedToClass :many +SELECT sha1, q.name, filename, version, q.active, created_at, duration, qcv.class_uuid, quiz_sha1, uuid, sc.name, id, email, firstname, lastname, u.active, role_id, u.class_uuid +FROM quiz q + JOIN quiz_class_visibility qcv ON q.sha1 = qcv.quiz_sha1 + JOIN student_class sc ON sc.uuid = qcv.class_uuid + JOIN user u ON sc.uuid = u.class_uuid +WHERE q.active = 1 + AND u.id = ? +LIMIT ? OFFSET ? +` + +type FindAllActiveQuizRestrictedToClassParams struct { + ID string `db:"id"` + Limit int64 `db:"limit"` + Offset int64 `db:"offset"` +} + +type FindAllActiveQuizRestrictedToClassRow struct { + Sha1 string `db:"sha1"` + Name string `db:"name"` + Filename string `db:"filename"` + Version int64 `db:"version"` + Active bool `db:"active"` + CreatedAt string `db:"created_at"` + Duration int64 `db:"duration"` + ClassUuid uuid.UUID `db:"class_uuid"` + QuizSha1 string `db:"quiz_sha1"` + Uuid uuid.UUID `db:"uuid"` + Name_2 string `db:"name_2"` + ID string `db:"id"` + Email string `db:"email"` + Firstname string `db:"firstname"` + Lastname string `db:"lastname"` + Active_2 bool `db:"active_2"` + RoleID int64 `db:"role_id"` + ClassUuid_2 uuid.UUID `db:"class_uuid_2"` +} + +func (q *Queries) FindAllActiveQuizRestrictedToClass(ctx context.Context, arg FindAllActiveQuizRestrictedToClassParams) ([]FindAllActiveQuizRestrictedToClassRow, error) { + rows, err := q.db.QueryContext(ctx, findAllActiveQuizRestrictedToClass, arg.ID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + items := []FindAllActiveQuizRestrictedToClassRow{} + for rows.Next() { + var i FindAllActiveQuizRestrictedToClassRow + if err := rows.Scan( + &i.Sha1, + &i.Name, + &i.Filename, + &i.Version, + &i.Active, + &i.CreatedAt, + &i.Duration, + &i.ClassUuid, + &i.QuizSha1, + &i.Uuid, + &i.Name_2, + &i.ID, + &i.Email, + &i.Firstname, + &i.Lastname, + &i.Active_2, + &i.RoleID, + &i.ClassUuid_2, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const findQuizByFilenameAndLatestVersion = `-- name: FindQuizByFilenameAndLatestVersion :one SELECT sha1, name, filename, version, active, created_at, duration FROM quiz @@ -255,6 +337,87 @@ func (q *Queries) FindQuizFullBySha1(ctx context.Context, sha1 string) ([]FindQu return items, nil } +const findQuizFullBySha1RestrictedToClass = `-- name: FindQuizFullBySha1RestrictedToClass :many +SELECT q.sha1 AS quiz_sha1, + q.filename AS quiz_filename, + q.name AS quiz_name, + q.version AS quiz_version, + q.created_at AS quiz_created_at, + q.duration AS quiz_duration, + q.active AS quiz_active, + qq.sha1 AS question_sha1, + qq.content AS question_content, + qa.sha1 AS answer_sha1, + qa.content AS answer_content, + qa.valid AS answer_valid +FROM quiz q + JOIN quiz_question_quiz qqq ON q.sha1 = qqq.quiz_sha1 + JOIN quiz_question qq ON qq.sha1 = qqq.question_sha1 + JOIN quiz_question_answer qqa ON qq.sha1 = qqa.question_sha1 + JOIN quiz_answer qa ON qa.sha1 = qqa.answer_sha1 + JOIN quiz_class_visibility qcv ON q.sha1 = qcv.quiz_sha1 + JOIN student_class sc ON sc.uuid = qcv.class_uuid + JOIN user u ON sc.uuid = u.class_uuid +WHERE q.sha1 = ? + AND u.id = ? +` + +type FindQuizFullBySha1RestrictedToClassParams struct { + Sha1 string `db:"sha1"` + ID string `db:"id"` +} + +type FindQuizFullBySha1RestrictedToClassRow struct { + QuizSha1 string `db:"quiz_sha1"` + QuizFilename string `db:"quiz_filename"` + QuizName string `db:"quiz_name"` + QuizVersion int64 `db:"quiz_version"` + QuizCreatedAt string `db:"quiz_created_at"` + QuizDuration int64 `db:"quiz_duration"` + QuizActive bool `db:"quiz_active"` + QuestionSha1 string `db:"question_sha1"` + QuestionContent string `db:"question_content"` + AnswerSha1 string `db:"answer_sha1"` + AnswerContent string `db:"answer_content"` + AnswerValid bool `db:"answer_valid"` +} + +func (q *Queries) FindQuizFullBySha1RestrictedToClass(ctx context.Context, arg FindQuizFullBySha1RestrictedToClassParams) ([]FindQuizFullBySha1RestrictedToClassRow, error) { + rows, err := q.db.QueryContext(ctx, findQuizFullBySha1RestrictedToClass, arg.Sha1, arg.ID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []FindQuizFullBySha1RestrictedToClassRow{} + for rows.Next() { + var i FindQuizFullBySha1RestrictedToClassRow + if err := rows.Scan( + &i.QuizSha1, + &i.QuizFilename, + &i.QuizName, + &i.QuizVersion, + &i.QuizCreatedAt, + &i.QuizDuration, + &i.QuizActive, + &i.QuestionSha1, + &i.QuestionContent, + &i.AnswerSha1, + &i.AnswerContent, + &i.AnswerValid, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const linkAnswer = `-- name: LinkAnswer :exec REPLACE INTO quiz_question_answer (question_sha1, answer_sha1) VALUES (?, ?) diff --git a/internal/back/infrastructure/sqlc/student_class.sql.go b/internal/back/infrastructure/sqlc/student_class.sql.go new file mode 100644 index 0000000..f21c162 --- /dev/null +++ b/internal/back/infrastructure/sqlc/student_class.sql.go @@ -0,0 +1,120 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: student_class.sql + +package sqlc + +import ( + "context" + + "github.com/google/uuid" +) + +const assignUserToClass = `-- name: AssignUserToClass :exec +UPDATE user +SET class_uuid = ? +WHERE id = ? +` + +type AssignUserToClassParams struct { + ClassUuid uuid.UUID `db:"class_uuid"` + ID string `db:"id"` +} + +func (q *Queries) AssignUserToClass(ctx context.Context, arg AssignUserToClassParams) error { + _, err := q.db.ExecContext(ctx, assignUserToClass, arg.ClassUuid, arg.ID) + return err +} + +const createOrReplaceClass = `-- name: CreateOrReplaceClass :exec +REPLACE INTO student_class (uuid, name) +VALUES (?, ?) +` + +type CreateOrReplaceClassParams struct { + Uuid uuid.UUID `db:"uuid"` + Name string `db:"name"` +} + +func (q *Queries) CreateOrReplaceClass(ctx context.Context, arg CreateOrReplaceClassParams) error { + _, err := q.db.ExecContext(ctx, createOrReplaceClass, arg.Uuid, arg.Name) + return err +} + +const createQuizClassVisibility = `-- name: CreateQuizClassVisibility :exec +REPLACE INTO quiz_class_visibility (class_uuid, quiz_sha1) +VALUES (?, ?) +` + +type CreateQuizClassVisibilityParams struct { + ClassUuid uuid.UUID `db:"class_uuid"` + QuizSha1 string `db:"quiz_sha1"` +} + +func (q *Queries) CreateQuizClassVisibility(ctx context.Context, arg CreateQuizClassVisibilityParams) error { + _, err := q.db.ExecContext(ctx, createQuizClassVisibility, arg.ClassUuid, arg.QuizSha1) + return err +} + +const deleteClassById = `-- name: DeleteClassById :exec +DELETE +FROM student_class +WHERE uuid = ? +` + +func (q *Queries) DeleteClassById(ctx context.Context, argUuid uuid.UUID) error { + _, err := q.db.ExecContext(ctx, deleteClassById, argUuid) + return err +} + +const deleteQuizClassVisibility = `-- name: DeleteQuizClassVisibility :exec +DELETE +FROM quiz_class_visibility +WHERE class_uuid = ? + AND quiz_sha1 = ? +` + +type DeleteQuizClassVisibilityParams struct { + ClassUuid uuid.UUID `db:"class_uuid"` + QuizSha1 string `db:"quiz_sha1"` +} + +func (q *Queries) DeleteQuizClassVisibility(ctx context.Context, arg DeleteQuizClassVisibilityParams) error { + _, err := q.db.ExecContext(ctx, deleteQuizClassVisibility, arg.ClassUuid, arg.QuizSha1) + return err +} + +const findAllClasses = `-- name: FindAllClasses :many +SELECT uuid, name +FROM student_class +LIMIT ? OFFSET ? +` + +type FindAllClassesParams struct { + Limit int64 `db:"limit"` + Offset int64 `db:"offset"` +} + +func (q *Queries) FindAllClasses(ctx context.Context, arg FindAllClassesParams) ([]StudentClass, error) { + rows, err := q.db.QueryContext(ctx, findAllClasses, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + items := []StudentClass{} + for rows.Next() { + var i StudentClass + if err := rows.Scan(&i.Uuid, &i.Name); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/sqlc.yaml b/sqlc.yaml index 3607698..9dd17b5 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -15,6 +15,8 @@ sql: go_type: "github.com/google/uuid.UUID" - column: "main.*.session_uuid" go_type: "github.com/google/uuid.UUID" + - column: "main.*.class_uuid" + go_type: "github.com/google/uuid.UUID" - column: "main.session_view.user_name" go_type: "string" - column: "main.session_view.remaining_sec"