package drops import ( "dk/internal/database" "fmt" "zombiezen.com/go/sqlite" ) // Builder provides a fluent interface for creating drops type Builder struct { drop *Drop } // NewBuilder creates a new drop builder func NewBuilder() *Builder { return &Builder{ drop: &Drop{}, } } // WithName sets the drop name func (b *Builder) WithName(name string) *Builder { b.drop.Name = name return b } // WithLevel sets the drop level requirement func (b *Builder) WithLevel(level int) *Builder { b.drop.Level = level return b } // WithType sets the drop type func (b *Builder) WithType(dropType int) *Builder { b.drop.Type = dropType return b } // WithAtt sets the attributes func (b *Builder) WithAtt(att string) *Builder { b.drop.Att = att return b } // Create saves the drop to the database and returns it func (b *Builder) Create() (*Drop, error) { // Use a transaction to ensure we can get the ID var drop *Drop err := database.Transaction(func(tx *database.Tx) error { query := `INSERT INTO drops (name, level, type, att) VALUES (?, ?, ?, ?)` if err := tx.Exec(query, b.drop.Name, b.drop.Level, b.drop.Type, b.drop.Att); err != nil { return fmt.Errorf("failed to insert drop: %w", err) } // Get the last inserted ID within the same transaction var lastID int err := tx.Query("SELECT last_insert_rowid()", func(stmt *sqlite.Stmt) error { lastID = stmt.ColumnInt(0) return nil }) if err != nil { return fmt.Errorf("failed to get last insert ID: %w", err) } // Create the drop with the ID drop = &Drop{ ID: lastID, Name: b.drop.Name, Level: b.drop.Level, Type: b.drop.Type, Att: b.drop.Att, } return nil }) if err != nil { return nil, fmt.Errorf("failed to create drop: %w", err) } return drop, nil }