171 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"log"
 | 
						|
)
 | 
						|
 | 
						|
type PlayerService struct {
 | 
						|
	db *DB
 | 
						|
}
 | 
						|
type PlayerServiceQuery struct {
 | 
						|
	Name *string `db:"name"`
 | 
						|
	ID   *int64  `db:"id"`
 | 
						|
}
 | 
						|
 | 
						|
func (ps *PlayerService) Query(query PlayerServiceQuery) ([]Player, error) {
 | 
						|
	res := []Player{}
 | 
						|
	sqlQuery := "SELECT id, name, guild FROM player"
 | 
						|
	whereQuery := BuildWhereQuery(query)
 | 
						|
	if whereQuery != "" {
 | 
						|
		sqlQuery += " " + whereQuery
 | 
						|
	}
 | 
						|
 | 
						|
	rows, err := ps.db.readConn.Query(sqlQuery)
 | 
						|
	if err != nil {
 | 
						|
		return res, fmt.Errorf("failed getting players for query %q: %v", sqlQuery, err)
 | 
						|
	}
 | 
						|
	defer rows.Close()
 | 
						|
 | 
						|
	for rows.Next() {
 | 
						|
		player := Player{}
 | 
						|
		err := rows.Scan(&player.ID, &player.Name, &player.Guild.ID)
 | 
						|
		if err != nil {
 | 
						|
			return res, fmt.Errorf("failed scanning player: %v", err)
 | 
						|
		}
 | 
						|
		res = append(res, player)
 | 
						|
	}
 | 
						|
 | 
						|
	return res, nil
 | 
						|
}
 | 
						|
 | 
						|
func (ps *PlayerService) Create(name string, guild Guild) (Player, error) {
 | 
						|
	log.Printf("Creating player %s in guild %s", name, guild.Name)
 | 
						|
	player := Player{}
 | 
						|
	res, err := ps.db.writeConn.Exec("insert into player (name, guild) values (?, ?)", name, guild.ID)
 | 
						|
	if err != nil {
 | 
						|
		return player, fmt.Errorf("failed to insert player: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	id, err := res.LastInsertId()
 | 
						|
	if err != nil {
 | 
						|
		return player, fmt.Errorf("failed to get last insert id: %v", err)
 | 
						|
	}
 | 
						|
	log.Printf("Created player %s in guild %s with id %d", name, guild.Name, id)
 | 
						|
 | 
						|
	qres, err := ps.Query(PlayerServiceQuery{ID: &id})
 | 
						|
	if err != nil {
 | 
						|
		return player, fmt.Errorf("failed getting player for id %d: %v", id, err)
 | 
						|
	}
 | 
						|
	if len(qres) > 1 {
 | 
						|
		return player, fmt.Errorf("more than one player found for id %d", id)
 | 
						|
	}
 | 
						|
 | 
						|
	return qres[0], nil
 | 
						|
}
 | 
						|
 | 
						|
func (ps *PlayerService) GetOrCreate(name string, guild Guild) (Player, error) {
 | 
						|
	player := Player{}
 | 
						|
	players, err := ps.Query(PlayerServiceQuery{Name: &name})
 | 
						|
	if len(players) > 1 {
 | 
						|
		return player, fmt.Errorf("more than one player found for name %s", name)
 | 
						|
	}
 | 
						|
	if err != nil || len(players) == 0 {
 | 
						|
		player, err = ps.Create(name, guild)
 | 
						|
		if err != nil {
 | 
						|
			return player, fmt.Errorf("failed creating player: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if len(players) == 1 {
 | 
						|
		player = players[0]
 | 
						|
	}
 | 
						|
	return player, nil
 | 
						|
}
 | 
						|
 | 
						|
type (
 | 
						|
	FullPlayer struct {
 | 
						|
		ID    int64  `json:"id"`
 | 
						|
		Name  string `json:"name"`
 | 
						|
		Guild struct {
 | 
						|
			ID   int64  `json:"id"`
 | 
						|
			Name string `json:"name"`
 | 
						|
		} `json:"guild"`
 | 
						|
		Associations []FullPlayerAssociation `json:"associations"`
 | 
						|
		Notes        []FullPlayerNote        `json:"notes"`
 | 
						|
	}
 | 
						|
 | 
						|
	FullPlayerAssociation struct {
 | 
						|
		ID   int64  `json:"id"`
 | 
						|
		Name string `json:"name"`
 | 
						|
		Note string `json:"note"`
 | 
						|
	}
 | 
						|
 | 
						|
	FullPlayerNote struct {
 | 
						|
		ID        int64  `json:"id"`
 | 
						|
		Content   string `json:"content"`
 | 
						|
		Timestamp string `json:"timestamp"`
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
func (ps *PlayerService) GetAllPlayerInfo(name string, nnotes int) (FullPlayer, error) {
 | 
						|
	res := FullPlayer{}
 | 
						|
 | 
						|
	err := ps.db.readConn.QueryRow(selectPlayer, name).Scan(&res.ID, &res.Name, &res.Guild.ID, &res.Guild.Name)
 | 
						|
	if err != nil {
 | 
						|
		return res, fmt.Errorf("failed getting player info: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	rows, err := ps.db.readConn.Query(selectAssociation, res.ID)
 | 
						|
	if err != nil {
 | 
						|
		return res, fmt.Errorf("failed getting player associations: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	for rows.Next() {
 | 
						|
		assoc := FullPlayerAssociation{}
 | 
						|
		err := rows.Scan(&assoc.ID, &assoc.Name, &assoc.Note)
 | 
						|
		if err != nil {
 | 
						|
			return res, fmt.Errorf("failed scanning association: %v", err)
 | 
						|
		}
 | 
						|
		res.Associations = append(res.Associations, assoc)
 | 
						|
	}
 | 
						|
	rows.Close()
 | 
						|
 | 
						|
	rows, err = ps.db.readConn.Query(selectNotes, res.ID, nnotes)
 | 
						|
	if err != nil {
 | 
						|
		return res, fmt.Errorf("failed getting player notes: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	for rows.Next() {
 | 
						|
		note := FullPlayerNote{}
 | 
						|
		err := rows.Scan(¬e.ID, ¬e.Content, ¬e.Timestamp)
 | 
						|
		if err != nil {
 | 
						|
			return res, fmt.Errorf("failed scanning note: %v", err)
 | 
						|
		}
 | 
						|
		res.Notes = append(res.Notes, note)
 | 
						|
	}
 | 
						|
	rows.Close()
 | 
						|
 | 
						|
	return res, nil
 | 
						|
}
 | 
						|
 | 
						|
func (ps *PlayerService) GetAllPlayers() ([]Player, error) {
 | 
						|
	res := []Player{}
 | 
						|
 | 
						|
	rows, err := ps.db.readConn.Query(selectPlayers)
 | 
						|
	if err != nil {
 | 
						|
		return res, fmt.Errorf("failed getting players: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	for rows.Next() {
 | 
						|
		player := Player{}
 | 
						|
		err := rows.Scan(&player.ID, &player.Name, &player.Guild.ID, &player.Guild.Name, &player.Notes, &player.Associations)
 | 
						|
		if err != nil {
 | 
						|
			return res, fmt.Errorf("failed scanning player: %v", err)
 | 
						|
		}
 | 
						|
		res = append(res, player)
 | 
						|
	}
 | 
						|
	rows.Close()
 | 
						|
 | 
						|
	return res, nil
 | 
						|
}
 |