49 lines
1.3 KiB
Go
49 lines
1.3 KiB
Go
|
package models
|
||
|
|
||
|
// Code generated by xo. DO NOT EDIT.
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
)
|
||
|
|
||
|
// LeaderboardEntry represents a row from 'leaderboard_entry'.
|
||
|
type LeaderboardEntry struct {
|
||
|
Name string `json:"name"` // name
|
||
|
Points int `json:"points"` // points
|
||
|
LastValid Time `json:"last_valid"` // last_valid
|
||
|
}
|
||
|
|
||
|
// Leaderboard runs a custom query, returning results as LeaderboardEntry.
|
||
|
func Leaderboard(ctx context.Context, db DB) ([]*LeaderboardEntry, error) {
|
||
|
// query
|
||
|
const sqlstr = `SELECT u.name, ` +
|
||
|
`COALESCE(SUM(qa.points_awarded), 0) AS points, ` +
|
||
|
`COALESCE(MAX(qa.submitted_at), u.created_at) as last_valid_submission ` +
|
||
|
`FROM users u ` +
|
||
|
`LEFT JOIN question_attempt qa ON u.id = qa.user_id AND qa.correct ` +
|
||
|
`GROUP BY u.id ` +
|
||
|
`ORDER BY COALESCE(SUM(qa.points_awarded), 0) DESC, ` +
|
||
|
`MAX(qa.submitted_at) ASC`
|
||
|
// run
|
||
|
logf(sqlstr)
|
||
|
rows, err := db.QueryContext(ctx, sqlstr)
|
||
|
if err != nil {
|
||
|
return nil, logerror(err)
|
||
|
}
|
||
|
defer rows.Close()
|
||
|
// load results
|
||
|
var res []*LeaderboardEntry
|
||
|
for rows.Next() {
|
||
|
var le LeaderboardEntry
|
||
|
// scan
|
||
|
if err := rows.Scan(&le.Name, &le.Points, &le.LastValid); err != nil {
|
||
|
return nil, logerror(err)
|
||
|
}
|
||
|
res = append(res, &le)
|
||
|
}
|
||
|
if err := rows.Err(); err != nil {
|
||
|
return nil, logerror(err)
|
||
|
}
|
||
|
return res, nil
|
||
|
}
|