package repository import ( "context" "database/sql" "time" "github.com/jackc/pgx/v5/pgxpool" "shop/internal/models" ) type ReservationRepository struct { pool *pgxpool.Pool } func NewReservationRepository(pool *pgxpool.Pool) *ReservationRepository { return &ReservationRepository{pool: pool} } func (r *ReservationRepository) Create(ctx context.Context, res *models.Reservation) error { return r.pool.QueryRow(ctx, ` INSERT INTO product_reservations (product_id, session_key, user_id, customer_name, customer_phone, expires_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, created_at `, res.ProductID, res.SessionKey, res.UserID, res.CustomerName, res.CustomerPhone, res.ExpiresAt, ).Scan(&res.ID, &res.CreatedAt) } func (r *ReservationRepository) ActiveByProduct(ctx context.Context, productID int) (*models.Reservation, error) { var res models.Reservation var userID sql.NullInt64 err := r.pool.QueryRow(ctx, ` SELECT id, product_id, session_key, user_id, customer_name, customer_phone, expires_at, created_at FROM product_reservations WHERE product_id = $1 AND expires_at > NOW() ORDER BY created_at DESC LIMIT 1 `, productID).Scan( &res.ID, &res.ProductID, &res.SessionKey, &userID, &res.CustomerName, &res.CustomerPhone, &res.ExpiresAt, &res.CreatedAt, ) if err != nil { return nil, err } if userID.Valid { id := int(userID.Int64) res.UserID = &id } return &res, nil } func (r *ReservationRepository) ReplaceForProduct(ctx context.Context, res *models.Reservation) error { tx, err := r.pool.Begin(ctx) if err != nil { return err } defer tx.Rollback(ctx) _, err = tx.Exec(ctx, `DELETE FROM product_reservations WHERE product_id = $1`, res.ProductID) if err != nil { return err } err = tx.QueryRow(ctx, ` INSERT INTO product_reservations (product_id, session_key, user_id, customer_name, customer_phone, expires_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, created_at `, res.ProductID, res.SessionKey, res.UserID, res.CustomerName, res.CustomerPhone, res.ExpiresAt, ).Scan(&res.ID, &res.CreatedAt) if err != nil { return err } return tx.Commit(ctx) } func (r *ReservationRepository) ExpiresIn() time.Duration { return 24 * time.Hour }