89 lines
1.8 KiB
Go

package drops
import (
"dk/internal/database"
"fmt"
"zombiezen.com/go/sqlite"
)
// Builder provides a fluent interface for creating drops
type Builder struct {
drop *Drop
db *database.DB
}
// NewBuilder creates a new drop builder
func NewBuilder(db *database.DB) *Builder {
return &Builder{
drop: &Drop{db: db},
db: db,
}
}
// 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 := b.db.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,
db: b.db,
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to create drop: %w", err)
}
return drop, nil
}