LeagueStats/server/app/Repositories/MatchRepository.ts

302 lines
8.1 KiB
TypeScript
Raw Normal View History

import Database from '@ioc:Adonis/Lucid/Database'
2022-01-07 23:16:49 +00:00
export interface SelectFilters {
puuid: string
season?: number
limit?: number
queue?: number
}
class MatchRepository {
private readonly JOIN_MATCHES = 'INNER JOIN matches ON matches.id = match_players.match_id'
private readonly JOIN_TEAMS =
'INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color'
private readonly JOIN_ALL = `${this.JOIN_MATCHES} ${this.JOIN_TEAMS}`
2022-01-07 23:16:49 +00:00
private globalFilters(filters: SelectFilters) {
let query = `
match_players.summoner_puuid = :puuid
AND match_players.remake = 0
AND matches.gamemode NOT IN (800, 810, 820, 830, 840, 850, 2000, 2010, 2020)
2022-01-07 23:16:49 +00:00
`
if (filters.season) query += ' AND matches.season = :season '
if (filters.queue) query += ' AND matches.gamemode = :queue '
return query
}
public async seasons(puuid: string) {
const query = `
SELECT DISTINCT
matches.season
FROM
match_players
${this.JOIN_MATCHES}
WHERE
match_players.summoner_puuid = :puuid
`
const { rows } = await Database.rawQuery(query, { puuid })
return rows
}
public async recentActivity(puuid: string) {
const query = `
SELECT
to_timestamp(matches.date/1000)::date as day,
COUNT(match_players.id) as count
FROM
match_players
${this.JOIN_MATCHES}
WHERE
match_players.summoner_puuid = :puuid
AND to_timestamp(matches.date/1000)::date > (CURRENT_DATE - INTERVAL '105 days')
GROUP BY
day
ORDER BY
day
`
const { rows } = await Database.rawQuery(query, { puuid })
return rows
2020-10-05 19:33:17 +00:00
}
2022-01-07 23:16:49 +00:00
public async globalStats(filters: SelectFilters) {
const query = `
SELECT
SUM(match_players.kills) as kills,
SUM(match_players.deaths) as deaths,
SUM(match_players.assists) as assists,
SUM(match_players.minions) as minions,
SUM(matches.game_duration) as time,
SUM(match_players.vision_score) as vision,
COUNT(match_players.id) as count,
AVG(match_players.kp) as kp,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
LIMIT
1
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows[0]
2020-10-05 19:33:17 +00:00
}
2022-01-07 23:16:49 +00:00
public async gamemodeStats(filters: SelectFilters) {
const query = `
SELECT
matches.gamemode as id,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
GROUP BY
matches.gamemode
ORDER BY
count DESC
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
2020-10-05 19:33:17 +00:00
}
2022-01-07 23:16:49 +00:00
public async roleStats(filters: SelectFilters) {
const query = `
SELECT
match_players.team_position as role,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
AND match_players.team_position != 0
GROUP BY
role
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
2020-10-08 07:51:12 +00:00
}
2022-01-07 23:16:49 +00:00
public async championStats(filters: SelectFilters) {
const query = `
SELECT
match_players.champion_id as id,
SUM(match_players.assists) as assists,
SUM(match_players.deaths) as deaths,
SUM(match_players.kills) as kills,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
GROUP BY
match_players.champion_id
ORDER BY
count DESC, match_players.champion_id
LIMIT
:limit
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
}
2022-01-07 23:16:49 +00:00
public async championClassStats(filters: SelectFilters) {
const query = `
SELECT
match_players.champion_role as id,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
GROUP BY
match_players.champion_role
ORDER BY
count DESC
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
2020-10-08 07:51:12 +00:00
}
2022-01-07 23:16:49 +00:00
public async mates(filters: SelectFilters) {
const query = `
SELECT
(array_agg(mates.summoner_name ORDER BY mates.match_id DESC))[1] as name,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses
FROM
match_players
${this.JOIN_ALL}
INNER JOIN match_players as mates ON match_players.match_id = mates.match_id AND match_players.team = mates.team
WHERE
${this.globalFilters(filters)}
GROUP BY
mates.summoner_puuid
ORDER BY
count DESC, wins DESC
LIMIT
15
`
const { rows } = await Database.rawQuery(query, filters as any)
// Remove the Summoner himself + unique game mates
return rows.splice(1).filter((row) => row.count > 1)
}
public async championCompleteStats(puuid: string, queue?: number, season?: number) {
2022-01-07 23:16:49 +00:00
const filters: SelectFilters = { puuid }
if (queue) filters.queue = queue
if (season) filters.season = season
const query = `
SELECT
match_players.champion_id as id,
SUM(match_players.assists) as assists,
SUM(match_players.deaths) as deaths,
SUM(match_players.kills) as kills,
COUNT(match_players.id) as count,
SUM(match_players.win) as wins,
SUM(match_players.loss) as losses,
AVG(matches.game_duration)::int as "gameLength",
AVG(match_players.minions)::int as minions,
AVG(match_players.gold)::int as gold,
AVG(match_players.damage_dealt_champions)::int as "dmgChamp",
AVG(match_players.damage_taken)::int as "dmgTaken",
AVG(match_players.kp) as kp,
MAX(matches.date) as date
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
GROUP BY
match_players.champion_id
ORDER BY
count DESC, match_players.champion_id
`
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
2020-10-08 07:51:12 +00:00
}
2022-01-07 23:16:49 +00:00
public async records(puuid: string, season?: number) {
const filters: SelectFilters = { puuid }
if (season) filters.season = season
2020-10-07 15:47:27 +00:00
const fields = [
'match_players.kills',
'match_players.deaths',
'match_players.assists',
'match_players.gold',
'matches.game_duration',
'match_players.minions',
'match_players.kda',
'match_players.damage_taken',
'match_players.damage_dealt_champions',
'match_players.damage_dealt_objectives',
'match_players.kp',
'match_players.vision_score',
'match_players.critical_strike',
'match_players.time_spent_living',
'match_players.heal',
'match_players.turret_kills',
'match_players.killing_spree',
'match_players.double_kills',
'match_players.triple_kills',
'match_players.quadra_kills',
'match_players.penta_kills',
2020-10-08 07:51:12 +00:00
]
const query = fields
.map((field) => {
return `
(SELECT
'${field}' AS what,
${field} AS amount,
match_players.win as result,
matches.id,
matches.date,
matches.gamemode,
match_players.champion_id
FROM
match_players
${this.JOIN_MATCHES}
WHERE
2022-01-07 23:16:49 +00:00
${this.globalFilters(filters)}
ORDER BY
${field} DESC, matches.id
LIMIT
1)
`
})
.join('UNION ALL ')
2020-10-08 07:51:12 +00:00
2022-01-07 23:16:49 +00:00
const { rows } = await Database.rawQuery(query, filters as any)
return rows
2020-10-08 07:51:12 +00:00
}
}
export default new MatchRepository()