implement before and after filters for matches

This commit is contained in:
Ilion Beyst 2022-08-08 18:31:11 +02:00
parent db7980504f
commit cf52ab6f7f
2 changed files with 32 additions and 8 deletions

View file

@ -130,13 +130,34 @@ pub fn list_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMat
}) })
} }
pub fn list_public_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<FullMatchData>> { pub fn list_public_matches(
amount: i64,
before: Option<NaiveDateTime>,
after: Option<NaiveDateTime>,
conn: &PgConnection,
) -> QueryResult<Vec<FullMatchData>> {
conn.transaction(|| { conn.transaction(|| {
let matches = matches::table // TODO: how can this common logic be abstracted?
// TODO: this is not nice. Replace this with proper cursor logic.
let mut query = matches::table
.filter(matches::is_public.eq(true)) .filter(matches::is_public.eq(true))
.order_by(matches::created_at.desc()) .into_boxed();
.limit(amount)
.get_results::<MatchBase>(conn)?; query = match (before, after) {
(None, None) => query.order_by(matches::created_at.desc()),
(Some(before), None) => query
.filter(matches::created_at.lt(before))
.order_by(matches::created_at.desc()),
(None, Some(after)) => query
.filter(matches::created_at.gt(after))
.order_by(matches::created_at.asc()),
(Some(before), Some(after)) => query
.filter(matches::created_at.lt(before))
.filter(matches::created_at.gt(after))
.order_by(matches::created_at.desc()),
};
let matches = query.limit(amount).get_results::<MatchBase>(conn)?;
fetch_full_match_data(matches, conn) fetch_full_match_data(matches, conn)
}) })
@ -145,11 +166,15 @@ pub fn list_public_matches(amount: i64, conn: &PgConnection) -> QueryResult<Vec<
pub fn list_bot_matches( pub fn list_bot_matches(
bot_id: i32, bot_id: i32,
amount: i64, amount: i64,
before: Option<NaiveDateTime>,
after: Option<NaiveDateTime>,
conn: &PgConnection, conn: &PgConnection,
) -> QueryResult<Vec<FullMatchData>> { ) -> QueryResult<Vec<FullMatchData>> {
conn.transaction(|| { conn.transaction(|| {
let matches = matches::table let matches = matches::table
.filter(matches::is_public.eq(true)) .filter(matches::is_public.eq(true))
.filter(matches::created_at.nullable().lt(before))
.filter(matches::created_at.nullable().gt(after))
.order_by(matches::created_at.desc()) .order_by(matches::created_at.desc())
.inner_join(match_players::table) .inner_join(match_players::table)
.inner_join( .inner_join(

View file

@ -35,7 +35,6 @@ pub struct ApiMatchPlayer {
pub struct ListRecentMatchesParams { pub struct ListRecentMatchesParams {
count: Option<usize>, count: Option<usize>,
// TODO: should timezone be specified here? // TODO: should timezone be specified here?
// TODO: implement these
before: Option<NaiveDateTime>, before: Option<NaiveDateTime>,
after: Option<NaiveDateTime>, after: Option<NaiveDateTime>,
@ -58,9 +57,9 @@ pub async fn list_recent_matches(
Some(bot_name) => { Some(bot_name) => {
let bot = db::bots::find_bot_by_name(&bot_name, &conn) let bot = db::bots::find_bot_by_name(&bot_name, &conn)
.map_err(|_| StatusCode::BAD_REQUEST)?; .map_err(|_| StatusCode::BAD_REQUEST)?;
matches::list_bot_matches(bot.id, count, &conn) matches::list_bot_matches(bot.id, count, params.before, params.after, &conn)
} }
None => matches::list_public_matches(count, &conn), None => matches::list_public_matches(count, params.before, params.after, &conn),
}; };
matches matches