first commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
BEGIN;
|
||||
|
||||
DROP INDEX IF EXISTS idx_refresh_tokens_user_id;
|
||||
DROP TABLE IF EXISTS refresh_tokens;
|
||||
DROP TABLE IF EXISTS users;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,23 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE refresh_tokens (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token TEXT NOT NULL UNIQUE,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_refresh_tokens_user_id ON refresh_tokens(user_id);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
DROP INDEX IF EXISTS idx_question_options_question;
|
||||
DROP INDEX IF EXISTS idx_questions_form_id;
|
||||
DROP INDEX IF EXISTS idx_forms_user_id;
|
||||
DROP TABLE IF EXISTS question_options;
|
||||
DROP TABLE IF EXISTS questions;
|
||||
DROP TABLE IF EXISTS forms;
|
||||
DROP TYPE IF EXISTS question_type;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,47 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TYPE question_type AS ENUM (
|
||||
'short_text',
|
||||
'long_text',
|
||||
'multiple_choice',
|
||||
'checkbox',
|
||||
'dropdown',
|
||||
'date',
|
||||
'rating'
|
||||
);
|
||||
|
||||
CREATE TABLE forms (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
response_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE questions (
|
||||
id UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
form_id UUID NOT NULL REFERENCES forms(id) ON DELETE CASCADE,
|
||||
type question_type NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
required BOOLEAN NOT NULL DEFAULT false,
|
||||
position INTEGER NOT NULL,
|
||||
PRIMARY KEY (form_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE question_options (
|
||||
id SERIAL PRIMARY KEY,
|
||||
form_id UUID NOT NULL,
|
||||
question_id UUID NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
FOREIGN KEY (form_id, question_id)
|
||||
REFERENCES questions(form_id, id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_forms_user_id ON forms(user_id);
|
||||
CREATE INDEX idx_questions_form_id ON questions(form_id);
|
||||
CREATE INDEX idx_question_options_question ON question_options(form_id, question_id);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,42 @@
|
||||
-- name: CreateUser :exec
|
||||
INSERT INTO users (email, password_hash)
|
||||
VALUES ($1, $2);
|
||||
|
||||
-- name: GetUserByEmail :one
|
||||
SELECT * FROM users
|
||||
WHERE email = $1
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetUserByID :one
|
||||
SELECT * FROM users
|
||||
WHERE id = $1
|
||||
LIMIT 1;
|
||||
|
||||
-- name: UpdateUserPassword :one
|
||||
UPDATE users
|
||||
SET password_hash = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: CreateRefreshToken :one
|
||||
INSERT INTO refresh_tokens (user_id, token, expires_at)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetRefreshToken :one
|
||||
SELECT * FROM refresh_tokens
|
||||
WHERE token = $1
|
||||
LIMIT 1;
|
||||
|
||||
-- name: DeleteRefreshToken :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE token = $1;
|
||||
|
||||
-- name: DeleteUserRefreshTokens :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE user_id = $1;
|
||||
|
||||
-- name: DeleteExpiredRefreshTokens :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE expires_at < now();
|
||||
@@ -0,0 +1,33 @@
|
||||
-- name: ListForms :many
|
||||
SELECT * FROM forms
|
||||
WHERE user_id = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: GetFormByID :one
|
||||
SELECT * FROM forms
|
||||
WHERE id = $1
|
||||
LIMIT 1;
|
||||
|
||||
-- name: CreateForm :one
|
||||
INSERT INTO forms (user_id, title, description)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateForm :one
|
||||
UPDATE forms
|
||||
SET title = $2,
|
||||
description = $3,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteForm :exec
|
||||
DELETE FROM forms
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: IncrementResponseCount :one
|
||||
UPDATE forms
|
||||
SET response_count = response_count + 1,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
@@ -0,0 +1,18 @@
|
||||
-- name: CreateQuestionOption :one
|
||||
INSERT INTO question_options (form_id, question_id, label, position)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetOptionsByFormID :many
|
||||
SELECT * FROM question_options
|
||||
WHERE form_id = $1
|
||||
ORDER BY question_id, position ASC;
|
||||
|
||||
-- name: GetOptionsByQuestionID :many
|
||||
SELECT * FROM question_options
|
||||
WHERE form_id = $1 AND question_id = $2
|
||||
ORDER BY position ASC;
|
||||
|
||||
-- name: DeleteOptionsByFormID :exec
|
||||
DELETE FROM question_options
|
||||
WHERE form_id = $1;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- name: CreateQuestion :one
|
||||
INSERT INTO questions (form_id, type, title, required, position)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetQuestionsByFormID :many
|
||||
SELECT * FROM questions
|
||||
WHERE form_id = $1
|
||||
ORDER BY position ASC;
|
||||
|
||||
-- name: DeleteQuestionsByFormID :exec
|
||||
DELETE FROM questions
|
||||
WHERE form_id = $1;
|
||||
@@ -0,0 +1,166 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: auth.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createRefreshToken = `-- name: CreateRefreshToken :one
|
||||
INSERT INTO refresh_tokens (user_id, token, expires_at)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, user_id, token, expires_at, created_at
|
||||
`
|
||||
|
||||
type CreateRefreshTokenParams struct {
|
||||
UserID uuid.UUID
|
||||
Token string
|
||||
ExpiresAt pgtype.Timestamptz
|
||||
}
|
||||
|
||||
func (q *Queries) CreateRefreshToken(ctx context.Context, arg CreateRefreshTokenParams) (RefreshToken, error) {
|
||||
row := q.db.QueryRow(ctx, createRefreshToken, arg.UserID, arg.Token, arg.ExpiresAt)
|
||||
var i RefreshToken
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Token,
|
||||
&i.ExpiresAt,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const createUser = `-- name: CreateUser :exec
|
||||
INSERT INTO users (email, password_hash)
|
||||
VALUES ($1, $2)
|
||||
`
|
||||
|
||||
type CreateUserParams struct {
|
||||
Email string
|
||||
PasswordHash string
|
||||
}
|
||||
|
||||
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error {
|
||||
_, err := q.db.Exec(ctx, createUser, arg.Email, arg.PasswordHash)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteExpiredRefreshTokens = `-- name: DeleteExpiredRefreshTokens :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE expires_at < now()
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteExpiredRefreshTokens(ctx context.Context) error {
|
||||
_, err := q.db.Exec(ctx, deleteExpiredRefreshTokens)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteRefreshToken = `-- name: DeleteRefreshToken :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE token = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteRefreshToken(ctx context.Context, token string) error {
|
||||
_, err := q.db.Exec(ctx, deleteRefreshToken, token)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteUserRefreshTokens = `-- name: DeleteUserRefreshTokens :exec
|
||||
DELETE FROM refresh_tokens
|
||||
WHERE user_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteUserRefreshTokens(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, deleteUserRefreshTokens, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getRefreshToken = `-- name: GetRefreshToken :one
|
||||
SELECT id, user_id, token, expires_at, created_at FROM refresh_tokens
|
||||
WHERE token = $1
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetRefreshToken(ctx context.Context, token string) (RefreshToken, error) {
|
||||
row := q.db.QueryRow(ctx, getRefreshToken, token)
|
||||
var i RefreshToken
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Token,
|
||||
&i.ExpiresAt,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserByEmail = `-- name: GetUserByEmail :one
|
||||
SELECT id, email, password_hash, created_at, updated_at FROM users
|
||||
WHERE email = $1
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserByEmail(ctx context.Context, email string) (User, error) {
|
||||
row := q.db.QueryRow(ctx, getUserByEmail, email)
|
||||
var i User
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.PasswordHash,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserByID = `-- name: GetUserByID :one
|
||||
SELECT id, email, password_hash, created_at, updated_at FROM users
|
||||
WHERE id = $1
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserByID(ctx context.Context, id uuid.UUID) (User, error) {
|
||||
row := q.db.QueryRow(ctx, getUserByID, id)
|
||||
var i User
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.PasswordHash,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateUserPassword = `-- name: UpdateUserPassword :one
|
||||
UPDATE users
|
||||
SET password_hash = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, email, password_hash, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpdateUserPasswordParams struct {
|
||||
ID uuid.UUID
|
||||
PasswordHash string
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) (User, error) {
|
||||
row := q.db.QueryRow(ctx, updateUserPassword, arg.ID, arg.PasswordHash)
|
||||
var i User
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Email,
|
||||
&i.PasswordHash,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: forms.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const createForm = `-- name: CreateForm :one
|
||||
INSERT INTO forms (user_id, title, description)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, user_id, title, description, response_count, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateFormParams struct {
|
||||
UserID uuid.UUID
|
||||
Title string
|
||||
Description pgtype.Text
|
||||
}
|
||||
|
||||
func (q *Queries) CreateForm(ctx context.Context, arg CreateFormParams) (Form, error) {
|
||||
row := q.db.QueryRow(ctx, createForm, arg.UserID, arg.Title, arg.Description)
|
||||
var i Form
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Title,
|
||||
&i.Description,
|
||||
&i.ResponseCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteForm = `-- name: DeleteForm :exec
|
||||
DELETE FROM forms
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteForm(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, deleteForm, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const getFormByID = `-- name: GetFormByID :one
|
||||
SELECT id, user_id, title, description, response_count, created_at, updated_at FROM forms
|
||||
WHERE id = $1
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetFormByID(ctx context.Context, id uuid.UUID) (Form, error) {
|
||||
row := q.db.QueryRow(ctx, getFormByID, id)
|
||||
var i Form
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Title,
|
||||
&i.Description,
|
||||
&i.ResponseCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const incrementResponseCount = `-- name: IncrementResponseCount :one
|
||||
UPDATE forms
|
||||
SET response_count = response_count + 1,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, user_id, title, description, response_count, created_at, updated_at
|
||||
`
|
||||
|
||||
func (q *Queries) IncrementResponseCount(ctx context.Context, id uuid.UUID) (Form, error) {
|
||||
row := q.db.QueryRow(ctx, incrementResponseCount, id)
|
||||
var i Form
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Title,
|
||||
&i.Description,
|
||||
&i.ResponseCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listForms = `-- name: ListForms :many
|
||||
SELECT id, user_id, title, description, response_count, created_at, updated_at FROM forms
|
||||
WHERE user_id = $1
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
func (q *Queries) ListForms(ctx context.Context, userID uuid.UUID) ([]Form, error) {
|
||||
rows, err := q.db.Query(ctx, listForms, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Form
|
||||
for rows.Next() {
|
||||
var i Form
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Title,
|
||||
&i.Description,
|
||||
&i.ResponseCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const updateForm = `-- name: UpdateForm :one
|
||||
UPDATE forms
|
||||
SET title = $2,
|
||||
description = $3,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, user_id, title, description, response_count, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpdateFormParams struct {
|
||||
ID uuid.UUID
|
||||
Title string
|
||||
Description pgtype.Text
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateForm(ctx context.Context, arg UpdateFormParams) (Form, error) {
|
||||
row := q.db.QueryRow(ctx, updateForm, arg.ID, arg.Title, arg.Description)
|
||||
var i Form
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Title,
|
||||
&i.Description,
|
||||
&i.ResponseCount,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type QuestionType string
|
||||
|
||||
const (
|
||||
QuestionTypeShortText QuestionType = "short_text"
|
||||
QuestionTypeLongText QuestionType = "long_text"
|
||||
QuestionTypeMultipleChoice QuestionType = "multiple_choice"
|
||||
QuestionTypeCheckbox QuestionType = "checkbox"
|
||||
QuestionTypeDropdown QuestionType = "dropdown"
|
||||
QuestionTypeDate QuestionType = "date"
|
||||
QuestionTypeRating QuestionType = "rating"
|
||||
)
|
||||
|
||||
func (e *QuestionType) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = QuestionType(s)
|
||||
case string:
|
||||
*e = QuestionType(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for QuestionType: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullQuestionType struct {
|
||||
QuestionType QuestionType
|
||||
Valid bool // Valid is true if QuestionType is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullQuestionType) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.QuestionType, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.QuestionType.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullQuestionType) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.QuestionType), nil
|
||||
}
|
||||
|
||||
type Form struct {
|
||||
ID uuid.UUID
|
||||
UserID uuid.UUID
|
||||
Title string
|
||||
Description pgtype.Text
|
||||
ResponseCount int32
|
||||
CreatedAt pgtype.Timestamptz
|
||||
UpdatedAt pgtype.Timestamptz
|
||||
}
|
||||
|
||||
type Question struct {
|
||||
ID uuid.UUID
|
||||
FormID uuid.UUID
|
||||
Type QuestionType
|
||||
Title string
|
||||
Required bool
|
||||
Position int32
|
||||
}
|
||||
|
||||
type QuestionOption struct {
|
||||
ID int32
|
||||
FormID uuid.UUID
|
||||
QuestionID uuid.UUID
|
||||
Label string
|
||||
Position int32
|
||||
}
|
||||
|
||||
type RefreshToken struct {
|
||||
ID uuid.UUID
|
||||
UserID uuid.UUID
|
||||
Token string
|
||||
ExpiresAt pgtype.Timestamptz
|
||||
CreatedAt pgtype.Timestamptz
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uuid.UUID
|
||||
Email string
|
||||
PasswordHash string
|
||||
CreatedAt pgtype.Timestamptz
|
||||
UpdatedAt pgtype.Timestamptz
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: question_options.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createQuestionOption = `-- name: CreateQuestionOption :one
|
||||
INSERT INTO question_options (form_id, question_id, label, position)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, form_id, question_id, label, position
|
||||
`
|
||||
|
||||
type CreateQuestionOptionParams struct {
|
||||
FormID uuid.UUID
|
||||
QuestionID uuid.UUID
|
||||
Label string
|
||||
Position int32
|
||||
}
|
||||
|
||||
func (q *Queries) CreateQuestionOption(ctx context.Context, arg CreateQuestionOptionParams) (QuestionOption, error) {
|
||||
row := q.db.QueryRow(ctx, createQuestionOption,
|
||||
arg.FormID,
|
||||
arg.QuestionID,
|
||||
arg.Label,
|
||||
arg.Position,
|
||||
)
|
||||
var i QuestionOption
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.FormID,
|
||||
&i.QuestionID,
|
||||
&i.Label,
|
||||
&i.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteOptionsByFormID = `-- name: DeleteOptionsByFormID :exec
|
||||
DELETE FROM question_options
|
||||
WHERE form_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteOptionsByFormID(ctx context.Context, formID uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, deleteOptionsByFormID, formID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getOptionsByFormID = `-- name: GetOptionsByFormID :many
|
||||
SELECT id, form_id, question_id, label, position FROM question_options
|
||||
WHERE form_id = $1
|
||||
ORDER BY question_id, position ASC
|
||||
`
|
||||
|
||||
func (q *Queries) GetOptionsByFormID(ctx context.Context, formID uuid.UUID) ([]QuestionOption, error) {
|
||||
rows, err := q.db.Query(ctx, getOptionsByFormID, formID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []QuestionOption
|
||||
for rows.Next() {
|
||||
var i QuestionOption
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.FormID,
|
||||
&i.QuestionID,
|
||||
&i.Label,
|
||||
&i.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getOptionsByQuestionID = `-- name: GetOptionsByQuestionID :many
|
||||
SELECT id, form_id, question_id, label, position FROM question_options
|
||||
WHERE form_id = $1 AND question_id = $2
|
||||
ORDER BY position ASC
|
||||
`
|
||||
|
||||
type GetOptionsByQuestionIDParams struct {
|
||||
FormID uuid.UUID
|
||||
QuestionID uuid.UUID
|
||||
}
|
||||
|
||||
func (q *Queries) GetOptionsByQuestionID(ctx context.Context, arg GetOptionsByQuestionIDParams) ([]QuestionOption, error) {
|
||||
rows, err := q.db.Query(ctx, getOptionsByQuestionID, arg.FormID, arg.QuestionID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []QuestionOption
|
||||
for rows.Next() {
|
||||
var i QuestionOption
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.FormID,
|
||||
&i.QuestionID,
|
||||
&i.Label,
|
||||
&i.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: questions.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createQuestion = `-- name: CreateQuestion :one
|
||||
INSERT INTO questions (form_id, type, title, required, position)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, form_id, type, title, required, position
|
||||
`
|
||||
|
||||
type CreateQuestionParams struct {
|
||||
FormID uuid.UUID
|
||||
Type QuestionType
|
||||
Title string
|
||||
Required bool
|
||||
Position int32
|
||||
}
|
||||
|
||||
func (q *Queries) CreateQuestion(ctx context.Context, arg CreateQuestionParams) (Question, error) {
|
||||
row := q.db.QueryRow(ctx, createQuestion,
|
||||
arg.FormID,
|
||||
arg.Type,
|
||||
arg.Title,
|
||||
arg.Required,
|
||||
arg.Position,
|
||||
)
|
||||
var i Question
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.FormID,
|
||||
&i.Type,
|
||||
&i.Title,
|
||||
&i.Required,
|
||||
&i.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteQuestionsByFormID = `-- name: DeleteQuestionsByFormID :exec
|
||||
DELETE FROM questions
|
||||
WHERE form_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteQuestionsByFormID(ctx context.Context, formID uuid.UUID) error {
|
||||
_, err := q.db.Exec(ctx, deleteQuestionsByFormID, formID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getQuestionsByFormID = `-- name: GetQuestionsByFormID :many
|
||||
SELECT id, form_id, type, title, required, position FROM questions
|
||||
WHERE form_id = $1
|
||||
ORDER BY position ASC
|
||||
`
|
||||
|
||||
func (q *Queries) GetQuestionsByFormID(ctx context.Context, formID uuid.UUID) ([]Question, error) {
|
||||
rows, err := q.db.Query(ctx, getQuestionsByFormID, formID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Question
|
||||
for rows.Next() {
|
||||
var i Question
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.FormID,
|
||||
&i.Type,
|
||||
&i.Title,
|
||||
&i.Required,
|
||||
&i.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
version: "2"
|
||||
sql:
|
||||
- engine: "postgresql"
|
||||
queries: "queries"
|
||||
schema: "migrations"
|
||||
gen:
|
||||
go:
|
||||
package: "repository"
|
||||
out: "repository"
|
||||
sql_package: "pgx/v5"
|
||||
overrides:
|
||||
- db_type: "uuid"
|
||||
go_type:
|
||||
import: "github.com/google/uuid"
|
||||
type: "UUID"
|
||||
- db_type: "uuid"
|
||||
go_type:
|
||||
import: "github.com/google/uuid"
|
||||
type: "UUID"
|
||||
pointer: true
|
||||
nullable: true
|
||||
- db_type: "timestamptz"
|
||||
go_type:
|
||||
type: "*time.Time"
|
||||
pointer: true
|
||||
nullable: true
|
||||
Reference in New Issue
Block a user