2026-02-23 20:02:17 +03:00
|
|
|
package merch
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"database/sql"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
|
"strings"
|
2026-03-04 17:59:46 +03:00
|
|
|
"time"
|
2026-03-04 17:02:11 +03:00
|
|
|
)
|
2026-02-23 20:02:17 +03:00
|
|
|
|
2026-03-01 22:13:39 +03:00
|
|
|
type Repository interface {
|
2026-03-04 17:59:46 +03:00
|
|
|
// createMerch creates new merch record and inserts extra data if given
|
2026-03-04 17:02:11 +03:00
|
|
|
createMerch(ctx context.Context, merch *Merch, extra []ExtraData) error
|
|
|
|
|
|
2026-03-04 17:59:46 +03:00
|
|
|
// getMany returns list of only main merch record, without origins extra data
|
|
|
|
|
getMany(ctx context.Context, userId string) ([]merchDTO, error)
|
|
|
|
|
|
|
|
|
|
// deleteOneMerchRecord sets deleted_at in merch + extra tables
|
|
|
|
|
deleteOneMerchRecord(ctx context.Context, userId, merchUuid string, delTime time.Time) error
|
|
|
|
|
|
2026-03-01 22:13:39 +03:00
|
|
|
Origins
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Origins interface {
|
2026-03-04 17:02:11 +03:00
|
|
|
createOrigin(ctx context.Context, origin *Origin) error
|
|
|
|
|
getOrigins(ctx context.Context) ([]Origin, error)
|
|
|
|
|
deleteOriginByName(ctx context.Context, name string, deletedAt sql.NullTime) error
|
2026-03-01 22:13:39 +03:00
|
|
|
}
|
2026-02-23 20:02:17 +03:00
|
|
|
|
|
|
|
|
type repo struct {
|
2026-03-04 17:02:11 +03:00
|
|
|
db *pgxpool.Pool
|
2026-02-23 20:02:17 +03:00
|
|
|
}
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
func newRepo(db *pgxpool.Pool) Repository {
|
2026-03-01 22:13:39 +03:00
|
|
|
return &repo{
|
2026-02-23 20:02:17 +03:00
|
|
|
db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-01 22:13:39 +03:00
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
func (r *repo) createOrigin(ctx context.Context, origin *Origin) error {
|
2026-03-01 22:13:39 +03:00
|
|
|
q := `INSERT INTO merch_origins (created_at, deleted_at, name) VALUES ($1, $2, $3)`
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
_, err := r.db.Exec(ctx, q, origin.CreatedAt, origin.DeletedAt, origin.Name)
|
2026-03-01 22:13:39 +03:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
func (r *repo) getOrigins(ctx context.Context) ([]Origin, error) {
|
2026-03-01 22:13:39 +03:00
|
|
|
q := `SELECT * FROM merch_origins WHERE deleted_at IS NULL`
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
rows, err := r.db.Query(ctx, q)
|
2026-03-01 22:13:39 +03:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
var origins []Origin
|
|
|
|
|
for rows.Next() {
|
|
|
|
|
var o Origin
|
|
|
|
|
if err = rows.Scan(&o.Id, &o.CreatedAt, &o.DeletedAt, &o.Name); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
origins = append(origins, o)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return origins, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
func (r *repo) deleteOriginByName(ctx context.Context, name string, deletedAt sql.NullTime) error {
|
2026-03-01 22:13:39 +03:00
|
|
|
q := `UPDATE merch_origins SET deleted_at = $1 WHERE name = $2`
|
|
|
|
|
|
2026-03-04 17:02:11 +03:00
|
|
|
_, err := r.db.Exec(ctx, q, deletedAt.Time, name)
|
2026-03-01 22:13:39 +03:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-03-04 17:02:11 +03:00
|
|
|
|
|
|
|
|
//Merch crud
|
|
|
|
|
|
|
|
|
|
func (r *repo) createMerch(ctx context.Context, merch *Merch, extra []ExtraData) error {
|
|
|
|
|
tx, err := r.db.Begin(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qMerch := `INSERT INTO merch (created_at, updated_at, deleted_at, merch_uuid, user_id, name)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
|
|
|
|
|
|
|
|
|
|
var merchId int64
|
|
|
|
|
err = tx.
|
|
|
|
|
QueryRow(ctx, qMerch, merch.CreatedAt, merch.UpdatedAt, merch.DeletedAt, merch.MerchUuid, merch.UserId, merch.Name).
|
|
|
|
|
Scan(&merchId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
tx.Rollback(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if extra == nil {
|
|
|
|
|
return tx.Commit(ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
countArgs := 1
|
|
|
|
|
var insertFields []string
|
|
|
|
|
var insertArgs []interface{}
|
|
|
|
|
|
|
|
|
|
for _, item := range extra {
|
|
|
|
|
insertFields = append(insertFields, fmt.Sprintf("($%v, $%v, $%v, $%v, $%v, $%v)",
|
|
|
|
|
countArgs, countArgs+1, countArgs+2, countArgs+3, countArgs+4, countArgs+5))
|
|
|
|
|
|
|
|
|
|
insertArgs = append(insertArgs, item.CreatedAt, item.UpdatedAt, item.DeletedAt, merchId, item.OriginId, item.URL)
|
|
|
|
|
|
|
|
|
|
countArgs += 6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qExtra := fmt.Sprintf(
|
|
|
|
|
"INSERT INTO merch_extra_data (created_at, updated_at, deleted_at, merch_id, origin_id, url) VALUES %v",
|
|
|
|
|
strings.Join(insertFields, ","))
|
|
|
|
|
|
|
|
|
|
_, err = tx.Exec(ctx, qExtra, insertArgs...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
tx.Rollback(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tx.Commit(ctx)
|
|
|
|
|
}
|
2026-03-04 17:59:46 +03:00
|
|
|
|
|
|
|
|
func (r *repo) getMany(ctx context.Context, userId string) ([]merchDTO, error) {
|
|
|
|
|
q := `SELECT created_at, updated_at, merch_uuid, name FROM merch WHERE deleted_at IS NULL AND user_id = $1`
|
|
|
|
|
|
|
|
|
|
rows, err := r.db.Query(ctx, q, userId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
var result []merchDTO
|
|
|
|
|
for rows.Next() {
|
|
|
|
|
var m merchDTO
|
|
|
|
|
if err = rows.Scan(&m.CreatedAt, &m.UpdatedAt, &m.MerchUuid, &m.Name); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
result = append(result, m)
|
|
|
|
|
}
|
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *repo) deleteOneMerchRecord(ctx context.Context, userId, merchUuid string, delTime time.Time) error {
|
|
|
|
|
tx, err := r.db.Begin(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var merch_id int64
|
|
|
|
|
qMerch := `UPDATE merch SET deleted_at = $1 WHERE merch_uuid = $2 AND user_id = $3 RETURNING id`
|
|
|
|
|
if err = tx.QueryRow(ctx, qMerch, delTime, merchUuid, userId).Scan(&merch_id); err != nil {
|
|
|
|
|
tx.Rollback(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if merch_id != 0 {
|
|
|
|
|
qExtra := `UPDATE merch_extra_data SET deleted_at = $1 WHERE merch_id = $2`
|
|
|
|
|
_, err = tx.Exec(ctx, qExtra, delTime, merch_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tx.Commit(ctx)
|
|
|
|
|
}
|