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 }