[BE] Use single connections instead of a Pool
This commit is contained in:
parent
673cd96a01
commit
ad7d224207
@ -2,6 +2,7 @@ use log::{error, info};
|
|||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
use sqlx::Connection;
|
||||||
|
|
||||||
use crate::json_result::JsonResult;
|
use crate::json_result::JsonResult;
|
||||||
use crate::model::person::{PersonCreate, PersonLink};
|
use crate::model::person::{PersonCreate, PersonLink};
|
||||||
@ -11,7 +12,7 @@ use crate::{db, model::person::Person};
|
|||||||
|
|
||||||
#[get("/person/<dni>")]
|
#[get("/person/<dni>")]
|
||||||
pub async fn get_by_dni(dni: i32) -> (Status, Json<JsonResult<Person>>) {
|
pub async fn get_by_dni(dni: i32) -> (Status, Json<JsonResult<Person>>) {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
return (Status::InternalServerError, JsonResult::err(reason));
|
return (Status::InternalServerError, JsonResult::err(reason));
|
||||||
|
@ -12,7 +12,7 @@ use std::{
|
|||||||
// TODO: Move to ENV
|
// TODO: Move to ENV
|
||||||
const SCAN_PATH: &str = "/srv/srv/shares/eegsac/ESCANEOS/";
|
const SCAN_PATH: &str = "/srv/srv/shares/eegsac/ESCANEOS/";
|
||||||
|
|
||||||
/// Represents the result of parsing a QR code, and look for an eegsac URL.
|
/// Represents the result of parsing a QR code, and looking for an eegsac URL.
|
||||||
///
|
///
|
||||||
/// When the frontend requests the list of files available for conversion, this
|
/// When the frontend requests the list of files available for conversion, this
|
||||||
/// is sent. It contains essentially a unix timestamp
|
/// is sent. It contains essentially a unix timestamp
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use cors::Cors;
|
use cors::Cors;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use sqlx::mysql::MySqlPoolOptions;
|
use sqlx::mysql::MySqlPoolOptions;
|
||||||
use sqlx::{MySql, Pool};
|
use sqlx::{MySql, Pool, MySqlConnection};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use sqlx::Connection;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
@ -14,32 +15,12 @@ mod online_classroom;
|
|||||||
|
|
||||||
pub mod json_result;
|
pub mod json_result;
|
||||||
|
|
||||||
static DB: OnceCell<Pool<MySql>> = OnceCell::new();
|
/// Opens & returns a connection to the database
|
||||||
|
|
||||||
/// Returns a global reference to the database pool
|
|
||||||
///
|
///
|
||||||
/// If the database pool has not been initialized, this function will attempt to initialize it
|
/// We don't use a connection pool because it often times out,
|
||||||
/// up to 3 times
|
/// we don't have a lot of traffic and reiniting the pool would
|
||||||
///
|
/// require to change a lot of code in multiple places.
|
||||||
/// If the database pool fails to initialize, this function will panic.
|
pub async fn db() -> Result<MySqlConnection, String> {
|
||||||
pub async fn db() -> Result<&'static Pool<MySql>, String> {
|
|
||||||
let attempts = 3;
|
|
||||||
|
|
||||||
for _ in 0..attempts {
|
|
||||||
match DB.get() {
|
|
||||||
Some(db) => return Ok(db),
|
|
||||||
None => {
|
|
||||||
log::info!("DB not initialized, initializing from db()");
|
|
||||||
let _ = init_db().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log::error!("Failed to initialize DB after {} attempts", attempts);
|
|
||||||
Err("Failed to initialize DB".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn init_db() -> Result<(), String> {
|
|
||||||
/*
|
/*
|
||||||
Init DB and set it as a global variable
|
Init DB and set it as a global variable
|
||||||
*/
|
*/
|
||||||
@ -48,21 +29,12 @@ pub async fn init_db() -> Result<(), String> {
|
|||||||
Err(_) => return Err("env DATABASE_URL not found".to_string()),
|
Err(_) => return Err("env DATABASE_URL not found".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let pool = MySqlPoolOptions::new()
|
let conn = sqlx::MySqlConnection::connect(db_url.as_str()).await;
|
||||||
.max_connections(5)
|
|
||||||
.connect(db_url.as_str())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match pool {
|
match conn {
|
||||||
Ok(pool) => match DB.set(pool) {
|
Ok(connection) => Ok(connection),
|
||||||
Ok(_) => Ok(()),
|
Err(reason) => {
|
||||||
Err(_) => {
|
log::error!("Error connecting to DB: {}", reason);
|
||||||
log::error!("Failed to set DB global variable");
|
|
||||||
Err("Failed to set DB".to_string())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("Error connecting to DB: {}", e);
|
|
||||||
Err("Error connecting to DB".to_string())
|
Err("Error connecting to DB".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +45,7 @@ async fn rocket() -> _ {
|
|||||||
dotenvy::dotenv().expect("Failed to load .env file");
|
dotenvy::dotenv().expect("Failed to load .env file");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
init_db().await;
|
// init_db().await;
|
||||||
|
|
||||||
/* Init Rocket */
|
/* Init Rocket */
|
||||||
rocket::build().attach(Cors {}).mount(
|
rocket::build().attach(Cors {}).mount(
|
||||||
|
@ -28,14 +28,14 @@ pub struct Course {
|
|||||||
|
|
||||||
impl Course {
|
impl Course {
|
||||||
pub async fn get_all() -> Result<Vec<Course>, String> {
|
pub async fn get_all() -> Result<Vec<Course>, String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
return Err(reason);
|
return Err(reason);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let results = sqlx::query!("SELECT * FROM course").fetch_all(db).await;
|
let results = sqlx::query!("SELECT * FROM course").fetch_all(&mut db).await;
|
||||||
|
|
||||||
let results = match results {
|
let results = match results {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
@ -60,7 +60,7 @@ impl Course {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_course_name(course_id: i32) -> Result<String, String> {
|
pub async fn get_course_name(course_id: i32) -> Result<String, String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
return Err(reason);
|
return Err(reason);
|
||||||
@ -71,7 +71,7 @@ impl Course {
|
|||||||
"SELECT course_name FROM course WHERE course_id = ?",
|
"SELECT course_name FROM course WHERE course_id = ?",
|
||||||
course_id
|
course_id
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
|
@ -9,7 +9,7 @@ pub struct CustomLabel {
|
|||||||
|
|
||||||
impl CustomLabel {
|
impl CustomLabel {
|
||||||
pub async fn get_all() -> Result<Vec<CustomLabel>, String> {
|
pub async fn get_all() -> Result<Vec<CustomLabel>, String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(reason),
|
Err(reason) => return Err(reason),
|
||||||
};
|
};
|
||||||
@ -20,7 +20,7 @@ impl CustomLabel {
|
|||||||
FROM custom_label
|
FROM custom_label
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@ -33,7 +33,7 @@ impl CustomLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_id_by_value(value: &String) -> Result<i32, String> {
|
pub async fn get_id_by_value(value: &String) -> Result<i32, String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(reason),
|
Err(reason) => return Err(reason),
|
||||||
};
|
};
|
||||||
@ -42,7 +42,7 @@ impl CustomLabel {
|
|||||||
"SELECT custom_label_id FROM custom_label WHERE custom_label_value = ?",
|
"SELECT custom_label_id FROM custom_label WHERE custom_label_value = ?",
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let result = match result {
|
let result = match result {
|
||||||
@ -63,7 +63,7 @@ impl CustomLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(value: &String) -> Result<i32, String> {
|
pub async fn create(value: &String) -> Result<i32, String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(reason),
|
Err(reason) => return Err(reason),
|
||||||
};
|
};
|
||||||
@ -72,7 +72,7 @@ impl CustomLabel {
|
|||||||
"INSERT INTO custom_label (custom_label_value) VALUES (?)",
|
"INSERT INTO custom_label (custom_label_value) VALUES (?)",
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
|
@ -34,13 +34,13 @@ pub struct Person {
|
|||||||
|
|
||||||
impl Person {
|
impl Person {
|
||||||
pub async fn get_by_dni(dni: i32) -> Result<Person, DBError> {
|
pub async fn get_by_dni(dni: i32) -> Result<Person, DBError> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(DBError::Str(reason)),
|
Err(reason) => return Err(DBError::Str(reason)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = sqlx::query_as!(Person, "SELECT * FROM person WHERE person_dni = ?", dni)
|
let result = sqlx::query_as!(Person, "SELECT * FROM person WHERE person_dni = ?", dni)
|
||||||
.fetch_one(db)
|
.fetch_one(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@ -63,7 +63,7 @@ pub struct PersonCreate {
|
|||||||
|
|
||||||
impl PersonCreate {
|
impl PersonCreate {
|
||||||
pub async fn create(&self) -> Result<(), String> {
|
pub async fn create(&self) -> Result<(), String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
@ -75,7 +75,7 @@ impl PersonCreate {
|
|||||||
self.person_paternal_surname,
|
self.person_paternal_surname,
|
||||||
self.person_maternal_surname,
|
self.person_maternal_surname,
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@ -98,7 +98,7 @@ pub struct PersonLink {
|
|||||||
impl PersonLink {
|
impl PersonLink {
|
||||||
/// Links a person to a user in the online classroom
|
/// Links a person to a user in the online classroom
|
||||||
pub async fn insert(&self) -> Result<(), String> {
|
pub async fn insert(&self) -> Result<(), String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(reason),
|
Err(reason) => return Err(reason),
|
||||||
};
|
};
|
||||||
@ -109,7 +109,7 @@ impl PersonLink {
|
|||||||
self.person_classroom_username,
|
self.person_classroom_username,
|
||||||
self.person_id,
|
self.person_id,
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
|
@ -32,7 +32,7 @@ pub struct RegisterCreate {
|
|||||||
impl RegisterCreate {
|
impl RegisterCreate {
|
||||||
/// Registers a new certificate
|
/// Registers a new certificate
|
||||||
pub async fn create(&self) -> Result<(), String> {
|
pub async fn create(&self) -> Result<(), String> {
|
||||||
let db = match db().await {
|
let mut db = match db().await {
|
||||||
Ok(db) => db,
|
Ok(db) => db,
|
||||||
Err(reason) => return Err(reason),
|
Err(reason) => return Err(reason),
|
||||||
};
|
};
|
||||||
@ -78,7 +78,7 @@ impl RegisterCreate {
|
|||||||
self.person_id,
|
self.person_id,
|
||||||
self.course_id
|
self.course_id
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@ -91,7 +91,7 @@ impl RegisterCreate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_next_register_code(course_id: i32) -> Result<i32, String> {
|
async fn get_next_register_code(course_id: i32) -> Result<i32, String> {
|
||||||
let db = db().await?;
|
let mut db = db().await?;
|
||||||
|
|
||||||
let course_name = Course::get_course_name(course_id).await?;
|
let course_name = Course::get_course_name(course_id).await?;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ impl RegisterCreate {
|
|||||||
WHERE register_course_id IN
|
WHERE register_course_id IN
|
||||||
(SELECT course_id FROM course WHERE course_name LIKE 'Matpel%')",
|
(SELECT course_id FROM course WHERE course_name LIKE 'Matpel%')",
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -121,7 +121,7 @@ impl RegisterCreate {
|
|||||||
WHERE register_course_id=?",
|
WHERE register_course_id=?",
|
||||||
course_id
|
course_id
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -165,14 +165,14 @@ pub struct Register {
|
|||||||
|
|
||||||
impl Register {
|
impl Register {
|
||||||
pub async fn get_by_dni(dni: String) -> Result<Vec<Register>, String> {
|
pub async fn get_by_dni(dni: String) -> Result<Vec<Register>, String> {
|
||||||
let db = db().await?;
|
let mut db = db().await?;
|
||||||
|
|
||||||
let res = sqlx::query!(
|
let res = sqlx::query!(
|
||||||
"SELECT * FROM register
|
"SELECT * FROM register
|
||||||
WHERE register_person_id = (SELECT person_id FROM person WHERE person_dni = ?)",
|
WHERE register_person_id = (SELECT person_id FROM person WHERE person_dni = ?)",
|
||||||
dni
|
dni
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let res = match res {
|
let res = match res {
|
||||||
@ -201,10 +201,10 @@ impl Register {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(register_id: i32) -> Result<(), String> {
|
pub async fn delete(register_id: i32) -> Result<(), String> {
|
||||||
let db = db().await?;
|
let mut db = db().await?;
|
||||||
|
|
||||||
let res = sqlx::query!("DELETE FROM register WHERE register_id = ?", register_id)
|
let res = sqlx::query!("DELETE FROM register WHERE register_id = ?", register_id)
|
||||||
.execute(db)
|
.execute(&mut db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -220,7 +220,7 @@ impl Register {
|
|||||||
register_id_list: String,
|
register_id_list: String,
|
||||||
person_dni_list: String,
|
person_dni_list: String,
|
||||||
) -> Result<Vec<ScanData>, String> {
|
) -> Result<Vec<ScanData>, String> {
|
||||||
let db = db().await?;
|
let mut db = db().await?;
|
||||||
|
|
||||||
let sql = format!(
|
let sql = format!(
|
||||||
"
|
"
|
||||||
@ -253,6 +253,7 @@ impl Register {
|
|||||||
let result = match db.fetch_all(sql.as_str()).await {
|
let result = match db.fetch_all(sql.as_str()).await {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
drop(sqlx::Error::PoolTimedOut);
|
||||||
log::error!("Error fetching course & person: {:?}", err);
|
log::error!("Error fetching course & person: {:?}", err);
|
||||||
return Err("Error fetching course & person".into());
|
return Err("Error fetching course & person".into());
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ export function ClassroomUserCreation(props: {
|
|||||||
person: Person,
|
person: Person,
|
||||||
onCreate: (classroom_id: number, classroom_username: string) => void,
|
onCreate: (classroom_id: number, classroom_username: string) => void,
|
||||||
}) {
|
}) {
|
||||||
const [email, setEmail] = createSignal("yuli.palo.apaza@gmail.com");
|
const [email, setEmail] = createSignal("alumno@eegsac.com");
|
||||||
const [username, setUsername] = createSignal("USERNAME");
|
const [username, setUsername] = createSignal("USERNAME");
|
||||||
const {setError, status, setStatus} = useLoading();
|
const {setError, status, setStatus} = useLoading();
|
||||||
const [names, setNames] = createSignal(props.person.person_names);
|
const [names, setNames] = createSignal(props.person.person_names);
|
||||||
|
1
rs-front/.gitignore
vendored
1
rs-front/.gitignore
vendored
@ -2,4 +2,5 @@ dist
|
|||||||
.directory
|
.directory
|
||||||
target
|
target
|
||||||
public/tailwind.css
|
public/tailwind.css
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user