Exemple #1
0
// ListTeamsForSeason is a http handler that returns a brief summary
// of all of the NBA games for the given season.
func (s *Server) ListGamesForSeason(ctx context.Context, rw http.ResponseWriter, req *http.Request, ps parameterSet) (interface{}, error) {
	var season data.Season
	err := season.UnmarshalText([]byte(ps["season"]))
	if err != nil {
		return nil, ErrBadRequest("Invalid season identifier")
	}

	const q = `
		SELECT games.id, home_team_id, visitor_team_id,
		       status, time, length_minutes
		FROM games
		WHERE season = ?
		ORDER BY time DESC, status ASC, length_minutes ASC
	`

	var games []*gameSummary
	err = s.db.DB.Select(&games, q, season.String())
	if err != nil {
		return nil, err
	}
	for _, g := range games {
		g.HomeTeam = teamSummaryFromData(s.teams.ByID(g.HomeTeamID))
		g.VisitorTeam = teamSummaryFromData(s.teams.ByID(g.VisitorTeamID))
	}
	return games, nil
}
Exemple #2
0
// ListPlayersForSeason is a http handler that returns a list of all the
// players active during the given season.
func (s *Server) RetrievePlayerForSeason(ctx context.Context, rw http.ResponseWriter, req *http.Request, ps parameterSet) (interface{}, error) {
	var (
		season   data.Season
		playerID int
	)
	err := season.UnmarshalText([]byte(ps["season"]))
	if err != nil {
		return nil, ErrBadRequest("Invalid season identifier")
	}
	playerID, err = ps.Int("playerID")
	if err != nil {
		return nil, ErrBadRequest("Bad player identifier")
	}

	var player data.PlayerDetails
	err = s.db.DB.Get(&player, playerID)
	if err == sql.ErrNoRows {
		return nil, ErrNotFound("Player not found")
	}
	if err != nil {
		return nil, err
	}

	resp := struct {
		Player      data.PlayerDetails `json:"player"`
		GamesPlayed []*playerStatLine  `json:"games_played"`
	}{
		Player:      player,
		GamesPlayed: []*playerStatLine{},
	}

	// Pull in their games too.
	const q = `
		SELECT player_game_stats.team_id, player_game_stats.game_id, stats.*,
		       games.home_team_id, games.visitor_team_id, games.time
		FROM player_game_stats
		INNER JOIN stats ON player_game_stats.stats_id = stats.id
		INNER JOIN games ON player_game_stats.game_id = games.id
		WHERE games.season = ? AND player_game_stats.player_id = ?
		ORDER BY games.time DESC
	`
	err = s.db.DB.Select(&resp.GamesPlayed, q, season.String(), playerID)
	if err != nil {
		return nil, err
	}
	for _, gp := range resp.GamesPlayed {
		if gp.TeamID == gp.HomeTeamID {
			gp.HomeOrAway = data.Home
		} else {
			gp.HomeOrAway = data.Away
		}

		// Calculate percentages, and other derived statistics that aren't
		// actually stored in the nbagame db because they're redundant.
		gp.Stats.Calculate()
	}

	return resp, nil
}
Exemple #3
0
// ListPlayersForSeason is a http handler that returns a list of all the
// players active during the given season.
// TODO(jackson): This endpoint isn't strictly correct, because if players
// take a year off, we'll incorrectly include them in that year.
func (s *Server) ListPlayersForSeason(ctx context.Context, rw http.ResponseWriter, req *http.Request, ps parameterSet) (interface{}, error) {
	var season data.Season
	err := season.UnmarshalText([]byte(ps["season"]))
	if err != nil {
		return nil, ErrBadRequest("Invalid season identifier")
	}

	const q = `
		SELECT * FROM players
		WHERE NOT dleague AND career_start <= ? AND career_end >= ?
		ORDER BY last_name, first_name ASC
	`

	var players []*data.PlayerDetails
	err = s.db.DB.Select(&players, q, season.SpringYear(), season.FallYear())
	if err != nil {
		return nil, err
	}
	return players, nil
}
Exemple #4
0
// RetrieveGameForSeason is a http handler that returns a full synopsis
// of a particular game.
func (s *Server) RetrieveGameForSeason(ctx context.Context, rw http.ResponseWriter, req *http.Request, ps parameterSet) (interface{}, error) {
	var season data.Season
	err := season.UnmarshalText([]byte(ps["season"]))
	if err != nil {
		return nil, ErrBadRequest("Invalid season identifier")
	}

	var details data.GameDetails
	err = s.db.DB.Get(&details, ps.String("gameID"))
	if err == sql.ErrNoRows {
		return nil, ErrNotFound("No such game exists")
	}
	if err != nil {
		return nil, err
	}

	g := &game{
		ID:     details.ID.String(),
		Date:   details.Date,
		Status: details.Status,
		HomeTeam: teamGamePerformance{
			teamSummary: *teamSummaryFromData(s.teams.ByID(details.HomeTeamID)),
		},
		VisitorTeam: teamGamePerformance{
			teamSummary: *teamSummaryFromData(s.teams.ByID(details.VisitorTeamID)),
		},
		Minutes:     details.LengthMinutes,
		Attendance:  details.Attendance,
		LeadChanges: details.LeadChanges,
		TimesTied:   details.TimesTied,
	}

	// Pull in data about the refs that officiated the game.
	const officialsQ = `
		SELECT o.id, o.first_name, o.last_name, o.jersey_number
		FROM officiated
		INNER JOIN officials o ON officiated.official_id = o.id
		WHERE officiated.game_id = ?
		ORDER BY o.last_name, o.first_name ASC
	`
	err = s.db.DB.Select(&g.Officials, officialsQ, g.ID)
	if err != nil {
		return nil, err
	}

	// Pull in aggregated stat lines for each team.
	const teamStatsQ = `
		SELECT team_game_stats.team_id, stats.*
		FROM team_game_stats
		INNER JOIN stats ON team_game_stats.stats_id = stats.id
		WHERE team_game_stats.game_id = ?
	`
	var teamStats []*struct {
		data.Stats
		TeamID int `db:"team_id"`
	}
	err = s.db.DB.Select(&teamStats, teamStatsQ, g.ID)
	if err != nil {
		return nil, err
	}
	for _, ts := range teamStats {
		ts.Stats.Calculate()
		if ts.TeamID == g.HomeTeam.ID {
			g.HomeTeam.Stats = &ts.Stats
		}
		if ts.TeamID == g.VisitorTeam.ID {
			g.VisitorTeam.Stats = &ts.Stats
		}
	}

	// Pull in aggregated stat lines for each player.
	const playerStatsQ = `
		SELECT stats.*, player_game_stats.team_id, player_game_stats.player_id, players.first_name, players.last_name
		FROM player_game_stats
		INNER JOIN stats ON player_game_stats.stats_id = stats.id
		INNER JOIN players ON players.id = player_game_stats.player_id
		WHERE player_game_stats.game_id = ?
		ORDER BY stats.points DESC
	`
	var playerStats []*struct {
		TeamID    int    `db:"team_id"`
		PlayerID  string `db:"player_id"`
		FirstName string `db:"first_name"`
		LastName  string `db:"last_name"`
		data.Stats
	}
	err = s.db.DB.Select(&playerStats, playerStatsQ, g.ID)
	if err != nil {
		return nil, err
	}
	for _, ps := range playerStats {
		pgp := playerGamePerformance{
			PlayerID:  ps.PlayerID,
			FirstName: ps.FirstName,
			LastName:  ps.LastName,
			Stats:     ps.Stats,
		}

		if ps.TeamID == g.HomeTeam.ID {
			g.HomeTeam.Players = append(g.HomeTeam.Players, pgp)
		}
		if ps.TeamID == g.VisitorTeam.ID {
			g.VisitorTeam.Players = append(g.VisitorTeam.Players, pgp)
		}
	}

	return g, nil
}