list only public matches in API

This commit is contained in:
Ilion Beyst 2022-07-30 19:49:08 +02:00
parent ee5c67c092
commit e8dbb01933
3 changed files with 46 additions and 24 deletions

View file

@ -89,6 +89,36 @@ pub struct MatchData {
pub match_players: Vec<MatchPlayer>, pub match_players: Vec<MatchPlayer>,
} }
/// Add player information to MatchBase instances
fn fetch_full_match_data(
matches: Vec<MatchBase>,
conn: &PgConnection,
) -> QueryResult<Vec<FullMatchData>> {
let match_players = MatchPlayer::belonging_to(&matches)
.left_join(
bot_versions::table.on(match_players::bot_version_id.eq(bot_versions::id.nullable())),
)
.left_join(bots::table.on(bot_versions::bot_id.eq(bots::id.nullable())))
.order_by((
match_players::match_id.asc(),
match_players::player_id.asc(),
))
.load::<FullMatchPlayerData>(conn)?
.grouped_by(&matches);
let res = matches
.into_iter()
.zip(match_players.into_iter())
.map(|(base, players)| FullMatchData {
base,
match_players: players.into_iter().collect(),
})
.collect();
Ok(res)
}
// TODO: this method should disappear
pub fn list_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMatchData>> { pub fn list_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMatchData>> {
conn.transaction(|| { conn.transaction(|| {
let matches = matches::table let matches = matches::table
@ -96,29 +126,19 @@ pub fn list_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMat
.limit(amount) .limit(amount)
.get_results::<MatchBase>(conn)?; .get_results::<MatchBase>(conn)?;
let match_players = MatchPlayer::belonging_to(&matches) fetch_full_match_data(matches, conn)
.left_join( })
bot_versions::table }
.on(match_players::bot_version_id.eq(bot_versions::id.nullable())),
)
.left_join(bots::table.on(bot_versions::bot_id.eq(bots::id.nullable())))
.order_by((
match_players::match_id.asc(),
match_players::player_id.asc(),
))
.load::<FullMatchPlayerData>(conn)?
.grouped_by(&matches);
let res = matches pub fn list_public_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMatchData>> {
.into_iter() conn.transaction(|| {
.zip(match_players.into_iter()) let matches = matches::table
.map(|(base, players)| FullMatchData { .filter(matches::is_public.eq(true))
base, .order_by(matches::created_at.desc())
match_players: players.into_iter().collect(), .limit(amount)
}) .get_results::<MatchBase>(conn)?;
.collect();
Ok(res) fetch_full_match_data(matches, conn)
}) })
} }

View file

@ -129,7 +129,7 @@ pub fn api() -> Router {
"/bots/:bot_name/upload", "/bots/:bot_name/upload",
post(routes::bots::upload_code_multipart), post(routes::bots::upload_code_multipart),
) )
.route("/matches", get(routes::matches::list_matches)) .route("/matches", get(routes::matches::list_public_matches))
.route("/matches/:match_id", get(routes::matches::get_match_data)) .route("/matches/:match_id", get(routes::matches::get_match_data))
.route( .route(
"/matches/:match_id/log", "/matches/:match_id/log",

View file

@ -23,8 +23,10 @@ pub struct ApiMatchPlayer {
bot_name: Option<String>, bot_name: Option<String>,
} }
pub async fn list_matches(conn: DatabaseConnection) -> Result<Json<Vec<ApiMatch>>, StatusCode> { pub async fn list_public_matches(
matches::list_matches(100, &conn) conn: DatabaseConnection,
) -> Result<Json<Vec<ApiMatch>>, StatusCode> {
matches::list_public_matches(100, &conn)
.map_err(|_| StatusCode::BAD_REQUEST) .map_err(|_| StatusCode::BAD_REQUEST)
.map(|matches| Json(matches.into_iter().map(match_data_to_api).collect())) .map(|matches| Json(matches.into_iter().map(match_data_to_api).collect()))
} }