2024-02-19 16:33:15 +00:00
|
|
|
package quiz
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2025-02-21 13:40:10 +00:00
|
|
|
"gitea.pena/SQuiz/common/dal/sqlcgen"
|
|
|
|
"gitea.pena/SQuiz/common/model"
|
2025-04-23 11:07:55 +00:00
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/lib/pq"
|
2024-03-13 16:21:37 +00:00
|
|
|
|
2024-02-19 16:33:15 +00:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Deps struct {
|
|
|
|
Queries *sqlcgen.Queries
|
|
|
|
Pool *sql.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
type QuizRepository struct {
|
|
|
|
queries *sqlcgen.Queries
|
|
|
|
pool *sql.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewQuizRepository(deps Deps) *QuizRepository {
|
|
|
|
return &QuizRepository{
|
|
|
|
queries: deps.Queries,
|
|
|
|
pool: deps.Pool,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
2024-06-02 08:57:25 +00:00
|
|
|
func (r *QuizRepository) CreateQuiz(ctx context.Context, record *model.Quiz) (uint64, error) {
|
2024-02-19 16:33:15 +00:00
|
|
|
if record.Qid == "" {
|
|
|
|
record.Qid = uuid.NewString()
|
|
|
|
}
|
|
|
|
|
2025-02-26 14:42:15 +00:00
|
|
|
uuidQid, err := uuid.Parse(record.Qid)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
2024-02-19 16:33:15 +00:00
|
|
|
params := sqlcgen.InsertQuizParams{
|
|
|
|
Accountid: record.AccountId,
|
|
|
|
Fingerprinting: sql.NullBool{Bool: record.Fingerprinting, Valid: true},
|
|
|
|
Repeatable: sql.NullBool{Bool: record.Repeatable, Valid: true},
|
|
|
|
NotePrevented: sql.NullBool{Bool: record.NotePrevented, Valid: true},
|
|
|
|
MailNotifications: sql.NullBool{Bool: record.MailNotifications, Valid: true},
|
|
|
|
UniqueAnswers: sql.NullBool{Bool: record.UniqueAnswers, Valid: true},
|
|
|
|
Super: sql.NullBool{Bool: record.Super, Valid: true},
|
|
|
|
GroupID: sql.NullInt64{Int64: int64(record.GroupId), Valid: true},
|
|
|
|
Name: sql.NullString{String: record.Name, Valid: true},
|
|
|
|
Description: sql.NullString{String: record.Description, Valid: true},
|
|
|
|
Config: sql.NullString{String: record.Config, Valid: true},
|
|
|
|
Status: record.Status,
|
|
|
|
LimitAnswers: sql.NullInt32{Int32: int32(record.Limit), Valid: true},
|
|
|
|
DueTo: sql.NullInt32{Int32: int32(record.DueTo), Valid: true},
|
|
|
|
TimeOfPassing: sql.NullInt32{Int32: int32(record.TimeOfPassing), Valid: true},
|
|
|
|
Pausable: sql.NullBool{Bool: record.Pausable, Valid: true},
|
|
|
|
ParentIds: record.ParentIds,
|
|
|
|
QuestionsCount: sql.NullInt32{Int32: int32(record.QuestionsCount), Valid: true},
|
2025-02-26 14:42:15 +00:00
|
|
|
Qid: uuid.NullUUID{UUID: uuidQid, Valid: true},
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data, err := r.queries.InsertQuiz(ctx, params)
|
|
|
|
if err != nil {
|
2024-06-02 08:57:25 +00:00
|
|
|
return 0, err
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
record.Id = uint64(data.ID)
|
|
|
|
record.CreatedAt = data.CreatedAt.Time
|
|
|
|
record.UpdatedAt = data.UpdatedAt.Time
|
|
|
|
record.Qid = data.Qid.UUID.String()
|
|
|
|
|
2024-06-02 08:57:25 +00:00
|
|
|
return record.Id, nil
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type GetQuizListDeps struct {
|
|
|
|
Limit, Offset, From, To, Group uint64
|
|
|
|
Deleted, Archived, Super bool
|
|
|
|
Search, Status, AccountId string
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// GetQuizList function for get data page from db
|
|
|
|
func (r *QuizRepository) GetQuizList(
|
|
|
|
ctx context.Context,
|
|
|
|
deps GetQuizListDeps) ([]model.Quiz, uint64, error) {
|
|
|
|
query := `
|
2025-06-11 14:09:37 +00:00
|
|
|
SELECT id, qid, accountid, deleted, archived, fingerprinting, repeatable, note_prevented,
|
|
|
|
mail_notifications, unique_answers, super, group_id, name, description, config, status,
|
|
|
|
limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids,
|
|
|
|
created_at, updated_at, questions_count, answers_count, average_time_passing, sessions_count,
|
|
|
|
gigachat
|
|
|
|
FROM quiz
|
2024-02-19 16:33:15 +00:00
|
|
|
%s
|
|
|
|
ORDER BY created_at DESC
|
|
|
|
LIMIT $1 OFFSET $2;
|
|
|
|
`
|
|
|
|
|
|
|
|
queryCnt := `SELECT count(1) FROM quiz %s;`
|
|
|
|
|
|
|
|
var (
|
|
|
|
whereClause []string
|
|
|
|
data []interface{}
|
|
|
|
)
|
|
|
|
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf(`accountid = '%s'`, deps.AccountId))
|
|
|
|
if deps.From != 0 {
|
|
|
|
data = append(data, deps.From)
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("created_at >= to_timestamp($%d)", len(data)))
|
|
|
|
}
|
|
|
|
if deps.To != 0 {
|
|
|
|
data = append(data, deps.To)
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("created_at <= to_timestamp($%d)", len(data)))
|
|
|
|
}
|
|
|
|
if deps.Deleted {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("deleted = true"))
|
|
|
|
} else {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("deleted = false"))
|
|
|
|
}
|
|
|
|
if deps.Archived {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("archived = true"))
|
|
|
|
} else {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("archived = false"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if deps.Super {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("super = true"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if deps.Group > 0 {
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("group_id = %d", deps.Group))
|
|
|
|
}
|
|
|
|
|
|
|
|
if deps.Status != "" {
|
|
|
|
data = append(data, deps.Status)
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("status = $%d", len(data)))
|
|
|
|
}
|
|
|
|
if deps.Search != "" {
|
|
|
|
data = append(data, deps.Search)
|
|
|
|
whereClause = append(whereClause, fmt.Sprintf("to_tsvector('russian', name) @@ to_tsquery('russian', $%d)", len(data)))
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(whereClause) != 0 {
|
|
|
|
query = fmt.Sprintf(query, fmt.Sprintf(" WHERE %s ", strings.Join(whereClause, " AND ")))
|
|
|
|
queryCnt = fmt.Sprintf(queryCnt, fmt.Sprintf(" WHERE %s ", strings.Join(whereClause, " AND ")))
|
|
|
|
} else {
|
|
|
|
query = fmt.Sprintf(query, "")
|
|
|
|
queryCnt = fmt.Sprintf(queryCnt, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
qerr, cerr error
|
|
|
|
count uint64
|
|
|
|
result []model.Quiz
|
|
|
|
)
|
|
|
|
|
|
|
|
data = append(data, deps.Limit, deps.Offset)
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
wg.Add(2)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
fmt.Println("Q1", query, deps.Limit, deps.Offset)
|
|
|
|
rows, err := r.pool.QueryContext(ctx, query, deps.Limit, deps.Offset)
|
|
|
|
if err != nil {
|
|
|
|
qerr = err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
var piece model.Quiz
|
|
|
|
pIds := pq.Int32Array{}
|
|
|
|
for rows.Next() {
|
|
|
|
if err := rows.Scan(
|
|
|
|
&piece.Id,
|
|
|
|
&piece.Qid,
|
|
|
|
&piece.AccountId,
|
|
|
|
&piece.Deleted,
|
|
|
|
&piece.Archived,
|
|
|
|
&piece.Fingerprinting,
|
|
|
|
&piece.Repeatable,
|
|
|
|
&piece.NotePrevented,
|
|
|
|
&piece.MailNotifications,
|
|
|
|
&piece.UniqueAnswers,
|
|
|
|
&piece.Super,
|
|
|
|
&piece.GroupId,
|
|
|
|
&piece.Name,
|
|
|
|
&piece.Description,
|
|
|
|
&piece.Config,
|
|
|
|
&piece.Status,
|
|
|
|
&piece.Limit,
|
|
|
|
&piece.DueTo,
|
|
|
|
&piece.TimeOfPassing,
|
|
|
|
&piece.Pausable,
|
|
|
|
&piece.Version,
|
|
|
|
&piece.VersionComment,
|
|
|
|
&pIds,
|
|
|
|
&piece.CreatedAt,
|
|
|
|
&piece.UpdatedAt,
|
|
|
|
&piece.QuestionsCount,
|
|
|
|
&piece.PassedCount,
|
|
|
|
&piece.AverageTime,
|
|
|
|
&piece.SessionCount,
|
2025-06-11 14:09:37 +00:00
|
|
|
&piece.GigaChat,
|
2024-02-19 16:33:15 +00:00
|
|
|
); err != nil {
|
|
|
|
qerr = err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
piece.ParentIds = pIds
|
|
|
|
result = append(result, piece)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
fmt.Println("Q2", queryCnt)
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
rows *sql.Rows
|
|
|
|
)
|
|
|
|
if len(data) == 2 {
|
|
|
|
rows, err = r.pool.QueryContext(ctx, queryCnt)
|
|
|
|
} else {
|
|
|
|
rows, err = r.pool.QueryContext(ctx, queryCnt, data[:len(data)-2]...)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
cerr = err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
if !rows.Next() {
|
|
|
|
cerr = errors.New("can not next count")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := rows.Scan(&count); err != nil {
|
|
|
|
cerr = err
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
fmt.Println("res", result, count, "!", cerr, "?", qerr)
|
|
|
|
if cerr != nil {
|
|
|
|
return nil, 0, cerr
|
|
|
|
}
|
|
|
|
if qerr != nil {
|
|
|
|
return nil, 0, qerr
|
|
|
|
}
|
|
|
|
return result, count, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// GetQuizByQid method for obtain quiz model by secured id
|
|
|
|
func (r *QuizRepository) GetQuizByQid(ctx context.Context, qid string) (model.Quiz, error) {
|
2025-02-26 14:42:15 +00:00
|
|
|
_, err := uuid.Parse(qid)
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
2024-02-19 16:33:15 +00:00
|
|
|
fmt.Println("QUID", `
|
2025-06-11 14:09:37 +00:00
|
|
|
SELECT id, qid, accountid, deleted, archived, fingerprinting, repeatable, note_prevented,
|
|
|
|
mail_notifications, unique_answers, super, group_id, name, description, config, status,
|
|
|
|
limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids,
|
|
|
|
created_at, updated_at, questions_count, answers_count, average_time_passing, sessions_count,
|
|
|
|
gigachat FROM quiz
|
2024-02-19 16:33:15 +00:00
|
|
|
WHERE
|
|
|
|
deleted = false AND
|
|
|
|
archived = false AND
|
|
|
|
status = 'start' AND
|
|
|
|
qid = $1;
|
|
|
|
`)
|
|
|
|
rows, err := r.pool.QueryContext(ctx, `
|
2025-06-11 14:09:37 +00:00
|
|
|
SELECT id, qid, accountid, deleted, archived, fingerprinting, repeatable, note_prevented,
|
|
|
|
mail_notifications, unique_answers, super, group_id, name, description, config, status,
|
|
|
|
limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids,
|
|
|
|
created_at, updated_at, questions_count, answers_count, average_time_passing, sessions_count,
|
|
|
|
gigachat FROM quiz
|
2024-02-19 16:33:15 +00:00
|
|
|
WHERE
|
|
|
|
deleted = false AND
|
|
|
|
archived = false AND
|
2025-04-16 22:32:44 +00:00
|
|
|
(status = 'start' OR status = 'ai') AND
|
2024-02-19 16:33:15 +00:00
|
|
|
qid = $1;
|
|
|
|
`, qid)
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
if !rows.Next() {
|
|
|
|
return model.Quiz{}, rows.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
var piece model.Quiz
|
|
|
|
pIds := pq.Int32Array{}
|
|
|
|
if err := rows.Scan(
|
|
|
|
&piece.Id,
|
|
|
|
&piece.Qid,
|
|
|
|
&piece.AccountId,
|
|
|
|
&piece.Deleted,
|
|
|
|
&piece.Archived,
|
|
|
|
&piece.Fingerprinting,
|
|
|
|
&piece.Repeatable,
|
|
|
|
&piece.NotePrevented,
|
|
|
|
&piece.MailNotifications,
|
|
|
|
&piece.UniqueAnswers,
|
|
|
|
&piece.Super,
|
|
|
|
&piece.GroupId,
|
|
|
|
&piece.Name,
|
|
|
|
&piece.Description,
|
|
|
|
&piece.Config,
|
|
|
|
&piece.Status,
|
|
|
|
&piece.Limit,
|
|
|
|
&piece.DueTo,
|
|
|
|
&piece.TimeOfPassing,
|
|
|
|
&piece.Pausable,
|
|
|
|
&piece.Version,
|
|
|
|
&piece.VersionComment,
|
|
|
|
&pIds,
|
|
|
|
&piece.CreatedAt,
|
|
|
|
&piece.UpdatedAt,
|
|
|
|
&piece.QuestionsCount,
|
|
|
|
&piece.PassedCount,
|
|
|
|
&piece.AverageTime,
|
|
|
|
&piece.SessionCount,
|
2025-06-11 14:09:37 +00:00
|
|
|
&piece.GigaChat,
|
2024-02-19 16:33:15 +00:00
|
|
|
); err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
piece.ParentIds = pIds
|
|
|
|
|
|
|
|
return piece, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
func (r *QuizRepository) DeleteQuiz(ctx context.Context, accountId string, id uint64) (model.Quiz, error) {
|
|
|
|
row, err := r.queries.DeleteQuizByID(ctx, sqlcgen.DeleteQuizByIDParams{
|
|
|
|
ID: int64(id),
|
|
|
|
Accountid: accountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
piece := model.Quiz{
|
|
|
|
Id: uint64(row.ID),
|
|
|
|
Qid: row.Qid.UUID.String(),
|
|
|
|
AccountId: row.Accountid,
|
|
|
|
Deleted: row.Deleted.Bool,
|
|
|
|
Archived: row.Archived.Bool,
|
|
|
|
Fingerprinting: row.Fingerprinting.Bool,
|
|
|
|
Repeatable: row.Repeatable.Bool,
|
|
|
|
NotePrevented: row.NotePrevented.Bool,
|
|
|
|
MailNotifications: row.MailNotifications.Bool,
|
|
|
|
UniqueAnswers: row.UniqueAnswers.Bool,
|
|
|
|
Super: row.Super.Bool,
|
|
|
|
GroupId: uint64(row.GroupID.Int64),
|
|
|
|
Name: row.Name.String,
|
|
|
|
Description: row.Description.String,
|
|
|
|
Config: row.Config.String,
|
|
|
|
Status: string(row.Status.([]byte)),
|
|
|
|
Limit: uint64(row.LimitAnswers.Int32),
|
|
|
|
DueTo: uint64(row.DueTo.Int32),
|
|
|
|
TimeOfPassing: uint64(row.TimeOfPassing.Int32),
|
|
|
|
Pausable: row.Pausable.Bool,
|
|
|
|
Version: int(row.Version.Int16),
|
|
|
|
VersionComment: row.VersionComment.String,
|
|
|
|
ParentIds: row.ParentIds,
|
|
|
|
CreatedAt: row.CreatedAt.Time,
|
|
|
|
UpdatedAt: row.UpdatedAt.Time,
|
|
|
|
QuestionsCount: uint64(row.QuestionsCount.Int32),
|
|
|
|
PassedCount: uint64(row.AnswersCount.Int32),
|
|
|
|
AverageTime: uint64(row.AverageTimePassing.Int32),
|
|
|
|
SessionCount: uint64(row.SessionsCount.Int32),
|
|
|
|
}
|
|
|
|
|
|
|
|
return piece, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// MoveToHistoryQuiz insert deleted duplicate of quiz
|
|
|
|
func (r *QuizRepository) MoveToHistoryQuiz(ctx context.Context, id uint64, accountId string) (model.Quiz, error) {
|
|
|
|
row, err := r.queries.MoveToHistoryQuiz(ctx, sqlcgen.MoveToHistoryQuizParams{
|
|
|
|
ID: int64(id),
|
|
|
|
Accountid: accountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
result := model.Quiz{
|
|
|
|
Id: uint64(row.ID),
|
|
|
|
Qid: row.Qid.UUID.String(),
|
|
|
|
ParentIds: row.ParentIds,
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// UpdateQuiz set new data for quiz
|
|
|
|
func (r *QuizRepository) UpdateQuiz(ctx context.Context, accountId string, record model.Quiz) error {
|
2024-04-16 19:53:12 +00:00
|
|
|
query := `UPDATE quiz SET`
|
|
|
|
var params []interface{}
|
2024-02-19 16:33:15 +00:00
|
|
|
|
|
|
|
if record.Name != "" {
|
2024-04-16 22:16:15 +00:00
|
|
|
query += ` name = $%d,`
|
2024-04-16 19:53:12 +00:00
|
|
|
params = append(params, record.Name)
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if record.Description != "" {
|
2024-04-16 22:16:15 +00:00
|
|
|
query += ` description = $%d::text,`
|
2024-04-16 19:53:12 +00:00
|
|
|
params = append(params, record.Description)
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if record.Status != "" {
|
2024-04-16 22:16:15 +00:00
|
|
|
query += ` status = $%d,`
|
2024-04-16 19:53:12 +00:00
|
|
|
params = append(params, record.Status)
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if record.Config != "" {
|
2024-04-16 22:16:15 +00:00
|
|
|
query += ` config = $%d::text,`
|
2024-04-16 19:53:12 +00:00
|
|
|
params = append(params, record.Config)
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
2024-04-16 22:16:15 +00:00
|
|
|
query += ` group_id = $%d, version = $%d WHERE id = $%d AND accountid = $%d`
|
2024-04-16 19:53:12 +00:00
|
|
|
|
|
|
|
params = append(params, record.GroupId, record.Version, record.Id, accountId)
|
2024-04-16 22:16:15 +00:00
|
|
|
var placeholders []any
|
2024-05-13 11:10:30 +00:00
|
|
|
for i := 1; i <= len(params); i++ {
|
2024-04-16 22:16:15 +00:00
|
|
|
placeholders = append(placeholders, i)
|
|
|
|
}
|
2024-02-19 16:33:15 +00:00
|
|
|
|
2024-04-16 22:16:15 +00:00
|
|
|
query = fmt.Sprintf(query, placeholders...)
|
2024-05-13 11:10:30 +00:00
|
|
|
|
2024-04-16 19:53:12 +00:00
|
|
|
_, err := r.pool.ExecContext(ctx, query, params...)
|
2024-02-19 16:33:15 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// CopyQuiz method for copy quiz with all of his questions
|
|
|
|
func (r *QuizRepository) CopyQuiz(ctx context.Context, accountId string, id uint64) (model.Quiz, error) {
|
|
|
|
row, err := r.queries.CopyQuiz(ctx, sqlcgen.CopyQuizParams{
|
|
|
|
ID: int64(id),
|
|
|
|
Accountid: accountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
result := model.Quiz{
|
|
|
|
Id: uint64(row.ID),
|
|
|
|
Qid: row.Qid.UUID.String(),
|
|
|
|
CreatedAt: row.CreatedAt.Time,
|
|
|
|
UpdatedAt: row.UpdatedAt.Time,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.queries.CopyQuizQuestions(ctx, sqlcgen.CopyQuizQuestionsParams{
|
|
|
|
QuizID: int64(id),
|
|
|
|
QuizID_2: row.ID,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return model.Quiz{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type QuizHistoryDeps struct {
|
|
|
|
Id, Limit, Offset uint64
|
|
|
|
AccountId string
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
// QuizHistory method for obtain quiz history from db
|
|
|
|
func (r *QuizRepository) QuizHistory(ctx context.Context, deps QuizHistoryDeps) ([]model.Quiz, error) {
|
|
|
|
rows, err := r.queries.GetQuizHistory(ctx, sqlcgen.GetQuizHistoryParams{
|
|
|
|
ID: int64(deps.Id),
|
|
|
|
Limit: int32(deps.Limit),
|
|
|
|
Offset: int32(deps.Offset),
|
|
|
|
Accountid: deps.AccountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var result []model.Quiz
|
|
|
|
for _, row := range rows {
|
|
|
|
piece := model.Quiz{
|
|
|
|
Id: uint64(row.ID),
|
|
|
|
Qid: row.Qid.UUID.String(),
|
|
|
|
AccountId: row.Accountid,
|
|
|
|
Deleted: row.Deleted.Bool,
|
|
|
|
Archived: row.Archived.Bool,
|
|
|
|
Fingerprinting: row.Fingerprinting.Bool,
|
|
|
|
Repeatable: row.Repeatable.Bool,
|
|
|
|
NotePrevented: row.NotePrevented.Bool,
|
|
|
|
MailNotifications: row.MailNotifications.Bool,
|
|
|
|
UniqueAnswers: row.UniqueAnswers.Bool,
|
|
|
|
Super: row.Super.Bool,
|
|
|
|
GroupId: uint64(row.GroupID.Int64),
|
|
|
|
Name: row.Name.String,
|
|
|
|
Description: row.Description.String,
|
|
|
|
Config: row.Config.String,
|
|
|
|
Status: string(row.Status.([]byte)),
|
|
|
|
Limit: uint64(row.LimitAnswers.Int32),
|
|
|
|
DueTo: uint64(row.DueTo.Int32),
|
|
|
|
TimeOfPassing: uint64(row.TimeOfPassing.Int32),
|
|
|
|
Pausable: row.Pausable.Bool,
|
|
|
|
Version: int(row.Version.Int16),
|
|
|
|
VersionComment: row.VersionComment.String,
|
|
|
|
ParentIds: row.ParentIds,
|
|
|
|
CreatedAt: row.CreatedAt.Time,
|
|
|
|
UpdatedAt: row.UpdatedAt.Time,
|
|
|
|
QuestionsCount: uint64(row.QuestionsCount.Int32),
|
|
|
|
PassedCount: uint64(row.AnswersCount.Int32),
|
|
|
|
AverageTime: uint64(row.AverageTimePassing.Int32),
|
|
|
|
SessionCount: uint64(row.SessionsCount.Int32),
|
|
|
|
}
|
|
|
|
|
|
|
|
result = append(result, piece)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *QuizRepository) ArchiveQuiz(ctx context.Context, accountId string, id uint64) error {
|
|
|
|
err := r.queries.ArchiveQuiz(ctx, sqlcgen.ArchiveQuizParams{
|
|
|
|
ID: int64(id),
|
|
|
|
Accountid: accountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
func (r *QuizRepository) GetQuizById(ctx context.Context, accountId string, id uint64) (*model.Quiz, error) {
|
|
|
|
row, err := r.queries.GetQuizById(ctx, sqlcgen.GetQuizByIdParams{
|
|
|
|
ID: int64(id),
|
|
|
|
Accountid: accountId,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
piece := model.Quiz{
|
|
|
|
Id: uint64(row.ID),
|
|
|
|
Qid: row.Qid.UUID.String(),
|
|
|
|
AccountId: row.Accountid,
|
|
|
|
Deleted: row.Deleted.Bool,
|
|
|
|
Archived: row.Archived.Bool,
|
|
|
|
Fingerprinting: row.Fingerprinting.Bool,
|
|
|
|
Repeatable: row.Repeatable.Bool,
|
|
|
|
NotePrevented: row.NotePrevented.Bool,
|
|
|
|
MailNotifications: row.MailNotifications.Bool,
|
|
|
|
UniqueAnswers: row.UniqueAnswers.Bool,
|
|
|
|
Super: row.Super.Bool,
|
|
|
|
GroupId: uint64(row.GroupID.Int64),
|
|
|
|
Name: row.Name.String,
|
|
|
|
Description: row.Description.String,
|
|
|
|
Config: row.Config.String,
|
|
|
|
Status: string(row.Status.([]byte)),
|
|
|
|
Limit: uint64(row.LimitAnswers.Int32),
|
|
|
|
DueTo: uint64(row.DueTo.Int32),
|
|
|
|
TimeOfPassing: uint64(row.TimeOfPassing.Int32),
|
|
|
|
Pausable: row.Pausable.Bool,
|
|
|
|
Version: int(row.Version.Int16),
|
|
|
|
VersionComment: row.VersionComment.String,
|
|
|
|
ParentIds: row.ParentIds,
|
|
|
|
CreatedAt: row.CreatedAt.Time,
|
|
|
|
UpdatedAt: row.UpdatedAt.Time,
|
|
|
|
QuestionsCount: uint64(row.QuestionsCount.Int32),
|
|
|
|
PassedCount: uint64(row.AnswersCount.Int32),
|
|
|
|
AverageTime: uint64(row.AverageTimePassing.Int32),
|
|
|
|
SessionCount: uint64(row.SessionsCount.Int32),
|
2025-06-10 10:09:37 +00:00
|
|
|
GigaChat: row.Gigachat,
|
2024-02-19 16:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &piece, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// test +
|
|
|
|
func (r *QuizRepository) GetQuizConfig(ctx context.Context, quizID uint64) (model.QuizConfig, string, error) {
|
|
|
|
row, err := r.queries.GetQuizConfig(ctx, int64(quizID))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return model.QuizConfig{}, "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
var config model.QuizConfig
|
|
|
|
if err := json.Unmarshal([]byte(row.Config.String), &config); err != nil {
|
|
|
|
return model.QuizConfig{}, "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return config, row.Accountid, nil
|
|
|
|
}
|
2024-03-19 14:18:05 +00:00
|
|
|
|
2024-03-19 16:49:20 +00:00
|
|
|
func (r *QuizRepository) QuizMove(ctx context.Context, qID, accountID string) (string, error) {
|
|
|
|
qUUID, err := uuid.Parse(qID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
qNullUUID := uuid.NullUUID{UUID: qUUID, Valid: true}
|
|
|
|
|
|
|
|
data, err := r.queries.QuizCopyQid(ctx, sqlcgen.QuizCopyQidParams{
|
|
|
|
Qid: qNullUUID,
|
|
|
|
Accountid: accountID,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.queries.CopyQuestionQuizID(ctx, sqlcgen.CopyQuestionQuizIDParams{
|
2024-03-28 23:51:52 +00:00
|
|
|
QuizID: data.ID,
|
|
|
|
QuizID_2: data.ID_2,
|
2024-03-19 16:49:20 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2024-03-19 14:18:05 +00:00
|
|
|
|
2024-03-28 23:51:52 +00:00
|
|
|
return data.Qid.UUID.String(), err
|
2024-03-19 14:18:05 +00:00
|
|
|
}
|
2024-04-03 16:14:53 +00:00
|
|
|
|
|
|
|
func (r *QuizRepository) GetAllQuizzesID(ctx context.Context, accountID string) ([]int64, error) {
|
|
|
|
ids, err := r.queries.GetListCreatedQuizzes(ctx, accountID)
|
|
|
|
if err != nil {
|
|
|
|
return []int64{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ids, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *QuizRepository) GetStartedQuizzesID(ctx context.Context, accountID string) ([]int64, error) {
|
|
|
|
ids, err := r.queries.GetListStartQuiz(ctx, accountID)
|
|
|
|
if err != nil {
|
|
|
|
return []int64{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ids, nil
|
|
|
|
}
|
2024-05-13 11:10:30 +00:00
|
|
|
|
2024-05-17 14:11:41 +00:00
|
|
|
func (r *QuizRepository) TemplateCopy(ctx context.Context, accountID, qID string) (int64, error) {
|
2024-05-13 11:10:30 +00:00
|
|
|
qUUID, err := uuid.Parse(qID)
|
|
|
|
if err != nil {
|
2024-05-17 14:11:41 +00:00
|
|
|
return 0, err
|
2024-05-13 11:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
qNullUUID := uuid.NullUUID{UUID: qUUID, Valid: true}
|
|
|
|
|
2024-05-17 14:11:41 +00:00
|
|
|
quizID, err := r.queries.TemplateCopy(ctx, sqlcgen.TemplateCopyParams{
|
2024-05-13 11:10:30 +00:00
|
|
|
Accountid: accountID,
|
|
|
|
Qid: qNullUUID,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
2024-05-17 14:11:41 +00:00
|
|
|
return 0, err
|
2024-05-13 11:10:30 +00:00
|
|
|
}
|
|
|
|
|
2024-05-17 14:11:41 +00:00
|
|
|
return quizID, nil
|
2024-05-13 11:10:30 +00:00
|
|
|
}
|
2025-04-23 11:07:55 +00:00
|
|
|
|
2025-05-10 09:18:27 +00:00
|
|
|
type DepsCreateQuizAudience struct {
|
|
|
|
QuizID int64 `json:"quiz_id"`
|
2025-06-06 14:05:34 +00:00
|
|
|
Sex int32 `json:"sex"` // 0 - female, 1 - male, 2 - not sex
|
2025-05-10 09:18:27 +00:00
|
|
|
Age string `json:"age"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *QuizRepository) CreateQuizAudience(ctx context.Context, audience DepsCreateQuizAudience) (int64, error) {
|
|
|
|
result, err := r.queries.CreateQuizAudience(ctx, sqlcgen.CreateQuizAudienceParams{
|
|
|
|
Quizid: audience.QuizID,
|
|
|
|
Sex: audience.Sex,
|
|
|
|
Age: audience.Age,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *QuizRepository) GetQuizAudience(ctx context.Context, quizID int64) ([]model.GigaChatAudience, error) {
|
|
|
|
rows, err := r.queries.GetQuizAudience(ctx, quizID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var audiences []model.GigaChatAudience
|
|
|
|
for _, row := range rows {
|
|
|
|
audiences = append(audiences, model.GigaChatAudience{
|
|
|
|
ID: row.ID,
|
|
|
|
QuizID: row.ID,
|
|
|
|
Sex: row.Sex,
|
|
|
|
Age: row.Age,
|
|
|
|
Deleted: row.Deleted,
|
|
|
|
CreatedAt: row.Createdat.Time.Unix(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return audiences, nil
|
|
|
|
}
|
|
|
|
|
2025-05-31 07:05:17 +00:00
|
|
|
func (r *QuizRepository) DeleteQuizAudience(ctx context.Context, quizID int64, audienceID int64) error {
|
2025-05-31 07:24:20 +00:00
|
|
|
err := r.queries.DeleteQuizAudience(ctx, sqlcgen.DeleteQuizAudienceParams{
|
|
|
|
Quizid: quizID,
|
|
|
|
ID: audienceID,
|
|
|
|
})
|
2025-05-10 09:18:27 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2025-05-13 22:38:55 +00:00
|
|
|
|
2025-05-31 07:24:20 +00:00
|
|
|
func (r *QuizRepository) CheckIsOwnerAudience(ctx context.Context, quizID int64, audienceID int64, accountID string) (bool, error) {
|
|
|
|
ok, err := r.queries.CheckIsOwnerAudience(ctx, sqlcgen.CheckIsOwnerAudienceParams{
|
|
|
|
Quizid: quizID,
|
|
|
|
ID: audienceID,
|
|
|
|
Accountid: accountID,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ok, nil
|
|
|
|
}
|
|
|
|
|
2025-04-23 11:07:55 +00:00
|
|
|
func (r *QuizRepository) CheckQuizOwner(ctx context.Context, accountID string, quizID uint64) (bool, error) {
|
|
|
|
id, err := r.queries.CheckQuizOwner(ctx, sqlcgen.CheckQuizOwnerParams{
|
|
|
|
Accountid: accountID,
|
|
|
|
ID: int64(quizID),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return id == accountID, nil
|
|
|
|
}
|
2025-06-10 09:59:02 +00:00
|
|
|
|
|
|
|
func (r *QuizRepository) UpdateGigaChatQuizFlag(ctx context.Context, quizID int64, accountID string) error {
|
|
|
|
err := r.queries.UpdateGigaChatQuizFlag(ctx, sqlcgen.UpdateGigaChatQuizFlagParams{
|
|
|
|
ID: quizID,
|
|
|
|
Accountid: accountID,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|