add submission

This commit is contained in:
Aravinth Manivannan 2021-10-10 19:23:48 +05:30
parent 3a7559d6a8
commit c3c199a7c3
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
6 changed files with 158 additions and 6 deletions

View file

@ -32,6 +32,10 @@ frontend: ## Build frontend assets
@-mkdir ./static/cache/bundle/css/ @-mkdir ./static/cache/bundle/css/
@yarn run dart-sass -s compressed templates/main.scss ./static/cache/bundle/css/main.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 migrate: ## Run database migrations
cargo run --bin tests-migrate cargo run --bin tests-migrate

View file

@ -1,5 +1,20 @@
CREATE TABLE IF NOT EXISTS survey_surveys ( --CREATE TYPE survey_bench AS (
ID UUID PRIMARY KEY NOT NULL UNIQUE, -- difficulty INTEGER,
name VARCHAR(100) NOT NULL, -- duration FLOAT(8)
challenges serial[] NOT NULL --);
)
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
);

View file

@ -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
);

124
src/api/v1/bench.rs Normal file
View file

@ -0,0 +1,124 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<Bench>,
}
#[my_codegen::post(
path = "crate::V1_API_ROUTES.benches.submit",
wrap = "crate::CheckLogin"
)]
async fn submit(
data: AppData,
id: Identity,
payload: web::Json<Submission>,
) -> ServiceResult<impl Responder> {
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())
}

View file

@ -18,7 +18,7 @@ use actix_web::web::ServiceConfig;
use uuid::Uuid; use uuid::Uuid;
pub mod auth; pub mod auth;
pub mod cache; pub mod bench;
mod meta; mod meta;
pub mod routes; pub mod routes;
pub use routes::ROUTES; pub use routes::ROUTES;
@ -26,6 +26,7 @@ pub use routes::ROUTES;
pub fn services(cfg: &mut ServiceConfig) { pub fn services(cfg: &mut ServiceConfig) {
meta::services(cfg); meta::services(cfg);
auth::services(cfg); auth::services(cfg);
bench::services(cfg);
} }
pub fn get_random(len: usize) -> String { pub fn get_random(len: usize) -> String {

View file

@ -15,6 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
use super::auth::routes::Auth; use super::auth::routes::Auth;
use super::bench::routes::Benches;
use super::meta::routes::Meta; use super::meta::routes::Meta;
pub const ROUTES: Routes = Routes::new(); pub const ROUTES: Routes = Routes::new();
@ -22,6 +23,7 @@ pub const ROUTES: Routes = Routes::new();
pub struct Routes { pub struct Routes {
pub auth: Auth, pub auth: Auth,
pub meta: Meta, pub meta: Meta,
pub benches: Benches,
} }
impl Routes { impl Routes {
@ -29,6 +31,7 @@ impl Routes {
Routes { Routes {
auth: Auth::new(), auth: Auth::new(),
meta: Meta::new(), meta: Meta::new(),
benches: Benches::new(),
} }
} }
} }