From aadccd65714e5562c0c8cf0791039b86ba122eb2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 14:27:08 +0300 Subject: [PATCH 001/107] update new queries with new bool var start --- dal/db_query/queries.sql | 14 +++++++------- dal/schema/000007_init.down.sql | 2 ++ dal/schema/000007_init.up.sql | 2 ++ sqlc.yaml | 2 ++ 4 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 dal/schema/000007_init.down.sql create mode 100644 dal/schema/000007_init.up.sql diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 257d9ca..c060422 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -282,8 +282,7 @@ WHERE privilege_name = $2 AND (amount < $3 OR created_at <= NOW() - INTERVAL '1 month'); -- name: GetAllAnswersByQuizID :many -SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 ORDER BY question_id ASC, created_at DESC; - +SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 AND start = false ORDER BY question_id ASC, created_at DESC; -- name: InsertAnswers :exec INSERT INTO answer( content, @@ -297,12 +296,13 @@ INSERT INTO answer( device, os, browser, - ip -) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12); + ip, + start +) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13); -- name: GetResultAnswers :many SELECT DISTINCT on (question_id) id, content, quiz_id, question_id, fingerprint, session,created_at, result, new,deleted FROM answer WHERE session = ( - SELECT session FROM answer WHERE answer.id = $1) ORDER BY question_id, created_at DESC; + SELECT session FROM answer WHERE answer.id = $1) AND start = false ORDER BY question_id, created_at DESC; -- name: GetQuestions :many SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at FROM question WHERE quiz_id = $1 AND deleted = FALSE; @@ -314,7 +314,7 @@ UPDATE answer SET deleted = TRUE WHERE id = $1 AND deleted = FALSE; SELECT a.id FROM answer a JOIN quiz q ON a.quiz_id = q.id -WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2; +WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2 AND a.start = false; -- name: CheckResultOwner :one -SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE; +SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE AND a.start = false; \ No newline at end of file diff --git a/dal/schema/000007_init.down.sql b/dal/schema/000007_init.down.sql new file mode 100644 index 0000000..374c55d --- /dev/null +++ b/dal/schema/000007_init.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE answer +DROP COLUMN start; \ No newline at end of file diff --git a/dal/schema/000007_init.up.sql b/dal/schema/000007_init.up.sql new file mode 100644 index 0000000..6b41425 --- /dev/null +++ b/dal/schema/000007_init.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE answer +ADD COLUMN start BOOLEAN NOT NULL DEFAULT FALSE; \ No newline at end of file diff --git a/sqlc.yaml b/sqlc.yaml index 31e8f53..625e6c4 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -16,6 +16,8 @@ packages: - "./dal/schema/000005_init.down.sql" - "./dal/schema/000006_init.up.sql" - "./dal/schema/000006_init.down.sql" + - "./dal/schema/000007_init.up.sql" + - "./dal/schema/000007_init.down.sql" engine: "postgresql" emit_json_tags: true emit_db_tags: true From 7bb41cca01c2581aec84386903eedfd6ef998956 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 14:32:26 +0300 Subject: [PATCH 002/107] update sqlc gen files --- dal/sqlcgen/models.go | 1 + dal/sqlcgen/queries.sql.go | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/dal/sqlcgen/models.go b/dal/sqlcgen/models.go index 2a6da31..5a42d12 100644 --- a/dal/sqlcgen/models.go +++ b/dal/sqlcgen/models.go @@ -35,6 +35,7 @@ type Answer struct { Os string `db:"os" json:"os"` Browser string `db:"browser" json:"browser"` Ip string `db:"ip" json:"ip"` + Start bool `db:"start" json:"start"` } type Privilege struct { diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 3a98c1e..1066e9f 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -91,7 +91,7 @@ func (q *Queries) CheckAndAddDefault(ctx context.Context, arg CheckAndAddDefault } const checkResultOwner = `-- name: CheckResultOwner :one -SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE +SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE AND a.start = false ` func (q *Queries) CheckResultOwner(ctx context.Context, id int64) (string, error) { @@ -105,7 +105,7 @@ const checkResultsOwner = `-- name: CheckResultsOwner :many SELECT a.id FROM answer a JOIN quiz q ON a.quiz_id = q.id -WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2 +WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2 AND a.start = false ` type CheckResultsOwnerParams struct { @@ -476,7 +476,7 @@ func (q *Queries) GetAccountWithPrivileges(ctx context.Context, userID sql.NullS } const getAllAnswersByQuizID = `-- name: GetAllAnswersByQuizID :many -SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 ORDER BY question_id ASC, created_at DESC +SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 AND start = false ORDER BY question_id ASC, created_at DESC ` type GetAllAnswersByQuizIDRow struct { @@ -985,7 +985,7 @@ func (q *Queries) GetQuizHistory(ctx context.Context, arg GetQuizHistoryParams) const getResultAnswers = `-- name: GetResultAnswers :many SELECT DISTINCT on (question_id) id, content, quiz_id, question_id, fingerprint, session,created_at, result, new,deleted FROM answer WHERE session = ( - SELECT session FROM answer WHERE answer.id = $1) ORDER BY question_id, created_at DESC + SELECT session FROM answer WHERE answer.id = $1) AND start = false ORDER BY question_id, created_at DESC ` type GetResultAnswersRow struct { @@ -1048,8 +1048,9 @@ INSERT INTO answer( device, os, browser, - ip -) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) + ip, + start +) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) ` type InsertAnswersParams struct { @@ -1065,6 +1066,7 @@ type InsertAnswersParams struct { Os string `db:"os" json:"os"` Browser string `db:"browser" json:"browser"` Ip string `db:"ip" json:"ip"` + Start bool `db:"start" json:"start"` } func (q *Queries) InsertAnswers(ctx context.Context, arg InsertAnswersParams) error { @@ -1081,6 +1083,7 @@ func (q *Queries) InsertAnswers(ctx context.Context, arg InsertAnswersParams) er arg.Os, arg.Browser, arg.Ip, + arg.Start, ) return err } From a26dce3bed0ec298d4031fef81849bba2f764fd8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 14:35:39 +0300 Subject: [PATCH 003/107] update create new answer with new bool var start --- repository/answer/answer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/repository/answer/answer.go b/repository/answer/answer.go index 6ced475..af4b316 100644 --- a/repository/answer/answer.go +++ b/repository/answer/answer.go @@ -50,6 +50,7 @@ func (r *AnswerRepository) CreateAnswers(ctx context.Context, answers []model.An Ip: ans.IP, Browser: ans.Browser, Os: ans.OS, + Start: ans.Start, } err := r.queries.InsertAnswers(ctx, params) From db75b0e5157154d461902364ff89db2a96506b46 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 15:31:12 +0300 Subject: [PATCH 004/107] init new statistics repo --- dal/dal.go | 44 +++++++++++++++++------------ repository/statistics/statistics.go | 23 +++++++++++++++ 2 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 repository/statistics/statistics.go diff --git a/dal/dal.go b/dal/dal.go index 3adc580..5f9418b 100644 --- a/dal/dal.go +++ b/dal/dal.go @@ -15,6 +15,7 @@ import ( "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/question" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/quiz" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/result" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/statistics" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/workers" "penahub.gitlab.yandexcloud.net/backend/quiz/core.git/clients/auth" "time" @@ -23,15 +24,16 @@ import ( var errNextDeclined = errors.New("next is declined") type DAL struct { - conn *sql.DB - authClient *auth.AuthClient - queries *sqlcgen.Queries - AccountRepo *account.AccountRepository - AnswerRepo *answer.AnswerRepository - QuestionRepo *question.QuestionRepository - QuizRepo *quiz.QuizRepository - ResultRepo *result.ResultRepository - WorkerRepo *workers.WorkerRepository + conn *sql.DB + authClient *auth.AuthClient + queries *sqlcgen.Queries + AccountRepo *account.AccountRepository + AnswerRepo *answer.AnswerRepository + QuestionRepo *question.QuestionRepository + QuizRepo *quiz.QuizRepository + ResultRepo *result.ResultRepository + WorkerRepo *workers.WorkerRepository + StatisticsRepo *statistics.StatisticsRepository } func New(ctx context.Context, cred string, authClient *auth.AuthClient) (*DAL, error) { @@ -79,16 +81,22 @@ func New(ctx context.Context, cred string, authClient *auth.AuthClient) (*DAL, e Queries: queries, }) + statisticsRepo := statistics.NewStatisticsRepo(statistics.Deps{ + Queries: queries, + Pool: pool, + }) + return &DAL{ - conn: pool, - authClient: authClient, - queries: queries, - AccountRepo: accountRepo, - AnswerRepo: answerRepo, - QuestionRepo: questionRepo, - QuizRepo: quizRepo, - ResultRepo: resultRepo, - WorkerRepo: workerRepo, + conn: pool, + authClient: authClient, + queries: queries, + AccountRepo: accountRepo, + AnswerRepo: answerRepo, + QuestionRepo: questionRepo, + QuizRepo: quizRepo, + ResultRepo: resultRepo, + WorkerRepo: workerRepo, + StatisticsRepo: statisticsRepo, }, nil } diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go new file mode 100644 index 0000000..a32a446 --- /dev/null +++ b/repository/statistics/statistics.go @@ -0,0 +1,23 @@ +package statistics + +import ( + "database/sql" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" +) + +type Deps struct { + Queries *sqlcgen.Queries + Pool *sql.DB +} + +type StatisticsRepository struct { + queries *sqlcgen.Queries + pool *sql.DB +} + +func NewStatisticsRepo(deps Deps) *StatisticsRepository { + return &StatisticsRepository{ + queries: deps.Queries, + pool: deps.Pool, + } +} From 621de17c77dae1eaee460c00f1bb14c59b5eaa6b Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 16:02:09 +0300 Subject: [PATCH 005/107] update query --- dal/db_query/queries.sql | 69 ++++++++++++++++++++++++++++- repository/statistics/statistics.go | 21 +++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index c060422..e97769b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -317,4 +317,71 @@ FROM answer a WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2 AND a.start = false; -- name: CheckResultOwner :one -SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE AND a.start = false; \ No newline at end of file +SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE AND a.start = false; + +-- name:DeviceStats :many +WITH DeviceStats AS ( + SELECT + device_type, + COUNT(*) AS device_count + FROM + answer + WHERE + quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + device_type +), + OSStats AS ( + SELECT + os, + COUNT(*) AS os_count + FROM + answer + WHERE + quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + os + ), + BrowserStats AS ( + SELECT + browser, + COUNT(*) AS browser_count + FROM + answer + WHERE + quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + browser + ), + TotalStats AS ( + SELECT + COUNT(*) AS total_count + FROM + answer + WHERE + quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + ) +SELECT + device_type, + (device_count::FLOAT / total_count) * 100 AS device_percentage, + os, + (os_count::FLOAT / total_count) * 100 AS os_percentage, + browser, + (browser_count::FLOAT / total_count) * 100 AS browser_percentage +FROM + DeviceStats, + OSStats, + BrowserStats, + TotalStats; \ No newline at end of file diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index a32a446..9f9a234 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -1,6 +1,7 @@ package statistics import ( + "context" "database/sql" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" ) @@ -21,3 +22,23 @@ func NewStatisticsRepo(deps Deps) *StatisticsRepository { pool: deps.Pool, } } + +type DeviceStatReq struct { + QuizId string + From uint64 + To uint64 +} + +type DeviceStatResp struct { + Device map[string]float64 + OS map[string]float64 + Browser map[string]float64 +} + +func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req DeviceStatReq) DeviceStatResp { + resp := DeviceStatResp{ + Device: make(map[string]float64), + OS: make(map[string]float64), + Browser: make(map[string]float64), + } +} From 720cbfb405e2e197aab96593340f3a0fe0c93dd2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 16:11:42 +0300 Subject: [PATCH 006/107] update sqlc gen files --- dal/db_query/queries.sql | 24 ++++---- dal/sqlcgen/queries.sql.go | 113 +++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 12 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index e97769b..c9a6e3e 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -319,7 +319,7 @@ WHERE a.id = ANY($1::bigint[]) AND a.deleted = FALSE AND q.accountid = $2 AND a. -- name: CheckResultOwner :one SELECT q.accountid FROM answer a JOIN quiz q ON a.quiz_id = q.id WHERE a.id = $1 AND a.deleted = FALSE AND a.start = false; --- name:DeviceStats :many +-- name: DeviceStatistics :many WITH DeviceStats AS ( SELECT device_type, @@ -327,7 +327,7 @@ WITH DeviceStats AS ( FROM answer WHERE - quiz_id = $1 + answer.quiz_id = $1 AND created_at >= to_timestamp($2) AND created_at <= to_timestamp($3) AND result = TRUE @@ -341,7 +341,7 @@ WITH DeviceStats AS ( FROM answer WHERE - quiz_id = $1 + answer.quiz_id = $1 AND created_at >= to_timestamp($2) AND created_at <= to_timestamp($3) AND result = TRUE @@ -355,7 +355,7 @@ WITH DeviceStats AS ( FROM answer WHERE - quiz_id = $1 + answer.quiz_id = $1 AND created_at >= to_timestamp($2) AND created_at <= to_timestamp($3) AND result = TRUE @@ -368,20 +368,20 @@ WITH DeviceStats AS ( FROM answer WHERE - quiz_id = $1 + answer.quiz_id = $1 AND created_at >= to_timestamp($2) AND created_at <= to_timestamp($3) AND result = TRUE ) SELECT - device_type, - (device_count::FLOAT / total_count) * 100 AS device_percentage, - os, - (os_count::FLOAT / total_count) * 100 AS os_percentage, - browser, - (browser_count::FLOAT / total_count) * 100 AS browser_percentage + DeviceStats.device_type, + (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100 AS device_percentage, + OSStats.os, + (OSStats.os_count::FLOAT / TotalStats.total_count) * 100 AS os_percentage, + BrowserStats.browser, + (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100 AS browser_percentage FROM DeviceStats, OSStats, BrowserStats, - TotalStats; \ No newline at end of file + TotalStats; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 1066e9f..aebc5fd 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -345,6 +345,119 @@ func (q *Queries) DeleteQuizByID(ctx context.Context, arg DeleteQuizByIDParams) return i, err } +const deviceStatistics = `-- name: DeviceStatistics :many +WITH DeviceStats AS ( + SELECT + device_type, + COUNT(*) AS device_count + FROM + answer + WHERE + answer.quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + device_type +), + OSStats AS ( + SELECT + os, + COUNT(*) AS os_count + FROM + answer + WHERE + answer.quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + os + ), + BrowserStats AS ( + SELECT + browser, + COUNT(*) AS browser_count + FROM + answer + WHERE + answer.quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + GROUP BY + browser + ), + TotalStats AS ( + SELECT + COUNT(*) AS total_count + FROM + answer + WHERE + answer.quiz_id = $1 + AND created_at >= to_timestamp($2) + AND created_at <= to_timestamp($3) + AND result = TRUE + ) +SELECT + DeviceStats.device_type, + (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100 AS device_percentage, + OSStats.os, + (OSStats.os_count::FLOAT / TotalStats.total_count) * 100 AS os_percentage, + BrowserStats.browser, + (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100 AS browser_percentage +FROM + DeviceStats, + OSStats, + BrowserStats, + TotalStats +` + +type DeviceStatisticsParams struct { + QuizID int64 `db:"quiz_id" json:"quiz_id"` + ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` + ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` +} + +type DeviceStatisticsRow struct { + DeviceType string `db:"device_type" json:"device_type"` + DevicePercentage int32 `db:"device_percentage" json:"device_percentage"` + Os string `db:"os" json:"os"` + OsPercentage int32 `db:"os_percentage" json:"os_percentage"` + Browser string `db:"browser" json:"browser"` + BrowserPercentage int32 `db:"browser_percentage" json:"browser_percentage"` +} + +func (q *Queries) DeviceStatistics(ctx context.Context, arg DeviceStatisticsParams) ([]DeviceStatisticsRow, error) { + rows, err := q.db.QueryContext(ctx, deviceStatistics, arg.QuizID, arg.ToTimestamp, arg.ToTimestamp_2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DeviceStatisticsRow + for rows.Next() { + var i DeviceStatisticsRow + if err := rows.Scan( + &i.DeviceType, + &i.DevicePercentage, + &i.Os, + &i.OsPercentage, + &i.Browser, + &i.BrowserPercentage, + ); 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 duplicateQuestion = `-- name: DuplicateQuestion :one INSERT INTO question( quiz_id, title, description, questiontype, required, From 4cc870989184dc68c218bd17aadb242d199215e4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 16:36:41 +0300 Subject: [PATCH 007/107] init methid for new device statistics --- repository/statistics/statistics.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 9f9a234..a02ba3c 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -24,21 +24,41 @@ func NewStatisticsRepo(deps Deps) *StatisticsRepository { } type DeviceStatReq struct { - QuizId string + QuizId int64 From uint64 To uint64 } type DeviceStatResp struct { - Device map[string]float64 + //ключ DeviceType значение процент + Device map[string]float64 // процентное соотношение DeviceType по всем ответам на опроc c res==true + // тоже самое тут только по OS и BROWSER OS map[string]float64 Browser map[string]float64 } -func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req DeviceStatReq) DeviceStatResp { +func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req DeviceStatReq) (DeviceStatResp, error) { resp := DeviceStatResp{ Device: make(map[string]float64), OS: make(map[string]float64), Browser: make(map[string]float64), } + + //todo подумать как в sqlc сделать не int32 а float64 + allStatistics, err := r.queries.DeviceStatistics(ctx, sqlcgen.DeviceStatisticsParams{ + QuizID: req.QuizId, + ToTimestamp: float64(req.From), + ToTimestamp_2: float64(req.To), + }) + if err != nil { + return resp, err + } + + for _, stat := range allStatistics { + resp.Device[stat.DeviceType] = float64(stat.DevicePercentage) + resp.OS[stat.Os] = float64(stat.OsPercentage) + resp.Browser[stat.Browser] = float64(stat.BrowserPercentage) + } + + return resp, nil } From ea098ba021ee6c74dabea5812ce51e13232bfc6f Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 19:28:22 +0300 Subject: [PATCH 008/107] add generalstats query need testing --- dal/db_query/queries.sql | 85 +++++++++++++++++++++++++++++ repository/statistics/statistics.go | 11 ++++ 2 files changed, 96 insertions(+) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index c9a6e3e..f4cb7d2 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -385,3 +385,88 @@ FROM OSStats, BrowserStats, TotalStats; + +-- name: GeneralStatistics :many +WITH TimeBucket AS ( + SELECT + CASE + WHEN $2 - $1 > 172800 THEN date_trunc('day', time_bucket) + ELSE date_trunc('hour', time_bucket) + END AS time_interval + FROM + generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket +), + OpenStats AS ( + SELECT + time_interval, + COUNT(DISTINCT session) AS open_count + FROM + ( + SELECT + session, + MIN(created_at) AS first_start_time + FROM + answer + WHERE + quiz_id = $3 + AND start = TRUE + AND created_at >= to_timestamp($1) + AND created_at <= to_timestamp($2) + GROUP BY + session + ) AS first_starts + GROUP BY + time_interval + ), + ResultStats AS ( + SELECT + time_interval, + COUNT(DISTINCT session) AS result_count + FROM + ( + SELECT + session, + MIN(created_at) AS first_result_time + FROM + answer + WHERE + quiz_id = $3 + AND result = TRUE + AND created_at >= to_timestamp($1) + AND created_at <= to_timestamp($2) + GROUP BY + session + ) AS first_results + GROUP BY + time_interval + ), + AvTimeStats AS ( + SELECT + a.time_interval, + AVG(EXTRACT(epoch FROM (a.created_at - b.created_at))) AS avg_time + FROM + answer a + JOIN answer b ON a.session = b.session + WHERE + a.quiz_id = $3 + AND a.result = TRUE + AND b.start = TRUE + AND a.created_at >= to_timestamp($1) + AND a.created_at <= to_timestamp($2) + GROUP BY + a.time_interval + ) +SELECT + tb.time_interval AS time_bucket, + COALESCE(os.open_count, 0) AS open_count, + COALESCE(rs.result_count, 0) AS result_count, + COALESCE(at.avg_time, 0) AS avg_time, + CASE + WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) + ELSE 0 + END AS conversion +FROM + TimeBucket tb + LEFT JOIN OpenStats os ON tb.time_interval = os.time_interval + LEFT JOIN ResultStats rs ON tb.time_interval = rs.time_interval + LEFT JOIN AvTimeStats at ON tb.time_interval = at.time_interval \ No newline at end of file diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index a02ba3c..05cfba3 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -62,3 +62,14 @@ func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req Devi return resp, nil } + +type GeneralStatsResp struct { + Open map[uint64]uint64 // количество ответов с полем start == true за период от одного пункта разбиения и до другого + Result map[uint64]uint64 // количество ответов с полем result == true за период от одного пункта разбиения и до другого + AvTime map[uint64]uint64 // среднее время между ответом с полем result == true и start == true. в рамках сессии + Conversion map[uint64]uint64 // Result/Open за период от одного пункта разбиения и до другого +} + +func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req DeviceStatReq) (GeneralStatsResp, error) { + +} From 9db559a602b71ca36a010bdbef96272404819103 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:02:01 +0300 Subject: [PATCH 009/107] update sqlc gen --- dal/db_query/queries.sql | 34 +++++---- dal/sqlcgen/queries.sql.go | 139 +++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 12 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index f4cb7d2..6270c2e 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -398,7 +398,7 @@ WITH TimeBucket AS ( ), OpenStats AS ( SELECT - time_interval, + tb.time_interval, COUNT(DISTINCT session) AS open_count FROM ( @@ -408,19 +408,21 @@ WITH TimeBucket AS ( FROM answer WHERE - quiz_id = $3 + answer.quiz_id = $3 AND start = TRUE AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) GROUP BY session ) AS first_starts + JOIN + TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY - time_interval + tb.time_interval ), ResultStats AS ( SELECT - time_interval, + tb.time_interval, COUNT(DISTINCT session) AS result_count FROM ( @@ -430,23 +432,28 @@ WITH TimeBucket AS ( FROM answer WHERE - quiz_id = $3 + answer.quiz_id = $3 AND result = TRUE AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) GROUP BY session ) AS first_results + JOIN + TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY - time_interval + tb.time_interval ), AvTimeStats AS ( SELECT - a.time_interval, + tb.time_interval, AVG(EXTRACT(epoch FROM (a.created_at - b.created_at))) AS avg_time FROM answer a - JOIN answer b ON a.session = b.session + JOIN + answer b ON a.session = b.session + JOIN + TimeBucket tb ON date_trunc('hour', a.created_at) = tb.time_interval WHERE a.quiz_id = $3 AND a.result = TRUE @@ -454,7 +461,7 @@ WITH TimeBucket AS ( AND a.created_at >= to_timestamp($1) AND a.created_at <= to_timestamp($2) GROUP BY - a.time_interval + tb.time_interval ) SELECT tb.time_interval AS time_bucket, @@ -467,6 +474,9 @@ SELECT END AS conversion FROM TimeBucket tb - LEFT JOIN OpenStats os ON tb.time_interval = os.time_interval - LEFT JOIN ResultStats rs ON tb.time_interval = rs.time_interval - LEFT JOIN AvTimeStats at ON tb.time_interval = at.time_interval \ No newline at end of file + LEFT JOIN + OpenStats os ON tb.time_interval = os.time_interval + LEFT JOIN + ResultStats rs ON tb.time_interval = rs.time_interval + LEFT JOIN + AvTimeStats at ON tb.time_interval = at.time_interval; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index aebc5fd..46bc4c2 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -488,6 +488,145 @@ func (q *Queries) DuplicateQuestion(ctx context.Context, id int64) (DuplicateQue return i, err } +const generalStatistics = `-- name: GeneralStatistics :many +WITH TimeBucket AS ( + SELECT + CASE + WHEN $2 - $1 > 172800 THEN date_trunc('day', time_bucket) + ELSE date_trunc('hour', time_bucket) + END AS time_interval + FROM + generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket +), + OpenStats AS ( + SELECT + tb.time_interval, + COUNT(DISTINCT session) AS open_count + FROM + ( + SELECT + session, + MIN(created_at) AS first_start_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND start = TRUE + AND created_at >= to_timestamp($1) + AND created_at <= to_timestamp($2) + GROUP BY + session + ) AS first_starts + JOIN + TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + GROUP BY + tb.time_interval + ), + ResultStats AS ( + SELECT + tb.time_interval, + COUNT(DISTINCT session) AS result_count + FROM + ( + SELECT + session, + MIN(created_at) AS first_result_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= to_timestamp($1) + AND created_at <= to_timestamp($2) + GROUP BY + session + ) AS first_results + JOIN + TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + GROUP BY + tb.time_interval + ), + AvTimeStats AS ( + SELECT + tb.time_interval, + AVG(EXTRACT(epoch FROM (a.created_at - b.created_at))) AS avg_time + FROM + answer a + JOIN + answer b ON a.session = b.session + JOIN + TimeBucket tb ON date_trunc('hour', a.created_at) = tb.time_interval + WHERE + a.quiz_id = $3 + AND a.result = TRUE + AND b.start = TRUE + AND a.created_at >= to_timestamp($1) + AND a.created_at <= to_timestamp($2) + GROUP BY + tb.time_interval + ) +SELECT + tb.time_interval AS time_bucket, + COALESCE(os.open_count, 0) AS open_count, + COALESCE(rs.result_count, 0) AS result_count, + COALESCE(at.avg_time, 0) AS avg_time, + CASE + WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) + ELSE 0 + END AS conversion +FROM + TimeBucket tb + LEFT JOIN + OpenStats os ON tb.time_interval = os.time_interval + LEFT JOIN + ResultStats rs ON tb.time_interval = rs.time_interval + LEFT JOIN + AvTimeStats at ON tb.time_interval = at.time_interval +` + +type GeneralStatisticsParams struct { + Column1 interface{} `db:"column_1" json:"column_1"` + Column2 interface{} `db:"column_2" json:"column_2"` + QuizID int64 `db:"quiz_id" json:"quiz_id"` +} + +type GeneralStatisticsRow struct { + TimeBucket interface{} `db:"time_bucket" json:"time_bucket"` + OpenCount int64 `db:"open_count" json:"open_count"` + ResultCount int64 `db:"result_count" json:"result_count"` + AvgTime float64 `db:"avg_time" json:"avg_time"` + Conversion int32 `db:"conversion" json:"conversion"` +} + +func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsParams) ([]GeneralStatisticsRow, error) { + rows, err := q.db.QueryContext(ctx, generalStatistics, arg.Column1, arg.Column2, arg.QuizID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GeneralStatisticsRow + for rows.Next() { + var i GeneralStatisticsRow + if err := rows.Scan( + &i.TimeBucket, + &i.OpenCount, + &i.ResultCount, + &i.AvgTime, + &i.Conversion, + ); 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 getAccAndPrivilegeByEmail = `-- name: GetAccAndPrivilegeByEmail :one SELECT a.id, From a9d3f8b5c656551cd2de417a3b31c29b48999fb5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:04:30 +0300 Subject: [PATCH 010/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 6270c2e..1fd03ce 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -390,7 +390,7 @@ FROM WITH TimeBucket AS ( SELECT CASE - WHEN $2 - $1 > 172800 THEN date_trunc('day', time_bucket) + WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', time_bucket) ELSE date_trunc('hour', time_bucket) END AS time_interval FROM diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 46bc4c2..83bb0f4 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -492,7 +492,7 @@ const generalStatistics = `-- name: GeneralStatistics :many WITH TimeBucket AS ( SELECT CASE - WHEN $2 - $1 > 172800 THEN date_trunc('day', time_bucket) + WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', time_bucket) ELSE date_trunc('hour', time_bucket) END AS time_interval FROM @@ -585,9 +585,9 @@ FROM ` type GeneralStatisticsParams struct { - Column1 interface{} `db:"column_1" json:"column_1"` - Column2 interface{} `db:"column_2" json:"column_2"` - QuizID int64 `db:"quiz_id" json:"quiz_id"` + ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` + ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` + QuizID int64 `db:"quiz_id" json:"quiz_id"` } type GeneralStatisticsRow struct { @@ -599,7 +599,7 @@ type GeneralStatisticsRow struct { } func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsParams) ([]GeneralStatisticsRow, error) { - rows, err := q.db.QueryContext(ctx, generalStatistics, arg.Column1, arg.Column2, arg.QuizID) + rows, err := q.db.QueryContext(ctx, generalStatistics, arg.ToTimestamp, arg.ToTimestamp_2, arg.QuizID) if err != nil { return nil, err } From db9996534890a0de0b0d92be4a826f517125fa1d Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:19:39 +0300 Subject: [PATCH 011/107] update time_bucket to_timestamp --- dal/db_query/queries.sql | 4 ++-- repository/statistics/statistics.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1fd03ce..518963d 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -390,8 +390,8 @@ FROM WITH TimeBucket AS ( SELECT CASE - WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', time_bucket) - ELSE date_trunc('hour', time_bucket) + WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) + ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 05cfba3..0bf9088 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -71,5 +71,28 @@ type GeneralStatsResp struct { } func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req DeviceStatReq) (GeneralStatsResp, error) { + resp := GeneralStatsResp{ + Open: make(map[uint64]uint64), + Result: make(map[uint64]uint64), + AvTime: make(map[uint64]uint64), + Conversion: make(map[uint64]uint64), + } + allStatistics, err := r.queries.GeneralStatistics(ctx, sqlcgen.GeneralStatisticsParams{ + QuizID: req.QuizId, + ToTimestamp: float64(req.From), + ToTimestamp_2: float64(req.To), + }) + if err != nil { + return resp, err + } + + for _, stat := range allStatistics { + resp.Open[stat.TimeBucket] = stat.OpenCount + resp.Result[stat.TimeBucket] = stat.ResultCount + resp.AvTime[stat.TimeBucket] = stat.AvgTime + resp.Conversion[stat.TimeBucket] = stat.Conversion + } + + return resp, nil } From 580657b5455b06507a177f44f500f5c669b9fa24 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:20:52 +0300 Subject: [PATCH 012/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 83bb0f4..a868d15 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -492,8 +492,8 @@ const generalStatistics = `-- name: GeneralStatistics :many WITH TimeBucket AS ( SELECT CASE - WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', time_bucket) - ELSE date_trunc('hour', time_bucket) + WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) + ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket From 27ced470cd0a65124efd02bb7dfbafa60033c9e9 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:27:59 +0300 Subject: [PATCH 013/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 518963d..1a777e3 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -464,7 +464,7 @@ WITH TimeBucket AS ( tb.time_interval ) SELECT - tb.time_interval AS time_bucket, + to_timestamp(tb.time_interval) AS time_bucket, COALESCE(os.open_count, 0) AS open_count, COALESCE(rs.result_count, 0) AS result_count, COALESCE(at.avg_time, 0) AS avg_time, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index a868d15..abc02cf 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -566,7 +566,7 @@ WITH TimeBucket AS ( tb.time_interval ) SELECT - tb.time_interval AS time_bucket, + to_timestamp(tb.time_interval) AS time_bucket, COALESCE(os.open_count, 0) AS open_count, COALESCE(rs.result_count, 0) AS result_count, COALESCE(at.avg_time, 0) AS avg_time, From 9c87245613322c574835a265996ca3e5190ba8f4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 15 Mar 2024 20:43:02 +0300 Subject: [PATCH 014/107] update --- repository/statistics/statistics.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 0bf9088..3532f15 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -77,7 +77,7 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev AvTime: make(map[uint64]uint64), Conversion: make(map[uint64]uint64), } - + // todo затетсить этот жоский запрос если что переписать allStatistics, err := r.queries.GeneralStatistics(ctx, sqlcgen.GeneralStatisticsParams{ QuizID: req.QuizId, ToTimestamp: float64(req.From), @@ -88,10 +88,10 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev } for _, stat := range allStatistics { - resp.Open[stat.TimeBucket] = stat.OpenCount - resp.Result[stat.TimeBucket] = stat.ResultCount - resp.AvTime[stat.TimeBucket] = stat.AvgTime - resp.Conversion[stat.TimeBucket] = stat.Conversion + resp.Open[stat.TimeBucket.(uint64)] = uint64(stat.OpenCount) + resp.Result[stat.TimeBucket.(uint64)] = uint64(stat.ResultCount) + resp.AvTime[stat.TimeBucket.(uint64)] = uint64(stat.AvgTime) + resp.Conversion[stat.TimeBucket.(uint64)] = uint64(stat.Conversion) } return resp, nil From 8ff7b0035661d57475cbbb46518a55c2d98dc3fb Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:29:43 +0300 Subject: [PATCH 015/107] update sql query --- dal/db_query/queries.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1a777e3..b57e152 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -375,11 +375,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100 AS device_percentage, + (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS device_percentage, OSStats.os, - (OSStats.os_count::FLOAT / TotalStats.total_count) * 100 AS os_percentage, + (OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS os_percentage, BrowserStats.browser, - (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100 AS browser_percentage + (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS browser_percentage FROM DeviceStats, OSStats, From 8114dc5212f46b1a53c154255f0a160c14a2e780 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:31:24 +0300 Subject: [PATCH 016/107] update sql query --- dal/db_query/queries.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index b57e152..22d411d 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -390,11 +390,11 @@ FROM WITH TimeBucket AS ( SELECT CASE - WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) + WHEN EXTRACT(epoch FROM to_timestamp($2)) - EXTRACT(epoch FROM to_timestamp($1)) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM - generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket + generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), '3600 seconds') AS time_bucket ), OpenStats AS ( SELECT From 666b0782a71da5bf4031f24f0a2c744ce2e7642d Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:39:09 +0300 Subject: [PATCH 017/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index abc02cf..ad5c165 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -401,11 +401,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100 AS device_percentage, + (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS device_percentage, OSStats.os, - (OSStats.os_count::FLOAT / TotalStats.total_count) * 100 AS os_percentage, + (OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS os_percentage, BrowserStats.browser, - (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100 AS browser_percentage + (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS browser_percentage FROM DeviceStats, OSStats, @@ -492,11 +492,11 @@ const generalStatistics = `-- name: GeneralStatistics :many WITH TimeBucket AS ( SELECT CASE - WHEN to_timestamp($2) - to_timestamp($1) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) + WHEN EXTRACT(epoch FROM to_timestamp($2)) - EXTRACT(epoch FROM to_timestamp($1)) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM - generate_series(to_timestamp($1), to_timestamp($2), '1 hour') AS time_bucket + generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), '3600 seconds') AS time_bucket ), OpenStats AS ( SELECT From 590aeb0e00400eaa5c1b33352153c013db12340a Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:44:14 +0300 Subject: [PATCH 018/107] update sqlc gen --- dal/db_query/queries.sql | 16 ++++++++-------- dal/sqlcgen/queries.sql.go | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 22d411d..876484b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -375,16 +375,16 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS device_percentage, OSStats.os, - (OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS os_percentage, BrowserStats.browser, - (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage FROM - DeviceStats, - OSStats, - BrowserStats, - TotalStats; + DeviceStats + CROSS JOIN OSStats + CROSS JOIN BrowserStats + CROSS JOIN TotalStats; -- name: GeneralStatistics :many WITH TimeBucket AS ( @@ -394,7 +394,7 @@ WITH TimeBucket AS ( ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM - generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), '3600 seconds') AS time_bucket + generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), 3600) AS time_bucket ), OpenStats AS ( SELECT diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index ad5c165..10a3d3b 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -401,16 +401,16 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - (DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS device_percentage, OSStats.os, - (OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS os_percentage, BrowserStats.browser, - (BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage FROM - DeviceStats, - OSStats, - BrowserStats, - TotalStats + DeviceStats + CROSS JOIN OSStats + CROSS JOIN BrowserStats + CROSS JOIN TotalStats ` type DeviceStatisticsParams struct { @@ -421,11 +421,11 @@ type DeviceStatisticsParams struct { type DeviceStatisticsRow struct { DeviceType string `db:"device_type" json:"device_type"` - DevicePercentage int32 `db:"device_percentage" json:"device_percentage"` + DevicePercentage string `db:"device_percentage" json:"device_percentage"` Os string `db:"os" json:"os"` - OsPercentage int32 `db:"os_percentage" json:"os_percentage"` + OsPercentage string `db:"os_percentage" json:"os_percentage"` Browser string `db:"browser" json:"browser"` - BrowserPercentage int32 `db:"browser_percentage" json:"browser_percentage"` + BrowserPercentage string `db:"browser_percentage" json:"browser_percentage"` } func (q *Queries) DeviceStatistics(ctx context.Context, arg DeviceStatisticsParams) ([]DeviceStatisticsRow, error) { @@ -496,7 +496,7 @@ WITH TimeBucket AS ( ELSE date_trunc('hour', to_timestamp(time_bucket)) END AS time_interval FROM - generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), '3600 seconds') AS time_bucket + generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), 3600) AS time_bucket ), OpenStats AS ( SELECT From 53b2e68ec98e3449c207d72b0bee37a2a0f34bc1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:46:28 +0300 Subject: [PATCH 019/107] update sqlc gen --- dal/db_query/queries.sql | 8 ++++---- dal/sqlcgen/queries.sql.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 876484b..8fe8b51 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -381,10 +381,10 @@ SELECT BrowserStats.browser, CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage FROM - DeviceStats - CROSS JOIN OSStats - CROSS JOIN BrowserStats - CROSS JOIN TotalStats; + DeviceStats, + OSStats, + BrowserStats, + TotalStats; -- name: GeneralStatistics :many WITH TimeBucket AS ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 10a3d3b..00685b3 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -407,10 +407,10 @@ SELECT BrowserStats.browser, CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage FROM - DeviceStats - CROSS JOIN OSStats - CROSS JOIN BrowserStats - CROSS JOIN TotalStats + DeviceStats, + OSStats, + BrowserStats, + TotalStats ` type DeviceStatisticsParams struct { From bf7f344d302b55906249a5dd33463799e1ed4779 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:49:32 +0300 Subject: [PATCH 020/107] update sqlc gen --- dal/db_query/queries.sql | 6 +++--- dal/sqlcgen/queries.sql.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 8fe8b51..6b0e890 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -375,11 +375,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS device_percentage, OSStats.os, - CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS os_percentage, BrowserStats.browser, - CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS browser_percentage FROM DeviceStats, OSStats, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 00685b3..0513243 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -401,11 +401,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS device_percentage, OSStats.os, - CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS os_percentage, BrowserStats.browser, - CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS DECIMAL(10,2)) AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS browser_percentage FROM DeviceStats, OSStats, @@ -421,11 +421,11 @@ type DeviceStatisticsParams struct { type DeviceStatisticsRow struct { DeviceType string `db:"device_type" json:"device_type"` - DevicePercentage string `db:"device_percentage" json:"device_percentage"` + DevicePercentage int32 `db:"device_percentage" json:"device_percentage"` Os string `db:"os" json:"os"` - OsPercentage string `db:"os_percentage" json:"os_percentage"` + OsPercentage int32 `db:"os_percentage" json:"os_percentage"` Browser string `db:"browser" json:"browser"` - BrowserPercentage string `db:"browser_percentage" json:"browser_percentage"` + BrowserPercentage int32 `db:"browser_percentage" json:"browser_percentage"` } func (q *Queries) DeviceStatistics(ctx context.Context, arg DeviceStatisticsParams) ([]DeviceStatisticsRow, error) { From 30e3841714c3c2bc01904b0bbef87d149089d366 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 22:56:08 +0300 Subject: [PATCH 021/107] update sqlc gen --- dal/db_query/queries.sql | 22 +++++++++++----------- dal/sqlcgen/queries.sql.go | 31 ++++++++++++++++--------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 6b0e890..0b88933 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -390,11 +390,11 @@ FROM WITH TimeBucket AS ( SELECT CASE - WHEN EXTRACT(epoch FROM to_timestamp($2)) - EXTRACT(epoch FROM to_timestamp($1)) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) - ELSE date_trunc('hour', to_timestamp(time_bucket)) + WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) + ELSE date_trunc('hour', timestamp_bucket) END AS time_interval FROM - generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), 3600) AS time_bucket + generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT @@ -410,8 +410,8 @@ WITH TimeBucket AS ( WHERE answer.quiz_id = $3 AND start = TRUE - AND created_at >= to_timestamp($1) - AND created_at <= to_timestamp($2) + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY session ) AS first_starts @@ -434,8 +434,8 @@ WITH TimeBucket AS ( WHERE answer.quiz_id = $3 AND result = TRUE - AND created_at >= to_timestamp($1) - AND created_at <= to_timestamp($2) + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY session ) AS first_results @@ -458,20 +458,20 @@ WITH TimeBucket AS ( a.quiz_id = $3 AND a.result = TRUE AND b.start = TRUE - AND a.created_at >= to_timestamp($1) - AND a.created_at <= to_timestamp($2) + AND a.created_at >= $1::timestamp + AND a.created_at <= $2::timestamp GROUP BY tb.time_interval ) SELECT - to_timestamp(tb.time_interval) AS time_bucket, + tb.time_interval AS time_bucket, COALESCE(os.open_count, 0) AS open_count, COALESCE(rs.result_count, 0) AS result_count, COALESCE(at.avg_time, 0) AS avg_time, CASE WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion FROM TimeBucket tb LEFT JOIN diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 0513243..d4461de 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -8,6 +8,7 @@ package sqlcgen import ( "context" "database/sql" + "time" "github.com/google/uuid" "github.com/lib/pq" @@ -492,11 +493,11 @@ const generalStatistics = `-- name: GeneralStatistics :many WITH TimeBucket AS ( SELECT CASE - WHEN EXTRACT(epoch FROM to_timestamp($2)) - EXTRACT(epoch FROM to_timestamp($1)) > 172800 THEN date_trunc('day', to_timestamp(time_bucket)) - ELSE date_trunc('hour', to_timestamp(time_bucket)) + WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) + ELSE date_trunc('hour', timestamp_bucket) END AS time_interval FROM - generate_series(EXTRACT(epoch FROM to_timestamp($1)), EXTRACT(epoch FROM to_timestamp($2)), 3600) AS time_bucket + generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT @@ -512,8 +513,8 @@ WITH TimeBucket AS ( WHERE answer.quiz_id = $3 AND start = TRUE - AND created_at >= to_timestamp($1) - AND created_at <= to_timestamp($2) + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY session ) AS first_starts @@ -536,8 +537,8 @@ WITH TimeBucket AS ( WHERE answer.quiz_id = $3 AND result = TRUE - AND created_at >= to_timestamp($1) - AND created_at <= to_timestamp($2) + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY session ) AS first_results @@ -560,20 +561,20 @@ WITH TimeBucket AS ( a.quiz_id = $3 AND a.result = TRUE AND b.start = TRUE - AND a.created_at >= to_timestamp($1) - AND a.created_at <= to_timestamp($2) + AND a.created_at >= $1::timestamp + AND a.created_at <= $2::timestamp GROUP BY tb.time_interval ) SELECT - to_timestamp(tb.time_interval) AS time_bucket, + tb.time_interval AS time_bucket, COALESCE(os.open_count, 0) AS open_count, COALESCE(rs.result_count, 0) AS result_count, COALESCE(at.avg_time, 0) AS avg_time, CASE WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion FROM TimeBucket tb LEFT JOIN @@ -585,9 +586,9 @@ FROM ` type GeneralStatisticsParams struct { - ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` - ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` - QuizID int64 `db:"quiz_id" json:"quiz_id"` + Column1 time.Time `db:"column_1" json:"column_1"` + Column2 time.Time `db:"column_2" json:"column_2"` + QuizID int64 `db:"quiz_id" json:"quiz_id"` } type GeneralStatisticsRow struct { @@ -599,7 +600,7 @@ type GeneralStatisticsRow struct { } func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsParams) ([]GeneralStatisticsRow, error) { - rows, err := q.db.QueryContext(ctx, generalStatistics, arg.ToTimestamp, arg.ToTimestamp_2, arg.QuizID) + rows, err := q.db.QueryContext(ctx, generalStatistics, arg.Column1, arg.Column2, arg.QuizID) if err != nil { return nil, err } From 8f361e4662b7cc026211be8926133c7cadde9aa7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:04:33 +0300 Subject: [PATCH 022/107] update repo method --- repository/statistics/statistics.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 3532f15..517346b 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" + "time" ) type Deps struct { @@ -79,9 +80,9 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev } // todo затетсить этот жоский запрос если что переписать allStatistics, err := r.queries.GeneralStatistics(ctx, sqlcgen.GeneralStatisticsParams{ - QuizID: req.QuizId, - ToTimestamp: float64(req.From), - ToTimestamp_2: float64(req.To), + QuizID: req.QuizId, + Column1: time.Unix(int64(req.From), 0), + Column2: time.Unix(int64(req.To), 0), }) if err != nil { return resp, err From e141b18a568452bb2290fb46924c1517200a95fc Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:09:52 +0300 Subject: [PATCH 023/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 0b88933..5c0e62f 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -392,7 +392,7 @@ WITH TimeBucket AS ( CASE WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) - END AS time_interval + END::TIMESTAMP AS time_interval FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), @@ -471,7 +471,7 @@ SELECT CASE WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion FROM TimeBucket tb LEFT JOIN diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index d4461de..e8caee8 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -495,7 +495,7 @@ WITH TimeBucket AS ( CASE WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) - END AS time_interval + END::TIMESTAMP AS time_interval FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), @@ -574,7 +574,7 @@ SELECT CASE WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion FROM TimeBucket tb LEFT JOIN @@ -592,11 +592,11 @@ type GeneralStatisticsParams struct { } type GeneralStatisticsRow struct { - TimeBucket interface{} `db:"time_bucket" json:"time_bucket"` - OpenCount int64 `db:"open_count" json:"open_count"` - ResultCount int64 `db:"result_count" json:"result_count"` - AvgTime float64 `db:"avg_time" json:"avg_time"` - Conversion int32 `db:"conversion" json:"conversion"` + TimeBucket time.Time `db:"time_bucket" json:"time_bucket"` + OpenCount int64 `db:"open_count" json:"open_count"` + ResultCount int64 `db:"result_count" json:"result_count"` + AvgTime float64 `db:"avg_time" json:"avg_time"` + Conversion int32 `db:"conversion" json:"conversion"` } func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsParams) ([]GeneralStatisticsRow, error) { From fa2bede7ad66c7aa55d06b5cbe5dcd4fce6812ac Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:12:33 +0300 Subject: [PATCH 024/107] update repo method --- repository/statistics/statistics.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 517346b..8afe0b2 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -89,10 +89,10 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev } for _, stat := range allStatistics { - resp.Open[stat.TimeBucket.(uint64)] = uint64(stat.OpenCount) - resp.Result[stat.TimeBucket.(uint64)] = uint64(stat.ResultCount) - resp.AvTime[stat.TimeBucket.(uint64)] = uint64(stat.AvgTime) - resp.Conversion[stat.TimeBucket.(uint64)] = uint64(stat.Conversion) + resp.Open[uint64(stat.TimeBucket.Unix())] = uint64(stat.OpenCount) + resp.Result[uint64(stat.TimeBucket.Unix())] = uint64(stat.ResultCount) + resp.AvTime[uint64(stat.TimeBucket.Unix())] = uint64(stat.AvgTime) + resp.Conversion[uint64(stat.TimeBucket.Unix())] = uint64(stat.Conversion) } return resp, nil From 7817c39b4091d57ed3a0637f930f43d40efaa292 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:21:55 +0300 Subject: [PATCH 025/107] update sql query --- dal/db_query/queries.sql | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 5c0e62f..a81ff91 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -415,8 +415,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_starts - JOIN - TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -439,8 +438,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_results - JOIN - TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), From f86e8ce0dd59fc16fc9952d1be2a3a330d66ecd1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:23:17 +0300 Subject: [PATCH 026/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index e8caee8..0cb5c43 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -518,8 +518,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_starts - JOIN - TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -542,8 +541,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_results - JOIN - TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), From 18b697f52b2f26c34cb70b144fe4b7e59975e3d8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:30:02 +0300 Subject: [PATCH 027/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index a81ff91..6a29cb1 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -415,7 +415,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_starts - RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -438,7 +438,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_results - RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 0cb5c43..8afc21d 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -518,7 +518,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_starts - RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -541,7 +541,7 @@ WITH TimeBucket AS ( GROUP BY session ) AS first_results - RIGHT JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), From b5c3002f4e6514fe328a7955dc08798bc925b1fb Mon Sep 17 00:00:00 2001 From: Pavel Date: Sat, 16 Mar 2024 23:58:01 +0300 Subject: [PATCH 028/107] update repo method --- repository/statistics/statistics.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 8afe0b2..c3e4ca5 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -45,7 +45,6 @@ func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req Devi Browser: make(map[string]float64), } - //todo подумать как в sqlc сделать не int32 а float64 allStatistics, err := r.queries.DeviceStatistics(ctx, sqlcgen.DeviceStatisticsParams{ QuizID: req.QuizId, ToTimestamp: float64(req.From), @@ -78,7 +77,7 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev AvTime: make(map[uint64]uint64), Conversion: make(map[uint64]uint64), } - // todo затетсить этот жоский запрос если что переписать + // todo затестить запрос нужно, когда на один тру ответ приходится один тру старт апдейтнуть запрос allStatistics, err := r.queries.GeneralStatistics(ctx, sqlcgen.GeneralStatisticsParams{ QuizID: req.QuizId, Column1: time.Unix(int64(req.From), 0), From 32b57399b0b69d92950329f198afc33add1cec4d Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 14:07:08 +0300 Subject: [PATCH 029/107] change some types --- repository/statistics/statistics.go | 60 +++++++++++++++++++---------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index c3e4ca5..69eee0e 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -32,17 +32,17 @@ type DeviceStatReq struct { type DeviceStatResp struct { //ключ DeviceType значение процент - Device map[string]float64 // процентное соотношение DeviceType по всем ответам на опроc c res==true + Device map[string]int32 // процентное соотношение DeviceType по всем ответам на опроc c res==true // тоже самое тут только по OS и BROWSER - OS map[string]float64 - Browser map[string]float64 + OS map[string]int32 + Browser map[string]int32 } func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req DeviceStatReq) (DeviceStatResp, error) { resp := DeviceStatResp{ - Device: make(map[string]float64), - OS: make(map[string]float64), - Browser: make(map[string]float64), + Device: make(map[string]int32), + OS: make(map[string]int32), + Browser: make(map[string]int32), } allStatistics, err := r.queries.DeviceStatistics(ctx, sqlcgen.DeviceStatisticsParams{ @@ -55,27 +55,27 @@ func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req Devi } for _, stat := range allStatistics { - resp.Device[stat.DeviceType] = float64(stat.DevicePercentage) - resp.OS[stat.Os] = float64(stat.OsPercentage) - resp.Browser[stat.Browser] = float64(stat.BrowserPercentage) + resp.Device[stat.DeviceType] = stat.DevicePercentage + resp.OS[stat.Os] = stat.OsPercentage + resp.Browser[stat.Browser] = stat.BrowserPercentage } return resp, nil } type GeneralStatsResp struct { - Open map[uint64]uint64 // количество ответов с полем start == true за период от одного пункта разбиения и до другого - Result map[uint64]uint64 // количество ответов с полем result == true за период от одного пункта разбиения и до другого - AvTime map[uint64]uint64 // среднее время между ответом с полем result == true и start == true. в рамках сессии - Conversion map[uint64]uint64 // Result/Open за период от одного пункта разбиения и до другого + Open map[int64]int64 // количество ответов с полем start == true за период от одного пункта разбиения и до другого + Result map[int64]int64 // количество ответов с полем result == true за период от одного пункта разбиения и до другого + AvTime map[int64]uint64 // среднее время между ответом с полем result == true и start == true. в рамках сессии + Conversion map[int64]int32 // Result/Open за период от одного пункта разбиения и до другого } func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req DeviceStatReq) (GeneralStatsResp, error) { resp := GeneralStatsResp{ - Open: make(map[uint64]uint64), - Result: make(map[uint64]uint64), - AvTime: make(map[uint64]uint64), - Conversion: make(map[uint64]uint64), + Open: make(map[int64]int64), + Result: make(map[int64]int64), + AvTime: make(map[int64]uint64), + Conversion: make(map[int64]int32), } // todo затестить запрос нужно, когда на один тру ответ приходится один тру старт апдейтнуть запрос allStatistics, err := r.queries.GeneralStatistics(ctx, sqlcgen.GeneralStatisticsParams{ @@ -88,11 +88,29 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev } for _, stat := range allStatistics { - resp.Open[uint64(stat.TimeBucket.Unix())] = uint64(stat.OpenCount) - resp.Result[uint64(stat.TimeBucket.Unix())] = uint64(stat.ResultCount) - resp.AvTime[uint64(stat.TimeBucket.Unix())] = uint64(stat.AvgTime) - resp.Conversion[uint64(stat.TimeBucket.Unix())] = uint64(stat.Conversion) + resp.Open[stat.TimeBucket.Unix()] = stat.OpenCount + resp.Result[stat.TimeBucket.Unix()] = stat.ResultCount + resp.AvTime[stat.TimeBucket.Unix()] = uint64(stat.AvgTime) + resp.Conversion[stat.TimeBucket.Unix()] = stat.Conversion } return resp, nil } + +type QuestionsStatsResp struct { + //Funnel 3 отдельных метрики + // 0 - количество сессий с любым ответом кроме start == true / количество сессий с ответом start == true + // 1 - количество сессий с result == false, но тип вопроса, на который ответ == result / количество сессий с ответом start == true + // 2 - количество сессий с ответом result == true / количество сессий с ответом start == true + Funnel [3]float64 + // ключ - заголовок вопроса найденного по айдишнику вопроса в ответе result == true, + // значение - процент ответов с result == true и таким айдишником вопроса + Results map[string]float64 + // ключ - заголовок вопроса, а значение - map, где ключ - вариант ответа на этот вопрос, + // т.е. группировка по полю Контент, а значение - процент таких ответов + Questions map[string]map[string]float64 +} + +func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req DeviceStatReq) (QuestionsStatsResp, error) { + +} From ca9f6ee46cfbbb23134dc478e51c59d2413780f7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 17:41:24 +0300 Subject: [PATCH 030/107] add question stat query --- dal/db_query/queries.sql | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 6a29cb1..1859c04 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -478,3 +478,86 @@ FROM ResultStats rs ON tb.time_interval = rs.time_interval LEFT JOIN AvTimeStats at ON tb.time_interval = at.time_interval; + +-- name: QuestionsStatistics :many +WITH Funnel AS ( + SELECT + COUNT(DISTINCT session) FILTER (WHERE a.start = FALSE) AS count_start_false, + COUNT(DISTINCT session) FILTER (WHERE a.start = TRUE) AS count_start_true, + COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN session END) AS count_f_result_with_t_question, + COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN session END) AS count_t_start_with_t_question, + COUNT(DISTINCT session) FILTER (WHERE a.result = TRUE) AS count_t_result + FROM + answer a + LEFT JOIN ( + SELECT DISTINCT a.session, q.id AS qid_true_result + FROM answer a + JOIN question q ON a.question_id = q.id + WHERE a.result = TRUE + ) AS q ON a.session = q.session + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) +), + Results AS ( + SELECT + q.title AS question_title, + COUNT(*)::FLOAT / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE), 0) AS percentage + FROM + answer a + JOIN + question q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = TRUE + GROUP BY + q.id, q.title + HAVING + COUNT(*) >= 1 + ), + Questions AS ( + SELECT + q.title AS question_title, + a.content AS answer_content, + COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + FROM + answer a + JOIN ( + SELECT q.id, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(*) >= 1 + ) +SELECT + Funnel.count_start_false, + Funnel.count_start_true, + Funnel.count_f_result_with_t_question, + Funnel.count_t_start_with_t_question, + Funnel.count_t_result, + Funnel.count_start_true, + Results.question_title AS results_question_title, + Results.percentage AS results_percentage, + Questions.question_title AS questions_question_title, + Questions.answer_content AS questions_answer_content, + Questions.percentage AS questions_percentage +FROM + Funnel, + Results, + Questions; + + From 75eaec5e332ec9294c1e3d5a269a3b49f8d58612 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 17:55:20 +0300 Subject: [PATCH 031/107] update sqlc gen --- dal/db_query/queries.sql | 5 +- dal/sqlcgen/queries.sql.go | 138 +++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1859c04..3447961 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -520,19 +520,20 @@ WITH Funnel AS ( ), Questions AS ( SELECT + q.id, q.title AS question_title, a.content AS answer_content, COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage FROM answer a JOIN ( - SELECT q.id, COUNT(*) AS total_answers + SELECT q.id, q.title, COUNT(*) AS total_answers FROM question q JOIN answer a ON q.id = a.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id + GROUP BY q.id, q.title ) q ON a.question_id = q.id WHERE a.quiz_id = $1 diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8afc21d..79a8fc1 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1573,6 +1573,144 @@ func (q *Queries) MoveToHistoryQuiz(ctx context.Context, arg MoveToHistoryQuizPa return i, err } +const questionsStatistics = `-- name: QuestionsStatistics :many +WITH Funnel AS ( + SELECT + COUNT(DISTINCT session) FILTER (WHERE a.start = FALSE) AS count_start_false, + COUNT(DISTINCT session) FILTER (WHERE a.start = TRUE) AS count_start_true, + COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN session END) AS count_f_result_with_t_question, + COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN session END) AS count_t_start_with_t_question, + COUNT(DISTINCT session) FILTER (WHERE a.result = TRUE) AS count_t_result + FROM + answer a + LEFT JOIN ( + SELECT DISTINCT a.session, q.id AS qid_true_result + FROM answer a + JOIN question q ON a.question_id = q.id + WHERE a.result = TRUE + ) AS q ON a.session = q.session + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) +), + Results AS ( + SELECT + q.title AS question_title, + COUNT(*)::FLOAT / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE), 0) AS percentage + FROM + answer a + JOIN + question q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = TRUE + GROUP BY + q.id, q.title + HAVING + COUNT(*) >= 1 + ), + Questions AS ( + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(*) >= 1 + ) +SELECT + Funnel.count_start_false, + Funnel.count_start_true, + Funnel.count_f_result_with_t_question, + Funnel.count_t_start_with_t_question, + Funnel.count_t_result, + Funnel.count_start_true, + Results.question_title AS results_question_title, + Results.percentage AS results_percentage, + Questions.question_title AS questions_question_title, + Questions.answer_content AS questions_answer_content, + Questions.percentage AS questions_percentage +FROM + Funnel, + Results, + Questions +` + +type QuestionsStatisticsParams struct { + QuizID int64 `db:"quiz_id" json:"quiz_id"` + ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` + ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` +} + +type QuestionsStatisticsRow struct { + CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` + CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` + CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` + CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` + CountTResult int64 `db:"count_t_result" json:"count_t_result"` + CountStartTrue_2 int64 `db:"count_start_true_2" json:"count_start_true_2"` + ResultsQuestionTitle string `db:"results_question_title" json:"results_question_title"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + QuestionsQuestionTitle string `db:"questions_question_title" json:"questions_question_title"` + QuestionsAnswerContent sql.NullString `db:"questions_answer_content" json:"questions_answer_content"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` +} + +func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { + rows, err := q.db.QueryContext(ctx, questionsStatistics, arg.QuizID, arg.ToTimestamp, arg.ToTimestamp_2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []QuestionsStatisticsRow + for rows.Next() { + var i QuestionsStatisticsRow + if err := rows.Scan( + &i.CountStartFalse, + &i.CountStartTrue, + &i.CountFResultWithTQuestion, + &i.CountTStartWithTQuestion, + &i.CountTResult, + &i.CountStartTrue_2, + &i.ResultsQuestionTitle, + &i.ResultsPercentage, + &i.QuestionsQuestionTitle, + &i.QuestionsAnswerContent, + &i.QuestionsPercentage, + ); 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 softDeleteResultByID = `-- name: SoftDeleteResultByID :exec UPDATE answer SET deleted = TRUE WHERE id = $1 AND deleted = FALSE ` From 120675f27add24244a3d65c118fcbb8dbf8c741c Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 17:58:18 +0300 Subject: [PATCH 032/107] update sqlc gen --- dal/db_query/queries.sql | 6 +++--- dal/sqlcgen/queries.sql.go | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 3447961..43e7daa 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -551,10 +551,10 @@ SELECT Funnel.count_t_start_with_t_question, Funnel.count_t_result, Funnel.count_start_true, - Results.question_title AS results_question_title, + Results.question_title AS results_title, Results.percentage AS results_percentage, - Questions.question_title AS questions_question_title, - Questions.answer_content AS questions_answer_content, + Questions.question_title AS questions_title, + Questions.answer_content AS answer_content, Questions.percentage AS questions_percentage FROM Funnel, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 79a8fc1..cd9cf2d 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1645,10 +1645,10 @@ SELECT Funnel.count_t_start_with_t_question, Funnel.count_t_result, Funnel.count_start_true, - Results.question_title AS results_question_title, + Results.question_title AS results_title, Results.percentage AS results_percentage, - Questions.question_title AS questions_question_title, - Questions.answer_content AS questions_answer_content, + Questions.question_title AS questions_title, + Questions.answer_content AS answer_content, Questions.percentage AS questions_percentage FROM Funnel, @@ -1669,10 +1669,10 @@ type QuestionsStatisticsRow struct { CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` CountStartTrue_2 int64 `db:"count_start_true_2" json:"count_start_true_2"` - ResultsQuestionTitle string `db:"results_question_title" json:"results_question_title"` + ResultsTitle string `db:"results_title" json:"results_title"` ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` - QuestionsQuestionTitle string `db:"questions_question_title" json:"questions_question_title"` - QuestionsAnswerContent sql.NullString `db:"questions_answer_content" json:"questions_answer_content"` + QuestionsTitle string `db:"questions_title" json:"questions_title"` + AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` } @@ -1692,10 +1692,10 @@ func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisti &i.CountTStartWithTQuestion, &i.CountTResult, &i.CountStartTrue_2, - &i.ResultsQuestionTitle, + &i.ResultsTitle, &i.ResultsPercentage, - &i.QuestionsQuestionTitle, - &i.QuestionsAnswerContent, + &i.QuestionsTitle, + &i.AnswerContent, &i.QuestionsPercentage, ); err != nil { return nil, err From df742260048174f79961327d97dc61659325f310 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:08:51 +0300 Subject: [PATCH 033/107] update sqlc gen --- dal/db_query/queries.sql | 1 - dal/sqlcgen/queries.sql.go | 3 --- 2 files changed, 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 43e7daa..0e41764 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -550,7 +550,6 @@ SELECT Funnel.count_f_result_with_t_question, Funnel.count_t_start_with_t_question, Funnel.count_t_result, - Funnel.count_start_true, Results.question_title AS results_title, Results.percentage AS results_percentage, Questions.question_title AS questions_title, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index cd9cf2d..9498643 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1644,7 +1644,6 @@ SELECT Funnel.count_f_result_with_t_question, Funnel.count_t_start_with_t_question, Funnel.count_t_result, - Funnel.count_start_true, Results.question_title AS results_title, Results.percentage AS results_percentage, Questions.question_title AS questions_title, @@ -1668,7 +1667,6 @@ type QuestionsStatisticsRow struct { CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` - CountStartTrue_2 int64 `db:"count_start_true_2" json:"count_start_true_2"` ResultsTitle string `db:"results_title" json:"results_title"` ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` @@ -1691,7 +1689,6 @@ func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisti &i.CountFResultWithTQuestion, &i.CountTStartWithTQuestion, &i.CountTResult, - &i.CountStartTrue_2, &i.ResultsTitle, &i.ResultsPercentage, &i.QuestionsTitle, From d3c21151d38a08761e62dff47205b63f73892d1e Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:17:57 +0300 Subject: [PATCH 034/107] update repo method --- repository/statistics/statistics.go | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 69eee0e..8b02fd7 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -3,6 +3,7 @@ package statistics import ( "context" "database/sql" + "fmt" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "time" ) @@ -98,6 +99,7 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev } type QuestionsStatsResp struct { + // PS это / не или а делить а то я спустя пару часов только догнал //Funnel 3 отдельных метрики // 0 - количество сессий с любым ответом кроме start == true / количество сессий с ответом start == true // 1 - количество сессий с result == false, но тип вопроса, на который ответ == result / количество сессий с ответом start == true @@ -112,5 +114,34 @@ type QuestionsStatsResp struct { } func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req DeviceStatReq) (QuestionsStatsResp, error) { + resp := QuestionsStatsResp{ + Funnel: [3]float64{}, + Results: make(map[string]float64), + Questions: make(map[string]map[string]float64), + } + queStatistics, err := r.queries.QuestionsStatistics(ctx, sqlcgen.QuestionsStatisticsParams{ + QuizID: req.QuizId, + ToTimestamp: float64(req.From), + ToTimestamp_2: float64(req.To), + }) + if err != nil { + return resp, err + } + + for _, row := range queStatistics { + resp.Funnel[0] = float64(row.CountStartFalse) / float64(row.CountStartTrue) + resp.Funnel[1] = float64(row.CountFResultWithTQuestion) / float64(row.CountStartTrue) + resp.Funnel[2] = float64(row.CountTResult) / float64(row.CountStartTrue) + + fmt.Println(resp.Funnel) + resp.Results[row.ResultsTitle] = float64(row.ResultsPercentage) + + if resp.Questions[row.QuestionsTitle] == nil { + resp.Questions[row.QuestionsTitle] = make(map[string]float64) + } + resp.Questions[row.QuestionsTitle][row.AnswerContent.String] = float64(row.QuestionsPercentage) + } + + return resp, nil } From 1c89273461c56f364a642cf983a01af47c3150a1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:24:23 +0300 Subject: [PATCH 035/107] add question stat query --- dal/db_query/queries.sql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 0e41764..d80e17d 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -482,11 +482,11 @@ FROM -- name: QuestionsStatistics :many WITH Funnel AS ( SELECT - COUNT(DISTINCT session) FILTER (WHERE a.start = FALSE) AS count_start_false, - COUNT(DISTINCT session) FILTER (WHERE a.start = TRUE) AS count_start_true, - COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN session END) AS count_f_result_with_t_question, - COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN session END) AS count_t_start_with_t_question, - COUNT(DISTINCT session) FILTER (WHERE a.result = TRUE) AS count_t_result + COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false, + COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true, + COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question, + COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN a.session END) AS count_t_start_with_t_question, + COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result FROM answer a LEFT JOIN ( From cb6dafbc2b7174473afac8c5a32f3f85e9e7a011 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:25:46 +0300 Subject: [PATCH 036/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 9498643..f176a43 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1576,11 +1576,11 @@ func (q *Queries) MoveToHistoryQuiz(ctx context.Context, arg MoveToHistoryQuizPa const questionsStatistics = `-- name: QuestionsStatistics :many WITH Funnel AS ( SELECT - COUNT(DISTINCT session) FILTER (WHERE a.start = FALSE) AS count_start_false, - COUNT(DISTINCT session) FILTER (WHERE a.start = TRUE) AS count_start_true, - COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN session END) AS count_f_result_with_t_question, - COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN session END) AS count_t_start_with_t_question, - COUNT(DISTINCT session) FILTER (WHERE a.result = TRUE) AS count_t_result + COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false, + COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true, + COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question, + COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN a.session END) AS count_t_start_with_t_question, + COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result FROM answer a LEFT JOIN ( From 00496d90068ce8028be37ca8bebc10fdf97c2ba8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:35:54 +0300 Subject: [PATCH 037/107] update sqlc gen --- dal/db_query/queries.sql | 20 ++++++++++++++++++-- dal/sqlcgen/queries.sql.go | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d80e17d..76351a2 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -500,21 +500,37 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) ), + TotalAnswers AS ( + SELECT + q.id AS question_id, + COUNT(*) AS total_answers + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id + ), Results AS ( SELECT q.title AS question_title, - COUNT(*)::FLOAT / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE), 0) AS percentage + COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage FROM answer a JOIN question q ON a.question_id = q.id + JOIN + TotalAnswers ta ON q.id = ta.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title + q.id, q.title, ta.total_answers HAVING COUNT(*) >= 1 ), diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index f176a43..5c65a33 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1594,21 +1594,37 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) ), + TotalAnswers AS ( + SELECT + q.id AS question_id, + COUNT(*) AS total_answers + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id + ), Results AS ( SELECT q.title AS question_title, - COUNT(*)::FLOAT / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE), 0) AS percentage + COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage FROM answer a JOIN question q ON a.question_id = q.id + JOIN + TotalAnswers ta ON q.id = ta.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title + q.id, q.title, ta.total_answers HAVING COUNT(*) >= 1 ), From 069caed142df928565cd4f39894820ac0baf23b8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:43:09 +0300 Subject: [PATCH 038/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 76351a2..d808e06 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -530,7 +530,7 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title, ta.total_answers + q.id, q.title HAVING COUNT(*) >= 1 ), diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 5c65a33..439387a 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1624,7 +1624,7 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title, ta.total_answers + q.id, q.title HAVING COUNT(*) >= 1 ), From 7ed22688936bb5c826ab8153397536e2758d4aad Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:50:46 +0300 Subject: [PATCH 039/107] update sqlc gen --- dal/db_query/queries.sql | 5 ++--- dal/sqlcgen/queries.sql.go | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d808e06..7ba7895 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -517,6 +517,7 @@ WITH Funnel AS ( Results AS ( SELECT q.title AS question_title, + ta.total_answers, COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage FROM answer a @@ -530,7 +531,7 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title + q.id, q.title, ta.total_answers HAVING COUNT(*) >= 1 ), @@ -575,5 +576,3 @@ FROM Funnel, Results, Questions; - - diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 439387a..3fd290c 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1611,6 +1611,7 @@ WITH Funnel AS ( Results AS ( SELECT q.title AS question_title, + ta.total_answers, COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage FROM answer a @@ -1624,7 +1625,7 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) AND a.result = TRUE GROUP BY - q.id, q.title + q.id, q.title, ta.total_answers HAVING COUNT(*) >= 1 ), From 0bfe1b73787bfc988a4112fdaa264cfe0115b574 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 18:57:18 +0300 Subject: [PATCH 040/107] update sqlc gen --- dal/db_query/queries.sql | 50 +++++++++++++++++++------------------- dal/sqlcgen/queries.sql.go | 50 +++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 7ba7895..df1c330 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -536,31 +536,31 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(*) >= 1 - ) + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content, q.total_answers + HAVING + COUNT(*) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 3fd290c..cddf33d 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1630,31 +1630,31 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(*) >= 1 - ) + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content, q.total_answers + HAVING + COUNT(*) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, From e2ae058c478801eeb11fe396cc6b9aacfd69c3f0 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:03:19 +0300 Subject: [PATCH 041/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index df1c330..f38204b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -540,7 +540,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index cddf33d..e720399 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1634,7 +1634,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( From 153d15351a3db2c90abb3b2b621161e14f29bcbf Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:23:42 +0300 Subject: [PATCH 042/107] update sqlc gen --- dal/db_query/queries.sql | 62 ++++++++++++++++++++---------------- dal/sqlcgen/queries.sql.go | 64 +++++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 55 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index f38204b..d1754fd 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -518,7 +518,10 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage + CASE + WHEN ta.total_answers = 0 THEN NULL + ELSE COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) + END AS percentage FROM answer a JOIN @@ -536,31 +539,34 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content, q.total_answers - HAVING - COUNT(*) >= 1 - ) + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + CASE + WHEN q.total_answers = 0 THEN NULL + ELSE COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) + END AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content, q.total_answers + HAVING + COUNT(*) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, @@ -575,4 +581,6 @@ SELECT FROM Funnel, Results, - Questions; + Questions +WHERE + Questions.percentage >= 1; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index e720399..b93a8f6 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1612,7 +1612,10 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS percentage + CASE + WHEN ta.total_answers = 0 THEN NULL + ELSE COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) + END AS percentage FROM answer a JOIN @@ -1630,31 +1633,34 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content, q.total_answers - HAVING - COUNT(*) >= 1 - ) + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + CASE + WHEN q.total_answers = 0 THEN NULL + ELSE COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) + END AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content, q.total_answers + HAVING + COUNT(*) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, @@ -1670,6 +1676,8 @@ FROM Funnel, Results, Questions +WHERE + Questions.percentage >= 1 ` type QuestionsStatisticsParams struct { @@ -1685,10 +1693,10 @@ type QuestionsStatisticsRow struct { CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + ResultsPercentage interface{} `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage interface{} `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From 1748e7556cbcd996e65cde743edc09b0cd79d13a Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:27:04 +0300 Subject: [PATCH 043/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d1754fd..1a5d9a2 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -520,7 +520,7 @@ WITH Funnel AS ( ta.total_answers, CASE WHEN ta.total_answers = 0 THEN NULL - ELSE COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) + ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM answer a @@ -545,7 +545,7 @@ WITH Funnel AS ( a.content AS answer_content, CASE WHEN q.total_answers = 0 THEN NULL - ELSE COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) + ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM answer a diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index b93a8f6..eeeb2c5 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1614,7 +1614,7 @@ WITH Funnel AS ( ta.total_answers, CASE WHEN ta.total_answers = 0 THEN NULL - ELSE COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) + ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM answer a @@ -1639,7 +1639,7 @@ WITH Funnel AS ( a.content AS answer_content, CASE WHEN q.total_answers = 0 THEN NULL - ELSE COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) + ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM answer a @@ -1693,10 +1693,10 @@ type QuestionsStatisticsRow struct { CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage interface{} `db:"results_percentage" json:"results_percentage"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage interface{} `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From c349706f2758dfb195a8822349fd45161b2d1364 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:30:58 +0300 Subject: [PATCH 044/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1a5d9a2..8cc41a2 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -519,7 +519,7 @@ WITH Funnel AS ( q.title AS question_title, ta.total_answers, CASE - WHEN ta.total_answers = 0 THEN NULL + WHEN ta.total_answers = 0 THEN 0 ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM @@ -544,7 +544,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CASE - WHEN q.total_answers = 0 THEN NULL + WHEN q.total_answers = 0 THEN 0 ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index eeeb2c5..ac8886e 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1613,7 +1613,7 @@ WITH Funnel AS ( q.title AS question_title, ta.total_answers, CASE - WHEN ta.total_answers = 0 THEN NULL + WHEN ta.total_answers = 0 THEN 0 ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM @@ -1638,7 +1638,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CASE - WHEN q.total_answers = 0 THEN NULL + WHEN q.total_answers = 0 THEN 0 ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM From 48725054c7c237dcefe62a9bbbee98defd1e1bad Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:38:19 +0300 Subject: [PATCH 045/107] update repo method --- dal/db_query/queries.sql | 2 -- repository/statistics/statistics.go | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 8cc41a2..87c3ea4 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -485,7 +485,6 @@ WITH Funnel AS ( COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false, COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true, COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question, - COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN a.session END) AS count_t_start_with_t_question, COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result FROM answer a @@ -571,7 +570,6 @@ SELECT Funnel.count_start_false, Funnel.count_start_true, Funnel.count_f_result_with_t_question, - Funnel.count_t_start_with_t_question, Funnel.count_t_result, Results.question_title AS results_title, Results.percentage AS results_percentage, diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 8b02fd7..6701a4f 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -130,9 +130,11 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D } for _, row := range queStatistics { - resp.Funnel[0] = float64(row.CountStartFalse) / float64(row.CountStartTrue) - resp.Funnel[1] = float64(row.CountFResultWithTQuestion) / float64(row.CountStartTrue) - resp.Funnel[2] = float64(row.CountTResult) / float64(row.CountStartTrue) + if row.CountStartTrue != 0 { + resp.Funnel[0] = float64(row.CountStartFalse) / float64(row.CountStartTrue) + resp.Funnel[1] = float64(row.CountFResultWithTQuestion) / float64(row.CountStartTrue) + resp.Funnel[2] = float64(row.CountTResult) / float64(row.CountStartTrue) + } fmt.Println(resp.Funnel) resp.Results[row.ResultsTitle] = float64(row.ResultsPercentage) From 0dd33625c7df29af2fb5184b11aa0836da695549 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:39:50 +0300 Subject: [PATCH 046/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index ac8886e..c5663d1 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1579,7 +1579,6 @@ WITH Funnel AS ( COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false, COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true, COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question, - COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN a.session END) AS count_t_start_with_t_question, COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result FROM answer a @@ -1665,7 +1664,6 @@ SELECT Funnel.count_start_false, Funnel.count_start_true, Funnel.count_f_result_with_t_question, - Funnel.count_t_start_with_t_question, Funnel.count_t_result, Results.question_title AS results_title, Results.percentage AS results_percentage, @@ -1690,7 +1688,6 @@ type QuestionsStatisticsRow struct { CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` - CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` @@ -1712,7 +1709,6 @@ func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisti &i.CountStartFalse, &i.CountStartTrue, &i.CountFResultWithTQuestion, - &i.CountTStartWithTQuestion, &i.CountTResult, &i.ResultsTitle, &i.ResultsPercentage, From 20d0e1d127cce53d0d35b6090a7c89f4527e67b6 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:52:29 +0300 Subject: [PATCH 047/107] update repo method --- dal/db_query/queries.sql | 10 ++-------- repository/statistics/statistics.go | 2 -- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 87c3ea4..35e6ff8 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -517,10 +517,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CASE - WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN @@ -542,10 +539,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CASE - WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 6701a4f..a0d33ea 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -3,7 +3,6 @@ package statistics import ( "context" "database/sql" - "fmt" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "time" ) @@ -136,7 +135,6 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D resp.Funnel[2] = float64(row.CountTResult) / float64(row.CountStartTrue) } - fmt.Println(resp.Funnel) resp.Results[row.ResultsTitle] = float64(row.ResultsPercentage) if resp.Questions[row.QuestionsTitle] == nil { From 6d16c459255d7ae0535932f698e3bcbcfa44b539 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 19:54:08 +0300 Subject: [PATCH 048/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index c5663d1..172343f 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1611,10 +1611,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CASE - WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN @@ -1636,10 +1633,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CASE - WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( From a68161f19b04c9b16006704134151ac7d9db2df5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:05:29 +0300 Subject: [PATCH 049/107] update sqlc gen --- dal/db_query/queries.sql | 10 ++++++++-- dal/sqlcgen/queries.sql.go | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 35e6ff8..87c3ea4 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -517,7 +517,10 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage + CASE + WHEN ta.total_answers = 0 THEN 0 + ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) + END AS percentage FROM answer a JOIN @@ -539,7 +542,10 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + CASE + WHEN q.total_answers = 0 THEN 0 + ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) + END AS percentage FROM answer a JOIN ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 172343f..c5663d1 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1611,7 +1611,10 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage + CASE + WHEN ta.total_answers = 0 THEN 0 + ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) + END AS percentage FROM answer a JOIN @@ -1633,7 +1636,10 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + CASE + WHEN q.total_answers = 0 THEN 0 + ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) + END AS percentage FROM answer a JOIN ( From 42b3a36a7f8f7be597d42a45f2f7aea09c4539e5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:09:22 +0300 Subject: [PATCH 050/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 87c3ea4..12ac1f3 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -519,7 +519,7 @@ WITH Funnel AS ( ta.total_answers, CASE WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) + ELSE CAST(COUNT(*) * 100 / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM answer a @@ -544,7 +544,7 @@ WITH Funnel AS ( a.content AS answer_content, CASE WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) + ELSE CAST(COUNT(*) * 100 / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM answer a diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index c5663d1..111a73f 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1613,7 +1613,7 @@ WITH Funnel AS ( ta.total_answers, CASE WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(ta.total_answers, 0) AS INTEGER) + ELSE CAST(COUNT(*) * 100 / NULLIF(ta.total_answers, 0) AS INTEGER) END AS percentage FROM answer a @@ -1638,7 +1638,7 @@ WITH Funnel AS ( a.content AS answer_content, CASE WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS INTEGER) + ELSE CAST(COUNT(*) * 100 / NULLIF(q.total_answers, 0) AS INTEGER) END AS percentage FROM answer a From cd4fd4719630260d32fe47bfe3f616603dba513a Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:14:42 +0300 Subject: [PATCH 051/107] update sqlc gen --- dal/db_query/queries.sql | 10 ++-------- dal/sqlcgen/queries.sql.go | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 12ac1f3..35e6ff8 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -517,10 +517,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CASE - WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*) * 100 / NULLIF(ta.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN @@ -542,10 +539,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CASE - WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*) * 100 / NULLIF(q.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 111a73f..172343f 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1611,10 +1611,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, ta.total_answers, - CASE - WHEN ta.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*) * 100 / NULLIF(ta.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN @@ -1636,10 +1633,7 @@ WITH Funnel AS ( q.id, q.title AS question_title, a.content AS answer_content, - CASE - WHEN q.total_answers = 0 THEN 0 - ELSE CAST(COUNT(*) * 100 / NULLIF(q.total_answers, 0) AS INTEGER) - END AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a JOIN ( From 469ccf80e27cd876fef0bdd2d0e95ea6ece313c4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:28:55 +0300 Subject: [PATCH 052/107] update sqlc gen --- dal/db_query/queries.sql | 56 ++++++++++++++++------------- dal/sqlcgen/queries.sql.go | 74 ++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 59 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 35e6ff8..59bd829 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -535,31 +535,37 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content, q.total_answers - HAVING - COUNT(*) >= 1 - ) + SELECT + q.title AS question_title, + NULL AS answer_content, + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + FROM + answer a + JOIN ( + SELECT + q.id, + q.title, + COUNT(*) AS total_answers + FROM + question q + JOIN + answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.title, q.total_answers + HAVING + COUNT(*) >= 1 +) SELECT Funnel.count_start_false, Funnel.count_start_true, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 172343f..18da995 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1629,31 +1629,37 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.id, - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( - SELECT q.id, q.title, COUNT(*) AS total_answers - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content, q.total_answers - HAVING - COUNT(*) >= 1 - ) + SELECT + q.title AS question_title, + NULL AS answer_content, + CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + FROM + answer a + JOIN ( + SELECT + q.id, + q.title, + COUNT(*) AS total_answers + FROM + question q + JOIN + answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.title, q.total_answers + HAVING + COUNT(*) >= 1 +) SELECT Funnel.count_start_false, Funnel.count_start_true, @@ -1679,15 +1685,15 @@ type QuestionsStatisticsParams struct { } type QuestionsStatisticsRow struct { - CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` - CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` - CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` - CountTResult int64 `db:"count_t_result" json:"count_t_result"` - ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` - QuestionsTitle string `db:"questions_title" json:"questions_title"` - AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` + CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` + CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` + CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` + CountTResult int64 `db:"count_t_result" json:"count_t_result"` + ResultsTitle string `db:"results_title" json:"results_title"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + QuestionsTitle string `db:"questions_title" json:"questions_title"` + AnswerContent interface{} `db:"answer_content" json:"answer_content"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From 3c3445b8fcb6f49744482aec704533e35e8f49ae Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:32:41 +0300 Subject: [PATCH 053/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 59bd829..f5a1d78 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -537,7 +537,7 @@ WITH Funnel AS ( Questions AS ( SELECT q.title AS question_title, - NULL AS answer_content, + a.content AS answer_content, CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 18da995..44f8f59 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1631,7 +1631,7 @@ WITH Funnel AS ( Questions AS ( SELECT q.title AS question_title, - NULL AS answer_content, + a.content AS answer_content, CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage FROM answer a @@ -1685,15 +1685,15 @@ type QuestionsStatisticsParams struct { } type QuestionsStatisticsRow struct { - CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` - CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` - CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` - CountTResult int64 `db:"count_t_result" json:"count_t_result"` - ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` - QuestionsTitle string `db:"questions_title" json:"questions_title"` - AnswerContent interface{} `db:"answer_content" json:"answer_content"` - QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` + CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` + CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` + CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` + CountTResult int64 `db:"count_t_result" json:"count_t_result"` + ResultsTitle string `db:"results_title" json:"results_title"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + QuestionsTitle string `db:"questions_title" json:"questions_title"` + AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From 30e78b4dc5aac171b907d1c7d38ebf0b3e692008 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:35:47 +0300 Subject: [PATCH 054/107] update sqlc gen --- dal/db_query/queries.sql | 5 +++-- dal/sqlcgen/queries.sql.go | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index f5a1d78..4e4f377 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -545,6 +545,7 @@ WITH Funnel AS ( SELECT q.id, q.title, + a.content, COUNT(*) AS total_answers FROM question q @@ -555,14 +556,14 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title + q.id, q.title, a.content ) q ON a.question_id = q.id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, q.total_answers + q.title, a.content, q.total_answers HAVING COUNT(*) >= 1 ) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 44f8f59..8cd7213 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1639,6 +1639,7 @@ WITH Funnel AS ( SELECT q.id, q.title, + a.content, COUNT(*) AS total_answers FROM question q @@ -1649,14 +1650,14 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title + q.id, q.title, a.content ) q ON a.question_id = q.id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, q.total_answers + q.title, a.content, q.total_answers HAVING COUNT(*) >= 1 ) From 716f49bc49b743abd8825e65f5f1861b5f4f23d8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:40:27 +0300 Subject: [PATCH 055/107] update sqlc gen --- dal/db_query/queries.sql | 3 +-- dal/sqlcgen/queries.sql.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 4e4f377..cb1f07f 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -545,7 +545,6 @@ WITH Funnel AS ( SELECT q.id, q.title, - a.content, COUNT(*) AS total_answers FROM question q @@ -556,7 +555,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title, a.content + q.id, q.title ) q ON a.question_id = q.id WHERE a.quiz_id = $1 diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8cd7213..3363863 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1639,7 +1639,6 @@ WITH Funnel AS ( SELECT q.id, q.title, - a.content, COUNT(*) AS total_answers FROM question q @@ -1650,7 +1649,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title, a.content + q.id, q.title ) q ON a.question_id = q.id WHERE a.quiz_id = $1 From 7360a1350a0c00ba6c1bc71560d6a5f7b199331c Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 20:45:06 +0300 Subject: [PATCH 056/107] update sqlc gen --- dal/db_query/queries.sql | 7 +++---- dal/sqlcgen/queries.sql.go | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index cb1f07f..4236a0e 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -538,14 +538,13 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM answer a JOIN ( SELECT q.id, - q.title, - COUNT(*) AS total_answers + q.title FROM question q JOIN @@ -562,7 +561,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, a.content, q.total_answers + q.title, a.content, q.id HAVING COUNT(*) >= 1 ) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 3363863..fbcd217 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1632,14 +1632,13 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(q.total_answers, 0) AS INTEGER) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM answer a JOIN ( SELECT q.id, - q.title, - COUNT(*) AS total_answers + q.title FROM question q JOIN @@ -1656,7 +1655,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, a.content, q.total_answers + q.title, a.content, q.id HAVING COUNT(*) >= 1 ) From 0f05193fb55151cea5b74fb0db78d8a5bb0a53b2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:03:58 +0300 Subject: [PATCH 057/107] update sqlc gen --- dal/db_query/queries.sql | 30 ++++++++---------------------- dal/sqlcgen/queries.sql.go | 30 ++++++++---------------------- 2 files changed, 16 insertions(+), 44 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 4236a0e..a0dae11 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -535,36 +535,22 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( SELECT - q.id, - q.title + q.title AS question_title, + a.content AS answer_content, + COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage FROM question q - JOIN - answer a ON q.id = a.question_id + JOIN answer a ON q.id = a.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.title, a.content, q.id - HAVING - COUNT(*) >= 1 -) + q.id, q.title, a.content + HAVING + COUNT(a.id) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index fbcd217..2997da5 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1629,36 +1629,22 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage - FROM - answer a - JOIN ( SELECT - q.id, - q.title + q.title AS question_title, + a.content AS answer_content, + COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage FROM question q - JOIN - answer a ON q.id = a.question_id + JOIN answer a ON q.id = a.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.id, q.title - ) q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.title, a.content, q.id - HAVING - COUNT(*) >= 1 -) + q.id, q.title, a.content + HAVING + COUNT(a.id) >= 1 + ) SELECT Funnel.count_start_false, Funnel.count_start_true, From 847302fbff04007566ae083c0db15f4fa59943e9 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:10:10 +0300 Subject: [PATCH 058/107] update sqlc gen --- dal/db_query/queries.sql | 32 ++++++++++++++++---------------- dal/sqlcgen/queries.sql.go | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index a0dae11..5ebd771 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -535,22 +535,22 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(a.id) >= 1 - ) + SELECT + q.title AS question_title, + a.content AS answer_content, + COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(a.id) >= 1 +) SELECT Funnel.count_start_false, Funnel.count_start_true, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 2997da5..dc93c22 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1629,22 +1629,22 @@ WITH Funnel AS ( COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(a.id) >= 1 - ) + SELECT + q.title AS question_title, + a.content AS answer_content, + COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(a.id) >= 1 +) SELECT Funnel.count_start_false, Funnel.count_start_true, From defb8c20c9bb4f27c3fc3ac21ce9793c18ec15f3 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:13:02 +0300 Subject: [PATCH 059/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 5ebd771..3fa416b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -538,7 +538,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage + CAST(COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM question q JOIN answer a ON q.id = a.question_id diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index dc93c22..57c508a 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1632,7 +1632,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS percentage + CAST(COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM question q JOIN answer a ON q.id = a.question_id From 6f94e07575069f12efdb20536a7ebc93f8d41c6b Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:21:07 +0300 Subject: [PATCH 060/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 3fa416b..4b60c67 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -538,7 +538,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -549,7 +549,7 @@ WITH Funnel AS ( GROUP BY q.id, q.title, a.content HAVING - COUNT(a.id) >= 1 + COUNT(*) >= 1 ) SELECT Funnel.count_start_false, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 57c508a..8ea6044 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1632,7 +1632,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(a.id) * 100.0 / NULLIF(SUM(COUNT(a.id)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -1643,7 +1643,7 @@ WITH Funnel AS ( GROUP BY q.id, q.title, a.content HAVING - COUNT(a.id) >= 1 + COUNT(*) >= 1 ) SELECT Funnel.count_start_false, From 36ac5dc116efa3698de8bdfa68daf6af54a0403e Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:29:32 +0300 Subject: [PATCH 061/107] update sqlc gen --- dal/db_query/queries.sql | 7 ++++++- dal/sqlcgen/queries.sql.go | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 4b60c67..da5eb97 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -538,7 +538,12 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage + CASE + WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN + CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + ELSE + FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + END AS percentage FROM question q JOIN answer a ON q.id = a.question_id diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8ea6044..bd57dbf 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1632,7 +1632,12 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) AS INTEGER) AS percentage + CASE + WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN + CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + ELSE + FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + END AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -1678,7 +1683,7 @@ type QuestionsStatisticsRow struct { ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage interface{} `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From b2bfeb7a102e4eabef01e287b7de416fb1102889 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:33:20 +0300 Subject: [PATCH 062/107] update sqlc gen --- dal/db_query/queries.sql | 16 ++++++++++------ dal/sqlcgen/queries.sql.go | 18 +++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index da5eb97..03e6abe 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -538,12 +538,15 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CASE - WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN - CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - ELSE - FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - END AS percentage + CAST( + CASE + WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN + CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + ELSE + FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + END + AS INTEGER + ) AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -551,6 +554,7 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = FALSE GROUP BY q.id, q.title, a.content HAVING diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index bd57dbf..37e65af 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1632,12 +1632,15 @@ WITH Funnel AS ( SELECT q.title AS question_title, a.content AS answer_content, - CASE - WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN - CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - ELSE - FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - END AS percentage + CAST( + CASE + WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN + CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + ELSE + FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) + END + AS INTEGER + ) AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -1645,6 +1648,7 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = FALSE GROUP BY q.id, q.title, a.content HAVING @@ -1683,7 +1687,7 @@ type QuestionsStatisticsRow struct { ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage interface{} `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From 0cb27652d9604cc043c0fccb7b3e653e5fcd4cc7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:36:56 +0300 Subject: [PATCH 063/107] update sqlc gen --- dal/db_query/queries.sql | 8 +++++++- dal/sqlcgen/queries.sql.go | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 03e6abe..7d6aa29 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -554,7 +554,13 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND a.result = FALSE + AND q.id NOT IN ( + SELECT DISTINCT q.id + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.result = TRUE + ) GROUP BY q.id, q.title, a.content HAVING diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 37e65af..4634706 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1648,7 +1648,13 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND a.result = FALSE + AND q.id NOT IN ( + SELECT DISTINCT q.id + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.result = TRUE + ) GROUP BY q.id, q.title, a.content HAVING From 8dabb450b013ebbe90857bb849546c316714d609 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:42:03 +0300 Subject: [PATCH 064/107] update sqlc gen --- dal/db_query/queries.sql | 15 +-------------- dal/sqlcgen/queries.sql.go | 15 +-------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 7d6aa29..1dedf0d 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -539,13 +539,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - CASE - WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN - CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - ELSE - FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - END - AS INTEGER + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS INTEGER ) AS percentage FROM question q @@ -554,13 +548,6 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND q.id NOT IN ( - SELECT DISTINCT q.id - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.result = TRUE - ) GROUP BY q.id, q.title, a.content HAVING diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 4634706..26fd097 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1633,13 +1633,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - CASE - WHEN COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0) - TRUNC(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) >= 0.5 THEN - CEIL(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - ELSE - FLOOR(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) OVER (PARTITION BY q.id), 0)) - END - AS INTEGER + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS INTEGER ) AS percentage FROM question q @@ -1648,13 +1642,6 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND q.id NOT IN ( - SELECT DISTINCT q.id - FROM question q - JOIN answer a ON q.id = a.question_id - WHERE a.quiz_id = $1 - AND a.result = TRUE - ) GROUP BY q.id, q.title, a.content HAVING From a26edaed3d68c2d946753f09e98c6c16064d5487 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:48:19 +0300 Subject: [PATCH 065/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1dedf0d..7444268 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -539,7 +539,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS INTEGER + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS NUMERIC(10, 2) ) AS percentage FROM question q diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 26fd097..e1c6815 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1633,7 +1633,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS INTEGER + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS NUMERIC(10, 2) ) AS percentage FROM question q @@ -1680,7 +1680,7 @@ type QuestionsStatisticsRow struct { ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage string `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From a1e594113dc041f5ad958d89eb3ad859e337ae4c Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:49:49 +0300 Subject: [PATCH 066/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 7444268..d5d6187 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -539,7 +539,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS NUMERIC(10, 2) + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS DECIMAL(10, 2) ) AS percentage FROM question q diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index e1c6815..689939d 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1633,7 +1633,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS NUMERIC(10, 2) + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS DECIMAL(10, 2) ) AS percentage FROM question q From d65f806e0c554f286b9093a9a8057970ebd1577e Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 21:51:09 +0300 Subject: [PATCH 067/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d5d6187..28e5dc3 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -539,7 +539,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS DECIMAL(10, 2) + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 ) AS percentage FROM question q diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 689939d..3fb82b9 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1633,7 +1633,7 @@ WITH Funnel AS ( q.title AS question_title, a.content AS answer_content, CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS DECIMAL(10, 2) + COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 ) AS percentage FROM question q @@ -1680,7 +1680,7 @@ type QuestionsStatisticsRow struct { ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` - QuestionsPercentage string `db:"questions_percentage" json:"questions_percentage"` + QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"` } func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { From 195bb48824b9773a511d6a4688c9c90e0369ca1c Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:08:19 +0300 Subject: [PATCH 068/107] update repo method --- dal/db_query/queries.sql | 68 ++++++++++++----------------- repository/statistics/statistics.go | 2 +- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 28e5dc3..d64e675 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -499,59 +499,49 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) ), - TotalAnswers AS ( - SELECT - q.id AS question_id, - COUNT(*) AS total_answers - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id - ), Results AS ( SELECT q.title AS question_title, - ta.total_answers, - CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage + COUNT(*) AS total_answers, + CAST( + COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 + ) AS percentage FROM answer a - JOIN - question q ON a.question_id = q.id - JOIN - TotalAnswers ta ON q.id = ta.question_id + JOIN question q ON a.question_id = q.id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND a.result = TRUE + AND q.id IN ( + SELECT DISTINCT a.question_id + FROM answer a + WHERE a.quiz_id = $1 + AND a.result = TRUE + ) GROUP BY - q.id, q.title, ta.total_answers + q.id, q.title HAVING COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 - ) AS percentage - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(*) >= 1 + SELECT + q.title AS question_title, + a.content AS answer_content, + CAST( + COUNT(CASE WHEN a.result = FALSE THEN 1 END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 + ) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(*) >= 1 ) SELECT Funnel.count_start_false, diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index a0d33ea..5d7b6b0 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -140,7 +140,7 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D if resp.Questions[row.QuestionsTitle] == nil { resp.Questions[row.QuestionsTitle] = make(map[string]float64) } - resp.Questions[row.QuestionsTitle][row.AnswerContent.String] = float64(row.QuestionsPercentage) + resp.Questions[row.QuestionsTitle][row.AnswerContent.String] = row.QuestionsPercentage } return resp, nil From d95d690cbeb60f674204f91c877bf465f52938ec Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:10:11 +0300 Subject: [PATCH 069/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 70 ++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 3fb82b9..1853b7a 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1593,59 +1593,49 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) ), - TotalAnswers AS ( - SELECT - q.id AS question_id, - COUNT(*) AS total_answers - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id - ), Results AS ( SELECT q.title AS question_title, - ta.total_answers, - CAST(COUNT(*) * 100.0 / NULLIF(ta.total_answers, 0) AS INTEGER) AS percentage + COUNT(*) AS total_answers, + CAST( + COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 + ) AS percentage FROM answer a - JOIN - question q ON a.question_id = q.id - JOIN - TotalAnswers ta ON q.id = ta.question_id + JOIN question q ON a.question_id = q.id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - AND a.result = TRUE + AND q.id IN ( + SELECT DISTINCT a.question_id + FROM answer a + WHERE a.quiz_id = $1 + AND a.result = TRUE + ) GROUP BY - q.id, q.title, ta.total_answers + q.id, q.title HAVING COUNT(*) >= 1 ), Questions AS ( - SELECT - q.title AS question_title, - a.content AS answer_content, - CAST( - COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 - ) AS percentage - FROM - question q - JOIN answer a ON q.id = a.question_id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY - q.id, q.title, a.content - HAVING - COUNT(*) >= 1 + SELECT + q.title AS question_title, + a.content AS answer_content, + CAST( + COUNT(CASE WHEN a.result = FALSE THEN 1 END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 + ) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(*) >= 1 ) SELECT Funnel.count_start_false, @@ -1677,7 +1667,7 @@ type QuestionsStatisticsRow struct { CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + ResultsPercentage float64 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"` From 5f596d735888e72e0d6e92d57b999f5fe438c4f9 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:21:12 +0300 Subject: [PATCH 070/107] update sqlc gen --- dal/db_query/queries.sql | 40 +++++++++++++++--------------------- dal/sqlcgen/queries.sql.go | 42 +++++++++++++++----------------------- 2 files changed, 33 insertions(+), 49 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d64e675..7f6690b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -500,30 +500,22 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) ), Results AS ( - SELECT - q.title AS question_title, - COUNT(*) AS total_answers, - CAST( - COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 - ) AS percentage - FROM - answer a - JOIN question q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - AND q.id IN ( - SELECT DISTINCT a.question_id - FROM answer a - WHERE a.quiz_id = $1 - AND a.result = TRUE - ) - GROUP BY - q.id, q.title - HAVING - COUNT(*) >= 1 - ), + SELECT + q.title AS question_title, + COUNT(*) AS total_answers, + COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.title, a.quiz_id + HAVING + COUNT(*) >= 1 + ), Questions AS ( SELECT q.title AS question_title, diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 1853b7a..e3d6998 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1594,30 +1594,22 @@ WITH Funnel AS ( AND a.created_at <= TO_TIMESTAMP($3) ), Results AS ( - SELECT - q.title AS question_title, - COUNT(*) AS total_answers, - CAST( - COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = TRUE THEN 1 ELSE NULL END)) OVER (PARTITION BY q.id), 0) AS FLOAT8 - ) AS percentage - FROM - answer a - JOIN question q ON a.question_id = q.id - WHERE - a.quiz_id = $1 - AND a.created_at >= TO_TIMESTAMP($2) - AND a.created_at <= TO_TIMESTAMP($3) - AND q.id IN ( - SELECT DISTINCT a.question_id - FROM answer a - WHERE a.quiz_id = $1 - AND a.result = TRUE - ) - GROUP BY - q.id, q.title - HAVING - COUNT(*) >= 1 - ), + SELECT + q.title AS question_title, + COUNT(*) AS total_answers, + COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS percentage + FROM + question q + JOIN answer a ON q.id = a.question_id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.title, a.quiz_id + HAVING + COUNT(*) >= 1 + ), Questions AS ( SELECT q.title AS question_title, @@ -1667,7 +1659,7 @@ type QuestionsStatisticsRow struct { CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage float64 `db:"results_percentage" json:"results_percentage"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"` From 6218cbd69c29bc858692c5eb166e7af27de7c4bf Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:23:30 +0300 Subject: [PATCH 071/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 7f6690b..eca20b5 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -512,7 +512,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, a.quiz_id + q.title, a.quiz_id, a.result HAVING COUNT(*) >= 1 ), diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index e3d6998..4becfec 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1606,7 +1606,7 @@ WITH Funnel AS ( AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) GROUP BY - q.title, a.quiz_id + q.title, a.quiz_id, a.result HAVING COUNT(*) >= 1 ), From ad4a8f77dcac7a9de4b50334fb78d8404f80857e Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:25:41 +0300 Subject: [PATCH 072/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index eca20b5..66caf80 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -503,7 +503,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, COUNT(*) AS total_answers, - COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS FLOAT8) AS percentage FROM question q JOIN answer a ON q.id = a.question_id diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 4becfec..8ddd24a 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1597,7 +1597,7 @@ WITH Funnel AS ( SELECT q.title AS question_title, COUNT(*) AS total_answers, - COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS percentage + CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS FLOAT8) AS percentage FROM question q JOIN answer a ON q.id = a.question_id @@ -1659,7 +1659,7 @@ type QuestionsStatisticsRow struct { CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` CountTResult int64 `db:"count_t_result" json:"count_t_result"` ResultsTitle string `db:"results_title" json:"results_title"` - ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + ResultsPercentage float64 `db:"results_percentage" json:"results_percentage"` QuestionsTitle string `db:"questions_title" json:"questions_title"` AnswerContent sql.NullString `db:"answer_content" json:"answer_content"` QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"` From 4199ac7f22f0b8b67b58e6ec1852b5348feb297e Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:28:28 +0300 Subject: [PATCH 073/107] update sqlc gen --- dal/db_query/queries.sql | 1 + dal/sqlcgen/queries.sql.go | 1 + 2 files changed, 2 insertions(+) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 66caf80..3f9c2a9 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -511,6 +511,7 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = TRUE GROUP BY q.title, a.quiz_id, a.result HAVING diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8ddd24a..e4cc860 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1605,6 +1605,7 @@ WITH Funnel AS ( a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = TRUE GROUP BY q.title, a.quiz_id, a.result HAVING From 1051d9c504ee58581aecd778ee68d8f88e461b4a Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 22:39:52 +0300 Subject: [PATCH 074/107] finish que stats method --- repository/statistics/statistics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 5d7b6b0..686e089 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -135,7 +135,7 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D resp.Funnel[2] = float64(row.CountTResult) / float64(row.CountStartTrue) } - resp.Results[row.ResultsTitle] = float64(row.ResultsPercentage) + resp.Results[row.ResultsTitle] = row.ResultsPercentage if resp.Questions[row.QuestionsTitle] == nil { resp.Questions[row.QuestionsTitle] = make(map[string]float64) From 47da9211e628bdba0331eda4bcbf2d4f1c0857f1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 12:09:47 +0300 Subject: [PATCH 075/107] change type int to float --- dal/db_query/queries.sql | 6 +++--- repository/statistics/statistics.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 3f9c2a9..5677042 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -375,11 +375,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS device_percentage, OSStats.os, - CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS os_percentage, BrowserStats.browser, - CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS browser_percentage FROM DeviceStats, OSStats, diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 686e089..382c1f5 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -32,17 +32,17 @@ type DeviceStatReq struct { type DeviceStatResp struct { //ключ DeviceType значение процент - Device map[string]int32 // процентное соотношение DeviceType по всем ответам на опроc c res==true + Device map[string]float64 // процентное соотношение DeviceType по всем ответам на опроc c res==true // тоже самое тут только по OS и BROWSER - OS map[string]int32 - Browser map[string]int32 + OS map[string]float64 + Browser map[string]float64 } func (r *StatisticsRepository) GetDeviceStatistics(ctx context.Context, req DeviceStatReq) (DeviceStatResp, error) { resp := DeviceStatResp{ - Device: make(map[string]int32), - OS: make(map[string]int32), - Browser: make(map[string]int32), + Device: make(map[string]float64), + OS: make(map[string]float64), + Browser: make(map[string]float64), } allStatistics, err := r.queries.DeviceStatistics(ctx, sqlcgen.DeviceStatisticsParams{ From bf40791e859ec8202c9eb73b19260636574bbbef Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 23:20:55 +0300 Subject: [PATCH 076/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index e4cc860..90630a3 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -402,11 +402,11 @@ WITH DeviceStats AS ( ) SELECT DeviceStats.device_type, - CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS device_percentage, + CAST((DeviceStats.device_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS device_percentage, OSStats.os, - CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS os_percentage, + CAST((OSStats.os_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS os_percentage, BrowserStats.browser, - CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS INT) AS browser_percentage + CAST((BrowserStats.browser_count::FLOAT / TotalStats.total_count) * 100.0 AS FLOAT8) AS browser_percentage FROM DeviceStats, OSStats, @@ -421,12 +421,12 @@ type DeviceStatisticsParams struct { } type DeviceStatisticsRow struct { - DeviceType string `db:"device_type" json:"device_type"` - DevicePercentage int32 `db:"device_percentage" json:"device_percentage"` - Os string `db:"os" json:"os"` - OsPercentage int32 `db:"os_percentage" json:"os_percentage"` - Browser string `db:"browser" json:"browser"` - BrowserPercentage int32 `db:"browser_percentage" json:"browser_percentage"` + DeviceType string `db:"device_type" json:"device_type"` + DevicePercentage float64 `db:"device_percentage" json:"device_percentage"` + Os string `db:"os" json:"os"` + OsPercentage float64 `db:"os_percentage" json:"os_percentage"` + Browser string `db:"browser" json:"browser"` + BrowserPercentage float64 `db:"browser_percentage" json:"browser_percentage"` } func (q *Queries) DeviceStatistics(ctx context.Context, arg DeviceStatisticsParams) ([]DeviceStatisticsRow, error) { From 02735ebe967a3978895c479a67fd4315b47ca5fd Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 12:32:59 +0300 Subject: [PATCH 077/107] update general query --- dal/db_query/queries.sql | 59 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 5677042..b064e14 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -400,22 +400,21 @@ WITH TimeBucket AS ( SELECT tb.time_interval, COUNT(DISTINCT session) AS open_count - FROM - ( - SELECT - session, - MIN(created_at) AS first_start_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND start = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_starts - JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + FROM ( + SELECT + session, + MAX(created_at) AS first_start_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND start = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_starts + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -425,20 +424,20 @@ WITH TimeBucket AS ( COUNT(DISTINCT session) AS result_count FROM ( - SELECT - session, - MIN(created_at) AS first_result_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_results - JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + SELECT + session, + MAX(created_at) AS first_result_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_results + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), From f6f40665b234b7e0619564716c295ead705e8db7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 17 Mar 2024 23:43:24 +0300 Subject: [PATCH 078/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 59 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 90630a3..a2960b9 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -503,22 +503,21 @@ WITH TimeBucket AS ( SELECT tb.time_interval, COUNT(DISTINCT session) AS open_count - FROM - ( - SELECT - session, - MIN(created_at) AS first_start_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND start = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_starts - JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + FROM ( + SELECT + session, + MAX(created_at) AS first_start_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND start = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_starts + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval GROUP BY tb.time_interval ), @@ -528,20 +527,20 @@ WITH TimeBucket AS ( COUNT(DISTINCT session) AS result_count FROM ( - SELECT - session, - MIN(created_at) AS first_result_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_results - JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + SELECT + session, + MAX(created_at) AS first_result_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_results + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval GROUP BY tb.time_interval ), From 8d833fc7009a0d7fc2c3c1229b0e57c8083ade55 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 13:01:58 +0300 Subject: [PATCH 079/107] update sqlc gen --- dal/db_query/queries.sql | 109 +++++++++++++++++--------------- dal/sqlcgen/queries.sql.go | 123 ++++++++++++++++++++----------------- 2 files changed, 125 insertions(+), 107 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index b064e14..56e8ebd 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -392,91 +392,100 @@ WITH TimeBucket AS ( CASE WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) - END::TIMESTAMP AS time_interval + END::TIMESTAMP AS time_interval_start, + LEAD( + CASE + WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) + ELSE date_trunc('hour', timestamp_bucket) + END::TIMESTAMP + ) OVER (ORDER BY timestamp_bucket) AS time_interval_end FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT - tb.time_interval, + tb.time_interval_start, + tb.time_interval_end, COUNT(DISTINCT session) AS open_count - FROM ( - SELECT - session, - MAX(created_at) AS first_start_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND start = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_starts - JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + FROM + ( + SELECT + session, + MIN(created_at) AS first_start_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND start = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_starts + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) >= tb.time_interval_start + AND date_trunc('hour', first_starts.first_start_time) < tb.time_interval_end GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ), ResultStats AS ( SELECT - tb.time_interval, - COUNT(DISTINCT session) AS result_count + tb.time_interval_start, + tb.time_interval_end, + COUNT(*) AS true_result_count FROM - ( - SELECT - session, - MAX(created_at) AS first_result_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_results - JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + answer + JOIN TimeBucket tb ON date_trunc('hour', answer.created_at) >= tb.time_interval_start + AND date_trunc('hour', answer.created_at) < tb.time_interval_end + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ), AvTimeStats AS ( SELECT - tb.time_interval, + tb.time_interval_start, + tb.time_interval_end, AVG(EXTRACT(epoch FROM (a.created_at - b.created_at))) AS avg_time FROM answer a - JOIN - answer b ON a.session = b.session - JOIN - TimeBucket tb ON date_trunc('hour', a.created_at) = tb.time_interval + JOIN answer b ON a.session = b.session + JOIN TimeBucket tb ON date_trunc('hour', a.created_at) >= tb.time_interval_start + AND date_trunc('hour', a.created_at) < tb.time_interval_end WHERE a.quiz_id = $3 AND a.result = TRUE AND b.start = TRUE + AND b.quiz_id = $3 AND a.created_at >= $1::timestamp AND a.created_at <= $2::timestamp + AND b.created_at >= $1::timestamp + AND b.created_at <= $2::timestamp GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ) SELECT - tb.time_interval AS time_bucket, + tb.time_interval_start AS time_bucket, COALESCE(os.open_count, 0) AS open_count, - COALESCE(rs.result_count, 0) AS result_count, - COALESCE(at.avg_time, 0) AS avg_time, + COALESCE(rs.true_result_count, 0) AS true_result_count, CASE - WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) + WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.true_result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion, + COALESCE(at.avg_time, 0) AS avg_time FROM TimeBucket tb LEFT JOIN - OpenStats os ON tb.time_interval = os.time_interval + OpenStats os ON tb.time_interval_start = os.time_interval_start + AND tb.time_interval_end = os.time_interval_end LEFT JOIN - ResultStats rs ON tb.time_interval = rs.time_interval + ResultStats rs ON tb.time_interval_start = rs.time_interval_start + AND tb.time_interval_end = rs.time_interval_end LEFT JOIN - AvTimeStats at ON tb.time_interval = at.time_interval; + AvTimeStats at ON tb.time_interval_start = at.time_interval_start + AND tb.time_interval_end = at.time_interval_end; -- name: QuestionsStatistics :many WITH Funnel AS ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index a2960b9..4282ccf 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -495,91 +495,100 @@ WITH TimeBucket AS ( CASE WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) - END::TIMESTAMP AS time_interval + END::TIMESTAMP AS time_interval_start, + LEAD( + CASE + WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) + ELSE date_trunc('hour', timestamp_bucket) + END::TIMESTAMP + ) OVER (ORDER BY timestamp_bucket) AS time_interval_end FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT - tb.time_interval, + tb.time_interval_start, + tb.time_interval_end, COUNT(DISTINCT session) AS open_count - FROM ( - SELECT - session, - MAX(created_at) AS first_start_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND start = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_starts - JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) = tb.time_interval + FROM + ( + SELECT + session, + MIN(created_at) AS first_start_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND start = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_starts + JOIN TimeBucket tb ON date_trunc('hour', first_starts.first_start_time) >= tb.time_interval_start + AND date_trunc('hour', first_starts.first_start_time) < tb.time_interval_end GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ), ResultStats AS ( SELECT - tb.time_interval, - COUNT(DISTINCT session) AS result_count + tb.time_interval_start, + tb.time_interval_end, + COUNT(*) AS true_result_count FROM - ( - SELECT - session, - MAX(created_at) AS first_result_time - FROM - answer - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp - GROUP BY - session - ) AS first_results - JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) = tb.time_interval + answer + JOIN TimeBucket tb ON date_trunc('hour', answer.created_at) >= tb.time_interval_start + AND date_trunc('hour', answer.created_at) < tb.time_interval_end + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ), AvTimeStats AS ( SELECT - tb.time_interval, + tb.time_interval_start, + tb.time_interval_end, AVG(EXTRACT(epoch FROM (a.created_at - b.created_at))) AS avg_time FROM answer a - JOIN - answer b ON a.session = b.session - JOIN - TimeBucket tb ON date_trunc('hour', a.created_at) = tb.time_interval + JOIN answer b ON a.session = b.session + JOIN TimeBucket tb ON date_trunc('hour', a.created_at) >= tb.time_interval_start + AND date_trunc('hour', a.created_at) < tb.time_interval_end WHERE a.quiz_id = $3 AND a.result = TRUE AND b.start = TRUE + AND b.quiz_id = $3 AND a.created_at >= $1::timestamp AND a.created_at <= $2::timestamp + AND b.created_at >= $1::timestamp + AND b.created_at <= $2::timestamp GROUP BY - tb.time_interval + tb.time_interval_start, tb.time_interval_end ) SELECT - tb.time_interval AS time_bucket, + tb.time_interval_start AS time_bucket, COALESCE(os.open_count, 0) AS open_count, - COALESCE(rs.result_count, 0) AS result_count, - COALESCE(at.avg_time, 0) AS avg_time, + COALESCE(rs.true_result_count, 0) AS true_result_count, CASE - WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.result_count, 0) / COALESCE(os.open_count, 0) + WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.true_result_count, 0) / COALESCE(os.open_count, 0) ELSE 0 - END AS conversion + END AS conversion, + COALESCE(at.avg_time, 0) AS avg_time FROM TimeBucket tb LEFT JOIN - OpenStats os ON tb.time_interval = os.time_interval + OpenStats os ON tb.time_interval_start = os.time_interval_start + AND tb.time_interval_end = os.time_interval_end LEFT JOIN - ResultStats rs ON tb.time_interval = rs.time_interval + ResultStats rs ON tb.time_interval_start = rs.time_interval_start + AND tb.time_interval_end = rs.time_interval_end LEFT JOIN - AvTimeStats at ON tb.time_interval = at.time_interval + AvTimeStats at ON tb.time_interval_start = at.time_interval_start + AND tb.time_interval_end = at.time_interval_end ` type GeneralStatisticsParams struct { @@ -589,11 +598,11 @@ type GeneralStatisticsParams struct { } type GeneralStatisticsRow struct { - TimeBucket time.Time `db:"time_bucket" json:"time_bucket"` - OpenCount int64 `db:"open_count" json:"open_count"` - ResultCount int64 `db:"result_count" json:"result_count"` - AvgTime float64 `db:"avg_time" json:"avg_time"` - Conversion int32 `db:"conversion" json:"conversion"` + TimeBucket time.Time `db:"time_bucket" json:"time_bucket"` + OpenCount int64 `db:"open_count" json:"open_count"` + TrueResultCount int64 `db:"true_result_count" json:"true_result_count"` + Conversion int32 `db:"conversion" json:"conversion"` + AvgTime float64 `db:"avg_time" json:"avg_time"` } func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsParams) ([]GeneralStatisticsRow, error) { @@ -608,9 +617,9 @@ func (q *Queries) GeneralStatistics(ctx context.Context, arg GeneralStatisticsPa if err := rows.Scan( &i.TimeBucket, &i.OpenCount, - &i.ResultCount, - &i.AvgTime, + &i.TrueResultCount, &i.Conversion, + &i.AvgTime, ); err != nil { return nil, err } From a371a523c605a1bcf8b124605920ffd9c0e18a0f Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 13:05:06 +0300 Subject: [PATCH 080/107] update general query --- repository/statistics/statistics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 382c1f5..77ad210 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -89,7 +89,7 @@ func (r *StatisticsRepository) GetGeneralStatistics(ctx context.Context, req Dev for _, stat := range allStatistics { resp.Open[stat.TimeBucket.Unix()] = stat.OpenCount - resp.Result[stat.TimeBucket.Unix()] = stat.ResultCount + resp.Result[stat.TimeBucket.Unix()] = stat.TrueResultCount resp.AvTime[stat.TimeBucket.Unix()] = uint64(stat.AvgTime) resp.Conversion[stat.TimeBucket.Unix()] = stat.Conversion } From 77e522c61fb6bb6a3b71ab1fe50da1c61834c6cb Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 14:12:10 +0300 Subject: [PATCH 081/107] update general query --- dal/db_query/queries.sql | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 56e8ebd..6d46608 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -431,16 +431,24 @@ WITH TimeBucket AS ( SELECT tb.time_interval_start, tb.time_interval_end, - COUNT(*) AS true_result_count + COUNT(DISTINCT session) AS true_result_count FROM - answer - JOIN TimeBucket tb ON date_trunc('hour', answer.created_at) >= tb.time_interval_start - AND date_trunc('hour', answer.created_at) < tb.time_interval_end - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp + ( + SELECT + session, + MIN(created_at) AS first_result_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_results + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) >= tb.time_interval_start + AND date_trunc('hour', first_results.first_result_time) < tb.time_interval_end GROUP BY tb.time_interval_start, tb.time_interval_end ), From 8f4e2a087b294512cf1213a36e1946410ec5415d Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 14:13:31 +0300 Subject: [PATCH 082/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 4282ccf..d411b20 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -534,16 +534,24 @@ WITH TimeBucket AS ( SELECT tb.time_interval_start, tb.time_interval_end, - COUNT(*) AS true_result_count + COUNT(DISTINCT session) AS true_result_count FROM - answer - JOIN TimeBucket tb ON date_trunc('hour', answer.created_at) >= tb.time_interval_start - AND date_trunc('hour', answer.created_at) < tb.time_interval_end - WHERE - answer.quiz_id = $3 - AND result = TRUE - AND created_at >= $1::timestamp - AND created_at <= $2::timestamp + ( + SELECT + session, + MIN(created_at) AS first_result_time + FROM + answer + WHERE + answer.quiz_id = $3 + AND result = TRUE + AND created_at >= $1::timestamp + AND created_at <= $2::timestamp + GROUP BY + session + ) AS first_results + JOIN TimeBucket tb ON date_trunc('hour', first_results.first_result_time) >= tb.time_interval_start + AND date_trunc('hour', first_results.first_result_time) < tb.time_interval_end GROUP BY tb.time_interval_start, tb.time_interval_end ), From 47ff43a4597049c886f74e81a5391242e1c01100 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 14:26:44 +0300 Subject: [PATCH 083/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 6d46608..dfbbfd2 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -398,7 +398,7 @@ WITH TimeBucket AS ( WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) END::TIMESTAMP - ) OVER (ORDER BY timestamp_bucket) AS time_interval_end + ) OVER (ORDER BY timestamp_bucket) - interval '1 hour' AS time_interval_end FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index d411b20..47dc477 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -501,7 +501,7 @@ WITH TimeBucket AS ( WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) END::TIMESTAMP - ) OVER (ORDER BY timestamp_bucket) AS time_interval_end + ) OVER (ORDER BY timestamp_bucket) - interval '1 hour' AS time_interval_end FROM generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket ), From bb9068452254f679fa2a1446fc2db736f33ec879 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 Mar 2024 14:36:00 +0300 Subject: [PATCH 084/107] update sqlc gen --- dal/db_query/queries.sql | 4 ++-- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index dfbbfd2..875da0b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -398,9 +398,9 @@ WITH TimeBucket AS ( WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) END::TIMESTAMP - ) OVER (ORDER BY timestamp_bucket) - interval '1 hour' AS time_interval_end + ) OVER (ORDER BY timestamp_bucket) AS time_interval_end FROM - generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket + generate_series($1::timestamp with time zone, $2::timestamp with time zone, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 47dc477..0a2d578 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -501,9 +501,9 @@ WITH TimeBucket AS ( WHEN EXTRACT(epoch FROM $2::timestamp) - EXTRACT(epoch FROM $1::timestamp) > 172800 THEN date_trunc('day', timestamp_bucket) ELSE date_trunc('hour', timestamp_bucket) END::TIMESTAMP - ) OVER (ORDER BY timestamp_bucket) - interval '1 hour' AS time_interval_end + ) OVER (ORDER BY timestamp_bucket) AS time_interval_end FROM - generate_series($1::timestamp, $2::timestamp, '1 hour'::interval) AS timestamp_bucket + generate_series($1::timestamp with time zone, $2::timestamp with time zone, '1 hour'::interval) AS timestamp_bucket ), OpenStats AS ( SELECT From 718380f2de6edf1d5c61e7f0c72e6161f816ec83 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 19 Mar 2024 17:18:05 +0300 Subject: [PATCH 085/107] add move query --- dal/db_query/queries.sql | 28 ++++++++++++++++++++++++++++ repository/quiz/quiz.go | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 875da0b..f4de8b6 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -568,3 +568,31 @@ FROM Questions WHERE Questions.percentage >= 1; + +-- name: QuizMove :many +WITH copy AS ( + INSERT INTO quiz (qid, accountid,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) + SELECT + uuid_generate_v4(), + $2, + 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,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP, + questions_count,answers_count,average_time_passing + FROM + quiz + WHERE + qid = $1 + RETURNING id, qid +) +INSERT INTO question (quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at) +SELECT + cq.id,title,description,questiontype, required,deleted,page, + content,version,parent_ids,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP +FROM + question q + JOIN + copy cq ON q.quiz_id = cq.qid +WHERE + q.deleted = false +RETURNING cq.qid; \ No newline at end of file diff --git a/repository/quiz/quiz.go b/repository/quiz/quiz.go index 9df6892..6aa26a9 100644 --- a/repository/quiz/quiz.go +++ b/repository/quiz/quiz.go @@ -578,3 +578,7 @@ func (r *QuizRepository) GetQuizConfig(ctx context.Context, quizID uint64) (mode return config, row.Accountid, nil } + +func (r *QuizRepository) QuizMove(ctx context.Context, qID, accountID string) { + +} From 9b29570c026a62dd5a02a3b16ba1f3837e19ab79 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 19 Mar 2024 19:13:03 +0300 Subject: [PATCH 086/107] update sqlc gen --- dal/db_query/queries.sql | 62 +++++++++++++++++++-------------- dal/sqlcgen/queries.sql.go | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 25 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index f4de8b6..948ffe8 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -569,30 +569,42 @@ FROM WHERE Questions.percentage >= 1; --- name: QuizMove :many -WITH copy AS ( - INSERT INTO quiz (qid, accountid,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) - SELECT - uuid_generate_v4(), - $2, - 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,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP, - questions_count,answers_count,average_time_passing - FROM - quiz - WHERE - qid = $1 - RETURNING id, qid -) -INSERT INTO question (quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at) +-- name: QuizCopyQid :one +WITH original_quiz AS ( + SELECT id + FROM quiz + WHERE quiz.qid = $1 AND quiz.accountId = $2 +), + new_quiz AS ( + INSERT INTO quiz ( + accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id + ) + SELECT + accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id + FROM + quiz + WHERE + qid = $1 AND accountId = $2 + RETURNING id,qid + ) SELECT - cq.id,title,description,questiontype, required,deleted,page, - content,version,parent_ids,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP + original_quiz.id AS original_quiz_id, + new_quiz.id AS new_quiz_id, + new_quiz.qid AS original_qid FROM - question q - JOIN - copy cq ON q.quiz_id = cq.qid -WHERE - q.deleted = false -RETURNING cq.qid; \ No newline at end of file + original_quiz, new_quiz; + +-- name: CopyQuestionQuizID :exec +INSERT INTO question ( + quiz_id, title, description, questiontype, required, + page, content, version, parent_ids, created_at, updated_at +) +SELECT + $2, title, description, questiontype, required, + page, content, version, parent_ids, created_at, updated_at +FROM + question +WHERE + question.quiz_id = $1 AND deleted = false; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 0a2d578..8a9e2f8 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -172,6 +172,30 @@ func (q *Queries) CopyQuestion(ctx context.Context, arg CopyQuestionParams) (Cop return i, err } +const copyQuestionQuizID = `-- name: CopyQuestionQuizID :exec +INSERT INTO question ( + quiz_id, title, description, questiontype, required, + page, content, version, parent_ids, created_at, updated_at +) +SELECT + $2, title, description, questiontype, required, + page, content, version, parent_ids, created_at, updated_at +FROM + question +WHERE + question.quiz_id = $1 AND deleted = false +` + +type CopyQuestionQuizIDParams struct { + QuizID int64 `db:"quiz_id" json:"quiz_id"` + QuizID_2 int64 `db:"quiz_id_2" json:"quiz_id_2"` +} + +func (q *Queries) CopyQuestionQuizID(ctx context.Context, arg CopyQuestionQuizIDParams) error { + _, err := q.db.ExecContext(ctx, copyQuestionQuizID, arg.QuizID, arg.QuizID_2) + return err +} + const copyQuiz = `-- name: CopyQuiz :one INSERT INTO quiz( accountid, archived,fingerprinting,repeatable,note_prevented,mail_notifications,unique_answers,name,description,config, @@ -1715,6 +1739,52 @@ func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisti return items, nil } +const quizCopyQid = `-- name: QuizCopyQid :one +WITH original_quiz AS ( + SELECT id + FROM quiz + WHERE quiz.qid = $1 AND quiz.accountId = $2 +), + new_quiz AS ( + INSERT INTO quiz ( + accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id + ) + SELECT + accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id + FROM + quiz + WHERE + qid = $1 AND accountId = $2 + RETURNING id,qid + ) +SELECT + original_quiz.id AS original_quiz_id, + new_quiz.id AS new_quiz_id, + new_quiz.qid AS original_qid +FROM + original_quiz, new_quiz +` + +type QuizCopyQidParams struct { + Qid uuid.NullUUID `db:"qid" json:"qid"` + Accountid string `db:"accountid" json:"accountid"` +} + +type QuizCopyQidRow struct { + OriginalQuizID int64 `db:"original_quiz_id" json:"original_quiz_id"` + NewQuizID int64 `db:"new_quiz_id" json:"new_quiz_id"` + OriginalQid uuid.NullUUID `db:"original_qid" json:"original_qid"` +} + +func (q *Queries) QuizCopyQid(ctx context.Context, arg QuizCopyQidParams) (QuizCopyQidRow, error) { + row := q.db.QueryRowContext(ctx, quizCopyQid, arg.Qid, arg.Accountid) + var i QuizCopyQidRow + err := row.Scan(&i.OriginalQuizID, &i.NewQuizID, &i.OriginalQid) + return i, err +} + const softDeleteResultByID = `-- name: SoftDeleteResultByID :exec UPDATE answer SET deleted = TRUE WHERE id = $1 AND deleted = FALSE ` From 735ebe63cb8fc6659d39a60abf20e5d274691c25 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 19 Mar 2024 19:49:20 +0300 Subject: [PATCH 087/107] init repo method for QuizMove --- repository/quiz/quiz.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/repository/quiz/quiz.go b/repository/quiz/quiz.go index 6aa26a9..9512eeb 100644 --- a/repository/quiz/quiz.go +++ b/repository/quiz/quiz.go @@ -579,6 +579,30 @@ func (r *QuizRepository) GetQuizConfig(ctx context.Context, quizID uint64) (mode return config, row.Accountid, nil } -func (r *QuizRepository) QuizMove(ctx context.Context, qID, accountID string) { +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{ + QuizID: data.OriginalQuizID, + QuizID_2: data.NewQuizID, + }) + + if err != nil { + return "", err + } + + return data.OriginalQid.UUID.String(), err } From 88a0fe7e58a4792341cffcdaf0f3abf63b6e408d Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 20 Mar 2024 20:44:03 +0300 Subject: [PATCH 088/107] add create excel util --- utils/excel.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 utils/excel.go diff --git a/utils/excel.go b/utils/excel.go new file mode 100644 index 0000000..a69d5cc --- /dev/null +++ b/utils/excel.go @@ -0,0 +1,33 @@ +package utils + +import ( + "bytes" + "github.com/tealeg/xlsx" +) + +func CreateExcel(headers []string, data map[int]string) (*bytes.Buffer, error) { + file := xlsx.NewFile() + sheet, err := file.AddSheet("sheet1") + if err != nil { + return nil, err + } + + headerRow := sheet.AddRow() + for _, header := range headers { + cell := headerRow.AddCell() + cell.Value = header + } + + dataRow := sheet.AddRow() + for i := 0; i < len(headers); i++ { + cell := dataRow.AddCell() + cell.Value = data[i] + } + + buffer := new(bytes.Buffer) + if err := file.Write(buffer); err != nil { + return nil, err + } + + return buffer, nil +} From 33e5180c5fc6bd40d4fd28f9b36953f2bfd17cfb Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 22 Mar 2024 14:31:37 +0300 Subject: [PATCH 089/107] add GetQidOwner query --- dal/db_query/queries.sql | 3 +++ repository/account/account.go | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 948ffe8..08b9f90 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -608,3 +608,6 @@ FROM question WHERE question.quiz_id = $1 AND deleted = false; + +-- name: GetQidOwner :one +SELECT accountid FROM quiz where qid=$1; \ No newline at end of file diff --git a/repository/account/account.go b/repository/account/account.go index 1d93013..16a86e7 100644 --- a/repository/account/account.go +++ b/repository/account/account.go @@ -307,3 +307,12 @@ func (r *AccountRepository) GetAccAndPrivilegeByEmail(ctx context.Context, email return account, privileges, nil } + +func (r *AccountRepository) GetQidOwner(ctx context.Context, qId string) (string, error) { + userID, err := r.queries.GetQidOwner(ctx) + if err != nil { + return "", err + } + + return userID, nil +} From 0f69edc9d0159b0f833a04d5f5530d0a190c3921 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 19 Mar 2024 20:09:44 +0300 Subject: [PATCH 090/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8a9e2f8..d265e04 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -989,6 +989,17 @@ func (q *Queries) GetPrivilegesQuizAccount(ctx context.Context, id int64) ([]Get return items, nil } +const getQidOwner = `-- name: GetQidOwner :one +SELECT accountid FROM quiz where qid=$1 +` + +func (q *Queries) GetQidOwner(ctx context.Context, qid uuid.NullUUID) (string, error) { + row := q.db.QueryRowContext(ctx, getQidOwner, qid) + var accountid string + err := row.Scan(&accountid) + return accountid, err +} + const getQuestionHistory = `-- name: GetQuestionHistory :many SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at FROM question WHERE question.id = $1 OR question.id = ANY( SELECT unnest(parent_ids) FROM question WHERE id = $1 From 548b4612089a4ca4f4ac79fba2840675aba6991d Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 22 Mar 2024 14:36:13 +0300 Subject: [PATCH 091/107] add repo method GetQidOwner --- repository/account/account.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/repository/account/account.go b/repository/account/account.go index 16a86e7..9150d27 100644 --- a/repository/account/account.go +++ b/repository/account/account.go @@ -309,7 +309,14 @@ func (r *AccountRepository) GetAccAndPrivilegeByEmail(ctx context.Context, email } func (r *AccountRepository) GetQidOwner(ctx context.Context, qId string) (string, error) { - userID, err := r.queries.GetQidOwner(ctx) + qUUID, err := uuid.Parse(qId) + if err != nil { + return "", err + } + + qNullUUID := uuid.NullUUID{UUID: qUUID, Valid: true} + + userID, err := r.queries.GetQidOwner(ctx, qNullUUID) if err != nil { return "", err } From eef2c4353a43ab3e5f83f91d5cba33338d8eee66 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 22 Mar 2024 15:06:18 +0300 Subject: [PATCH 092/107] add decrypt and ecrypt --- utils/encrypted.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 utils/encrypted.go diff --git a/utils/encrypted.go b/utils/encrypted.go new file mode 100644 index 0000000..81fbd17 --- /dev/null +++ b/utils/encrypted.go @@ -0,0 +1,57 @@ +package utils + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +type Encrypt struct { + pubKey string + privKey string +} + +func NewEncrypt(pubKey, privKey string) *Encrypt { + return &Encrypt{pubKey: pubKey, privKey: privKey} +} + +func (e *Encrypt) EncryptStr(str string) (string, error) { + block, _ := pem.Decode([]byte(e.pubKey)) + if block == nil { + return "", errors.New("failed to parse PEM block containing the public key") + } + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return "", err + } + rsaPubKey, ok := pub.(*rsa.PublicKey) + if !ok { + return "", errors.New("failed to parse RSA public key") + } + + shifr, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPubKey, []byte(str)) + if err != nil { + return "", err + } + return string(shifr), nil +} + +func (e *Encrypt) DecryptStr(shifr string) (string, error) { + block, _ := pem.Decode([]byte(e.privKey)) + if block == nil { + return "", errors.New("failed to parse PEM block containing the private key") + } + + priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return "", err + } + + res, err := rsa.DecryptPKCS1v15(rand.Reader, priv, []byte(shifr)) + if err != nil { + return "", err + } + return string(res), nil +} From 95a2f52339d5b82901aacb8f571b71e7d56b7136 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 22 Mar 2024 15:36:36 +0300 Subject: [PATCH 093/107] update encrypt --- utils/encrypted.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/utils/encrypted.go b/utils/encrypted.go index 81fbd17..24034eb 100644 --- a/utils/encrypted.go +++ b/utils/encrypted.go @@ -17,28 +17,28 @@ func NewEncrypt(pubKey, privKey string) *Encrypt { return &Encrypt{pubKey: pubKey, privKey: privKey} } -func (e *Encrypt) EncryptStr(str string) (string, error) { +func (e *Encrypt) EncryptStr(str string) ([]byte, error) { block, _ := pem.Decode([]byte(e.pubKey)) if block == nil { - return "", errors.New("failed to parse PEM block containing the public key") + return nil, errors.New("failed to parse PEM block containing the public key") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return "", err + return nil, err } rsaPubKey, ok := pub.(*rsa.PublicKey) if !ok { - return "", errors.New("failed to parse RSA public key") + return nil, errors.New("failed to parse RSA public key") } shifr, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPubKey, []byte(str)) if err != nil { - return "", err + return nil, err } - return string(shifr), nil + return shifr, nil } -func (e *Encrypt) DecryptStr(shifr string) (string, error) { +func (e *Encrypt) DecryptStr(shifr []byte) (string, error) { block, _ := pem.Decode([]byte(e.privKey)) if block == nil { return "", errors.New("failed to parse PEM block containing the private key") @@ -49,7 +49,7 @@ func (e *Encrypt) DecryptStr(shifr string) (string, error) { return "", err } - res, err := rsa.DecryptPKCS1v15(rand.Reader, priv, []byte(shifr)) + res, err := rsa.DecryptPKCS1v15(rand.Reader, priv, shifr) if err != nil { return "", err } From bec22dd0b5b374f5637932134d5fb6d59af1327b Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 25 Mar 2024 11:30:06 +0300 Subject: [PATCH 094/107] add new AllServiceStatistics query --- dal/db_query/queries.sql | 23 ++++++++++++++++++++++- repository/statistics/statistics.go | 11 +++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 08b9f90..d7ca343 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -610,4 +610,25 @@ WHERE question.quiz_id = $1 AND deleted = false; -- name: GetQidOwner :one -SELECT accountid FROM quiz where qid=$1; \ No newline at end of file +SELECT accountid FROM quiz where qid=$1; + +-- name: AllServiceStatistics :one +WITH Registrations AS ( + SELECT COUNT(*) AS registration_count + FROM account + WHERE created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) +), + Quizes AS ( + SELECT COUNT(*) AS quiz_count + FROM quiz + WHERE deleted = false AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) + ), + Results AS ( + SELECT COUNT(*) AS result_count + FROM answer + WHERE result = true AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) + ) +SELECT + (SELECT registration_count FROM Registrations) AS registrations, + (SELECT quiz_count FROM Quizes) AS quizes, + (SELECT result_count FROM Results) AS results; \ No newline at end of file diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index 77ad210..e3bbad7 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -145,3 +145,14 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D return resp, nil } + +type StatisticResp struct { + // от from до to + Registrations uint64 // количество зарегестрированных аккаунтов + Quizes uint64 // количество созданных не удаленных квизов + Results uint64 // количество ответов с result = true +} + +func (r *StatisticsRepository) AllServiceStatistics(ctx context.Context, from, to uint64) (StatisticResp, error) { + allSvcStats, err := r.queries.AllServiceStatistics +} From 1b82e14c43459ee16b2bbe2648e227db97b7c96f Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 25 Mar 2024 11:34:07 +0300 Subject: [PATCH 095/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index d265e04..6b30d29 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -59,6 +59,46 @@ func (q *Queries) AccountPagination(ctx context.Context, arg AccountPaginationPa return items, nil } +const allServiceStatistics = `-- name: AllServiceStatistics :one +WITH Registrations AS ( + SELECT COUNT(*) AS registration_count + FROM account + WHERE created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) +), + Quizes AS ( + SELECT COUNT(*) AS quiz_count + FROM quiz + WHERE deleted = false AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) + ), + Results AS ( + SELECT COUNT(*) AS result_count + FROM answer + WHERE result = true AND created_at >= to_timestamp($1) AND created_at <= to_timestamp($2) + ) +SELECT + (SELECT registration_count FROM Registrations) AS registrations, + (SELECT quiz_count FROM Quizes) AS quizes, + (SELECT result_count FROM Results) AS results +` + +type AllServiceStatisticsParams struct { + ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` + ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` +} + +type AllServiceStatisticsRow struct { + Registrations int64 `db:"registrations" json:"registrations"` + Quizes int64 `db:"quizes" json:"quizes"` + Results int64 `db:"results" json:"results"` +} + +func (q *Queries) AllServiceStatistics(ctx context.Context, arg AllServiceStatisticsParams) (AllServiceStatisticsRow, error) { + row := q.db.QueryRowContext(ctx, allServiceStatistics, arg.ToTimestamp, arg.ToTimestamp_2) + var i AllServiceStatisticsRow + err := row.Scan(&i.Registrations, &i.Quizes, &i.Results) + return i, err +} + const archiveQuiz = `-- name: ArchiveQuiz :exec UPDATE quiz SET archived = true WHERE id=$1 AND accountId=$2 ` From 830f548708538fe375bca14b0c87f92e09a85c51 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 25 Mar 2024 11:41:16 +0300 Subject: [PATCH 096/107] init new method in statsRepo --- repository/statistics/statistics.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/repository/statistics/statistics.go b/repository/statistics/statistics.go index e3bbad7..2ae9789 100644 --- a/repository/statistics/statistics.go +++ b/repository/statistics/statistics.go @@ -148,11 +148,26 @@ func (r *StatisticsRepository) GetQuestionsStatistics(ctx context.Context, req D type StatisticResp struct { // от from до to - Registrations uint64 // количество зарегестрированных аккаунтов - Quizes uint64 // количество созданных не удаленных квизов - Results uint64 // количество ответов с result = true + Registrations int64 // количество зарегестрированных аккаунтов + Quizes int64 // количество созданных не удаленных квизов + Results int64 // количество ответов с result = true } func (r *StatisticsRepository) AllServiceStatistics(ctx context.Context, from, to uint64) (StatisticResp, error) { - allSvcStats, err := r.queries.AllServiceStatistics + allSvcStats, err := r.queries.AllServiceStatistics(ctx, sqlcgen.AllServiceStatisticsParams{ + ToTimestamp: float64(from), + ToTimestamp_2: float64(to), + }) + + if err != nil { + return StatisticResp{}, err + } + + resp := StatisticResp{ + Registrations: allSvcStats.Registrations, + Quizes: allSvcStats.Quizes, + Results: allSvcStats.Results, + } + + return resp, nil } From 4e42c241b062d3f4db7227ed26ea65f5aa006fce Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 27 Mar 2024 13:15:43 +0300 Subject: [PATCH 097/107] add new column for result content --- model/model.go | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/model/model.go b/model/model.go index cfb3689..cd0792a 100644 --- a/model/model.go +++ b/model/model.go @@ -133,20 +133,26 @@ type Answer struct { } type ResultContent struct { - Text string `json:"text"` - Name string `json:"name"` - Email string `json:"email"` - Phone string `json:"phone"` - Address string `json:"address"` - Telegram string `json:"telegram"` - Wechat string `json:"wechat"` - Viber string `json:"viber"` - Vk string `json:"vk"` - Skype string `json:"skype"` - Whatsup string `json:"whatsup"` - Messenger string `json:"messenger"` - Custom map[string]string `json:"customs"` - Start bool `json:"start"` + Text string `json:"text"` + Name string `json:"name"` + Email string `json:"email"` + Phone string `json:"phone"` + Address string `json:"address"` + Telegram string `json:"telegram"` + Wechat string `json:"wechat"` + Viber string `json:"viber"` + Vk string `json:"vk"` + Skype string `json:"skype"` + Whatsup string `json:"whatsup"` + Messenger string `json:"messenger"` + Custom map[string]string `json:"customs"` + Start bool `json:"start"` + IMGContent ImageContent `json:"imagecontent"` +} + +type ImageContent struct { + Description string + Image string } type ResultAnswer struct { From 416edf5094dbf972b5dbd8acb1ccf195d87f3a38 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 27 Mar 2024 17:35:06 +0300 Subject: [PATCH 098/107] fix --- model/model.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/model/model.go b/model/model.go index cd0792a..e5fcaea 100644 --- a/model/model.go +++ b/model/model.go @@ -133,21 +133,21 @@ type Answer struct { } type ResultContent struct { - Text string `json:"text"` - Name string `json:"name"` - Email string `json:"email"` - Phone string `json:"phone"` - Address string `json:"address"` - Telegram string `json:"telegram"` - Wechat string `json:"wechat"` - Viber string `json:"viber"` - Vk string `json:"vk"` - Skype string `json:"skype"` - Whatsup string `json:"whatsup"` - Messenger string `json:"messenger"` - Custom map[string]string `json:"customs"` - Start bool `json:"start"` - IMGContent ImageContent `json:"imagecontent"` + Text string `json:"text"` + Name string `json:"name"` + Email string `json:"email"` + Phone string `json:"phone"` + Address string `json:"address"` + Telegram string `json:"telegram"` + Wechat string `json:"wechat"` + Viber string `json:"viber"` + Vk string `json:"vk"` + Skype string `json:"skype"` + Whatsup string `json:"whatsup"` + Messenger string `json:"messenger"` + Custom map[string]string `json:"customs"` + Start bool `json:"start"` + //IMGContent ImageContent `json:"imagecontent"` } type ImageContent struct { From afb94fcb4941ab2974a9cc032f21023634c6c054 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 13:35:38 +0300 Subject: [PATCH 099/107] update query --- dal/db_query/queries.sql | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index d7ca343..e93772b 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -282,7 +282,18 @@ WHERE privilege_name = $2 AND (amount < $3 OR created_at <= NOW() - INTERVAL '1 month'); -- name: GetAllAnswersByQuizID :many -SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 AND start = false ORDER BY question_id ASC, created_at DESC; +SELECT DISTINCT ON (a.question_id) + a.content, a.created_at, a.question_id, a.id, q.questiontype, quiz.qid +FROM + answer a + JOIN + question q ON a.question_id = q.id + JOIN + quiz ON q.quiz_id = quiz.id +WHERE + a.session = $1 AND a.start = false AND a.deleted = false +ORDER BY + a.question_id ASC, a.created_at DESC; -- name: InsertAnswers :exec INSERT INTO answer( content, From 8957585976fd2e2f3624601acb185fd72bc55933 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 13:37:43 +0300 Subject: [PATCH 100/107] update sqlc gen --- dal/sqlcgen/queries.sql.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 6b30d29..9d6f574 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -807,14 +807,27 @@ func (q *Queries) GetAccountWithPrivileges(ctx context.Context, userID sql.NullS } const getAllAnswersByQuizID = `-- name: GetAllAnswersByQuizID :many -SELECT DISTINCT ON(question_id) content, created_at, question_id, id FROM answer WHERE session = $1 AND start = false ORDER BY question_id ASC, created_at DESC +SELECT DISTINCT ON (a.question_id) + a.content, a.created_at, a.question_id, a.id, q.questiontype, quiz.qid +FROM + answer a + JOIN + question q ON a.question_id = q.id + JOIN + quiz ON q.quiz_id = quiz.id +WHERE + a.session = $1 AND a.start = false AND a.deleted = false +ORDER BY + a.question_id ASC, a.created_at DESC ` type GetAllAnswersByQuizIDRow struct { - Content sql.NullString `db:"content" json:"content"` - CreatedAt sql.NullTime `db:"created_at" json:"created_at"` - QuestionID int64 `db:"question_id" json:"question_id"` - ID int64 `db:"id" json:"id"` + Content sql.NullString `db:"content" json:"content"` + CreatedAt sql.NullTime `db:"created_at" json:"created_at"` + QuestionID int64 `db:"question_id" json:"question_id"` + ID int64 `db:"id" json:"id"` + Questiontype interface{} `db:"questiontype" json:"questiontype"` + Qid uuid.NullUUID `db:"qid" json:"qid"` } func (q *Queries) GetAllAnswersByQuizID(ctx context.Context, session sql.NullString) ([]GetAllAnswersByQuizIDRow, error) { @@ -831,6 +844,8 @@ func (q *Queries) GetAllAnswersByQuizID(ctx context.Context, session sql.NullStr &i.CreatedAt, &i.QuestionID, &i.ID, + &i.Questiontype, + &i.Qid, ); err != nil { return nil, err } From f54a40e2ac920629df91e9cef1838e03817040da Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 14:53:12 +0300 Subject: [PATCH 101/107] add minioClient to answer Repo --- dal/dal.go | 17 +++++++++++--- dal/dal_minio.go | 44 +++++++++++++++++++++++++++++++++++++ go.mod | 16 ++++++++++++-- go.sum | 32 +++++++++++++++++++++++++++ repository/answer/answer.go | 21 ++++++++++++++---- 5 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 dal/dal_minio.go diff --git a/dal/dal.go b/dal/dal.go index 5f9418b..465e1c0 100644 --- a/dal/dal.go +++ b/dal/dal.go @@ -9,6 +9,7 @@ import ( "github.com/golang-migrate/migrate/v4/database/postgres" _ "github.com/golang-migrate/migrate/v4/source/file" _ "github.com/lib/pq" + "github.com/minio/minio-go/v7" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/account" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/answer" @@ -36,7 +37,7 @@ type DAL struct { StatisticsRepo *statistics.StatisticsRepository } -func New(ctx context.Context, cred string, authClient *auth.AuthClient) (*DAL, error) { +func New(ctx context.Context, cred string, authClient *auth.AuthClient, minioClient *minio.Client) (*DAL, error) { pool, err := sql.Open("postgres", cred) if err != nil { return nil, err @@ -57,9 +58,19 @@ func New(ctx context.Context, cred string, authClient *auth.AuthClient) (*DAL, e Pool: pool, }) + storerAnswer := &StorerAnswer{} + + if minioClient != nil { + storerAnswer, err = NewAnswerMinio(ctx, minioClient) + if err != nil { + return nil, err + } + } + answerRepo := answer.NewAnswerRepository(answer.Deps{ - Queries: queries, - Pool: pool, + Queries: queries, + Pool: pool, + AnswerMinio: storerAnswer, }) questionRepo := question.NewQuestionRepository(question.Deps{ diff --git a/dal/dal_minio.go b/dal/dal_minio.go new file mode 100644 index 0000000..0ed90e9 --- /dev/null +++ b/dal/dal_minio.go @@ -0,0 +1,44 @@ +package dal + +import ( + "context" + "fmt" + "github.com/minio/minio-go/v7" + "net/url" + "time" +) + +const ( + bucketAnswers = "squizanswer" +) + +type StorerAnswer struct { + client *minio.Client +} + +func NewAnswerMinio(ctx context.Context, minioClient *minio.Client) (*StorerAnswer, error) { + if ok, err := minioClient.BucketExists(ctx, bucketAnswers); !ok { + if err := minioClient.MakeBucket(ctx, bucketAnswers, minio.MakeBucketOptions{}); err != nil { + return nil, err + } + } else if err != nil { + return nil, err + } + + return &StorerAnswer{ + client: minioClient, + }, nil +} + +func (s *StorerAnswer) GetAnswerURL(ctx context.Context, quizID string, questionID int64, filename string) (string, error) { + objectName := fmt.Sprintf("%s/%d/%s", quizID, questionID, filename) + + reqParams := make(url.Values) + reqParams.Set("response-content-disposition", "attachment") + url, err := s.client.PresignedGetObject(ctx, bucketAnswers, objectName, time.Hour*1, reqParams) + if err != nil { + return "", err + } + + return url.String(), nil +} diff --git a/go.mod b/go.mod index fc2ebef..2f74b5c 100644 --- a/go.mod +++ b/go.mod @@ -17,17 +17,29 @@ require ( require ( github.com/andybalholm/brotli v1.0.5 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/klauspost/compress v1.17.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/minio-go/v7 v7.0.69 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.7.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index a3ed716..12c0db5 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE= github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -31,6 +33,7 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -38,8 +41,15 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -49,8 +59,19 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0= +github.com/minio/minio-go/v7 v7.0.69/go.mod h1:XAvOPJQ5Xlzk5o3o/ArO2NMbhSGkimC+bpW/ngRKDmQ= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -77,14 +98,23 @@ github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVS github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -92,6 +122,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d h1:gbaDt35HMDqOK84WYmDIlXMI7rstUcRqNttaT6Kx1do= diff --git a/repository/answer/answer.go b/repository/answer/answer.go index af4b316..19abc7c 100644 --- a/repository/answer/answer.go +++ b/repository/answer/answer.go @@ -3,18 +3,22 @@ package answer import ( "context" "database/sql" + "fmt" + "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" ) type Deps struct { - Queries *sqlcgen.Queries - Pool *sql.DB + Queries *sqlcgen.Queries + Pool *sql.DB + AnswerMinio *dal.StorerAnswer } type AnswerRepository struct { - queries *sqlcgen.Queries - pool *sql.DB + queries *sqlcgen.Queries + pool *sql.DB + answerMinio *dal.StorerAnswer } func NewAnswerRepository(deps Deps) *AnswerRepository { @@ -81,6 +85,15 @@ func (r *AnswerRepository) GetAllAnswersByQuizID(ctx context.Context, session st for _, row := range rows { + if row.Questiontype.(string) == model.TypeFile { + fileURL, err := r.answerMinio.GetAnswerURL(ctx, row.Qid.UUID.String(), row.QuestionID, row.Content.String) + if err != nil { + fmt.Println("GetAnswerURL dal answer minio answer", err) + return nil, err + } + row.Content = sql.NullString{String: fmt.Sprintf("%s|%s", fileURL, row.Content.String), Valid: true} + } + resultAnswer := model.ResultAnswer{ Content: row.Content.String, CreatedAt: row.CreatedAt.Time, From a7f632c44159fc9e741a66d767600c254cadfe47 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 14:54:20 +0300 Subject: [PATCH 102/107] add minioClient to answer Repo --- repository/answer/answer.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/repository/answer/answer.go b/repository/answer/answer.go index 19abc7c..50198bd 100644 --- a/repository/answer/answer.go +++ b/repository/answer/answer.go @@ -23,8 +23,9 @@ type AnswerRepository struct { func NewAnswerRepository(deps Deps) *AnswerRepository { return &AnswerRepository{ - queries: deps.Queries, - pool: deps.Pool, + queries: deps.Queries, + pool: deps.Pool, + answerMinio: deps.AnswerMinio, } } From 4f61bc17b0fd3cd569446d449bb9eb553c094aa7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 15:22:54 +0300 Subject: [PATCH 103/107] add minioClient to answer Repo --- dal/dal.go | 4 ++-- repository/answer/answer.go | 5 ++--- {dal => repository/answer}/dal_minio.go | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) rename {dal => repository/answer}/dal_minio.go (98%) diff --git a/dal/dal.go b/dal/dal.go index 465e1c0..7b4cdde 100644 --- a/dal/dal.go +++ b/dal/dal.go @@ -58,10 +58,10 @@ func New(ctx context.Context, cred string, authClient *auth.AuthClient, minioCli Pool: pool, }) - storerAnswer := &StorerAnswer{} + storerAnswer := &answer.StorerAnswer{} if minioClient != nil { - storerAnswer, err = NewAnswerMinio(ctx, minioClient) + storerAnswer, err = answer.NewAnswerMinio(ctx, minioClient) if err != nil { return nil, err } diff --git a/repository/answer/answer.go b/repository/answer/answer.go index 50198bd..0b943df 100644 --- a/repository/answer/answer.go +++ b/repository/answer/answer.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "fmt" - "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" ) @@ -12,13 +11,13 @@ import ( type Deps struct { Queries *sqlcgen.Queries Pool *sql.DB - AnswerMinio *dal.StorerAnswer + AnswerMinio *StorerAnswer } type AnswerRepository struct { queries *sqlcgen.Queries pool *sql.DB - answerMinio *dal.StorerAnswer + answerMinio *StorerAnswer } func NewAnswerRepository(deps Deps) *AnswerRepository { diff --git a/dal/dal_minio.go b/repository/answer/dal_minio.go similarity index 98% rename from dal/dal_minio.go rename to repository/answer/dal_minio.go index 0ed90e9..73276a8 100644 --- a/dal/dal_minio.go +++ b/repository/answer/dal_minio.go @@ -1,4 +1,4 @@ -package dal +package answer import ( "context" From 9eea1d69da86a03feabdc4b92293ee204e0ec558 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 28 Mar 2024 22:31:00 +0300 Subject: [PATCH 104/107] update sqlc gen --- dal/db_query/queries.sql | 6 +++--- dal/sqlcgen/queries.sql.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index e93772b..5341986 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -584,7 +584,7 @@ WHERE WITH original_quiz AS ( SELECT id FROM quiz - WHERE quiz.qid = $1 AND quiz.accountId = $2 + WHERE quiz.qid = $1 AND quiz.accountid = $2 ), new_quiz AS ( INSERT INTO quiz ( @@ -597,7 +597,7 @@ WITH original_quiz AS ( FROM quiz WHERE - qid = $1 AND accountId = $2 + qid = $1 AND accountid = $2 RETURNING id,qid ) SELECT @@ -642,4 +642,4 @@ WITH Registrations AS ( SELECT (SELECT registration_count FROM Registrations) AS registrations, (SELECT quiz_count FROM Quizes) AS quizes, - (SELECT result_count FROM Results) AS results; \ No newline at end of file + (SELECT result_count FROM Results) AS results; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 9d6f574..c134602 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1809,7 +1809,7 @@ const quizCopyQid = `-- name: QuizCopyQid :one WITH original_quiz AS ( SELECT id FROM quiz - WHERE quiz.qid = $1 AND quiz.accountId = $2 + WHERE quiz.qid = $1 AND quiz.accountid = $2 ), new_quiz AS ( INSERT INTO quiz ( @@ -1822,7 +1822,7 @@ WITH original_quiz AS ( FROM quiz WHERE - qid = $1 AND accountId = $2 + qid = $1 AND accountid = $2 RETURNING id,qid ) SELECT From 76b883af1134ab94a95a52b87537cc5ded215668 Mon Sep 17 00:00:00 2001 From: skeris Date: Fri, 29 Mar 2024 01:23:08 +0300 Subject: [PATCH 105/107] fix: move quiz request --- dal/db_query/queries.sql | 23 +++++------------------ dal/sqlcgen/queries.sql.go | 26 ++++++-------------------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 08b9f90..1d8d9e4 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -570,31 +570,18 @@ WHERE Questions.percentage >= 1; -- name: QuizCopyQid :one -WITH original_quiz AS ( - SELECT id - FROM quiz - WHERE quiz.qid = $1 AND quiz.accountId = $2 -), - new_quiz AS ( INSERT INTO quiz ( accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id ) SELECT - accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + $2, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id FROM - quiz + quiz as q WHERE - qid = $1 AND accountId = $2 - RETURNING id,qid - ) -SELECT - original_quiz.id AS original_quiz_id, - new_quiz.id AS new_quiz_id, - new_quiz.qid AS original_qid -FROM - original_quiz, new_quiz; + q.qid = $1 + RETURNING id,qid; -- name: CopyQuestionQuizID :exec INSERT INTO question ( @@ -610,4 +597,4 @@ WHERE question.quiz_id = $1 AND deleted = false; -- name: GetQidOwner :one -SELECT accountid FROM quiz where qid=$1; \ No newline at end of file +SELECT accountid FROM quiz where qid=$1; diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index d265e04..a5a7993 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1751,31 +1751,18 @@ func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisti } const quizCopyQid = `-- name: QuizCopyQid :one -WITH original_quiz AS ( - SELECT id - FROM quiz - WHERE quiz.qid = $1 AND quiz.accountId = $2 -), - new_quiz AS ( INSERT INTO quiz ( accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id ) SELECT - accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, + $2, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config, status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id FROM - quiz + quiz as q WHERE - qid = $1 AND accountId = $2 + q.qid = $1 RETURNING id,qid - ) -SELECT - original_quiz.id AS original_quiz_id, - new_quiz.id AS new_quiz_id, - new_quiz.qid AS original_qid -FROM - original_quiz, new_quiz ` type QuizCopyQidParams struct { @@ -1784,15 +1771,14 @@ type QuizCopyQidParams struct { } type QuizCopyQidRow struct { - OriginalQuizID int64 `db:"original_quiz_id" json:"original_quiz_id"` - NewQuizID int64 `db:"new_quiz_id" json:"new_quiz_id"` - OriginalQid uuid.NullUUID `db:"original_qid" json:"original_qid"` + ID int64 `db:"id" json:"id"` + Qid uuid.NullUUID `db:"qid" json:"qid"` } func (q *Queries) QuizCopyQid(ctx context.Context, arg QuizCopyQidParams) (QuizCopyQidRow, error) { row := q.db.QueryRowContext(ctx, quizCopyQid, arg.Qid, arg.Accountid) var i QuizCopyQidRow - err := row.Scan(&i.OriginalQuizID, &i.NewQuizID, &i.OriginalQid) + err := row.Scan(&i.ID, &i.Qid) return i, err } From e4b40cc929d5c2ab1059d61e90fd57c602779a65 Mon Sep 17 00:00:00 2001 From: skeris Date: Fri, 29 Mar 2024 02:51:52 +0300 Subject: [PATCH 106/107] -- --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/queries.sql.go | 9 +++++---- repository/quiz/quiz.go | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1d8d9e4..0692c46 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -581,7 +581,7 @@ WHERE quiz as q WHERE q.qid = $1 - RETURNING id,qid; + RETURNING (select id from quiz where qid = $2),id, qid; -- name: CopyQuestionQuizID :exec INSERT INTO question ( diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index a5a7993..8368925 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1762,7 +1762,7 @@ const quizCopyQid = `-- name: QuizCopyQid :one quiz as q WHERE q.qid = $1 - RETURNING id,qid + RETURNING (select id from quiz where qid = $2),id, qid ` type QuizCopyQidParams struct { @@ -1771,14 +1771,15 @@ type QuizCopyQidParams struct { } type QuizCopyQidRow struct { - ID int64 `db:"id" json:"id"` - Qid uuid.NullUUID `db:"qid" json:"qid"` + ID int64 `db:"id" json:"id"` + ID_2 int64 `db:"id_2" json:"id_2"` + Qid uuid.NullUUID `db:"qid" json:"qid"` } func (q *Queries) QuizCopyQid(ctx context.Context, arg QuizCopyQidParams) (QuizCopyQidRow, error) { row := q.db.QueryRowContext(ctx, quizCopyQid, arg.Qid, arg.Accountid) var i QuizCopyQidRow - err := row.Scan(&i.ID, &i.Qid) + err := row.Scan(&i.ID, &i.ID_2, &i.Qid) return i, err } diff --git a/repository/quiz/quiz.go b/repository/quiz/quiz.go index 9512eeb..0061bc6 100644 --- a/repository/quiz/quiz.go +++ b/repository/quiz/quiz.go @@ -596,13 +596,13 @@ func (r *QuizRepository) QuizMove(ctx context.Context, qID, accountID string) (s } err = r.queries.CopyQuestionQuizID(ctx, sqlcgen.CopyQuestionQuizIDParams{ - QuizID: data.OriginalQuizID, - QuizID_2: data.NewQuizID, + QuizID: data.ID, + QuizID_2: data.ID_2, }) if err != nil { return "", err } - return data.OriginalQid.UUID.String(), err + return data.Qid.UUID.String(), err } From 4e1b1b45d0c0c52329ae92e5f97d50cde8452147 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 29 Mar 2024 11:37:16 +0300 Subject: [PATCH 107/107] update sqlc gen --- dal/db_query/queries.sql | 2 +- dal/sqlcgen/db.go | 2 +- dal/sqlcgen/models.go | 2 +- dal/sqlcgen/queries.sql.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 0692c46..847d970 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -581,7 +581,7 @@ WHERE quiz as q WHERE q.qid = $1 - RETURNING (select id from quiz where qid = $2),id, qid; + RETURNING (select id from quiz where qid = $1),id, qid; -- name: CopyQuestionQuizID :exec INSERT INTO question ( diff --git a/dal/sqlcgen/db.go b/dal/sqlcgen/db.go index 6e5541c..7090fb4 100644 --- a/dal/sqlcgen/db.go +++ b/dal/sqlcgen/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.26.0 package sqlcgen diff --git a/dal/sqlcgen/models.go b/dal/sqlcgen/models.go index 5a42d12..75ae972 100644 --- a/dal/sqlcgen/models.go +++ b/dal/sqlcgen/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.26.0 package sqlcgen diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8368925..ea031dc 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.26.0 // source: queries.sql package sqlcgen @@ -1762,7 +1762,7 @@ const quizCopyQid = `-- name: QuizCopyQid :one quiz as q WHERE q.qid = $1 - RETURNING (select id from quiz where qid = $2),id, qid + RETURNING (select id from quiz where qid = $1),id, qid ` type QuizCopyQidParams struct {