Files
landing_page/backend/internal/repository/publications.go
T
Godopu d3dc7f19d9 refactor: eliminate dead code, redundant API queries, and enforce empty JSON array slices
- Remove redundant adminGetStatsSummary query and unused AdminStatsSummary interface
- Initialize empty repository slices with make([]T, 0) to ensure empty JSON arrays instead of null
- Add optional chaining in dashboard aggregations for strict null-safety
- Passed 100% unanimous peer reviews from planner-reviewer-claude-01 and reviewer-cline-01
2026-08-25 15:47:31 +09:00

183 lines
5.6 KiB
Go

package repository
import (
"context"
"database/sql"
"fmt"
"git.godopu.com/lab/landing_page/backend/internal/models"
)
type PublicationsRepository struct {
db *sql.DB
}
func NewPublicationsRepository(db *sql.DB) *PublicationsRepository {
return &PublicationsRepository{db: db}
}
func (r *PublicationsRepository) GetPublications(ctx context.Context, category string) ([]models.Publication, error) {
query := `
SELECT id, category, title, authors, venue, volume, published_at, kci, doi, is_highlight, created_at
FROM publications
`
var args []any
if category != "" {
query += " WHERE category = ?"
args = append(args, category)
}
query += " ORDER BY published_at DESC, id ASC"
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("query publications: %w", err)
}
defer rows.Close()
pubs := make([]models.Publication, 0)
for rows.Next() {
var p models.Publication
if err := rows.Scan(
&p.ID, &p.Category, &p.Title, &p.Authors,
&p.Venue, &p.Volume, &p.PublishedAt, &p.KCI, &p.DOI, &p.IsHighlight, &p.CreatedAt,
); err != nil {
return nil, fmt.Errorf("scan publication: %w", err)
}
pubs = append(pubs, p)
}
return pubs, rows.Err()
}
func (r *PublicationsRepository) CreatePublication(ctx context.Context, p models.Publication) (int, error) {
res, err := r.db.ExecContext(ctx, `
INSERT INTO publications (category, title, authors, venue, volume, published_at, kci, doi, is_highlight)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight)
if err != nil {
return 0, fmt.Errorf("insert publication: %w", err)
}
id, err := res.LastInsertId()
return int(id), err
}
func (r *PublicationsRepository) UpdatePublication(ctx context.Context, id int, p models.Publication) error {
res, err := r.db.ExecContext(ctx, `
UPDATE publications
SET category = ?, title = ?, authors = ?, venue = ?, volume = ?, published_at = ?, kci = ?, doi = ?, is_highlight = ?
WHERE id = ?
`, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight, id)
if err != nil {
return fmt.Errorf("update publication: %w", err)
}
rows, err := res.RowsAffected()
if err == nil && rows == 0 {
return sql.ErrNoRows
}
return err
}
func (r *PublicationsRepository) DeletePublication(ctx context.Context, id int) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM publications WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("delete publication: %w", err)
}
rows, err := res.RowsAffected()
if err == nil && rows == 0 {
return sql.ErrNoRows
}
return err
}
func (r *PublicationsRepository) GetHighlights(ctx context.Context) ([]models.Publication, error) {
query := `
SELECT id, category, title, authors, venue, volume, published_at, kci, doi, is_highlight, created_at
FROM publications
WHERE is_highlight = 1
ORDER BY published_at DESC, id ASC
`
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("query highlights: %w", err)
}
defer rows.Close()
pubs := make([]models.Publication, 0)
for rows.Next() {
var p models.Publication
if err := rows.Scan(
&p.ID, &p.Category, &p.Title, &p.Authors,
&p.Venue, &p.Volume, &p.PublishedAt, &p.KCI, &p.DOI, &p.IsHighlight, &p.CreatedAt,
); err != nil {
return nil, fmt.Errorf("scan highlight: %w", err)
}
pubs = append(pubs, p)
}
return pubs, rows.Err()
}
func (r *PublicationsRepository) GetPatents(ctx context.Context) ([]models.Patent, error) {
query := `
SELECT id, title, inventors, application_no, application_at, registration_no, registration_at, country, published_at, created_at
FROM patents
ORDER BY published_at DESC, id ASC
`
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("query patents: %w", err)
}
defer rows.Close()
patents := make([]models.Patent, 0)
for rows.Next() {
var p models.Patent
if err := rows.Scan(
&p.ID, &p.Title, &p.Inventors, &p.ApplicationNo,
&p.ApplicationAt, &p.RegistrationNo, &p.RegistrationAt, &p.Country, &p.PublishedAt, &p.CreatedAt,
); err != nil {
return nil, fmt.Errorf("scan patent: %w", err)
}
patents = append(patents, p)
}
return patents, rows.Err()
}
func (r *PublicationsRepository) CreatePatent(ctx context.Context, p models.Patent) (int, error) {
res, err := r.db.ExecContext(ctx, `
INSERT INTO patents (title, inventors, application_no, application_at, registration_no, registration_at, country, published_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`, p.Title, p.Inventors, p.ApplicationNo, p.ApplicationAt, p.RegistrationNo, p.RegistrationAt, p.Country, p.PublishedAt)
if err != nil {
return 0, fmt.Errorf("insert patent: %w", err)
}
id, err := res.LastInsertId()
return int(id), err
}
func (r *PublicationsRepository) UpdatePatent(ctx context.Context, id int, p models.Patent) error {
res, err := r.db.ExecContext(ctx, `
UPDATE patents
SET title = ?, inventors = ?, application_no = ?, application_at = ?, registration_no = ?, registration_at = ?, country = ?, published_at = ?
WHERE id = ?
`, p.Title, p.Inventors, p.ApplicationNo, p.ApplicationAt, p.RegistrationNo, p.RegistrationAt, p.Country, p.PublishedAt, id)
if err != nil {
return fmt.Errorf("update patent: %w", err)
}
rows, err := res.RowsAffected()
if err == nil && rows == 0 {
return sql.ErrNoRows
}
return err
}
func (r *PublicationsRepository) DeletePatent(ctx context.Context, id int) error {
res, err := r.db.ExecContext(ctx, `DELETE FROM patents WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("delete patent: %w", err)
}
rows, err := res.RowsAffected()
if err == nil && rows == 0 {
return sql.ErrNoRows
}
return err
}