package repository import ( "database/sql" "encoding/json" "fmt" "floorvisualizer/internal/model" ) func InsertArticles(d *sql.DB, articles []model.Article) error { for i := range articles { articles[i].SetImageJSON() } const batchSize = 50 for start := 0; start < len(articles); start += batchSize { end := start + batchSize if end > len(articles) { end = len(articles) } batch := articles[start:end] for _, a := range batch { _, err := d.Exec(` INSERT INTO articles (title, summary, content, cover_url, image_urls) VALUES ($1,$2,$3,$4,$5) `, a.Title, a.Summary, a.Content, a.CoverURL, a.ImageJSON) if err != nil { return fmt.Errorf("insert article: %w", err) } } } return nil } func GetArticleByID(d *sql.DB, id int) (*model.Article, error) { var a model.Article var imageJSON string err := d.QueryRow(` SELECT id, title, summary, content, cover_url, image_urls::text, created_at FROM articles WHERE id = $1 `, id).Scan(&a.ID, &a.Title, &a.Summary, &a.Content, &a.CoverURL, &imageJSON, &a.CreatedAt) if err != nil { return nil, err } json.Unmarshal([]byte(imageJSON), &a.ImageURLs) if a.ImageURLs == nil { a.ImageURLs = []string{} } return &a, nil } func ListArticles(d *sql.DB, page, limit int) ([]model.Article, int, error) { if limit <= 0 { limit = 10 } if page <= 0 { page = 1 } var total int if err := d.QueryRow("SELECT COUNT(*) FROM articles").Scan(&total); err != nil { return nil, 0, err } offset := (page - 1) * limit rows, err := d.Query(` SELECT id, title, summary, content, cover_url, image_urls::text, created_at FROM articles ORDER BY id LIMIT $1 OFFSET $2 `, limit, offset) if err != nil { return nil, 0, err } defer rows.Close() var out []model.Article for rows.Next() { var a model.Article var imageJSON string if err := rows.Scan(&a.ID, &a.Title, &a.Summary, &a.Content, &a.CoverURL, &imageJSON, &a.CreatedAt); err != nil { return nil, 0, err } json.Unmarshal([]byte(imageJSON), &a.ImageURLs) if a.ImageURLs == nil { a.ImageURLs = []string{} } out = append(out, a) } return out, total, rows.Err() } func RandomArticles(d *sql.DB, count int) ([]model.Article, error) { rows, err := d.Query(` SELECT id, title, summary, content, cover_url, image_urls::text, created_at FROM articles ORDER BY RANDOM() LIMIT $1 `, count) if err != nil { return nil, err } defer rows.Close() var out []model.Article for rows.Next() { var a model.Article var imageJSON string if err := rows.Scan(&a.ID, &a.Title, &a.Summary, &a.Content, &a.CoverURL, &imageJSON, &a.CreatedAt); err != nil { return nil, err } json.Unmarshal([]byte(imageJSON), &a.ImageURLs) if a.ImageURLs == nil { a.ImageURLs = []string{} } out = append(out, a) } return out, rows.Err() }