From c3c199a7c315d3d4ba3caed85dee4ef799843cb8 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Sun, 10 Oct 2021 19:23:48 +0530 Subject: [PATCH] add submission --- Makefile | 4 + migrations/20211005151526_survey_surveys.sql | 25 +++- .../20211010134814_survey_response_tokens.sql | 5 + src/api/v1/bench.rs | 124 ++++++++++++++++++ src/api/v1/mod.rs | 3 +- src/api/v1/routes.rs | 3 + 6 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 migrations/20211010134814_survey_response_tokens.sql create mode 100644 src/api/v1/bench.rs diff --git a/Makefile b/Makefile index 121a3a8..09f568d 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,10 @@ frontend: ## Build frontend assets @-mkdir ./static/cache/bundle/css/ @yarn run dart-sass -s compressed templates/main.scss ./static/cache/bundle/css/main.css +lint: ## Lint codebase + cargo fmt -v --all -- --emit files + cargo clippy --workspace --tests --all-features + migrate: ## Run database migrations cargo run --bin tests-migrate diff --git a/migrations/20211005151526_survey_surveys.sql b/migrations/20211005151526_survey_surveys.sql index bbf59ae..2d230a2 100644 --- a/migrations/20211005151526_survey_surveys.sql +++ b/migrations/20211005151526_survey_surveys.sql @@ -1,5 +1,20 @@ -CREATE TABLE IF NOT EXISTS survey_surveys ( - ID UUID PRIMARY KEY NOT NULL UNIQUE, - name VARCHAR(100) NOT NULL, - challenges serial[] NOT NULL -) +--CREATE TYPE survey_bench AS ( +-- difficulty INTEGER, +-- duration FLOAT(8) +--); + +CREATE EXTENSION IF NOT EXISTS hstore; + +CREATE TABLE IF NOT EXISTS survey_responses ( + user_id UUID NOT NULL references survey_users(ID) ON DELETE CASCADE, + device_user_provided VARCHAR(400) NOT NULL, + device_software_recognised VARCHAR(400) NOT NULL, + ID SERIAL PRIMARY KEY NOT NULL, + threads INTEGER +); + +CREATE TABLE IF NOT EXISTS survey_benches ( + resp_id INTEGER NOT NULL references survey_responses(ID) ON DELETE CASCADE, + difficulty INTEGER NOT NULL, + duration FLOAT(8) NOT NULL +); diff --git a/migrations/20211010134814_survey_response_tokens.sql b/migrations/20211010134814_survey_response_tokens.sql new file mode 100644 index 0000000..d19bfad --- /dev/null +++ b/migrations/20211010134814_survey_response_tokens.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS survey_response_tokens ( + resp_id INTEGER NOT NULL references survey_responses(ID) ON DELETE CASCADE, + user_id UUID NOT NULL references survey_users(ID) ON DELETE CASCADE, + ID UUID PRIMARY KEY NOT NULL UNIQUE +); diff --git a/src/api/v1/bench.rs b/src/api/v1/bench.rs new file mode 100644 index 0000000..4c4acc0 --- /dev/null +++ b/src/api/v1/bench.rs @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2021 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +use std::str::FromStr; + +use actix_identity::Identity; +use actix_web::{web, HttpResponse, Responder}; +use futures::future::try_join_all; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use super::get_random; +use super::get_uuid; +use crate::errors::*; +use crate::AppData; + +pub mod routes { + pub struct Benches { + pub submit: &'static str, + } + + impl Benches { + pub const fn new() -> Benches { + let submit = "/api/v1/benches"; + Benches { submit } + } + } +} + +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(submit); +} + +#[derive(Serialize, Deserialize)] +struct Bench { + duration: f32, + difficulty: i32, +} + +#[derive(Serialize, Deserialize)] +struct Submission { + device_user_provided: String, + device_software_recognised: String, + threads: i32, + benches: Vec, +} + +#[my_codegen::post( + path = "crate::V1_API_ROUTES.benches.submit", + wrap = "crate::CheckLogin" +)] +async fn submit( + data: AppData, + id: Identity, + payload: web::Json, +) -> ServiceResult { + let username = id.identity().unwrap(); + + let user_id = Uuid::from_str(&username).unwrap(); + let payload = payload.into_inner(); + + sqlx::query!("INSERT INTO survey_responses (user_id, device_user_provided, device_software_recognised, + threads) VALUES ($1, $2, $3, $4)", &user_id, &payload.device_user_provided, + &payload.device_software_recognised, &payload.threads).execute(&data.db).await?; + + struct ID { + id: i32, + } + + let resp_id = sqlx::query_as!( + ID, + "SELECT ID FROM survey_responses + WHERE user_id = $1 AND device_software_recognised = $2", + &user_id, + &payload.device_software_recognised + ) + .fetch_one(&data.db) + .await?; + + let mut futs = Vec::with_capacity(payload.benches.len()); + + for bench in payload.benches.iter() { + let fut = sqlx::query!( + "INSERT INTO survey_benches + (resp_id, difficulty, duration) VALUES ($1, $2, $3)", + &resp_id.id, + &bench.difficulty, + bench.duration + ) + .execute(&data.db); + + futs.push(fut); + } + + let submitions_id = get_uuid(); + + let fut = sqlx::query!( + "INSERT INTO survey_response_tokens (resp_id, user_id, id) + VALUES ($1, $2, $3)", + &resp_id.id, + &user_id, + &submitions_id + ) + .execute(&data.db); + + futs.push(fut); + + try_join_all(futs).await?; + + Ok(HttpResponse::Ok()) +} diff --git a/src/api/v1/mod.rs b/src/api/v1/mod.rs index 47f9e34..925849c 100644 --- a/src/api/v1/mod.rs +++ b/src/api/v1/mod.rs @@ -18,7 +18,7 @@ use actix_web::web::ServiceConfig; use uuid::Uuid; pub mod auth; -pub mod cache; +pub mod bench; mod meta; pub mod routes; pub use routes::ROUTES; @@ -26,6 +26,7 @@ pub use routes::ROUTES; pub fn services(cfg: &mut ServiceConfig) { meta::services(cfg); auth::services(cfg); + bench::services(cfg); } pub fn get_random(len: usize) -> String { diff --git a/src/api/v1/routes.rs b/src/api/v1/routes.rs index 6cd6471..620e214 100644 --- a/src/api/v1/routes.rs +++ b/src/api/v1/routes.rs @@ -15,6 +15,7 @@ * along with this program. If not, see . */ use super::auth::routes::Auth; +use super::bench::routes::Benches; use super::meta::routes::Meta; pub const ROUTES: Routes = Routes::new(); @@ -22,6 +23,7 @@ pub const ROUTES: Routes = Routes::new(); pub struct Routes { pub auth: Auth, pub meta: Meta, + pub benches: Benches, } impl Routes { @@ -29,6 +31,7 @@ impl Routes { Routes { auth: Auth::new(), meta: Meta::new(), + benches: Benches::new(), } } }