95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
package services
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
"github.com/rede5/gohorsejobs/backend/internal/models"
|
|
)
|
|
|
|
type FavoriteJobService struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
func NewFavoriteJobService(db *sql.DB) *FavoriteJobService {
|
|
return &FavoriteJobService{DB: db}
|
|
}
|
|
|
|
func (s *FavoriteJobService) AddFavorite(userID, jobID string) (*models.FavoriteJob, error) {
|
|
query := `
|
|
INSERT INTO favorite_jobs (user_id, job_id, created_at)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (user_id, job_id) DO NOTHING
|
|
RETURNING id, user_id, job_id, created_at
|
|
`
|
|
|
|
var favorite models.FavoriteJob
|
|
err := s.DB.QueryRow(query, userID, jobID, time.Now()).Scan(
|
|
&favorite.ID, &favorite.UserID, &favorite.JobID, &favorite.CreatedAt,
|
|
)
|
|
|
|
if err == sql.ErrNoRows {
|
|
// Already exists, fetch it
|
|
err = s.DB.QueryRow(
|
|
"SELECT id, user_id, job_id, created_at FROM favorite_jobs WHERE user_id = $1 AND job_id = $2",
|
|
userID, jobID,
|
|
).Scan(&favorite.ID, &favorite.UserID, &favorite.JobID, &favorite.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &favorite, nil
|
|
}
|
|
|
|
func (s *FavoriteJobService) RemoveFavorite(userID, jobID string) error {
|
|
_, err := s.DB.Exec("DELETE FROM favorite_jobs WHERE user_id = $1 AND job_id = $2", userID, jobID)
|
|
return err
|
|
}
|
|
|
|
func (s *FavoriteJobService) GetFavorites(userID string) ([]models.FavoriteJobWithDetails, error) {
|
|
query := `
|
|
SELECT
|
|
f.id, f.user_id, f.job_id, f.created_at,
|
|
j.title, j.company_id, c.name, c.logo_url, j.location,
|
|
j.salary_min, j.salary_max, j.salary_type
|
|
FROM favorite_jobs f
|
|
JOIN jobs j ON f.job_id = j.id
|
|
JOIN companies c ON j.company_id = c.id
|
|
WHERE f.user_id = $1
|
|
ORDER BY f.created_at DESC
|
|
`
|
|
|
|
rows, err := s.DB.Query(query, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var favorites []models.FavoriteJobWithDetails
|
|
for rows.Next() {
|
|
var fav models.FavoriteJobWithDetails
|
|
err := rows.Scan(
|
|
&fav.ID, &fav.UserID, &fav.JobID, &fav.CreatedAt,
|
|
&fav.JobTitle, &fav.CompanyID, &fav.CompanyName, &fav.CompanyLogoURL, &fav.Location,
|
|
&fav.SalaryMin, &fav.SalaryMax, &fav.SalaryType,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
favorites = append(favorites, fav)
|
|
}
|
|
|
|
return favorites, nil
|
|
}
|
|
|
|
func (s *FavoriteJobService) IsFavorite(userID, jobID string) (bool, error) {
|
|
var exists bool
|
|
err := s.DB.QueryRow(
|
|
"SELECT EXISTS(SELECT 1 FROM favorite_jobs WHERE user_id = $1 AND job_id = $2)",
|
|
userID, jobID,
|
|
).Scan(&exists)
|
|
return exists, err
|
|
}
|