Skip to content

Commit

Permalink
feat: list submission by user or contest or user and contest
Browse files Browse the repository at this point in the history
  • Loading branch information
K0nnyaku committed Dec 3, 2024
1 parent 9acee94 commit cade2f3
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/models/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Submission {
pub status: Status,
pub results: Vec<JudgeResult>,
pub creator: Thing,
pub contest_id: Option<Thing>,

pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
Expand Down
86 changes: 77 additions & 9 deletions src/routes/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct CreateSubmission {
pub auth: OwnedCredentials,
pub code: String,
pub lang: Language,
pub contest_id: Option<String>,
}

#[derive(Serialize, Deserialize)]
Expand All @@ -34,12 +35,18 @@ pub async fn submit(
}

let data = data.into_inner();
let submission = submission::create(db, &data.auth.id, id, data.code, data.lang)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?
.ok_or(Error::ServerError(Json(
"Failed to submit, please try again later.".into(),
)))?;
let submission = submission::create(
db,
&data.auth.id,
id,
data.code,
data.lang,
data.contest_id.as_deref(),
)
.await?
.ok_or(Error::ServerError(Json(
"Failed to submit, please try again later.".into(),
)))?;

Ok(Json(Response {
success: true,
Expand All @@ -57,8 +64,7 @@ pub async fn get(
_auth: Json<Credentials<'_>>,
) -> Result<Submission> {
let submission = submission::get_by_id(db, id)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?
.await?
.ok_or(Error::NotFound(Json("Submission not found".into())))?;

Ok(Json(Response {
Expand All @@ -68,7 +74,69 @@ pub async fn get(
}))
}

#[post("/list/<id>", data = "<_auth>")]
pub async fn list_by_user(
db: &State<Surreal<Client>>,
id: &str,
_auth: Json<Credentials<'_>>,
) -> Result<Vec<Submission>> {
let submissions = submission::list_by_user(db, ("account", id).into())
.await?
.ok_or(Error::NotFound(Json("Submission not found".into())))?;

Ok(Json(Response {
success: true,
message: "submission fetched successfully".to_string(),
data: Some(submissions),
}))
}

#[post("/list/<id>", data = "<_auth>")]
pub async fn list_by_contest(
db: &State<Surreal<Client>>,
id: &str,
_auth: Json<Credentials<'_>>,
) -> Result<Vec<Submission>> {
let submissions = submission::list_by_contest(db, ("contest", id).into())
.await?
.ok_or(Error::NotFound(Json("Submission not found".into())))?;

Ok(Json(Response {
success: true,
message: "submission fetched successfully".to_string(),
data: Some(submissions),
}))
}

#[post("/list/<contest_id>/<user_id>", data = "<_auth>")]
pub async fn list_within_contest(
db: &State<Surreal<Client>>,
contest_id: &str,
user_id: &str,
_auth: Json<Credentials<'_>>,
) -> Result<Vec<Submission>> {
let submissions = submission::list_within_contest(
db,
("contest", contest_id).into(),
("contest", user_id).into(),
)
.await?
.ok_or(Error::NotFound(Json("Submission not found".into())))?;

Ok(Json(Response {
success: true,
message: "submission fetched successfully".to_string(),
data: Some(submissions),
}))
}

pub fn routes() -> Vec<rocket::Route> {
use rocket::routes;
routes![submit, get]
routes![
submit,
get,
list_by_user,
list_by_contest,
list_within_contest
]
}
46 changes: 45 additions & 1 deletion src/utils/submission.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::models::submission::Submission;
use anyhow::Result;
use eval_stack::compile::Language;
use surrealdb::{engine::remote::ws::Client, Surreal};
use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};

pub async fn create(
db: &Surreal<Client>,
account_id: &str,
problem_id: &str,
code: String,
lang: Language,
contest_id: Option<&str>,
) -> Result<Option<Submission>> {
Ok(db
.create("submission")
Expand All @@ -22,6 +23,12 @@ pub async fn create(
creator: ("account", account_id).into(),
results: vec![],

contest_id: (if let Some(contest_id) = contest_id {
Some(("contest", contest_id).into())
} else {
None
}),

created_at: chrono::Local::now().naive_local(),
updated_at: chrono::Local::now().naive_local(),
})
Expand All @@ -31,3 +38,40 @@ pub async fn create(
pub async fn get_by_id(db: &Surreal<Client>, id: &str) -> Result<Option<Submission>> {
Ok(db.select(("submission", id)).await?)
}

pub async fn list_by_user(db: &Surreal<Client>, creator: Thing) -> Result<Option<Vec<Submission>>> {
Ok(db
.query("SELECT * FROM submission WHERE creator = $creator")
.bind(("creator", creator))
.await?
.take(0)?)
}

pub async fn list_by_contest(
db: &Surreal<Client>,
contest_id: Thing,
) -> Result<Option<Vec<Submission>>> {
Ok(db
.query("SELECT * FROM submission WHERE contest_id = $contest_id")
.bind(("contest_id", contest_id))
.await?
.take(0)?)
}

pub async fn list_within_contest(
db: &Surreal<Client>,
contest_id: Thing,
user_id: Thing,
) -> Result<Option<Vec<Submission>>> {
let submissions = list_by_contest(db, contest_id).await?;

match submissions {
Some(submissions) => Ok(Some(
submissions
.into_iter()
.filter(|s| s.creator == user_id)
.collect(),
)),
None => Ok(None),
}
}

0 comments on commit cade2f3

Please sign in to comment.