115 lines
2.4 KiB
Go
115 lines
2.4 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
|
|
db *database.DB
|
|
}
|
|
|
|
// NewBuilder creates a new town builder
|
|
func NewBuilder(db *database.DB) *Builder {
|
|
return &Builder{
|
|
town: &Town{
|
|
db: db,
|
|
},
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// 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 := b.db.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
|
|
} |