sabisan/internal/store/projects.go
V fac53d7b85
All checks were successful
Publish / Test, build, and push image (push) Successful in 3m38s
Refactor app and store layout
2026-05-17 00:03:50 +01:00

123 lines
4.3 KiB
Go

package store
import (
"context"
"database/sql"
)
func (s *Store) Projects(ctx context.Context, featuredOnly bool) ([]Project, error) {
query := `select id, slug, title, location, year, category, description, cover_image, featured, created_at from projects`
if featuredOnly {
query += ` where featured = 1`
}
query += ` order by created_at desc, id desc`
rows, err := s.db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
defer rows.Close()
var projects []Project
for rows.Next() {
var p Project
var featured int
if err := rows.Scan(&p.ID, &p.Slug, &p.Title, &p.Location, &p.Year, &p.Category, &p.Description, &p.CoverImage, &featured, &p.CreatedAt); err != nil {
return nil, err
}
p.Featured = featured == 1
projects = append(projects, p)
}
return projects, rows.Err()
}
func (s *Store) ProjectBySlug(ctx context.Context, slug string) (Project, error) {
var p Project
var featured int
err := s.db.QueryRowContext(ctx, `select id, slug, title, location, year, category, description, cover_image, featured, created_at from projects where slug = ?`, slug).
Scan(&p.ID, &p.Slug, &p.Title, &p.Location, &p.Year, &p.Category, &p.Description, &p.CoverImage, &featured, &p.CreatedAt)
if err != nil {
return p, err
}
p.Featured = featured == 1
p.Images, err = s.ProjectImages(ctx, p.ID)
return p, err
}
func (s *Store) ProjectImages(ctx context.Context, projectID int64) ([]ProjectImage, error) {
rows, err := s.db.QueryContext(ctx, `select id, project_id, path, caption, position from project_images where project_id = ? order by position asc, id asc`, projectID)
if err != nil {
return nil, err
}
defer rows.Close()
var images []ProjectImage
for rows.Next() {
var img ProjectImage
if err := rows.Scan(&img.ID, &img.ProjectID, &img.Path, &img.Caption, &img.Position); err != nil {
return nil, err
}
images = append(images, img)
}
return images, rows.Err()
}
func (s *Store) ProjectImagesByProject(ctx context.Context) (map[int64][]ProjectImage, error) {
rows, err := s.db.QueryContext(ctx, `select id, project_id, path, caption, position from project_images order by project_id asc, position asc, id asc`)
if err != nil {
return nil, err
}
defer rows.Close()
images := make(map[int64][]ProjectImage)
for rows.Next() {
var img ProjectImage
if err := rows.Scan(&img.ID, &img.ProjectID, &img.Path, &img.Caption, &img.Position); err != nil {
return nil, err
}
images[img.ProjectID] = append(images[img.ProjectID], img)
}
return images, rows.Err()
}
func (s *Store) ProjectImageForSlug(ctx context.Context, slug string, imageID int64) (Project, ProjectImage, error) {
p, err := s.ProjectBySlug(ctx, slug)
if err != nil {
return Project{}, ProjectImage{}, err
}
for _, img := range p.Images {
if img.ID == imageID {
return p, img, nil
}
}
return Project{}, ProjectImage{}, sql.ErrNoRows
}
func (s *Store) CreateProject(ctx context.Context, p Project) (int64, error) {
res, err := s.db.ExecContext(ctx, `insert into projects (slug, title, location, year, category, description, cover_image, featured) values (?, ?, ?, ?, ?, ?, ?, ?)`,
p.Slug, p.Title, p.Location, p.Year, p.Category, p.Description, p.CoverImage, boolInt(p.Featured))
if err != nil {
return 0, err
}
return res.LastInsertId()
}
func (s *Store) UpdateProject(ctx context.Context, p Project) error {
_, err := s.db.ExecContext(ctx, `update projects set slug=?, title=?, location=?, year=?, category=?, description=?, cover_image=?, featured=? where id=?`,
p.Slug, p.Title, p.Location, p.Year, p.Category, p.Description, p.CoverImage, boolInt(p.Featured), p.ID)
return err
}
func (s *Store) DeleteProject(ctx context.Context, id int64) error {
_, err := s.db.ExecContext(ctx, `delete from projects where id = ?`, id)
return err
}
func (s *Store) AddProjectImage(ctx context.Context, projectID int64, path, caption string) error {
var pos int
_ = s.db.QueryRowContext(ctx, `select coalesce(max(position), -1) + 1 from project_images where project_id = ?`, projectID).Scan(&pos)
_, err := s.db.ExecContext(ctx, `insert into project_images (project_id, path, caption, position) values (?, ?, ?, ?)`, projectID, path, caption, pos)
return err
}
func (s *Store) DeleteProjectImage(ctx context.Context, id int64) error {
_, err := s.db.ExecContext(ctx, `delete from project_images where id = ?`, id)
return err
}