112 lines
2.3 KiB
Go

package towns
import (
"fmt"
"dk/internal/database"
"zombiezen.com/go/sqlite"
)
// Builder provides a fluent interface for creating towns
type Builder struct {
town *Town
}
// NewBuilder creates a new town builder
func NewBuilder() *Builder {
return &Builder{
town: &Town{},
}
}
// WithName sets the town name
func (b *Builder) WithName(name string) *Builder {
b.town.Name = name
return b
}
// WithX sets the X coordinate
func (b *Builder) WithX(x int) *Builder {
b.town.X = x
return b
}
// WithY sets the Y coordinate
func (b *Builder) WithY(y int) *Builder {
b.town.Y = y
return b
}
// WithCoordinates sets both X and Y coordinates
func (b *Builder) WithCoordinates(x, y int) *Builder {
b.town.X = x
b.town.Y = y
return b
}
// WithInnCost sets the inn cost
func (b *Builder) WithInnCost(cost int) *Builder {
b.town.InnCost = cost
return b
}
// WithMapCost sets the map cost
func (b *Builder) WithMapCost(cost int) *Builder {
b.town.MapCost = cost
return b
}
// WithTPCost sets the teleport cost
func (b *Builder) WithTPCost(cost int) *Builder {
b.town.TPCost = cost
return b
}
// WithShopList sets the shop list as a comma-separated string
func (b *Builder) WithShopList(shopList string) *Builder {
b.town.ShopList = shopList
return b
}
// WithShopItems sets the shop items from a slice of item IDs
func (b *Builder) WithShopItems(items []string) *Builder {
b.town.SetShopItems(items)
return b
}
// Create saves the town to the database and returns the created town with ID
func (b *Builder) Create() (*Town, error) {
// Use a transaction to ensure we can get the ID
var town *Town
err := database.Transaction(func(tx *database.Tx) error {
query := `INSERT INTO towns (name, x, y, inn_cost, map_cost, tp_cost, shop_list)
VALUES (?, ?, ?, ?, ?, ?, ?)`
if err := tx.Exec(query, b.town.Name, b.town.X, b.town.Y,
b.town.InnCost, b.town.MapCost, b.town.TPCost, b.town.ShopList); err != nil {
return fmt.Errorf("failed to insert town: %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.town.ID = id
town = b.town
return nil
})
if err != nil {
return nil, err
}
return town, nil
}