256 lines
5.7 KiB
Go
256 lines
5.7 KiB
Go
package dal
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
_ "embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"gitea.pena/SQuiz/answerer/dal/sqlcgen"
|
|
"gitea.pena/SQuiz/answerer/model"
|
|
_ "github.com/ClickHouse/clickhouse-go"
|
|
"github.com/google/uuid"
|
|
"github.com/lib/pq"
|
|
_ "github.com/lib/pq"
|
|
"time"
|
|
)
|
|
|
|
type DAL struct {
|
|
pool *sql.DB
|
|
queries *sqlcgen.Queries
|
|
}
|
|
|
|
func New(ctx context.Context, cred string) (*DAL, error) {
|
|
pool, err := sql.Open("postgres", cred)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
|
|
defer cancel()
|
|
|
|
if err := pool.PingContext(timeoutCtx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
queries := sqlcgen.New(pool)
|
|
|
|
return &DAL{
|
|
pool: pool,
|
|
queries: queries,
|
|
}, nil
|
|
}
|
|
|
|
func (d *DAL) Close(ctx context.Context) error {
|
|
err := d.pool.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *DAL) GetQuizByQid(ctx context.Context, qid string) (model.Quiz, error) {
|
|
_, err := uuid.Parse(qid)
|
|
if err != nil {
|
|
return model.Quiz{}, err
|
|
}
|
|
|
|
fmt.Println("QUID", `
|
|
SELECT * FROM quiz
|
|
WHERE
|
|
deleted = false AND
|
|
archived = false AND
|
|
status = 'start' AND
|
|
qid = $1;
|
|
`)
|
|
rows, err := d.pool.QueryContext(ctx, `
|
|
SELECT * FROM quiz
|
|
WHERE
|
|
deleted = false AND
|
|
archived = false AND
|
|
(status = 'start' OR status = 'ai') AND
|
|
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,
|
|
&piece.GigaChat,
|
|
); err != nil {
|
|
return model.Quiz{}, err
|
|
}
|
|
|
|
piece.ParentIds = pIds
|
|
|
|
return piece, nil
|
|
}
|
|
|
|
func (d *DAL) GetQuestionListByIDs(ctx context.Context, ids []int32) ([]model.Question, error) {
|
|
rows, err := d.queries.GetQuestionListByIDs(ctx, ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var questions []model.Question
|
|
for _, row := range rows {
|
|
question := model.Question{
|
|
Id: uint64(row.ID),
|
|
QuizId: uint64(row.QuizID),
|
|
Title: row.Title,
|
|
Description: row.Description.String,
|
|
Type: string(row.Questiontype.([]byte)),
|
|
Required: row.Required.Bool,
|
|
Deleted: row.Deleted.Bool,
|
|
Page: int(row.Page.Int16),
|
|
Content: row.Content.String,
|
|
Version: int(row.Version.Int16),
|
|
ParentIds: row.ParentIds,
|
|
CreatedAt: row.CreatedAt.Time,
|
|
UpdatedAt: row.UpdatedAt.Time,
|
|
Auditory: row.Auditory,
|
|
}
|
|
|
|
questions = append(questions, question)
|
|
}
|
|
|
|
return questions, nil
|
|
}
|
|
|
|
func (d *DAL) CreateQuestion(ctx context.Context, record *model.Question) (uint64, error) {
|
|
params := sqlcgen.InsertQuestionParams{
|
|
QuizID: int64(record.QuizId),
|
|
Title: record.Title,
|
|
Description: sql.NullString{String: record.Description, Valid: true},
|
|
Questiontype: record.Type,
|
|
Required: sql.NullBool{Bool: record.Required, Valid: true},
|
|
Page: sql.NullInt16{Int16: int16(record.Page), Valid: true},
|
|
Content: sql.NullString{String: record.Content, Valid: true},
|
|
ParentIds: record.ParentIds,
|
|
UpdatedAt: sql.NullTime{Time: time.Now(), Valid: true},
|
|
Session: record.Session,
|
|
Auditory: record.Auditory,
|
|
}
|
|
|
|
data, err := d.queries.InsertQuestion(ctx, params)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
record.Id = uint64(data.ID)
|
|
record.CreatedAt = data.CreatedAt.Time
|
|
record.UpdatedAt = data.UpdatedAt.Time
|
|
|
|
return record.Id, nil
|
|
}
|
|
|
|
func (d *DAL) CreateAnswers(ctx context.Context, answers []model.Answer, session, fp string, quizID uint64) ([]model.Answer, []error) {
|
|
var (
|
|
createdAnswers []model.Answer
|
|
errs []error
|
|
)
|
|
|
|
tx, err := d.pool.BeginTx(ctx, nil)
|
|
if err != nil {
|
|
return nil, []error{err}
|
|
}
|
|
|
|
for _, ans := range answers {
|
|
if ans.Utm == nil {
|
|
ans.Utm = make(model.UTMSavingMap)
|
|
}
|
|
utmJSON, err := json.Marshal(ans.Utm)
|
|
if err != nil {
|
|
return nil, []error{err}
|
|
}
|
|
|
|
params := sqlcgen.InsertAnswersParams{
|
|
Content: sql.NullString{String: ans.Content, Valid: true},
|
|
QuizID: int64(quizID),
|
|
QuestionID: int64(ans.QuestionId),
|
|
Fingerprint: sql.NullString{String: fp, Valid: true},
|
|
Session: sql.NullString{String: session, Valid: true},
|
|
Result: sql.NullBool{Bool: ans.Result, Valid: true},
|
|
Email: ans.Email,
|
|
Device: ans.Device,
|
|
DeviceType: ans.DeviceType,
|
|
Ip: ans.IP,
|
|
Browser: ans.Browser,
|
|
Os: ans.OS,
|
|
Start: ans.Start,
|
|
Utm: utmJSON,
|
|
Version: ans.Version,
|
|
}
|
|
|
|
row, err := d.queries.InsertAnswers(ctx, params)
|
|
createdAnswer := model.Answer{
|
|
Id: uint64(row.ID),
|
|
Content: row.Content.String,
|
|
QuizId: uint64(row.QuizID),
|
|
QuestionId: uint64(row.QuestionID),
|
|
Fingerprint: row.Fingerprint.String,
|
|
Session: row.Session.String,
|
|
Result: row.Result.Bool,
|
|
New: row.New.Bool,
|
|
Email: row.Email,
|
|
DeviceType: row.DeviceType,
|
|
Device: row.Device,
|
|
OS: row.Os,
|
|
Browser: row.Browser,
|
|
IP: row.Ip,
|
|
Start: row.Start,
|
|
Version: row.Version,
|
|
}
|
|
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
} else {
|
|
createdAnswers = append(createdAnswers, createdAnswer)
|
|
}
|
|
}
|
|
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
return nil, errs
|
|
}
|
|
|
|
return createdAnswers, errs
|
|
}
|