package babble import ( "fmt" "time" "dk/internal/database" "zombiezen.com/go/sqlite" ) // Builder provides a fluent interface for creating babble messages type Builder struct { babble *Babble } // NewBuilder creates a new babble builder func NewBuilder() *Builder { return &Builder{ babble: &Babble{ Posted: time.Now().Unix(), // Default to current time }, } } // WithAuthor sets the author username func (b *Builder) WithAuthor(author string) *Builder { b.babble.Author = author return b } // WithBabble sets the message content func (b *Builder) WithBabble(message string) *Builder { b.babble.Babble = message return b } // WithMessage is an alias for WithBabble for more intuitive usage func (b *Builder) WithMessage(message string) *Builder { return b.WithBabble(message) } // WithPosted sets the posted timestamp func (b *Builder) WithPosted(posted int64) *Builder { b.babble.Posted = posted return b } // WithPostedTime sets the posted timestamp from a time.Time func (b *Builder) WithPostedTime(t time.Time) *Builder { b.babble.Posted = t.Unix() return b } // Create saves the babble message to the database and returns the created babble with ID func (b *Builder) Create() (*Babble, error) { // Use a transaction to ensure we can get the ID var babble *Babble err := database.Transaction(func(tx *database.Tx) error { query := `INSERT INTO babble (posted, author, babble) VALUES (?, ?, ?)` if err := tx.Exec(query, b.babble.Posted, b.babble.Author, b.babble.Babble); err != nil { return fmt.Errorf("failed to insert babble: %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.babble.ID = id babble = b.babble return nil }) if err != nil { return nil, err } return babble, nil }