[FEATURE] Detailed stats about player weapon usage and hitgroups (#1)
Reviewed-on: https://git.harting.dev/CSGOWTF/csgowtfd/pulls/1 Co-authored-by: Giovanni Harting <539@idlegandalf.com> Co-committed-by: Giovanni Harting <539@idlegandalf.com>
This commit is contained in:
@@ -8,6 +8,8 @@ import (
|
||||
"csgowtfd/ent/player"
|
||||
"csgowtfd/ent/predicate"
|
||||
"csgowtfd/ent/stats"
|
||||
"csgowtfd/ent/weaponstats"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -27,10 +29,10 @@ type StatsQuery struct {
|
||||
fields []string
|
||||
predicates []predicate.Stats
|
||||
// eager-loading edges.
|
||||
withMatches *MatchQuery
|
||||
withPlayers *PlayerQuery
|
||||
withFKs bool
|
||||
modifiers []func(s *sql.Selector)
|
||||
withMatches *MatchQuery
|
||||
withPlayers *PlayerQuery
|
||||
withWeaponStats *WeaponStatsQuery
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
@@ -111,6 +113,28 @@ func (sq *StatsQuery) QueryPlayers() *PlayerQuery {
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryWeaponStats chains the current query on the "weapon_stats" edge.
|
||||
func (sq *StatsQuery) QueryWeaponStats() *WeaponStatsQuery {
|
||||
query := &WeaponStatsQuery{config: sq.config}
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := sq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := sq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(stats.Table, stats.FieldID, selector),
|
||||
sqlgraph.To(weaponstats.Table, weaponstats.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, stats.WeaponStatsTable, stats.WeaponStatsColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(sq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first Stats entity from the query.
|
||||
// Returns a *NotFoundError when no Stats was found.
|
||||
func (sq *StatsQuery) First(ctx context.Context) (*Stats, error) {
|
||||
@@ -287,13 +311,14 @@ func (sq *StatsQuery) Clone() *StatsQuery {
|
||||
return nil
|
||||
}
|
||||
return &StatsQuery{
|
||||
config: sq.config,
|
||||
limit: sq.limit,
|
||||
offset: sq.offset,
|
||||
order: append([]OrderFunc{}, sq.order...),
|
||||
predicates: append([]predicate.Stats{}, sq.predicates...),
|
||||
withMatches: sq.withMatches.Clone(),
|
||||
withPlayers: sq.withPlayers.Clone(),
|
||||
config: sq.config,
|
||||
limit: sq.limit,
|
||||
offset: sq.offset,
|
||||
order: append([]OrderFunc{}, sq.order...),
|
||||
predicates: append([]predicate.Stats{}, sq.predicates...),
|
||||
withMatches: sq.withMatches.Clone(),
|
||||
withPlayers: sq.withPlayers.Clone(),
|
||||
withWeaponStats: sq.withWeaponStats.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: sq.sql.Clone(),
|
||||
path: sq.path,
|
||||
@@ -322,6 +347,17 @@ func (sq *StatsQuery) WithPlayers(opts ...func(*PlayerQuery)) *StatsQuery {
|
||||
return sq
|
||||
}
|
||||
|
||||
// WithWeaponStats tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "weapon_stats" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (sq *StatsQuery) WithWeaponStats(opts ...func(*WeaponStatsQuery)) *StatsQuery {
|
||||
query := &WeaponStatsQuery{config: sq.config}
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
sq.withWeaponStats = query
|
||||
return sq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
@@ -386,19 +422,13 @@ func (sq *StatsQuery) prepareQuery(ctx context.Context) error {
|
||||
func (sq *StatsQuery) sqlAll(ctx context.Context) ([]*Stats, error) {
|
||||
var (
|
||||
nodes = []*Stats{}
|
||||
withFKs = sq.withFKs
|
||||
_spec = sq.querySpec()
|
||||
loadedTypes = [2]bool{
|
||||
loadedTypes = [3]bool{
|
||||
sq.withMatches != nil,
|
||||
sq.withPlayers != nil,
|
||||
sq.withWeaponStats != nil,
|
||||
}
|
||||
)
|
||||
if sq.withMatches != nil || sq.withPlayers != nil {
|
||||
withFKs = true
|
||||
}
|
||||
if withFKs {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, stats.ForeignKeys...)
|
||||
}
|
||||
_spec.ScanValues = func(columns []string) ([]interface{}, error) {
|
||||
node := &Stats{config: sq.config}
|
||||
nodes = append(nodes, node)
|
||||
@@ -426,10 +456,7 @@ func (sq *StatsQuery) sqlAll(ctx context.Context) ([]*Stats, error) {
|
||||
ids := make([]uint64, 0, len(nodes))
|
||||
nodeids := make(map[uint64][]*Stats)
|
||||
for i := range nodes {
|
||||
if nodes[i].match_stats == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].match_stats
|
||||
fk := nodes[i].MatchStats
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
@@ -455,10 +482,7 @@ func (sq *StatsQuery) sqlAll(ctx context.Context) ([]*Stats, error) {
|
||||
ids := make([]uint64, 0, len(nodes))
|
||||
nodeids := make(map[uint64][]*Stats)
|
||||
for i := range nodes {
|
||||
if nodes[i].player_stats == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].player_stats
|
||||
fk := nodes[i].PlayerStats
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
@@ -480,6 +504,35 @@ func (sq *StatsQuery) sqlAll(ctx context.Context) ([]*Stats, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if query := sq.withWeaponStats; query != nil {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[int]*Stats)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
nodes[i].Edges.WeaponStats = []*WeaponStats{}
|
||||
}
|
||||
query.withFKs = true
|
||||
query.Where(predicate.WeaponStats(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(stats.WeaponStatsColumn, fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.stats_weapon_stats
|
||||
if fk == nil {
|
||||
return nil, fmt.Errorf(`foreign-key "stats_weapon_stats" is nil for node %v`, n.ID)
|
||||
}
|
||||
node, ok := nodeids[*fk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(`unexpected foreign-key "stats_weapon_stats" returned %v for node %v`, *fk, n.ID)
|
||||
}
|
||||
node.Edges.WeaponStats = append(node.Edges.WeaponStats, n)
|
||||
}
|
||||
}
|
||||
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user