package spells import ( "dk/internal/database" "fmt" "zombiezen.com/go/sqlite" ) // Builder provides a fluent interface for creating spells type Builder struct { spell *Spell db *database.DB } // NewBuilder creates a new spell builder func NewBuilder(db *database.DB) *Builder { return &Builder{ spell: &Spell{db: db}, db: db, } } // WithName sets the spell name func (b *Builder) WithName(name string) *Builder { b.spell.Name = name return b } // WithMP sets the spell's mana point cost func (b *Builder) WithMP(mp int) *Builder { b.spell.MP = mp return b } // WithAttribute sets the spell's attribute (power/effectiveness) func (b *Builder) WithAttribute(attribute int) *Builder { b.spell.Attribute = attribute return b } // WithType sets the spell type func (b *Builder) WithType(spellType int) *Builder { b.spell.Type = spellType return b } // Create saves the spell to the database and returns it func (b *Builder) Create() (*Spell, error) { // Use a transaction to ensure we can get the ID var spell *Spell err := b.db.Transaction(func(tx *database.Tx) error { query := `INSERT INTO spells (name, mp, attribute, type) VALUES (?, ?, ?, ?)` if err := tx.Exec(query, b.spell.Name, b.spell.MP, b.spell.Attribute, b.spell.Type); err != nil { return fmt.Errorf("failed to insert spell: %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 spell with the ID spell = &Spell{ ID: lastID, Name: b.spell.Name, MP: b.spell.MP, Attribute: b.spell.Attribute, Type: b.spell.Type, db: b.db, } return nil }) if err != nil { return nil, fmt.Errorf("failed to create spell: %w", err) } return spell, nil }