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 db *database.DB } // NewBuilder creates a new news builder func NewBuilder(db *database.DB) *Builder { return &Builder{ news: &News{ db: db, Posted: time.Now().Unix(), // Default to current time }, db: db, } } // 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 := b.db.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 }