137 lines
3.6 KiB
Go
137 lines
3.6 KiB
Go
package services
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
"github.com/rede5/gohorsejobs/backend/internal/models"
|
|
)
|
|
|
|
type CompanyFollowerService struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
func NewCompanyFollowerService(db *sql.DB) *CompanyFollowerService {
|
|
return &CompanyFollowerService{DB: db}
|
|
}
|
|
|
|
func (s *CompanyFollowerService) Follow(userID, companyID string) (*models.CompanyFollower, error) {
|
|
query := `
|
|
INSERT INTO company_followers (user_id, company_id, created_at)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (user_id, company_id) DO NOTHING
|
|
RETURNING id, user_id, company_id, created_at
|
|
`
|
|
|
|
var follower models.CompanyFollower
|
|
err := s.DB.QueryRow(query, userID, companyID, time.Now()).Scan(
|
|
&follower.ID, &follower.UserID, &follower.CompanyID, &follower.CreatedAt,
|
|
)
|
|
|
|
if err == sql.ErrNoRows {
|
|
err = s.DB.QueryRow(
|
|
"SELECT id, user_id, company_id, created_at FROM company_followers WHERE user_id = $1 AND company_id = $2",
|
|
userID, companyID,
|
|
).Scan(&follower.ID, &follower.UserID, &follower.CompanyID, &follower.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &follower, nil
|
|
}
|
|
|
|
func (s *CompanyFollowerService) Unfollow(userID, companyID string) error {
|
|
_, err := s.DB.Exec("DELETE FROM company_followers WHERE user_id = $1 AND company_id = $2", userID, companyID)
|
|
return err
|
|
}
|
|
|
|
func (s *CompanyFollowerService) GetFollowing(userID string) ([]models.CompanyFollowerWithCompany, error) {
|
|
query := `
|
|
SELECT
|
|
cf.id, cf.user_id, cf.company_id, cf.created_at,
|
|
c.name, c.logo_url,
|
|
(SELECT COUNT(*) FROM jobs j WHERE j.company_id = c.id AND j.status = 'published') as jobs_count
|
|
FROM company_followers cf
|
|
JOIN companies c ON cf.company_id = c.id
|
|
WHERE cf.user_id = $1
|
|
ORDER BY cf.created_at DESC
|
|
`
|
|
|
|
rows, err := s.DB.Query(query, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var followers []models.CompanyFollowerWithCompany
|
|
for rows.Next() {
|
|
var f models.CompanyFollowerWithCompany
|
|
err := rows.Scan(
|
|
&f.ID, &f.UserID, &f.CompanyID, &f.CreatedAt,
|
|
&f.CompanyName, &f.CompanyLogoURL, &f.JobsCount,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
followers = append(followers, f)
|
|
}
|
|
|
|
return followers, nil
|
|
}
|
|
|
|
func (s *CompanyFollowerService) IsFollowing(userID, companyID string) (bool, error) {
|
|
var exists bool
|
|
err := s.DB.QueryRow(
|
|
"SELECT EXISTS(SELECT 1 FROM company_followers WHERE user_id = $1 AND company_id = $2)",
|
|
userID, companyID,
|
|
).Scan(&exists)
|
|
return exists, err
|
|
}
|
|
|
|
func (s *CompanyFollowerService) GetCompanyFollowersCount(companyID string) (int, error) {
|
|
var count int
|
|
err := s.DB.QueryRow(
|
|
"SELECT COUNT(*) FROM company_followers WHERE company_id = $1",
|
|
companyID,
|
|
).Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
func (s *CompanyFollowerService) GetCompaniesWithJobs(limit, offset int) ([]models.CompanyFollowerWithCompany, error) {
|
|
query := `
|
|
SELECT
|
|
cf.id, cf.user_id, cf.company_id, cf.created_at,
|
|
c.name, c.logo_url,
|
|
(SELECT COUNT(*) FROM jobs j WHERE j.company_id = c.id AND j.status = 'published') as jobs_count
|
|
FROM companies c
|
|
LEFT JOIN company_followers cf ON cf.company_id = c.id
|
|
WHERE c.active = true
|
|
GROUP BY c.id, cf.id
|
|
ORDER BY jobs_count DESC, c.name ASC
|
|
LIMIT $1 OFFSET $2
|
|
`
|
|
|
|
rows, err := s.DB.Query(query, limit, offset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var companies []models.CompanyFollowerWithCompany
|
|
for rows.Next() {
|
|
var c models.CompanyFollowerWithCompany
|
|
err := rows.Scan(
|
|
&c.ID, &c.UserID, &c.CompanyID, &c.CreatedAt,
|
|
&c.CompanyName, &c.CompanyLogoURL, &c.JobsCount,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
companies = append(companies, c)
|
|
}
|
|
|
|
return companies, nil
|
|
}
|