190 lines
4.8 KiB
Go
190 lines
4.8 KiB
Go
package appearances
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
// Appearance represents a single appearance with ID, name, and client version requirements
|
|
type Appearance struct {
|
|
ID int32 `json:"id"` // Appearance ID
|
|
Name string `json:"name"` // Appearance name
|
|
MinClient int16 `json:"min_client"` // Minimum client version required
|
|
|
|
db *database.Database `json:"-"` // Database connection
|
|
isNew bool `json:"-"` // Whether this is a new appearance
|
|
}
|
|
|
|
// New creates a new appearance with the given database
|
|
func New(db *database.Database) *Appearance {
|
|
return &Appearance{
|
|
db: db,
|
|
isNew: true,
|
|
}
|
|
}
|
|
|
|
// NewWithData creates a new appearance with data
|
|
func NewWithData(id int32, name string, minClientVersion int16, db *database.Database) *Appearance {
|
|
return &Appearance{
|
|
ID: id,
|
|
Name: name,
|
|
MinClient: minClientVersion,
|
|
db: db,
|
|
isNew: true,
|
|
}
|
|
}
|
|
|
|
// Load loads an appearance by ID from the database
|
|
func Load(db *database.Database, id int32) (*Appearance, error) {
|
|
appearance := &Appearance{
|
|
db: db,
|
|
isNew: false,
|
|
}
|
|
|
|
query := `SELECT appearance_id, name, min_client_version FROM appearances WHERE appearance_id = ?`
|
|
row := db.QueryRow(query, id)
|
|
|
|
err := row.Scan(&appearance.ID, &appearance.Name, &appearance.MinClient)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load appearance %d: %w", id, err)
|
|
}
|
|
|
|
return appearance, nil
|
|
}
|
|
|
|
// GetID returns the appearance ID (implements Identifiable interface)
|
|
func (a *Appearance) GetID() int32 {
|
|
return a.ID
|
|
}
|
|
|
|
// GetName returns the appearance name
|
|
func (a *Appearance) GetName() string {
|
|
return a.Name
|
|
}
|
|
|
|
// GetMinClientVersion returns the minimum client version required
|
|
func (a *Appearance) GetMinClientVersion() int16 {
|
|
return a.MinClient
|
|
}
|
|
|
|
// GetNameString returns the name as a string (alias for GetName for C++ compatibility)
|
|
func (a *Appearance) GetNameString() string {
|
|
return a.Name
|
|
}
|
|
|
|
// SetName sets the appearance name
|
|
func (a *Appearance) SetName(name string) {
|
|
a.Name = name
|
|
}
|
|
|
|
// SetMinClientVersion sets the minimum client version
|
|
func (a *Appearance) SetMinClientVersion(version int16) {
|
|
a.MinClient = version
|
|
}
|
|
|
|
// IsCompatibleWithClient returns true if the appearance is compatible with the given client version
|
|
func (a *Appearance) IsCompatibleWithClient(clientVersion int16) bool {
|
|
return clientVersion >= a.MinClient
|
|
}
|
|
|
|
// IsNew returns true if this is a new appearance not yet saved to database
|
|
func (a *Appearance) IsNew() bool {
|
|
return a.isNew
|
|
}
|
|
|
|
// Save saves the appearance to the database
|
|
func (a *Appearance) Save() error {
|
|
if a.db == nil {
|
|
return fmt.Errorf("no database connection available")
|
|
}
|
|
|
|
if a.isNew {
|
|
return a.insert()
|
|
}
|
|
return a.update()
|
|
}
|
|
|
|
// Delete removes the appearance from the database
|
|
func (a *Appearance) Delete() error {
|
|
if a.db == nil {
|
|
return fmt.Errorf("no database connection available")
|
|
}
|
|
|
|
if a.isNew {
|
|
return fmt.Errorf("cannot delete unsaved appearance")
|
|
}
|
|
|
|
query := `DELETE FROM appearances WHERE appearance_id = ?`
|
|
_, err := a.db.Exec(query, a.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete appearance %d: %w", a.ID, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Reload reloads the appearance data from the database
|
|
func (a *Appearance) Reload() error {
|
|
if a.db == nil {
|
|
return fmt.Errorf("no database connection available")
|
|
}
|
|
|
|
if a.isNew {
|
|
return fmt.Errorf("cannot reload unsaved appearance")
|
|
}
|
|
|
|
query := `SELECT name, min_client_version FROM appearances WHERE appearance_id = ?`
|
|
row := a.db.QueryRow(query, a.ID)
|
|
|
|
err := row.Scan(&a.Name, &a.MinClient)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to reload appearance %d: %w", a.ID, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Clone creates a copy of the appearance
|
|
func (a *Appearance) Clone() *Appearance {
|
|
return &Appearance{
|
|
ID: a.ID,
|
|
Name: a.Name,
|
|
MinClient: a.MinClient,
|
|
db: a.db,
|
|
isNew: true, // Clone is always new
|
|
}
|
|
}
|
|
|
|
// insert inserts a new appearance into the database
|
|
func (a *Appearance) insert() error {
|
|
query := `INSERT INTO appearances (appearance_id, name, min_client_version) VALUES (?, ?, ?)`
|
|
_, err := a.db.Exec(query, a.ID, a.Name, a.MinClient)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to insert appearance: %w", err)
|
|
}
|
|
|
|
a.isNew = false
|
|
return nil
|
|
}
|
|
|
|
// update updates an existing appearance in the database
|
|
func (a *Appearance) update() error {
|
|
query := `UPDATE appearances SET name = ?, min_client_version = ? WHERE appearance_id = ?`
|
|
result, err := a.db.Exec(query, a.Name, a.MinClient, a.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update appearance: %w", err)
|
|
}
|
|
|
|
rowsAffected, err := result.RowsAffected()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get rows affected: %w", err)
|
|
}
|
|
|
|
if rowsAffected == 0 {
|
|
return fmt.Errorf("appearance %d not found for update", a.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|