Skip to content

Commit 2fab0b5

Browse files
hrideshmgivinjabraham
authored andcommitted
feat: implement status update breaks
1 parent b0fce44 commit 2fab0b5

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Add migration script here
2+
CREATE TABLE statusbreaks (
3+
id SERIAL PRIMARY KEY,
4+
start_date DATE NOT NULL,
5+
end_date DATE NOT NULL,
6+
year INT NOT NULL,
7+
reason TEXT
8+
);

src/graphql/mutations/status_mutations.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use chrono_tz::Asia::Kolkata;
33
use sqlx::PgPool;
44
use std::sync::Arc;
55

6-
use crate::models::status_update::StatusUpdateRecord;
6+
use crate::models::status_update::{CreateStatusBreakInput, StatusBreakRecord, StatusUpdateRecord};
77

88
#[derive(Default)]
99
pub struct StatusMutations;
@@ -38,4 +38,26 @@ impl StatusMutations {
3838

3939
Ok(status)
4040
}
41+
42+
async fn create_status_break(
43+
&self,
44+
ctx: &Context<'_>,
45+
input: CreateStatusBreakInput,
46+
) -> Result<StatusBreakRecord> {
47+
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context");
48+
let status = sqlx::query_as::<_, StatusBreakRecord>(
49+
"INSERT INTO StatusBreaks (start_date, end_date, year, reason)
50+
VALUES ($1, $2, $3, $4)
51+
RETURNING *
52+
",
53+
)
54+
.bind(input.start_date)
55+
.bind(input.end_date)
56+
.bind(input.year)
57+
.bind(&input.reason)
58+
.fetch_one(pool.as_ref())
59+
.await?;
60+
61+
Ok(status)
62+
}
4163
}

src/graphql/queries/member_queries.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,20 @@ impl StatusInfo {
168168
async fn consecutive_misses(&self, ctx: &Context<'_>) -> Result<Option<i64>> {
169169
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");
170170

171+
// We measure the miss streak by finding the distance to the last sent update.
172+
// The inner most subquery here is used for filtering out dates which occur during a break.
171173
let result: Option<i64> = sqlx::query_scalar(
172174
"
173175
SELECT distance
174176
FROM (
175177
SELECT is_sent, ROW_NUMBER() OVER (ORDER BY date DESC) - 1 AS distance
176-
FROM StatusUpdateHistory
178+
FROM StatusUpdateHistory suh
177179
WHERE member_id = $1
180+
AND NOT EXISTS (
181+
SELECT * FROM StatusBreaks sb
182+
WHERE year = (SELECT year from Member where member_id=$1)
183+
AND suh.date BETWEEN sb.start_date AND sb.end_date
184+
)
178185
)
179186
WHERE is_sent = TRUE
180187
ORDER BY distance ASC

src/models/status_update.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use async_graphql::SimpleObject;
1+
use async_graphql::{InputObject, SimpleObject};
22
use chrono::NaiveDate;
33
use sqlx::FromRow;
44

@@ -15,3 +15,20 @@ pub struct StatusUpdateStreakRecord {
1515
pub current_streak: Option<i64>,
1616
pub max_streak: Option<i64>,
1717
}
18+
19+
#[derive(SimpleObject, FromRow)]
20+
pub struct StatusBreakRecord {
21+
pub id: i32,
22+
pub start_date: NaiveDate,
23+
pub end_date: NaiveDate,
24+
pub year: i32,
25+
pub reason: Option<String>,
26+
}
27+
28+
#[derive(InputObject)]
29+
pub struct CreateStatusBreakInput {
30+
pub start_date: NaiveDate,
31+
pub end_date: NaiveDate,
32+
pub year: i32,
33+
pub reason: Option<String>,
34+
}

0 commit comments

Comments
 (0)