83 lines
1.7 KiB
Go

package news
import (
"fmt"
"time"
"dk/internal/database"
"zombiezen.com/go/sqlite"
)
// Builder provides a fluent interface for creating news posts
type Builder struct {
news *News
}
// NewBuilder creates a new news builder
func NewBuilder() *Builder {
return &Builder{
news: &News{
Posted: time.Now().Unix(), // Default to current time
},
}
}
// WithAuthor sets the author ID
func (b *Builder) WithAuthor(authorID int) *Builder {
b.news.Author = authorID
return b
}
// WithContent sets the news content
func (b *Builder) WithContent(content string) *Builder {
b.news.Content = content
return b
}
// WithPosted sets the posted timestamp
func (b *Builder) WithPosted(posted int64) *Builder {
b.news.Posted = posted
return b
}
// WithPostedTime sets the posted timestamp from a time.Time
func (b *Builder) WithPostedTime(t time.Time) *Builder {
b.news.Posted = t.Unix()
return b
}
// Create saves the news post to the database and returns the created news with ID
func (b *Builder) Create() (*News, error) {
// Use a transaction to ensure we can get the ID
var news *News
err := database.Transaction(func(tx *database.Tx) error {
query := `INSERT INTO news (author, posted, content)
VALUES (?, ?, ?)`
if err := tx.Exec(query, b.news.Author, b.news.Posted, b.news.Content); err != nil {
return fmt.Errorf("failed to insert news: %w", err)
}
// Get the last insert ID
var id int
err := tx.Query("SELECT last_insert_rowid()", func(stmt *sqlite.Stmt) error {
id = stmt.ColumnInt(0)
return nil
})
if err != nil {
return fmt.Errorf("failed to get insert ID: %w", err)
}
b.news.ID = id
news = b.news
return nil
})
if err != nil {
return nil, err
}
return news, nil
}