Add duration to header response.

Add sort_id to processes_table.
Remove postgresql errors from error messages.
Filter "Codigo de Referencia" on the DB side.
Optimize get_random_process_id by using sort_id.
This commit is contained in:
Pedro de Oliveira 2023-06-03 21:53:00 +01:00
parent 49896cd208
commit f9ae423e39
4 changed files with 54 additions and 55 deletions

View File

@ -18,56 +18,55 @@ pub struct AppState {
}
pub fn get_random_process_id(db: &DbPool) -> i32 {
sql_function!(fn random() -> Text);
use diesel::dsl::*;
let mut conn = db.get().unwrap();
processes::table
.limit(1)
let random_sort_id: i32 = processes::table
.select(sql::<diesel::sql_types::Integer>(
"CAST(floor(random() * max(sort_id)) + 1 AS INTEGER)",
))
.first::<i32>(&mut conn)
.expect("fail");
let result: i32 = processes::table
.filter(processes::sort_id.ge(random_sort_id))
.select(processes::id)
.order(random())
.first(&mut conn)
.expect("fail")
.expect("fail");
result
}
pub fn get_full_process(process_id: i32, db: &DbPool) -> Value {
pub fn get_full_process(process_id: i32, db: &DbPool) -> Result<Value, String> {
let mut conn = db.get().unwrap();
let process = processes::table
let result = processes::table
.select(Process::as_select())
.filter(processes::id.eq(process_id))
.first(&mut conn)
.expect("fail");
.first(&mut conn);
let mut results: Vec<(String, String)> = ProcessTag::belonging_to(&process)
.inner_join(tags::table)
.select((tags::title_api, process_tags::contents))
.load(&mut conn)
.expect("fail");
if let Ok(process) = result {
let mut results: Vec<(String, String)> = ProcessTag::belonging_to(&process)
.inner_join(tags::table)
.select((tags::title_api, process_tags::contents))
.filter(process_tags::tag_id.ne(1)) // Codigo de Referencia
.load(&mut conn)
.expect("fail");
results.sort_by_key(|(key, _)| key.clone());
results.sort_by_key(|(key, _)| key.clone());
let mut data = json!({
"document": {
"titulo": process.title,
},
});
let mut data = json!({
"document": {
"titulo": process.title,
},
});
if let Some(document) = data.get_mut("document").and_then(Value::as_object_mut) {
for (title, contents) in results {
if title != "codigo_de_referencia" {
if let Some(document) = data.get_mut("document").and_then(Value::as_object_mut) {
for (title, contents) in results {
document.insert(title, Value::String(contents));
}
document.insert("digital".to_owned(), Value::Bool(process.scan));
}
document.insert("digital".to_owned(), Value::Bool(process.scan));
}
if let Some(object) = data.as_object_mut() {
object.insert(
"link".to_owned(),
Value::String(format!("https://inquisicao.info/view/{process_id}")),
);
Ok(data)
} else {
Err("Invalid process id".to_owned())
}
data
}
fn get_total(key: &str, db: &DbPool) -> Result<i64, String> {
@ -87,22 +86,16 @@ fn get_total(key: &str, db: &DbPool) -> Result<i64, String> {
match result {
Ok(total) => Ok(total),
Err(error) => {
// TODO: Dont show PostgreSQL errors
Err(error.to_string())
}
Err(_error) => Err("Not found".to_owned()),
}
}
pub fn find_process(key: &str, offset: i64, db: &DbPool) -> Result<Value, String> {
let ts_config = TsConfigurationByName("SIMPLE");
let mut conn = db.get().unwrap();
let total_result = get_total(key, db);
match total_result {
Ok(total) => {
dbg!(&total);
Ok(_total) => {
let result = OffsetDsl::offset(
process_tags::table
.inner_join(tags::table)
@ -139,12 +132,9 @@ pub fn find_process(key: &str, offset: i64, db: &DbPool) -> Result<Value, String
match result {
Ok(value) => {
let (process_id, _title_api, _headline, _rank) = value;
Ok(get_full_process(process_id, db))
}
Err(error) => {
// TODO: Dont show PostgreSQL errors
Err(error.to_string())
Ok(get_full_process(process_id, db).unwrap())
}
Err(_error) => Err("Not found".to_owned()),
}
}
Err(error) => Err(error),

View File

@ -1,7 +1,8 @@
use crate::database::{find_process, get_full_process, get_random_process_id, AppState};
use actix_web::{get, web, HttpResponse};
use serde_json::json;
use std::collections::HashMap;
use crate::database::{AppState, find_process, get_full_process, get_random_process_id};
use std::time::Instant;
pub fn config(conf: &mut web::ServiceConfig) {
let scope = web::scope("/api")
@ -12,9 +13,13 @@ pub fn config(conf: &mut web::ServiceConfig) {
#[get("/degredo")]
pub async fn get_degredo(data: web::Data<AppState>) -> HttpResponse {
let start = Instant::now();
let id = get_random_process_id(&data.db);
let data = get_full_process(id, &data.db);
HttpResponse::Ok().json(data)
let duration = start.elapsed();
HttpResponse::Ok()
.append_header(("duration", duration.as_millis().to_string()))
.json(data)
}
#[get("/adcautelam")]
@ -22,6 +27,7 @@ pub async fn get_adcautelam(
params: web::Query<HashMap<String, String>>,
data: web::Data<AppState>,
) -> HttpResponse {
let start = Instant::now();
let key = match params.get("key") {
Some(value) if !value.is_empty() => value.as_str(),
_ => {
@ -38,9 +44,11 @@ pub async fn get_adcautelam(
let offset = page - 1;
let result = find_process(key, offset, &data.db);
let duration = start.elapsed();
match result {
Ok(data) => HttpResponse::Ok().json(data),
Ok(data) => HttpResponse::Ok()
.append_header(("duration", duration.as_millis().to_string()))
.json(data),
Err(error) => HttpResponse::NotFound().json(error),
}
}

View File

@ -1,4 +1,4 @@
use chrono::naive::NaiveDate;
//use chrono::naive::NaiveDate;
use diesel::prelude::*;
#[derive(Identifiable, Queryable, Selectable, PartialEq, Debug)]
@ -8,9 +8,9 @@ pub struct Process {
pub id: i32,
pub title: String,
pub scan: bool,
dt_start: Option<NaiveDate>,
dt_finish: Option<NaiveDate>,
origin: Option<String>,
//dt_start: Option<NaiveDate>,
//dt_finish: Option<NaiveDate>,
//origin: Option<String>,
}
#[derive(Identifiable, Associations, Queryable, Selectable, Debug)]

View File

@ -20,6 +20,7 @@ diesel::table! {
dt_start -> Nullable<Date>,
dt_finish -> Nullable<Date>,
origin -> Nullable<Varchar>,
sort_id -> Int4,
}
}