diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 0959f77..9b4ede0 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -421,6 +421,7 @@ dependencies = [ "axum-extra", "booksman-orm", "clap", + "dotenvy", "entity", "error-chain", "itertools", diff --git a/backend/api/Cargo.toml b/backend/api/Cargo.toml index 80f7c6e..a129148 100644 --- a/backend/api/Cargo.toml +++ b/backend/api/Cargo.toml @@ -10,6 +10,7 @@ entity = { path = "../entity" } axum = "^0.5" axum-extra = { version = "^0.3", features = ["spa"] } clap = { version = "^3", features = ["derive"] } +dotenvy = "0.15.0" error-chain = "0.12.4" log = "^0.4" reqwest = {version = "0.11.11", features = ["json"]} diff --git a/backend/api/src/lib.rs b/backend/api/src/lib.rs index 646ce1d..9b15187 100644 --- a/backend/api/src/lib.rs +++ b/backend/api/src/lib.rs @@ -3,7 +3,7 @@ use axum::{ response::IntoResponse, routing::{get,post}, Json, Router, - extract::{Extension, Form, Path, Query}, + extract::{Extension, Form, Path}, }; use axum_extra::routing::SpaRouter; use clap::Parser; @@ -15,12 +15,13 @@ use tower::ServiceBuilder; use tower_http::cors::CorsLayer; use tower_http::trace::TraceLayer; use booksman_orm::{ - sea_orm::{Database, DatabaseConnection, ActiveValue}, + sea_orm::{Database, DatabaseConnection}, Mutation as MutationCore, Query as QueryCore, + BookAndMeta, }; use itertools::Itertools; -use std::iter::Peekable; use ::entity::entities::{book,book_author,book_person,book_place,book_subject,book_time,book_isbn}; +use std::env; #[derive(Deserialize, Serialize, Debug, Clone)] struct BookUI { @@ -118,6 +119,15 @@ pub async fn main() { // enable console logging tracing_subscriber::fmt::init(); + + dotenvy::dotenv().ok(); + let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file"); + + let conn = Database::connect(db_url) + .await + .expect("Database connection failed"); + //Migrator::up(&conn, None).await.unwrap(); + let app = Router::new() .route("/api/search_openlibrary", get(search_openlibrary)) .route("/api/delete/:id", post(delete_book)) @@ -125,6 +135,7 @@ pub async fn main() { .route("/api/create", post(create_book)) .merge(SpaRouter::new("/assets", opt.static_dir)) .layer(ServiceBuilder::new().layer(TraceLayer::new_for_http())) + .layer(Extension(conn)) .layer( // see https://docs.rs/tower-http/latest/tower_http/cors/index.html // for more details @@ -207,29 +218,62 @@ async fn list_book( let books = QueryCore::find_books_plus_meta_in_page(conn,1,5) .await .expect("could not list books"); -let res: Vec = (books.0).iter() - .group_by(|x| (x.id, x.title.clone()) ).into_iter().peekable() + + let mut data_grouped: Vec<(i32,Vec)> = Vec::with_capacity(5); + for (key, group) in &books.0.into_iter().group_by(|x| x.id) { + data_grouped.push((key, group.collect())); + } + +let mut res: Vec = Vec::with_capacity(5); + for (id,group) in data_grouped.into_iter() { + let bookui = BookUI{ + id, +title: group.clone().into_iter().map( |u| u.title).next().unwrap(), +open_library_key: group.clone().into_iter().map( |u| u.open_library_key).next(), +edition_count: group.clone().into_iter().clone().map(|u| u.edition_count).next(), +first_publish_year: group.clone().into_iter().clone().map(|u| u.first_publish_year).next(), +median_page_count: group.clone().into_iter().clone().map(|u| u.median_page_count).next(), +goodread_id: group.clone().into_iter().clone().map(|u| u.goodread_id).next(), +description: group.clone().into_iter().clone().map(|u| u.description).next(), +cover: group.clone().into_iter().clone().map(|u| u.cover).next(), +location: group.clone().into_iter().clone().map(|u| u.location).next(), +time_added: group.clone().into_iter().clone().map(|u| u.time_added).next(), +rating: group.clone().into_iter().clone().map(|u| u.rating).next(), +comments: group.clone().into_iter().clone().map(|u| u.comments).next(), +author_name: Some(group.clone().into_iter().map(|u| u.author_name).collect()), +person: Some(group.clone().into_iter().map(|u| u.person).collect()), +place: Some(group.clone().into_iter().map(|u| u.place).collect()), +subject: Some(group.clone().into_iter().map(|u| u.subject).collect()), +time: Some(group.clone().into_iter().map(|u| u.time).collect()), +isbn: Some(group.clone().into_iter().map(|u| u.isbn).collect()), + + }; + res.push(bookui); + } +/* let mut res: Vec = (books.0).iter() + .group_by(|x| (x.id, x.title.clone()) ).into_iter() .map(|((id,title), group )| BookUI{ id, title, -open_library_key: group.map( |u| u.open_library_key).peek(), -edition_count: group.clone().map(|u| u.edition_count).next(), -first_publish_year: group.clone().map(|u| u.first_publish_year).next(), -median_page_count: group.clone().map(|u| u.median_page_count).next(), -goodread_id: group.clone().map(|u| u.goodread_id).next(), -description: group.clone().map(|u| u.description).next(), -cover: group.clone().map(|u| u.cover).next(), -location: group.clone().map(|u| u.location).next(), -time_added: group.clone().map(|u| u.time_added).next(), -rating: group.clone().map(|u| u.rating).next(), -comments: group.clone().map(|u| u.comments).next(), -author_name: Some(group.map(|u| u.author_name).collect()), -person: Some(group.map(|u| u.person).collect()), -place: Some(group.map(|u| u.place).collect()), -subject: Some(group.map(|u| u.subject).collect()), -time: Some(group.map(|u| u.time).collect()), -isbn: Some(group.map(|u| u.isbn).collect()), +open_library_key: group.map( |u| u.open_library_key.clone()).next(), +edition_count: group.map(|u| u.edition_count).next(), +first_publish_year: group.map(|u| u.first_publish_year).next(), +median_page_count: group.map(|u| u.median_page_count).next(), +goodread_id: group.map(|u| u.goodread_id.clone()).next(), +description: group.map(|u| u.description.clone()).next(), +cover: group.map(|u| u.cover.clone()).next(), +location: group.map(|u| u.location.clone()).next(), +time_added: group.map(|u| u.time_added.clone()).next(), +rating: group.map(|u| u.rating).next(), +comments: group.map(|u| u.comments.clone()).next(), +author_name: Some(group.map(|u| u.author_name.clone()).collect()), +person: Some(group.map(|u| u.person.clone()).collect()), +place: Some(group.map(|u| u.place.clone()).collect()), +subject: Some(group.map(|u| u.subject.clone()).collect()), +time: Some(group.map(|u| u.time.clone()).collect()), +isbn: Some(group.map(|u| u.isbn.clone()).collect()), }).collect(); + */ return Json(res); // "success" } diff --git a/backend/orm/src/query.rs b/backend/orm/src/query.rs index a647bcc..d5312e0 100644 --- a/backend/orm/src/query.rs +++ b/backend/orm/src/query.rs @@ -5,7 +5,7 @@ use ::entity::entities::{book,book_author,book_person,book_place,book_subject,bo use sea_orm::*; //use sea_query::Expr; -#[derive(FromQueryResult)] +#[derive(FromQueryResult,Clone)] pub struct BookAndMeta { pub id: i32, pub open_library_key: String,