package merch import ( "context" "database/sql" "fmt" "github.com/jackc/pgx/v5/pgxpool" "strings" ) type Repository interface { createMerch(ctx context.Context, merch *Merch, extra []ExtraData) error Origins } type Origins interface { createOrigin(ctx context.Context, origin *Origin) error getOrigins(ctx context.Context) ([]Origin, error) deleteOriginByName(ctx context.Context, name string, deletedAt sql.NullTime) error } type repo struct { db *pgxpool.Pool } func newRepo(db *pgxpool.Pool) Repository { return &repo{ db: db, } } func (r *repo) createOrigin(ctx context.Context, origin *Origin) error { q := `INSERT INTO merch_origins (created_at, deleted_at, name) VALUES ($1, $2, $3)` _, err := r.db.Exec(ctx, q, origin.CreatedAt, origin.DeletedAt, origin.Name) if err != nil { return err } return nil } func (r *repo) getOrigins(ctx context.Context) ([]Origin, error) { q := `SELECT * FROM merch_origins WHERE deleted_at IS NULL` rows, err := r.db.Query(ctx, q) 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 } func (r *repo) deleteOriginByName(ctx context.Context, name string, deletedAt sql.NullTime) error { q := `UPDATE merch_origins SET deleted_at = $1 WHERE name = $2` _, err := r.db.Exec(ctx, q, deletedAt.Time, name) if err != nil { return err } return nil } //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) }